00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifdef WITH_FREETYPE
00013
00014 #include "stdafx.h"
00015 #include "debug.h"
00016 #include "fontdetection.h"
00017 #include "string_func.h"
00018 #include "strings_func.h"
00019
00020 extern FT_Library _library;
00021
00027
00028
00029
00030
00031 #ifdef WIN32
00032 #include "core/alloc_func.hpp"
00033 #include "core/math_func.hpp"
00034 #include <windows.h>
00035 #include <shlobj.h>
00036 #include "os/windows/win32.h"
00037
00048 const char *GetShortPath(const TCHAR *long_path)
00049 {
00050 static char short_path[MAX_PATH];
00051 #ifdef UNICODE
00052 WCHAR short_path_w[MAX_PATH];
00053 GetShortPathName(long_path, short_path_w, lengthof(short_path_w));
00054 WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, lengthof(short_path), NULL, NULL);
00055 #else
00056
00057 GetShortPathName(long_path, short_path, lengthof(short_path));
00058 #endif
00059 return short_path;
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #define FONT_DIR_NT "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"
00071 #define FONT_DIR_9X "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts"
00072 FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
00073 {
00074 FT_Error err = FT_Err_Cannot_Open_Resource;
00075 HKEY hKey;
00076 LONG ret;
00077 TCHAR vbuffer[MAX_PATH], dbuffer[256];
00078 TCHAR *pathbuf;
00079 const char *font_path;
00080 uint index;
00081 size_t path_len;
00082
00083
00084
00085
00086 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_NT), 0, KEY_READ, &hKey);
00087 if (ret != ERROR_SUCCESS) ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_9X), 0, KEY_READ, &hKey);
00088
00089 if (ret != ERROR_SUCCESS) {
00090 DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows (NT)\\CurrentVersion\\Fonts");
00091 return err;
00092 }
00093
00094
00095 TCHAR *font_namep = _tcsdup(OTTD2FS(font_name));
00096
00097 for (index = 0;; index++) {
00098 TCHAR *s;
00099 DWORD vbuflen = lengthof(vbuffer);
00100 DWORD dbuflen = lengthof(dbuffer);
00101
00102 ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, NULL, NULL, (byte*)dbuffer, &dbuflen);
00103 if (ret != ERROR_SUCCESS) goto registry_no_font_found;
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 s = _tcschr(vbuffer, _T('('));
00115 if (s != NULL) s[-1] = '\0';
00116
00117 if (_tcschr(vbuffer, _T('&')) == NULL) {
00118 if (_tcsicmp(vbuffer, font_namep) == 0) break;
00119 } else {
00120 if (_tcsstr(vbuffer, font_namep) != NULL) break;
00121 }
00122 }
00123
00124 if (!SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) {
00125 DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
00126 goto folder_error;
00127 }
00128
00129
00130
00131
00132
00133 path_len = _tcslen(vbuffer) + _tcslen(dbuffer) + 2;
00134 pathbuf = AllocaM(TCHAR, path_len);
00135 _sntprintf(pathbuf, path_len, _T("%s\\%s"), vbuffer, dbuffer);
00136
00137
00138 font_path = GetShortPath(pathbuf);
00139
00140 index = 0;
00141 do {
00142 err = FT_New_Face(_library, font_path, index, face);
00143 if (err != FT_Err_Ok) break;
00144
00145 if (strncasecmp(font_name, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
00146
00147 if (strncasecmp(font_name + strlen(font_name) + 1, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
00148 err = FT_Err_Cannot_Open_Resource;
00149
00150 } while ((FT_Long)++index != (*face)->num_faces);
00151
00152
00153 folder_error:
00154 registry_no_font_found:
00155 free(font_namep);
00156 RegCloseKey(hKey);
00157 return err;
00158 }
00159
00173 static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont)
00174 {
00175 static char font_name[MAX_PATH];
00176 const char *ret_font_name = NULL;
00177 uint pos = 0;
00178 HDC dc;
00179 HGDIOBJ oldfont;
00180 byte *buf;
00181 DWORD dw;
00182 uint16 format, count, stringOffset, platformId, encodingId, languageId, nameId, length, offset;
00183
00184 HFONT font = CreateFontIndirect(&logfont->elfLogFont);
00185 if (font == NULL) goto err1;
00186
00187 dc = GetDC(NULL);
00188 oldfont = SelectObject(dc, font);
00189 dw = GetFontData(dc, 'eman', 0, NULL, 0);
00190 if (dw == GDI_ERROR) goto err2;
00191
00192 buf = MallocT<byte>(dw);
00193 dw = GetFontData(dc, 'eman', 0, buf, dw);
00194 if (dw == GDI_ERROR) goto err3;
00195
00196 format = buf[pos++] << 8;
00197 format += buf[pos++];
00198 assert(format == 0);
00199 count = buf[pos++] << 8;
00200 count += buf[pos++];
00201 stringOffset = buf[pos++] << 8;
00202 stringOffset += buf[pos++];
00203 for (uint i = 0; i < count; i++) {
00204 platformId = buf[pos++] << 8;
00205 platformId += buf[pos++];
00206 encodingId = buf[pos++] << 8;
00207 encodingId += buf[pos++];
00208 languageId = buf[pos++] << 8;
00209 languageId += buf[pos++];
00210 nameId = buf[pos++] << 8;
00211 nameId += buf[pos++];
00212 if (nameId != 1) {
00213 pos += 4;
00214 continue;
00215 }
00216 length = buf[pos++] << 8;
00217 length += buf[pos++];
00218 offset = buf[pos++] << 8;
00219 offset += buf[pos++];
00220
00221
00222 length = min(length, MAX_PATH - 1);
00223 for (uint j = 0; j < length; j++) font_name[j] = buf[stringOffset + offset + j];
00224 font_name[length] = '\0';
00225
00226 if ((platformId == 1 && languageId == 0) ||
00227 (platformId == 3 && languageId == 0x0409)) {
00228 ret_font_name = font_name;
00229 break;
00230 }
00231 }
00232
00233 err3:
00234 free(buf);
00235 err2:
00236 SelectObject(dc, oldfont);
00237 ReleaseDC(NULL, dc);
00238 DeleteObject(font);
00239 err1:
00240 return ret_font_name == NULL ? WIDE_TO_MB((const TCHAR*)logfont->elfFullName) : ret_font_name;
00241 }
00242
00243 class FontList {
00244 protected:
00245 TCHAR **fonts;
00246 uint items;
00247 uint capacity;
00248
00249 public:
00250 FontList() : fonts(NULL), items(0), capacity(0) { };
00251
00252 ~FontList() {
00253 if (this->fonts == NULL) return;
00254
00255 for (uint i = 0; i < this->items; i++) {
00256 free(this->fonts[i]);
00257 }
00258
00259 free(this->fonts);
00260 }
00261
00262 bool Add(const TCHAR *font) {
00263 for (uint i = 0; i < this->items; i++) {
00264 if (_tcscmp(this->fonts[i], font) == 0) return false;
00265 }
00266
00267 if (this->items == this->capacity) {
00268 this->capacity += 10;
00269 this->fonts = ReallocT(this->fonts, this->capacity);
00270 }
00271
00272 this->fonts[this->items++] = _tcsdup(font);
00273
00274 return true;
00275 }
00276 };
00277
00278 struct EFCParam {
00279 FreeTypeSettings *settings;
00280 LOCALESIGNATURE locale;
00281 MissingGlyphSearcher *callback;
00282 FontList fonts;
00283 };
00284
00285 static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam)
00286 {
00287 EFCParam *info = (EFCParam *)lParam;
00288
00289
00290 if (!info->fonts.Add((const TCHAR*)logfont->elfFullName)) return 1;
00291
00292 if (!(type & TRUETYPE_FONTTYPE)) return 1;
00293
00294 if (logfont->elfLogFont.lfCharSet == SYMBOL_CHARSET) return 1;
00295
00296 if (info->callback->Monospace() && (logfont->elfLogFont.lfPitchAndFamily & (FF_MODERN | FIXED_PITCH)) != (FF_MODERN | FIXED_PITCH)) return 1;
00297
00298
00299 if ((metric->ntmFontSig.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (metric->ntmFontSig.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) {
00300
00301 FONTSIGNATURE fs;
00302 memset(&fs, 0, sizeof(fs));
00303 HFONT font = CreateFontIndirect(&logfont->elfLogFont);
00304 if (font != NULL) {
00305 HDC dc = GetDC(NULL);
00306 HGDIOBJ oldfont = SelectObject(dc, font);
00307 GetTextCharsetInfo(dc, &fs, 0);
00308 SelectObject(dc, oldfont);
00309 ReleaseDC(NULL, dc);
00310 DeleteObject(font);
00311 }
00312 if ((fs.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (fs.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) return 1;
00313 }
00314
00315 char font_name[MAX_PATH];
00316 convert_from_fs((const TCHAR *)logfont->elfFullName, font_name, lengthof(font_name));
00317
00318
00319 const char *english_name = GetEnglishFontName(logfont);
00320 strecpy(font_name + strlen(font_name) + 1, english_name, lastof(font_name));
00321
00322
00323 bool ft_init = _library != NULL;
00324 bool found = false;
00325 FT_Face face;
00326
00327 if ((ft_init || FT_Init_FreeType(&_library) == FT_Err_Ok) && GetFontByFaceName(font_name, &face) == FT_Err_Ok) {
00328 FT_Done_Face(face);
00329 found = true;
00330 }
00331 if (!ft_init) {
00332
00333 FT_Done_FreeType(_library);
00334 _library = NULL;
00335 }
00336
00337 if (!found) return 1;
00338
00339 info->callback->SetFontNames(info->settings, font_name);
00340 if (info->callback->FindMissingGlyphs(NULL)) return 1;
00341 DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name);
00342 return 0;
00343 }
00344
00345 bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
00346 {
00347 DEBUG(freetype, 1, "Trying fallback fonts");
00348 EFCParam langInfo;
00349 if (GetLocaleInfo(MAKELCID(winlangid, SORT_DEFAULT), LOCALE_FONTSIGNATURE, (LPTSTR)&langInfo.locale, sizeof(langInfo.locale) / sizeof(TCHAR)) == 0) {
00350
00351 DEBUG(freetype, 1, "Can't get locale info for fallback font (langid=0x%x)", winlangid);
00352 return false;
00353 }
00354 langInfo.settings = settings;
00355 langInfo.callback = callback;
00356
00357 LOGFONT font;
00358
00359 font.lfCharSet = DEFAULT_CHARSET;
00360 font.lfFaceName[0] = '\0';
00361 font.lfPitchAndFamily = 0;
00362
00363 HDC dc = GetDC(NULL);
00364 int ret = EnumFontFamiliesEx(dc, &font, (FONTENUMPROC)&EnumFontCallback, (LPARAM)&langInfo, 0);
00365 ReleaseDC(NULL, dc);
00366 return ret == 0;
00367 }
00368
00369 #elif defined(__APPLE__)
00370
00371
00372
00373
00374 #include "os/macosx/macos.h"
00375
00376 FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
00377 {
00378 FT_Error err = FT_Err_Cannot_Open_Resource;
00379
00380
00381 CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name, kCFStringEncodingUTF8);
00382 ATSFontRef font = ATSFontFindFromName(name, kATSOptionFlagsDefault);
00383 CFRelease(name);
00384 if (font == kInvalidFont) return err;
00385
00386
00387 FSRef ref;
00388 OSStatus os_err = -1;
00389 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
00390 if (MacOSVersionIsAtLeast(10, 5, 0)) {
00391 os_err = ATSFontGetFileReference(font, &ref);
00392 } else
00393 #endif
00394 {
00395 #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) && !__LP64__
00396
00397 #if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
00398 #define ATSFSSpec FSSpec
00399 #endif
00400 FSSpec spec;
00401 os_err = ATSFontGetFileSpecification(font, (ATSFSSpec *)&spec);
00402 if (os_err == noErr) os_err = FSpMakeFSRef(&spec, &ref);
00403 #endif
00404 }
00405
00406 if (os_err == noErr) {
00407
00408 UInt8 file_path[PATH_MAX];
00409 if (FSRefMakePath(&ref, file_path, sizeof(file_path)) == noErr) {
00410 DEBUG(freetype, 3, "Font path for %s: %s", font_name, file_path);
00411 err = FT_New_Face(_library, (const char *)file_path, 0, face);
00412 }
00413 }
00414
00415 return err;
00416 }
00417
00418 bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
00419 {
00420 bool result = false;
00421
00422 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
00423 if (MacOSVersionIsAtLeast(10, 5, 0)) {
00424
00425
00426 char lang[16];
00427 if (strcmp(language_isocode, "zh_TW") == 0) {
00428
00429 strecpy(lang, "zh-Hant", lastof(lang));
00430 } else if (strcmp(language_isocode, "zh_CN") == 0) {
00431
00432 strecpy(lang, "zh-Hans", lastof(lang));
00433 } else {
00434
00435 strecpy(lang, language_isocode, lastof(lang));
00436 char *sep = strchr(lang, '_');
00437 if (sep != NULL) *sep = '\0';
00438 }
00439
00440
00441 CFStringRef lang_codes[2];
00442 lang_codes[0] = CFStringCreateWithCString(kCFAllocatorDefault, lang, kCFStringEncodingUTF8);
00443 lang_codes[1] = CFSTR("en");
00444 CFArrayRef lang_arr = CFArrayCreate(kCFAllocatorDefault, (const void **)lang_codes, lengthof(lang_codes), &kCFTypeArrayCallBacks);
00445 CFDictionaryRef lang_attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&kCTFontLanguagesAttribute, (const void **)&lang_arr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
00446 CTFontDescriptorRef lang_desc = CTFontDescriptorCreateWithAttributes(lang_attribs);
00447 CFRelease(lang_arr);
00448 CFRelease(lang_attribs);
00449 CFRelease(lang_codes[0]);
00450
00451
00452 CFSetRef mandatory_attribs = CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontLanguagesAttribute, 1, &kCFTypeSetCallBacks);
00453 CFArrayRef descs = CTFontDescriptorCreateMatchingFontDescriptors(lang_desc, mandatory_attribs);
00454 CFRelease(mandatory_attribs);
00455 CFRelease(lang_desc);
00456
00457 for (CFIndex i = 0; descs != NULL && i < CFArrayGetCount(descs); i++) {
00458 CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs, i);
00459
00460
00461 CFDictionaryRef traits = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
00462 CTFontSymbolicTraits symbolic_traits;
00463 CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait), kCFNumberIntType, &symbolic_traits);
00464 CFRelease(traits);
00465
00466
00467 if ((symbolic_traits & kCTFontClassMaskTrait) == (CTFontStylisticClass)kCTFontSymbolicClass || (symbolic_traits & kCTFontVerticalTrait)) continue;
00468
00469 if (symbolic_traits & kCTFontBoldTrait) continue;
00470
00471 if (((symbolic_traits & kCTFontMonoSpaceTrait) == kCTFontMonoSpaceTrait) != callback->Monospace()) continue;
00472
00473
00474 char name[128];
00475 CFStringRef font_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontDisplayNameAttribute);
00476 CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8);
00477 CFRelease(font_name);
00478
00479
00480
00481 if (name[0] == '.' || strncmp(name, "LastResort", 10) == 0) continue;
00482
00483
00484 callback->SetFontNames(settings, name);
00485 if (!callback->FindMissingGlyphs(NULL)) {
00486 DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name);
00487 result = true;
00488 break;
00489 }
00490 }
00491 if (descs != NULL) CFRelease(descs);
00492 } else
00493 #endif
00494 {
00495
00496
00497 ATSFontIterator itr;
00498 ATSFontRef font;
00499 ATSFontIteratorCreate(kATSFontContextLocal, NULL, NULL, kATSOptionFlagsDefaultScope, &itr);
00500 while (!result && ATSFontIteratorNext(itr, &font) == noErr) {
00501
00502 char name[128];
00503 CFStringRef font_name;
00504 ATSFontGetName(font, kATSOptionFlagsDefault, &font_name);
00505 CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8);
00506
00507 bool monospace = IsMonospaceFont(font_name);
00508 CFRelease(font_name);
00509
00510
00511 if (monospace != callback->Monospace()) continue;
00512
00513
00514 if (strstr(name, "Italic") != NULL || strstr(name, "Bold")) continue;
00515
00516
00517 if (name[0] == '.' || strncmp(name, "Apple Symbols", 13) == 0 || strncmp(name, "LastResort", 10) == 0) continue;
00518
00519
00520 callback->SetFontNames(settings, name);
00521 if (!callback->FindMissingGlyphs(NULL)) {
00522 DEBUG(freetype, 2, "ATS-Font for %s: %s", language_isocode, name);
00523 result = true;
00524 break;
00525 }
00526 }
00527 ATSFontIteratorRelease(&itr);
00528 }
00529
00530 if (!result) {
00531
00532
00533 callback->SetFontNames(settings, "Arial Unicode MS");
00534 result = !callback->FindMissingGlyphs(NULL);
00535 }
00536
00537 callback->FindMissingGlyphs(NULL);
00538 return result;
00539 }
00540
00541 #elif defined(WITH_FONTCONFIG)
00542
00543 #include <fontconfig/fontconfig.h>
00544
00545
00546
00547
00548 FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
00549 {
00550 FT_Error err = FT_Err_Cannot_Open_Resource;
00551
00552 if (!FcInit()) {
00553 ShowInfoF("Unable to load font configuration");
00554 } else {
00555 FcPattern *match;
00556 FcPattern *pat;
00557 FcFontSet *fs;
00558 FcResult result;
00559 char *font_style;
00560 char *font_family;
00561
00562
00563 font_family = strdup(font_name);
00564 font_style = strchr(font_family, ',');
00565 if (font_style != NULL) {
00566 font_style[0] = '\0';
00567 font_style++;
00568 while (*font_style == ' ' || *font_style == '\t') font_style++;
00569 }
00570
00571
00572 pat = FcNameParse((FcChar8*)font_family);
00573 if (font_style != NULL) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style);
00574 FcConfigSubstitute(0, pat, FcMatchPattern);
00575 FcDefaultSubstitute(pat);
00576 fs = FcFontSetCreate();
00577 match = FcFontMatch(0, pat, &result);
00578
00579 if (fs != NULL && match != NULL) {
00580 int i;
00581 FcChar8 *family;
00582 FcChar8 *style;
00583 FcChar8 *file;
00584 FcFontSetAdd(fs, match);
00585
00586 for (i = 0; err != FT_Err_Ok && i < fs->nfont; i++) {
00587
00588 if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) == FcResultMatch &&
00589 FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch &&
00590 FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch) {
00591
00592
00593 if (font_style != NULL && strcasecmp(font_style, (char*)style) != 0) continue;
00594
00595
00596
00597
00598 if (strcasecmp(font_family, (char*)family) == 0) {
00599 err = FT_New_Face(_library, (char *)file, 0, face);
00600 }
00601 }
00602 }
00603 }
00604
00605 free(font_family);
00606 FcPatternDestroy(pat);
00607 FcFontSetDestroy(fs);
00608 FcFini();
00609 }
00610
00611 return err;
00612 }
00613
00614 bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback)
00615 {
00616 if (!FcInit()) return false;
00617
00618 bool ret = false;
00619
00620
00621
00622
00623 char lang[16];
00624 seprintf(lang, lastof(lang), ":lang=%s", language_isocode);
00625 char *split = strchr(lang, '_');
00626 if (split != NULL) *split = '\0';
00627
00628
00629 FcPattern *pat = FcNameParse((FcChar8*)lang);
00630
00631 FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, NULL);
00632
00633 FcFontSet *fs = FcFontList(NULL, pat, os);
00634
00635
00636 FcObjectSetDestroy(os);
00637 FcPatternDestroy(pat);
00638
00639 if (fs != NULL) {
00640 int best_weight = -1;
00641 const char *best_font = NULL;
00642
00643 for (int i = 0; i < fs->nfont; i++) {
00644 FcPattern *font = fs->fonts[i];
00645
00646 FcChar8 *file = NULL;
00647 FcResult res = FcPatternGetString(font, FC_FILE, 0, &file);
00648 if (res != FcResultMatch || file == NULL) {
00649 continue;
00650 }
00651
00652
00653 int value = 0;
00654 FcPatternGetInteger(font, FC_SPACING, 0, &value);
00655 if (callback->Monospace() != (value == FC_MONO) && value != FC_DUAL) continue;
00656
00657
00658 FcPatternGetInteger(font, FC_SLANT, 0, &value);
00659 if (value != 0) continue;
00660
00661
00662 FcPatternGetInteger(font, FC_WEIGHT, 0, &value);
00663 if (value <= best_weight) continue;
00664
00665 callback->SetFontNames(settings, (const char*)file);
00666
00667 bool missing = callback->FindMissingGlyphs(NULL);
00668 DEBUG(freetype, 1, "Font \"%s\" misses%s glyphs", file, missing ? "" : " no");
00669
00670 if (!missing) {
00671 best_weight = value;
00672 best_font = (const char *)file;
00673 }
00674 }
00675
00676 if (best_font != NULL) {
00677 ret = true;
00678 callback->SetFontNames(settings, best_font);
00679 InitFreeType(callback->Monospace());
00680 }
00681
00682
00683 FcFontSetDestroy(fs);
00684 }
00685
00686 FcFini();
00687 return ret;
00688 }
00689
00690 #else
00691 FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) {return FT_Err_Cannot_Open_Resource;}
00692 bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; }
00693 #endif
00694
00695 #endif