6 #define WIN32_LEAN_AND_MEAN
10 #elif !defined(ECERE_NOTRUETYPE) && !defined(ECERE_NOFONTCONFIG)
12 #include <fontconfig/fontconfig.h>
13 static FcConfig * fcConfig;
17 #if defined(__WIN32__) && !defined(ECERE_NOTRUETYPE)
20 char fileName[MAX_FILENAME];
25 static int CALLBACK MyFontProc(ENUMLOGFONTEX * font, NEWTEXTMETRICEX *lpntme, int fontType, LPARAM lParam)
27 //if(fontType == TRUETYPE_FONTTYPE)
29 FontData * fontData = (FontData *) lParam;
30 char * fileName = (char *)lParam;
32 int weight = (fontData->flags.bold) ? FW_BOLD : FW_NORMAL;
33 int italic = (fontData->flags.italic) ? 1 : 0;
34 if((fontData->forgive || weight == font->elfLogFont.lfWeight) && italic == (font->elfLogFont.lfItalic != 0))
36 if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",0,KEY_READ,&key) ||
37 !RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts",0,KEY_READ,&key))
43 char fontFileName[1024];
46 DWORD sizeFileName = 1024;
48 if(RegEnumValue(key, value++, entryName, &size, null, (PDWORD)&type, (LPBYTE)fontFileName, &sizeFileName) != ERROR_SUCCESS)
50 if((occurrence = SearchString(entryName, 0, (const char *)font->elfFullName, false, false)))
53 for(c = (int)(occurrence - entryName) - 1; c >= 0; c--)
55 char ch = entryName[c];
56 if(ch == '&') { c = -1; break; }
57 else if(ch != ' ') break;
60 for(c = (int)(occurrence - entryName) + strlen((char *)font->elfFullName); ; c++)
62 char ch = entryName[c];
63 if(ch == 0 || ch == '&' || ch == '(') { c = -1; break; }
64 else if(ch != ' ') break;
67 if(atoi(entryName + c))
71 strcpy(fileName, fontFileName);
85 public class FaceInfo : struct
91 ~FaceInfo() { delete fileName; }
94 public Array<FaceInfo> ResolveFont(const String faceName, float size, FontFlags flags)
96 Array<FaceInfo> fileNames { };
97 #if !defined(ECERE_NOTRUETYPE)
98 char fileName[MAX_LOCATION];
99 bool fakeItalic = flags.italic;
101 #if !defined(__WIN32__)
104 const char * ecereFonts = getenv("ECERE_FONTS");
105 if(!ecereFonts) ecereFonts = "<:ecere>";
106 #if !defined(__WIN32__)
108 char linkCfgPath[MAX_LOCATION];
110 strcpy(linkCfgPath, ecereFonts);
111 PathCat(linkCfgPath, "linking.cfg");
112 linkCfg = FileOpen(linkCfgPath, read);
115 strcpy(fileName, faceName);
117 if(!FileExists(fileName))
119 strcpy(fileName, ecereFonts);
120 PathCat(fileName, faceName);
121 if(flags.bold && flags.italic) strcat(fileName, "bi");
122 else if(flags.bold) strcat(fileName, "bd");
123 else if(flags.italic) strcat(fileName, "i");
124 strcat(fileName, ".ttf");
128 if(flags.italic && !FileExists(fileName))
130 strcpy(fileName, ecereFonts);
131 PathCat(fileName, faceName);
132 if(flags.bold) strcat(fileName, "bd");
133 strcat(fileName, ".ttf");
138 // Search in current working directory
139 if(!FileExists(fileName))
141 strcpy(fileName, faceName);
142 if(flags.bold && flags.italic) strcat(fileName, "bi");
143 else if(flags.bold) strcat(fileName, "bd");
144 else if(flags.italic) strcat(fileName, "i");
145 strcat(fileName, ".ttf");
149 if(flags.italic && !FileExists(fileName))
151 strcpy(fileName, faceName);
152 if(flags.bold) strcat(fileName, "bd");
153 strcat(fileName, ".ttf");
159 #if defined(__WIN32__)
160 if(!FileExists(fileName))
162 FontData fontData = { { 0 } };
163 LOGFONT logFont = { 0 };
168 logFont.lfCharSet = DEFAULT_CHARSET;
169 strcpy(logFont.lfFaceName, faceName);
170 fontData.flags = flags;
172 EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (LPARAM)&fontData, 0);
173 if(!fontData.fileName[0] && flags.bold)
175 fontData.forgive = true;
176 EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (LPARAM)&fontData, 0);
178 if(!fontData.fileName[0])
181 fontData.flags.italic = false;
182 EnumFontFamiliesEx(hdc, &logFont, (void *)MyFontProc, (LPARAM)&fontData, 0);
186 if(fontData.fileName[0])
188 GetWindowsDirectory(fileName, MAX_LOCATION);
189 PathCat(fileName, "fonts");
190 PathCat(fileName, fontData.fileName);
194 #elif !defined(ECERE_NOFONTCONFIG)
201 unichar testChar = 0;
204 fcConfig = FcInitLoadConfigAndFonts();
206 charSet = FcCharSetCreate();
208 if(!strcmpi(faceName, "Mangal"))
214 FcCharSetAddChar(charSet, testChar);
216 pattern = FcPatternBuild(null,
217 //FC_SOURCE, FcTypeString, "freetype",
218 FC_FAMILY, FcTypeString, faceName,
219 //FC_SCALABLE, FcTypeBool, 1,
220 FC_SIZE, FcTypeDouble, (double)size,
221 FC_WEIGHT, FcTypeInteger, flags.bold ? FC_WEIGHT_BOLD : FC_WEIGHT_MEDIUM /*FC_WEIGHT_LIGHT*/,
222 FC_SLANT, FcTypeInteger, flags.italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN,
223 testChar ? FC_CHARSET : 0,FcTypeCharSet, charSet,
225 FcDefaultSubstitute(pattern);
226 FcConfigSubstitute(fcConfig, pattern, FcMatchPattern); //FcMatchFont);
228 matched = FcFontMatch (0, pattern, &result);
229 // printf("Locating %s\n", faceName);
232 FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family);
233 //printf("Fontconfig returned %s\n", family);
235 if(matched && (result == FcResultMatch /*|| result == FcResultNoId*/) /*&& !strcmpi(family, faceName)*/)
238 FcPatternGetString (matched, FC_FILE, 0, (FcChar8 **)&fileName2);
239 FcPatternGetInteger(matched, FC_INDEX, 0, &fontID);
240 FcPatternGetDouble(matched, FC_SIZE, 0, &fontSize);
241 strcpy(fileName, fileName2);
242 // size = (float)fontSize;
244 //printf("Matched to %s, %f\n", fileName, size);
248 //printf("Could not find a match for %s, %f, %s %s (%d)\n", faceName, size, flags.bold ? "bold" : "", flags.italic ? "italic" : "", (int)result);
250 if(pattern) FcPatternDestroy(pattern);
251 if(matched) FcPatternDestroy(matched);
252 if(charSet) FcCharSetDestroy(charSet);
257 if(!FileExists(fileName))
258 ChangeExtension(fileName, "otf", fileName);
259 if(!FileExists(fileName))
260 ChangeExtension(fileName, "ttc", fileName);
262 //if(FileExists(fileName))
264 char links[1024] = "";
266 #if defined(__WIN32__)
269 if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink",0,KEY_READ,&key) ||
270 !RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\FontLink\\SystemLink",0,KEY_READ,&key))
275 RegQueryValueEx(key, faceName, null, &type, (LPBYTE)links, &size);
276 memset(links + size, 0, 1024 - size);
284 while(linkCfg.GetLine(line, sizeof(line)))
286 int len = strlen(faceName);
287 if(line[0] == '[' && !strncasecmp(line + 1, faceName, len) && line[len + 1] == ']')
289 while(linkCfg.GetLine(line, sizeof(line)))
291 TrimLSpaces(line, line);
292 if(!line[0] || line[0] == '[')
295 memcpy(links + linksPos, line, len);
309 fileName = CopyString(fileName),
310 fakeItalic = fakeItalic,
313 fileNames.Add(faceInfo);
318 if(!links[linksPos]) break;
319 for(c = 0; (ch = links[linksPos + c]); c++)
325 if(fontName[0] || ch == ',')
327 #if defined(__WIN32__)
328 GetWindowsDirectory(fileName, MAX_LOCATION);
329 PathCat(fileName, "fonts");
330 PathCat(fileName, fontName);
331 #elif !defined(ECERE_NOFONTCONFIG)
332 if(getenv("ECERE_FONTS"))
334 strcpy(fileName, ecereFonts);
335 PathCat(fileName, fontName);
345 pattern = FcPatternBuild(null,
346 //FC_SOURCE, FcTypeString, "freetype",
347 //FC_SCALABLE, FcTypeBool, 1,
348 FC_FAMILY, FcTypeString, links + linksPos + c + 1,
349 FC_SIZE, FcTypeDouble, (double)size,
350 FC_WEIGHT, FcTypeInteger, flags.bold ? FC_WEIGHT_BOLD : FC_WEIGHT_MEDIUM /*FC_WEIGHT_LIGHT*/,
351 FC_SLANT, FcTypeInteger, flags.italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN,
353 FcDefaultSubstitute(pattern);
354 FcConfigSubstitute(fcConfig, pattern, FcMatchPattern); //FcMatchFont);
356 //printf("Locating %s\n", links + linksPos + c + 1);
357 matched = FcFontMatch (0, pattern, &result);
360 FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family);
361 // printf("Fontconfig returned %s\n", family);
363 if(matched && (result == FcResultMatch /*|| result == FcResultNoId*/) &&
364 FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch /*&& !strcmpi(family, links + linksPos + c + 1)*/)
367 FcPatternGetString (matched, FC_FILE, 0, (FcChar8 **)&fileName2);
368 FcPatternGetInteger(matched, FC_INDEX, 0, &fontID);
369 FcPatternGetDouble(matched, FC_SIZE, 0, &fontSize);
370 strcpy(fileName, fileName2);
371 //size = (float)fontSize;
372 // printf("Matched to %s, %f\n", fileName, size);
376 // printf("Could not find a match for %s, %f, %s %s (%d)\n", links + linksPos + c + 1, size, flags.bold ? "bold" : "", flags.italic ? "italic" : "", (int)result);
378 if(pattern) FcPatternDestroy(pattern);
379 if(matched) FcPatternDestroy(matched);
386 while(links[linksPos] && links[linksPos] != ',') linksPos++;
392 #if !defined(__WIN32__)
400 public FaceInfo ResolveCharFont(const String faceName, float size, FontFlags flags, const String lang, unichar testChar)
402 FaceInfo info = null;
403 #if !defined(__WIN32__) && !defined(ECERE_NOFONTCONFIG)
405 double fontSize = size;
409 FcCharSet * charSet = FcCharSetCreate();
411 String fileName = null;
413 FcCharSetAddChar(charSet, testChar);
414 //printf("Loading with char %x\n", testChar);
416 pattern = FcPatternBuild(null,
417 //FC_SOURCE, FcTypeString, "freetype",
418 //FC_SCALABLE, FcTypeBool, 1,
419 FC_FAMILY, FcTypeString, faceName,
420 FC_SIZE, FcTypeDouble, (double)size,
421 FC_WEIGHT, FcTypeInteger, flags.bold ? FC_WEIGHT_BOLD : FC_WEIGHT_MEDIUM,
422 FC_SLANT, FcTypeInteger, flags.italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN,
423 FC_CHARSET,FcTypeCharSet, charSet,
424 lang ? FC_LANG : 0, FcTypeString, lang,
426 FcDefaultSubstitute(pattern);
427 FcConfigSubstitute(fcConfig, pattern, FcMatchPattern); //FcMatchFont);
429 //printf("Locating %s for script %d\n", faceName, curScript);
430 matched = FcFontMatch (0, pattern, &result);
433 FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family);
434 //printf("Fontconfig returned %s\n", family);
436 if(matched && (result == FcResultMatch) && FcPatternGetString(matched, FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch)
438 FcPatternGetString (matched, FC_FILE, 0, (FcChar8 **)&fileName);
439 FcPatternGetInteger(matched, FC_INDEX, 0, &fontID);
440 FcPatternGetDouble(matched, FC_SIZE, 0, &fontSize);
441 // printf("\nMatched to %s, %f\n", fileName, fontSize);
445 fileName = CopyString(fileName);
451 //printf("Could not find a match for %s, %f, %s %s (%d)\n", faceName, size, flags.bold ? "bold" : "", flags.italic ? "italic" : "", (int)result);
453 if(pattern) FcPatternDestroy(pattern);
454 if(matched) FcPatternDestroy(matched);
455 if(charSet) FcCharSetDestroy(charSet);
456 #elif defined(__WIN32__) && !defined(ECERE_NOFONTCONFIG)
458 // Fall back to Arial Unicode MS
459 char fileName[MAX_LOCATION];
460 GetWindowsDirectory(fileName, MAX_LOCATION);
461 PathCat(fileName, "fonts/arialuni.ttf");
462 info = { fileName = CopyString(fileName) };