Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vf.c
Go to the documentation of this file.
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 */
31  "VF",
32  1, /* virtual fonts scale just fine */
34  NULL, /* get_glyph */
35  NULL, /* shrink0 */
36  NULL, /* shrink1 */
38  NULL, /* reset */
39  NULL, /* lookup */
40  kpse_vf_format,
41  NULL
42 };
43 
45  "OVF",
46  1, /* virtual fonts scale just fine */
48  NULL, /* get_glyph */
49  NULL, /* shrink0 */
50  NULL, /* shrink1 */
52  NULL, /* reset */
53  NULL, /* lookup */
54  kpse_ovf_format,
55  NULL
56 };
57 
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  ref->next = NULL;
140  op = fuget1(p);
141  }
142 
143  if(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4)
144  goto error;
145 
146  /* This function correctly reads both .vf and .ovf files */
147 
148  font->chars = xnalloc(DviFontChar, 256);
149  for(i = 0; i < 256; i++)
150  font->chars[i].offset = 0;
151  nchars = 256;
152  loc = -1; hic = -1;
153  /* now read the characters themselves */
154  while(op <= 242) {
155  int pl;
156  Int32 cc;
157  Int32 tfm;
158 
159  if(op == 242) {
160  pl = fuget4(p);
161  cc = fuget4(p);
162  tfm = fuget4(p);
163  } else {
164  pl = op;
165  cc = fuget1(p);
166  tfm = fuget3(p);
167  }
168  if (cc < 0 || cc > 65536) {
169  /* TeX engines do not support char codes bigger than 65535 */
170  mdvi_error(_("(vf) %s: unexpected character %d\n"),
171  font->fontname, cc);
172  goto error;
173  }
174  if(loc < 0 || cc < loc)
175  loc = cc;
176  if(hic < 0 || cc > hic)
177  hic = cc;
178  if(cc >= nchars) {
179  font->chars = xresize(font->chars,
180  DviFontChar, cc + 16);
181  for(i = nchars; i < cc + 16; i++)
182  font->chars[i].offset = 0;
183  nchars = cc + 16;
184  }
185  if(font->chars[cc].offset) {
186  mdvi_error(_("(vf) %s: character %d redefined\n"),
187  font->fontname, cc);
188  goto error;
189  }
190 
191  DEBUG((DBG_GLYPHS, "(vf) %s: defined character %d (macro length %d)\n",
192  font->fontname, cc, pl));
193  font->chars[cc].width = pl + 1;
194  font->chars[cc].code = cc;
195  font->chars[cc].tfmwidth = TFMSCALE(tfm, z, alpha, beta);
196  font->chars[cc].offset = mlen;
197  font->chars[cc].loaded = 1;
198  if(mlen + pl + 1 > msize) {
199  msize = mlen + pl + 256;
200  macros = xresize(macros, Uchar, msize);
201  }
202  if(pl && fread(macros + mlen, 1, pl, p) != pl)
203  break;
204  macros[mlen+pl] = DVI_EOP;
205  mlen += pl + 1;
206  op = fuget1(p);
207  }
208  if(op != 248) {
209  mdvi_error(_("(vf) %s: no postamble\n"), font->fontname);
210  goto error;
211  }
212 
213  /* make macro memory just big enough */
214  if(msize > mlen) {
215  macros = xresize(macros, Uchar, mlen);
216  msize = mlen;
217  }
218 
220  "(vf) %s: macros use %d bytes\n", font->fontname, msize));
221 
222  if(loc > 0 || hic < nchars-1) {
223  memmove(font->chars, font->chars + loc,
224  (hic - loc + 1) * sizeof(DviFontChar));
225  font->chars = xresize(font->chars,
226  DviFontChar, hic - loc + 1);
227  }
228  font->loc = loc;
229  font->hic = hic;
230  font->private = macros;
231 
232  return 0;
233 
234 badvf:
235  mdvi_error(_("%s: File corrupted, or not a VF file.\n"), font->fontname);
236 error:
237  if(font->chars)
238  mdvi_free(font->chars);
239  if(macros)
240  mdvi_free(macros);
241  return -1;
242 }
243 
244 static void vf_free_macros(DviFont *font)
245 {
246  mdvi_free(font->private);
247 }