1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | #include <X11/Xos.h> |
8 | #include <X11/IntrinsicP.h> |
9 | #include <X11/StringDefs.h> |
10 | #include <stdio.h> |
11 | #include <stdlib.h> |
12 | #include <ctype.h> |
13 | #include "DviP.h" |
14 | #include "XFontName.h" |
15 | |
16 | static char * |
17 | savestr (const char *s) |
18 | { |
19 | char *n; |
20 | |
21 | if (!s) |
22 | return NULL((void*)0); |
23 | n = XtMalloc (strlen (s) + 1); |
24 | if (n) |
25 | strcpy (n, s)__builtin___strcpy_chk (n, s, __builtin_object_size (n, 2 > 1 ? 1 : 0)); |
26 | return n; |
27 | } |
28 | |
29 | static DviFontList * |
30 | LookupFontByPosition (DviWidget dw, int position) |
31 | { |
32 | DviFontList *f; |
33 | |
34 | for (f = dw->dvi.fonts; f; f=f->next) |
35 | if (f->dvi_number == position) |
36 | break; |
37 | return f; |
38 | } |
39 | |
40 | static DviFontSizeList * |
41 | LookupFontSizeBySize (DviWidget dw, DviFontList *f, int size) |
42 | { |
43 | DviFontSizeList *fs, *best = NULL((void*)0); |
44 | int bestdist; |
45 | char fontNameString[2048]; |
46 | XFontName fontName; |
47 | unsigned int fontNameAttributes; |
48 | int dist; |
49 | |
50 | if (f->scalable) |
51 | { |
52 | for (best = f->sizes; best; best = best->next) |
53 | if (best->size == size) |
54 | return best; |
55 | best = (DviFontSizeList *) XtMalloc (sizeof *best); |
56 | best->next = f->sizes; |
57 | best->size = size; |
58 | XParseFontName (f->x_name, &fontName, &fontNameAttributes); |
59 | fontNameAttributes &= ~(FontNamePixelSize(1<<7)|FontNameAverageWidth(1<<12)); |
60 | fontNameAttributes |= FontNameResolutionX(1<<9); |
61 | fontNameAttributes |= FontNameResolutionY(1<<10); |
62 | fontNameAttributes |= FontNamePointSize(1<<8); |
63 | fontName.ResolutionX = dw->dvi.screen_resolution; |
64 | fontName.ResolutionY = dw->dvi.screen_resolution; |
65 | fontName.PointSize = size * 10 / dw->dvi.size_scale; |
66 | XFormatFontName (&fontName, fontNameAttributes, fontNameString); |
67 | best->x_name = savestr (fontNameString); |
68 | #ifdef USE_XFT |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | best->core = False0; |
75 | if (!strcmp (fontName.CharSetRegistry, "adobe") && |
76 | !strcmp (fontName.CharSetEncoding, "fontspecific")) |
77 | { |
78 | best->core = True1; |
79 | } |
80 | #endif |
81 | best->doesnt_exist = 0; |
82 | best->font = NULL((void*)0); |
83 | f->sizes = best; |
84 | } |
85 | else |
86 | { |
87 | bestdist = 65536; |
88 | for (fs = f->sizes; fs; fs=fs->next) { |
89 | dist = size - fs->size; |
90 | if (dist < 0) |
91 | dist = -dist * 16; |
92 | if (dist < bestdist) |
93 | { |
94 | best = fs; |
95 | bestdist = dist; |
96 | } |
97 | } |
98 | } |
99 | return best; |
100 | } |
101 | |
102 | static char * |
103 | SkipFontNameElement (char *n) |
104 | { |
105 | while (*n != '-') |
106 | if (!*++n) |
107 | return NULL((void*)0); |
108 | return n+1; |
109 | } |
110 | |
111 | # define SizePosition8 8 |
112 | # define EncodingPosition13 13 |
113 | |
114 | #ifndef USE_XFT |
115 | static int |
116 | ConvertFontNameToSize (char *n) |
117 | { |
118 | int i, size; |
119 | |
120 | for (i = 0; i < SizePosition8; i++) { |
121 | n = SkipFontNameElement (n); |
122 | if (!n) |
123 | return -1; |
124 | } |
125 | size = atoi (n); |
126 | return size/10; |
127 | } |
128 | #endif |
129 | |
130 | static char * |
131 | ConvertFontNameToEncoding (char *n) |
132 | { |
133 | int i; |
134 | for (i = 0; i < EncodingPosition13; i++) { |
135 | n = SkipFontNameElement (n); |
136 | if (!n) |
137 | return NULL((void*)0); |
138 | } |
139 | return n; |
140 | } |
141 | |
142 | static void |
143 | DisposeFontSizes (DviWidget dw, DviFontSizeList *fs) |
144 | { |
145 | DviFontSizeList *next; |
146 | |
147 | for (; fs; fs=next) { |
148 | next = fs->next; |
149 | if (fs->x_name) |
150 | XtFree (fs->x_name); |
151 | if (fs->font) |
152 | { |
153 | #ifdef USE_XFT |
154 | XftFontClose (XtDisplay (dw)(((dw)->core.screen)->display), fs->font); |
155 | #else |
156 | XUnloadFont (XtDisplay (dw)(((dw)->core.screen)->display), fs->font->fid); |
157 | XFree ((char *)fs->font); |
158 | #endif |
159 | } |
160 | XtFree ((char *) fs); |
161 | } |
162 | } |
163 | |
164 | void |
165 | ResetFonts (DviWidget dw) |
166 | { |
167 | DviFontList *f; |
168 | |
169 | for (f = dw->dvi.fonts; f; f = f->next) |
170 | { |
171 | if (f->initialized) |
172 | { |
173 | DisposeFontSizes (dw, f->sizes); |
174 | f->sizes = NULL((void*)0); |
175 | f->initialized = FALSE0; |
176 | f->scalable = FALSE0; |
177 | } |
178 | } |
179 | |
180 | |
181 | |
182 | dw->dvi.font = NULL((void*)0); |
183 | dw->dvi.font_number = -1; |
184 | dw->dvi.cache.font = NULL((void*)0); |
185 | dw->dvi.cache.font_number = -1; |
186 | } |
187 | |
188 | static DviFontSizeList * |
189 | InstallFontSizes (DviWidget dw, char *x_name, Boolean *scalablep) |
190 | { |
191 | #ifndef USE_XFT |
192 | char fontNameString[2048]; |
193 | char **fonts; |
194 | int i, count; |
195 | int size; |
196 | DviFontSizeList *new; |
197 | XFontName fontName; |
198 | unsigned int fontNameAttributes; |
199 | #endif |
200 | DviFontSizeList *sizes; |
201 | |
202 | sizes = NULL((void*)0); |
203 | #ifdef USE_XFT |
204 | *scalablep = TRUE1; |
205 | #else |
206 | *scalablep = FALSE0; |
207 | if (!XParseFontName (x_name, &fontName, &fontNameAttributes)) |
208 | return NULL((void*)0); |
209 | |
210 | fontNameAttributes &= ~(FontNamePixelSize(1<<7)|FontNamePointSize(1<<8)); |
211 | fontNameAttributes |= FontNameResolutionX(1<<9); |
212 | fontNameAttributes |= FontNameResolutionY(1<<10); |
213 | fontName.ResolutionX = dw->dvi.screen_resolution; |
214 | fontName.ResolutionY = dw->dvi.screen_resolution; |
215 | XFormatFontName (&fontName, fontNameAttributes, fontNameString); |
216 | fonts = XListFonts (XtDisplay (dw)(((dw)->core.screen)->display), fontNameString, 10000000, &count); |
217 | for (i = 0; i < count; i++) { |
218 | size = ConvertFontNameToSize (fonts[i]); |
219 | if (size == 0) |
220 | { |
221 | DisposeFontSizes (dw, sizes); |
222 | *scalablep = TRUE1; |
223 | sizes = NULL((void*)0); |
224 | break; |
225 | } |
226 | if (size != -1) { |
227 | new = (DviFontSizeList *) XtMalloc (sizeof *new); |
228 | new->next = sizes; |
229 | new->size = size; |
230 | new->x_name = savestr (fonts[i]); |
231 | new->doesnt_exist = 0; |
232 | new->font = NULL((void*)0); |
233 | sizes = new; |
234 | } |
235 | } |
236 | XFreeFontNames (fonts); |
237 | #endif |
238 | return sizes; |
239 | } |
240 | |
241 | static DviFontList * |
242 | InstallFont (DviWidget dw, int position, const char *dvi_name, const char *x_name) |
243 | { |
244 | DviFontList *f; |
245 | const char *encoding; |
246 | |
247 | f = LookupFontByPosition (dw, position); |
248 | if (f) { |
249 | |
250 | |
251 | |
252 | if (!strcmp (f->dvi_name, dvi_name) && !strcmp (f->x_name, x_name)) |
253 | return f; |
254 | |
255 | DisposeFontSizes (dw, f->sizes); |
256 | if (f->dvi_name) |
257 | XtFree (f->dvi_name); |
258 | if (f->x_name) |
259 | XtFree (f->x_name); |
260 | } else { |
261 | f = (DviFontList *) XtMalloc (sizeof (*f)); |
262 | f->next = dw->dvi.fonts; |
263 | dw->dvi.fonts = f; |
264 | } |
265 | f->initialized = FALSE0; |
266 | f->dvi_name = savestr (dvi_name); |
267 | f->x_name = savestr (x_name); |
268 | f->dvi_number = position; |
269 | f->sizes = NULL((void*)0); |
270 | f->scalable = FALSE0; |
271 | if (f->x_name) { |
272 | encoding = ConvertFontNameToEncoding (f->x_name); |
273 | f->char_map = DviFindMap (encoding); |
274 | } else |
275 | f->char_map = NULL((void*)0); |
276 | |
277 | |
278 | |
279 | dw->dvi.font = NULL((void*)0); |
280 | dw->dvi.font_number = -1; |
281 | dw->dvi.cache.font = NULL((void*)0); |
282 | dw->dvi.cache.font_number = -1; |
283 | return f; |
284 | } |
285 | |
286 | static const char * |
287 | MapDviNameToXName (DviWidget dw, const char *dvi_name) |
288 | { |
289 | DviFontMap *fm; |
290 | |
291 | for (fm = dw->dvi.font_map; fm; fm=fm->next) |
| 2 | | Assuming pointer value is null | |
|
| 3 | | Loop condition is false. Execution continues on line 294 | |
|
292 | if (!strcmp (fm->dvi_name, dvi_name)) |
293 | return fm->x_name; |
294 | ++dvi_name; |
295 | for (fm = dw->dvi.font_map; fm; fm=fm->next) |
| 4 | | Loop condition is false. Execution continues on line 298 | |
|
296 | if (!strcmp (fm->dvi_name, "R")) |
297 | return fm->x_name; |
298 | if (dw->dvi.font_map->x_name) |
| 5 | | Access to field 'x_name' results in a dereference of a null pointer (loaded from field 'font_map') |
|
299 | return dw->dvi.font_map->x_name; |
300 | return "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-1"; |
301 | } |
302 | |
303 | |
304 | void |
305 | ParseFontMap (DviWidget dw) |
306 | { |
307 | char dvi_name[1024]; |
308 | char x_name[2048]; |
309 | char *m, *s; |
310 | DviFontMap *fm, *new; |
311 | |
312 | if (dw->dvi.font_map) |
313 | DestroyFontMap (dw->dvi.font_map); |
314 | fm = NULL((void*)0); |
315 | m = dw->dvi.font_map_string; |
316 | while (*m) { |
317 | s = m; |
318 | while (*m && !isspace (*m)) |
319 | ++m; |
320 | strncpy (dvi_name, s, m-s)__builtin___strncpy_chk (dvi_name, s, m-s, __builtin_object_size (dvi_name, 2 > 1 ? 1 : 0)); |
321 | dvi_name[m-s] = '\0'; |
322 | while (isspace (*m)) |
323 | ++m; |
324 | s = m; |
325 | while (*m && *m != '\n') |
326 | ++m; |
327 | strncpy (x_name, s, m-s)__builtin___strncpy_chk (x_name, s, m-s, __builtin_object_size (x_name, 2 > 1 ? 1 : 0)); |
328 | x_name[m-s] = '\0'; |
329 | new = (DviFontMap *) XtMalloc (sizeof *new); |
330 | new->x_name = savestr (x_name); |
331 | new->dvi_name = savestr (dvi_name); |
332 | new->next = fm; |
333 | fm = new; |
334 | ++m; |
335 | } |
336 | dw->dvi.font_map = fm; |
337 | } |
338 | |
339 | void |
340 | DestroyFontMap (DviFontMap *font_map) |
341 | { |
342 | DviFontMap *next; |
343 | |
344 | for (; font_map; font_map = next) { |
345 | next = font_map->next; |
346 | if (font_map->x_name) |
347 | XtFree (font_map->x_name); |
348 | if (font_map->dvi_name) |
349 | XtFree (font_map->dvi_name); |
350 | XtFree ((char *) font_map); |
351 | } |
352 | } |
353 | |
354 | |
355 | void |
356 | SetFontPosition (DviWidget dw, int position, const char *dvi_name, const char *extra) |
357 | { |
358 | const char *x_name; |
359 | |
360 | x_name = MapDviNameToXName (dw, dvi_name); |
| 1 | Calling 'MapDviNameToXName' | |
|
361 | (void) InstallFont (dw, position, dvi_name, x_name); |
362 | } |
363 | |
364 | #ifdef USE_XFT |
365 | XftFont * |
366 | #else |
367 | XFontStruct * |
368 | #endif |
369 | QueryFont (DviWidget dw, int position, int size) |
370 | { |
371 | DviFontList *f; |
372 | DviFontSizeList *fs; |
373 | |
374 | f = LookupFontByPosition (dw, position); |
375 | if (!f) |
376 | return dw->dvi.default_font; |
377 | if (!f->initialized) { |
378 | f->sizes = InstallFontSizes (dw, f->x_name, &f->scalable); |
379 | f->initialized = TRUE1; |
380 | } |
381 | fs = LookupFontSizeBySize (dw, f, size); |
382 | if (!fs) |
383 | return dw->dvi.default_font; |
384 | if (!fs->font) { |
385 | if (fs->x_name) |
386 | { |
387 | #ifdef USE_XFT |
388 | XftPattern *pat; |
389 | XftPattern *match; |
390 | XftResult result; |
391 | |
392 | pat = XftXlfdParse (fs->x_name, False0, False0); |
393 | XftPatternAddBool (pat, XFT_CORE, fs->core); |
394 | match = XftFontMatch (XtDisplay (dw)(((dw)->core.screen)->display), |
395 | XScreenNumberOfScreen(dw->core.screen), |
396 | pat, &result); |
397 | XftPatternDestroy (pat); |
398 | if (match) |
399 | { |
400 | fs->font = XftFontOpenPattern (XtDisplay (dw)(((dw)->core.screen)->display), |
401 | match); |
402 | if (!fs->font) |
403 | XftPatternDestroy (match); |
404 | } |
405 | else |
406 | fs->font = 0; |
407 | #else |
408 | fs->font = XLoadQueryFont (XtDisplay (dw)(((dw)->core.screen)->display), fs->x_name); |
409 | #endif |
410 | } |
411 | if (!fs->font) |
412 | fs->font = dw->dvi.default_font; |
413 | } |
414 | return fs->font; |
415 | } |
416 | |
417 | DviCharNameMap * |
418 | QueryFontMap (DviWidget dw, int position) |
419 | { |
420 | DviFontList *f; |
421 | |
422 | f = LookupFontByPosition (dw, position); |
423 | if (f) |
424 | return f->char_map; |
425 | else |
426 | return NULL((void*)0); |
427 | } |
428 | |
429 | unsigned char * |
430 | DviCharIsLigature (DviCharNameMap *map, const char *name) |
431 | { |
432 | int i; |
433 | |
434 | for (i = 0; i < DVI_MAX_LIGATURES16; i++) { |
435 | if (!map->ligatures[i][0]) |
436 | break; |
437 | if (!strcmp (name, map->ligatures[i][0])) |
438 | return (unsigned char *) map->ligatures[i][1]; |
439 | } |
440 | return NULL((void*)0); |
441 | } |