summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/download.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/dvipsk/download.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/dvipsk/download.c')
-rw-r--r--Build/source/texk/dvipsk/download.c562
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
+}