summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/download.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipsk/download.c')
-rw-r--r--Build/source/texk/dvipsk/download.c572
1 files changed, 572 insertions, 0 deletions
diff --git a/Build/source/texk/dvipsk/download.c b/Build/source/texk/dvipsk/download.c
new file mode 100644
index 00000000000..54718ce2adf
--- /dev/null
+++ b/Build/source/texk/dvipsk/download.c
@@ -0,0 +1,572 @@
+/*
+ * Code to download a font definition at the beginning of a section.
+ * hacked by SPQR 8.95 to allow for non-partial downloading
+ *
+ */
+#include "dvips.h" /* The copyright notice in that file is included too! */
+#ifndef DOWNLOAD_USING_PDFTEX
+#define DOWNLOAD_USING_PDFTEX
+#endif
+#ifndef DOWNLOAD_USING_PDFTEX
+#include "t1part.h"
+#endif
+#define DVIPS
+/*
+ * The external declarations:
+ */
+#include "protos.h"
+
+static unsigned char dummyend[8] = { 252 };
+
+/*
+ * We have a routine that downloads an individual character.
+ */
+static int lastccout;
+quarterword *unpack_bb(chardesctype *c, integer *cwidth, integer *cheight,
+ integer *xoff, integer *yoff) {
+ quarterword *p = c->packptr;
+ halfword cmd = *p++;
+ if (cmd & 4) {
+ if ((cmd & 7) == 7) {
+ *cwidth = getlong(p);
+ *cheight = getlong(p + 4);
+ *xoff = getlong(p + 8);
+ *yoff = getlong(p + 12);
+ p += 16;
+ } else {
+ *cwidth = p[0] * 256 + p[1];
+ *cheight = p[2] * 256 + p[3];
+ *xoff = p[4] * 256 + p[5];
+ if (*xoff > 32767)
+ *xoff -= 65536 ;
+ *yoff = p[6] * 256 + p[7];
+ if (*xoff > 32767)
+ *xoff -= 65536 ;
+ p += 8;
+ }
+ } else {
+ *cwidth = *p++;
+ *cheight = *p++;
+ *xoff = *p++;
+ *yoff = *p++;
+ if (*xoff > 127)
+ *xoff -= 256;
+ if (*yoff > 127)
+ *yoff -= 256;
+ }
+ return p ;
+}
+static void
+downchar(chardesctype *c, shalfword cc)
+{
+ register long i, j;
+ integer cheight, cwidth;
+ register long k;
+ register quarterword *p;
+ register halfword cmd;
+ integer xoff, yoff;
+ halfword wwidth = 0;
+ register long len;
+ int smallchar;
+
+ cmd = *(c->packptr) ;
+ p = unpack_bb(c, &cwidth, &cheight, &xoff, &yoff) ;
+ if (c->flags & BIGCHAR)
+ smallchar = 0;
+ else
+ smallchar = 5;
+ if (compressed) {
+ len = getlong(p);
+ p += 4;
+ } else {
+ wwidth = (cwidth + 15) / 16;
+ i = 2 * cheight * (long)wwidth;
+ if (i <= 0)
+ i = 2;
+ i += smallchar;
+ if (mbytesleft < i) {
+ if (mbytesleft >= RASTERCHUNK)
+ (void) free((char *) mraster);
+ if (RASTERCHUNK > i) {
+ mraster = (quarterword *)mymalloc((integer)RASTERCHUNK);
+ mbytesleft = RASTERCHUNK;
+ } else {
+ k = i + i / 4;
+ mraster = (quarterword *)mymalloc((integer)k);
+ mbytesleft = k;
+ }
+ }
+ k = i;
+ while (k > 0)
+ mraster[--k] = 0;
+ unpack(p, (halfword *)mraster, cwidth, cheight, cmd);
+ p = mraster;
+ len = i - smallchar;
+ }
+ if (cheight == 0 || cwidth == 0 || len == 0) {
+ cwidth = 1;
+ cheight = 1;
+ wwidth = 1;
+ len = 2;
+ if (compressed)
+ p = dummyend; /* CMD(END); see repack.c */
+ else
+ mraster[0] = 0;
+ }
+ if (smallchar) {
+ p[len] = cwidth;
+ p[len + 1] = cheight;
+ p[len + 2] = xoff + 128;
+ p[len + 3] = yoff + 128;
+ p[len + 4] = c->pixelwidth;
+ } else
+/*
+ * Now we actually send out the data.
+ */
+ specialout('[');
+ if (compressed) {
+ specialout('<');
+ mhexout(p, len + smallchar);
+ specialout('>');
+ } else {
+ i = (cwidth + 7) / 8;
+ if (i * cheight > 65520) {
+ long bc = 0;
+ specialout('<');
+ for (j=0; j<cheight; j++) {
+ if (bc + i > 65520) {
+ specialout('>');
+ specialout('<');
+ bc = 0;
+ }
+ mhexout(p, i);
+ bc += i;
+ p += 2*wwidth;
+ }
+ specialout('>');
+ } else {
+ specialout('<');
+ if (2 * wwidth == i)
+ mhexout(p, ((long)cheight) * i + smallchar);
+ else {
+ for (j=0; j<cheight; j++) {
+ mhexout(p, i);
+ p += 2*wwidth;
+ }
+ if (smallchar)
+ mhexout(p, (long)smallchar);
+ }
+ specialout('>');
+ }
+ }
+ if (smallchar == 0) {
+ numout((integer)cwidth);
+ numout((integer)cheight);
+ numout((integer)xoff + 128); /* not all these casts needed. */
+ numout((integer)yoff + 128);
+ numout((integer)(c->pixelwidth));
+ }
+ if (lastccout + 1 == cc) {
+ cmdout("I");
+ } else {
+ numout((integer)cc);
+ cmdout("D");
+ }
+ lastccout = cc;
+}
+/*
+ * Output the literal name of the font change command with PostScript index n
+ */
+static char goodnames[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+void
+makepsname(register char *s, register int n)
+{
+ n--;
+ *s++ = 'F' + n / (sizeof(goodnames)-1);
+ *s++ = goodnames[n % (sizeof(goodnames)-1)];
+ *s++ = 0;
+}
+void
+lfontout(int n)
+{
+ char buf[10];
+ char *b = buf;
+ *b++ = '/';
+ makepsname(b, n);
+ cmdout(buf);
+}
+
+/*
+ * And the download procedure.
+ */
+void
+download(charusetype *p, int psfont)
+{
+ double scale;
+ int seq;
+ register int b, i;
+ register halfword bit;
+ register chardesctype *c;
+ int cc, maxcc = -1, numcc;
+ double fontscale;
+ char name[10];
+ lastccout = -5;
+ name[0] = '/';
+ makepsname(name + 1, psfont);
+ curfnt = p->fd;
+ curfnt->psname = psfont;
+ if (curfnt->resfont) {
+ struct resfont *rf = curfnt->resfont;
+ int non_empty=0;
+ for (b=0; b<16; b++)
+ if(p->bitmap[b] !=0)
+ non_empty =1;
+ if(non_empty==0 && curfnt->iswide == 0 && curfnt->codewidth==1)
+ return;
+ cmdout(name);
+/* following code re-arranged - Rob Hutchings 1992Apr02 */
+ c = curfnt->chardesc + 255;
+ cc = 255;
+ numcc = 0;
+ i = 0;
+ for (b=15; b>=0; b--) {
+ for (bit=1; bit; bit<<=1) {
+ if (p->bitmap[b] & bit) {
+ if (i > 0) {
+ numout((integer)i);
+ specialout('[');
+ i = 0;
+ }
+ numout((integer)c->pixelwidth);
+ c->flags |= EXISTS;
+ numcc++;
+ } else {
+ i++;
+ c->flags &= ~EXISTS;
+ }
+ c--;
+ cc--;
+ }
+ }
+ if (i > 0) {
+ numout((integer)i);
+ specialout('[');
+ }
+ specialout ('{');
+ if (rf->specialinstructions)
+ cmdout(rf->specialinstructions);
+ specialout ('}');
+ numout((integer)numcc);
+ /*
+ * This code has been bogus for a long time. The fix is
+ * straightforward. The input, curfnt->scaledsize, is the
+ * desired size of the font in dvi units. The output is the
+ * fontscale, which is the height of the font in output units
+ * which are simply pixels. Thus, all we need to do is multiply
+ * by the default generic conv, which properly takes into
+ * account magnification, num/den, output resolution, and so on.
+ * Sorry this bug has been in here so long. -tgr
+ */
+ fontscale = curfnt->scaledsize * conv;
+ sprintf(nextstring, "%g", fontscale);
+ cmdout(nextstring);
+ strcpy(nextstring, "/");
+ strcat(nextstring, rf->PSname);
+ cmdout(nextstring);
+/* end of changed section - Rob */
+ cmdout("rf");
+ rf->sent = 1;
+ return;
+ }
+/*
+ * Here we calculate the largest character actually used, and
+ * send it as a parameter to df.
+ */
+ cc = 0;
+ numcc = 0;
+ for (b=0; b<16; b++) {
+ for (bit=32768; bit!=0; bit>>=1) {
+ if (p->bitmap[b] & bit) {
+ maxcc = cc;
+ numcc++;
+ }
+ cc++;
+ }
+ }
+ if (numcc <= 0)
+ return;
+ fontscale = ((double)(curfnt->scaledsize)) / 65536.0;
+ fontscale *= (mag/1000.0);
+ newline();
+ fprintf(bitfile, "%%DVIPSBitmapFont: %s %s %g %d\n", name+1, curfnt->name,
+ fontscale, numcc);
+ scale = fontscale * DPI / 72.0 ;
+ seq = -1 ;
+ if (encodetype3)
+ seq = downloadbmencoding(curfnt->name, scale, curfnt) ;
+ cmdout(name);
+ numout((integer)numcc);
+ numout((integer)maxcc + 1);
+/*
+ * If we need to scale the font, we say so by using dfs
+ * instead of df, and we give it a scale factor. We also
+ * scale the character widths; this is ugly, but scaling
+ * fonts is ugly, and this is the best we can probably do.
+ */
+ if (curfnt->dpi != curfnt->loadeddpi) {
+ numout((integer)curfnt->dpi);
+ numout((integer)curfnt->loadeddpi);
+ if (curfnt->alreadyscaled == 0) {
+ for (b=0, c=curfnt->chardesc; b<256; b++, c++)
+ c->pixelwidth = (c->pixelwidth *
+ (long)curfnt->dpi * 2 + curfnt->loadeddpi) / (2 * curfnt->loadeddpi);
+ curfnt->alreadyscaled = 1;
+ }
+ cmdout("dfs");
+ } else
+ cmdout("df");
+ c = curfnt->chardesc;
+ cc = 0;
+ for (b=0; b<16; b++) {
+ for (bit=32768; bit; bit>>=1) {
+ if (p->bitmap[b] & bit) {
+ downchar(c, (shalfword)cc);
+ c->flags |= EXISTS;
+ } else
+ c->flags &= ~EXISTS;
+ c++;
+ cc++;
+ }
+ }
+ cmdout("E");
+ newline() ;
+ if (seq >= 0)
+ finishbitmapencoding(name, scale) ;
+ fprintf(bitfile, "%%EndDVIPSBitmapFont\n");
+}
+
+#ifdef DOWNLOAD_USING_PDFTEX
+/*
+ * Magic code to deal with PostScript font partial downloading.
+ * We track the encodings we've seen so far and keep them in these
+ * structures. We rely on writet1 to load the encodings for us.
+ */
+static struct seenEncodings {
+ struct seenEncodings *next;
+ const char *name;
+ char **glyphs;
+} *seenEncodings;
+
+/*
+ * Load a new encoding and return the array of glyphs as a vector.
+ * Linear search.
+ */
+static char **getEncoding(char *encoding) {
+ struct seenEncodings *p = seenEncodings;
+ while (p != 0)
+ if (strcmp(encoding, p->name) == 0)
+ break;
+ else
+ p = p->next;
+ if (p == 0) {
+ p = (struct seenEncodings *)mymalloc(sizeof(struct seenEncodings));
+ p->next = seenEncodings;
+ seenEncodings = p;
+ p->name = xstrdup(encoding);
+ p->glyphs = load_enc_file(encoding);
+ }
+ return p->glyphs;
+}
+/*
+ * When partially downloading a type 1 font, sometimes the font uses
+ * the built-in encoding (which we don't know at this point) so we want
+ * to subset it by character code. Sometimes the font uses a different
+ * encoding, so we want to subset it by glyph. These routines manage
+ * accumulating all the glyph names for a particular font from all
+ * the various uses into a single, slash-delimited string for writet1().
+ *
+ * If no glyphs have been added, extraGlyphs is null. In all cases,
+ * the memory allocated for this is in extraGlyphSpace.
+ */
+static char *extraGlyphs = 0;
+static char *extraGlyphSpace = 0;
+static int extraGlyphSize = 0;
+static int glyphSizeUsed = 0;
+/*
+ * We want to make sure we pass in null or "/" but never "".
+ */
+static void clearExtraGlyphList(void) {
+ glyphSizeUsed = 0;
+ extraGlyphs = 0;
+}
+/*
+ * Add the glyph name; make sure it hasn't been added already.
+ * We do this by adding it, so we can get the // around it,
+ * and *then* see if it's already there and if it is un-add it.
+ */
+static void addGlyph(const char *glyphName) {
+ int len = strlen(glyphName);
+ char *startOfAdd = 0;
+ if (len + glyphSizeUsed + 3 > extraGlyphSize) {
+ extraGlyphSize = 2 * (extraGlyphSize + len + 100);
+ extraGlyphSpace = (char *) xrealloc(extraGlyphSpace, extraGlyphSize);
+ }
+ extraGlyphs = extraGlyphSpace;
+ if (glyphSizeUsed == 0) {
+ startOfAdd = extraGlyphs + glyphSizeUsed;
+ extraGlyphs[glyphSizeUsed++] = '/'; /* leading / */
+ } else {
+ startOfAdd = extraGlyphs + glyphSizeUsed - 1;
+ }
+ strcpy(extraGlyphs + glyphSizeUsed, glyphName);
+ glyphSizeUsed += len;
+ extraGlyphs[glyphSizeUsed++] = '/'; /* trailing / */
+ extraGlyphs[glyphSizeUsed] = 0;
+ if (strstr(extraGlyphs, startOfAdd) != startOfAdd) { /* already there! */
+ glyphSizeUsed = startOfAdd - extraGlyphs + 1; /* kill the second copy */
+ extraGlyphs[glyphSizeUsed] = 0;
+ }
+}
+#endif
+
+/*
+ * Download a PostScript font, using partial font downloading if
+ * necessary.
+ */
+static void
+downpsfont(charusetype *p, charusetype *all)
+{
+ static unsigned char grid[256];
+ int GridCount;
+ register int b;
+ register halfword bit;
+ register chardesctype *c;
+ struct resfont *rf;
+ int cc;
+ int j;
+
+ curfnt = p->fd;
+ rf = curfnt->resfont;
+ if (rf == 0 || rf->Fontfile == NULL)
+ return;
+ for (; all->fd; all++)
+ if (all->fd->resfont &&
+ strcmp(rf->PSname, all->fd->resfont->PSname) == 0)
+ break;
+ if (all != p)
+ return;
+ if (rf->sent == 2) /* sent as header, from a PS file */
+ return;
+ for (j=0; downloadedpsnames[j] && j < unused_top_of_psnames; j++) {
+ if (strcmp (downloadedpsnames[j], rf->PSname) == 0)
+ return;
+ }
+ if (all->fd == 0)
+ error("! internal error in downpsfont");
+ if (!partialdownload) {
+ infont = all->fd->resfont->PSname;
+ copyfile(all->fd->resfont->Fontfile);
+ infont = 0;
+ return;
+ }
+ for (cc=0; cc<256; cc++)
+ grid[cc] = 0;
+#ifdef DOWNLOAD_USING_PDFTEX
+ clearExtraGlyphList();
+#endif
+ for (; all->fd; all++) {
+ if (all->fd->resfont == 0 ||
+ strcmp(rf->PSname, all->fd->resfont->PSname))
+ continue;
+ curfnt = all->fd;
+#ifdef DOWNLOAD_USING_PDFTEX
+ if (curfnt->resfont->Vectfile) {
+ char **glyphs = getEncoding(curfnt->resfont->Vectfile);
+ c = curfnt->chardesc + 255;
+ cc = 255;
+ for (b=15; b>=0; b--) {
+ for (bit=1; bit; bit<<=1) {
+ if (all->bitmap[b] & bit) {
+ addGlyph(glyphs[cc]);
+ }
+ c--;
+ cc--;
+ }
+ }
+ } else {
+#endif
+ c = curfnt->chardesc + 255;
+ cc = 255;
+ for (b=15; b>=0; b--) {
+ for (bit=1; bit; bit<<=1) {
+ if (all->bitmap[b] & bit) {
+ grid[cc]=1;
+ }
+ c--;
+ cc--;
+ }
+ }
+#ifdef DOWNLOAD_USING_PDFTEX
+ }
+#endif
+ }
+
+ for (GridCount=0,cc=0; cc<256; cc++) {
+/* tmpgrid[cc]=grid[cc]; */
+ if(grid[cc] ==1) {
+ GridCount++;
+ }
+ }
+ if(GridCount!=0
+#ifdef DOWNLOAD_USING_PDFTEX
+ || extraGlyphs
+#endif
+ ) {
+ newline();
+ if (! disablecomments)
+ fprintf(bitfile, "%%%%BeginFont: %s\n", rf->PSname);
+#ifdef DOWNLOAD_USING_PDFTEX
+ if (!t1_subset_2(rf->Fontfile, grid, extraGlyphs))
+#else
+ if(FontPart(bitfile, rf->Fontfile, rf->Vectfile) < 0)
+#endif
+ exit(1);
+ if (!quiet) {
+ if (strlen(realnameoffile) + prettycolumn > STDOUTSIZE) {
+ fprintf(stderr, "\n");
+ prettycolumn = 0;
+ }
+ fprintf_str(stderr, "<%s>", realnameoffile);
+ prettycolumn += strlen(realnameoffile) + 2;
+ }
+ if (! disablecomments)
+ fprintf(bitfile, "%%%%EndFont \n");
+ }
+}
+
+void
+dopsfont(sectiontype *fs)
+{
+ charusetype *cu;
+
+ cu = (charusetype *) (fs + 1);
+#ifdef DOWNLOAD_USING_PDFTEX
+ while (cu->fd) {
+ if (cu->psfused)
+ cu->fd->psflag = EXISTS;
+ downpsfont(cu++, (charusetype *)(fs + 1));
+ }
+#else
+ line = getmem(BUFSIZ);
+ tmpline=line;
+ while (cu->fd) {
+ if (cu->psfused)
+ cu->fd->psflag = EXISTS;
+ downpsfont(cu++, (charusetype *)(fs + 1));
+ }
+ loadbase = ~FLG_LOAD_BASE;
+ FirstCharB=UnDefineChars(FirstCharB);
+ free(tmpline);
+#endif
+}