3 Copyright 1991, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
28 * Author: Keith Packard, MIT X Consortium
34 #include <X11/fonts/fntfilst.h>
35 #include <X11/keysym.h>
41 ISOLatin1ToLower(unsigned char source)
43 if (source >= XK_A && source <= XK_Z)
44 return source + (XK_a - XK_A);
45 if (source >= XK_Agrave && source <= XK_Odiaeresis)
46 return source + (XK_agrave - XK_Agrave);
47 if (source >= XK_Ooblique && source <= XK_Thorn)
48 return source + (XK_oslash - XK_Ooblique);
53 CopyISOLatin1Lowered(char *dest, char *source, int length)
56 for (i = 0; i < length; i++, source++, dest++)
57 *dest = ISOLatin1ToLower(*source);
62 * Map FPE functions to renderer functions
65 static int FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont,
66 int flags, FontEntryPtr entry,
67 fsBitmapFormat format,
68 fsBitmapFormatMask fmask,
69 FontPtr non_cachable_font);
72 FontFileNameCheck (char *name)
76 /* OS/2 uses D:/... as a path name for fonts, so accept this as a valid
77 * path if it starts with a letter and a colon. Same applies for WIN32
79 if (isalpha(*name) && name[1]==':')
84 return ((strcmp(name, "built-ins") == 0) || (*name == '/'));
89 FontFileInitFPE (FontPathElementPtr fpe)
94 status = FontFileReadDirectory (fpe->name, &dir);
95 if (status == Successful)
97 if (dir->nonScalable.used > 0)
98 if (!FontFileRegisterBitmapSource (fpe))
100 FontFileFreeFPE (fpe);
103 fpe->private = (pointer) dir;
110 FontFileResetFPE (FontPathElementPtr fpe)
112 FontDirectoryPtr dir;
114 dir = (FontDirectoryPtr) fpe->private;
116 * The reset must fail for bitmap fonts because they get cleared when
119 if (FontFileDirectoryChanged (dir))
121 /* can't do it, so tell the caller to close and re-open */
122 return FPEResetFailed;
126 if (dir->nonScalable.used > 0)
127 if (!FontFileRegisterBitmapSource (fpe))
129 return FPEResetFailed;
136 FontFileFreeFPE (FontPathElementPtr fpe)
138 FontFileUnregisterBitmapSource (fpe);
139 FontFileFreeDir ((FontDirectoryPtr) fpe->private);
144 transfer_values_to_alias(char *entryname, int entrynamelength,
146 char **aliasName, FontScalablePtr vals)
148 static char aliasname[MAXFONTNAMELEN];
150 char lowerName[MAXFONTNAMELEN];
152 *aliasName = resolvedname;
153 if ((len = strlen(*aliasName)) <= MAXFONTNAMELEN &&
154 (entrynamelength < MAXFONTNAMELEN) &&
155 FontFileCountDashes (*aliasName, len) == 14)
157 FontScalableRec tmpVals;
158 FontScalableRec tmpVals2;
162 /* If we're aliasing a scalable name, transfer values
163 from the name into the destination alias, multiplying
164 by matrices that appear in the alias. */
166 CopyISOLatin1Lowered (lowerName, entryname,
168 lowerName[entrynamelength] = '\0';
170 if (FontParseXLFDName(lowerName, &tmpVals,
171 FONT_XLFD_REPLACE_NONE) &&
172 !tmpVals.values_supplied &&
173 FontParseXLFDName(*aliasName, &tmpVals,
174 FONT_XLFD_REPLACE_NONE))
176 double *matrix = 0, tempmatrix[4];
178 /* Use a matrix iff exactly one is defined */
179 if ((tmpVals.values_supplied & PIXELSIZE_MASK) ==
181 !(tmpVals.values_supplied & POINTSIZE_MASK))
182 matrix = tmpVals.pixel_matrix;
183 else if ((tmpVals.values_supplied & POINTSIZE_MASK) ==
185 !(tmpVals.values_supplied & PIXELSIZE_MASK))
186 matrix = tmpVals.point_matrix;
188 /* If matrix given in the alias, compute new point
189 and/or pixel matrices */
192 /* Complete the XLFD name to avoid potential
194 if (FontFileCompleteXLFD(&tmpVals2, &tmpVals2))
197 matrix[0] * tmpVals2.point_matrix[0] +
198 matrix[1] * tmpVals2.point_matrix[2];
200 matrix[0] * tmpVals2.point_matrix[1] +
201 matrix[1] * tmpVals2.point_matrix[3];
203 matrix[2] * tmpVals2.point_matrix[0] +
204 matrix[3] * tmpVals2.point_matrix[2];
206 matrix[2] * tmpVals2.point_matrix[1] +
207 matrix[3] * tmpVals2.point_matrix[3];
208 tmpVals2.point_matrix[0] = tempmatrix[0];
209 tmpVals2.point_matrix[1] = tempmatrix[1];
210 tmpVals2.point_matrix[2] = tempmatrix[2];
211 tmpVals2.point_matrix[3] = tempmatrix[3];
214 matrix[0] * tmpVals2.pixel_matrix[0] +
215 matrix[1] * tmpVals2.pixel_matrix[2];
217 matrix[0] * tmpVals2.pixel_matrix[1] +
218 matrix[1] * tmpVals2.pixel_matrix[3];
220 matrix[2] * tmpVals2.pixel_matrix[0] +
221 matrix[3] * tmpVals2.pixel_matrix[2];
223 matrix[2] * tmpVals2.pixel_matrix[1] +
224 matrix[3] * tmpVals2.pixel_matrix[3];
225 tmpVals2.pixel_matrix[0] = tempmatrix[0];
226 tmpVals2.pixel_matrix[1] = tempmatrix[1];
227 tmpVals2.pixel_matrix[2] = tempmatrix[2];
228 tmpVals2.pixel_matrix[3] = tempmatrix[3];
230 tmpVals2.values_supplied =
231 (tmpVals2.values_supplied &
232 ~(PIXELSIZE_MASK | POINTSIZE_MASK)) |
233 PIXELSIZE_ARRAY | POINTSIZE_ARRAY;
239 CopyISOLatin1Lowered (aliasname, *aliasName, len + 1);
240 if (nameok && FontParseXLFDName(aliasname, &tmpVals2,
241 FONT_XLFD_REPLACE_VALUE))
242 /* Return a version of the aliasname that has
243 had the vals stuffed into it. To avoid
244 memory leak, this alias name lives in a
245 static buffer. The caller needs to be done
246 with this buffer before this procedure is
247 called again to avoid reentrancy problems. */
248 *aliasName = aliasname;
256 FontFileOpenFont (pointer client, FontPathElementPtr fpe, Mask flags,
257 char *name, int namelen,
258 fsBitmapFormat format, fsBitmapFormatMask fmask,
259 XID id, FontPtr *pFont, char **aliasName,
260 FontPtr non_cachable_font)
262 FontDirectoryPtr dir;
263 char lowerName[MAXFONTNAMELEN];
264 char fileName[MAXFONTFILENAMELEN*2 + 1];
267 FontScalableRec vals;
268 FontScalableEntryPtr scalable;
269 FontScaledPtr scaled;
270 FontBitmapEntryPtr bitmap;
276 if (namelen >= MAXFONTNAMELEN)
278 dir = (FontDirectoryPtr) fpe->private;
280 /* Match non-scalable pattern */
281 CopyISOLatin1Lowered (lowerName, name, namelen);
282 lowerName[namelen] = '\0';
283 ranges = FontParseRanges(lowerName, &nranges);
284 tmpName.name = lowerName;
285 tmpName.length = namelen;
286 tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
287 if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE))
288 bzero(&vals, sizeof(vals));
289 if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) &&
290 tmpName.ndashes == 14 &&
291 FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO))
293 tmpName.length = strlen(lowerName);
294 entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName);
299 switch (entry->type) {
300 case FONT_ENTRY_BITMAP:
301 bitmap = &entry->u.bitmap;
304 *pFont = bitmap->pFont;
310 ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format,
311 fmask, non_cachable_font);
312 if (ret == Successful && *pFont)
316 case FONT_ENTRY_ALIAS:
317 vals.nranges = nranges;
318 vals.ranges = ranges;
319 transfer_values_to_alias(entry->name.name, entry->name.length,
320 entry->u.alias.resolved, aliasName, &vals);
332 if (ret != BadFontName)
334 if (ranges) free(ranges);
338 /* Match XLFD patterns */
339 CopyISOLatin1Lowered (lowerName, name, namelen);
340 lowerName[namelen] = '\0';
341 tmpName.name = lowerName;
342 tmpName.length = namelen;
343 tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
344 if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) ||
345 !(tmpName.length = strlen (lowerName),
346 entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName,
348 CopyISOLatin1Lowered (lowerName, name, namelen);
349 lowerName[namelen] = '\0';
350 tmpName.name = lowerName;
351 tmpName.length = namelen;
352 tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
353 entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals);
356 strcpy(lowerName, entry->name.name);
357 tmpName.name = lowerName;
358 tmpName.length = entry->name.length;
359 tmpName.ndashes = entry->name.ndashes;
365 noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */
366 if (entry->type == FONT_ENTRY_SCALABLE &&
367 FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults))
369 scalable = &entry->u.scalable;
370 if ((vals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY ||
371 (vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY ||
372 (vals.values_supplied &
373 ~SIZE_SPECIFY_MASK & ~CHARSUBSET_SPECIFIED))
376 scaled = FontFileFindScaledInstance (entry, &vals,
379 * A scaled instance can occur one of two ways:
381 * Either the font has been scaled to this
382 * size already, in which case scaled->pFont
383 * will point at that font.
385 * Or a bitmap instance in this size exists,
386 * which is handled as if we got a pattern
387 * matching the bitmap font name.
393 *pFont = scaled->pFont;
397 else if (scaled->bitmap)
399 entry = scaled->bitmap;
400 bitmap = &entry->u.bitmap;
403 *pFont = bitmap->pFont;
409 ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry,
412 if (ret == Successful && *pFont)
416 else /* "cannot" happen */
423 ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &tmpName, &vals, format, fmask, noSpecificSize);
424 if (ret != Successful)
426 char origName[MAXFONTNAMELEN];
428 CopyISOLatin1Lowered (origName, name, namelen);
429 origName[namelen] = '\0';
431 /* Pass the original XLFD name in the vals
432 structure; the rasterizer is free to examine it
433 for hidden meanings. This information will not
434 be saved in the scaled-instances table. */
436 vals.xlfdName = origName;
437 vals.ranges = ranges;
438 vals.nranges = nranges;
440 if (strlen(dir->directory) + strlen(scalable->fileName) >=
444 strcpy (fileName, dir->directory);
445 strcat (fileName, scalable->fileName);
446 if (scalable->renderer->OpenScalable) {
447 ret = (*scalable->renderer->OpenScalable) (fpe, pFont,
448 flags, entry, fileName, &vals, format, fmask,
451 else if (scalable->renderer->OpenBitmap) {
452 ret = (*scalable->renderer->OpenBitmap) (fpe, pFont,
453 flags, entry, fileName, format, fmask,
458 /* In case rasterizer does something bad because of
459 charset subsetting... */
460 if (ret == Successful &&
461 ((*pFont)->info.firstCol > (*pFont)->info.lastCol ||
462 (*pFont)->info.firstRow > (*pFont)->info.lastRow))
464 (*(*pFont)->unload_font)(*pFont);
467 /* Save the instance */
468 if (ret == Successful)
470 if (FontFileAddScaledInstance (entry, &vals,
474 (*pFont)->fpePrivate = (pointer) 0;
491 FontFileCloseFont (FontPathElementPtr fpe, FontPtr pFont)
495 if ((entry = (FontEntryPtr) pFont->fpePrivate)) {
496 switch (entry->type) {
497 case FONT_ENTRY_SCALABLE:
498 FontFileRemoveScaledInstance (entry, pFont);
500 case FONT_ENTRY_BITMAP:
501 entry->u.bitmap.pFont = 0;
504 /* "cannot" happen */
507 pFont->fpePrivate = 0;
509 (*pFont->unload_font) (pFont);
513 FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont,
514 int flags, FontEntryPtr entry,
515 fsBitmapFormat format, fsBitmapFormatMask fmask,
516 FontPtr non_cachable_font)
518 FontBitmapEntryPtr bitmap;
519 char fileName[MAXFONTFILENAMELEN*2+1];
521 FontDirectoryPtr dir;
523 dir = (FontDirectoryPtr) fpe->private;
524 bitmap = &entry->u.bitmap;
525 if(!bitmap || !bitmap->renderer->OpenBitmap)
527 if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
529 strcpy (fileName, dir->directory);
530 strcat (fileName, bitmap->fileName);
531 ret = (*bitmap->renderer->OpenBitmap)
532 (fpe, pFont, flags, entry, fileName, format, fmask,
534 if (ret == Successful)
536 bitmap->pFont = *pFont;
537 (*pFont)->fpePrivate = (pointer) entry;
543 FontFileOpenBitmap (FontPathElementPtr fpe, FontPtr *pFont,
544 int flags, FontEntryPtr entry,
545 fsBitmapFormat format, fsBitmapFormatMask fmask)
547 return FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, fmask,
552 FontFileGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo,
555 FontBitmapEntryPtr bitmap;
556 char fileName[MAXFONTFILENAMELEN*2+1];
558 FontDirectoryPtr dir;
560 dir = (FontDirectoryPtr) fpe->private;
561 bitmap = &entry->u.bitmap;
562 if (!bitmap || !bitmap->renderer->GetInfoBitmap)
564 if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName))
566 strcpy (fileName, dir->directory);
567 strcat (fileName, bitmap->fileName);
568 ret = (*bitmap->renderer->GetInfoBitmap) (fpe, pFontInfo, entry, fileName);
573 _FontFileAddScalableNames(FontNamesPtr names, FontNamesPtr scaleNames,
574 FontNamePtr nameptr, char *zeroChars,
575 FontScalablePtr vals, fsRange *ranges,
576 int nranges, int *max)
579 FontScalableRec zeroVals, tmpVals;
580 for (i = 0; i < scaleNames->nnames; i++)
582 char nameChars[MAXFONTNAMELEN];
585 FontParseXLFDName (scaleNames->names[i], &zeroVals,
586 FONT_XLFD_REPLACE_NONE);
588 if (FontFileCompleteXLFD (&tmpVals, &zeroVals))
592 strcpy (nameChars, scaleNames->names[i]);
593 if ((vals->values_supplied & PIXELSIZE_MASK) ||
594 !(vals->values_supplied & PIXELSIZE_WILDCARD) ||
597 tmpVals.values_supplied =
598 (tmpVals.values_supplied & ~PIXELSIZE_MASK) |
599 (vals->values_supplied & PIXELSIZE_MASK);
600 tmpVals.pixel_matrix[0] = vals->pixel_matrix[0];
601 tmpVals.pixel_matrix[1] = vals->pixel_matrix[1];
602 tmpVals.pixel_matrix[2] = vals->pixel_matrix[2];
603 tmpVals.pixel_matrix[3] = vals->pixel_matrix[3];
605 if ((vals->values_supplied & POINTSIZE_MASK) ||
606 !(vals->values_supplied & POINTSIZE_WILDCARD) ||
609 tmpVals.values_supplied =
610 (tmpVals.values_supplied & ~POINTSIZE_MASK) |
611 (vals->values_supplied & POINTSIZE_MASK);
612 tmpVals.point_matrix[0] = vals->point_matrix[0];
613 tmpVals.point_matrix[1] = vals->point_matrix[1];
614 tmpVals.point_matrix[2] = vals->point_matrix[2];
615 tmpVals.point_matrix[3] = vals->point_matrix[3];
617 if (vals->width <= 0)
623 tmpVals.ranges = ranges;
624 tmpVals.nranges = nranges;
625 FontParseXLFDName (nameChars, &tmpVals,
626 FONT_XLFD_REPLACE_VALUE);
627 /* If we're marking aliases with negative lengths, we
628 need to concoct a valid target name to follow it.
629 Otherwise we're done. */
630 if (scaleNames->length[i] >= 0)
632 (void) AddFontNamesName (names, nameChars,
634 /* If our original pattern matches the name from
635 the table and that name doesn't duplicate what
636 we just added, add the name from the table */
637 if (strcmp(nameChars, scaleNames->names[i]) &&
638 FontFileMatchName(scaleNames->names[i],
639 scaleNames->length[i],
644 (void) AddFontNamesName (names, scaleNames->names[i],
645 scaleNames->length[i]);
651 vals->ranges = ranges;
652 vals->nranges = nranges;
653 if (transfer_values_to_alias(zeroChars,
655 scaleNames->names[++i],
658 (void) AddFontNamesName (names, nameChars,
660 names->length[names->nnames - 1] =
661 -names->length[names->nnames - 1];
662 (void) AddFontNamesName (names, aliasName,
664 /* If our original pattern matches the name from
665 the table and that name doesn't duplicate what
666 we just added, add the name from the table */
667 if (strcmp(nameChars, scaleNames->names[i - 1]) &&
668 FontFileMatchName(scaleNames->names[i - 1],
669 -scaleNames->length[i - 1],
674 (void) AddFontNamesName (names,
675 scaleNames->names[i - 1],
676 -scaleNames->length[i - 1]);
677 names->length[names->nnames - 1] =
678 -names->length[names->nnames - 1];
679 (void) AddFontNamesName (names, aliasName,
690 _FontFileListFonts (pointer client, FontPathElementPtr fpe,
691 char *pat, int len, int max, FontNamesPtr names,
694 FontDirectoryPtr dir;
695 char lowerChars[MAXFONTNAMELEN], zeroChars[MAXFONTNAMELEN];
696 FontNameRec lowerName;
697 FontNameRec zeroName;
698 FontNamesPtr scaleNames;
699 FontScalableRec vals;
702 int result = BadFontName;
704 if (len >= MAXFONTNAMELEN)
706 dir = (FontDirectoryPtr) fpe->private;
707 CopyISOLatin1Lowered (lowerChars, pat, len);
708 lowerChars[len] = '\0';
709 lowerName.name = lowerChars;
710 lowerName.length = len;
711 lowerName.ndashes = FontFileCountDashes (lowerChars, len);
713 /* Match XLFD patterns */
715 strcpy (zeroChars, lowerChars);
716 if (lowerName.ndashes == 14 &&
717 FontParseXLFDName (zeroChars, &vals, FONT_XLFD_REPLACE_ZERO))
719 ranges = FontParseRanges(lowerChars, &nranges);
720 result = FontFileFindNamesInScalableDir (&dir->nonScalable,
721 &lowerName, max, names,
724 LIST_ALIASES_AND_TARGET_NAMES :
725 NORMAL_ALIAS_BEHAVIOR) |
726 IGNORE_SCALABLE_ALIASES,
728 zeroName.name = zeroChars;
729 zeroName.length = strlen (zeroChars);
730 zeroName.ndashes = lowerName.ndashes;
732 /* Look for scalable names and aliases, adding scaled instances of
733 them to the output */
735 /* Scalable names... */
736 scaleNames = MakeFontNamesRecord (0);
739 if (ranges) free(ranges);
742 FontFileFindNamesInScalableDir (&dir->scalable, &zeroName, max,
745 LIST_ALIASES_AND_TARGET_NAMES :
746 NORMAL_ALIAS_BEHAVIOR, (int *)0);
747 _FontFileAddScalableNames(names, scaleNames, &lowerName,
748 zeroChars, &vals, ranges, nranges,
750 FreeFontNames (scaleNames);
752 /* Scalable aliases... */
753 scaleNames = MakeFontNamesRecord (0);
756 if (ranges) free(ranges);
759 FontFileFindNamesInScalableDir (&dir->nonScalable, &zeroName,
760 max, scaleNames, &vals,
762 LIST_ALIASES_AND_TARGET_NAMES :
763 NORMAL_ALIAS_BEHAVIOR, (int *)0);
764 _FontFileAddScalableNames(names, scaleNames, &lowerName,
765 zeroChars, &vals, ranges, nranges,
767 FreeFontNames (scaleNames);
769 if (ranges) free(ranges);
773 result = FontFileFindNamesInScalableDir (&dir->nonScalable,
774 &lowerName, max, names,
777 LIST_ALIASES_AND_TARGET_NAMES :
778 NORMAL_ALIAS_BEHAVIOR,
780 if (result == Successful)
781 result = FontFileFindNamesInScalableDir (&dir->scalable,
782 &lowerName, max, names,
785 LIST_ALIASES_AND_TARGET_NAMES :
786 NORMAL_ALIAS_BEHAVIOR, (int *)0);
791 typedef struct _LFWIData {
794 } LFWIDataRec, *LFWIDataPtr;
797 FontFileListFonts (pointer client, FontPathElementPtr fpe, char *pat,
798 int len, int max, FontNamesPtr names)
800 return _FontFileListFonts (client, fpe, pat, len, max, names, 0);
804 FontFileStartListFonts(pointer client, FontPathElementPtr fpe,
805 char *pat, int len, int max,
806 pointer *privatep, int mark_aliases)
811 data = malloc (sizeof *data);
814 data->names = MakeFontNamesRecord (0);
820 ret = _FontFileListFonts (client, fpe, pat, len,
821 max, data->names, mark_aliases);
822 if (ret != Successful)
824 FreeFontNames (data->names);
829 *privatep = (pointer) data;
835 FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe,
836 char *pat, int len, int max,
839 return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 0);
844 FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe,
845 char **namep, int *namelenp,
846 FontInfoPtr *pFontInfo)
848 FontDirectoryPtr dir;
849 char lowerName[MAXFONTNAMELEN];
850 char fileName[MAXFONTFILENAMELEN*2 + 1];
853 FontScalableRec vals;
854 FontScalableEntryPtr scalable;
855 FontScaledPtr scaled;
856 FontBitmapEntryPtr bitmap;
863 int namelen = *namelenp;
865 if (namelen >= MAXFONTNAMELEN)
867 dir = (FontDirectoryPtr) fpe->private;
869 /* Match non-scalable pattern */
870 CopyISOLatin1Lowered (lowerName, name, namelen);
871 lowerName[namelen] = '\0';
872 ranges = FontParseRanges(lowerName, &nranges);
873 tmpName.name = lowerName;
874 tmpName.length = namelen;
875 tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
876 if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE))
877 bzero(&vals, sizeof(vals));
878 if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) &&
879 tmpName.ndashes == 14 &&
880 FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO))
882 tmpName.length = strlen(lowerName);
883 entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName);
888 switch (entry->type) {
889 case FONT_ENTRY_BITMAP:
890 bitmap = &entry->u.bitmap;
893 *pFontInfo = &bitmap->pFont->info;
898 ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry);
901 case FONT_ENTRY_ALIAS:
902 vals.nranges = nranges;
903 vals.ranges = ranges;
904 transfer_values_to_alias(entry->name.name, entry->name.length,
905 entry->u.alias.resolved, namep, &vals);
906 *namelenp = strlen (*namep);
918 if (ret != BadFontName)
920 if (ranges) free(ranges);
924 /* Match XLFD patterns */
925 CopyISOLatin1Lowered (lowerName, name, namelen);
926 lowerName[namelen] = '\0';
927 tmpName.name = lowerName;
928 tmpName.length = namelen;
929 tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
930 if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) ||
931 !(tmpName.length = strlen (lowerName),
932 entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName,
934 CopyISOLatin1Lowered (lowerName, name, namelen);
935 lowerName[namelen] = '\0';
936 tmpName.name = lowerName;
937 tmpName.length = namelen;
938 tmpName.ndashes = FontFileCountDashes (lowerName, namelen);
939 entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals);
942 strcpy(lowerName, entry->name.name);
943 tmpName.name = lowerName;
944 tmpName.length = entry->name.length;
945 tmpName.ndashes = entry->name.ndashes;
951 noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */
952 if (entry && entry->type == FONT_ENTRY_SCALABLE &&
953 FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults))
955 scalable = &entry->u.scalable;
956 scaled = FontFileFindScaledInstance (entry, &vals, noSpecificSize);
958 * A scaled instance can occur one of two ways:
960 * Either the font has been scaled to this
961 * size already, in which case scaled->pFont
962 * will point at that font.
964 * Or a bitmap instance in this size exists,
965 * which is handled as if we got a pattern
966 * matching the bitmap font name.
972 *pFontInfo = &scaled->pFont->info;
975 else if (scaled->bitmap)
977 entry = scaled->bitmap;
978 bitmap = &entry->u.bitmap;
981 *pFontInfo = &bitmap->pFont->info;
986 ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry);
989 else /* "cannot" happen */
997 char origName[MAXFONTNAMELEN];
999 CopyISOLatin1Lowered (origName, name, namelen);
1000 origName[namelen] = '\0';
1001 vals.xlfdName = origName;
1002 vals.ranges = ranges;
1003 vals.nranges = nranges;
1005 /* Make a new scaled instance */
1006 if (strlen(dir->directory) + strlen(scalable->fileName) >=
1010 strcpy (fileName, dir->directory);
1011 strcat (fileName, scalable->fileName);
1012 if (scalable->renderer->GetInfoScalable)
1013 ret = (*scalable->renderer->GetInfoScalable)
1014 (fpe, *pFontInfo, entry, &tmpName, fileName,
1016 else if (scalable->renderer->GetInfoBitmap)
1017 ret = (*scalable->renderer->GetInfoBitmap)
1018 (fpe, *pFontInfo, entry, fileName);
1026 if (ret == Successful) return ret;
1028 CopyISOLatin1Lowered (lowerName, name, namelen);
1029 tmpName.length = namelen;
1040 FontFileListNextFontWithInfo(pointer client, FontPathElementPtr fpe,
1041 char **namep, int *namelenp,
1042 FontInfoPtr *pFontInfo,
1043 int *numFonts, pointer private)
1045 LFWIDataPtr data = (LFWIDataPtr) private;
1050 if (data->current == data->names->nnames)
1052 FreeFontNames (data->names);
1056 name = data->names->names[data->current];
1057 namelen = data->names->length[data->current];
1058 ret = FontFileListOneFontWithInfo (client, fpe, &name, &namelen, pFontInfo);
1059 if (ret == BadFontName)
1062 *namelenp = namelen;
1064 *numFonts = data->names->nnames - data->current;
1069 FontFileStartListFontsAndAliases(pointer client, FontPathElementPtr fpe,
1070 char *pat, int len, int max,
1073 return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 1);
1077 FontFileListNextFontOrAlias(pointer client, FontPathElementPtr fpe,
1078 char **namep, int *namelenp, char **resolvedp,
1079 int *resolvedlenp, pointer private)
1081 LFWIDataPtr data = (LFWIDataPtr) private;
1086 if (data->current == data->names->nnames)
1088 FreeFontNames (data->names);
1092 name = data->names->names[data->current];
1093 namelen = data->names->length[data->current];
1095 /* If this is a real font name... */
1099 *namelenp = namelen;
1102 /* Else if an alias */
1105 /* Tell the caller that this is an alias... let him resolve it to
1106 see if it's valid */
1108 *namelenp = -namelen;
1109 *resolvedp = data->names->names[++data->current];
1110 *resolvedlenp = data->names->length[data->current];
1111 ret = FontNameAlias;
1119 FontFileRegisterLocalFpeFunctions (void)
1121 RegisterFPEFunctions(FontFileNameCheck,
1128 FontFileStartListFontsWithInfo,
1129 FontFileListNextFontWithInfo,
1133 FontFileStartListFontsAndAliases,
1134 FontFileListNextFontOrAlias,
1135 FontFileEmptyBitmapSource);