summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/virtualfont.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipsk/virtualfont.c')
-rw-r--r--Build/source/texk/dvipsk/virtualfont.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/Build/source/texk/dvipsk/virtualfont.c b/Build/source/texk/dvipsk/virtualfont.c
new file mode 100644
index 00000000000..287be596609
--- /dev/null
+++ b/Build/source/texk/dvipsk/virtualfont.c
@@ -0,0 +1,322 @@
+/*
+ * Here's the code to load a VF file into memory.
+ * Any resemblance between this file and loadfont.c is purely uncoincidental.
+ */
+#include "dvips.h" /* The copyright notice in that file is included too! */
+#ifdef KPATHSEA
+#include <kpathsea/c-pathmx.h>
+#include <kpathsea/concatn.h>
+#endif
+/*
+ * The external declarations:
+ */
+#include "protos.h"
+/*
+ * Now we have some routines to get stuff from the VF file.
+ * Subroutine vfbyte returns the next byte.
+ */
+static FILE *vffile;
+static char name[500];
+static void
+badvf(const char *s)
+{
+ char *msg = concatn("! Bad VF file ", name, ": ", s, NULL);
+ error(msg);
+}
+
+static shalfword
+vfbyte(void)
+{
+ register shalfword i;
+
+ if ((i=getc(vffile))==EOF)
+ badvf("unexpected eof");
+ return(i);
+}
+
+static integer
+vfquad(void)
+{
+ register integer i;
+
+ i = vfbyte();
+ if (i > 127)
+ i -= 256;
+ i = i * 256 + vfbyte();
+ i = i * 256 + vfbyte();
+ i = i * 256 + vfbyte();
+ return(i);
+}
+
+static integer
+vftrio(void)
+{
+ register integer i;
+
+ i = vfbyte();
+ i = i * 256 + vfbyte();
+ i = i * 256 + vfbyte();
+ return(i);
+}
+
+static int
+vfopen(register fontdesctype *fd)
+{
+ register char *n;
+#ifndef KPATHSEA
+ register char *d;
+#endif
+
+ n = fd->name;
+#ifndef KPATHSEA
+ d = fd->area;
+ if (*d==0)
+ d = vfpath;
+#endif
+ if (strlen(n) + 5 >= sizeof (name)) {
+ /* 5 for vf() + null */
+ error("! VF file name too long in vfopen");
+ }
+#ifdef MVSXA /* IBM: MVS/XA */
+ sprintf(name, "vf(%s)", n);
+#else
+ sprintf(name, "%s.vf", n);
+#endif
+#ifdef KPATHSEA
+ if (0 != (vffile=search(vfpath, name, READBIN)))
+#else
+ if (0 != (vffile=search(d, name, READBIN)))
+#endif
+ return(VF_TEX);
+ if (!noomega)
+#ifdef KPATHSEA
+ if (0 != (vffile=search(ovfpath, n, READBIN)))
+#else
+ if (0 != (vffile=search(d, n, READBIN)))
+#endif
+ return(VF_OMEGA);
+ return(0);
+}
+
+/*
+ * The following routine is like fontdef, but for local fontdefs in VF files.
+ */
+static fontmaptype *
+vfontdef(integer s, int siz)
+{
+ register integer i, j, fn;
+ register fontdesctype *fp;
+ register fontmaptype *cfnt;
+ char *nam, *area;
+ integer cksum, scsize, dssize;
+
+ fn = vfbyte();
+ while (siz-- > 1)
+ fn = (fn << 8) + vfbyte();
+ cfnt = (fontmaptype *)mymalloc((integer)sizeof(fontmaptype));
+ cfnt->fontnum = fn;
+ cksum = vfquad();
+ scsize = scalewidth(s, vfquad());
+ dssize = (integer)(alpha * (real)vfquad());
+ i = vfbyte(); j = vfbyte();
+ if (nextstring + i + j > maxstring)
+ error("! out of string space");
+ area = nextstring;
+ for (; i>0; i--)
+ *nextstring++ = vfbyte();
+ *nextstring++ = 0;
+ nam = nextstring;
+ for (; j>0; j--)
+ *nextstring++ = vfbyte();
+ *nextstring++ = 0;
+ fp = matchfont(nam, area, scsize, (char *)0);
+ if (fp) {
+ nextstring = nam;
+ fp->checksum = cksum;
+ } else {
+ fp = newfontdesc(cksum, scsize, dssize, nam, area);
+ fp->next = fonthead;
+ fonthead = fp;
+ }
+ cfnt->desc = fp;
+ return (cfnt);
+}
+
+/*
+ * Now our virtualfont routine.
+ */
+Boolean
+virtualfont(register fontdesctype *curfnt)
+{
+ register integer i, j;
+ register shalfword cmd;
+ register integer k;
+ register integer length;
+ register integer cc;
+ register chardesctype *cd;
+ integer scaledsize = curfnt->scaledsize;
+ integer no_of_chars=256;
+ integer maxcc=255;
+ register quarterword *tempr;
+ fontmaptype *fm, *newf;
+ int id, kindfont;
+ kindfont = vfopen(curfnt); /* VF_TEX for TeX and pTeX, VF_OMEGA for Omega */
+ curfnt->kind = kindfont;
+ if (!kindfont)
+ return (0);
+#ifdef DEBUG
+ if (dd(D_FONTS))
+ fprintf_str(stderr,"Loading virtual font %s at %.1fpt\n",
+ name, (real)scaledsize/(alpha*0x100000));
+#endif /* DEBUG */
+
+/*
+ * We clear out some pointers:
+ */
+ if (kindfont==VF_OMEGA) {
+ no_of_chars = VF_MEM_UNIT;
+ curfnt->maxchars=VF_MEM_UNIT;
+ free(curfnt->chardesc);
+ curfnt->chardesc = (chardesctype *)
+ mymalloc(VF_MEM_UNIT * (integer)sizeof(chardesctype));
+ }
+ for (i=0; i<no_of_chars; i++) {
+ curfnt->chardesc[i].TFMwidth = 0;
+ curfnt->chardesc[i].packptr = NULL;
+ curfnt->chardesc[i].pixelwidth = 0;
+ curfnt->chardesc[i].flags = 0;
+ curfnt->chardesc[i].flags2 = 0;
+ }
+ if (vfbyte()!=247)
+ badvf("expected pre");
+ if (vfbyte()!=202)
+ badvf("wrong id byte");
+ for(i=vfbyte(); i>0; i--)
+ vfbyte();
+ k = vfquad();
+ check_checksum (k, curfnt->checksum, curfnt->name);
+ k = (integer)(alpha * (real)vfquad());
+ if (k > curfnt->designsize + 2 || k < curfnt->designsize - 2) {
+ id = 0;
+ if (!noptex) {
+ tfmopen(curfnt); /* We check if parent is jfm or not. */
+ id = tfm16();
+ fclose(tfmfile);
+ }
+ if (id != 9 && id != 11) {
+ char *msg = concat("Design size mismatch in font ", name);
+ error(msg);
+ free(msg);
+ }
+ }
+/*
+ * Now we look for font definitions.
+ */
+ fm = NULL;
+ id = 0;
+ while ((cmd=vfbyte())>=243) {
+ if (cmd==248 && (id == 9 || id == 11)) /* parent is jfm and no character definitions */
+ goto close_vf;
+ if (cmd>246)
+ badvf("unexpected command in preamble");
+ newf = vfontdef(scaledsize, cmd-242);
+ if (fm)
+ fm->next = newf;
+ else {
+ curfnt->localfonts = newf;
+ if (!noptex && id==0) {
+ tfmopen(curfnt->localfonts->desc); /* We check if parent is jfm or not. */
+ id = tfm16();
+ fclose(tfmfile);
+ if (id == 9 || id == 11)
+ curfnt->kind = VF_PTEX;
+ }
+ }
+ fm = newf;
+ fm->next = NULL; /* FIFO */
+ }
+/*
+ * Now we get down to the serious business of reading character definitions.
+ */
+ do {
+ if (cmd==242) {
+ length = vfquad() + 2;
+ if (length<2) badvf("negative length packet");
+ if (length>65535) badvf("packet too long");
+ cc = vfquad();
+ if (cc>=no_of_chars && cc<MAX_CODE) {
+ j = VF_MEM_UNIT * ((integer)(cc/VF_MEM_UNIT) + 1);
+ curfnt->chardesc = (chardesctype *)xrealloc(curfnt->chardesc,
+ sizeof(chardesctype)*j);
+ for (i=no_of_chars; i<j; i++) {
+ curfnt->chardesc[i].TFMwidth = 0;
+ curfnt->chardesc[i].packptr = NULL;
+ curfnt->chardesc[i].pixelwidth = 0;
+ curfnt->chardesc[i].flags = 0;
+ curfnt->chardesc[i].flags2 = 0;
+ }
+ no_of_chars = j;
+ curfnt->maxchars=no_of_chars;
+ }
+ else if (cc<0 || cc>=no_of_chars) badvf("character code out of range");
+ cd = curfnt->chardesc + cc;
+ cd->TFMwidth = scalewidth(vfquad(), scaledsize);
+ } else {
+ length = cmd + 2;
+ cc = vfbyte();
+ cd = curfnt->chardesc + cc;
+ cd->TFMwidth = scalewidth(vftrio(), scaledsize);
+ }
+ maxcc = (maxcc<cc) ? cc : maxcc;
+ if (cd->TFMwidth >= 0)
+ cd->pixelwidth = ((integer)(conv*cd->TFMwidth+0.5));
+ else
+ cd->pixelwidth = -((integer)(conv*-cd->TFMwidth+0.5));
+ cd->flags = EXISTS;
+ cd->flags2 = EXISTS;
+ if (bytesleft < length) {
+#ifdef DEBUG
+ if (dd(D_MEM))
+ fprintf(stderr,
+#ifdef SHORTINT
+ "Allocating new raster memory (%ld req, %ld left)\n",
+#else
+ "Allocating new raster memory (%d req, %ld left)\n",
+#endif
+ length, bytesleft);
+#endif /* DEBUG */
+ if (length > MINCHUNK) {
+ tempr = (quarterword *)mymalloc((integer)length);
+ bytesleft = 0;
+ } else {
+ raster = (quarterword *)mymalloc((integer)RASTERCHUNK);
+ tempr = raster;
+ bytesleft = RASTERCHUNK - length;
+ raster += length;
+ }
+ } else {
+ tempr = raster;
+ bytesleft -= length;
+ raster += length;
+ }
+ cd->packptr = tempr;
+ length -= 2;
+ *tempr++ = length / 256;
+ *tempr++ = length % 256;
+ for (; length>0; length--)
+ *tempr++ = vfbyte();
+ cmd = vfbyte();
+ } while (cmd < 243);
+ if (cmd != 248)
+ badvf("missing postamble");
+ close_vf:
+ fclose(vffile);
+ curfnt->loaded = 2;
+ if (maxcc+1<no_of_chars) {
+ curfnt->chardesc = (chardesctype *)
+ xrealloc(curfnt->chardesc,
+ (maxcc+1) * (integer)sizeof(chardesctype));
+ curfnt->maxchars=maxcc+1;
+ }
+ return (1);
+}