1 /* vf.c -- VF font support */
2 /*
3 * Copyright (C) 2000, Matias Atria
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #include <config.h>
21 #include <string.h>
22
23 #include "mdvi.h"
24 #include "private.h"
25
26 static int vf_load_font __PROTO((DviParams *, DviFont *));
27 static void vf_free_macros __PROTO((DviFont *));
28
29 /* only symbol exported by this file */
30 DviFontInfo vf_font_info = {
31 "VF",
32 1, /* virtual fonts scale just fine */
33 vf_load_font,
34 NULL, /* get_glyph */
35 NULL, /* shrink0 */
36 NULL, /* shrink1 */
37 vf_free_macros,
38 NULL, /* reset */
39 NULL, /* lookup */
40 kpse_vf_format,
41 NULL
42 };
43
44 DviFontInfo ovf_font_info = {
45 "OVF",
46 1, /* virtual fonts scale just fine */
47 vf_load_font,
48 NULL, /* get_glyph */
49 NULL, /* shrink0 */
50 NULL, /* shrink1 */
51 vf_free_macros,
52 NULL, /* reset */
53 NULL, /* lookup */
54 kpse_ovf_format,
55 NULL
56 };
57
vf_load_font(DviParams * params,DviFont * font)58 static int vf_load_font(DviParams *params, DviFont *font)
59 {
60 FILE *p;
61 Uchar *macros;
62 int msize;
63 int mlen;
64 Int32 checksum;
65 long alpha, beta, z;
66 int op;
67 int i;
68 int nchars;
69 int loc, hic;
70 DviFontRef *last;
71
72 macros = NULL;
73 msize = mlen = 0;
74 p = font->in;
75
76 if(fuget1(p) != 247 || fuget1(p) != 202)
77 goto badvf;
78 mlen = fuget1(p);
79 fseek(p, (long)mlen, SEEK_CUR);
80 checksum = fuget4(p);
81 if(checksum && font->checksum && checksum != font->checksum) {
82 mdvi_warning(_("%s: Checksum mismatch (expected %u, got %u)\n"),
83 font->fontname, font->checksum, checksum);
84 } else if(!font->checksum)
85 font->checksum = checksum;
86 font->design = fuget4(p);
87
88 /* read all the fonts in the preamble */
89 last = NULL;
90
91 /* initialize alpha, beta and z for TFM width computation */
92 TFMPREPARE(font->scale, z, alpha, beta);
93
94 op = fuget1(p);
95 while(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4) {
96 DviFontRef *ref;
97 Int32 scale, design;
98 Uint32 checksum;
99 int id;
100 int n;
101 int hdpi;
102 int vdpi;
103 char *name;
104
105 /* process fnt_def commands */
106
107 id = fugetn(p, op - DVI_FNT_DEF1 + 1);
108 checksum = fuget4(p);
109 scale = fuget4(p);
110 design = fuget4(p);
111
112 /* scale this font according to our parent's scale */
113 scale = TFMSCALE(scale, z, alpha, beta);
114 design = FROUND(params->tfm_conv * design);
115
116 /* compute the resolution */
117 hdpi = FROUND(params->mag * params->dpi * scale / design);
118 vdpi = FROUND(params->mag * params->vdpi * scale / design);
119 n = fuget1(p) + fuget1(p);
120 name = mdvi_malloc(n + 1);
121 fread(name, 1, n, p);
122 name[n] = 0;
123 DEBUG((DBG_FONTS, "(vf) %s: defined font `%s' at %.1fpt (%dx%d dpi)\n",
124 font->fontname, name,
125 (double)scale / (params->tfm_conv * 0x100000), hdpi, vdpi));
126
127 /* get the font */
128 ref = font_reference(params, id, name, checksum, hdpi, vdpi, scale);
129 if(ref == NULL) {
130 mdvi_error(_("(vf) %s: could not load font `%s'\n"),
131 font->fontname, name);
132 goto error;
133 }
134 mdvi_free(name);
135 if(last == NULL)
136 font->subfonts = last = ref;
137 else {
138 last->next = ref;
139 last = ref;
140 }
141 ref->next = NULL;
142 op = fuget1(p);
143 }
144
145 if(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4)
146 goto error;
147
148 /* This function correctly reads both .vf and .ovf files */
149
150 font->chars = xnalloc(DviFontChar, 256);
151 for(i = 0; i < 256; i++)
152 font->chars[i].offset = 0;
153 nchars = 256;
154 loc = -1; hic = -1;
155 /* now read the characters themselves */
156 while(op <= 242) {
157 int pl;
158 Int32 cc;
159 Int32 tfm;
160
161 if(op == 242) {
162 pl = fuget4(p);
163 cc = fuget4(p);
164 tfm = fuget4(p);
165 } else {
166 pl = op;
167 cc = fuget1(p);
168 tfm = fuget3(p);
169 }
170 if (cc < 0 || cc > 65536) {
171 /* TeX engines do not support char codes bigger than 65535 */
172 mdvi_error(_("(vf) %s: unexpected character %d\n"),
173 font->fontname, cc);
174 goto error;
175 }
176 if(loc < 0 || cc < loc)
177 loc = cc;
178 if(hic < 0 || cc > hic)
179 hic = cc;
180 if(cc >= nchars) {
181 font->chars = xresize(font->chars,
182 DviFontChar, cc + 16);
183 for(i = nchars; i < cc + 16; i++)
184 font->chars[i].offset = 0;
185 nchars = cc + 16;
186 }
187 if(font->chars[cc].offset) {
188 mdvi_error(_("(vf) %s: character %d redefined\n"),
189 font->fontname, cc);
190 goto error;
191 }
192
193 DEBUG((DBG_GLYPHS, "(vf) %s: defined character %d (macro length %d)\n",
194 font->fontname, cc, pl));
195 font->chars[cc].width = pl + 1;
196 font->chars[cc].code = cc;
197 font->chars[cc].tfmwidth = TFMSCALE(tfm, z, alpha, beta);
198 font->chars[cc].offset = mlen;
199 font->chars[cc].loaded = 1;
200 if(mlen + pl + 1 > msize) {
201 msize = mlen + pl + 256;
202 macros = xresize(macros, Uchar, msize);
203 }
204 if(pl && fread(macros + mlen, 1, pl, p) != pl)
205 break;
206 macros[mlen+pl] = DVI_EOP;
207 mlen += pl + 1;
208 op = fuget1(p);
209 }
210 if(op != 248) {
211 mdvi_error(_("(vf) %s: no postamble\n"), font->fontname);
212 goto error;
213 }
214
215 /* make macro memory just big enough */
216 if(msize > mlen) {
217 macros = xresize(macros, Uchar, mlen);
218 msize = mlen;
219 }
220
221 DEBUG((DBG_FONTS|DBG_GLYPHS,
222 "(vf) %s: macros use %d bytes\n", font->fontname, msize));
223
224 if(loc > 0 || hic < nchars-1) {
225 memmove(font->chars, font->chars + loc,
226 (hic - loc + 1) * sizeof(DviFontChar));
227 font->chars = xresize(font->chars,
228 DviFontChar, hic - loc + 1);
229 }
230 font->loc = loc;
231 font->hic = hic;
232 font->private = macros;
233
234 return 0;
235
236 badvf:
237 mdvi_error(_("%s: File corrupted, or not a VF file.\n"), font->fontname);
238 error:
239 if(font->chars)
240 mdvi_free(font->chars);
241 if(macros)
242 mdvi_free(macros);
243 return -1;
244 }
245
vf_free_macros(DviFont * font)246 static void vf_free_macros(DviFont *font)
247 {
248 mdvi_free(font->private);
249 }
250