Bug Summary

File:fontfile/fontdir.c
Location:line 157, column 2
Description:Null pointer argument in call to string copy function

Annotated Source Code

1/*
2
3Copyright 1991, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27/*
28 * Author: Keith Packard, MIT X Consortium
29 */
30
31#ifdef HAVE_CONFIG_H1
32#include <config.h>
33#endif
34#include "libxfontint.h"
35#include <X11/fonts/fntfilst.h>
36#include <X11/keysym.h>
37
38#if HAVE_STDINT_H1
39#include <stdint.h>
40#elif !defined(INT32_MAX2147483647)
41#define INT32_MAX2147483647 0x7fffffff
42#endif
43
44Bool
45FontFileInitTable (FontTablePtr table, int size)
46{
47 if (size < 0 || (size > INT32_MAX2147483647/sizeof(FontEntryRec)))
48 return FALSE0;
49 if (size)
50 {
51 table->entries = malloc(sizeof(FontEntryRec) * size);
52 if (!table->entries)
53 return FALSE0;
54 }
55 else
56 table->entries = 0;
57 table->used = 0;
58 table->size = size;
59 table->sorted = FALSE0;
60 return TRUE1;
61}
62
63void
64FontFileFreeEntry (FontEntryPtr entry)
65{
66 FontScalableExtraPtr extra;
67 int i;
68
69 if (entry->name.name)
70 free(entry->name.name);
71 entry->name.name = NULL((void *)0);
72
73 switch (entry->type)
74 {
75 case FONT_ENTRY_SCALABLE0:
76 free (entry->u.scalable.fileName);
77 extra = entry->u.scalable.extra;
78 for (i = 0; i < extra->numScaled; i++)
79 if (extra->scaled[i].vals.ranges)
80 free (extra->scaled[i].vals.ranges);
81 free (extra->scaled);
82 free (extra);
83 break;
84 case FONT_ENTRY_BITMAP2:
85 free (entry->u.bitmap.fileName);
86 entry->u.bitmap.fileName = NULL((void *)0);
87 break;
88 case FONT_ENTRY_ALIAS3:
89 free (entry->u.alias.resolved);
90 entry->u.alias.resolved = NULL((void *)0);
91 break;
92 }
93}
94
95void
96FontFileFreeTable (FontTablePtr table)
97{
98 int i;
99
100 for (i = 0; i < table->used; i++)
101 FontFileFreeEntry (&table->entries[i]);
102 free (table->entries);
103}
104
105FontDirectoryPtr
106FontFileMakeDir(const char *dirName, int size)
107{
108 FontDirectoryPtr dir;
109 int dirlen;
110 int needslash = 0;
111 const char *attrib;
112 int attriblen;
113
114#if !defined(WIN32)
115 attrib = strchr(dirName, ':');
1
Value assigned to 'attrib'
116#else
117 /* OS/2 uses the colon in the drive letter descriptor, skip this */
118 attrib = strchr(dirName+2, ':');
119#endif
120 if (attrib) {
2
Assuming 'attrib' is null
3
Taking false branch
121 dirlen = attrib - dirName;
122 attriblen = strlen(attrib);
123 } else {
124 dirlen = strlen(dirName);
125 attriblen = 0;
126 }
127 if (dirName[dirlen - 1] != '/')
4
Taking false branch
128#ifdef NCD
129 if (dirlen) /* leave out slash for builtins */
130#endif
131 needslash = 1;
132 dir = malloc(sizeof *dir + dirlen + needslash + 1 +
133 (attriblen ? attriblen + 1 : 0));
5
'?' condition is false
134 if (!dir)
6
Assuming 'dir' is non-null
7
Taking false branch
135 return (FontDirectoryPtr)0;
136 if (!FontFileInitTable (&dir->scalable, 0))
8
Taking false branch
137 {
138 free (dir);
139 return (FontDirectoryPtr)0;
140 }
141 if (!FontFileInitTable (&dir->nonScalable, size))
9
Taking false branch
142 {
143 FontFileFreeTable (&dir->scalable);
144 free (dir);
145 return (FontDirectoryPtr)0;
146 }
147 dir->directory = (char *) (dir + 1);
148 dir->dir_mtime = 0;
149 dir->alias_mtime = 0;
150 if (attriblen)
10
Taking false branch
151 dir->attributes = dir->directory + dirlen + needslash + 1;
152 else
153 dir->attributes = NULL((void *)0);
154 strncpy(dir->directory, dirName, dirlen)__builtin___strncpy_chk (dir->directory, dirName, dirlen, __builtin_object_size
(dir->directory, 2 > 1 ? 1 : 0))
;
155 dir->directory[dirlen] = '\0';
156 if (dir->attributes)
11
Taking true branch
157 strcpy(dir->attributes, attrib)__builtin___strcpy_chk (dir->attributes, attrib, __builtin_object_size
(dir->attributes, 2 > 1 ? 1 : 0))
;
12
Within the expansion of the macro 'strcpy':
a
Null pointer argument in call to string copy function
158 if (needslash)
159 strcat(dir->directory, "/")__builtin___strcat_chk (dir->directory, "/", __builtin_object_size
(dir->directory, 2 > 1 ? 1 : 0))
;
160 return dir;
161}
162
163void
164FontFileFreeDir (FontDirectoryPtr dir)
165{
166 FontFileFreeTable (&dir->scalable);
167 FontFileFreeTable (&dir->nonScalable);
168 free(dir);
169}
170
171FontEntryPtr
172FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype)
173{
174 FontEntryPtr entry;
175 int newsize;
176
177 /* can't add entries to a sorted table, pointers get broken! */
178 if (table->sorted)
179 return (FontEntryPtr) 0; /* "cannot" happen */
180 if (table->used == table->size) {
181 if (table->size >= ((INT32_MAX2147483647 / sizeof(FontEntryRec)) - 100))
182 /* If we've read so many entries we're going to ask for 2gb
183 or more of memory, something is so wrong with this font
184 directory that we should just give up before we overflow. */
185 return NULL((void *)0);
186 newsize = table->size + 100;
187 entry = realloc(table->entries, newsize * sizeof(FontEntryRec));
188 if (!entry)
189 return (FontEntryPtr)0;
190 table->size = newsize;
191 table->entries = entry;
192 }
193 entry = &table->entries[table->used];
194 *entry = *prototype;
195 entry->name.name = malloc(prototype->name.length + 1);
196 if (!entry->name.name)
197 return (FontEntryPtr)0;
198 memcpy (entry->name.name, prototype->name.name, prototype->name.length)__builtin___memcpy_chk (entry->name.name, prototype->name
.name, prototype->name.length, __builtin_object_size (entry
->name.name, 0))
;
199 entry->name.name[entry->name.length] = '\0';
200 table->used++;
201 return entry;
202}
203
204/*
205 * Compare two strings just like strcmp, but preserve decimal integer
206 * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" <
207 * "iso10646-1". Strings are sorted as if sequences of digits were
208 * prefixed by a length indicator (i.e., does not ignore leading zeroes).
209 *
210 * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
211 */
212#define Xisdigit(c)('\060' <= (c) && (c) <= '\071') ('\060' <= (c) && (c) <= '\071')
213
214static int strcmpn(const char *s1, const char *s2)
215{
216 int digits, predigits = 0;
217 const char *ss1, *ss2;
218
219 while (1) {
220 if (*s1 == 0 && *s2 == 0)
221 return 0;
222 digits = Xisdigit(*s1)('\060' <= (*s1) && (*s1) <= '\071') && Xisdigit(*s2)('\060' <= (*s2) && (*s2) <= '\071');
223 if (digits && !predigits) {
224 ss1 = s1;
225 ss2 = s2;
226 while (Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071'))
227 ss1++, ss2++;
228 if (!Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071'))
229 return -1;
230 if (Xisdigit(*ss1)('\060' <= (*ss1) && (*ss1) <= '\071') && !Xisdigit(*ss2)('\060' <= (*ss2) && (*ss2) <= '\071'))
231 return 1;
232 }
233 if ((unsigned char)*s1 < (unsigned char)*s2)
234 return -1;
235 if ((unsigned char)*s1 > (unsigned char)*s2)
236 return 1;
237 predigits = digits;
238 s1++, s2++;
239 }
240}
241
242
243static int
244FontFileNameCompare(const void* a, const void* b)
245{
246 FontEntryPtr a_name = (FontEntryPtr) a,
247 b_name = (FontEntryPtr) b;
248
249 return strcmpn(a_name->name.name, b_name->name.name);
250}
251
252void
253FontFileSortTable (FontTablePtr table)
254{
255 if (!table->sorted) {
256 qsort((char *) table->entries, table->used, sizeof(FontEntryRec),
257 FontFileNameCompare);
258 table->sorted = TRUE1;
259 }
260}
261
262void
263FontFileSortDir(FontDirectoryPtr dir)
264{
265 FontFileSortTable (&dir->scalable);
266 FontFileSortTable (&dir->nonScalable);
267 /* now that the table is fixed in size, swizzle the pointers */
268 FontFileSwitchStringsToBitmapPointers (dir);
269}
270
271/*
272 Given a Font Table, SetupWildMatch() sets up various pointers and state
273 information so the table can be searched for name(s) that match a given
274 fontname pattern -- which may contain wildcards. Under certain
275 circumstances, SetupWildMatch() will find the one table entry that
276 matches the pattern. If those circumstances do not pertain,
277 SetupWildMatch() returns a range within the the table that should be
278 searched for matching name(s). With the information established by
279 SetupWildMatch(), including state information in "private", the
280 PatternMatch() procedure is then used to test names in the range for a
281 match.
282*/
283
284#define isWild(c)((c) == 0x002a || (c) == 0x003f) ((c) == XK_asterisk0x002a || (c) == XK_question0x003f)
285#define isDigit(c)(0x0030 <= (c) && (c) <= 0x0039) (XK_00x0030 <= (c) && (c) <= XK_90x0039)
286
287static int
288SetupWildMatch(FontTablePtr table, FontNamePtr pat,
289 int *leftp, int *rightp, int *privatep)
290{
291 int nDashes;
292 char c;
293 char *t;
294 char *firstWild;
295 char *firstDigit;
296 int first;
297 int center,
298 left,
299 right;
300 int result;
301 char *name;
302
303 name = pat->name;
304 nDashes = pat->ndashes;
305 firstWild = 0;
306 firstDigit = 0;
307 t = name;
308 while ((c = *t++)) {
309 if (isWild(c)((c) == 0x002a || (c) == 0x003f)) {
310 if (!firstWild)
311 firstWild = t - 1;
312 }
313 if (isDigit(c)(0x0030 <= (c) && (c) <= 0x0039)) {
314 if (!firstDigit)
315 firstDigit = t - 1;
316 }
317 }
318 left = 0;
319 right = table->used;
320 if (firstWild)
321 *privatep = nDashes;
322 else
323 *privatep = -1;
324 if (!table->sorted) {
325 *leftp = left;
326 *rightp = right;
327 return -1;
328 } else if (firstWild) {
329 if (firstDigit && firstDigit < firstWild)
330 first = firstDigit - name;
331 else
332 first = firstWild - name;
333 while (left < right) {
334 center = (left + right) / 2;
335 result = strncmp(name, table->entries[center].name.name, first);
336 if (result == 0)
337 break;
338 if (result < 0)
339 right = center;
340 else
341 left = center + 1;
342 }
343 *leftp = left;
344 *rightp = right;
345 return -1;
346 } else {
347 while (left < right) {
348 center = (left + right) / 2;
349 result = strcmpn(name, table->entries[center].name.name);
350 if (result == 0)
351 return center;
352 if (result < 0)
353 right = center;
354 else
355 left = center + 1;
356 }
357 *leftp = 1;
358 *rightp = 0;
359 return -1;
360 }
361}
362
363static int
364PatternMatch(char *pat, int patdashes, char *string, int stringdashes)
365{
366 char c,
367 t;
368
369 if (stringdashes < patdashes)
370 return 0;
371 for (;;) {
372 switch (c = *pat++) {
373 case '*':
374 if (!(c = *pat++))
375 return 1;
376 if (c == XK_minus0x002d) {
377 patdashes--;
378 for (;;) {
379 while ((t = *string++) != XK_minus0x002d)
380 if (!t)
381 return 0;
382 stringdashes--;
383 if (PatternMatch(pat, patdashes, string, stringdashes))
384 return 1;
385 if (stringdashes == patdashes)
386 return 0;
387 }
388 } else {
389 for (;;) {
390 while ((t = *string++) != c) {
391 if (!t)
392 return 0;
393 if (t == XK_minus0x002d) {
394 if (stringdashes-- < patdashes)
395 return 0;
396 }
397 }
398 if (PatternMatch(pat, patdashes, string, stringdashes))
399 return 1;
400 }
401 }
402 case '?':
403 if (*string++ == XK_minus0x002d)
404 stringdashes--;
405 break;
406 case '\0':
407 return (*string == '\0');
408 case XK_minus0x002d:
409 if (*string++ == XK_minus0x002d) {
410 patdashes--;
411 stringdashes--;
412 break;
413 }
414 return 0;
415 default:
416 if (c == *string++)
417 break;
418 return 0;
419 }
420 }
421}
422
423int
424FontFileCountDashes (char *name, int namelen)
425{
426 int ndashes = 0;
427
428 while (namelen--)
429 if (*name++ == '\055') /* avoid non ascii systems */
430 ++ndashes;
431 return ndashes;
432}
433
434/* exported in public API in <X11/fonts/fntfil.h> */
435char *
436FontFileSaveString (char *s)strdup(char *s)
437{
438 return strdup(s);
439}
440#define FontFileSaveString(s)strdup(s) strdup(s)
441
442FontEntryPtr
443FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat,
444 FontScalablePtr vals)
445{
446 int i,
447 start,
448 stop,
449 res,
450 private;
451 FontNamePtr name;
452
453 if (!table->entries)
454 return NULL((void *)0);
455 if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0)
456 return &table->entries[i];
457 for (i = start; i < stop; i++) {
458 name = &table->entries[i].name;
459 res = PatternMatch(pat->name, private, name->name, name->ndashes);
460 if (res > 0)
461 {
462 /* Check to see if enhancements requested are available */
463 if (vals)
464 {
465 int vs = vals->values_supplied;
466 int cap;
467
468 if (table->entries[i].type == FONT_ENTRY_SCALABLE0)
469 cap = table->entries[i].u.scalable.renderer->capabilities;
470 else if (table->entries[i].type == FONT_ENTRY_ALIAS3)
471 cap = ~0; /* Calling code will have to see if true */
472 else
473 cap = 0;
474 if ((((vs & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 ||
475 (vs & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8) &&
476 !(cap & CAP_MATRIX0x1)) ||
477 ((vs & CHARSUBSET_SPECIFIED0x40) &&
478 !(cap & CAP_CHARSUBSETTING0x2)))
479 continue;
480 }
481 return &table->entries[i];
482 }
483 if (res < 0)
484 break;
485 }
486 return (FontEntryPtr)0;
487}
488
489FontEntryPtr
490FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat)
491{
492 return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0);
493}
494
495int
496FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max,
497 FontNamesPtr names, FontScalablePtr vals,
498 int alias_behavior, int *newmax)
499{
500 int i,
501 start,
502 stop,
503 res,
504 private;
505 int ret = Successful85;
506 FontEntryPtr fname;
507 FontNamePtr name;
508
509 if (max <= 0)
510 return Successful85;
511 if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) {
512 if (alias_behavior == NORMAL_ALIAS_BEHAVIOR0 ||
513 table->entries[i].type != FONT_ENTRY_ALIAS3)
514 {
515 name = &table->entries[i].name;
516 if (newmax) *newmax = max - 1;
517 return xfont2_add_font_names_name(names, name->name, name->length);
518 }
519 start = i;
520 stop = i + 1;
521 }
522 for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) {
523 res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes);
524 if (res > 0) {
525 if (vals)
526 {
527 int vs = vals->values_supplied;
528 int cap;
529
530 if (fname->type == FONT_ENTRY_SCALABLE0)
531 cap = fname->u.scalable.renderer->capabilities;
532 else if (fname->type == FONT_ENTRY_ALIAS3)
533 cap = ~0; /* Calling code will have to see if true */
534 else
535 cap = 0;
536 if ((((vs & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 ||
537 (vs & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8) &&
538 !(cap & CAP_MATRIX0x1)) ||
539 ((vs & CHARSUBSET_SPECIFIED0x40) &&
540 !(cap & CAP_CHARSUBSETTING0x2)))
541 continue;
542 }
543
544 if ((alias_behavior & IGNORE_SCALABLE_ALIASES(1<<1)) &&
545 fname->type == FONT_ENTRY_ALIAS3)
546 {
547 FontScalableRec tmpvals;
548 if (FontParseXLFDName (fname->name.name, &tmpvals,
549 FONT_XLFD_REPLACE_NONE0) &&
550 !(tmpvals.values_supplied & SIZE_SPECIFY_MASK0xf))
551 continue;
552 }
553
554 ret = xfont2_add_font_names_name(names, fname->name.name, fname->name.length);
555 if (ret != Successful85)
556 goto bail;
557
558 /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark
559 this entry as an alias by negating its length and follow
560 it by the resolved name */
561 if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES(1<<0)) &&
562 fname->type == FONT_ENTRY_ALIAS3)
563 {
564 names->length[names->nnames - 1] =
565 -names->length[names->nnames - 1];
566 ret = xfont2_add_font_names_name(names, fname->u.alias.resolved,
567 strlen(fname->u.alias.resolved));
568 if (ret != Successful85)
569 goto bail;
570 }
571
572 if (--max <= 0)
573 break;
574 } else if (res < 0)
575 break;
576 }
577 bail: ;
578 if (newmax) *newmax = max;
579 return ret;
580}
581
582int
583FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat,
584 int max, FontNamesPtr names)
585{
586 return FontFileFindNamesInScalableDir(table, pat, max, names,
587 (FontScalablePtr)0,
588 NORMAL_ALIAS_BEHAVIOR0, (int *)0);
589}
590
591Bool
592FontFileMatchName(char *name, int length, FontNamePtr pat)
593{
594 /* Perform a fontfile-type name match on a single name */
595 FontTableRec table;
596 FontEntryRec entries[1];
597
598 /* Dummy up a table */
599 table.used = 1;
600 table.size = 1;
601 table.sorted = TRUE1;
602 table.entries = entries;
603 entries[0].name.name = name;
604 entries[0].name.length = length;
605 entries[0].name.ndashes = FontFileCountDashes(name, length);
606
607 return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0;
608}
609
610/*
611 * Add a font file to a directory. This handles bitmap and
612 * scalable names both
613 */
614
615Bool
616FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName)
617{
618 FontEntryRec entry;
619 FontScalableRec vals, zeroVals;
620 FontRendererPtr renderer;
621 FontEntryPtr existing;
622 FontScalableExtraPtr extra;
623 FontEntryPtr bitmap = 0, scalable;
624 Bool isscale;
625 Bool scalable_xlfd;
626
627 renderer = FontFileMatchRenderer (fileName);
628 if (!renderer)
629 return FALSE0;
630 entry.name.length = strlen (fontName);
631 if (entry.name.length > MAXFONTNAMELEN1024)
632 entry.name.length = MAXFONTNAMELEN1024;
633 entry.name.name = fontName;
634 CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length);
635 entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
636 entry.name.name[entry.name.length] = '\0';
637 /*
638 * Add a bitmap name if the incoming name isn't an XLFD name, or
639 * if it isn't a scalable name (i.e. non-zero scalable fields)
640 *
641 * If name of bitmapped font contains XLFD enhancements, do not add
642 * a scalable version of the name... this can lead to confusion and
643 * ambiguity between the font name and the field enhancements.
644 */
645 isscale = entry.name.ndashes == 14 &&
646 FontParseXLFDName(entry.name.name,
647 &vals, FONT_XLFD_REPLACE_NONE0) &&
648 (vals.values_supplied & PIXELSIZE_MASK0x3) != PIXELSIZE_ARRAY0x2 &&
649 (vals.values_supplied & POINTSIZE_MASK0xc) != POINTSIZE_ARRAY0x8 &&
650 !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK0x40);
651#define UNSCALED_ATTRIB"unscaled" "unscaled"
652 scalable_xlfd = (isscale &&
653 (((vals.values_supplied & PIXELSIZE_MASK0x3) == 0) ||
654 ((vals.values_supplied & POINTSIZE_MASK0xc) == 0)));
655 /*
656 * For scalable fonts without a scalable XFLD, check if the "unscaled"
657 * attribute is present.
658 */
659 if (isscale && !scalable_xlfd &&
660 dir->attributes && dir->attributes[0] == ':') {
661 char *ptr1 = dir->attributes + 1;
662 char *ptr2;
663 int length;
664 int uslength = strlen(UNSCALED_ATTRIB"unscaled");
665
666 do {
667 ptr2 = strchr(ptr1, ':');
668 if (ptr2)
669 length = ptr2 - ptr1;
670 else
671 length = dir->attributes + strlen(dir->attributes) - ptr1;
672 if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB"unscaled", uslength))
673 isscale = FALSE0;
674 if (ptr2)
675 ptr1 = ptr2 + 1;
676 } while (ptr2);
677 }
678 if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK0xf))
679 {
680 /*
681 * If the renderer doesn't support OpenBitmap, FontFileOpenFont
682 * will still do the right thing.
683 */
684 entry.type = FONT_ENTRY_BITMAP2;
685 entry.u.bitmap.renderer = renderer;
686 entry.u.bitmap.pFont = NullFont((FontPtr) 0);
687 if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName)strdup(fileName)))
688 return FALSE0;
689 if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry)))
690 {
691 free (entry.u.bitmap.fileName);
692 return FALSE0;
693 }
694 }
695 /*
696 * Parse out scalable fields from XLFD names - a scalable name
697 * just gets inserted, a scaled name has more things to do.
698 */
699 if (isscale)
700 {
701 if (vals.values_supplied & SIZE_SPECIFY_MASK0xf)
702 {
703 bzero((char *)&zeroVals, sizeof(zeroVals))__builtin___memset_chk ((char *)&zeroVals, 0, sizeof(zeroVals
), __builtin_object_size ((char *)&zeroVals, 0))
;
704 zeroVals.x = vals.x;
705 zeroVals.y = vals.y;
706 zeroVals.values_supplied = PIXELSIZE_SCALAR0x1 | POINTSIZE_SCALAR0x4;
707 FontParseXLFDName (entry.name.name, &zeroVals,
708 FONT_XLFD_REPLACE_VALUE3);
709 entry.name.length = strlen (entry.name.name);
710 existing = FontFileFindNameInDir (&dir->scalable, &entry.name);
711 if (existing)
712 {
713 if ((vals.values_supplied & POINTSIZE_MASK0xc) ==
714 POINTSIZE_SCALAR0x4 &&
715 (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize__libxfont__GetDefaultPointSize())
716 {
717 existing->u.scalable.extra->defaults = vals;
718
719 free (existing->u.scalable.fileName);
720 if (!(existing->u.scalable.fileName = FontFileSaveString (fileName)strdup(fileName)))
721 return FALSE0;
722 }
723 if(bitmap)
724 {
725 FontFileCompleteXLFD(&vals, &vals);
726 FontFileAddScaledInstance (existing, &vals, NullFont((FontPtr) 0),
727 bitmap->name.name);
728 return TRUE1;
729 }
730 }
731 }
732 if (!(entry.u.scalable.fileName = FontFileSaveString (fileName)strdup(fileName)))
733 return FALSE0;
734 extra = malloc (sizeof (FontScalableExtraRec));
735 if (!extra)
736 {
737 free (entry.u.scalable.fileName);
738 return FALSE0;
739 }
740 bzero((char *)&extra->defaults, sizeof(extra->defaults))__builtin___memset_chk ((char *)&extra->defaults, 0, sizeof
(extra->defaults), __builtin_object_size ((char *)&extra
->defaults, 0))
;
741 if ((vals.values_supplied & POINTSIZE_MASK0xc) == POINTSIZE_SCALAR0x4 &&
742 (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize__libxfont__GetDefaultPointSize())
743 extra->defaults = vals;
744 else
745 {
746 FontResolutionPtr resolution;
747 int num;
748 int default_point_size = GetDefaultPointSize__libxfont__GetDefaultPointSize();
749
750 extra->defaults.point_matrix[0] =
751 extra->defaults.point_matrix[3] =
752 (double)default_point_size / 10.0;
753 extra->defaults.point_matrix[1] =
754 extra->defaults.point_matrix[2] = 0.0;
755 extra->defaults.values_supplied =
756 POINTSIZE_SCALAR0x4 | PIXELSIZE_UNDEFINED0;
757 extra->defaults.width = -1;
758 if (vals.x <= 0 || vals.y <= 0)
759 {
760 resolution = GetClientResolutions__libxfont__GetClientResolutions (&num);
761 if (resolution && num > 0)
762 {
763 extra->defaults.x = resolution->x_resolution;
764 extra->defaults.y = resolution->y_resolution;
765 }
766 else
767 {
768 extra->defaults.x = 75;
769 extra->defaults.y = 75;
770 }
771 }
772 else
773 {
774 extra->defaults.x = vals.x;
775 extra->defaults.y = vals.y;
776 }
777 FontFileCompleteXLFD (&extra->defaults, &extra->defaults);
778 }
779 extra->numScaled = 0;
780 extra->sizeScaled = 0;
781 extra->scaled = 0;
782 extra->private = 0;
783 entry.type = FONT_ENTRY_SCALABLE0;
784 entry.u.scalable.renderer = renderer;
785 entry.u.scalable.extra = extra;
786 if (!(scalable = FontFileAddEntry (&dir->scalable, &entry)))
787 {
788 free (extra);
789 free (entry.u.scalable.fileName);
790 return FALSE0;
791 }
792 if (vals.values_supplied & SIZE_SPECIFY_MASK0xf)
793 {
794 if(bitmap)
795 {
796 FontFileCompleteXLFD(&vals, &vals);
797 FontFileAddScaledInstance (scalable, &vals, NullFont((FontPtr) 0),
798 bitmap->name.name);
799 }
800 }
801 }
802 return TRUE1;
803}
804
805Bool
806FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName)
807{
808 FontEntryRec entry;
809
810 if (strcmp(aliasName,fontName) == 0) {
811 /* Don't allow an alias to point to itself and create a loop */
812 return FALSE0;
813 }
814 entry.name.length = strlen (aliasName);
815 CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length);
816 entry.name.name = aliasName;
817 entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length);
818 entry.type = FONT_ENTRY_ALIAS3;
819 if (!(entry.u.alias.resolved = FontFileSaveString (fontName)strdup(fontName)))
820 return FALSE0;
821 if (!FontFileAddEntry (&dir->nonScalable, &entry))
822 {
823 free (entry.u.alias.resolved);
824 return FALSE0;
825 }
826 return TRUE1;
827}