diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/dvipsk/download.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipsk/download.c')
-rw-r--r-- | Build/source/texk/dvipsk/download.c | 562 |
1 files changed, 562 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..c7d6c0eab9f --- /dev/null +++ b/Build/source/texk/dvipsk/download.c @@ -0,0 +1,562 @@ +/* + * 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 +/* + * These are the external routines we call. + */ +#include "protos.h" +/* + * These are the external variables we access. + */ +extern char *nextstring, *infont ; +extern FILE *bitfile ; +extern fontdesctype *curfnt ; +extern long bytesleft ; +extern long mbytesleft ; +extern quarterword *raster ; +extern quarterword *mraster ; +extern Boolean compressed ; +extern Boolean partialdownload ; +extern double mag ; +extern int actualdpi ; +static unsigned char dummyend[8] = { 252 } ; +extern int prettycolumn ; +extern int quiet ; +extern Boolean disablecomments ; +extern real conv ; + +/* + * We have a routine that downloads an individual character. + */ +static int lastccout ; +void downchar P2C(chardesctype *, c, shalfword, cc) +{ + register long i, j ; + register halfword cheight, cwidth ; + register long k ; + register quarterword *p ; + register halfword cmd ; + register shalfword xoff, yoff ; + halfword wwidth = 0 ; + register long len ; + int smallchar ; + + p = c->packptr ; + 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] ; /* N.B.: xoff, yoff are signed halfwords */ + yoff = p[6] * 256 + p[7] ; + p += 8 ; + } + } else { + cwidth = *p++ ; + cheight = *p++ ; + xoff = *p++ ; + yoff = *p++ ; + if (xoff > 127) + xoff -= 256 ; + if (yoff > 127) + yoff -= 256 ; + } + 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 P2C(register char *, s, register int, n) +{ + n-- ; + *s++ = 'F' + n / (sizeof(goodnames)-1) ; + *s++ = goodnames[n % (sizeof(goodnames)-1)] ; + *s++ = 0 ; +} +void +lfontout P1C(int, n) +{ + char buf[10]; + char *b = buf ; + *b++ = '/' ; + makepsname(b, n) ; + cmdout(buf); +} + +/* + * And the download procedure. + */ +void download P2C(charusetype *, p, int, psfont) +{ + 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->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 ; + (void)sprintf(nextstring, "%g", fontscale) ; + cmdout(nextstring) ; + (void)strcpy(nextstring, "/") ; + (void)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) ; + 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, cc) ; + c->flags |= EXISTS ; + } else + c->flags &= ~EXISTS ; + c++ ; + cc++ ; + } + } + cmdout("E") ; + newline() ; + fprintf(bitfile, "%%EndDVIPSBitmapFont\n") ; +} +/* + * 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 ; + char *name ; + char **glyphs ; +} *seenEncodings ; +#define MAX_CHAR_CODE 256 +/* + * 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) { + int i ; + p = (struct seenEncodings *)mymalloc(sizeof(struct seenEncodings)) ; + p->next = seenEncodings ; + seenEncodings = p ; + p->name = xstrdup(encoding) ; + p->glyphs = (char **)mymalloc((MAX_CHAR_CODE+1) * sizeof(char *)) ; + for (i=0; i<MAX_CHAR_CODE; i++) + p->glyphs[i] = ".notdef" ; + load_enc(encoding, p->glyphs) ; + } + 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 ; +#ifdef DOWNLOAD_USING_PDFTEX +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() { + 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(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. + */ +void downpsfont P2C(charusetype *, p, charusetype *, all) +{ +#ifdef DOWNLOAD_USING_PDFTEX + static unsigned char grid[256]; +#endif + int GridCount ; + register int b; + register halfword bit ; + register chardesctype *c ; + struct resfont *rf ; + int cc; + + 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 ; + 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 || extraGlyphs) { + if (!quiet) { + if (strlen(rf->Fontfile) + prettycolumn > STDOUTSIZE) { + fprintf(stderr, "\n") ; + prettycolumn = 0 ; + } + (void)fprintf(stderr, "<%s>", rf->Fontfile); + prettycolumn += strlen(rf->Fontfile) + 2 ; + } + newline() ; + if (! disablecomments) + (void)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 (! disablecomments) + (void)fprintf(bitfile, "%%%%EndFont \n"); + } +} + +void dopsfont P1C(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 +} |