summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/fontdef.c
blob: 466c2d4aacff9228b6e7eb7bcbaad267a7dd138e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 *  Stores the data from a font definition into the global data structures.
 *  A routine skipnop is also included to handle nops and font definitions
 *  between pages.
 */
#include "dvips.h" /* The copyright notice in that file is included too! */
#ifdef KPATHSEA
#include <kpathsea/magstep.h>
#endif

/*
 *   The external declarations:
 */
#include "protos.h"

/*
 * newfontdesc creates a new font descriptor with the given parameters and
 * returns a pointer to the new object.
*/
fontdesctype*
newfontdesc(integer cksum, integer scsize, integer dssize,
            char *name, char *area)
{
   register fontdesctype *fp;

   fp = (fontdesctype *)mymalloc((integer)sizeof(fontdesctype));
   fp->chardesc = (chardesctype *)mymalloc(256*(integer)sizeof(chardesctype));
   fp->maxchars = 256;
   fp->iswide = 0;
   fp->psname = 0;
   fp->loaded = 0;
   fp->checksum = cksum;
   fp->scaledsize = scsize;
   fp->designsize = dssize;
   fp->thinspace = scsize / 6;
   fp->scalename = NULL;
   fp->psflag = 0;
   fp->codewidth = 1;
   fp->name = name;
#ifdef VMCMS   /* IBM: VM/CMS */
   {
     int i;
     for ( i=0; fp->name[i]; i++ )
       fp->name[i] = ascii2ebcdic[ fp->name[i] ];
   }
#else
#ifdef MVSXA   /* IBM: MVS/XA */
   {
     int i;
     for ( i=0; fp->name[i]; i++ )
       fp->name[i] = ascii2ebcdic[ fp->name[i] ];
   }
#endif   /* IBM: MVS/XA */
#endif   /* IBM: VM/CMS */
   fp->area = area;
   fp->resfont = NULL;
   fp->localfonts = NULL;
#ifdef KPATHSEA
   fp->dpi = kpse_magstep_fix ((halfword)(mag*(float)fp->scaledsize*DPI/
         ((float)fp->designsize*1000.0)+0.5), DPI, NULL);
#else
   fp->dpi = dpicheck((halfword)(mag*fp->scaledsize*DPI/
         ((float)fp->designsize*1000.0)+0.5));
#endif
   fp->loadeddpi = fp->dpi;
#ifdef DEBUG
   if (dd(D_FONTS))
      fprintf(stderr,"Defining font (%s) %s at %.1fpt\n",
         area, name, (real)scsize/(alpha*0x100000));
#endif /* DEBUG */
   return fp;
}
/*
 * Try to find a font with a given name and approximate scaled size, returning
 * NULL if unsuccessful.  If scname and the font's scalename are both
 * non-NULL they must match exactly.  If both are NULL, scsize and the
 * font's scaledsize come from the dvi file and should match exactly.
 * Otherwise there can be some slop due to the inaccuracies of sizes
 * read from an included psfile.
 */
fontdesctype *
matchfont(char *name, char *area, integer scsize, char *scname)
{
   register fontdesctype *fp;
   register integer smin, smax;

   smin = scsize - fsizetol;
   smax = scsize + fsizetol;
   for (fp=fonthead; fp; fp=fp->next)
      if (smin < fp->scaledsize && fp->scaledsize < smax &&
            strcmp(name,fp->name)==0 && strcmp(area,fp->area)==0) {
         if (scname == NULL) {
            if (fp->scalename!=NULL || scsize==fp->scaledsize)
               break;
         } else {
            if (fp->scalename==NULL || strcmp(scname,fp->scalename)==0)
               break;
         }
      }
#ifdef DEBUG
   if (dd(D_FONTS) && fp)
      fprintf(stderr,"(Already known.)\n");
#endif /* DEBUG */
   return fp;
}
/*
 *   fontdef takes a font definition in the dvi file and loads the data
 *   into its data structures.
 */
void
fontdef(int siz)
{
   register integer i, j, fn;
   register fontdesctype *fp;
   register fontmaptype *cfnt;
   char *name, *area;
   integer cksum, scsize, dssize;

   fn = dvibyte();
   while (siz-- > 1)
      fn = (fn << 8) + dvibyte();
   for (cfnt=ffont; cfnt; cfnt = cfnt->next)
      if (cfnt->fontnum == fn) goto alreadydefined;
   cfnt = (fontmaptype *)mymalloc((integer)sizeof(fontmaptype));
   cfnt->next = ffont;
   ffont = cfnt;
   cfnt->fontnum = fn;
   cksum = signedquad();
   scsize = signedquad();
   dssize = signedquad();
   i = dvibyte(); j = dvibyte();
   if (nextstring + i + j > maxstring)
      error("! out of string space");
   area = nextstring;
   for (; i>0; i--)
      *nextstring++ = dvibyte();
   *nextstring++ = 0;
   name = nextstring;
   for (; j>0; j--)
      *nextstring++ = dvibyte();
   *nextstring++ = 0;
   fp = matchfont(name, area, scsize, (char *)0);
   if (fp) {
      nextstring = name;
      fp->checksum = cksum;
   } else {
      fp = newfontdesc(cksum, scsize, dssize, name, area);
      fp->next = fonthead;
      fonthead = fp;
   }
   cfnt->desc = fp;
   return;
alreadydefined:
/* A DVI file will not define a font twice; but we may be scanning
 * a font definition twice because a new section has started,
 * or because of collated copies. */
      skipover(12);
      skipover(dvibyte()+dvibyte());
}

/*
 *   The next routine handles nops or font definitions between pages in a
 *   dvi file.  Returns the first command that is not a nop or font definition.
 *
 *   Now handles specials (but ignores them)
 */
int
skipnop(void)
{
  register int cmd;

   while (1) {
      switch(cmd=dvibyte()) {
case 138: break;
case 239: skipover((int)dvibyte()); break; /* xxx1 */
case 240: skipover((int)twobytes()); break; /* xxx2 */
case 241: skipover((int)threebytes()); break; /* xxx3 */
case 242: skipover((int)signedquad()); break; /* xxx4 */
case 243: case 244: case 245: case 246: fontdef(cmd-242); break;
default: return cmd;
      }
   }
}