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