summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/loadfont.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
committerKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
commitad547a6b5986815fda458221149728d9d9ab1d87 (patch)
tree16296910eb3eca724371474ea9aea3994dc69614 /Build/source/texk/dvipsk/loadfont.c
parent947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff)
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipsk/loadfont.c')
-rw-r--r--Build/source/texk/dvipsk/loadfont.c535
1 files changed, 535 insertions, 0 deletions
diff --git a/Build/source/texk/dvipsk/loadfont.c b/Build/source/texk/dvipsk/loadfont.c
new file mode 100644
index 00000000000..f6d151dfd17
--- /dev/null
+++ b/Build/source/texk/dvipsk/loadfont.c
@@ -0,0 +1,535 @@
+/*
+ * Here's the code to load a PK file into memory.
+ * Individual bitmaps won't be unpacked until they prove to be needed.
+ */
+#include "dvips.h" /* The copyright notice in that file is included too! */
+#ifdef OS2
+#include <stdlib.h>
+#endif
+#ifdef KPATHSEA
+#include <kpathsea/c-pathmx.h>
+#include <kpathsea/concatn.h>
+#include <kpathsea/tex-glyph.h>
+#include <kpathsea/tex-make.h>
+#include <kpathsea/lib.h>
+#ifndef MAXPATHLEN
+#define MAXPATHLEN (256)
+#endif
+#else
+#if defined(SYSV) || defined(VMS) || (defined(MSDOS) && !defined(__DJGPP__)) || defined(OS2) || defined(ATARIST)
+#define MAXPATHLEN (256)
+#else
+#include <sys/param.h> /* for MAXPATHLEN */
+#endif
+#endif
+/*
+ * The external declarations:
+ */
+#include "protos_add.h"
+
+char errbuf[1500];
+int lastresortsizes[40];
+int bitmapfontseen = 0 ;
+/*
+ * Now we have some routines to get stuff from the PK file.
+ * Subroutine pkbyte returns the next byte.
+ */
+FILE *pkfile;
+char name[MAXPATHLEN];
+void
+badpk(const char *s)
+{
+ char *msg = concatn ("! Bad PK file ", name, ": ", s, NULL);
+ error(msg);
+}
+
+shalfword
+pkbyte(void)
+{
+ register shalfword i;
+
+ if ((i=getc(pkfile))==EOF)
+ badpk("unexpected eof");
+ return(i);
+}
+
+integer
+pkquad(void)
+{
+ register integer i;
+
+ i = pkbyte();
+ if (i > 127)
+ i -= 256;
+ i = i * 256 + pkbyte();
+ i = i * 256 + pkbyte();
+ i = i * 256 + pkbyte();
+ return(i);
+}
+
+integer
+pktrio(void)
+{
+ register integer i;
+
+ i = pkbyte();
+ i = i * 256 + pkbyte();
+ i = i * 256 + pkbyte();
+ return(i);
+}
+
+
+/*
+ * pkopen opens the pk file. This is system dependent. We work really
+ * hard to open some sort of PK file.
+ */
+#ifdef VMCMS /* IBM: VM/CMS - we let DVIPS EXEC handle this after
+ the DVIPS MODULE has finished to avoid
+ complications with system calls. */
+int dontmakefont = 0;
+#else
+#ifdef MVSXA /* IBM: MVS/XA - we let system administrator handle this on
+ MVS/XA since some printers can't get to user
+ fonts anyway */
+int dontmakefont = 1;
+#else
+int dontmakefont = 0; /* if makefont fails once we won't try again */
+#endif /* IBM: VM/CMS */
+#endif
+
+static void
+lectureuser(void) {
+ static int userwarned = 0;
+
+ if (! userwarned) {
+ error("Such scaling will generate extremely poor output.");
+ userwarned = 1;
+ }
+}
+static Boolean
+pkopen(register fontdesctype *fd)
+{
+ register char *d, *n;
+ const char *name_ret;
+#ifdef KPATHSEA
+ int dpi_ret;
+#else
+ int vdpi;
+#endif
+ d = fd->area;
+ n = fd->name;
+#ifndef KPATHSEA
+ if (*d==0)
+ d = pkpath;
+#endif
+#ifdef FONTLIB
+ if (*(fd->area) == 0) {
+ int del;
+ for (del=0; del<=RES_TOLERANCE(fd->dpi); del=del>0?-del:-del+1) {
+ if ((pkfile=flisearch(n, fd->dpi + del)) != (FILE *)NULL )
+ return(1);
+ }
+ }
+#endif
+ {
+#ifdef KPATHSEA
+ char *this_name = concat (d, n);
+
+ pkfile = pksearch(this_name, READBIN, fd->dpi, &name_ret, &dpi_ret);
+
+ if (!pkfile || !FILESTRCASEEQ (this_name, name_ret)) {
+ char *msg = concatn ("Font ", fd->area, n, " not found; ", NULL);
+ /* wasting some memory */
+ if (!pkfile)
+ msg = concat (msg, "characters will be left blank.");
+ else
+ msg = concat3 (msg, "using ", name_ret);
+ dontmakefont = 1;
+ error (msg);
+
+ } else if (!kpse_bitmap_tolerance ((double) dpi_ret, (double) fd->dpi))
+ {
+ fd->loadeddpi = dpi_ret;
+ fd->alreadyscaled = 0;
+ sprintf(errbuf,
+ "Font %s at %d not found; scaling %d instead.",
+ n, fd->dpi, dpi_ret);
+ error(errbuf);
+ lectureuser();
+ }
+
+ if (this_name != name_ret)
+ free (this_name);
+
+ return pkfile != NULL;
+ }
+#else
+ int del;
+ for (del=0; del<=RES_TOLERANCE(fd->dpi); del=del>0?-del:-del+1) {
+ if (actualdpi == vactualdpi) {
+ vdpi = 0;
+ } else {
+ vdpi = (2 * ((long)vactualdpi) * (fd->dpi + del) + actualdpi)
+ / (2 * actualdpi);
+ }
+#ifdef MVSXA
+ sprintf(name, "pk%d(%s)", fd->dpi + del, n);
+#else
+ sprintf(name, "%s.%dpk", n, fd->dpi + del);
+#endif
+ if (0 != (pkfile=pksearch(d, name, READBIN, n, fd->dpi + del, vdpi)))
+ return(1);
+ }
+ }
+ if (d == pkpath) {
+ if (actualdpi == vactualdpi) {
+ vdpi = 0;
+ } else {
+ vdpi = (2 * ((long)vactualdpi) * fd->dpi + actualdpi)
+ / (2 * actualdpi);
+ }
+#ifdef MVSXA
+ sprintf(name, "pk%d(%s)", fd->dpi, n);
+#else
+ sprintf(name, "%s.%dpk", n, fd->dpi);
+#endif
+ makefont(n, (int)fd->dpi, DPI);
+ if (dontmakefont == 0 &&
+ (pkfile = pksearch(d, name, READBIN, n, fd->dpi, vdpi)))
+ return(1);
+#ifndef MSDOS
+#ifdef OS2
+ if (_osmode == OS2_MODE)
+ dontmakefont = 1; /* failed so don't try again under OS/2,
+ but do try for MSDOS */
+#else
+#ifndef ATARIST
+ dontmakefont = 1;
+#endif
+#endif
+#endif
+ }
+/*
+ * If nothing above worked, then we get desparate. We attempt to
+ * open the stupid font at one of a small set of predefined sizes,
+ * and then use PostScript scaling to generate the correct size.
+ *
+ * We much prefer scaling up to scaling down, since scaling down
+ * can omit character features, so we try the larger sizes first,
+ * and then work down.
+ */
+ {
+ int i, j;
+
+ if (lastresortsizes[0] && fd->dpi < 30000) {
+ for (i=0; lastresortsizes[i] < fd->dpi; i++);
+ for (j = i-1; j >= 0; j--) {
+ if (actualdpi == vactualdpi) {
+ vdpi = 0;
+ } else {
+ vdpi = (2 * ((long)vactualdpi) * lastresortsizes[j] + actualdpi)
+ / (2 * actualdpi);
+ }
+#ifdef MVSXA
+ sprintf(name, "pk%d(%s)", lastresortsizes[j], n);
+#else
+ sprintf(name, "%s.%dpk", n, lastresortsizes[j]);
+#endif
+#ifdef FONTLIB
+ if (0 != (pkfile=flisearch(n,(halfword)lastresortsizes[j]))
+ || 0 != (pkfile=pksearch(d, name, READBIN, n,
+ (halfword)lastresortsizes[j], vdpi))) {
+#else
+ if (0 != (pkfile=pksearch(d, name, READBIN, n,
+ (halfword)lastresortsizes[j], vdpi))) {
+#endif
+ fd->loadeddpi = lastresortsizes[j];
+ fd->alreadyscaled = 0;
+ sprintf(errbuf,
+ "Font %s at %d dpi not found; scaling %d instead.",
+ n, fd->dpi, lastresortsizes[j]);
+ error(errbuf);
+ lectureuser();
+ return 1;
+ }
+ }
+ for (j = i; lastresortsizes[j] < 30000; j++) {
+ if (actualdpi == vactualdpi) {
+ vdpi = 0;
+ } else {
+ vdpi = (2 * ((long)vactualdpi) * lastresortsizes[j] + actualdpi)
+ / (2 * actualdpi);
+ }
+ sprintf(name, "%s.%dpk", n, lastresortsizes[j]);
+#ifdef FONTLIB
+ if (0 != (pkfile=flisearch(n, (halfword)lastresortsizes[j]))
+ || 0 != (pkfile=pksearch(d, name, READBIN, n,
+ (halfword)lastresortsizes[j], vdpi))) {
+#else
+ if (0 != (pkfile=pksearch(d, name, READBIN, n,
+ (halfword)lastresortsizes[j], vdpi))) {
+#endif
+ fd->loadeddpi = lastresortsizes[j];
+ fd->alreadyscaled = 0;
+ sprintf(errbuf,
+ "Font %s at %d dpi not found; scaling %d instead.",
+ name, fd->dpi, lastresortsizes[j]);
+ error(errbuf);
+ lectureuser();
+ return 1;
+ }
+ }
+ }
+ }
+#ifdef MVSXA
+ sprintf(name, "%s.pk%d", n, fd->dpi);
+#else
+ sprintf(name, "%s.%dpk", n, fd->dpi);
+#endif
+ sprintf(errbuf,
+ "Font %s%s not found, characters will be left blank.",
+ fd->area, name);
+ error(errbuf);
+ return(0);
+#endif /* KPATHSEA */
+}
+
+/*
+ * Now our loadfont routine. We return an integer indicating the
+ * highest character code in the font, so we know how much space
+ * to reserve for the character. (It's returned in the font
+ * structure, along with everything else.)
+ */
+void
+loadfont(register fontdesctype *curfnt)
+{
+ register integer i;
+ register shalfword cmd;
+ register integer k;
+ register integer length = 0;
+ register shalfword cc = 0;
+ register integer scaledsize = curfnt->scaledsize;
+ register quarterword *tempr;
+ register chardesctype *cd = 0;
+ int maxcc = 0;
+ int munged = 0;
+/*
+ * We clear out some pointers:
+ */
+ if (curfnt->loaded == 3) {
+ for (i=0; i<256; i++) {
+ curfnt->chardesc[i].TFMwidth = 0;
+ curfnt->chardesc[i].packptr = NULL;
+ curfnt->chardesc[i].pixelwidth = 0;
+ curfnt->chardesc[i].flags &= EXISTS;
+ curfnt->chardesc[i].flags2 = 0;
+ }
+ } else {
+ for (i=0; i<256; 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;
+ }
+ }
+ curfnt->maxchars = 256; /* just in case we return before the end */
+ curfnt->llx = 0 ;
+ curfnt->lly = 0 ;
+ curfnt->urx = 0 ;
+ curfnt->ury = 0 ;
+ if (!pkopen(curfnt)) {
+ tfmload(curfnt);
+ return;
+ }
+ bitmapfontseen = 1 ;
+ curfnt->dir = 0;
+ if (!quiet) {
+ if (strlen(realnameoffile) + prettycolumn > STDOUTSIZE) {
+ fprintf(stderr, "\n");
+ prettycolumn = 0;
+ }
+ fprintf_str(stderr, "<%s>", realnameoffile);
+ prettycolumn += strlen(realnameoffile) + 2;
+ }
+#ifdef DEBUG
+ if (dd(D_FONTS))
+ fprintf_str(stderr,"Loading pk font %s at %.1fpt\n",
+ curfnt->name, (real)scaledsize/(alpha*0x100000));
+#endif /* DEBUG */
+ if (pkbyte()!=247)
+ badpk("expected pre");
+ if (pkbyte()!=89)
+ badpk("wrong id byte");
+ for(i=pkbyte(); i>0; i--)
+ pkbyte();
+ k = (integer)(alpha * (real)pkquad());
+ if (k > curfnt->designsize + fsizetol
+ || k < curfnt->designsize - fsizetol) {
+ char *msg = concat ("Design size mismatch in font ", curfnt->name);
+ error (msg);
+ free (msg);
+ }
+ k = pkquad();
+ if (k && curfnt->checksum)
+ if (k!=curfnt->checksum) {
+ char *msg = concat ("Checksum mismatch in font ", curfnt->name);
+ error (msg);
+ free (msg);
+ }
+ k = pkquad(); /* assume that hppp is correct in the PK file */
+ k = pkquad(); /* assume that vppp is correct in the PK file */
+/*
+ * Now we get down to the serious business of reading character definitions.
+ */
+ while ((cmd=pkbyte())!=245) {
+ if (cmd < 240) {
+ switch (cmd & 7) {
+case 0: case 1: case 2: case 3:
+ length = (cmd & 7) * 256 + pkbyte() - 3;
+ cc = pkbyte();
+ cd = curfnt->chardesc+cc;
+ if (nosmallchars || curfnt->dpi != curfnt->loadeddpi)
+ cd->flags |= BIGCHAR;
+ cd->TFMwidth = scalewidth(pktrio(), scaledsize);
+ cd->pixelwidth = pkbyte();
+ break;
+case 4: case 5: case 6:
+ length = (cmd & 3) * 65536L + pkbyte() * 256L;
+ length = length + pkbyte() - 4L;
+ cc = pkbyte();
+ cd = curfnt->chardesc+cc;
+ cd->TFMwidth = scalewidth(pktrio(), scaledsize);
+ cd->flags |= BIGCHAR;
+ i = pkbyte();
+ cd->pixelwidth = i * 256 + pkbyte();
+ break;
+case 7:
+ length = pkquad() - 11;
+ cc = pkquad();
+ if (cc<0 || cc>255) badpk("character code out of range");
+ cd = curfnt->chardesc + cc;
+ cd->flags |= BIGCHAR;
+ cd->TFMwidth = scalewidth(pkquad(), scaledsize);
+ cd->pixelwidth = (pkquad() + 32768) >> 16;
+ k = pkquad();
+ }
+ if (cd->pixelwidth == 0 && cd->TFMwidth != 0) {
+ if (cd->TFMwidth > 0)
+ k = (integer)(cd->TFMwidth * conv + 0.5);
+ else
+ k = -(integer)(-cd->TFMwidth * conv + 0.5);
+ if (k != 0) {
+ cd->pixelwidth = k;
+ munged++;
+ }
+ }
+ if (length <= 0)
+ badpk("packet length too small");
+ if (dopprescan && ((cd->flags & EXISTS) == 0)) {
+ for (length--; length>0; length--)
+ pkbyte();
+ } else {
+ if (cc > maxcc)
+ maxcc = cc;
+ if (bytesleft < length || (length > MINCHUNK && compressed)) {
+#ifdef DEBUG
+ if (dd(D_MEM))
+ fprintf(stderr,
+#ifdef SHORTINT
+ "Allocating new raster memory (%ld req, %ld left)\n",
+ length, bytesleft);
+#else
+ "Allocating new raster memory (%d req, %d left)\n",
+ (int)length, (int)bytesleft);
+#endif
+#endif /* DEBUG */
+ if (length > MINCHUNK) {
+ tempr = (quarterword *)mymalloc((integer)length);
+ } else {
+ raster = (quarterword *)mymalloc((integer)RASTERCHUNK);
+ tempr = raster;
+ bytesleft = RASTERCHUNK - length;
+ raster += length;
+ }
+ } else {
+ tempr = raster;
+ bytesleft -= length;
+ raster += length;
+ }
+ cd->packptr = tempr;
+ *tempr++ = cmd;
+ for (length--; length>0; length--)
+ *tempr++ = pkbyte();
+ {
+ // update the global font bounding box
+ // this is only used to set font sizes for type 3 bitmap
+ // encoding.
+ integer cwidth, cheight, xoff, yoff ;
+ unpack_bb(cd, &cwidth, &cheight, &xoff, &yoff) ;
+ if (-xoff < curfnt->llx)
+ curfnt->llx = -xoff ;
+ if (cwidth - xoff > curfnt->urx)
+ curfnt->urx = cwidth - xoff ;
+ if (yoff - cheight < curfnt->lly)
+ curfnt->lly = yoff - cheight ;
+ if (yoff > curfnt->ury)
+ curfnt->ury = yoff ;
+ }
+ }
+ cd->flags2 |= EXISTS;
+ } else {
+ k = 0;
+ switch (cmd) {
+case 243:
+ k = pkbyte();
+ if (k > 127)
+ k -= 256;
+case 242:
+ k = k * 256 + pkbyte();
+case 241:
+ k = k * 256 + pkbyte();
+case 240:
+ k = k * 256 + pkbyte();
+ while (k-- > 0)
+ i = pkbyte();
+ break;
+case 244:
+ k = pkquad();
+ break;
+case 246:
+ break;
+default:
+ badpk("! unexpected command");
+ }
+ }
+ }
+#ifdef FONTLIB
+ if (flib)
+ flib = 0;
+ else
+#endif
+ fclose(pkfile);
+ curfnt->loaded = 1;
+ curfnt->maxchars = maxcc + 1;
+ if (munged > 0) {
+ static int seen = 0;
+ sprintf(errbuf,
+ "Font %s at %d dpi has most likely been made improperly;",
+ curfnt->name, curfnt->dpi);
+ error(errbuf);
+ if (seen)
+ return;
+ seen = 1;
+ sprintf(errbuf,
+ "%d characters have 0 escapements but non-trivial TFM widths.", munged);
+ error(errbuf);
+ error(
+ "I'm stumbling along as best I can, but I recommend regenerating");
+ error(
+ "these fonts; the problem is probably that they are non-CM fonts");
+ error(
+ "(such as circle10 or line10) created with a MF with the CM base");
+ error("preloaded .");
+ }
+}