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