|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 17355 (0x43cb) Types: TextFile Names: »pdr.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/dvitps/src/pdr.c«
/* Copyright 1988 Stephan v. Bechtolsheim */ /* This file is part of the TeXPS Software Package. The TeXPS Software Package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the TeXPS Software Package General Public License for full details. Everyone is granted permission to copy, modify and redistribute the TeXPS Software Package, but only under the conditions described in the TeXPS Software Package General Public License. A copy of this license is supposed to have been given to you along with TeXPS Software Package so you can know your rights and responsibilities. It should be in a file named CopyrightLong. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* * All code which sets up PS fonts: read in pdr file, compute * font matrix etc. */ /* * Debug switches: * DEBUG_VM: VM (virtual memory) debug */ #include <stdio.h> #if SYS_V == 1 #include <string.h> #else #include <strings.h> #endif #include "defs.h" #include "units.h" #include "dvitps.h" #include "extfil.h" #include "fontd.h" #include "pdr.h" #include "emit.h" /* External declarations library. */ extern char *Malloc(); extern char *StrcpyAlloc(); extern char *GetBytes(); /* Other external declarations. */ extern void HandleCheckSum(); extern void PsDownLoad(); extern int Resolution; extern int HConvUnMag; extern int HConv; extern int CurFontNumber; extern FE_P Fonts[MAX_FONTS]; extern int FontsMissing; extern FE_P CurFontPointer; extern int DriverMag; extern int SmallPsVectors; extern EX_FILES Ex_PsOutput; int WidthVectors = TRUE; /* Download width vectors for PS fonts ? */ /* * ReadPdrFileInfo * *************** * Read in the information from the pdr file. * All the information will be read in, no later loading of any information * will occur. No caching therefore. */ void ReadPdrFileInfo() { double mfac; /* Factor to compute the Postscript matrix */ int le; /* Length of basename */ int i; /* Loop counter */ PDR_P p; CE_P ce; int index; /* Index into the character array for the current font */ double use_size_point; /* Usage size of the font in points */ char buffer[256]; int t; int check_sum; /* Check sum read from .pdr file. */ int tfm; /* Tfm width read from .pdr file. */ /* Open pdr file (not cached), check on correct file id, allocate * structure for pdr file data and insert into * font structure, read basename, append '\0' to it. */ FExOpen (&(CurFontPointer->f_ex_file), EFT_READ, EFQ_NO_STDIN | EFQ_CACHE | EFQ_FILE_NAME_LOADED, NULL, NULL); if ((t=NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2)) != PDR_FILE_ID) Fatal4 ("ReadPdrFileInfo(): illegal PDR_FILE_ID [%s], read: %d, expected: %d", CurFontPointer->f_ex_file.ef_fn, t, PDR_FILE_ID); p = (PDR_P) Malloc(sizeof(PDR)); CurFontPointer->f_pdr = p; p->p_same = NULL; p->p_basename = Malloc((le=NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1))+1); for (i=0; i<le; i++) p->p_basename[i] = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1); p->p_basename[le] = '\0'; /* Checksum business. */ check_sum = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4); switch (CurFontPointer->f_class) { case FOCLASS_AS_REQUESTED: HandleCheckSum (check_sum); break; case FOCLASS_REPLACEMENT_FONT: /* Note that when a replacement font is used the checksum as found in the dvi file has no relevancy. */ CurFontPointer->f_c = check_sum; break; default: Fatal ("ReadPdrFileInfo(): FOCLASS_ illegal."); } p->p_hcc = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 2); /* Highest character code */ p->p_ds = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4); /* design size */ p->p_sp = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4); /* space factor */ /* Read in matrix elements */ p->p_a = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4)); p->p_b = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4)); p->p_c = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4)); p->p_d = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4)); /* Compute use size. */ use_size_point = (double)CurFontPointer->f_s/HConvUnMag/Resolution * 72.27; #ifdef DEBUG fprintf (stderr, "%% Matrix: %6.4lf %6.4lf %6.4lf %6.4lf\n", p->p_a, p->p_b, p->p_c, p->p_d); /* Print design size and use size in pt */ fprintf (stderr, "%% Basename: \"%s\", ", p->p_basename); fprintf (stderr, "Design / Use size: %6.3lf / %6.3lf [pt]\n", (double) ((double)CurFontPointer->f_d/HConvUnMag)/Resolution * 72.27, use_size_point); fprintf (stderr, "%% Font Magnification (including global): %5.3lf\n", (double)(DriverMag/1000.0 * (double)CurFontPointer->f_s / (double)CurFontPointer->f_d)); #endif /* Read in other parameters from the pdr file. */ p->p_tx = SignExtend(EX_FP(CurFontPointer->f_ex_file), 4); p->p_ty = SignExtend(EX_FP(CurFontPointer->f_ex_file), 4); p->p_o = SignExtend(EX_FP(CurFontPointer->f_ex_file), 4); p->p_mc = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 4); p->p_emul = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1); /* Is it an invisible SliTeX font? */ p->p_i_slitex = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1); #ifdef DEBUG fprintf (stderr, "Name: %s, Invisible flag: %d\n", CurFontPointer->f_n, p->p_i_slitex); #endif /* If font emulation is going on, width vectors must be downloaded. */ if (p->p_emul == 1 && !WidthVectors) Fatal2 ("ReadPdrFileInfo(): no -w option with font emulation (\"%s\")", CurFontPointer->f_ex_file.ef_fn); p->p_length = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1); #ifdef DEBUG fprintf (stderr, "%% %d characters in font\n", p->p_length); #endif /* Now compute the right matrix for this font. */ mfac = DriverMag/1000.0 * /* (double)CurFontPointer->f_s / (double)CurFontPointer->f_d * */ use_size_point / 72.27 * Resolution; #ifdef DEBUG fprintf (stderr, "%% Matrix factor: %7.3lf\n", mfac); #endif p->p_a *= mfac; p->p_b *= mfac; p->p_c *= mfac; p->p_d *= mfac; /* Initialize the character array. */ for (i=0; i<MAX_CHAR_PS; i++) { CurFontPointer->f_ch[i].c_dl = FALSE; CurFontPointer->f_ch[i].c_type = CT_NONE; } /* Read in character names, character widths, character types, character names and PS procedures. This is from the character array in the pdr file. */ for (i=0; i<p->p_length; i++) { index = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1); #ifdef DEBUG fprintf (stderr, "%% ReadPdrFileInfo(): %dth char, code = '%o\n", i, index); #endif if (index<0 || index>=MAX_CHARS) Fatal2 ("ReadPdrFileInfo(): illegal character index '%o", index); ce = &(CurFontPointer->f_ch[index]); ce->c_type = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1); ce->c_execps_type = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1); #ifdef DEBUG fprintf (stderr, "%% ReadPdrFileInfo(): c_type: %d, c_execps_type: %d\n", ce->c_type, ce->c_execps_type); #endif switch (ce->c_type) { case CT_AFM: case CT_ASS: ce->c_dl = FALSE; break; case CT_EXECPS: ce->c_dl = FALSE; break; case CT_WIDTH_ONLY: ce->c_dl = FALSE; break; default: Fatal4 ("ReadPdrFileInfo(): [1] Illegal CT_ case, char: '%o, type = %d, i = %d", index, ce->c_type, i); } /* Load tfm with tfm width of character from .pdr file. */ tfm = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4); switch (CurFontPointer->f_class) { case FOCLASS_AS_REQUESTED: ce->c_w_tfm = (DVIU) (CurFontPointer->f_s * FIXES_TO_FLOAT(tfm)); break; case FOCLASS_REPLACEMENT_FONT: /* In case of a replacement font the tfm width to be used is already loaded (from the font which was supposed to be used originally.) Now we convert from tfm units to DVIUs. */ ce->c_w_tfm = (DVIU) (CurFontPointer->f_s * FIXES_TO_FLOAT(ce->c_w_tfm)); break; } /* If a width vector is used, the width of each character is rounded to the nearest integer position. Otherwise the width is used as directly read in from the pdr file. */ if (WidthVectors) ce->c_rw = HConv * PixRound (ce->c_w_tfm, HConv); else ce->c_rw = ce->c_w_tfm; switch (ce->c_type) { case CT_ASS: case CT_AFM: ce->c_n = GetBytes(EX_FP(CurFontPointer->f_ex_file), NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2)); break; case CT_EXECPS: ce->c_prog = GetBytes(EX_FP(CurFontPointer->f_ex_file), NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2)); /* Here build the name to be used for the character procedure name. */ sprintf (buffer, "@F%d==%o", CurFontNumber, index); ce->c_n = StrcpyAlloc(buffer); break; case CT_WIDTH_ONLY: if (NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2) != 0) Fatal ("ReadPdrFileInfo(): CT_WIDTH_ONLY"); ce->c_n = 0; break; default: Fatal ("ReadPdrFileInfo(): [2] Illegal CT_* case"); } #ifdef DEBUG fprintf (stderr, "%% PS Char '%3o, width = %6d (%s)\n", index, ce->c_w_tfm, ce->c_n); #endif } /* for */ /* Note that .pdr files are not cached, because PS fonts are established right away. Therefore the .pdr file can be closed now. */ FExClose (&CurFontPointer->f_ex_file); } /* * NewPSFont * ********* * Establish a new PostScript font. This procedure sends all the necessary * information to the PostScript printer. */ void NewPsFont() { int vn; /* vector number for this ps font */ int i; PDR_P p; int max_char_code; /* max character code used for PS fonts */ if (CurFontPointer->f_new_font) return; CurFontPointer->f_new_font = TRUE; p = CurFontPointer->f_pdr; /* Some prologue files for PS fonts are needed. */ PsDownLoad ("ps-fonts.pro", 0); /* General PS font stuff */ PsDownLoad ("reencode.pro", 0); /* Reencode: adding character codes */ PsDownLoad ("set-widths.pro", 0); /* Setting the width (kerning width dic) */ #ifdef DEBUG_VM fprintf(EX_FP(Ex_PsOutput), "(Begin PS Font) @ReportVmStatus\n"); #endif /* This opens the chain of PS names we give to the current * font as we add information and modify it. */ CurFontPointer->f_pdr->p_ser = 0; fprintf (EX_FP(Ex_PsOutput), "/@F%d-0 { /%s } def\n", CurFontNumber, p->p_basename); /* (1) Generates a regular font */ fprintf (EX_FP(Ex_PsOutput), "/@F%d-%d [%6.4lf %6.4lf %6.4lf %6.4lf 0.0 0.0] @F%d-%d @newfont-ps\n", CurFontNumber, CurFontPointer->f_pdr->p_ser+1, CurFontPointer->f_pdr->p_a, CurFontPointer->f_pdr->p_b, CurFontPointer->f_pdr->p_c, -CurFontPointer->f_pdr->p_d, CurFontNumber, CurFontPointer->f_pdr->p_ser); CurFontPointer->f_pdr->p_ser++; /* Start with the assumpation that this font needs its own width and character name vectors. Vectors are identified by numbers to be able to distinguish among vectors of the same type but different sources. */ vn = CurFontNumber; /* vn stands for vector number. */ /* Check now whether another font's width and character name vector can be used. */ for (i=0; i<MAX_FONTS; i++) { if (Fonts[i] != NULL && /* Is there such font? */ i != CurFontNumber && /* Is it a different font? */ Fonts[i]->f_type == CF_PDR && /* Is it a PostScript font? */ Fonts[i]->f_new_font && /* Is it a PostScript font which has a different width and character name vector from other PostScript fonts? */ ComparePdrFileLoaded (CurFontNumber, i)) { /* If yes was an answer to all the preceding questions, then now check whether the two fonts are comparable or not. */ /* Indeed, there is an identical font. Now generate a link which establishes that the two fonts are in a certail sense equivalent. */ if (Fonts[i]->f_pdr->p_same == NULL) { CurFontPointer->f_pdr->p_same = Fonts[i]; vn = i; } else { CurFontPointer->f_pdr->p_same = Fonts[i]->f_pdr->p_same; vn = CurFontPointer->f_pdr->p_same->f_k; } #ifdef DEBUG fprintf (stderr, "%% Current font %d vector-equivalent to font %d\n", CurFontNumber, vn); #endif break; } } /* Note the following DEBUG statement's messages printed which summarize the result from the preceding operation: vn was set initially to CurFontNumber, and if that has not changed, then no equivalent font was found. */ #ifdef DEBUG if (vn == CurFontNumber) fprintf (stderr, "%% Font %d, no vector-equivalent font available.\n", CurFontNumber); else fprintf (stderr, "%% Font %d: vector-equivalent font %d available.\n", CurFontNumber, vn); #endif /* * We are going to download three vectors now: * (a) encoding vector: a bunch of names all starting with '/' * (b) character codes vector: 8#0 8#1 8#20 ... * (c) a width vector: * We can save us repeating the encoding name and the encoding-codes * vector though if we already had such vectors from a different font. */ /* Compute the maximum character code. */ max_char_code = MAX_CHAR_PS - 1; if (SmallPsVectors) max_char_code = 127; if (vn == CurFontNumber) { /* This font is a font for which NO other equivalent font is available. If there is a vector-equivalent font available, do nothing. (a) Generate the encoding vector now. */ fprintf (EX_FP(Ex_PsOutput), "/@Encoding-Vector-%d [\n", vn); for (i=0; i<=max_char_code; i++) { switch (CurFontPointer->f_ch[i].c_type) { case CT_AFM: case CT_ASS: fprintf (EX_FP(Ex_PsOutput), "\t/%s\n", CurFontPointer->f_ch[i].c_n); break; case CT_EXECPS: break; } } /* for */ fprintf (EX_FP(Ex_PsOutput), "] def\n"); /* (b) Generate the character code vector next. */ fprintf (EX_FP(Ex_PsOutput), "/@CharCode-Vector-%d [\n", vn); for (i=0; i<=max_char_code; i++) { switch (CurFontPointer->f_ch[i].c_type) { case CT_ASS: case CT_AFM: fprintf (EX_FP(Ex_PsOutput), "\t8#%o\n", i); break; case CT_EXECPS: break; } } /* for */ fprintf (EX_FP(Ex_PsOutput), "] def\n"); } /* if vn == CurFontNumber */ /* (c) The width vector is downloaded here. That width vector is never identical (that's a reasonable assumption) to any other width vector. */ if (WidthVectors) { fprintf (EX_FP(Ex_PsOutput), "/@Width-Vector-%d [\n", CurFontNumber); for (i=0; i<=max_char_code; i++) { switch (CurFontPointer->f_ch[i].c_type) { case CT_ASS: case CT_AFM: fprintf (EX_FP(Ex_PsOutput), "\t%5.0lf\n", (double)((double)CurFontPointer->f_ch[i].c_rw / (double)CurFontPointer->f_s * 1000.0)); break; case CT_EXECPS: break; } } /* for */ fprintf (EX_FP(Ex_PsOutput), "] def\n"); } /* * We modify the encoding vector, adding definitions for those characters * which had character code -1 in the afm file, the socalled unassigned * characters. */ fprintf (EX_FP(Ex_PsOutput), "/@F%d-%d /@F%d-%d @Encoding-Vector-%d @CharCode-Vector-%d @ReEncodeSmall\n", CurFontNumber, CurFontPointer->f_pdr->p_ser, CurFontNumber, CurFontPointer->f_pdr->p_ser+1, vn, vn); CurFontPointer->f_pdr->p_ser++; /* Now we add the width dictionary. */ if (WidthVectors) { fprintf (EX_FP(Ex_PsOutput), "@Encoding-Vector-%d @Width-Vector-%d @MakeWidthDictionary\n", vn, CurFontNumber); fprintf (EX_FP(Ex_PsOutput), "/@F%d-%d /@F%d-%d @AddWidthDictionary\n", CurFontNumber, CurFontPointer->f_pdr->p_ser, CurFontNumber, CurFontPointer->f_pdr->p_ser+1); CurFontPointer->f_pdr->p_ser++; } #ifdef DEBUG_VM fprintf (EX_FP(Ex_PsOutput), "(End PS Font) @ReportVmStatus\n"); #endif } /* * ComparePdrFileLoaded * ******************** * Compare two pdr files which are already loaded. * * n1, n2: the indices of two fonts. * RET: TRUE, if these fonts have the same basename, * the same font matrix and the same encoding vector. */ int ComparePdrFileLoaded (n1, n2) int n1; int n2; { PDR_P p1, p2; /* Pdr file pointers. */ int i; /* Loop counter. */ CE c1, c2; /* Character information entries. */ if (Fonts[n1] == NULL || Fonts[n2] == NULL) Fatal ("ComparePdrFileLoaded(): undefined fonts."); if (Fonts[n1]->f_type != CF_PDR || Fonts[n2]->f_type != CF_PDR) Fatal ("ComparePdrFileLoaded(): fonts are no PS fonts."); p1 = Fonts[n1]->f_pdr; /* Get pointers to the .pdr file. */ p2 = Fonts[n2]->f_pdr; /* Different base names: the two fonts are certainly different. */ if (Strcmp(p1->p_basename, p2->p_basename) != 0) return (FALSE); /* Compare encoding vector of the two fonts. */ for (i=0; i<MAX_CHAR_PS; i++) { c1 = Fonts[n1]->f_ch[i]; c2 = Fonts[n2]->f_ch[i]; if (c1.c_type == CT_NONE && c2.c_type == CT_NONE) continue; if (c1.c_type != c2.c_type) return (FALSE); if (Strcmp(c1.c_n, c2.c_n) != 0) /* Compare PostScript names of the */ return (FALSE); /* two characters here. */ } /* for */ return (TRUE); }