fontfile.c revision c7b4381a
1a96d7823Smrg/* 2a96d7823Smrg 3a96d7823SmrgCopyright 1991, 1998 The Open Group 4a96d7823Smrg 5a96d7823SmrgPermission to use, copy, modify, distribute, and sell this software and its 6a96d7823Smrgdocumentation for any purpose is hereby granted without fee, provided that 7a96d7823Smrgthe above copyright notice appear in all copies and that both that 8a96d7823Smrgcopyright notice and this permission notice appear in supporting 9a96d7823Smrgdocumentation. 10a96d7823Smrg 11a96d7823SmrgThe above copyright notice and this permission notice shall be included in 12a96d7823Smrgall copies or substantial portions of the Software. 13a96d7823Smrg 14a96d7823SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15a96d7823SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16a96d7823SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17a96d7823SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18a96d7823SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19a96d7823SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20a96d7823Smrg 21a96d7823SmrgExcept as contained in this notice, the name of The Open Group shall not be 22a96d7823Smrgused in advertising or otherwise to promote the sale, use or other dealings 23a96d7823Smrgin this Software without prior written authorization from The Open Group. 24a96d7823Smrg 25a96d7823Smrg*/ 26a96d7823Smrg 27a96d7823Smrg/* 28a96d7823Smrg * Author: Keith Packard, MIT X Consortium 29a96d7823Smrg */ 30a96d7823Smrg 31a96d7823Smrg#ifdef HAVE_CONFIG_H 32a96d7823Smrg#include <config.h> 33a96d7823Smrg#endif 34a96d7823Smrg#include "libxfontint.h" 35a96d7823Smrg#include <X11/fonts/fntfilst.h> 36a96d7823Smrg#include <X11/keysym.h> 37a96d7823Smrg#ifdef WIN32 38a96d7823Smrg#include <ctype.h> 39a96d7823Smrg#endif 40c7b4381aSmrg#include "src/util/replace.h" 41a96d7823Smrg 42a96d7823Smrgstatic unsigned char 43a96d7823SmrgISOLatin1ToLower(unsigned char source) 44a96d7823Smrg{ 45a96d7823Smrg if (source >= XK_A && source <= XK_Z) 46a96d7823Smrg return source + (XK_a - XK_A); 47a96d7823Smrg if (source >= XK_Agrave && source <= XK_Odiaeresis) 48a96d7823Smrg return source + (XK_agrave - XK_Agrave); 49a96d7823Smrg if (source >= XK_Ooblique && source <= XK_Thorn) 50a96d7823Smrg return source + (XK_oslash - XK_Ooblique); 51a96d7823Smrg return source; 52a96d7823Smrg} 53a96d7823Smrg 54a96d7823Smrg_X_HIDDEN void 55a96d7823SmrgCopyISOLatin1Lowered(char *dest, const char *source, int length) 56a96d7823Smrg{ 57a96d7823Smrg int i; 58a96d7823Smrg for (i = 0; i < length; i++, source++, dest++) 59a96d7823Smrg *dest = ISOLatin1ToLower(*source); 60a96d7823Smrg *dest = '\0'; 61a96d7823Smrg} 62a96d7823Smrg 63a96d7823Smrg/* 64a96d7823Smrg * Map FPE functions to renderer functions 65a96d7823Smrg */ 66a96d7823Smrg 67a96d7823Smrgstatic int FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont, 68a96d7823Smrg int flags, FontEntryPtr entry, 69a96d7823Smrg fsBitmapFormat format, 70a96d7823Smrg fsBitmapFormatMask fmask, 71a96d7823Smrg FontPtr non_cachable_font); 72a96d7823Smrg 73a96d7823Smrgint 74a96d7823SmrgFontFileNameCheck (const char *name) 75a96d7823Smrg{ 76a96d7823Smrg#ifndef NCD 77a96d7823Smrg#if defined(WIN32) 78a96d7823Smrg /* OS/2 uses D:/... as a path name for fonts, so accept this as a valid 79a96d7823Smrg * path if it starts with a letter and a colon. Same applies for WIN32 80a96d7823Smrg */ 81a96d7823Smrg if (isalpha(*name) && name[1]==':') 82a96d7823Smrg return TRUE; 83a96d7823Smrg#endif 84a96d7823Smrg return *name == '/'; 85a96d7823Smrg#else 86a96d7823Smrg return ((strcmp(name, "built-ins") == 0) || (*name == '/')); 87a96d7823Smrg#endif 88a96d7823Smrg} 89a96d7823Smrg 90a96d7823Smrgint 91a96d7823SmrgFontFileInitFPE (FontPathElementPtr fpe) 92a96d7823Smrg{ 93a96d7823Smrg int status; 94a96d7823Smrg FontDirectoryPtr dir; 95a96d7823Smrg 96a96d7823Smrg status = FontFileReadDirectory (fpe->name, &dir); 97a96d7823Smrg if (status == Successful) 98a96d7823Smrg { 99a96d7823Smrg if (dir->nonScalable.used > 0) 100a96d7823Smrg if (!FontFileRegisterBitmapSource (fpe)) 101a96d7823Smrg { 102a96d7823Smrg FontFileFreeFPE (fpe); 103a96d7823Smrg return AllocError; 104a96d7823Smrg } 105a96d7823Smrg fpe->private = (pointer) dir; 106a96d7823Smrg } 107a96d7823Smrg return status; 108a96d7823Smrg} 109a96d7823Smrg 110a96d7823Smrg/* ARGSUSED */ 111a96d7823Smrgint 112a96d7823SmrgFontFileResetFPE (FontPathElementPtr fpe) 113a96d7823Smrg{ 114a96d7823Smrg FontDirectoryPtr dir; 115a96d7823Smrg 116a96d7823Smrg dir = (FontDirectoryPtr) fpe->private; 117a96d7823Smrg /* 118a96d7823Smrg * The reset must fail for bitmap fonts because they get cleared when 119a96d7823Smrg * the path is set. 120a96d7823Smrg */ 121a96d7823Smrg if (FontFileDirectoryChanged (dir)) 122a96d7823Smrg { 123a96d7823Smrg /* can't do it, so tell the caller to close and re-open */ 124a96d7823Smrg return FPEResetFailed; 125a96d7823Smrg } 126a96d7823Smrg else 127a96d7823Smrg { 128a96d7823Smrg if (dir->nonScalable.used > 0) 129a96d7823Smrg if (!FontFileRegisterBitmapSource (fpe)) 130a96d7823Smrg { 131a96d7823Smrg return FPEResetFailed; 132a96d7823Smrg } 133a96d7823Smrg return Successful; 134a96d7823Smrg } 135a96d7823Smrg} 136a96d7823Smrg 137a96d7823Smrgint 138a96d7823SmrgFontFileFreeFPE (FontPathElementPtr fpe) 139a96d7823Smrg{ 140a96d7823Smrg FontFileUnregisterBitmapSource (fpe); 141a96d7823Smrg FontFileFreeDir ((FontDirectoryPtr) fpe->private); 142a96d7823Smrg return Successful; 143a96d7823Smrg} 144a96d7823Smrg 145a96d7823Smrgstatic int 146a96d7823Smrgtransfer_values_to_alias(char *entryname, int entrynamelength, 147a96d7823Smrg char *resolvedname, 148a96d7823Smrg char **aliasName, FontScalablePtr vals) 149a96d7823Smrg{ 150a96d7823Smrg static char aliasname[MAXFONTNAMELEN]; 151a96d7823Smrg int nameok = 1, len; 152a96d7823Smrg char lowerName[MAXFONTNAMELEN]; 153a96d7823Smrg 154a96d7823Smrg *aliasName = resolvedname; 155a96d7823Smrg if ((len = strlen(*aliasName)) <= MAXFONTNAMELEN && 156a96d7823Smrg (entrynamelength < MAXFONTNAMELEN) && 157a96d7823Smrg FontFileCountDashes (*aliasName, len) == 14) 158a96d7823Smrg { 159a96d7823Smrg FontScalableRec tmpVals; 160a96d7823Smrg FontScalableRec tmpVals2; 161a96d7823Smrg 162a96d7823Smrg tmpVals2 = *vals; 163a96d7823Smrg 164a96d7823Smrg /* If we're aliasing a scalable name, transfer values 165a96d7823Smrg from the name into the destination alias, multiplying 166a96d7823Smrg by matrices that appear in the alias. */ 167a96d7823Smrg 168a96d7823Smrg CopyISOLatin1Lowered (lowerName, entryname, 169a96d7823Smrg entrynamelength); 170a96d7823Smrg lowerName[entrynamelength] = '\0'; 171a96d7823Smrg 172a96d7823Smrg if (FontParseXLFDName(lowerName, &tmpVals, 173a96d7823Smrg FONT_XLFD_REPLACE_NONE) && 174a96d7823Smrg !tmpVals.values_supplied && 175a96d7823Smrg FontParseXLFDName(*aliasName, &tmpVals, 176a96d7823Smrg FONT_XLFD_REPLACE_NONE)) 177a96d7823Smrg { 178a96d7823Smrg double *matrix = 0, tempmatrix[4]; 179a96d7823Smrg 180a96d7823Smrg /* Use a matrix iff exactly one is defined */ 181a96d7823Smrg if ((tmpVals.values_supplied & PIXELSIZE_MASK) == 182a96d7823Smrg PIXELSIZE_ARRAY && 183a96d7823Smrg !(tmpVals.values_supplied & POINTSIZE_MASK)) 184a96d7823Smrg matrix = tmpVals.pixel_matrix; 185a96d7823Smrg else if ((tmpVals.values_supplied & POINTSIZE_MASK) == 186a96d7823Smrg POINTSIZE_ARRAY && 187a96d7823Smrg !(tmpVals.values_supplied & PIXELSIZE_MASK)) 188a96d7823Smrg matrix = tmpVals.point_matrix; 189a96d7823Smrg 190a96d7823Smrg /* If matrix given in the alias, compute new point 191a96d7823Smrg and/or pixel matrices */ 192a96d7823Smrg if (matrix) 193a96d7823Smrg { 194a96d7823Smrg /* Complete the XLFD name to avoid potential 195a96d7823Smrg gotchas */ 196a96d7823Smrg if (FontFileCompleteXLFD(&tmpVals2, &tmpVals2)) 197a96d7823Smrg { 198a96d7823Smrg tempmatrix[0] = 199a96d7823Smrg matrix[0] * tmpVals2.point_matrix[0] + 200a96d7823Smrg matrix[1] * tmpVals2.point_matrix[2]; 201a96d7823Smrg tempmatrix[1] = 202a96d7823Smrg matrix[0] * tmpVals2.point_matrix[1] + 203a96d7823Smrg matrix[1] * tmpVals2.point_matrix[3]; 204a96d7823Smrg tempmatrix[2] = 205a96d7823Smrg matrix[2] * tmpVals2.point_matrix[0] + 206a96d7823Smrg matrix[3] * tmpVals2.point_matrix[2]; 207a96d7823Smrg tempmatrix[3] = 208a96d7823Smrg matrix[2] * tmpVals2.point_matrix[1] + 209a96d7823Smrg matrix[3] * tmpVals2.point_matrix[3]; 210a96d7823Smrg tmpVals2.point_matrix[0] = tempmatrix[0]; 211a96d7823Smrg tmpVals2.point_matrix[1] = tempmatrix[1]; 212a96d7823Smrg tmpVals2.point_matrix[2] = tempmatrix[2]; 213a96d7823Smrg tmpVals2.point_matrix[3] = tempmatrix[3]; 214a96d7823Smrg 215a96d7823Smrg tempmatrix[0] = 216a96d7823Smrg matrix[0] * tmpVals2.pixel_matrix[0] + 217a96d7823Smrg matrix[1] * tmpVals2.pixel_matrix[2]; 218a96d7823Smrg tempmatrix[1] = 219a96d7823Smrg matrix[0] * tmpVals2.pixel_matrix[1] + 220a96d7823Smrg matrix[1] * tmpVals2.pixel_matrix[3]; 221a96d7823Smrg tempmatrix[2] = 222a96d7823Smrg matrix[2] * tmpVals2.pixel_matrix[0] + 223a96d7823Smrg matrix[3] * tmpVals2.pixel_matrix[2]; 224a96d7823Smrg tempmatrix[3] = 225a96d7823Smrg matrix[2] * tmpVals2.pixel_matrix[1] + 226a96d7823Smrg matrix[3] * tmpVals2.pixel_matrix[3]; 227a96d7823Smrg tmpVals2.pixel_matrix[0] = tempmatrix[0]; 228a96d7823Smrg tmpVals2.pixel_matrix[1] = tempmatrix[1]; 229a96d7823Smrg tmpVals2.pixel_matrix[2] = tempmatrix[2]; 230a96d7823Smrg tmpVals2.pixel_matrix[3] = tempmatrix[3]; 231a96d7823Smrg 232a96d7823Smrg tmpVals2.values_supplied = 233a96d7823Smrg (tmpVals2.values_supplied & 234a96d7823Smrg ~(PIXELSIZE_MASK | POINTSIZE_MASK)) | 235a96d7823Smrg PIXELSIZE_ARRAY | POINTSIZE_ARRAY; 236a96d7823Smrg } 237a96d7823Smrg else 238a96d7823Smrg nameok = 0; 239a96d7823Smrg } 240a96d7823Smrg 241a96d7823Smrg CopyISOLatin1Lowered (aliasname, *aliasName, len + 1); 242a96d7823Smrg if (nameok && FontParseXLFDName(aliasname, &tmpVals2, 243a96d7823Smrg FONT_XLFD_REPLACE_VALUE)) 244a96d7823Smrg /* Return a version of the aliasname that has 245a96d7823Smrg had the vals stuffed into it. To avoid 246a96d7823Smrg memory leak, this alias name lives in a 247a96d7823Smrg static buffer. The caller needs to be done 248a96d7823Smrg with this buffer before this procedure is 249a96d7823Smrg called again to avoid reentrancy problems. */ 250a96d7823Smrg *aliasName = aliasname; 251a96d7823Smrg } 252a96d7823Smrg } 253a96d7823Smrg return nameok; 254a96d7823Smrg} 255a96d7823Smrg 256a96d7823Smrg/* ARGSUSED */ 257a96d7823Smrgint 258a96d7823SmrgFontFileOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, 259a96d7823Smrg const char *name, int namelen, 260a96d7823Smrg fsBitmapFormat format, fsBitmapFormatMask fmask, 261a96d7823Smrg XID id, FontPtr *pFont, char **aliasName, 262a96d7823Smrg FontPtr non_cachable_font) 263a96d7823Smrg{ 264a96d7823Smrg FontDirectoryPtr dir; 265a96d7823Smrg char lowerName[MAXFONTNAMELEN]; 266a96d7823Smrg char fileName[MAXFONTFILENAMELEN*2 + 1]; 267a96d7823Smrg FontNameRec tmpName; 268a96d7823Smrg FontEntryPtr entry; 269a96d7823Smrg FontScalableRec vals; 270a96d7823Smrg FontScalableEntryPtr scalable; 271a96d7823Smrg FontScaledPtr scaled; 272a96d7823Smrg FontBitmapEntryPtr bitmap; 273a96d7823Smrg int ret; 274a96d7823Smrg Bool noSpecificSize; 275a96d7823Smrg int nranges; 276a96d7823Smrg fsRange *ranges; 277a96d7823Smrg 278a96d7823Smrg if (namelen >= MAXFONTNAMELEN) 279a96d7823Smrg return AllocError; 280a96d7823Smrg dir = (FontDirectoryPtr) fpe->private; 281a96d7823Smrg 282a96d7823Smrg /* Match non-scalable pattern */ 283a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 284a96d7823Smrg lowerName[namelen] = '\0'; 285a96d7823Smrg ranges = FontParseRanges(lowerName, &nranges); 286a96d7823Smrg tmpName.name = lowerName; 287a96d7823Smrg tmpName.length = namelen; 288a96d7823Smrg tmpName.ndashes = FontFileCountDashes (lowerName, namelen); 289a96d7823Smrg if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE)) 290a96d7823Smrg bzero(&vals, sizeof(vals)); 291a96d7823Smrg if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) && 292a96d7823Smrg tmpName.ndashes == 14 && 293a96d7823Smrg FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO)) 294a96d7823Smrg { 295a96d7823Smrg tmpName.length = strlen(lowerName); 296a96d7823Smrg entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName); 297a96d7823Smrg } 298a96d7823Smrg 299a96d7823Smrg if (entry) 300a96d7823Smrg { 301a96d7823Smrg switch (entry->type) { 302a96d7823Smrg case FONT_ENTRY_BITMAP: 303a96d7823Smrg bitmap = &entry->u.bitmap; 304a96d7823Smrg if (bitmap->pFont) 305a96d7823Smrg { 306a96d7823Smrg *pFont = bitmap->pFont; 307a96d7823Smrg (*pFont)->fpe = fpe; 308a96d7823Smrg ret = Successful; 309a96d7823Smrg } 310a96d7823Smrg else 311a96d7823Smrg { 312a96d7823Smrg ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, 313a96d7823Smrg fmask, non_cachable_font); 314a96d7823Smrg if (ret == Successful && *pFont) 315a96d7823Smrg (*pFont)->fpe = fpe; 316a96d7823Smrg } 317a96d7823Smrg break; 318a96d7823Smrg case FONT_ENTRY_ALIAS: 319a96d7823Smrg vals.nranges = nranges; 320a96d7823Smrg vals.ranges = ranges; 321a96d7823Smrg transfer_values_to_alias(entry->name.name, entry->name.length, 322a96d7823Smrg entry->u.alias.resolved, aliasName, &vals); 323a96d7823Smrg ret = FontNameAlias; 324a96d7823Smrg break; 325a96d7823Smrg default: 326a96d7823Smrg ret = BadFontName; 327a96d7823Smrg } 328a96d7823Smrg } 329a96d7823Smrg else 330a96d7823Smrg { 331a96d7823Smrg ret = BadFontName; 332a96d7823Smrg } 333a96d7823Smrg 334a96d7823Smrg if (ret != BadFontName) 335a96d7823Smrg { 336a96d7823Smrg if (ranges) free(ranges); 337a96d7823Smrg return ret; 338a96d7823Smrg } 339a96d7823Smrg 340a96d7823Smrg /* Match XLFD patterns */ 341a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 342a96d7823Smrg lowerName[namelen] = '\0'; 343a96d7823Smrg tmpName.name = lowerName; 344a96d7823Smrg tmpName.length = namelen; 345a96d7823Smrg tmpName.ndashes = FontFileCountDashes (lowerName, namelen); 346a96d7823Smrg if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) || 347a96d7823Smrg !(tmpName.length = strlen (lowerName), 348a96d7823Smrg entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, 349a96d7823Smrg &vals))) { 350a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 351a96d7823Smrg lowerName[namelen] = '\0'; 352a96d7823Smrg tmpName.name = lowerName; 353a96d7823Smrg tmpName.length = namelen; 354a96d7823Smrg tmpName.ndashes = FontFileCountDashes (lowerName, namelen); 355a96d7823Smrg entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals); 356a96d7823Smrg if (entry) 357a96d7823Smrg { 358c7b4381aSmrg strlcpy(lowerName, entry->name.name, sizeof(lowerName)); 359a96d7823Smrg tmpName.name = lowerName; 360a96d7823Smrg tmpName.length = entry->name.length; 361a96d7823Smrg tmpName.ndashes = entry->name.ndashes; 362a96d7823Smrg } 363a96d7823Smrg } 364a96d7823Smrg 365a96d7823Smrg if (entry) 366a96d7823Smrg { 367a96d7823Smrg noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */ 368a96d7823Smrg if (entry->type == FONT_ENTRY_SCALABLE && 369a96d7823Smrg FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults)) 370a96d7823Smrg { 371a96d7823Smrg scalable = &entry->u.scalable; 372a96d7823Smrg if ((vals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || 373a96d7823Smrg (vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY || 374a96d7823Smrg (vals.values_supplied & 375a96d7823Smrg ~SIZE_SPECIFY_MASK & ~CHARSUBSET_SPECIFIED)) 376a96d7823Smrg scaled = 0; 377a96d7823Smrg else 378a96d7823Smrg scaled = FontFileFindScaledInstance (entry, &vals, 379a96d7823Smrg noSpecificSize); 380a96d7823Smrg /* 381a96d7823Smrg * A scaled instance can occur one of two ways: 382a96d7823Smrg * 383a96d7823Smrg * Either the font has been scaled to this 384a96d7823Smrg * size already, in which case scaled->pFont 385a96d7823Smrg * will point at that font. 386a96d7823Smrg * 387a96d7823Smrg * Or a bitmap instance in this size exists, 388a96d7823Smrg * which is handled as if we got a pattern 389a96d7823Smrg * matching the bitmap font name. 390a96d7823Smrg */ 391a96d7823Smrg if (scaled) 392a96d7823Smrg { 393a96d7823Smrg if (scaled->pFont) 394a96d7823Smrg { 395a96d7823Smrg *pFont = scaled->pFont; 396a96d7823Smrg (*pFont)->fpe = fpe; 397a96d7823Smrg ret = Successful; 398a96d7823Smrg } 399a96d7823Smrg else if (scaled->bitmap) 400a96d7823Smrg { 401a96d7823Smrg entry = scaled->bitmap; 402a96d7823Smrg bitmap = &entry->u.bitmap; 403a96d7823Smrg if (bitmap->pFont) 404a96d7823Smrg { 405a96d7823Smrg *pFont = bitmap->pFont; 406a96d7823Smrg (*pFont)->fpe = fpe; 407a96d7823Smrg ret = Successful; 408a96d7823Smrg } 409a96d7823Smrg else 410a96d7823Smrg { 411a96d7823Smrg ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, 412a96d7823Smrg format, fmask, 413a96d7823Smrg non_cachable_font); 414a96d7823Smrg if (ret == Successful && *pFont) 415a96d7823Smrg (*pFont)->fpe = fpe; 416a96d7823Smrg } 417a96d7823Smrg } 418a96d7823Smrg else /* "cannot" happen */ 419a96d7823Smrg { 420a96d7823Smrg ret = BadFontName; 421a96d7823Smrg } 422a96d7823Smrg } 423a96d7823Smrg else 424a96d7823Smrg { 425a96d7823Smrg ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &tmpName, &vals, format, fmask, noSpecificSize); 426a96d7823Smrg if (ret != Successful) 427a96d7823Smrg { 428a96d7823Smrg char origName[MAXFONTNAMELEN]; 429a96d7823Smrg 430a96d7823Smrg CopyISOLatin1Lowered (origName, name, namelen); 431a96d7823Smrg origName[namelen] = '\0'; 432a96d7823Smrg 433a96d7823Smrg /* Pass the original XLFD name in the vals 434a96d7823Smrg structure; the rasterizer is free to examine it 435a96d7823Smrg for hidden meanings. This information will not 436a96d7823Smrg be saved in the scaled-instances table. */ 437a96d7823Smrg 438a96d7823Smrg vals.xlfdName = origName; 439a96d7823Smrg vals.ranges = ranges; 440a96d7823Smrg vals.nranges = nranges; 441a96d7823Smrg 442a96d7823Smrg if (strlen(dir->directory) + strlen(scalable->fileName) >= 443a96d7823Smrg sizeof(fileName)) { 444a96d7823Smrg ret = BadFontName; 445a96d7823Smrg } else { 446c7b4381aSmrg strlcpy (fileName, dir->directory, sizeof(fileName)); 447c7b4381aSmrg strlcat (fileName, scalable->fileName, sizeof(fileName)); 448a96d7823Smrg if (scalable->renderer->OpenScalable) { 449a96d7823Smrg ret = (*scalable->renderer->OpenScalable) (fpe, pFont, 450a96d7823Smrg flags, entry, fileName, &vals, format, fmask, 451a96d7823Smrg non_cachable_font); 452a96d7823Smrg } 453a96d7823Smrg else if (scalable->renderer->OpenBitmap) { 454a96d7823Smrg ret = (*scalable->renderer->OpenBitmap) (fpe, pFont, 455a96d7823Smrg flags, entry, fileName, format, fmask, 456a96d7823Smrg non_cachable_font); 457a96d7823Smrg } 458a96d7823Smrg } 459a96d7823Smrg 460a96d7823Smrg /* In case rasterizer does something bad because of 461a96d7823Smrg charset subsetting... */ 462a96d7823Smrg if (ret == Successful && 463a96d7823Smrg ((*pFont)->info.firstCol > (*pFont)->info.lastCol || 464a96d7823Smrg (*pFont)->info.firstRow > (*pFont)->info.lastRow)) 465a96d7823Smrg { 466a96d7823Smrg (*(*pFont)->unload_font)(*pFont); 467a96d7823Smrg ret = BadFontName; 468a96d7823Smrg } 469a96d7823Smrg /* Save the instance */ 470a96d7823Smrg if (ret == Successful) 471a96d7823Smrg { 472a96d7823Smrg if (FontFileAddScaledInstance (entry, &vals, 473a96d7823Smrg *pFont, (char *) 0)) 474a96d7823Smrg ranges = 0; 475a96d7823Smrg else 476a96d7823Smrg (*pFont)->fpePrivate = (pointer) 0; 477a96d7823Smrg (*pFont)->fpe = fpe; 478a96d7823Smrg } 479a96d7823Smrg } 480a96d7823Smrg } 481a96d7823Smrg } 482a96d7823Smrg } 483a96d7823Smrg else 484a96d7823Smrg ret = BadFontName; 485a96d7823Smrg 486a96d7823Smrg if (ranges) 487a96d7823Smrg free(ranges); 488a96d7823Smrg return ret; 489a96d7823Smrg} 490a96d7823Smrg 491a96d7823Smrg/* ARGSUSED */ 492a96d7823Smrgvoid 493a96d7823SmrgFontFileCloseFont (FontPathElementPtr fpe, FontPtr pFont) 494a96d7823Smrg{ 495a96d7823Smrg FontEntryPtr entry; 496a96d7823Smrg 497a96d7823Smrg if ((entry = (FontEntryPtr) pFont->fpePrivate)) { 498a96d7823Smrg switch (entry->type) { 499a96d7823Smrg case FONT_ENTRY_SCALABLE: 500a96d7823Smrg FontFileRemoveScaledInstance (entry, pFont); 501a96d7823Smrg break; 502a96d7823Smrg case FONT_ENTRY_BITMAP: 503a96d7823Smrg entry->u.bitmap.pFont = 0; 504a96d7823Smrg break; 505a96d7823Smrg default: 506a96d7823Smrg /* "cannot" happen */ 507a96d7823Smrg break; 508a96d7823Smrg } 509a96d7823Smrg pFont->fpePrivate = 0; 510a96d7823Smrg } 511a96d7823Smrg (*pFont->unload_font) (pFont); 512a96d7823Smrg} 513a96d7823Smrg 514a96d7823Smrgstatic int 515a96d7823SmrgFontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont, 516a96d7823Smrg int flags, FontEntryPtr entry, 517a96d7823Smrg fsBitmapFormat format, fsBitmapFormatMask fmask, 518a96d7823Smrg FontPtr non_cachable_font) 519a96d7823Smrg{ 520a96d7823Smrg FontBitmapEntryPtr bitmap; 521a96d7823Smrg char fileName[MAXFONTFILENAMELEN*2+1]; 522a96d7823Smrg int ret; 523a96d7823Smrg FontDirectoryPtr dir; 524a96d7823Smrg 525a96d7823Smrg dir = (FontDirectoryPtr) fpe->private; 526a96d7823Smrg bitmap = &entry->u.bitmap; 527a96d7823Smrg if(!bitmap || !bitmap->renderer->OpenBitmap) 528a96d7823Smrg return BadFontName; 529a96d7823Smrg if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName)) 530a96d7823Smrg return BadFontName; 531c7b4381aSmrg strlcpy (fileName, dir->directory, sizeof(fileName)); 532c7b4381aSmrg strlcat (fileName, bitmap->fileName, sizeof(fileName)); 533a96d7823Smrg ret = (*bitmap->renderer->OpenBitmap) 534a96d7823Smrg (fpe, pFont, flags, entry, fileName, format, fmask, 535a96d7823Smrg non_cachable_font); 536a96d7823Smrg if (ret == Successful) 537a96d7823Smrg { 538a96d7823Smrg bitmap->pFont = *pFont; 539a96d7823Smrg (*pFont)->fpePrivate = (pointer) entry; 540a96d7823Smrg } 541a96d7823Smrg return ret; 542a96d7823Smrg} 543a96d7823Smrg 544a96d7823Smrgint 545a96d7823SmrgFontFileOpenBitmap (FontPathElementPtr fpe, FontPtr *pFont, 546a96d7823Smrg int flags, FontEntryPtr entry, 547a96d7823Smrg fsBitmapFormat format, fsBitmapFormatMask fmask) 548a96d7823Smrg{ 549a96d7823Smrg return FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, fmask, 550a96d7823Smrg (FontPtr)0); 551a96d7823Smrg} 552a96d7823Smrg 553a96d7823Smrgstatic int 554a96d7823SmrgFontFileGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo, 555a96d7823Smrg FontEntryPtr entry) 556a96d7823Smrg{ 557a96d7823Smrg FontBitmapEntryPtr bitmap; 558a96d7823Smrg char fileName[MAXFONTFILENAMELEN*2+1]; 559a96d7823Smrg int ret; 560a96d7823Smrg FontDirectoryPtr dir; 561a96d7823Smrg 562a96d7823Smrg dir = (FontDirectoryPtr) fpe->private; 563a96d7823Smrg bitmap = &entry->u.bitmap; 564a96d7823Smrg if (!bitmap || !bitmap->renderer->GetInfoBitmap) 565a96d7823Smrg return BadFontName; 566a96d7823Smrg if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName)) 567a96d7823Smrg return BadFontName; 568c7b4381aSmrg strlcpy (fileName, dir->directory, sizeof(fileName)); 569c7b4381aSmrg strlcat (fileName, bitmap->fileName, sizeof(fileName)); 570a96d7823Smrg ret = (*bitmap->renderer->GetInfoBitmap) (fpe, pFontInfo, entry, fileName); 571a96d7823Smrg return ret; 572a96d7823Smrg} 573a96d7823Smrg 574a96d7823Smrgstatic void 575a96d7823Smrg_FontFileAddScalableNames(FontNamesPtr names, FontNamesPtr scaleNames, 576a96d7823Smrg FontNamePtr nameptr, char *zeroChars, 577a96d7823Smrg FontScalablePtr vals, fsRange *ranges, 578a96d7823Smrg int nranges, int *max) 579a96d7823Smrg{ 580a96d7823Smrg int i; 581a96d7823Smrg FontScalableRec zeroVals, tmpVals; 582a96d7823Smrg for (i = 0; i < scaleNames->nnames; i++) 583a96d7823Smrg { 584a96d7823Smrg char nameChars[MAXFONTNAMELEN]; 585a96d7823Smrg if (!*max) 586a96d7823Smrg return; 587a96d7823Smrg FontParseXLFDName (scaleNames->names[i], &zeroVals, 588a96d7823Smrg FONT_XLFD_REPLACE_NONE); 589a96d7823Smrg tmpVals = *vals; 590a96d7823Smrg if (FontFileCompleteXLFD (&tmpVals, &zeroVals)) 591a96d7823Smrg { 592a96d7823Smrg --*max; 593a96d7823Smrg 594c7b4381aSmrg strlcpy (nameChars, scaleNames->names[i], sizeof(nameChars)); 595a96d7823Smrg if ((vals->values_supplied & PIXELSIZE_MASK) || 596a96d7823Smrg !(vals->values_supplied & PIXELSIZE_WILDCARD) || 597a96d7823Smrg vals->y == 0) 598a96d7823Smrg { 599a96d7823Smrg tmpVals.values_supplied = 600a96d7823Smrg (tmpVals.values_supplied & ~PIXELSIZE_MASK) | 601a96d7823Smrg (vals->values_supplied & PIXELSIZE_MASK); 602a96d7823Smrg tmpVals.pixel_matrix[0] = vals->pixel_matrix[0]; 603a96d7823Smrg tmpVals.pixel_matrix[1] = vals->pixel_matrix[1]; 604a96d7823Smrg tmpVals.pixel_matrix[2] = vals->pixel_matrix[2]; 605a96d7823Smrg tmpVals.pixel_matrix[3] = vals->pixel_matrix[3]; 606a96d7823Smrg } 607a96d7823Smrg if ((vals->values_supplied & POINTSIZE_MASK) || 608a96d7823Smrg !(vals->values_supplied & POINTSIZE_WILDCARD) || 609a96d7823Smrg vals->y == 0) 610a96d7823Smrg { 611a96d7823Smrg tmpVals.values_supplied = 612a96d7823Smrg (tmpVals.values_supplied & ~POINTSIZE_MASK) | 613a96d7823Smrg (vals->values_supplied & POINTSIZE_MASK); 614a96d7823Smrg tmpVals.point_matrix[0] = vals->point_matrix[0]; 615a96d7823Smrg tmpVals.point_matrix[1] = vals->point_matrix[1]; 616a96d7823Smrg tmpVals.point_matrix[2] = vals->point_matrix[2]; 617a96d7823Smrg tmpVals.point_matrix[3] = vals->point_matrix[3]; 618a96d7823Smrg } 619a96d7823Smrg if (vals->width <= 0) 620a96d7823Smrg tmpVals.width = 0; 621a96d7823Smrg if (vals->x == 0) 622a96d7823Smrg tmpVals.x = 0; 623a96d7823Smrg if (vals->y == 0) 624a96d7823Smrg tmpVals.y = 0; 625a96d7823Smrg tmpVals.ranges = ranges; 626a96d7823Smrg tmpVals.nranges = nranges; 627a96d7823Smrg FontParseXLFDName (nameChars, &tmpVals, 628a96d7823Smrg FONT_XLFD_REPLACE_VALUE); 629a96d7823Smrg /* If we're marking aliases with negative lengths, we 630a96d7823Smrg need to concoct a valid target name to follow it. 631a96d7823Smrg Otherwise we're done. */ 632a96d7823Smrg if (scaleNames->length[i] >= 0) 633a96d7823Smrg { 634a96d7823Smrg (void) xfont2_add_font_names_name (names, nameChars, 635a96d7823Smrg strlen (nameChars)); 636a96d7823Smrg /* If our original pattern matches the name from 637a96d7823Smrg the table and that name doesn't duplicate what 638a96d7823Smrg we just added, add the name from the table */ 639a96d7823Smrg if (strcmp(nameChars, scaleNames->names[i]) && 640a96d7823Smrg FontFileMatchName(scaleNames->names[i], 641a96d7823Smrg scaleNames->length[i], 642a96d7823Smrg nameptr) && 643a96d7823Smrg *max) 644a96d7823Smrg { 645a96d7823Smrg --*max; 646a96d7823Smrg (void) xfont2_add_font_names_name (names, scaleNames->names[i], 647a96d7823Smrg scaleNames->length[i]); 648a96d7823Smrg } 649a96d7823Smrg } 650a96d7823Smrg else 651a96d7823Smrg { 652a96d7823Smrg char *aliasName; 653a96d7823Smrg vals->ranges = ranges; 654a96d7823Smrg vals->nranges = nranges; 655a96d7823Smrg if (transfer_values_to_alias(zeroChars, 656a96d7823Smrg strlen(zeroChars), 657a96d7823Smrg scaleNames->names[++i], 658a96d7823Smrg &aliasName, vals)) 659a96d7823Smrg { 660a96d7823Smrg (void) xfont2_add_font_names_name (names, nameChars, 661a96d7823Smrg strlen (nameChars)); 662a96d7823Smrg names->length[names->nnames - 1] = 663a96d7823Smrg -names->length[names->nnames - 1]; 664a96d7823Smrg (void) xfont2_add_font_names_name (names, aliasName, 665a96d7823Smrg strlen (aliasName)); 666a96d7823Smrg /* If our original pattern matches the name from 667a96d7823Smrg the table and that name doesn't duplicate what 668a96d7823Smrg we just added, add the name from the table */ 669a96d7823Smrg if (strcmp(nameChars, scaleNames->names[i - 1]) && 670a96d7823Smrg FontFileMatchName(scaleNames->names[i - 1], 671a96d7823Smrg -scaleNames->length[i - 1], 672a96d7823Smrg nameptr) && 673a96d7823Smrg *max) 674a96d7823Smrg { 675a96d7823Smrg --*max; 676a96d7823Smrg (void) xfont2_add_font_names_name (names, 677a96d7823Smrg scaleNames->names[i - 1], 678a96d7823Smrg -scaleNames->length[i - 1]); 679a96d7823Smrg names->length[names->nnames - 1] = 680a96d7823Smrg -names->length[names->nnames - 1]; 681a96d7823Smrg (void) xfont2_add_font_names_name (names, aliasName, 682a96d7823Smrg strlen (aliasName)); 683a96d7823Smrg } 684a96d7823Smrg } 685a96d7823Smrg } 686a96d7823Smrg } 687a96d7823Smrg } 688a96d7823Smrg} 689a96d7823Smrg 690a96d7823Smrg/* ARGSUSED */ 691a96d7823Smrgstatic int 692a96d7823Smrg_FontFileListFonts (pointer client, FontPathElementPtr fpe, 693a96d7823Smrg const char *pat, int len, int max, FontNamesPtr names, 694a96d7823Smrg int mark_aliases) 695a96d7823Smrg{ 696a96d7823Smrg FontDirectoryPtr dir; 697a96d7823Smrg char lowerChars[MAXFONTNAMELEN], zeroChars[MAXFONTNAMELEN]; 698a96d7823Smrg FontNameRec lowerName; 699a96d7823Smrg FontNameRec zeroName; 700a96d7823Smrg FontNamesPtr scaleNames; 701a96d7823Smrg FontScalableRec vals; 702a96d7823Smrg fsRange *ranges; 703a96d7823Smrg int nranges; 704a96d7823Smrg int result = BadFontName; 705a96d7823Smrg 706a96d7823Smrg if (len >= MAXFONTNAMELEN) 707a96d7823Smrg return AllocError; 708a96d7823Smrg dir = (FontDirectoryPtr) fpe->private; 709a96d7823Smrg CopyISOLatin1Lowered (lowerChars, pat, len); 710a96d7823Smrg lowerChars[len] = '\0'; 711a96d7823Smrg lowerName.name = lowerChars; 712a96d7823Smrg lowerName.length = len; 713a96d7823Smrg lowerName.ndashes = FontFileCountDashes (lowerChars, len); 714a96d7823Smrg 715a96d7823Smrg /* Match XLFD patterns */ 716a96d7823Smrg 717c7b4381aSmrg strlcpy (zeroChars, lowerChars, sizeof(zeroChars)); 718a96d7823Smrg if (lowerName.ndashes == 14 && 719a96d7823Smrg FontParseXLFDName (zeroChars, &vals, FONT_XLFD_REPLACE_ZERO)) 720a96d7823Smrg { 721a96d7823Smrg ranges = FontParseRanges(lowerChars, &nranges); 722a96d7823Smrg result = FontFileFindNamesInScalableDir (&dir->nonScalable, 723a96d7823Smrg &lowerName, max, names, 724a96d7823Smrg (FontScalablePtr)0, 725a96d7823Smrg (mark_aliases ? 726a96d7823Smrg LIST_ALIASES_AND_TARGET_NAMES : 727a96d7823Smrg NORMAL_ALIAS_BEHAVIOR) | 728a96d7823Smrg IGNORE_SCALABLE_ALIASES, 729a96d7823Smrg &max); 730a96d7823Smrg zeroName.name = zeroChars; 731a96d7823Smrg zeroName.length = strlen (zeroChars); 732a96d7823Smrg zeroName.ndashes = lowerName.ndashes; 733a96d7823Smrg 734a96d7823Smrg /* Look for scalable names and aliases, adding scaled instances of 735a96d7823Smrg them to the output */ 736a96d7823Smrg 737a96d7823Smrg /* Scalable names... */ 738a96d7823Smrg scaleNames = xfont2_make_font_names_record (0); 739a96d7823Smrg if (!scaleNames) 740a96d7823Smrg { 741a96d7823Smrg if (ranges) free(ranges); 742a96d7823Smrg return AllocError; 743a96d7823Smrg } 744a96d7823Smrg FontFileFindNamesInScalableDir (&dir->scalable, &zeroName, max, 745a96d7823Smrg scaleNames, &vals, 746a96d7823Smrg mark_aliases ? 747a96d7823Smrg LIST_ALIASES_AND_TARGET_NAMES : 748a96d7823Smrg NORMAL_ALIAS_BEHAVIOR, (int *)0); 749a96d7823Smrg _FontFileAddScalableNames(names, scaleNames, &lowerName, 750a96d7823Smrg zeroChars, &vals, ranges, nranges, 751a96d7823Smrg &max); 752a96d7823Smrg xfont2_free_font_names (scaleNames); 753a96d7823Smrg 754a96d7823Smrg /* Scalable aliases... */ 755a96d7823Smrg scaleNames = xfont2_make_font_names_record (0); 756a96d7823Smrg if (!scaleNames) 757a96d7823Smrg { 758a96d7823Smrg if (ranges) free(ranges); 759a96d7823Smrg return AllocError; 760a96d7823Smrg } 761a96d7823Smrg FontFileFindNamesInScalableDir (&dir->nonScalable, &zeroName, 762a96d7823Smrg max, scaleNames, &vals, 763a96d7823Smrg mark_aliases ? 764a96d7823Smrg LIST_ALIASES_AND_TARGET_NAMES : 765a96d7823Smrg NORMAL_ALIAS_BEHAVIOR, (int *)0); 766a96d7823Smrg _FontFileAddScalableNames(names, scaleNames, &lowerName, 767a96d7823Smrg zeroChars, &vals, ranges, nranges, 768a96d7823Smrg &max); 769a96d7823Smrg xfont2_free_font_names (scaleNames); 770a96d7823Smrg 771a96d7823Smrg if (ranges) free(ranges); 772a96d7823Smrg } 773a96d7823Smrg else 774a96d7823Smrg { 775a96d7823Smrg result = FontFileFindNamesInScalableDir (&dir->nonScalable, 776a96d7823Smrg &lowerName, max, names, 777a96d7823Smrg (FontScalablePtr)0, 778a96d7823Smrg mark_aliases ? 779a96d7823Smrg LIST_ALIASES_AND_TARGET_NAMES : 780a96d7823Smrg NORMAL_ALIAS_BEHAVIOR, 781a96d7823Smrg &max); 782a96d7823Smrg if (result == Successful) 783a96d7823Smrg result = FontFileFindNamesInScalableDir (&dir->scalable, 784a96d7823Smrg &lowerName, max, names, 785a96d7823Smrg (FontScalablePtr)0, 786a96d7823Smrg mark_aliases ? 787a96d7823Smrg LIST_ALIASES_AND_TARGET_NAMES : 788a96d7823Smrg NORMAL_ALIAS_BEHAVIOR, (int *)0); 789a96d7823Smrg } 790a96d7823Smrg return result; 791a96d7823Smrg} 792a96d7823Smrg 793a96d7823Smrgtypedef struct _LFWIData { 794a96d7823Smrg FontNamesPtr names; 795a96d7823Smrg int current; 796a96d7823Smrg} LFWIDataRec, *LFWIDataPtr; 797a96d7823Smrg 798a96d7823Smrgint 799a96d7823SmrgFontFileListFonts (pointer client, FontPathElementPtr fpe, const char *pat, 800a96d7823Smrg int len, int max, FontNamesPtr names) 801a96d7823Smrg{ 802a96d7823Smrg return _FontFileListFonts (client, fpe, pat, len, max, names, 0); 803a96d7823Smrg} 804a96d7823Smrg 805a96d7823Smrgint 806a96d7823SmrgFontFileStartListFonts(pointer client, FontPathElementPtr fpe, 807a96d7823Smrg const char *pat, int len, int max, 808a96d7823Smrg pointer *privatep, int mark_aliases) 809a96d7823Smrg{ 810a96d7823Smrg LFWIDataPtr data; 811a96d7823Smrg int ret; 812a96d7823Smrg 813a96d7823Smrg data = malloc (sizeof *data); 814a96d7823Smrg if (!data) 815a96d7823Smrg return AllocError; 816a96d7823Smrg data->names = xfont2_make_font_names_record (0); 817a96d7823Smrg if (!data->names) 818a96d7823Smrg { 819a96d7823Smrg free (data); 820a96d7823Smrg return AllocError; 821a96d7823Smrg } 822a96d7823Smrg ret = _FontFileListFonts (client, fpe, pat, len, 823a96d7823Smrg max, data->names, mark_aliases); 824a96d7823Smrg if (ret != Successful) 825a96d7823Smrg { 826a96d7823Smrg xfont2_free_font_names (data->names); 827a96d7823Smrg free (data); 828a96d7823Smrg return ret; 829a96d7823Smrg } 830a96d7823Smrg data->current = 0; 831a96d7823Smrg *privatep = (pointer) data; 832a96d7823Smrg return Successful; 833a96d7823Smrg} 834a96d7823Smrg 835a96d7823Smrg 836a96d7823Smrgint 837a96d7823SmrgFontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, 838a96d7823Smrg const char *pat, int len, int max, 839a96d7823Smrg pointer *privatep) 840a96d7823Smrg{ 841a96d7823Smrg return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 0); 842a96d7823Smrg} 843a96d7823Smrg 844a96d7823Smrg/* ARGSUSED */ 845a96d7823Smrgstatic int 846a96d7823SmrgFontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe, 847a96d7823Smrg char **namep, int *namelenp, 848a96d7823Smrg FontInfoPtr *pFontInfo) 849a96d7823Smrg{ 850a96d7823Smrg FontDirectoryPtr dir; 851a96d7823Smrg char lowerName[MAXFONTNAMELEN]; 852a96d7823Smrg char fileName[MAXFONTFILENAMELEN*2 + 1]; 853a96d7823Smrg FontNameRec tmpName; 854a96d7823Smrg FontEntryPtr entry; 855a96d7823Smrg FontScalableRec vals; 856a96d7823Smrg FontScalableEntryPtr scalable; 857a96d7823Smrg FontScaledPtr scaled; 858a96d7823Smrg FontBitmapEntryPtr bitmap; 859a96d7823Smrg int ret; 860a96d7823Smrg Bool noSpecificSize; 861a96d7823Smrg int nranges; 862a96d7823Smrg fsRange *ranges; 863a96d7823Smrg 864a96d7823Smrg char *name = *namep; 865a96d7823Smrg int namelen = *namelenp; 866a96d7823Smrg 867a96d7823Smrg if (namelen >= MAXFONTNAMELEN) 868a96d7823Smrg return AllocError; 869a96d7823Smrg dir = (FontDirectoryPtr) fpe->private; 870a96d7823Smrg 871a96d7823Smrg /* Match non-scalable pattern */ 872a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 873a96d7823Smrg lowerName[namelen] = '\0'; 874a96d7823Smrg ranges = FontParseRanges(lowerName, &nranges); 875a96d7823Smrg tmpName.name = lowerName; 876a96d7823Smrg tmpName.length = namelen; 877a96d7823Smrg tmpName.ndashes = FontFileCountDashes (lowerName, namelen); 878a96d7823Smrg if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE)) 879a96d7823Smrg bzero(&vals, sizeof(vals)); 880a96d7823Smrg if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) && 881a96d7823Smrg tmpName.ndashes == 14 && 882a96d7823Smrg FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO)) 883a96d7823Smrg { 884a96d7823Smrg tmpName.length = strlen(lowerName); 885a96d7823Smrg entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName); 886a96d7823Smrg } 887a96d7823Smrg 888a96d7823Smrg if (entry) 889a96d7823Smrg { 890a96d7823Smrg switch (entry->type) { 891a96d7823Smrg case FONT_ENTRY_BITMAP: 892a96d7823Smrg bitmap = &entry->u.bitmap; 893a96d7823Smrg if (bitmap->pFont) 894a96d7823Smrg { 895a96d7823Smrg *pFontInfo = &bitmap->pFont->info; 896a96d7823Smrg ret = Successful; 897a96d7823Smrg } 898a96d7823Smrg else 899a96d7823Smrg { 900a96d7823Smrg ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry); 901a96d7823Smrg } 902a96d7823Smrg break; 903a96d7823Smrg case FONT_ENTRY_ALIAS: 904a96d7823Smrg vals.nranges = nranges; 905a96d7823Smrg vals.ranges = ranges; 906a96d7823Smrg transfer_values_to_alias(entry->name.name, entry->name.length, 907a96d7823Smrg entry->u.alias.resolved, namep, &vals); 908a96d7823Smrg *namelenp = strlen (*namep); 909a96d7823Smrg ret = FontNameAlias; 910a96d7823Smrg break; 911a96d7823Smrg default: 912a96d7823Smrg ret = BadFontName; 913a96d7823Smrg } 914a96d7823Smrg } 915a96d7823Smrg else 916a96d7823Smrg { 917a96d7823Smrg ret = BadFontName; 918a96d7823Smrg } 919a96d7823Smrg 920a96d7823Smrg if (ret != BadFontName) 921a96d7823Smrg { 922a96d7823Smrg if (ranges) free(ranges); 923a96d7823Smrg return ret; 924a96d7823Smrg } 925a96d7823Smrg 926a96d7823Smrg /* Match XLFD patterns */ 927a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 928a96d7823Smrg lowerName[namelen] = '\0'; 929a96d7823Smrg tmpName.name = lowerName; 930a96d7823Smrg tmpName.length = namelen; 931a96d7823Smrg tmpName.ndashes = FontFileCountDashes (lowerName, namelen); 932a96d7823Smrg if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) || 933a96d7823Smrg !(tmpName.length = strlen (lowerName), 934a96d7823Smrg entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, 935a96d7823Smrg &vals))) { 936a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 937a96d7823Smrg lowerName[namelen] = '\0'; 938a96d7823Smrg tmpName.name = lowerName; 939a96d7823Smrg tmpName.length = namelen; 940a96d7823Smrg tmpName.ndashes = FontFileCountDashes (lowerName, namelen); 941a96d7823Smrg entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals); 942a96d7823Smrg if (entry) 943a96d7823Smrg { 944c7b4381aSmrg strlcpy(lowerName, entry->name.name, sizeof(lowerName)); 945a96d7823Smrg tmpName.name = lowerName; 946a96d7823Smrg tmpName.length = entry->name.length; 947a96d7823Smrg tmpName.ndashes = entry->name.ndashes; 948a96d7823Smrg } 949a96d7823Smrg } 950a96d7823Smrg 951a96d7823Smrg if (entry) 952a96d7823Smrg { 953a96d7823Smrg noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */ 954a96d7823Smrg if (entry && entry->type == FONT_ENTRY_SCALABLE && 955a96d7823Smrg FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults)) 956a96d7823Smrg { 957a96d7823Smrg scalable = &entry->u.scalable; 958a96d7823Smrg scaled = FontFileFindScaledInstance (entry, &vals, noSpecificSize); 959a96d7823Smrg /* 960a96d7823Smrg * A scaled instance can occur one of two ways: 961a96d7823Smrg * 962a96d7823Smrg * Either the font has been scaled to this 963a96d7823Smrg * size already, in which case scaled->pFont 964a96d7823Smrg * will point at that font. 965a96d7823Smrg * 966a96d7823Smrg * Or a bitmap instance in this size exists, 967a96d7823Smrg * which is handled as if we got a pattern 968a96d7823Smrg * matching the bitmap font name. 969a96d7823Smrg */ 970a96d7823Smrg if (scaled) 971a96d7823Smrg { 972a96d7823Smrg if (scaled->pFont) 973a96d7823Smrg { 974a96d7823Smrg *pFontInfo = &scaled->pFont->info; 975a96d7823Smrg ret = Successful; 976a96d7823Smrg } 977a96d7823Smrg else if (scaled->bitmap) 978a96d7823Smrg { 979a96d7823Smrg entry = scaled->bitmap; 980a96d7823Smrg bitmap = &entry->u.bitmap; 981a96d7823Smrg if (bitmap->pFont) 982a96d7823Smrg { 983a96d7823Smrg *pFontInfo = &bitmap->pFont->info; 984a96d7823Smrg ret = Successful; 985a96d7823Smrg } 986a96d7823Smrg else 987a96d7823Smrg { 988a96d7823Smrg ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry); 989a96d7823Smrg } 990a96d7823Smrg } 991a96d7823Smrg else /* "cannot" happen */ 992a96d7823Smrg { 993a96d7823Smrg ret = BadFontName; 994a96d7823Smrg } 995a96d7823Smrg } 996a96d7823Smrg else 997a96d7823Smrg { 998a96d7823Smrg { 999a96d7823Smrg char origName[MAXFONTNAMELEN]; 1000a96d7823Smrg 1001a96d7823Smrg CopyISOLatin1Lowered (origName, name, namelen); 1002a96d7823Smrg origName[namelen] = '\0'; 1003a96d7823Smrg vals.xlfdName = origName; 1004a96d7823Smrg vals.ranges = ranges; 1005a96d7823Smrg vals.nranges = nranges; 1006a96d7823Smrg 1007a96d7823Smrg /* Make a new scaled instance */ 1008a96d7823Smrg if (strlen(dir->directory) + strlen(scalable->fileName) >= 1009a96d7823Smrg sizeof(fileName)) { 1010a96d7823Smrg ret = BadFontName; 1011a96d7823Smrg } else { 1012c7b4381aSmrg strlcpy (fileName, dir->directory, sizeof(fileName)); 1013c7b4381aSmrg strlcat (fileName, scalable->fileName, sizeof(fileName)); 1014a96d7823Smrg if (scalable->renderer->GetInfoScalable) 1015a96d7823Smrg ret = (*scalable->renderer->GetInfoScalable) 1016a96d7823Smrg (fpe, *pFontInfo, entry, &tmpName, fileName, 1017a96d7823Smrg &vals); 1018a96d7823Smrg else if (scalable->renderer->GetInfoBitmap) 1019a96d7823Smrg ret = (*scalable->renderer->GetInfoBitmap) 1020a96d7823Smrg (fpe, *pFontInfo, entry, fileName); 1021a96d7823Smrg } 1022a96d7823Smrg if (ranges) { 1023a96d7823Smrg free(ranges); 1024a96d7823Smrg ranges = NULL; 1025a96d7823Smrg } 1026a96d7823Smrg } 1027a96d7823Smrg } 1028a96d7823Smrg if (ret == Successful) return ret; 1029a96d7823Smrg } 1030a96d7823Smrg CopyISOLatin1Lowered (lowerName, name, namelen); 1031a96d7823Smrg tmpName.length = namelen; 1032a96d7823Smrg } 1033a96d7823Smrg else 1034a96d7823Smrg ret = BadFontName; 1035a96d7823Smrg 1036a96d7823Smrg if (ranges) 1037a96d7823Smrg free(ranges); 1038a96d7823Smrg return ret; 1039a96d7823Smrg} 1040a96d7823Smrg 1041a96d7823Smrgint 1042a96d7823SmrgFontFileListNextFontWithInfo(pointer client, FontPathElementPtr fpe, 1043a96d7823Smrg char **namep, int *namelenp, 1044a96d7823Smrg FontInfoPtr *pFontInfo, 1045a96d7823Smrg int *numFonts, pointer private) 1046a96d7823Smrg{ 1047a96d7823Smrg LFWIDataPtr data = (LFWIDataPtr) private; 1048a96d7823Smrg int ret; 1049a96d7823Smrg char *name; 1050a96d7823Smrg int namelen; 1051a96d7823Smrg 1052a96d7823Smrg if (data->current == data->names->nnames) 1053a96d7823Smrg { 1054a96d7823Smrg xfont2_free_font_names (data->names); 1055a96d7823Smrg free (data); 1056a96d7823Smrg return BadFontName; 1057a96d7823Smrg } 1058a96d7823Smrg name = data->names->names[data->current]; 1059a96d7823Smrg namelen = data->names->length[data->current]; 1060a96d7823Smrg ret = FontFileListOneFontWithInfo (client, fpe, &name, &namelen, pFontInfo); 1061a96d7823Smrg if (ret == BadFontName) 1062a96d7823Smrg ret = AllocError; 1063a96d7823Smrg *namep = name; 1064a96d7823Smrg *namelenp = namelen; 1065a96d7823Smrg ++data->current; 1066a96d7823Smrg *numFonts = data->names->nnames - data->current; 1067a96d7823Smrg return ret; 1068a96d7823Smrg} 1069a96d7823Smrg 1070a96d7823Smrgint 1071a96d7823SmrgFontFileStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, 1072a96d7823Smrg const char *pat, int len, int max, 1073a96d7823Smrg pointer *privatep) 1074a96d7823Smrg{ 1075a96d7823Smrg return FontFileStartListFonts(client, fpe, pat, len, max, privatep, 1); 1076a96d7823Smrg} 1077a96d7823Smrg 1078a96d7823Smrgint 1079a96d7823SmrgFontFileListNextFontOrAlias(pointer client, FontPathElementPtr fpe, 1080a96d7823Smrg char **namep, int *namelenp, char **resolvedp, 1081a96d7823Smrg int *resolvedlenp, pointer private) 1082a96d7823Smrg{ 1083a96d7823Smrg LFWIDataPtr data = (LFWIDataPtr) private; 1084a96d7823Smrg int ret; 1085a96d7823Smrg char *name; 1086a96d7823Smrg int namelen; 1087a96d7823Smrg 1088a96d7823Smrg if (data->current == data->names->nnames) 1089a96d7823Smrg { 1090a96d7823Smrg xfont2_free_font_names (data->names); 1091a96d7823Smrg free (data); 1092a96d7823Smrg return BadFontName; 1093a96d7823Smrg } 1094a96d7823Smrg name = data->names->names[data->current]; 1095a96d7823Smrg namelen = data->names->length[data->current]; 1096a96d7823Smrg 1097a96d7823Smrg /* If this is a real font name... */ 1098a96d7823Smrg if (namelen >= 0) 1099a96d7823Smrg { 1100a96d7823Smrg *namep = name; 1101a96d7823Smrg *namelenp = namelen; 1102a96d7823Smrg ret = Successful; 1103a96d7823Smrg } 1104a96d7823Smrg /* Else if an alias */ 1105a96d7823Smrg else 1106a96d7823Smrg { 1107a96d7823Smrg /* Tell the caller that this is an alias... let him resolve it to 1108a96d7823Smrg see if it's valid */ 1109a96d7823Smrg *namep = name; 1110a96d7823Smrg *namelenp = -namelen; 1111a96d7823Smrg *resolvedp = data->names->names[++data->current]; 1112a96d7823Smrg *resolvedlenp = data->names->length[data->current]; 1113a96d7823Smrg ret = FontNameAlias; 1114a96d7823Smrg } 1115a96d7823Smrg 1116a96d7823Smrg ++data->current; 1117a96d7823Smrg return ret; 1118a96d7823Smrg} 1119a96d7823Smrg 1120a96d7823Smrgstatic const xfont2_fpe_funcs_rec fontfile_fpe_funcs = { 1121a96d7823Smrg .version = XFONT2_FPE_FUNCS_VERSION, 1122a96d7823Smrg .name_check = FontFileNameCheck, 1123a96d7823Smrg .init_fpe = FontFileInitFPE, 1124a96d7823Smrg .free_fpe = FontFileFreeFPE, 1125a96d7823Smrg .reset_fpe = FontFileResetFPE, 1126a96d7823Smrg .open_font = FontFileOpenFont, 1127a96d7823Smrg .close_font = FontFileCloseFont, 1128a96d7823Smrg .list_fonts = FontFileListFonts, 1129a96d7823Smrg .start_list_fonts_with_info = FontFileStartListFontsWithInfo, 1130a96d7823Smrg .list_next_font_with_info = FontFileListNextFontWithInfo, 1131a96d7823Smrg .wakeup_fpe = 0, 1132a96d7823Smrg .client_died = 0, 1133a96d7823Smrg .load_glyphs = 0, 1134a96d7823Smrg .start_list_fonts_and_aliases = FontFileStartListFontsAndAliases, 1135a96d7823Smrg .list_next_font_or_alias = FontFileListNextFontOrAlias, 1136a96d7823Smrg .set_path_hook = FontFileEmptyBitmapSource, 1137a96d7823Smrg}; 1138a96d7823Smrg 1139a96d7823Smrgvoid 1140a96d7823SmrgFontFileRegisterLocalFpeFunctions (void) 1141a96d7823Smrg{ 1142a96d7823Smrg register_fpe_funcs(&fontfile_fpe_funcs); 1143a96d7823Smrg} 1144