summaryrefslogtreecommitdiff
path: root/Build/source/texk/ttf2pk/vplaux.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
commit487ca4806cc046076293cf6cc5fbba0db282bac7 (patch)
tree847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/ttf2pk/vplaux.c
parenta3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff)
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/ttf2pk/vplaux.c')
-rw-r--r--Build/source/texk/ttf2pk/vplaux.c588
1 files changed, 588 insertions, 0 deletions
diff --git a/Build/source/texk/ttf2pk/vplaux.c b/Build/source/texk/ttf2pk/vplaux.c
new file mode 100644
index 00000000000..a84fac0decf
--- /dev/null
+++ b/Build/source/texk/ttf2pk/vplaux.c
@@ -0,0 +1,588 @@
+/*
+ * vplaux.c
+ *
+ * This file is part of the ttf2pk package.
+ *
+ * Copyright 1997-1999, 2000 by
+ * Frederic Loyer <loyer@ensta.fr>
+ * Werner Lemberg <wl@gnu.org>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "ttf2tfm.h"
+#include "newobj.h"
+#include "ttfenc.h"
+#include "texenc.h"
+#include "tfmaux.h"
+#include "vplaux.h"
+#include "errormsg.h"
+#include "case.h"
+
+
+#undef PI
+#define PI 3.14159265358979323846264338327
+
+
+#define vout(s) fprintf(out, s)
+
+#define voutln(str) {fprintf(out, "%s\n", str); vlevout(level);}
+#define voutln2(f, s) {fprintf(out, f, s); vlevnlout(level);}
+#define voutln3(f, a, b) {fprintf(out, f, a, b); vlevnlout(level);}
+#define voutln4(f, a, b, c) {fprintf(out, f, a, b, c); vlevnlout(level);}
+
+
+static char vcharbuf[6];
+static char vnamebuf[100];
+
+/* the depth of parenthesis nesting in VPL file being written */
+static int level;
+
+
+static FILE *out;
+
+
+static void
+vlevout(register int l)
+{
+ while (l--)
+ vout(" ");
+}
+
+
+static void
+vlevnlout(int level)
+{
+ vout("\n");
+ vlevout(level);
+}
+
+
+static void
+vleft(int *levelp)
+{
+ (*levelp)++;
+ vout("(");
+}
+
+
+static void
+vright(int *levelp)
+{
+ (*levelp)--;
+ voutln(")");
+}
+
+
+static char *
+vchar(int c,
+ char *buf,
+ Boolean forceoctal)
+{
+ if (forceoctal == 0 && isalnum(c))
+ (void)sprintf(buf, "C %c", c);
+ else
+ (void)sprintf(buf, "O %o", (unsigned)c);
+ return buf;
+}
+
+
+static char *
+vname(int c,
+ char *buf,
+ ttfinfo **array,
+ Boolean forceoctal)
+{
+ if (!forceoctal && isalnum(c))
+ buf[0] = '\0';
+ else
+ sprintf(buf, " (comment %s)", array[c]->adobename);
+ return buf;
+}
+
+
+static int
+texheight(register ttfinfo *ti,
+ ttfinfo *ac,
+ int xh)
+{
+ register char **p;
+ register ttfinfo *aci, *acci;
+ char buffer[200];
+
+
+ if (xh <= 50 || *(ti->adobename + 1))
+ return ti->ury; /* that was the simple case */
+
+ for (p = accents; *p; p++) /* otherwise we look for accented letters. */
+ /* We even check glyphs not in any encoding */
+ if (NULL != (aci = findadobe(*p, ac)))
+ {
+ strcpy(buffer, ti->adobename);
+ strcat(buffer, *p);
+ if (NULL != (acci = findadobe(buffer, ac)))
+ return acci->ury - aci->ury + xh;
+ }
+ return ti->ury;
+}
+
+
+/*
+ * Compute uppercase mapping, when making a small caps font.
+ */
+
+void
+upmap(Font *fnt)
+{
+ register ttfinfo *ti, *Ti;
+ register char *p, *q;
+ register pcc *np, *nq;
+ int i, j;
+ char lwr[50];
+
+
+ for (Ti = fnt->charlist; Ti; Ti = Ti->next)
+ {
+ p = Ti->adobename;
+ if (isupper(*p))
+ {
+ q = lwr;
+ for (; *p; p++)
+ *q++ = tolower(*p);
+ *q = '\0';
+
+ if (NULL != (ti = findmappedadobe(lwr, fnt->inencptrs)))
+ {
+ for (i = ti->outcode; i >= 0; i = fnt->nextout[i])
+ fnt->uppercase[i] = Ti;
+ for (i = Ti->outcode; i >= 0; i = fnt->nextout[i])
+ fnt->lowercase[i] = ti;
+ }
+ }
+ }
+
+ /*
+ * Note that, contrary to the normal true/false conventions,
+ * uppercase[i] is NULL and lowercase[i] is non-NULL when `i' is the
+ * ASCII code of an uppercase letter; and vice versa for lowercase
+ * letters.
+ */
+
+ if (NULL != (ti = findmappedadobe("germandbls", fnt->inencptrs)))
+ if (NULL != (Ti = findmappedadobe("S", fnt->inencptrs)))
+ /* we also construct SS */
+ {
+ for (i = ti->outcode; i >= 0; i = fnt->nextout[i])
+ fnt->uppercase[i] = ti;
+ ti->incode = -1;
+ ti->width = Ti->width << 1;
+ ti->llx = Ti->llx;
+ ti->lly = Ti->lly;
+ ti->urx = Ti->width + Ti->urx;
+ ti->ury = Ti->ury;
+ ti->kerns = Ti->kerns;
+
+ np = newpcc();
+ np->partname = "S";
+ nq = newpcc();
+ nq->partname = "S";
+ nq->xoffset = Ti->width;
+ np->next = nq;
+ ti->pccs = np;
+ ti->constructed = True;
+ }
+
+ for (i = 0; casetable[i].upper; i++)
+ {
+ if ((ti = findmappedadobe(casetable[i].lower, fnt->inencptrs)))
+ for (j = ti->outcode; j >= 0; j = fnt->nextout[j])
+ fnt->uppercase[j] = findmappedadobe(casetable[i].upper,
+ fnt->inencptrs);
+ }
+}
+
+/*
+ * The logic above seems to work well enough, but it leaves useless
+ * characters like `fi' and `fl' in the font if they were present
+ * initially, and it omits characters like `dotlessj' if they are
+ * absent initially.
+ */
+
+
+void
+writevpl(Font *fnt, char makevpl, Boolean forceoctal)
+{
+ register int i, j, k;
+ register ttfinfo *ti;
+ register lig *nlig;
+ register kern *nkern;
+ register pcc *npcc;
+ ttfinfo *asucc, *asub, *api;
+ ttfptr *kern_eq;
+ int xoff, yoff, ht;
+ int bc, ec;
+ char buf[200];
+ char header[256];
+ Boolean unlabeled;
+ float Slant;
+
+
+ out = fnt->vplout;
+
+ header[0] = '\0';
+ strncat(header, "Created by `", 12);
+ strncat(header, fnt->titlebuf, 255 - 12 - 1);
+ strncat(header, "'", 1);
+
+ voutln2("(VTITLE %s)", header);
+ voutln("(COMMENT Please change VTITLE if you edit this file)");
+ (void)sprintf(buf, "TeX-%s%s%s%s",
+ fnt->fullname,
+ (fnt->efactor == 1.0 ? "" : "-E"),
+ (fnt->slant == 0.0 ? "" : "-S"),
+ (makevpl == 1 ? "" : "-CSC"));
+
+ if (strlen(buf) > 19) /* too long, will retain first 9 and last 10 chars */
+ {
+ register char *p, *q;
+
+
+ for (p = &buf[9], q = &buf[strlen(buf)-10]; p < &buf[19];
+ p++, q++)
+ *p = *q;
+ buf[19] = '\0';
+ }
+ voutln2("(FAMILY %s)", buf);
+
+ {
+ char tbuf[300];
+ char *base_encoding = fnt->codingscheme;
+
+
+ if (strcmp(fnt->outencoding->name, base_encoding) == 0)
+ sprintf(tbuf, "%s", fnt->outencoding->name);
+ else
+ sprintf(tbuf, "%s + %s", base_encoding, fnt->outencoding->name);
+
+ if (strlen(tbuf) > 39)
+ {
+ warning("Coding scheme too long; shortening to 39 characters");
+ tbuf[39] = '\0';
+ }
+ voutln2("(CODINGSCHEME %s)", tbuf);
+ }
+
+ {
+ long t, sc;
+ char *s;
+ int n, pos;
+
+
+ s = header;
+ n = strlen(s);
+ t = ((long)n) << 24;
+ sc = 16;
+ pos = 18;
+
+ voutln(
+ "(COMMENT The following `HEADER' lines are equivalent to the string)");
+ voutln2("(COMMENT \"%s\")", header);
+
+ while (n > 0)
+ {
+ t |= ((long)(*(unsigned char *)s++)) << sc;
+ sc -= 8;
+ if (sc < 0)
+ {
+ voutln3("(HEADER D %d O %lo)", pos, t);
+ t = 0;
+ sc = 24;
+ pos++;
+ }
+ n--;
+ }
+ if (t)
+ voutln3("(HEADER D %d O %lo)", pos, t);
+ }
+
+ voutln("(DESIGNSIZE R 10.0)");
+ voutln("(DESIGNUNITS R 1000)");
+ voutln("(COMMENT DESIGNSIZE (1 em) IS IN POINTS)");
+ voutln("(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/1000)");
+
+#if 0
+ /* Let vptovf compute the checksum. */
+ voutln2("(CHECKSUM O %lo)", cksum ^ 0xFFFFFFFF);
+#endif
+
+ if (fnt->boundarychar >= 0)
+ voutln2("(BOUNDARYCHAR O %lo)", (unsigned long)fnt->boundarychar);
+
+ vleft(&level);
+ voutln("FONTDIMEN");
+
+ Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0));
+
+ if (Slant)
+ voutln2("(SLANT R %f)", Slant);
+ voutln2("(SPACE D %d)", fnt->fontspace);
+ if (!fnt->fixedpitch)
+ {
+ voutln2("(STRETCH D %d)", transform(200, 0, fnt->efactor, fnt->slant));
+ voutln2("(SHRINK D %d)", transform(100, 0, fnt->efactor, fnt->slant));
+ }
+ voutln2("(XHEIGHT D %d)", fnt->xheight);
+ voutln2("(QUAD D %d)", transform(1000, 0, fnt->efactor, fnt->slant));
+ voutln2("(EXTRASPACE D %d)",
+ fnt->fixedpitch ? fnt->fontspace :
+ transform(111, 0, fnt->efactor, fnt->slant));
+ vright(&level);
+
+ vleft(&level);
+ voutln("MAPFONT D 0");
+ voutln2("(FONTNAME %s)", fnt->fullname);
+#if 0
+ voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum);
+#endif
+ vright(&level);
+
+ if (makevpl > 1)
+ {
+ vleft(&level);
+ voutln("MAPFONT D 1");
+ voutln2("(FONTNAME %s)", fnt->fullname);
+ voutln2("(FONTAT D %d)", (int)(1000.0 * fnt->capheight + 0.5));
+#if 0
+ voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum);
+#endif
+ vright(&level);
+ }
+
+ for (i = 0; i <= 0xFF && fnt->outencptrs[i] == NULL; i++)
+ ;
+ bc = i;
+ for (i = 0xFF; i >= 0 && fnt->outencptrs[i] == NULL; i--)
+ ;
+ ec = i;
+
+ vleft(&level);
+ voutln("LIGTABLE");
+ ti = findadobe("||", fnt->charlist);
+ unlabeled = True;
+ for (nlig = ti->ligs; nlig; nlig = nlig->next)
+ if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs)))
+ {
+ if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs)))
+ if (asucc->outcode >= 0)
+ if (asub->outcode >= 0)
+ {
+ if (unlabeled)
+ {
+ voutln("(LABEL BOUNDARYCHAR)");
+ unlabeled = False;
+ }
+ for (j = asucc->outcode; j >= 0; j = fnt->nextout[j])
+ voutln4("(%s %s O %o)", vplligops[nlig->op],
+ vchar(j, vcharbuf, forceoctal),
+ (unsigned)asub->outcode);
+ }
+ }
+ if (!unlabeled)
+ voutln("(STOP)");
+
+ for (i = bc; i <= ec; i++)
+ if ((ti = fnt->outencptrs[i]) && ti->outcode == i)
+ {
+ unlabeled = True;
+ if (fnt->uppercase[i] == NULL)
+ /* omit ligatures from smallcap lowercase */
+ for (nlig = ti->ligs; nlig; nlig = nlig->next)
+ if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs)))
+ if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs)))
+ if (asucc->outcode >= 0)
+ if (asub->outcode >= 0)
+ {
+ if (unlabeled)
+ {
+ for (j = ti->outcode; j >= 0; j = fnt->nextout[j])
+ voutln3("(LABEL %s)%s",
+ vchar(j, vcharbuf, forceoctal),
+ vname(j, vnamebuf,
+ fnt->outencptrs, forceoctal));
+ unlabeled = False;
+ }
+ for (j = asucc->outcode; j >= 0; j = fnt->nextout[j])
+ {
+ voutln4("(%s %s O %o)", vplligops[nlig->op],
+ vchar(j, vcharbuf, forceoctal),
+ (unsigned)asub->outcode);
+ if (nlig->boundleft)
+ break;
+ }
+ }
+
+ for (nkern = (fnt->uppercase[i] ? fnt->uppercase[i]->kerns : ti->kerns);
+ nkern; nkern=nkern->next)
+ if (NULL != (asucc = findmappedadobe(nkern->succ, fnt->inencptrs)))
+ for (j = asucc->outcode; j >= 0; j = fnt->nextout[j])
+ {
+ if (fnt->uppercase[j] == NULL)
+ {
+ if (unlabeled)
+ {
+ for (k = ti->outcode; k >= 0; k = fnt->nextout[k])
+ voutln3("(LABEL %s)%s",
+ vchar(k, vcharbuf, forceoctal),
+ vname(k, vnamebuf, fnt->outencptrs, forceoctal));
+ unlabeled = False;
+ }
+
+ /*
+ * If other characters have the same kerns as this
+ * one, output the label here. This makes the TFM
+ * file much smaller than if we output all the
+ * kerns again under a different label.
+ */
+
+ for (kern_eq = ti->kern_equivs; kern_eq;
+ kern_eq = kern_eq->next)
+ {
+ k = kern_eq->ch->outcode;
+ if (k >= 0 && k <= 0xFF)
+ voutln3("(LABEL %s)%s",
+ vchar(k, vcharbuf, forceoctal),
+ vname(k, vnamebuf, fnt->outencptrs, forceoctal));
+ }
+ ti->kern_equivs = NULL; /* Only output those labels once. */
+
+ if (fnt->uppercase[i])
+ {
+ if (fnt->lowercase[j])
+ {
+ for (k = fnt->lowercase[j]->outcode; k >= 0;
+ k = fnt->nextout[k])
+ voutln4("(KRN %s R %.1f)%s",
+ vchar(k, vcharbuf, forceoctal),
+ fnt->capheight * nkern->delta,
+ vname(k, vnamebuf, fnt->outencptrs, forceoctal));
+ }
+ else
+ voutln4("(KRN %s R %.1f)%s",
+ vchar(j, vcharbuf, forceoctal),
+ fnt->capheight * nkern->delta,
+ vname(j, vnamebuf, fnt->outencptrs, forceoctal));
+ }
+ else
+ {
+ voutln4("(KRN %s R %d)%s",
+ vchar(j, vcharbuf, forceoctal),
+ nkern->delta,
+ vname(j, vnamebuf, fnt->outencptrs, forceoctal));
+ if (fnt->lowercase[j])
+ for (k = fnt->lowercase[j]->outcode; k >= 0;
+ k = fnt->nextout[k])
+ voutln4("(KRN %s R %.1f)%s",
+ vchar(k, vcharbuf, forceoctal),
+ fnt->capheight * nkern->delta,
+ vname(k, vnamebuf, fnt->outencptrs, forceoctal));
+ }
+ }
+ }
+ if (!unlabeled)
+ voutln("(STOP)");
+ }
+ vright(&level);
+
+ for (i = bc; i <= ec; i++)
+ if (NULL != (ti = fnt->outencptrs[i]))
+ {
+ vleft(&level);
+ fprintf(out, "CHARACTER %s%s\n ",
+ vchar(i, vcharbuf, forceoctal),
+ vname(i, vnamebuf, fnt->outencptrs, forceoctal));
+
+ if (fnt->uppercase[i])
+ {
+ ti = fnt->uppercase[i];
+ voutln2("(CHARWD R %.1f)", fnt->capheight * (ti->width));
+ if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight)))
+ voutln2("(CHARHT R %.1f)", fnt->capheight * ht);
+ if (ti->lly)
+ voutln2("(CHARDP R %.1f)", -fnt->capheight * ti->lly);
+ if (ti->urx > ti->width)
+ voutln2("(CHARIC R %.1f)", fnt->capheight * (ti->urx - ti->width));
+ }
+ else
+ {
+ voutln2("(CHARWD R %d)", ti->width);
+ if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight)))
+ voutln2("(CHARHT R %d)", ht);
+ if (ti->lly)
+ voutln2("(CHARDP R %d)", -ti->lly);
+ if (ti->urx > ti->width)
+ voutln2("(CHARIC R %d)", ti->urx - ti->width);
+ }
+
+ if (ti->incode != i || fnt->uppercase[i] || ti->constructed)
+ {
+ vleft(&level);
+ voutln("MAP");
+ if (fnt->uppercase[i])
+ voutln("(SELECTFONT D 1)");
+
+ if (ti->pccs && (ti->incode < 0 || ti->constructed))
+ {
+ xoff = 0;
+ yoff = 0;
+
+ for (npcc = ti->pccs; npcc; npcc = npcc->next)
+ if (NULL != (api = findmappedadobe(npcc->partname,
+ fnt->inencptrs)))
+ if (api->outcode >= 0)
+ {
+ if (npcc->xoffset != xoff)
+ {
+ if (fnt->uppercase[i])
+ {
+ voutln2("(MOVERIGHT R %.1f)",
+ fnt->capheight * (npcc->xoffset - xoff));
+ }
+ else
+ voutln2("(MOVERIGHT R %d)", npcc->xoffset - xoff);
+
+ xoff = npcc->xoffset;
+ }
+
+ if (npcc->yoffset != yoff)
+ {
+ if (fnt->uppercase[i])
+ {
+ voutln2("(MOVEUP R %.1f)",
+ fnt->capheight * (npcc->yoffset - yoff));
+ }
+ else
+ voutln2("(MOVEUP R %d)", npcc->yoffset - yoff);
+
+ yoff = npcc->yoffset;
+ }
+
+ voutln2("(SETCHAR O %o)", (unsigned)api->incode);
+ xoff += fnt->outencptrs[api->outcode]->width;
+ }
+ }
+ else
+ voutln2("(SETCHAR O %o)", (unsigned)ti->incode);
+ vright(&level);
+ }
+ vright(&level);
+ }
+
+ if (level)
+ oops("I forgot to match the parentheses.");
+}
+
+
+/* end */