Bug Summary

File:fontfile/fontdir.c
Location:line 156, column 2
Description:Null pointer passed as an argument to a 'nonnull' parameter

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 <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
43Bool
44FontFileInitTable (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
62void
63FontFileFreeEntry (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
94void
95FontFileFreeTable (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
104FontDirectoryPtr
105FontFileMakeDir(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 /* OS/2 uses the colon in the drive letter descriptor, skip this */
117 attrib = strchr(dirName+2, ':');
118#endif
119 if (attrib) {
1
Assuming 'attrib' is null
2
Taking false branch
120 dirlen = attrib - dirName;
121 attriblen = strlen(attrib);
122 } else {
123 dirlen = strlen(dirName);
124 attriblen = 0;
125 }
126 if (dirName[dirlen - 1] != '/')
3
Taking false branch
127#ifdef NCD
128 if (dirlen) /* leave out slash for builtins */
129#endif
130 needslash = 1;
131 dir = malloc(sizeof *dir + dirlen + needslash + 1 +
132 (attriblen ? attriblen + 1 : 0));
4
'?' condition is false
133 if (!dir)
5
Assuming 'dir' is non-null
6
Taking false branch
134 return (FontDirectoryPtr)0;
135 if (!FontFileInitTable (&dir->scalable, 0))
7
Taking false branch
136 {
137 free (dir);
138 return (FontDirectoryPtr)0;
139 }
140 if (!FontFileInitTable (&dir->nonScalable, size))
8
Taking false branch
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)
9
Taking false branch
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)
10
Taking true branch
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
162void
163FontFileFreeDir (FontDirectoryPtr dir)
164{
165 FontFileFreeTable (&dir->scalable);
166 FontFileFreeTable (&dir->nonScalable);
167 free(dir);
168}
169
170FontEntryPtr
171FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype)
172{
173 FontEntryPtr entry;
174 int newsize;
175
176 /* can't add entries to a sorted table, pointers get broken! */
177 if (table->sorted)
178 return (FontEntryPtr) 0; /* "cannot" happen */
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 * Compare two strings just like strcmp, but preserve decimal integer
200 * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" <
201 * "iso10646-1". Strings are sorted as if sequences of digits were
202 * prefixed by a length indicator (i.e., does not ignore leading zeroes).
203 *
204 * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
205 */
206#define Xisdigit(c)('\060' <= (c) && (c) <= '\071') ('\060' <= (c) && (c) <= '\071')
207
208static 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
237static int
238FontFileNameCompare(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
246void
247FontFileSortTable (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
256void
257FontFileSortDir(FontDirectoryPtr dir)
258{
259 FontFileSortTable (&dir->scalable);
260 FontFileSortTable (&dir->nonScalable);
261 /* now that the table is fixed in size, swizzle the pointers */
262 FontFileSwitchStringsToBitmapPointers (dir);
263}
264
265/*
266 Given a Font Table, SetupWildMatch() sets up various pointers and state
267 information so the table can be searched for name(s) that match a given
268 fontname pattern -- which may contain wildcards. Under certain
269 circumstances, SetupWildMatch() will find the one table entry that
270 matches the pattern. If those circumstances do not pertain,
271 SetupWildMatch() returns a range within the the table that should be
272 searched for matching name(s). With the information established by
273 SetupWildMatch(), including state information in "private", the
274 PatternMatch() procedure is then used to test names in the range for a
275 match.
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
281static int
282SetupWildMatch(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
357static int
358PatternMatch(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
417int
418FontFileCountDashes (char *name, int namelen)
419{
420 int ndashes = 0;
421
422 while (namelen--)
423 if (*name++ == '\055') /* avoid non ascii systems */
424 ++ndashes;
425 return ndashes;
426}
427
428char *
429FontFileSaveString (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
440FontEntryPtr
441FontFileFindNameInScalableDir(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 /* Check to see if enhancements requested are available */
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; /* Calling code will have to see if true */
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
487FontEntryPtr
488FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat)
489{
490 return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0);
491}
492
493int
494FontFileFindNamesInScalableDir(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; /* Calling code will have to see if true */
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 /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark
557 this entry as an alias by negating its length and follow
558 it by the resolved name */
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
580int
581FontFileFindNamesInDir(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
589Bool
590FontFileMatchName(char *name, int length, FontNamePtr pat)
591{
592 /* Perform a fontfile-type name match on a single name */
593 FontTableRec table;
594 FontEntryRec entries[1];
595
596 /* Dummy up a table */
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 * Add a font file to a directory. This handles bitmap and
610 * scalable names both
611 */
612
613Bool
614FontFileAddFontFile (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 * Add a bitmap name if the incoming name isn't an XLFD name, or
637 * if it isn't a scalable name (i.e. non-zero scalable fields)
638 *
639 * If name of bitmapped font contains XLFD enhancements, do not add
640 * a scalable version of the name... this can lead to confusion and
641 * ambiguity between the font name and the field enhancements.
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 * For scalable fonts without a scalable XFLD, check if the "unscaled"
655 * attribute is present.
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 * If the renderer doesn't support OpenBitmap, FontFileOpenFont
680 * will still do the right thing.
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 * Parse out scalable fields from XLFD names - a scalable name
695 * just gets inserted, a scaled name has more things to do.
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
803Bool
804FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName)
805{
806 FontEntryRec entry;
807
808 if (strcmp(aliasName,fontName) == 0) {
809 /* Don't allow an alias to point to itself and create a loop */
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}