]> www.fi.muni.cz Git - evince.git/blob - backend/dvi/mdvi-lib/t1.c
Update FSF address everywhere.
[evince.git] / backend / dvi / mdvi-lib / t1.c
1 /*
2  * Copyright (C) 2000, Matias Atria
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 /* 
20  * Type1 font support for MDVI
21  *
22  * We use T1lib only as a rasterizer, not to draw glyphs.
23  */
24
25 #include <config.h>
26 #include "mdvi.h"
27
28 #ifdef WITH_TYPE1_FONTS
29
30 #include <stdio.h>
31 #include <t1lib.h>
32 #include "private.h"
33
34 static int      t1lib_initialized = 0;
35
36 typedef struct t1info {
37         struct t1info *next;
38         struct t1info *prev;
39         char    *fontname;      /* (short) name of this font */
40         int     t1id;           /* T1lib's id for this font */  
41         int     hasmetrics;     /* have we processed this font? */
42         TFMInfo *tfminfo;       /* TFM data is shared */
43         DviFontMapInfo mapinfo;
44         DviEncoding *encoding;
45 } T1Info;
46
47 static void  t1_font_remove __PROTO((T1Info *));
48 static int   t1_load_font __PROTO((DviParams *, DviFont *));
49 static int   t1_font_get_glyph __PROTO((DviParams *, DviFont *, int));
50 static void  t1_font_shrink_glyph 
51                 __PROTO((DviContext *, DviFont *, DviFontChar *, DviGlyph *));
52 static void  t1_free_data __PROTO((DviFont *));
53 static void  t1_reset_font __PROTO((DviFont *));
54 static char *t1_lookup_font __PROTO((const char *, Ushort *, Ushort *));
55
56 /* only symbol exported by this file */
57 DviFontInfo t1_font_info = {
58         "Type1",
59         1, /* scaling supported by format */
60         t1_load_font,
61         t1_font_get_glyph,
62         t1_font_shrink_glyph,
63         mdvi_shrink_glyph_grey,
64         t1_free_data,
65         t1_reset_font,
66         t1_lookup_font, /* lookup */
67         kpse_type1_format,
68         NULL
69 };
70
71 /* this seems good enough for most DVI files */
72 #define T1_HASH_SIZE    31
73
74 /* If these parameters change, we must delete all size information
75  * in all fonts, and reset the device resolutions in T1lib */
76 static int t1lib_xdpi = -1;
77 static int t1lib_ydpi = -1;
78
79 static ListHead t1fonts = {NULL, NULL, 0};
80 static DviHashTable t1hash;
81
82 /* Type1 fonts need their own `lookup' function. Here is how it works: 
83  * First we try to find the font by its given name. If that fails, we
84  * query the font maps. A typical font map entry may contain the line
85  * 
86  * ptmr8rn Times-Roman ".82 ExtendFont TeXBase1Encoding ReEncodeFont" <8r.enc <ptmr
87  *
88  * which means: If you're looking for the font `ptmr8rn' load `Times-Roman'
89  * which is in `ptmr' instead, and extend it by 0.82 points, then reencode
90  * it with the vector TeXBase1Encoding from the file `8r.enc'. This will
91  * fail if the entry looks like this:
92  *
93  * ptmr8rn Times-Roman ".82 ExtendFont TeXBase1Encoding ReEncodeFont" <8r.enc
94  *
95  * because to deal with this we would need to be able to locate the font file
96  * for the `Times-Roman' font ourselves, and that's beyond the scope of mdvi.
97  * But hey, we tried hard.
98  */
99 char    *t1_lookup_font(const char *name, Ushort *hdpi, Ushort *vdpi)
100 {
101         char    *filename;
102         char    *newname;
103         const char *ext;
104         DviFontMapInfo info;
105
106         DEBUG((DBG_TYPE1, "(t1) looking for `%s'\n", name));
107
108         /* first let's try the font we were asked for */
109         filename = kpse_find_file(name, kpse_type1_format, 1);
110         if(filename != NULL) {
111                 /* we got it */
112                 return filename;
113         }
114
115         DEBUG((DBG_TYPE1, "(t1) %s: not found, querying font maps\n", name));   
116         /* now query the fontmap */
117         if(mdvi_query_fontmap(&info, name) < 0) {
118                 /* it's not there either */
119                 return NULL;
120         }
121         
122         /* check what we got */
123         if(info.fullfile) {
124                 DEBUG((DBG_TYPE1, "(t1) %s: found `%s' (cached)\n",
125                         name, info.fullfile));
126                 /* this is a cached lookup */
127                 return mdvi_strdup(info.fullfile);
128         }
129         
130         /* no file associated to this font? */
131         if(info.fontfile == NULL)
132                 return info.psname ? mdvi_ps_find_font(info.psname) : NULL;
133                 
134         /* let's extract the extension */
135         ext = file_extension(info.fontfile);
136         if(ext && !STREQ(ext, "pfa") && !STREQ(ext, "pfb")) {
137                 DEBUG((DBG_TYPE1, 
138                         "(t1) %s: associated name `%s' is not Type1\n",
139                         name, info.fontfile));
140                 /* it's not a Type1 font */
141                 return NULL;
142         }
143
144         /* get the `base' name */
145         if(ext) {
146                 newname = mdvi_strdup(name);
147                 newname[ext - info.fontfile - 1] = 0;
148         } else
149                 newname = (char *)name; /* we don't modify this */
150
151         /* look it up */
152         DEBUG((DBG_TYPE1, "(t1) looking for `%s' on behalf of `%s'\n",
153                 newname, name));
154         filename = kpse_find_file(newname, kpse_type1_format, 1);
155
156         /* we don't need this anymore */
157         if(newname != name)
158                 mdvi_free(newname);
159         if(filename == NULL) {
160                 DEBUG((DBG_TYPE1, "(t1) %s: not found\n", name));
161                 return NULL;
162         }
163         
164         DEBUG((DBG_TYPE1, "(t1) %s: found as `%s'\n", name, filename));
165         /* got it! let's remember this */
166         mdvi_add_fontmap_file(name, filename);
167         return filename;
168 }
169
170 static void t1_reset_resolution(int xdpi, int ydpi)
171 {
172         int     i;
173         int     nfonts;
174
175         DEBUG((DBG_TYPE1, "(t1) resetting device resolution (current: (%d,%d))\n",
176                 t1lib_xdpi, t1lib_ydpi));
177 #if T1LIB_VERSION < 5
178         nfonts = T1_Get_no_fonts();
179 #else
180         nfonts = T1_GetNoFonts();
181 #endif  
182
183         for(i = 0; i < nfonts; i++)
184                 T1_DeleteAllSizes(i);
185         /* reset device resolutions */
186         if(T1_SetDeviceResolutions((float)xdpi, (float)ydpi) < 0)
187                 mdvi_warning(_("(t1) failed to reset device resolution\n"));
188         else
189                 DEBUG((DBG_TYPE1, 
190                         "(t1) reset successful, new resolution is (%d, %d)\n",
191                         xdpi, ydpi));
192         t1lib_xdpi = xdpi;
193         t1lib_ydpi = ydpi;
194 }
195
196 static void t1_reset_font(DviFont *font)
197 {
198         T1Info *info = (T1Info *)font->private;
199         
200         if(info == NULL)
201                 return;
202         DEBUG((DBG_FONTS, "(t1) resetting font `%s'\n", font->fontname));
203         /* just mark the font as not having metric info. It will be reset
204          * automatically later */
205         info->hasmetrics = 0;
206 }
207
208 static void t1_transform_font(T1Info *info)
209 {
210         if(!info->hasmetrics && info->encoding != NULL) {
211                 DEBUG((DBG_TYPE1, "(t1) %s: encoding with vector `%s'\n",
212                         info->fontname, info->encoding->name));
213                 T1_DeleteAllSizes(info->t1id);
214                 if(T1_ReencodeFont(info->t1id, info->encoding->vector) < 0)
215                         mdvi_warning(_("%s: could not encode font\n"), info->fontname);
216         }
217         if(info->mapinfo.slant) {
218                 DEBUG((DBG_TYPE1, "(t1) %s: slanting by %.3f\n", 
219                         info->fontname,
220                         MDVI_FMAP_SLANT(&info->mapinfo)));
221                 T1_SlantFont(info->t1id, 
222                         MDVI_FMAP_SLANT(&info->mapinfo));
223         }
224         if(info->mapinfo.extend) {
225                 DEBUG((DBG_TYPE1, "(t1) %s: extending by %.3f\n",
226                         info->fontname,
227                         MDVI_FMAP_EXTEND(&info->mapinfo)));
228                 T1_ExtendFont(info->t1id, 
229                         MDVI_FMAP_EXTEND(&info->mapinfo));
230         }               
231 }
232
233 /* if this function is called, we really need this font */
234 static int t1_really_load_font(DviParams *params, DviFont *font, T1Info *info)
235 {
236         int     i;
237         T1Info  *old;
238         int     t1id;
239         int     copied;
240         int     status;
241
242         DEBUG((DBG_TYPE1, "(t1) really_load_font(%s)\n", info->fontname));
243
244         /* if the parameters changed, reset T1lib */
245         if(t1lib_xdpi != params->dpi || t1lib_ydpi != params->vdpi)
246                 t1_reset_resolution(params->dpi, params->vdpi);
247
248         /* if we already have a T1lib id, do nothing */
249         if(info->t1id != -1) {
250                 info->hasmetrics = 1;
251                 /* apply slant and extend again */
252                 t1_transform_font(info);
253                 return 0;
254         }
255
256         /* before we even attempt to load the font, make sure we have metric
257          * data for it */
258         info->tfminfo = mdvi_ps_get_metrics(info->fontname);
259         if(info->tfminfo == NULL) {
260                 DEBUG((DBG_FONTS, 
261                         "(t1) %s: no metric data, font ignored\n",
262                         info->fontname));
263                 goto t1_error;
264         }
265         /* fix this */
266         font->design = info->tfminfo->design;
267
268         /* check if we have a font with this name (maybe at a different size) */
269         old = (T1Info *)mdvi_hash_lookup(&t1hash, (unsigned char *)info->fontname);
270         if(old == info) {
271                 /* let's avoid confusion */
272                 old = NULL;
273         }
274         if(old && old->t1id != -1) {
275                 /* let's take advantage of T1lib's font sharing */
276                 t1id = T1_CopyFont(old->t1id);
277                 DEBUG((DBG_TYPE1, "(t1) %s -> %d (CopyFont)\n", 
278                         info->fontname, t1id));
279                 copied = 1;
280         } else {
281                 t1id = T1_AddFont(font->filename);
282                 DEBUG((DBG_TYPE1, "(t1) %s -> %d (AddFont)\n",
283                         info->fontname, t1id));
284                 copied = 0;
285         }
286         if(t1id < 0)
287                 goto t1_error;
288         info->t1id = t1id;
289
290         /* 
291          * a minor optimization: If the old font in the hash table has
292          * not been loaded yet, replace it by this one, so we can use
293          * CopyFont later.
294          */
295         if(old && old->t1id == -1) {
296                 DEBUG((DBG_TYPE1, "(t1) font `%s' exchanged in hash table\n",
297                         info->fontname));
298                 mdvi_hash_remove(&t1hash, (unsigned char *)old->fontname);
299                 mdvi_hash_add(&t1hash, (unsigned char *)info->fontname, 
300                         info, MDVI_HASH_UNCHECKED);
301         }
302
303         /* now let T1lib load it */
304         if(!copied && T1_LoadFont(info->t1id) < 0) {
305                 DEBUG((DBG_TYPE1, "(t1) T1_LoadFont(%d) failed with error %d\n",
306                         info->t1id, T1_errno));
307                 goto t1_error;
308         }
309         DEBUG((DBG_TYPE1, "(t1) T1_LoadFont(%d) -> Ok\n", info->t1id));
310
311         /* get information from the fontmap */
312         status = mdvi_query_fontmap(&info->mapinfo, info->fontname);
313         if(!status && info->mapinfo.encoding)
314                 info->encoding = mdvi_request_encoding(info->mapinfo.encoding);
315         t1_transform_font(info);
316
317         i = info->tfminfo->hic - info->tfminfo->loc + 1;
318         if(i != font->hic - font->loc + 1) {
319                 /* reset to optimal size */
320                 font->chars = mdvi_realloc(font->chars, i * sizeof(DviFontChar));
321         }
322
323         /* get the scaled characters metrics */
324         get_tfm_chars(params, font, info->tfminfo, 0);
325         info->hasmetrics = 1;
326         
327         DEBUG((DBG_TYPE1, "(t1) font `%s' really-loaded\n", info->fontname));
328         return 0;
329
330 t1_error:
331         /* some error does not allows us to use this font. We need to reset
332          * the font structure, so the font system can try to read this
333          * font in a different class */
334         
335         /* first destroy the private data */
336         t1_font_remove(info);
337         /* now reset all chars -- this is the important part */
338         mdvi_free(font->chars);
339         font->chars = NULL;
340         font->loc = font->hic = 0;
341         return -1;
342 }
343
344 static int init_t1lib(DviParams *params)
345 {
346         int     t1flags;
347
348 #ifdef WORD_LITTLE_ENDIAN
349         /* try making T1lib use bitmaps in our format, but if this
350          * fails we'll convert the bitmap ourselves */
351         T1_SetBitmapPad(BITMAP_BITS);
352 #endif
353         T1_SetDeviceResolutions((float)params->dpi, (float)params->vdpi);
354         t1flags = IGNORE_CONFIGFILE|IGNORE_FONTDATABASE|T1_NO_AFM;
355         if(DEBUGGING(TYPE1))
356                 t1flags |= LOGFILE;
357         if(T1_InitLib(t1flags) == NULL)
358                 return (t1lib_initialized = -1);
359         if(DEBUGGING(TYPE1)) {
360                 DEBUG((DBG_TYPE1, "T1lib debugging output saved in t1lib.log\n"));
361                 T1_SetLogLevel(T1LOG_DEBUG);
362         }
363         /* initialize our hash table, but don't allocate memory for it
364          * until we use it */
365         mdvi_hash_init(&t1hash);
366         DEBUG((DBG_TYPE1, "(t1) t1lib %s initialized -- resolution is (%d, %d), pad is %d bits\n",
367                 T1_GetLibIdent(), params->dpi, params->vdpi, T1_GetBitmapPad()));
368         t1lib_initialized = 1;  
369         t1lib_xdpi = params->dpi;
370         t1lib_ydpi = params->vdpi;
371         return 0;
372 }
373
374 static int t1_load_font(DviParams *params, DviFont *font)
375 {
376         T1Info  *info;
377         int     i;
378                                 
379         if(t1lib_initialized < 0)
380                 return -1;
381         else if(t1lib_initialized == 0 && init_t1lib(params) < 0)
382                 return -1;
383
384         if(font->in != NULL) {
385                 /* we don't need this */
386                 fclose(font->in);
387                 font->in = NULL;
388         }
389
390         info = xalloc(T1Info);
391
392         /* 
393          * mark the font as `unregistered' with T1lib. It will
394          * be added when we actually use it
395          */
396         info->t1id = -1;
397
398         /* add the font to our list */
399         info->fontname = font->fontname;
400         info->hasmetrics = 0;
401         info->encoding = NULL;
402         info->mapinfo.psname = NULL;
403         info->mapinfo.encoding = NULL;
404         info->mapinfo.fontfile = NULL;
405         info->mapinfo.extend = 0;
406         info->mapinfo.slant = 0;
407         info->encoding = NULL;
408         
409         /* create the hash table if we have not done so yet */
410         if(t1hash.nbucks == 0)
411                 mdvi_hash_create(&t1hash, T1_HASH_SIZE);
412         mdvi_hash_add(&t1hash, (unsigned char *) info->fontname, info, MDVI_HASH_UNIQUE);               
413         listh_append(&t1fonts, LIST(info));
414
415         font->private = info;
416                 
417         /* reset everything */
418         font->chars = xnalloc(DviFontChar, 256);
419         font->loc = 0;
420         font->hic = 255;
421         for(i = 0; i < 256; i++) {
422                 font->chars[i].code = i;
423                 font->chars[i].offset = 1;
424                 font->chars[i].loaded = 0;
425                 font->chars[i].glyph.data = NULL;
426                 font->chars[i].shrunk.data = NULL;
427                 font->chars[i].grey.data = NULL;
428         }
429         
430         return 0;
431 }
432
433 #define GLYPH_WIDTH(g) \
434         ((g)->metrics.rightSideBearing - (g)->metrics.leftSideBearing)
435 #define GLYPH_HEIGHT(g) \
436         ((g)->metrics.ascent - (g)->metrics.descent)
437
438 static inline BITMAP *t1_glyph_bitmap(GLYPH *glyph)
439 {
440         int     w, h, pad;
441         
442         w = GLYPH_WIDTH(glyph);
443         h = GLYPH_HEIGHT(glyph);
444
445         if(!w || !h)
446                 return MDVI_GLYPH_EMPTY;
447
448         pad = T1_GetBitmapPad();
449         return bitmap_convert_lsb8((unsigned char *)glyph->bits, w, h, ROUND(w, pad) * (pad >> 3));
450 }
451
452 static void t1_font_shrink_glyph(DviContext *dvi, DviFont *font, DviFontChar *ch, DviGlyph *dest)
453 {
454         double  size;
455         GLYPH   *glyph;
456         T1Info  *info;
457         T1_TMATRIX matrix;
458         
459         info = (T1Info *)font->private;
460         ASSERT(info != NULL);
461
462         DEBUG((DBG_TYPE1, "(t1) shrinking glyph for character %d in `%s' (%d,%d)\n",
463                 ch->code, font->fontname, ch->width, ch->height));      
464         size = (double)font->scale / (dvi->params.tfm_conv * 0x100000);
465         size = 72.0 * size / 72.27;
466         matrix.cxx = 1.0/(double)dvi->params.hshrink;
467         matrix.cyy = 1.0/(double)dvi->params.vshrink;
468         matrix.cxy = 0.0;
469         matrix.cyx = 0.0;
470         glyph = T1_SetChar(info->t1id, ch->code, (float)size, &matrix);
471
472         dest->data = t1_glyph_bitmap(glyph);
473         dest->x = -glyph->metrics.leftSideBearing;
474         dest->y = glyph->metrics.ascent;
475         dest->w = GLYPH_WIDTH(glyph);
476         dest->h = GLYPH_HEIGHT(glyph);
477
478 #ifndef NODEBUG
479         if(DEBUGGING(BITMAP_DATA)) {
480                 DEBUG((DBG_BITMAP_DATA, 
481                         "(t1) %s: t1_shrink_glyph(%d): (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
482                         ch->glyph.w, ch->glyph.h, ch->glyph.x, ch->glyph.y,
483                         dest->w, dest->h, dest->x, dest->y));
484                 bitmap_print(stderr, (BITMAP *)dest->data);
485         }
486 #endif
487         /* transform the glyph - we could do this with t1lib, but we do
488          * it ourselves for now */
489         font_transform_glyph(dvi->params.orientation, dest);
490 }
491
492 static int t1_font_get_glyph(DviParams *params, DviFont *font, int code)
493 {
494         T1Info  *info = (T1Info *)font->private;
495         GLYPH   *glyph;
496         DviFontChar *ch;
497         double  size;
498         T1_TMATRIX matrix;
499         int     dpi;
500         
501         ASSERT(info != NULL);
502         if(!info->hasmetrics && t1_really_load_font(params, font, info) < 0)
503                 return -1;
504         ch = FONTCHAR(font, code);      
505         if(!ch || !glyph_present(ch))
506                 return -1;
507         ch->loaded = 1;
508         if(!ch->width || !ch->height) {
509                 ch->glyph.x = ch->x;
510                 ch->glyph.y = ch->y;
511                 ch->glyph.w = ch->width;
512                 ch->glyph.h = ch->height;
513                 ch->glyph.data = NULL;
514                 return 0;
515         }
516
517         /* load the glyph with T1lib (this is done only once for each glyph) */
518
519         /* get size in TeX points (tfm_conv includes dpi and magnification) */
520         size = (double)font->scale / (params->tfm_conv * 0x100000);
521         /* and transform into PostScript points */
522         size = 72.0 * size / 72.27;
523
524         dpi = Max(font->hdpi, font->vdpi);
525         /* we don't want the glyph to be cached twice (once by us, another by 
526          * T1lib), so we use an identity matrix to tell T1lib not to keep the
527          * glyph around */
528         matrix.cxx = (double)font->hdpi / dpi;
529         matrix.cyy = (double)font->vdpi / dpi;
530         matrix.cxy = matrix.cyx = 0.0;
531         glyph = T1_SetChar(info->t1id, ch->code, (float)size, &matrix);
532         if(glyph == NULL) {
533                 ch->glyph.x = ch->x;
534                 ch->glyph.y = ch->y;
535                 ch->glyph.w = ch->width;
536                 ch->glyph.h = ch->height;
537                 ch->glyph.data = NULL;
538                 ch->missing = 1;
539                 return 0;
540         }
541         /* and make it a bitmap */
542         ch->glyph.data = t1_glyph_bitmap(glyph);
543         ch->glyph.x = -glyph->metrics.leftSideBearing;
544         ch->glyph.y = glyph->metrics.ascent;
545         ch->glyph.w = GLYPH_WIDTH(glyph);
546         ch->glyph.h = GLYPH_HEIGHT(glyph);
547
548         /* let's also fix the glyph's origin 
549          * (which is not contained in the TFM) */
550         ch->x = ch->glyph.x;
551         ch->y = ch->glyph.y;
552         /* let's fix these too */
553         ch->width = ch->glyph.w;
554         ch->height = ch->glyph.h;
555                 
556         return 0;
557 }
558
559 static void t1_font_remove(T1Info *info)
560 {
561         T1Info  *old;
562         
563         /* first remove it from our list */
564         listh_remove(&t1fonts, LIST(info));
565
566         /* it it's in the hash table, we may need to replace this by another font */
567         old = (T1Info *)mdvi_hash_lookup(&t1hash, (unsigned char *)info->fontname);
568         if(old == info) {
569                 mdvi_hash_remove(&t1hash, (unsigned char *) info->fontname);
570                 /* go through the list and see if there is another 
571                  * font with this name */
572                 for(old = (T1Info *)t1fonts.head; old; old = old->next)
573                         if(STREQ(old->fontname, info->fontname))
574                                 break;
575                 if(old != NULL)
576                         mdvi_hash_add(&t1hash, (unsigned char *) old->fontname, old, 
577                                 MDVI_HASH_UNCHECKED);
578         }
579         /* release our encoding vector */
580         if(info->encoding) {
581                 DEBUG((DBG_TYPE1, "(t1) %s: releasing vector `%s'\n",
582                         info->fontname, info->encoding->name));
583                 mdvi_release_encoding(info->encoding, 1);
584         }
585
586         /* now get rid of it */
587         if(info->t1id != -1) {
588                 DEBUG((DBG_TYPE1, "(t1) %s: T1_DeleteFont(%d)\n",
589                         info->fontname, info->t1id));
590                 T1_DeleteFont(info->t1id);
591         } else
592                 DEBUG((DBG_TYPE1, "(t1) %s: not loaded yet, DeleteFont skipped\n",
593                         info->fontname));
594
595         if(info->tfminfo)
596                 free_font_metrics(info->tfminfo);
597         /*mdvi_free(info->fontname);*/
598         mdvi_free(info);
599 }
600
601 static void t1_free_data(DviFont *font)
602 {
603         /* called after all the glyphs are destroyed */
604
605         if(font->private == NULL) {
606                 /* this is perfectly normal, it just means the font has 
607                  * not been requested by MDVI yet */
608                 return;
609         }
610         
611         /* destroy this data */
612
613         t1_font_remove((T1Info *)font->private);
614         font->private = NULL;
615
616         /* 
617          * if this is the last T1 font, reset the T1 library
618          * It is important that we do this, because this is will be called
619          * when the resolution or the magnification changes.
620          */
621         if(t1fonts.count == 0) {
622                 DEBUG((DBG_TYPE1, "(t1) last font removed -- closing T1lib\n"));
623                 T1_CloseLib();
624                 t1lib_initialized = 0;
625                 t1lib_xdpi = -1;
626                 t1lib_ydpi = -1;
627         }
628 }
629
630 #endif /* WITH_TYPE1_FONTS */