]> www.fi.muni.cz Git - evince.git/blob - backend/dvi/mdvi-lib/vf.c
Do not include ev-poppler.h when pdf is disabled.
[evince.git] / backend / dvi / mdvi-lib / vf.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <string.h>
21
22 #include "mdvi.h"
23 #include "private.h"
24
25 static int  vf_load_font __PROTO((DviParams *, DviFont *));
26 static void vf_free_macros __PROTO((DviFont *));
27
28 /* only symbol exported by this file */
29 DviFontInfo vf_font_info = {
30         "VF",
31         1, /* virtual fonts scale just fine */
32         vf_load_font,
33         NULL,   /* get_glyph */
34         NULL,   /* shrink0 */
35         NULL,   /* shrink1 */
36         vf_free_macros,
37         NULL,   /* reset */
38         NULL,   /* lookup */
39         kpse_vf_format,
40         NULL
41 };
42
43 DviFontInfo ovf_font_info = {
44         "OVF",
45         1, /* virtual fonts scale just fine */
46         vf_load_font,
47         NULL,   /* get_glyph */
48         NULL,   /* shrink0 */
49         NULL,   /* shrink1 */
50         vf_free_macros,
51         NULL,   /* reset */
52         NULL,   /* lookup */
53         kpse_ovf_format,
54         NULL
55 };
56
57 static int vf_load_font(DviParams *params, DviFont *font)
58 {
59         FILE    *p;
60         Uchar   *macros;
61         int     msize;
62         int     mlen;
63         Int32   checksum;
64         long    alpha, beta, z;
65         int     op;
66         int     i;
67         int     nchars;
68         int     loc, hic;
69         DviFontRef *last;
70         
71         macros = NULL;
72         msize = mlen = 0;
73         p = font->in;
74         
75         if(fuget1(p) != 247 || fuget1(p) != 202)
76                 goto badvf;
77         mlen = fuget1(p);
78         fseek(p, (long)mlen, SEEK_CUR);
79         checksum = fuget4(p);
80         if(checksum && font->checksum && checksum != font->checksum) {
81                 warning(_("%s: Checksum mismatch (expected %u, got %u)\n"),
82                         font->fontname, font->checksum, checksum);
83         } else if(!font->checksum)
84                 font->checksum = checksum;
85         font->design = fuget4(p);
86         
87         /* read all the fonts in the preamble */
88         last = NULL;
89
90         /* initialize alpha, beta and z for TFM width computation */
91         TFMPREPARE(font->scale, z, alpha, beta);
92
93         op = fuget1(p); 
94         while(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4) {
95                 DviFontRef *ref;
96                 Int32   scale, design;
97                 Uint32  checksum;
98                 int     id;
99                 int     n;
100                 int     hdpi;
101                 int     vdpi;
102                 char    *name;
103                 
104                 /* process fnt_def commands */
105                 
106                 id = fugetn(p, op - DVI_FNT_DEF1 + 1);
107                 checksum = fuget4(p);
108                 scale = fuget4(p);
109                 design = fuget4(p);
110
111                 /* scale this font according to our parent's scale */
112                 scale = TFMSCALE(scale, z, alpha, beta);
113                 design = FROUND(params->tfm_conv * design);
114
115                 /* compute the resolution */
116                 hdpi = FROUND(params->mag * params->dpi * scale / design);
117                 vdpi = FROUND(params->mag * params->vdpi * scale / design);
118                 n = fuget1(p) + fuget1(p);
119                 name = mdvi_malloc(n + 1);
120                 fread(name, 1, n, p);
121                 name[n] = 0;
122                 DEBUG((DBG_FONTS, "(vf) %s: defined font `%s' at %.1fpt (%dx%d dpi)\n",
123                         font->fontname, name, 
124                         (double)scale / (params->tfm_conv * 0x100000), hdpi, vdpi));
125
126                 /* get the font */
127                 ref = font_reference(params, id, name, checksum, hdpi, vdpi, scale);
128                 if(ref == NULL) {
129                         error(_("(vf) %s: could not load font `%s'\n"), 
130                                 font->fontname, name);
131                         goto error;
132                 }
133                 mdvi_free(name);
134                 if(last == NULL)
135                         font->subfonts = last = ref;
136                 else
137                         last->next = ref;
138                 ref->next = NULL;
139                 op = fuget1(p);
140         }
141         
142         if(op >= DVI_FNT_DEF1 && op <= DVI_FNT_DEF4)
143                 goto error;
144
145         /* This function correctly reads both .vf and .ovf files */
146         
147         font->chars = xnalloc(DviFontChar, 256);
148         for(i = 0; i < 256; i++)
149                 font->chars[i].offset = 0;
150         nchars = 256;
151         loc = -1; hic = -1;
152         /* now read the characters themselves */
153         while(op <= 242) {
154                 int     pl;
155                 Int32   cc;
156                 Int32   tfm;
157                 
158                 if(op == 242) {
159                         pl = fuget4(p);
160                         cc = fuget4(p);
161                         tfm = fuget4(p);
162                 } else {
163                         pl = op;
164                         cc = fuget1(p);
165                         tfm = fuget3(p);
166                 }
167                 if(loc < 0 || cc < loc)
168                         loc = cc;
169                 if(hic < 0 || cc > hic)
170                         hic = cc;
171                 if(cc >= nchars) {
172                         font->chars = xresize(font->chars, 
173                                 DviFontChar, cc + 16);
174                         for(i = nchars; i < cc + 16; i++)
175                                 font->chars[i].offset = 0;
176                         nchars = cc + 16;
177                 }
178                 if(font->chars[cc].offset) {
179                         error(_("(vf) %s: character %d redefined\n"),
180                                 font->fontname, cc);
181                         goto error;
182                 }
183                                 
184                 DEBUG((DBG_GLYPHS, "(vf) %s: defined character %d (macro length %d)\n",
185                         font->fontname, cc, pl));
186                 font->chars[cc].width = pl + 1;
187                 font->chars[cc].code = cc;
188                 font->chars[cc].tfmwidth = TFMSCALE(tfm, z, alpha, beta);
189                 font->chars[cc].offset = mlen;
190                 font->chars[cc].loaded = 1;
191                 if(mlen + pl + 1 > msize) {
192                         msize = mlen + pl + 256;
193                         macros = xresize(macros, Uchar, msize);
194                 }
195                 if(pl && fread(macros + mlen, 1, pl, p) != pl)
196                         break;
197                 macros[mlen+pl] = DVI_EOP;
198                 mlen += pl + 1;
199                 op = fuget1(p);
200         }
201         if(op != 248) {
202                 error(_("(vf) %s: no postamble\n"), font->fontname);
203                 goto error;
204         }
205
206         /* make macro memory just big enough */
207         if(msize > mlen) {
208                 macros = xresize(macros, Uchar, mlen);
209                 msize = mlen;
210         }
211         
212         DEBUG((DBG_FONTS|DBG_GLYPHS, 
213                 "(vf) %s: macros use %d bytes\n", font->fontname, msize));
214
215         if(loc > 0 || hic < nchars-1) {
216                 memmove(font->chars, font->chars + loc,
217                         (hic - loc + 1) * sizeof(DviFontChar));
218                 font->chars = xresize(font->chars,
219                         DviFontChar, hic - loc + 1);
220         }
221         font->loc = loc;
222         font->hic = hic;
223         font->private = macros;
224
225         return 0;
226         
227 badvf:
228         error(_("%s: File corrupted, or not a VF file.\n"), font->fontname);
229 error:
230         if(font->chars)
231                 mdvi_free(font->chars);
232         if(macros)
233                 mdvi_free(macros);
234         return -1;
235 }
236
237 static void vf_free_macros(DviFont *font)
238 {
239         mdvi_free(font->private);       
240 }