diff options
Diffstat (limited to 'src/fontfile/fontdir.c')
-rw-r--r-- | src/fontfile/fontdir.c | 233 |
1 files changed, 148 insertions, 85 deletions
diff --git a/src/fontfile/fontdir.c b/src/fontfile/fontdir.c index beca5af..a2bd411 100644 --- a/src/fontfile/fontdir.c +++ b/src/fontfile/fontdir.c @@ -25,6 +25,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ +/* $XFree86: xc/lib/font/fontfile/fontdir.c,v 3.19 2002/05/31 18:45:50 dawes Exp $ */ /* * Author: Keith Packard, MIT X Consortium @@ -34,9 +35,7 @@ in this Software without prior written authorization from The Open Group. #include <X11/keysym.h> Bool -FontFileInitTable (table, size) - FontTablePtr table; - int size; +FontFileInitTable (FontTablePtr table, int size) { if (size) { @@ -53,14 +52,14 @@ FontFileInitTable (table, size) } void -FontFileFreeEntry (entry) - FontEntryPtr entry; +FontFileFreeEntry (FontEntryPtr entry) { FontScalableExtraPtr extra; int i; if (entry->name.name) xfree(entry->name.name); + entry->name.name = NULL; switch (entry->type) { @@ -75,9 +74,11 @@ FontFileFreeEntry (entry) break; case FONT_ENTRY_BITMAP: xfree (entry->u.bitmap.fileName); + entry->u.bitmap.fileName = NULL; break; case FONT_ENTRY_ALIAS: xfree (entry->u.alias.resolved); + entry->u.alias.resolved = NULL; break; #ifdef NOTYET case FONT_ENTRY_BC: @@ -87,8 +88,7 @@ FontFileFreeEntry (entry) } void -FontFileFreeTable (table) - FontTablePtr table; +FontFileFreeTable (FontTablePtr table) { int i; @@ -98,21 +98,44 @@ FontFileFreeTable (table) } FontDirectoryPtr -FontFileMakeDir(dirName, size) - char *dirName; - int size; +FontFileMakeDir(char *dirName, int size) { FontDirectoryPtr dir; int dirlen; int needslash = 0; +#ifdef FONTDIRATTRIB + char *attrib; + int attriblen; +#endif +#ifdef FONTDIRATTRIB +#ifndef __UNIXOS2__ + attrib = strchr(dirName, ':'); +#else + /* OS/2 uses the colon in the drive letter descriptor, skip this */ + attrib = strchr(dirName+2, ':'); +#endif + if (attrib) { + dirlen = attrib - dirName; + attriblen = strlen(attrib); + } else { + dirlen = strlen(dirName); + attriblen = 0; + } +#else dirlen = strlen(dirName); +#endif if (dirName[dirlen - 1] != '/') #ifdef NCD if (dirlen) /* leave out slash for builtins */ #endif needslash = 1; +#ifdef FONTDIRATTRIB + dir = (FontDirectoryPtr) xalloc(sizeof *dir + dirlen + needslash + 1 + + (attriblen ? attriblen + 1 : 0)); +#else dir = (FontDirectoryPtr) xalloc(sizeof *dir + dirlen + needslash + 1); +#endif if (!dir) return (FontDirectoryPtr)0; if (!FontFileInitTable (&dir->scalable, 0)) @@ -129,15 +152,25 @@ FontFileMakeDir(dirName, size) dir->directory = (char *) (dir + 1); dir->dir_mtime = 0; dir->alias_mtime = 0; +#ifdef FONTDIRATTRIB + if (attriblen) + dir->attributes = dir->directory + dirlen + needslash + 1; + else + dir->attributes = NULL; + strncpy(dir->directory, dirName, dirlen); + dir->directory[dirlen] = '\0'; + if (dir->attributes) + strcpy(dir->attributes, attrib); +#else strcpy(dir->directory, dirName); +#endif if (needslash) strcat(dir->directory, "/"); return dir; } void -FontFileFreeDir (dir) - FontDirectoryPtr dir; +FontFileFreeDir (FontDirectoryPtr dir) { FontFileFreeTable (&dir->scalable); FontFileFreeTable (&dir->nonScalable); @@ -145,9 +178,7 @@ FontFileFreeDir (dir) } FontEntryPtr -FontFileAddEntry(table, prototype) - FontTablePtr table; - FontEntryPtr prototype; +FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype) { FontEntryPtr entry; int newsize; @@ -175,24 +206,56 @@ FontFileAddEntry(table, prototype) return entry; } +/* + * Compare two strings just like strcmp, but preserve decimal integer + * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" < + * "iso10646-1". Strings are sorted as if sequences of digits were + * prefixed by a length indicator (i.e., does not ignore leading zeroes). + * + * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> + */ +#define Xisdigit(c) ('\060' <= (c) && (c) <= '\071') + +static int strcmpn(const char *s1, const char *s2) +{ + int digits, predigits = 0; + const char *ss1, *ss2; + + while (1) { + if (*s1 == 0 && *s2 == 0) + return 0; + digits = Xisdigit(*s1) && Xisdigit(*s2); + if (digits && !predigits) { + ss1 = s1; + ss2 = s2; + while (Xisdigit(*ss1) && Xisdigit(*ss2)) + ss1++, ss2++; + if (!Xisdigit(*ss1) && Xisdigit(*ss2)) + return -1; + if (Xisdigit(*ss1) && !Xisdigit(*ss2)) + return 1; + } + if ((unsigned char)*s1 < (unsigned char)*s2) + return -1; + if ((unsigned char)*s1 > (unsigned char)*s2) + return 1; + predigits = digits; + s1++, s2++; + } +} + + static int -#ifdef NeedFunctionPrototypes FontFileNameCompare(const void* a, const void* b) -#else -FontFileNameCompare(a, b) - char *a, - *b; -#endif { FontEntryPtr a_name = (FontEntryPtr) a, b_name = (FontEntryPtr) b; - return strcmp(a_name->name.name, b_name->name.name); + return strcmpn(a_name->name.name, b_name->name.name); } void -FontFileSortTable (table) - FontTablePtr table; +FontFileSortTable (FontTablePtr table) { if (!table->sorted) { qsort((char *) table->entries, table->used, sizeof(FontEntryRec), @@ -202,8 +265,7 @@ FontFileSortTable (table) } void -FontFileSortDir(dir) - FontDirectoryPtr dir; +FontFileSortDir(FontDirectoryPtr dir) { FontFileSortTable (&dir->scalable); FontFileSortTable (&dir->nonScalable); @@ -225,19 +287,17 @@ FontFileSortDir(dir) */ #define isWild(c) ((c) == XK_asterisk || (c) == XK_question) +#define isDigit(c) (XK_0 <= (c) && (c) <= XK_9) static int -SetupWildMatch(table, pat, leftp, rightp, privatep) - FontTablePtr table; - FontNamePtr pat; - int *leftp, - *rightp; - int *privatep; +SetupWildMatch(FontTablePtr table, FontNamePtr pat, + int *leftp, int *rightp, int *privatep) { int nDashes; char c; char *t; char *firstWild; + char *firstDigit; int first; int center, left, @@ -248,12 +308,17 @@ SetupWildMatch(table, pat, leftp, rightp, privatep) name = pat->name; nDashes = pat->ndashes; firstWild = 0; + firstDigit = 0; t = name; while ((c = *t++)) { if (isWild(c)) { if (!firstWild) firstWild = t - 1; } + if (isDigit(c)) { + if (!firstDigit) + firstDigit = t - 1; + } } left = 0; right = table->used; @@ -266,7 +331,10 @@ SetupWildMatch(table, pat, leftp, rightp, privatep) *rightp = right; return -1; } else if (firstWild) { - first = firstWild - name; + if (firstDigit && firstDigit < firstWild) + first = firstDigit - name; + else + first = firstWild - name; while (left < right) { center = (left + right) / 2; result = strncmp(name, table->entries[center].name.name, first); @@ -283,7 +351,7 @@ SetupWildMatch(table, pat, leftp, rightp, privatep) } else { while (left < right) { center = (left + right) / 2; - result = strcmp(name, table->entries[center].name.name); + result = strcmpn(name, table->entries[center].name.name); if (result == 0) return center; if (result < 0) @@ -298,9 +366,7 @@ SetupWildMatch(table, pat, leftp, rightp, privatep) } static int -PatternMatch(pat, patdashes, string, stringdashes) - char *pat; - char *string; +PatternMatch(char *pat, int patdashes, char *string, int stringdashes) { char c, t; @@ -360,9 +426,7 @@ PatternMatch(pat, patdashes, string, stringdashes) } int -FontFileCountDashes (name, namelen) - char *name; - int namelen; +FontFileCountDashes (char *name, int namelen) { int ndashes = 0; @@ -373,8 +437,7 @@ FontFileCountDashes (name, namelen) } char * -FontFileSaveString (s) - char *s; +FontFileSaveString (char *s) { char *n; @@ -386,10 +449,8 @@ FontFileSaveString (s) } FontEntryPtr -FontFileFindNameInScalableDir(table, pat, vals) - FontTablePtr table; - FontNamePtr pat; - FontScalablePtr vals; +FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat, + FontScalablePtr vals) { int i, start, @@ -417,11 +478,11 @@ FontFileFindNameInScalableDir(table, pat, vals) cap = ~0; /* Calling code will have to see if true */ else cap = 0; - if (((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || - (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && - !(cap & CAP_MATRIX) || - (vs & CHARSUBSET_SPECIFIED) && - !(cap & CAP_CHARSUBSETTING)) + if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && + !(cap & CAP_MATRIX)) || + ((vs & CHARSUBSET_SPECIFIED) && + !(cap & CAP_CHARSUBSETTING))) continue; } return &table->entries[i]; @@ -433,23 +494,15 @@ FontFileFindNameInScalableDir(table, pat, vals) } FontEntryPtr -FontFileFindNameInDir(table, pat) - FontTablePtr table; - FontNamePtr pat; +FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat) { return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0); } int -FontFileFindNamesInScalableDir(table, pat, max, names, vals, - alias_behavior, newmax) - FontTablePtr table; - FontNamePtr pat; - int max; - FontNamesPtr names; - FontScalablePtr vals; - int alias_behavior; - int *newmax; +FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max, + FontNamesPtr names, FontScalablePtr vals, + int alias_behavior, int *newmax) { int i, start, @@ -487,11 +540,11 @@ FontFileFindNamesInScalableDir(table, pat, max, names, vals, cap = ~0; /* Calling code will have to see if true */ else cap = 0; - if (((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && - !(cap & CAP_MATRIX) || - (vs & CHARSUBSET_SPECIFIED) && - !(cap & CAP_CHARSUBSETTING)) + !(cap & CAP_MATRIX)) || + ((vs & CHARSUBSET_SPECIFIED) && + !(cap & CAP_CHARSUBSETTING))) continue; } @@ -534,11 +587,8 @@ FontFileFindNamesInScalableDir(table, pat, max, names, vals, } int -FontFileFindNamesInDir(table, pat, max, names) - FontTablePtr table; - FontNamePtr pat; - int max; - FontNamesPtr names; +FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat, + int max, FontNamesPtr names) { return FontFileFindNamesInScalableDir(table, pat, max, names, (FontScalablePtr)0, @@ -546,10 +596,7 @@ FontFileFindNamesInDir(table, pat, max, names) } Bool -FontFileMatchName(name, length, pat) - char *name; - int length; - FontNamePtr pat; +FontFileMatchName(char *name, int length, FontNamePtr pat) { /* Perform a fontfile-type name match on a single name */ FontTableRec table; @@ -573,17 +620,14 @@ FontFileMatchName(name, length, pat) */ Bool -FontFileAddFontFile (dir, fontName, fileName) - FontDirectoryPtr dir; - char *fontName; - char *fileName; +FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName) { FontEntryRec entry; FontScalableRec vals, zeroVals; FontRendererPtr renderer; FontEntryPtr existing; FontScalableExtraPtr extra; - FontEntryPtr bitmap, scalable; + FontEntryPtr bitmap = 0, scalable; Bool isscale; renderer = FontFileMatchRenderer (fileName); @@ -610,6 +654,28 @@ FontFileAddFontFile (dir, fontName, fileName) (vals.values_supplied & PIXELSIZE_MASK) != PIXELSIZE_ARRAY && (vals.values_supplied & POINTSIZE_MASK) != POINTSIZE_ARRAY && !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK); +#ifdef FONTDIRATTRIB +#define UNSCALED_ATTRIB "unscaled" + /* For scalable fonts, check if the "unscaled" attribute is present */ + if (isscale && dir->attributes && dir->attributes[0] == ':') { + char *ptr1 = dir->attributes + 1; + char *ptr2; + int length; + int uslength = strlen(UNSCALED_ATTRIB); + + do { + ptr2 = strchr(ptr1, ':'); + if (ptr2) + length = ptr2 - ptr1; + else + length = dir->attributes + strlen(dir->attributes) - ptr1; + if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB, uslength)) + isscale = FALSE; + if (ptr2) + ptr1 = ptr2 + 1; + } while (ptr2); + } +#endif if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK)) { /* If the fontname says it is nonScalable, make sure that the @@ -739,10 +805,7 @@ FontFileAddFontFile (dir, fontName, fileName) } Bool -FontFileAddFontAlias (dir, aliasName, fontName) - FontDirectoryPtr dir; - char *aliasName; - char *fontName; +FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName) { FontEntryRec entry; |