1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | #ifdef HAVE_CONFIG_H1 |
32 | #include <config.h> |
33 | #endif |
34 | #include <X11/fonts/fntfilst.h> |
35 | #include <X11/keysym.h> |
36 | |
37 | #if HAVE_STDINT_H1 |
38 | #include <stdint.h> |
39 | #elif !defined(INT32_MAX(2147483647)) |
40 | #define INT32_MAX(2147483647) 0x7fffffff |
41 | #endif |
42 | |
43 | Bool |
44 | FontFileInitTable (FontTablePtr table, int size) |
45 | { |
46 | if (size < 0 || (size > INT32_MAX(2147483647)/sizeof(FontEntryRec))) |
47 | return FALSE0; |
48 | if (size) |
49 | { |
50 | table->entries = malloc(sizeof(FontEntryRec) * size); |
51 | if (!table->entries) |
52 | return FALSE0; |
53 | } |
54 | else |
55 | table->entries = 0; |
56 | table->used = 0; |
57 | table->size = size; |
58 | table->sorted = FALSE0; |
59 | return TRUE1; |
60 | } |
61 | |
62 | void |
63 | FontFileFreeEntry (FontEntryPtr entry) |
64 | { |
65 | FontScalableExtraPtr extra; |
66 | int i; |
67 | |
68 | if (entry->name.name) |
69 | free(entry->name.name); |
70 | entry->name.name = NULL((void*)0); |
71 | |
72 | switch (entry->type) |
73 | { |
74 | case FONT_ENTRY_SCALABLE0: |
75 | free (entry->u.scalable.fileName); |
76 | extra = entry->u.scalable.extra; |
77 | for (i = 0; i < extra->numScaled; i++) |
78 | if (extra->scaled[i].vals.ranges) |
79 | free (extra->scaled[i].vals.ranges); |
80 | free (extra->scaled); |
81 | free (extra); |
82 | break; |
83 | case FONT_ENTRY_BITMAP2: |
84 | free (entry->u.bitmap.fileName); |
85 | entry->u.bitmap.fileName = NULL((void*)0); |
86 | break; |
87 | case FONT_ENTRY_ALIAS3: |
88 | free (entry->u.alias.resolved); |
89 | entry->u.alias.resolved = NULL((void*)0); |
90 | break; |
91 | } |
92 | } |
93 | |
94 | void |
95 | FontFileFreeTable (FontTablePtr table) |
96 | { |
97 | int i; |
98 | |
99 | for (i = 0; i < table->used; i++) |
100 | FontFileFreeEntry (&table->entries[i]); |
101 | free (table->entries); |
102 | } |
103 | |
104 | FontDirectoryPtr |
105 | FontFileMakeDir(const char *dirName, int size) |
106 | { |
107 | FontDirectoryPtr dir; |
108 | int dirlen; |
109 | int needslash = 0; |
110 | const char *attrib; |
111 | int attriblen; |
112 | |
113 | #if !defined(WIN32) |
114 | attrib = strchr(dirName, ':'); |
115 | #else |
116 | |
117 | attrib = strchr(dirName+2, ':'); |
118 | #endif |
119 | if (attrib) { |
| 1 | Assuming 'attrib' is null |
|
| |
120 | dirlen = attrib - dirName; |
121 | attriblen = strlen(attrib); |
122 | } else { |
123 | dirlen = strlen(dirName); |
124 | attriblen = 0; |
125 | } |
126 | if (dirName[dirlen - 1] != '/') |
| |
127 | #ifdef NCD |
128 | if (dirlen) |
129 | #endif |
130 | needslash = 1; |
131 | dir = malloc(sizeof *dir + dirlen + needslash + 1 + |
132 | (attriblen ? attriblen + 1 : 0)); |
| |
133 | if (!dir) |
| 5 | Assuming 'dir' is non-null |
|
| |
134 | return (FontDirectoryPtr)0; |
135 | if (!FontFileInitTable (&dir->scalable, 0)) |
| |
136 | { |
137 | free (dir); |
138 | return (FontDirectoryPtr)0; |
139 | } |
140 | if (!FontFileInitTable (&dir->nonScalable, size)) |
| |
141 | { |
142 | FontFileFreeTable (&dir->scalable); |
143 | free (dir); |
144 | return (FontDirectoryPtr)0; |
145 | } |
146 | dir->directory = (char *) (dir + 1); |
147 | dir->dir_mtime = 0; |
148 | dir->alias_mtime = 0; |
149 | if (attriblen) |
| |
150 | dir->attributes = dir->directory + dirlen + needslash + 1; |
151 | else |
152 | dir->attributes = NULL((void*)0); |
153 | strncpy(dir->directory, dirName, dirlen); |
154 | dir->directory[dirlen] = '\0'; |
155 | if (dir->attributes) |
| |
156 | strcpy(dir->attributes, attrib); |
| 11 | Null pointer passed as an argument to a 'nonnull' parameter |
|
157 | if (needslash) |
158 | strcat(dir->directory, "/"); |
159 | return dir; |
160 | } |
161 | |
162 | void |
163 | FontFileFreeDir (FontDirectoryPtr dir) |
164 | { |
165 | FontFileFreeTable (&dir->scalable); |
166 | FontFileFreeTable (&dir->nonScalable); |
167 | free(dir); |
168 | } |
169 | |
170 | FontEntryPtr |
171 | FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype) |
172 | { |
173 | FontEntryPtr entry; |
174 | int newsize; |
175 | |
176 | |
177 | if (table->sorted) |
178 | return (FontEntryPtr) 0; |
179 | if (table->used == table->size) { |
180 | newsize = table->size + 100; |
181 | entry = realloc(table->entries, newsize * sizeof(FontEntryRec)); |
182 | if (!entry) |
183 | return (FontEntryPtr)0; |
184 | table->size = newsize; |
185 | table->entries = entry; |
186 | } |
187 | entry = &table->entries[table->used]; |
188 | *entry = *prototype; |
189 | entry->name.name = malloc(prototype->name.length + 1); |
190 | if (!entry->name.name) |
191 | return (FontEntryPtr)0; |
192 | memcpy (entry->name.name, prototype->name.name, prototype->name.length); |
193 | entry->name.name[entry->name.length] = '\0'; |
194 | table->used++; |
195 | return entry; |
196 | } |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | #define Xisdigit(c)('\060' <= (c) && (c) <= '\071') ('\060' <= (c) && (c) <= '\071') |
207 | |
208 | static int strcmpn(const char *s1, const char *s2) |
209 | { |
210 | int digits, predigits = 0; |
211 | const char *ss1, *ss2; |
212 | |
213 | while (1) { |
214 | if (*s1 == 0 && *s2 == 0) |
215 | return 0; |
216 | digits = Xisdigit(*s1)('\060' <= (*s1) && (*s1) <= '\071') && Xisdigit(*s2)('\060' <= (*s2) && (*s2) <= '\071'); |
217 | if (digits && !predigits) { |
218 | ss1 = s1; |
219 | ss2 = s2; |
220 | while (Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071')) |
221 | ss1++, ss2++; |
222 | if (!Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071')) |
223 | return -1; |
224 | if (Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && !Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071')) |
225 | return 1; |
226 | } |
227 | if ((unsigned char)*s1 < (unsigned char)*s2) |
228 | return -1; |
229 | if ((unsigned char)*s1 > (unsigned char)*s2) |
230 | return 1; |
231 | predigits = digits; |
232 | s1++, s2++; |
233 | } |
234 | } |
235 | |
236 | |
237 | static int |
238 | FontFileNameCompare(const void* a, const void* b) |
239 | { |
240 | FontEntryPtr a_name = (FontEntryPtr) a, |
241 | b_name = (FontEntryPtr) b; |
242 | |
243 | return strcmpn(a_name->name.name, b_name->name.name); |
244 | } |
245 | |
246 | void |
247 | FontFileSortTable (FontTablePtr table) |
248 | { |
249 | if (!table->sorted) { |
250 | qsort((char *) table->entries, table->used, sizeof(FontEntryRec), |
251 | FontFileNameCompare); |
252 | table->sorted = TRUE1; |
253 | } |
254 | } |
255 | |
256 | void |
257 | FontFileSortDir(FontDirectoryPtr dir) |
258 | { |
259 | FontFileSortTable (&dir->scalable); |
260 | FontFileSortTable (&dir->nonScalable); |
261 | |
262 | FontFileSwitchStringsToBitmapPointers (dir); |
263 | } |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | #define isWild(c)((c) == 0x002a || (c) == 0x003f) ((c) == XK_asterisk0x002a || (c) == XK_question0x003f) |
279 | #define isDigit(c)(0x0030 <= (c) && (c) <= 0x0039) (XK_00x0030 <= (c) && (c) <= XK_90x0039) |
280 | |
281 | static int |
282 | SetupWildMatch(FontTablePtr table, FontNamePtr pat, |
283 | int *leftp, int *rightp, int *privatep) |
284 | { |
285 | int nDashes; |
286 | char c; |
287 | char *t; |
288 | char *firstWild; |
289 | char *firstDigit; |
290 | int first; |
291 | int center, |
292 | left, |
293 | right; |
294 | int result; |
295 | char *name; |
296 | |
297 | name = pat->name; |
298 | nDashes = pat->ndashes; |
299 | firstWild = 0; |
300 | firstDigit = 0; |
301 | t = name; |
302 | while ((c = *t++)) { |
303 | if (isWild(c)((c) == 0x002a || (c) == 0x003f)) { |
304 | if (!firstWild) |
305 | firstWild = t - 1; |
306 | } |
307 | if (isDigit(c)(0x0030 <= (c) && (c) <= 0x0039)) { |
308 | if (!firstDigit) |
309 | firstDigit = t - 1; |
310 | } |
311 | } |
312 | left = 0; |
313 | right = table->used; |
314 | if (firstWild) |
315 | *privatep = nDashes; |
316 | else |
317 | *privatep = -1; |
318 | if (!table->sorted) { |
319 | *leftp = left; |
320 | *rightp = right; |
321 | return -1; |
322 | } else if (firstWild) { |
323 | if (firstDigit && firstDigit < firstWild) |
324 | first = firstDigit - name; |
325 | else |
326 | first = firstWild - name; |
327 | while (left < right) { |
328 | center = (left + right) / 2; |
329 | result = strncmp(name, table->entries[center].name.name, first); |
330 | if (result == 0) |
331 | break; |
332 | if (result < 0) |
333 | right = center; |
334 | else |
335 | left = center + 1; |
336 | } |
337 | *leftp = left; |
338 | *rightp = right; |
339 | return -1; |
340 | } else { |
341 | while (left < right) { |
342 | center = (left + right) / 2; |
343 | result = strcmpn(name, table->entries[center].name.name); |
344 | if (result == 0) |
345 | return center; |
346 | if (result < 0) |
347 | right = center; |
348 | else |
349 | left = center + 1; |
350 | } |
351 | *leftp = 1; |
352 | *rightp = 0; |
353 | return -1; |
354 | } |
355 | } |
356 | |
357 | static int |
358 | PatternMatch(char *pat, int patdashes, char *string, int stringdashes) |
359 | { |
360 | char c, |
361 | t; |
362 | |
363 | if (stringdashes < patdashes) |
364 | return 0; |
365 | for (;;) { |
366 | switch (c = *pat++) { |
367 | case '*': |
368 | if (!(c = *pat++)) |
369 | return 1; |
370 | if (c == XK_minus0x002d) { |
371 | patdashes--; |
372 | for (;;) { |
373 | while ((t = *string++) != XK_minus0x002d) |
374 | if (!t) |
375 | return 0; |
376 | stringdashes--; |
377 | if (PatternMatch(pat, patdashes, string, stringdashes)) |
378 | return 1; |
379 | if (stringdashes == patdashes) |
380 | return 0; |
381 | } |
382 | } else { |
383 | for (;;) { |
384 | while ((t = *string++) != c) { |
385 | if (!t) |
386 | return 0; |
387 | if (t == XK_minus0x002d) { |
388 | if (stringdashes-- < patdashes) |
389 | return 0; |
390 | } |
391 | } |
392 | if (PatternMatch(pat, patdashes, string, stringdashes)) |
393 | return 1; |
394 | } |
395 | } |
396 | case '?': |
397 | if (*string++ == XK_minus0x002d) |
398 | stringdashes--; |
399 | break; |
400 | case '\0': |
401 | return (*string == '\0'); |
402 | case XK_minus0x002d: |
403 | if (*string++ == XK_minus0x002d) { |
404 | patdashes--; |
405 | stringdashes--; |
406 | break; |
407 | } |
408 | return 0; |
409 | default: |
410 | if (c == *string++) |
411 | break; |
412 | return 0; |
413 | } |
414 | } |
415 | } |
416 | |
417 | int |
418 | FontFileCountDashes (char *name, int namelen) |
419 | { |
420 | int ndashes = 0; |
421 | |
422 | while (namelen--) |
423 | if (*name++ == '\055') |
424 | ++ndashes; |
425 | return ndashes; |
426 | } |
427 | |
428 | char * |
429 | FontFileSaveString (char *s) |
430 | { |
431 | char *n; |
432 | |
433 | n = malloc (strlen (s) + 1); |
434 | if (!n) |
435 | return 0; |
436 | strcpy (n, s); |
437 | return n; |
438 | } |
439 | |
440 | FontEntryPtr |
441 | FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat, |
442 | FontScalablePtr vals) |
443 | { |
444 | int i, |
445 | start, |
446 | stop, |
447 | res, |
448 | private; |
449 | FontNamePtr name; |
450 | |
451 | if (!table->entries) |
452 | return NULL((void*)0); |
453 | if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) |
454 | return &table->entries[i]; |
455 | for (i = start; i < stop; i++) { |
456 | name = &table->entries[i].name; |
457 | res = PatternMatch(pat->name, private, name->name, name->ndashes); |
458 | if (res > 0) |
459 | { |
460 | |
461 | if (vals) |
462 | { |
463 | int vs = vals->values_supplied; |
464 | int cap; |
465 | |
466 | if (table->entries[i].type == FONT_ENTRY_SCALABLE0) |
467 | cap = table->entries[i].u.scalable.renderer->capabilities; |
468 | else if (table->entries[i].type == FONT_ENTRY_ALIAS3) |
469 | cap = ~0; |
470 | else |
471 | cap = 0; |
472 | if ((((vs & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 || |
473 | (vs & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8) && |
474 | !(cap & CAP_MATRIX0x1)) || |
475 | ((vs & CHARSUBSET_SPECIFIED0x40) && |
476 | !(cap & CAP_CHARSUBSETTING0x2))) |
477 | continue; |
478 | } |
479 | return &table->entries[i]; |
480 | } |
481 | if (res < 0) |
482 | break; |
483 | } |
484 | return (FontEntryPtr)0; |
485 | } |
486 | |
487 | FontEntryPtr |
488 | FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat) |
489 | { |
490 | return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0); |
491 | } |
492 | |
493 | int |
494 | FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max, |
495 | FontNamesPtr names, FontScalablePtr vals, |
496 | int alias_behavior, int *newmax) |
497 | { |
498 | int i, |
499 | start, |
500 | stop, |
501 | res, |
502 | private; |
503 | int ret = Successful85; |
504 | FontEntryPtr fname; |
505 | FontNamePtr name; |
506 | |
507 | if (max <= 0) |
508 | return Successful85; |
509 | if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) { |
510 | if (alias_behavior == NORMAL_ALIAS_BEHAVIOR0 || |
511 | table->entries[i].type != FONT_ENTRY_ALIAS3) |
512 | { |
513 | name = &table->entries[i].name; |
514 | if (newmax) *newmax = max - 1; |
515 | return AddFontNamesName(names, name->name, name->length); |
516 | } |
517 | start = i; |
518 | stop = i + 1; |
519 | } |
520 | for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) { |
521 | res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes); |
522 | if (res > 0) { |
523 | if (vals) |
524 | { |
525 | int vs = vals->values_supplied; |
526 | int cap; |
527 | |
528 | if (fname->type == FONT_ENTRY_SCALABLE0) |
529 | cap = fname->u.scalable.renderer->capabilities; |
530 | else if (fname->type == FONT_ENTRY_ALIAS3) |
531 | cap = ~0; |
532 | else |
533 | cap = 0; |
534 | if ((((vs & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 || |
535 | (vs & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8) && |
536 | !(cap & CAP_MATRIX0x1)) || |
537 | ((vs & CHARSUBSET_SPECIFIED0x40) && |
538 | !(cap & CAP_CHARSUBSETTING0x2))) |
539 | continue; |
540 | } |
541 | |
542 | if ((alias_behavior & IGNORE_SCALABLE_ALIASES(1<<1)) && |
543 | fname->type == FONT_ENTRY_ALIAS3) |
544 | { |
545 | FontScalableRec tmpvals; |
546 | if (FontParseXLFDName (fname->name.name, &tmpvals, |
547 | FONT_XLFD_REPLACE_NONE0) && |
548 | !(tmpvals.values_supplied & SIZE_SPECIFY_MASK0xf)) |
549 | continue; |
550 | } |
551 | |
552 | ret = AddFontNamesName(names, fname->name.name, fname->name.length); |
553 | if (ret != Successful85) |
554 | goto bail; |
555 | |
556 | |
557 | |
558 | |
559 | if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES(1<<0)) && |
560 | fname->type == FONT_ENTRY_ALIAS3) |
561 | { |
562 | names->length[names->nnames - 1] = |
563 | -names->length[names->nnames - 1]; |
564 | ret = AddFontNamesName(names, fname->u.alias.resolved, |
565 | strlen(fname->u.alias.resolved)); |
566 | if (ret != Successful85) |
567 | goto bail; |
568 | } |
569 | |
570 | if (--max <= 0) |
571 | break; |
572 | } else if (res < 0) |
573 | break; |
574 | } |
575 | bail: ; |
576 | if (newmax) *newmax = max; |
577 | return ret; |
578 | } |
579 | |
580 | int |
581 | FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat, |
582 | int max, FontNamesPtr names) |
583 | { |
584 | return FontFileFindNamesInScalableDir(table, pat, max, names, |
585 | (FontScalablePtr)0, |
586 | NORMAL_ALIAS_BEHAVIOR0, (int *)0); |
587 | } |
588 | |
589 | Bool |
590 | FontFileMatchName(char *name, int length, FontNamePtr pat) |
591 | { |
592 | |
593 | FontTableRec table; |
594 | FontEntryRec entries[1]; |
595 | |
596 | |
597 | table.used = 1; |
598 | table.size = 1; |
599 | table.sorted = TRUE1; |
600 | table.entries = entries; |
601 | entries[0].name.name = name; |
602 | entries[0].name.length = length; |
603 | entries[0].name.ndashes = FontFileCountDashes(name, length); |
604 | |
605 | return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0; |
606 | } |
607 | |
608 | |
609 | |
610 | |
611 | |
612 | |
613 | Bool |
614 | FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName) |
615 | { |
616 | FontEntryRec entry; |
617 | FontScalableRec vals, zeroVals; |
618 | FontRendererPtr renderer; |
619 | FontEntryPtr existing; |
620 | FontScalableExtraPtr extra; |
621 | FontEntryPtr bitmap = 0, scalable; |
622 | Bool isscale; |
623 | Bool scalable_xlfd; |
624 | |
625 | renderer = FontFileMatchRenderer (fileName); |
626 | if (!renderer) |
627 | return FALSE0; |
628 | entry.name.length = strlen (fontName); |
629 | if (entry.name.length > MAXFONTNAMELEN1024) |
630 | entry.name.length = MAXFONTNAMELEN1024; |
631 | entry.name.name = fontName; |
632 | CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length); |
633 | entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length); |
634 | entry.name.name[entry.name.length] = '\0'; |
635 | |
636 | |
637 | |
638 | |
639 | |
640 | |
641 | |
642 | |
643 | isscale = entry.name.ndashes == 14 && |
644 | FontParseXLFDName(entry.name.name, |
645 | &vals, FONT_XLFD_REPLACE_NONE0) && |
646 | (vals.values_supplied & PIXELSIZE_MASK0x3) != PIXELSIZE_ARRAY0x2 && |
647 | (vals.values_supplied & POINTSIZE_MASK0xc) != POINTSIZE_ARRAY0x8 && |
648 | !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK0x40); |
649 | #define UNSCALED_ATTRIB"unscaled" "unscaled" |
650 | scalable_xlfd = (isscale && |
651 | (((vals.values_supplied & PIXELSIZE_MASK0x3) == 0) || |
652 | ((vals.values_supplied & POINTSIZE_MASK0xc) == 0))); |
653 | |
654 | |
655 | |
656 | |
657 | if (isscale && !scalable_xlfd && |
658 | dir->attributes && dir->attributes[0] == ':') { |
659 | char *ptr1 = dir->attributes + 1; |
660 | char *ptr2; |
661 | int length; |
662 | int uslength = strlen(UNSCALED_ATTRIB"unscaled"); |
663 | |
664 | do { |
665 | ptr2 = strchr(ptr1, ':'); |
666 | if (ptr2) |
667 | length = ptr2 - ptr1; |
668 | else |
669 | length = dir->attributes + strlen(dir->attributes) - ptr1; |
670 | if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB"unscaled", uslength)) |
671 | isscale = FALSE0; |
672 | if (ptr2) |
673 | ptr1 = ptr2 + 1; |
674 | } while (ptr2); |
675 | } |
676 | if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK0xf)) |
677 | { |
678 | |
679 | |
680 | |
681 | |
682 | entry.type = FONT_ENTRY_BITMAP2; |
683 | entry.u.bitmap.renderer = renderer; |
684 | entry.u.bitmap.pFont = NullFont((FontPtr) 0); |
685 | if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName))) |
686 | return FALSE0; |
687 | if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry))) |
688 | { |
689 | free (entry.u.bitmap.fileName); |
690 | return FALSE0; |
691 | } |
692 | } |
693 | |
694 | |
695 | |
696 | |
697 | if (isscale) |
698 | { |
699 | if (vals.values_supplied & SIZE_SPECIFY_MASK0xf) |
700 | { |
701 | bzero((char *)&zeroVals, sizeof(zeroVals))memset((char *)&zeroVals,0,sizeof(zeroVals)); |
702 | zeroVals.x = vals.x; |
703 | zeroVals.y = vals.y; |
704 | zeroVals.values_supplied = PIXELSIZE_SCALAR0x1 | POINTSIZE_SCALAR0x4; |
705 | FontParseXLFDName (entry.name.name, &zeroVals, |
706 | FONT_XLFD_REPLACE_VALUE3); |
707 | entry.name.length = strlen (entry.name.name); |
708 | existing = FontFileFindNameInDir (&dir->scalable, &entry.name); |
709 | if (existing) |
710 | { |
711 | if ((vals.values_supplied & POINTSIZE_MASK0xc) == |
712 | POINTSIZE_SCALAR0x4 && |
713 | (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize()) |
714 | { |
715 | existing->u.scalable.extra->defaults = vals; |
716 | |
717 | free (existing->u.scalable.fileName); |
718 | if (!(existing->u.scalable.fileName = FontFileSaveString (fileName))) |
719 | return FALSE0; |
720 | } |
721 | if(bitmap) |
722 | { |
723 | FontFileCompleteXLFD(&vals, &vals); |
724 | FontFileAddScaledInstance (existing, &vals, NullFont((FontPtr) 0), |
725 | bitmap->name.name); |
726 | return TRUE1; |
727 | } |
728 | } |
729 | } |
730 | if (!(entry.u.scalable.fileName = FontFileSaveString (fileName))) |
731 | return FALSE0; |
732 | extra = malloc (sizeof (FontScalableExtraRec)); |
733 | if (!extra) |
734 | { |
735 | free (entry.u.scalable.fileName); |
736 | return FALSE0; |
737 | } |
738 | bzero((char *)&extra->defaults, sizeof(extra->defaults))memset((char *)&extra->defaults,0,sizeof(extra->defaults )); |
739 | if ((vals.values_supplied & POINTSIZE_MASK0xc) == POINTSIZE_SCALAR0x4 && |
740 | (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize()) |
741 | extra->defaults = vals; |
742 | else |
743 | { |
744 | FontResolutionPtr resolution; |
745 | int num; |
746 | int default_point_size = GetDefaultPointSize(); |
747 | |
748 | extra->defaults.point_matrix[0] = |
749 | extra->defaults.point_matrix[3] = |
750 | (double)default_point_size / 10.0; |
751 | extra->defaults.point_matrix[1] = |
752 | extra->defaults.point_matrix[2] = 0.0; |
753 | extra->defaults.values_supplied = |
754 | POINTSIZE_SCALAR0x4 | PIXELSIZE_UNDEFINED0; |
755 | extra->defaults.width = -1; |
756 | if (vals.x <= 0 || vals.y <= 0) |
757 | { |
758 | resolution = GetClientResolutions (&num); |
759 | if (resolution && num > 0) |
760 | { |
761 | extra->defaults.x = resolution->x_resolution; |
762 | extra->defaults.y = resolution->y_resolution; |
763 | } |
764 | else |
765 | { |
766 | extra->defaults.x = 75; |
767 | extra->defaults.y = 75; |
768 | } |
769 | } |
770 | else |
771 | { |
772 | extra->defaults.x = vals.x; |
773 | extra->defaults.y = vals.y; |
774 | } |
775 | FontFileCompleteXLFD (&extra->defaults, &extra->defaults); |
776 | } |
777 | extra->numScaled = 0; |
778 | extra->sizeScaled = 0; |
779 | extra->scaled = 0; |
780 | extra->private = 0; |
781 | entry.type = FONT_ENTRY_SCALABLE0; |
782 | entry.u.scalable.renderer = renderer; |
783 | entry.u.scalable.extra = extra; |
784 | if (!(scalable = FontFileAddEntry (&dir->scalable, &entry))) |
785 | { |
786 | free (extra); |
787 | free (entry.u.scalable.fileName); |
788 | return FALSE0; |
789 | } |
790 | if (vals.values_supplied & SIZE_SPECIFY_MASK0xf) |
791 | { |
792 | if(bitmap) |
793 | { |
794 | FontFileCompleteXLFD(&vals, &vals); |
795 | FontFileAddScaledInstance (scalable, &vals, NullFont((FontPtr) 0), |
796 | bitmap->name.name); |
797 | } |
798 | } |
799 | } |
800 | return TRUE1; |
801 | } |
802 | |
803 | Bool |
804 | FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName) |
805 | { |
806 | FontEntryRec entry; |
807 | |
808 | if (strcmp(aliasName,fontName) == 0) { |
809 | |
810 | return FALSE0; |
811 | } |
812 | entry.name.length = strlen (aliasName); |
813 | CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length); |
814 | entry.name.name = aliasName; |
815 | entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length); |
816 | entry.type = FONT_ENTRY_ALIAS3; |
817 | if (!(entry.u.alias.resolved = FontFileSaveString (fontName))) |
818 | return FALSE0; |
819 | if (!FontFileAddEntry (&dir->nonScalable, &entry)) |
820 | { |
821 | free (entry.u.alias.resolved); |
822 | return FALSE0; |
823 | } |
824 | return TRUE1; |
825 | } |