Bug Summary

File:backend/dvi/mdvi-lib/font.c
Warning:line 214, column 6
Using a fixed address is not portable because that address will probably not be valid in all environments or platforms

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name font.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/backend/dvi/mdvi-lib -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../../.. -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/backend/dvi/mdvi-lib -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-02-17-123621-54189-1 -x c font.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#include <config.h>
20#include <stdlib.h>
21
22#include "mdvi.h"
23#include "private.h"
24
25static ListHead fontlist;
26
27extern char *_mdvi_fallback_font;
28
29extern void vf_free_macros(DviFont *);
30
31#define finfosearch.info search.info
32#define TYPENAME(font)((font)->search.info ? (font)->search.info->name : "none"
)
\
33 ((font)->finfosearch.info ? (font)->finfosearch.info->name : "none")
34
35int font_reopen(DviFont *font)
36{
37 if(font->in)
38 fseek(font->in, (long)0, SEEK_SET0);
39 else if((font->in = fopenkpse_fopen_trace(font->filename, "rb")) == NULL((void*)0)) {
40 DEBUG((DBG_FILES, "reopen(%s) -> Error\n", font->filename))__debug ((1 << 2), "reopen(%s) -> Error\n", font->
filename)
;
41 return -1;
42 }
43 DEBUG((DBG_FILES, "reopen(%s) -> Ok.\n", font->filename))__debug ((1 << 2), "reopen(%s) -> Ok.\n", font->filename
)
;
44 return 0;
45}
46
47/* used from context: params and device */
48static int load_font_file(DviParams *params, DviFont *font)
49{
50 int status;
51
52 if(SEARCH_DONE(font->search)((font->search).id < 0))
53 return -1;
54 if(font->in == NULL((void*)0) && font_reopen(font) < 0)
55 return -1;
56 DEBUG((DBG_FONTS, "%s: loading %s font from `%s'\n",__debug ((1 << 1), "%s: loading %s font from `%s'\n", font
->fontname, font->search.info->name, font->filename
)
57 font->fontname,__debug ((1 << 1), "%s: loading %s font from `%s'\n", font
->fontname, font->search.info->name, font->filename
)
58 font->finfo->name, font->filename))__debug ((1 << 1), "%s: loading %s font from `%s'\n", font
->fontname, font->search.info->name, font->filename
)
;
59 do {
60 status = font->finfosearch.info->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 fclosekpse_fclose_trace(font->in);
66 font->in = NULL((void*)0);
67 }
68 DEBUG((DBG_FONTS, "reload_font(%s) -> %s\n",__debug ((1 << 1), "reload_font(%s) -> %s\n", font->
fontname, status < 0 ? "Error" : "Ok")
69 font->fontname, status < 0 ? "Error" : "Ok"))__debug ((1 << 1), "reload_font(%s) -> %s\n", font->
fontname, status < 0 ? "Error" : "Ok")
;
70 return 0;
71}
72
73void font_drop_one(DviFontRef *ref)
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 fclosekpse_fclose_trace(font->in);
92 font->in = NULL((void*)0);
93 }
94 if(LIST(font)((List *)(font)) != fontlist.tail) {
95 /* move it to the end of the list */
96 listh_remove(&fontlist, LIST(font)((List *)(font)));
97 listh_append(&fontlist, LIST(font)((List *)(font)));
98 }
99 }
100 DEBUG((DBG_FONTS, "%s: reference dropped, %d more left\n",__debug ((1 << 1), "%s: reference dropped, %d more left\n"
, font->fontname, font->links)
101 font->fontname, font->links))__debug ((1 << 1), "%s: reference dropped, %d more left\n"
, font->fontname, font->links)
;
102}
103
104void font_drop_chain(DviFontRef *head)
105{
106 DviFontRef *ptr;
107
108 for(; (ptr = head); ) {
109 head = ptr->next;
110 font_drop_one(ptr);
111 }
112}
113
114int font_free_unused(DviDevice *dev)
115{
116 DviFont *font, *next;
117 int count = 0;
118
119 DEBUG((DBG_FONTS, "destroying unused fonts\n"))__debug ((1 << 1), "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",__debug ((1 << 1), "removing unused %s font `%s'\n", ((
font)->search.info ? (font)->search.info->name : "none"
), font->fontname)
128 TYPENAME(font), font->fontname))__debug ((1 << 1), "removing unused %s font `%s'\n", ((
font)->search.info ? (font)->search.info->name : "none"
), font->fontname)
;
129 listh_remove(&fontlist, LIST(font)((List *)(font)));
130 if(font->in)
131 fclosekpse_fclose_trace(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 */
138 font_reset_font_glyphs(dev, font, MDVI_FONTSEL_GLYPH(1 << 2));
139 /* let the font destroy its private data */
140 if(font->finfosearch.info->freedata)
141 font->finfosearch.info->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))__debug ((1 << 1), "%d unused fonts removed\n", count);
150 return count;
151}
152
153/* used from context: params and device */
154DviFontRef *
155font_reference(
156 DviParams *params, /* rendering parameters */
157 Int32 id, /* external id number */
158 const char *name, /* font name */
159 Int32 sum, /* checksum (from DVI of VF) */
160 int hdpi, /* resolution */
161 int vdpi,
162 Int32 scale) /* scaling factor (from DVI or VF) */
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((void*)0)) {
179 font = mdvi_add_font(name, sum, hdpi, vdpi, scale);
180 if(font == NULL((void*)0))
181 return NULL((void*)0);
182 listh_append(&fontlist, LIST(font)((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))__debug ((1 << 1), "font_reference(%s) -> Error\n", name
)
;
186 return NULL((void*)0);
187 }
188 ref = xalloc(DviFontRef)(DviFontRef *)mdvi_malloc(sizeof(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)((List *)(font)) != fontlist.head) {
200 listh_remove(&fontlist, LIST(font)((List *)(font)));
201 listh_prepend(&fontlist, LIST(font)((List *)(font)));
202 }
203
204 DEBUG((DBG_FONTS, "font_reference(%s) -> %d links\n",__debug ((1 << 1), "font_reference(%s) -> %d links\n"
, font->fontname, font->links)
205 font->fontname, font->links))__debug ((1 << 1), "font_reference(%s) -> %d links\n"
, font->fontname, font->links)
;
206 return ref;
207}
208
209void font_transform_glyph(DviOrientation orient, DviGlyph *g)
210{
211 BITMAP *map;
212 int x, y;
213
214 map = (BITMAP *)g->data;
25
Using a fixed address is not portable because that address will probably not be valid in all environments or platforms
215 if(MDVI_GLYPH_ISEMPTY(map)((map) == ((void *)1)))
216 map = NULL((void*)0);
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)({ int _s = g->w; g->w = g->h; g->h = _s; });
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)({ int _s = g->w; g->w = g->h; g->h = _s; });
250 break;
251 case MDVI_ORIENT_IRP90:
252 if(map) bitmap_flip_rotate_counter_clockwise(map);
253 y = g->y;
254 x = g->x;
255 g->x = y;
256 g->y = x;
257 SWAPINT(g->w, g->h)({ int _s = g->w; g->w = g->h; g->h = _s; });
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)({ int _s = g->w; g->w = g->h; g->h = _s; });
266 break;
267 }
268}
269
270static int load_one_glyph(DviContext *dvi, DviFont *font, int code)
271{
272 BITMAP *map;
273 DviFontChar *ch;
274 int status;
275
276#ifndef NODEBUG
277 ch = FONTCHAR(font, code)(((code) < font->loc || (code) > font->hic || !(font
)->chars) ? ((void*)0) : &font->chars[(code) - (font
)->loc])
;
8
'?' condition is false
278 DEBUG((DBG_GLYPHS, "loading glyph code %d in %s (at %u)\n",__debug ((1 << 7), "loading glyph code %d in %s (at %u)\n"
, code, font->fontname, ch->offset)
279 code, font->fontname, ch->offset))__debug ((1 << 7), "loading glyph code %d in %s (at %u)\n"
, code, font->fontname, ch->offset)
;
280#endif
281 if(font->finfosearch.info->getglyph == NULL((void*)0)) {
9
Assuming field 'getglyph' is not equal to NULL
10
Taking false branch
282 /* font type does not need to load glyphs (e.g. vf) */
283 return 0;
284 }
285
286 status = font->finfosearch.info->getglyph(&dvi->params, font, code);
287 if(status < 0)
11
Assuming 'status' is >= 0
288 return -1;
289 /* get the glyph again (font->chars may have changed) */
290 ch = FONTCHAR(font, code)(((code) < font->loc || (code) > font->hic || !(font
)->chars) ? ((void*)0) : &font->chars[(code) - (font
)->loc])
;
12
Taking false branch
13
Assuming 'code' is >= field 'loc'
14
Assuming 'code' is <= field 'hic'
15
Assuming field 'chars' is non-null
16
'?' condition is false
291#ifndef NODEBUG
292 map = (BITMAP *)ch->glyph.data;
293 if(DEBUGGING(BITMAP_DATA)(_mdvi_debug_mask & (1 << 13))) {
17
Assuming the condition is true
18
Taking true branch
294 DEBUG((DBG_BITMAP_DATA,__debug ((1 << 13), "%s: new %s bitmap for character %d:\n"
, font->fontname, ((font)->search.info ? (font)->search
.info->name : "none"), code)
19
Assuming field 'info' is non-null
20
'?' condition is true
295 "%s: new %s bitmap for character %d:\n",__debug ((1 << 13), "%s: new %s bitmap for character %d:\n"
, font->fontname, ((font)->search.info ? (font)->search
.info->name : "none"), code)
296 font->fontname, TYPENAME(font), code))__debug ((1 << 13), "%s: new %s bitmap for character %d:\n"
, font->fontname, ((font)->search.info ? (font)->search
.info->name : "none"), code)
;
297 if(MDVI_GLYPH_ISEMPTY(map)((map) == ((void *)1)))
21
Assuming 'map' is equal to 1
22
Taking true branch
298 DEBUG((DBG_BITMAP_DATA, "blank bitmap\n"))__debug ((1 << 13), "blank bitmap\n");
299 else
300 bitmap_print(stderrstderr, map);
301 }
302#endif
303 /* check if we have to scale it */
304 if(!font->finfosearch.info->scalable && font->hdpi != font->vdpi) {
23
Assuming field 'scalable' is not equal to 0
305 int hs, vs, d;
306
307 /* we scale it ourselves */
308 d = Max(font->hdpi, font->vdpi)(((font->hdpi) > (font->vdpi)) ? (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,__debug ((1 << 1), "%s: scaling glyph %d to resolution %dx%d\n"
, font->fontname, code, font->hdpi, font->vdpi)
316 "%s: scaling glyph %d to resolution %dx%d\n",__debug ((1 << 1), "%s: scaling glyph %d to resolution %dx%d\n"
, font->fontname, code, font->hdpi, font->vdpi)
317 font->fontname, code, font->hdpi, font->vdpi))__debug ((1 << 1), "%s: scaling glyph %d to resolution %dx%d\n"
, 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->finfosearch.info->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)((ch->glyph.data) == ((void *)1)))
332 bitmap_destroy((BITMAP *)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 }
341 font_transform_glyph(dvi->params.orientation, &ch->glyph);
24
Calling 'font_transform_glyph'
342
343 return 0;
344}
345
346DviFontChar *font_get_glyph(DviContext *dvi, DviFont *font, int code)
347{
348 DviFontChar *ch;
349
350again:
351 /* if we have not loaded the font yet, do so now */
352 if(!font->chars && load_font_file(&dvi->params, font) < 0)
1
Assuming field 'chars' is non-null
353 return NULL((void*)0);
354
355 /* get the unscaled glyph, maybe loading it from disk */
356 ch = FONTCHAR(font, code)(((code) < font->loc || (code) > font->hic || !(font
)->chars) ? ((void*)0) : &font->chars[(code) - (font
)->loc])
;
2
Assuming 'code' is >= field 'loc'
3
Assuming 'code' is <= field 'hic'
4
'?' condition is false
357 if(!ch
4.1
'ch' is non-null
|| !glyph_present(ch)((ch) && (ch)->offset))
5
Assuming the condition is false
358 return NULL((void*)0);
359 if(!ch->loaded && load_one_glyph(dvi, font, code) == -1) {
6
Assuming field 'loaded' is 0
7
Calling 'load_one_glyph'
360 if(font->chars == NULL((void*)0)) {
361 /* we need to try another font class */
362 goto again;
363 }
364 return NULL((void*)0);
365 }
366 /* yes, we have to do this again */
367 ch = FONTCHAR(font, code)(((code) < font->loc || (code) > font->hic || !(font
)->chars) ? ((void*)0) : &font->chars[(code) - (font
)->loc])
;
368
369 /* Got the glyph. If we also have the right scaled glyph, do no more */
370 if(!ch->width || !ch->height ||
371 font->finfosearch.info->getglyph == NULL((void*)0) ||
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)((ch->glyph.data) == ((void *)1))) {
377 if(MDVI_GLYPH_UNSET(ch->shrunk.data)((ch->shrunk.data) == ((void*)0)))
378 mdvi_shrink_box(dvi, font, ch, &ch->shrunk);
379 return ch;
380 } else if(MDVI_ENABLED(dvi, MDVI_PARAM_ANTIALIASED)((dvi)->params.flags & (1))) {
381 if(ch->grey.data &&
382 !MDVI_GLYPH_ISEMPTY(ch->grey.data)((ch->grey.data) == ((void *)1)) &&
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)((ch->grey.data) == ((void *)1))) {
388 if(dvi->device.free_image)
389 dvi->device.free_image(ch->grey.data);
390 ch->grey.data = NULL((void*)0);
391 }
392 font->finfosearch.info->shrink1(dvi, font, ch, &ch->grey);
393 } else if(!ch->shrunk.data)
394 font->finfosearch.info->shrink0(dvi, font, ch, &ch->shrunk);
395
396 return ch;
397}
398
399void font_reset_one_glyph(DviDevice *dev, DviFontChar *ch, int what)
400{
401 if(!glyph_present(ch)((ch) && (ch)->offset))
402 return;
403 if(what & MDVI_FONTSEL_BITMAP(1 << 0)) {
404 if(MDVI_GLYPH_NONEMPTY(ch->shrunk.data)((ch->shrunk.data) && (ch->shrunk.data) != ((void
*)1))
)
405 bitmap_destroy((BITMAP *)ch->shrunk.data);
406 ch->shrunk.data = NULL((void*)0);
407 }
408 if(what & MDVI_FONTSEL_GREY(1 << 1)) {
409 if(MDVI_GLYPH_NONEMPTY(ch->grey.data)((ch->grey.data) && (ch->grey.data) != ((void *
)1))
) {
410 if(dev->free_image)
411 dev->free_image(ch->grey.data);
412 }
413 ch->grey.data = NULL((void*)0);
414 }
415 if(what & MDVI_FONTSEL_GLYPH(1 << 2)) {
416 if(MDVI_GLYPH_NONEMPTY(ch->glyph.data)((ch->glyph.data) && (ch->glyph.data) != ((void
*)1))
)
417 bitmap_destroy((BITMAP *)ch->glyph.data);
418 ch->glyph.data = NULL((void*)0);
419 ch->loaded = 0;
420 }
421}
422
423void font_reset_font_glyphs(DviDevice *dev, DviFont *font, int what)
424{
425 int i;
426 DviFontChar *ch;
427
428 if(what & MDVI_FONTSEL_GLYPH(1 << 2))
429 what |= MDVI_FONTSEL_BITMAP(1 << 0)|MDVI_FONTSEL_GREY(1 << 1);
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))__debug ((1 << 2), "close(%s)\n", font->filename);
438 fclosekpse_fclose_trace(font->in);
439 font->in = NULL((void*)0);
440 }
441 if(font->finfosearch.info->getglyph == NULL((void*)0))
442 return;
443 DEBUG((DBG_FONTS, "resetting glyphs in font `%s'\n", font->fontname))__debug ((1 << 1), "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)((ch) && (ch)->offset))
446 font_reset_one_glyph(dev, ch, what);
447 }
448 if((what & MDVI_FONTSEL_GLYPH(1 << 2)) && font->finfosearch.info->reset)
449 font->finfosearch.info->reset(font);
450}
451
452void font_reset_chain_glyphs(DviDevice *dev, DviFontRef *head, int what)
453{
454 DviFontRef *ref;
455
456 for(ref = head; ref; ref = ref->next)
457 font_reset_font_glyphs(dev, ref->ref, what);
458}
459
460static int compare_refs(const void *p1, const void *p2)
461{
462 return ((*(DviFontRef **)p1)->fontid - (*(DviFontRef **)p2)->fontid);
463}
464
465void font_finish_definitions(DviContext *dvi)
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((void*)0)) {
474 mdvi_warning(_("%s: no fonts defined\n")gettext("%s: no fonts defined\n"), dvi->filename);
475 return;
476 }
477 map = xnalloc(DviFontRef *, dvi->nfonts)(DviFontRef * *)mdvi_calloc((dvi->nfonts), sizeof(DviFontRef
*))
;
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}
484
485DviFontRef *font_find_flat(DviContext *dvi, Int32 id)
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}
494
495DviFontRef *font_find_mapped(DviContext *dvi, Int32 id)
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((void*)0);
517 return map[n];
518}
519