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
font.c File Reference
#include <config.h>
#include <stdlib.h>
#include "mdvi.h"
#include "private.h"
+ Include dependency graph for font.c:

Go to the source code of this file.

Macros

#define finfo   search.info
 
#define TYPENAME(font)   ((font)->finfo ? (font)->finfo->name : "none")
 

Functions

void vf_free_macros (DviFont *)
 
int font_reopen (DviFont *font)
 
static int load_font_file (DviParams *params, DviFont *font)
 
void font_drop_one (DviFontRef *ref)
 
void font_drop_chain (DviFontRef *head)
 
int font_free_unused (DviDevice *dev)
 
DviFontReffont_reference (DviParams *params, Int32 id, const char *name, Int32 sum, int hdpi, int vdpi, Int32 scale)
 
void font_transform_glyph (DviOrientation orient, DviGlyph *g)
 
static int load_one_glyph (DviContext *dvi, DviFont *font, int code)
 
DviFontCharfont_get_glyph (DviContext *dvi, DviFont *font, int code)
 
void font_reset_one_glyph (DviDevice *dev, DviFontChar *ch, int what)
 
void font_reset_font_glyphs (DviDevice *dev, DviFont *font, int what)
 
void font_reset_chain_glyphs (DviDevice *dev, DviFontRef *head, int what)
 
static int compare_refs (const void *p1, const void *p2)
 
void font_finish_definitions (DviContext *dvi)
 
DviFontReffont_find_flat (DviContext *dvi, Int32 id)
 
DviFontReffont_find_mapped (DviContext *dvi, Int32 id)
 

Variables

static ListHead fontlist
 
char * _mdvi_fallback_font
 

Macro Definition Documentation

#define finfo   search.info

Definition at line 31 of file font.c.

#define TYPENAME (   font)    ((font)->finfo ? (font)->finfo->name : "none")

Definition at line 32 of file font.c.

Function Documentation

static int compare_refs ( const void *  p1,
const void *  p2 
)
static

Definition at line 460 of file font.c.

461 {
462  return ((*(DviFontRef **)p1)->fontid - (*(DviFontRef **)p2)->fontid);
463 }

+ Here is the caller graph for this function:

void font_drop_chain ( DviFontRef head)

Definition at line 104 of file font.c.

105 {
106  DviFontRef *ptr;
107 
108  for(; (ptr = head); ) {
109  head = ptr->next;
110  font_drop_one(ptr);
111  }
112 }

+ Here is the caller graph for this function:

void font_drop_one ( DviFontRef ref)

Definition at line 73 of file font.c.

74 {
75  DviFont *font;
76 
77  font = ref->ref;
78  mdvi_free(ref);
79  /* drop all children */
80  for(ref = font->subfonts; ref; ref = ref->next) {
81  /* just adjust the reference counts */
82  ref->ref->links--;
83  }
84  if(--font->links == 0) {
85  /*
86  * this font doesn't have any more references, but
87  * we still keep it around in case a virtual font
88  * requests it.
89  */
90  if(font->in) {
91  fclose(font->in);
92  font->in = NULL;
93  }
94  if(LIST(font) != fontlist.tail) {
95  /* move it to the end of the list */
96  listh_remove(&fontlist, LIST(font));
97  listh_append(&fontlist, LIST(font));
98  }
99  }
100  DEBUG((DBG_FONTS, "%s: reference dropped, %d more left\n",
101  font->fontname, font->links));
102 }

+ Here is the caller graph for this function:

DviFontRef* font_find_flat ( DviContext dvi,
Int32  id 
)

Definition at line 485 of file font.c.

486 {
487  DviFontRef *ref;
488 
489  for(ref = dvi->fonts; ref; ref = ref->next)
490  if(ref->fontid == id)
491  break;
492  return ref;
493 }

+ Here is the caller graph for this function:

DviFontRef* font_find_mapped ( DviContext dvi,
Int32  id 
)

Definition at line 495 of file font.c.

496 {
497  int lo, hi, n;
498  DviFontRef **map;
499 
500  /* do a binary search */
501  lo = 0; hi = dvi->nfonts;
502  map = dvi->fontmap;
503  while(lo < hi) {
504  int sign;
505 
506  n = (hi + lo) >> 1;
507  sign = (map[n]->fontid - id);
508  if(sign == 0)
509  break;
510  else if(sign < 0)
511  lo = n;
512  else
513  hi = n;
514  }
515  if(lo >= hi)
516  return NULL;
517  return map[n];
518 }

+ Here is the caller graph for this function:

void font_finish_definitions ( DviContext dvi)

Definition at line 465 of file font.c.

466 {
467  int count;
468  DviFontRef **map, *ref;
469 
470  /* first get rid of unused fonts */
471  font_free_unused(&dvi->device);
472 
473  if(dvi->fonts == NULL) {
474  mdvi_warning(_("%s: no fonts defined\n"), dvi->filename);
475  return;
476  }
477  map = xnalloc(DviFontRef *, dvi->nfonts);
478  for(count = 0, ref = dvi->fonts; ref; ref = ref->next)
479  map[count++] = ref;
480  /* sort the array by font id */
481  qsort(map, dvi->nfonts, sizeof(DviFontRef *), compare_refs);
482  dvi->fontmap = map;
483 }

+ Here is the caller graph for this function:

int font_free_unused ( DviDevice dev)

Definition at line 114 of file font.c.

115 {
116  DviFont *font, *next;
117  int count = 0;
118 
119  DEBUG((DBG_FONTS, "destroying unused fonts\n"));
120  for(font = (DviFont *)fontlist.head; font; font = next) {
121  DviFontRef *ref;
122 
123  next = font->next;
124  if(font->links)
125  continue;
126  count++;
127  DEBUG((DBG_FONTS, "removing unused %s font `%s'\n",
128  TYPENAME(font), font->fontname));
129  listh_remove(&fontlist, LIST(font));
130  if(font->in)
131  fclose(font->in);
132  /* get rid of subfonts (but can't use `drop_chain' here) */
133  for(; (ref = font->subfonts); ) {
134  font->subfonts = ref->next;
135  mdvi_free(ref);
136  }
137  /* remove this font */
139  /* let the font destroy its private data */
140  if(font->finfo->freedata)
141  font->finfo->freedata(font);
142  /* destroy characters */
143  if(font->chars)
144  mdvi_free(font->chars);
145  mdvi_free(font->fontname);
146  mdvi_free(font->filename);
147  mdvi_free(font);
148  }
149  DEBUG((DBG_FONTS, "%d unused fonts removed\n", count));
150  return count;
151 }

+ Here is the caller graph for this function:

DviFontChar* font_get_glyph ( DviContext dvi,
DviFont font,
int  code 
)

Definition at line 346 of file font.c.

347 {
348  DviFontChar *ch;
349 
350 again:
351  /* if we have not loaded the font yet, do so now */
352  if(!font->chars && load_font_file(&dvi->params, font) < 0)
353  return NULL;
354 
355  /* get the unscaled glyph, maybe loading it from disk */
356  ch = FONTCHAR(font, code);
357  if(!ch || !glyph_present(ch))
358  return NULL;
359  if(!ch->loaded && load_one_glyph(dvi, font, code) == -1) {
360  if(font->chars == NULL) {
361  /* we need to try another font class */
362  goto again;
363  }
364  return NULL;
365  }
366  /* yes, we have to do this again */
367  ch = FONTCHAR(font, code);
368 
369  /* Got the glyph. If we also have the right scaled glyph, do no more */
370  if(!ch->width || !ch->height ||
371  font->finfo->getglyph == NULL ||
372  (dvi->params.hshrink == 1 && dvi->params.vshrink == 1))
373  return ch;
374 
375  /* If the glyph is empty, we just need to shrink the box */
376  if(ch->missing || MDVI_GLYPH_ISEMPTY(ch->glyph.data)) {
377  if(MDVI_GLYPH_UNSET(ch->shrunk.data))
378  mdvi_shrink_box(dvi, font, ch, &ch->shrunk);
379  return ch;
380  } else if(MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)) {
381  if(ch->grey.data &&
382  !MDVI_GLYPH_ISEMPTY(ch->grey.data) &&
383  ch->fg == dvi->curr_fg &&
384  ch->bg == dvi->curr_bg)
385  return ch;
386  if(ch->grey.data &&
387  !MDVI_GLYPH_ISEMPTY(ch->grey.data)) {
388  if(dvi->device.free_image)
389  dvi->device.free_image(ch->grey.data);
390  ch->grey.data = NULL;
391  }
392  font->finfo->shrink1(dvi, font, ch, &ch->grey);
393  } else if(!ch->shrunk.data)
394  font->finfo->shrink0(dvi, font, ch, &ch->shrunk);
395 
396  return ch;
397 }

+ Here is the caller graph for this function:

DviFontRef* font_reference ( DviParams params,
Int32  id,
const char *  name,
Int32  sum,
int  hdpi,
int  vdpi,
Int32  scale 
)

Definition at line 155 of file font.c.

163 {
164  DviFont *font;
165  DviFontRef *ref;
166  DviFontRef *subfont_ref;
167 
168  /* see if there is a font with the same characteristics */
169  for(font = (DviFont *)fontlist.head; font; font = font->next) {
170  if(strcmp(name, font->fontname) == 0
171  && (!sum || !font->checksum || font->checksum == sum)
172  && font->hdpi == hdpi
173  && font->vdpi == vdpi
174  && font->scale == scale)
175  break;
176  }
177  /* try to load the font */
178  if(font == NULL) {
179  font = mdvi_add_font(name, sum, hdpi, vdpi, scale);
180  if(font == NULL)
181  return NULL;
182  listh_append(&fontlist, LIST(font));
183  }
184  if(!font->links && !font->chars && load_font_file(params, font) < 0) {
185  DEBUG((DBG_FONTS, "font_reference(%s) -> Error\n", name));
186  return NULL;
187  }
188  ref = xalloc(DviFontRef);
189  ref->ref = font;
190 
191  font->links++;
192  for(subfont_ref = font->subfonts; subfont_ref; subfont_ref = subfont_ref->next) {
193  /* just adjust the reference counts */
194  subfont_ref->ref->links++;
195  }
196 
197  ref->fontid = id;
198 
199  if(LIST(font) != fontlist.head) {
200  listh_remove(&fontlist, LIST(font));
201  listh_prepend(&fontlist, LIST(font));
202  }
203 
204  DEBUG((DBG_FONTS, "font_reference(%s) -> %d links\n",
205  font->fontname, font->links));
206  return ref;
207 }

+ Here is the caller graph for this function:

int font_reopen ( DviFont font)

Definition at line 35 of file font.c.

36 {
37  if(font->in)
38  fseek(font->in, (long)0, SEEK_SET);
39  else if((font->in = fopen(font->filename, "rb")) == NULL) {
40  DEBUG((DBG_FILES, "reopen(%s) -> Error\n", font->filename));
41  return -1;
42  }
43  DEBUG((DBG_FILES, "reopen(%s) -> Ok.\n", font->filename));
44  return 0;
45 }

+ Here is the caller graph for this function:

void font_reset_chain_glyphs ( DviDevice dev,
DviFontRef head,
int  what 
)

Definition at line 452 of file font.c.

453 {
454  DviFontRef *ref;
455 
456  for(ref = head; ref; ref = ref->next)
457  font_reset_font_glyphs(dev, ref->ref, what);
458 }

+ Here is the caller graph for this function:

void font_reset_font_glyphs ( DviDevice dev,
DviFont font,
int  what 
)

Definition at line 423 of file font.c.

424 {
425  int i;
426  DviFontChar *ch;
427 
428  if(what & MDVI_FONTSEL_GLYPH)
430  if(font->subfonts) {
431  DviFontRef *ref;
432 
433  for(ref = font->subfonts; ref; ref = ref->next)
434  font_reset_font_glyphs(dev, ref->ref, what);
435  }
436  if(font->in) {
437  DEBUG((DBG_FILES, "close(%s)\n", font->filename));
438  fclose(font->in);
439  font->in = NULL;
440  }
441  if(font->finfo->getglyph == NULL)
442  return;
443  DEBUG((DBG_FONTS, "resetting glyphs in font `%s'\n", font->fontname));
444  for(ch = font->chars, i = font->loc; i <= font->hic; ch++, i++) {
445  if(glyph_present(ch))
446  font_reset_one_glyph(dev, ch, what);
447  }
448  if((what & MDVI_FONTSEL_GLYPH) && font->finfo->reset)
449  font->finfo->reset(font);
450 }

+ Here is the caller graph for this function:

void font_reset_one_glyph ( DviDevice dev,
DviFontChar ch,
int  what 
)

Definition at line 399 of file font.c.

400 {
401  if(!glyph_present(ch))
402  return;
403  if(what & MDVI_FONTSEL_BITMAP) {
406  ch->shrunk.data = NULL;
407  }
408  if(what & MDVI_FONTSEL_GREY) {
409  if(MDVI_GLYPH_NONEMPTY(ch->grey.data)) {
410  if(dev->free_image)
411  dev->free_image(ch->grey.data);
412  }
413  ch->grey.data = NULL;
414  }
415  if(what & MDVI_FONTSEL_GLYPH) {
418  ch->glyph.data = NULL;
419  ch->loaded = 0;
420  }
421 }

+ Here is the caller graph for this function:

void font_transform_glyph ( DviOrientation  orient,
DviGlyph g 
)

Definition at line 209 of file font.c.

210 {
211  BITMAP *map;
212  int x, y;
213 
214  map = (BITMAP *)g->data;
215  if(MDVI_GLYPH_ISEMPTY(map))
216  map = NULL;
217 
218  /* put the glyph in the right orientation */
219  switch(orient) {
220  case MDVI_ORIENT_TBLR:
221  break;
222  case MDVI_ORIENT_TBRL:
223  g->x = g->w - g->x;
224  if(map) bitmap_flip_horizontally(map);
225  break;
226  case MDVI_ORIENT_BTLR:
227  g->y = g->h - g->y;
228  if(map) bitmap_flip_vertically(map);
229  break;
230  case MDVI_ORIENT_BTRL:
231  g->x = g->w - g->x;
232  g->y = g->h - g->y;
233  if(map) bitmap_flip_diagonally(map);
234  break;
235  case MDVI_ORIENT_RP90:
236  if(map) bitmap_rotate_counter_clockwise(map);
237  y = g->y;
238  x = g->w - g->x;
239  g->x = y;
240  g->y = x;
241  SWAPINT(g->w, g->h);
242  break;
243  case MDVI_ORIENT_RM90:
244  if(map) bitmap_rotate_clockwise(map);
245  y = g->h - g->y;
246  x = g->x;
247  g->x = y;
248  g->y = x;
249  SWAPINT(g->w, g->h);
250  break;
251  case MDVI_ORIENT_IRP90:
253  y = g->y;
254  x = g->x;
255  g->x = y;
256  g->y = x;
257  SWAPINT(g->w, g->h);
258  break;
259  case MDVI_ORIENT_IRM90:
260  if(map) bitmap_flip_rotate_clockwise(map);
261  y = g->h - g->y;
262  x = g->w - g->x;
263  g->x = y;
264  g->y = x;
265  SWAPINT(g->w, g->h);
266  break;
267  }
268 }

+ Here is the caller graph for this function:

static int load_font_file ( DviParams params,
DviFont font 
)
static

Definition at line 48 of file font.c.

49 {
50  int status;
51 
52  if(SEARCH_DONE(font->search))
53  return -1;
54  if(font->in == NULL && font_reopen(font) < 0)
55  return -1;
56  DEBUG((DBG_FONTS, "%s: loading %s font from `%s'\n",
57  font->fontname,
58  font->finfo->name, font->filename));
59  do {
60  status = font->finfo->load(params, font);
61  } while(status < 0 && mdvi_font_retry(params, font) == 0);
62  if(status < 0)
63  return -1;
64  if(font->in) {
65  fclose(font->in);
66  font->in = NULL;
67  }
68  DEBUG((DBG_FONTS, "reload_font(%s) -> %s\n",
69  font->fontname, status < 0 ? "Error" : "Ok"));
70  return 0;
71 }

+ Here is the caller graph for this function:

static int load_one_glyph ( DviContext dvi,
DviFont font,
int  code 
)
static

Definition at line 270 of file font.c.

271 {
272  BITMAP *map;
273  DviFontChar *ch;
274  int status;
275 
276 #ifndef NODEBUG
277  ch = FONTCHAR(font, code);
278  DEBUG((DBG_GLYPHS, "loading glyph code %d in %s (at %u)\n",
279  code, font->fontname, ch->offset));
280 #endif
281  if(font->finfo->getglyph == NULL) {
282  /* font type does not need to load glyphs (e.g. vf) */
283  return 0;
284  }
285 
286  status = font->finfo->getglyph(&dvi->params, font, code);
287  if(status < 0)
288  return -1;
289  /* get the glyph again (font->chars may have changed) */
290  ch = FONTCHAR(font, code);
291 #ifndef NODEBUG
292  map = (BITMAP *)ch->glyph.data;
293  if(DEBUGGING(BITMAP_DATA)) {
295  "%s: new %s bitmap for character %d:\n",
296  font->fontname, TYPENAME(font), code));
297  if(MDVI_GLYPH_ISEMPTY(map))
298  DEBUG((DBG_BITMAP_DATA, "blank bitmap\n"));
299  else
300  bitmap_print(stderr, map);
301  }
302 #endif
303  /* check if we have to scale it */
304  if(!font->finfo->scalable && font->hdpi != font->vdpi) {
305  int hs, vs, d;
306 
307  /* we scale it ourselves */
308  d = Max(font->hdpi, font->vdpi);
309  hs = d / font->hdpi;
310  vs = d / font->vdpi;
311  if(ch->width && ch->height && (hs > 1 || vs > 1)) {
312  int h, v;
313  DviGlyph glyph;
314 
315  DEBUG((DBG_FONTS,
316  "%s: scaling glyph %d to resolution %dx%d\n",
317  font->fontname, code, font->hdpi, font->vdpi));
318  h = dvi->params.hshrink;
319  v = dvi->params.vshrink;
320  d = dvi->params.density;
321  dvi->params.hshrink = hs;
322  dvi->params.vshrink = vs;
323  dvi->params.density = 50;
324  /* shrink it */
325  font->finfo->shrink0(dvi, font, ch, &glyph);
326  /* restore parameters */
327  dvi->params.hshrink = h;
328  dvi->params.vshrink = v;
329  dvi->params.density = d;
330  /* update glyph data */
331  if(!MDVI_GLYPH_ISEMPTY(ch->glyph.data))
333  ch->glyph.data = glyph.data;
334  ch->glyph.x = glyph.x;
335  ch->glyph.y = glyph.y;
336  ch->glyph.w = glyph.w;
337  ch->glyph.h = glyph.h;
338  }
339 
340  }
342 
343  return 0;
344 }

+ Here is the caller graph for this function:

void vf_free_macros ( DviFont )

Variable Documentation

char* _mdvi_fallback_font

Definition at line 65 of file fontsrch.c.

ListHead fontlist
static

Definition at line 25 of file font.c.