beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / GlobalParamsWin.cc
blobf9f40ef4e29953c7dd4ef4620bb43020d574f5a1
1 /* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
2 but mostly based on xpdf code.
4 // Copyright (C) 2010, 2012 Hib Eris <hib@hiberis.nl>
5 // Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
6 // Copyright (C) 2012 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
7 // Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com>
8 // Copyright (C) 2012 Mark Brand <mabrand@mabrand.nl>
9 // Copyright (C) 2013 Adam Reichold <adamreichold@myopera.com>
10 // Copyright (C) 2013 Dmytro Morgun <lztoad@gmail.com>
12 TODO: instead of a fixed mapping defined in displayFontTab, it could
13 scan the whole fonts directory, parse TTF files and build font
14 description for all fonts available in Windows. That's how MuPDF works.
17 #ifndef PACKAGE_NAME
18 #include <config.h>
19 #endif
21 #ifdef USE_GCC_PRAGMAS
22 #pragma implementation
23 #endif
25 #include <windows.h>
26 #if !(_WIN32_IE >= 0x0500)
27 #error "_WIN32_IE must be defined >= 0x0500 for SHGFP_TYPE_CURRENT from shlobj.h"
28 #endif
29 #include <shlobj.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <ctype.h>
33 #include <assert.h>
35 #include "goo/gmem.h"
36 #include "goo/GooString.h"
37 #include "goo/GooList.h"
38 #include "goo/GooHash.h"
39 #include "goo/gfile.h"
40 #include "Error.h"
41 #include "NameToCharCode.h"
42 #include "CharCodeToUnicode.h"
43 #include "UnicodeMap.h"
44 #include "CMap.h"
45 #include "BuiltinFontTables.h"
46 #include "FontEncodingTables.h"
47 #include "GlobalParams.h"
48 #include "GfxFont.h"
49 #include <sys/stat.h>
50 #include "Object.h"
51 #include "Stream.h"
52 #include "Lexer.h"
53 #include "Parser.h"
55 #if MULTITHREADED
56 # define lockGlobalParams gLockMutex(&mutex)
57 # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
58 # define lockCMapCache gLockMutex(&cMapCacheMutex)
59 # define unlockGlobalParams gUnlockMutex(&mutex)
60 # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
61 # define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
62 #else
63 # define lockGlobalParams
64 # define lockUnicodeMapCache
65 # define lockCMapCache
66 # define unlockGlobalParams
67 # define unlockUnicodeMapCache
68 # define unlockCMapCache
69 #endif
71 #define DEFAULT_SUBSTITUTE_FONT "Helvetica"
72 #define DEFAULT_CID_FONT_AC1_MSWIN "MingLiU" /* Adobe-CNS1 for Taiwan, HongKong */
73 #define DEFAULT_CID_FONT_AG1_MSWIN "SimSun" /* Adobe-GB1 for PRC, Singapore */
74 #define DEFAULT_CID_FONT_AJ1_MSWIN "MS-Mincho" /* Adobe-Japan1 */
75 #define DEFAULT_CID_FONT_AJ2_MSWIN "MS-Mincho" /* Adobe-Japan2 (legacy) */
76 #define DEFAULT_CID_FONT_AK1_MSWIN "Batang" /* Adobe-Korea1 */
77 #define DEFAULT_CID_FONT_MSWIN "ArialUnicode" /* Unknown */
79 static struct {
80 const char *name;
81 const char *t1FileName;
82 const char *ttFileName;
83 GBool warnIfMissing;
84 } displayFontTab[] = {
85 {"Courier", "n022003l.pfb", "cour.ttf", gTrue},
86 {"Courier-Bold", "n022004l.pfb", "courbd.ttf", gTrue},
87 {"Courier-BoldOblique", "n022024l.pfb", "courbi.ttf", gTrue},
88 {"Courier-Oblique", "n022023l.pfb", "couri.ttf", gTrue},
89 {"Helvetica", "n019003l.pfb", "arial.ttf", gTrue},
90 {"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf", gTrue},
91 {"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf", gTrue},
92 {"Helvetica-Oblique", "n019023l.pfb", "ariali.ttf", gTrue},
93 // TODO: not sure if "symbol.ttf" is right
94 {"Symbol", "s050000l.pfb", "symbol.ttf", gTrue},
95 {"Times-Bold", "n021004l.pfb", "timesbd.ttf", gTrue},
96 {"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf", gTrue},
97 {"Times-Italic", "n021023l.pfb", "timesi.ttf", gTrue},
98 {"Times-Roman", "n021003l.pfb", "times.ttf", gTrue},
99 // TODO: not sure if "wingding.ttf" is right
100 {"ZapfDingbats", "d050000l.pfb", "wingding.ttf", gTrue},
102 // those seem to be frequently accessed by PDF files and I kind of guess
103 // which font file do the refer to
104 {"Palatino", NULL, "pala.ttf", gTrue},
105 {"Palatino-Roman", NULL, "pala.ttf", gTrue},
106 {"Palatino-Bold", NULL, "palab.ttf", gTrue},
107 {"Palatino-Italic", NULL, "palai.ttf", gTrue},
108 {"Palatino,Italic", NULL, "palai.ttf", gTrue},
109 {"Palatino-BoldItalic", NULL, "palabi.ttf", gTrue},
111 {"ArialBlack", NULL, "arialbd.ttf", gTrue},
113 {"ArialNarrow", NULL, "arialn.ttf", gTrue},
114 {"ArialNarrow,Bold", NULL, "arialnb.ttf", gTrue},
115 {"ArialNarrow,Italic", NULL, "arialni.ttf", gTrue},
116 {"ArialNarrow,BoldItalic", NULL, "arialnbi.ttf", gTrue},
117 {"ArialNarrow-Bold", NULL, "arialnb.ttf", gTrue},
118 {"ArialNarrow-Italic", NULL, "arialni.ttf", gTrue},
119 {"ArialNarrow-BoldItalic", NULL, "arialnbi.ttf", gTrue},
121 {"HelveticaNarrow", NULL, "arialn.ttf", gTrue},
122 {"HelveticaNarrow,Bold", NULL, "arialnb.ttf", gTrue},
123 {"HelveticaNarrow,Italic", NULL, "arialni.ttf", gTrue},
124 {"HelveticaNarrow,BoldItalic", NULL, "arialnbi.ttf", gTrue},
125 {"HelveticaNarrow-Bold", NULL, "arialnb.ttf", gTrue},
126 {"HelveticaNarrow-Italic", NULL, "arialni.ttf", gTrue},
127 {"HelveticaNarrow-BoldItalic", NULL, "arialnbi.ttf", gTrue},
129 {"BookAntiqua", NULL, "bkant.ttf", gTrue},
130 {"BookAntiqua,Bold", NULL, "bkant.ttf", gTrue},
131 {"BookAntiqua,Italic", NULL, "bkant.ttf", gTrue},
132 {"BookAntiqua,BoldItalic", NULL, "bkant.ttf", gTrue},
133 {"BookAntiqua-Bold", NULL, "bkant.ttf", gTrue},
134 {"BookAntiqua-Italic", NULL, "bkant.ttf", gTrue},
135 {"BookAntiqua-BoldItalic", NULL, "bkant.ttf", gTrue},
137 {"Verdana", NULL, "verdana.ttf", gTrue},
138 {"Verdana,Bold", NULL, "verdanab.ttf", gTrue},
139 {"Verdana,Italic", NULL, "verdanai.ttf", gTrue},
140 {"Verdana,BoldItalic", NULL, "verdanaz.ttf", gTrue},
141 {"Verdana-Bold", NULL, "verdanab.ttf", gTrue},
142 {"Verdana-Italic", NULL, "verdanai.ttf", gTrue},
143 {"Verdana-BoldItalic", NULL, "verdanaz.ttf", gTrue},
145 {"Tahoma", NULL, "tahoma.ttf", gTrue},
146 {"Tahoma,Bold", NULL, "tahomabd.ttf", gTrue},
147 {"Tahoma,Italic", NULL, "tahoma.ttf", gTrue},
148 {"Tahoma,BoldItalic", NULL, "tahomabd.ttf", gTrue},
149 {"Tahoma-Bold", NULL, "tahomabd.ttf", gTrue},
150 {"Tahoma-Italic", NULL, "tahoma.ttf", gTrue},
151 {"Tahoma-BoldItalic", NULL, "tahomabd.ttf", gTrue},
153 {"CCRIKH+Verdana", NULL, "verdana.ttf", gTrue},
154 {"CCRIKH+Verdana,Bold", NULL, "verdanab.ttf", gTrue},
155 {"CCRIKH+Verdana,Italic", NULL, "verdanai.ttf", gTrue},
156 {"CCRIKH+Verdana,BoldItalic", NULL, "verdanaz.ttf", gTrue},
157 {"CCRIKH+Verdana-Bold", NULL, "verdanab.ttf", gTrue},
158 {"CCRIKH+Verdana-Italic", NULL, "verdanai.ttf", gTrue},
159 {"CCRIKH+Verdana-BoldItalic", NULL, "verdanaz.ttf", gTrue},
161 {"Georgia", NULL, "georgia.ttf", gTrue},
162 {"Georgia,Bold", NULL, "georgiab.ttf", gTrue},
163 {"Georgia,Italic", NULL, "georgiai.ttf", gTrue},
164 {"Georgia,BoldItalic", NULL, "georgiaz.ttf", gTrue},
165 {"Georgia-Bold", NULL, "georgiab.ttf", gTrue},
166 {"Georgia-Italic", NULL, "georgiai.ttf", gTrue},
167 {"Georgia-BoldItalic", NULL, "georgiaz.ttf", gTrue},
169 // fallback for Adobe CID fonts:
170 {"MingLiU", NULL, "mingliu.ttf", gFalse},
171 {"SimSun", NULL, "simsun.ttf", gFalse},
172 {"MS-Mincho", NULL, "msmincho.ttf", gFalse},
173 {"Batang", NULL, "batang.ttf", gFalse},
174 {"ArialUnicode", NULL, "arialuni.ttf", gTrue},
175 {NULL}
178 #define FONTS_SUBDIR "\\fonts"
180 static void GetWindowsFontDir(char *winFontDir, int cbWinFontDirLen)
182 BOOL (__stdcall *SHGetSpecialFolderPathFunc)(HWND hwndOwner,
183 LPTSTR lpszPath,
184 int nFolder,
185 BOOL fCreate);
186 HRESULT (__stdcall *SHGetFolderPathFunc)(HWND hwndOwner,
187 int nFolder,
188 HANDLE hToken,
189 DWORD dwFlags,
190 LPTSTR pszPath);
192 // SHGetSpecialFolderPath isn't available in older versions of shell32.dll (Win95 and
193 // WinNT4), so do a dynamic load of ANSI versions.
194 winFontDir[0] = '\0';
196 HMODULE hLib = LoadLibrary("shell32.dll");
197 if (hLib) {
198 SHGetFolderPathFunc = (HRESULT (__stdcall *)(HWND, int, HANDLE, DWORD, LPTSTR))
199 GetProcAddress(hLib, "SHGetFolderPathA");
200 if (SHGetFolderPathFunc)
201 (*SHGetFolderPathFunc)(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, winFontDir);
203 if (!winFontDir[0]) {
204 // Try an older function
205 SHGetSpecialFolderPathFunc = (BOOL (__stdcall *)(HWND, LPTSTR, int, BOOL))
206 GetProcAddress(hLib, "SHGetSpecialFolderPathA");
207 if (SHGetSpecialFolderPathFunc)
208 (*SHGetSpecialFolderPathFunc)(NULL, winFontDir, CSIDL_FONTS, FALSE);
210 FreeLibrary(hLib);
212 if (winFontDir[0])
213 return;
215 // Try older DLL
216 hLib = LoadLibrary("SHFolder.dll");
217 if (hLib) {
218 SHGetFolderPathFunc = (HRESULT (__stdcall *)(HWND, int, HANDLE, DWORD, LPTSTR))
219 GetProcAddress(hLib, "SHGetFolderPathA");
220 if (SHGetFolderPathFunc)
221 (*SHGetFolderPathFunc)(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, winFontDir);
222 FreeLibrary(hLib);
224 if (winFontDir[0])
225 return;
227 // Everything else failed so the standard fonts directory.
228 GetWindowsDirectory(winFontDir, cbWinFontDirLen);
229 if (winFontDir[0]) {
230 strncat(winFontDir, FONTS_SUBDIR, cbWinFontDirLen);
231 winFontDir[cbWinFontDirLen-1] = 0;
235 static bool FileExists(const char *path)
237 FILE * f = fopen(path, "rb");
238 if (f) {
239 fclose(f);
240 return true;
242 return false;
245 void SysFontList::scanWindowsFonts(GooString *winFontDir) {
246 OSVERSIONINFO version;
247 const char *path;
248 DWORD idx, valNameLen, dataLen, type;
249 HKEY regKey;
250 char valName[1024], data[1024];
251 int n, fontNum;
252 char *p0, *p1;
253 GooString *fontPath;
255 version.dwOSVersionInfoSize = sizeof(version);
256 GetVersionEx(&version);
257 if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
258 path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
259 } else {
260 path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
262 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
263 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
264 &regKey) == ERROR_SUCCESS) {
265 idx = 0;
266 while (1) {
267 valNameLen = sizeof(valName) - 1;
268 dataLen = sizeof(data) - 1;
269 if (RegEnumValue(regKey, idx, valName, &valNameLen, NULL,
270 &type, (LPBYTE)data, &dataLen) != ERROR_SUCCESS) {
271 break;
273 if (type == REG_SZ &&
274 valNameLen > 0 && valNameLen < sizeof(valName) &&
275 dataLen > 0 && dataLen < sizeof(data)) {
276 valName[valNameLen] = '\0';
277 data[dataLen] = '\0';
278 n = strlen(data);
279 if (!strcasecmp(data + n - 4, ".ttf") ||
280 !strcasecmp(data + n - 4, ".ttc") ||
281 !strcasecmp(data + n - 4, ".otf")) {
282 fontPath = new GooString(data);
283 if (!(dataLen >= 3 && data[1] == ':' && data[2] == '\\')) {
284 fontPath->insert(0, '\\');
285 fontPath->insert(0, winFontDir);
286 fontPath->append('\0');
288 p0 = valName;
289 fontNum = 0;
290 while (*p0) {
291 p1 = strstr(p0, " & ");
292 if (p1) {
293 *p1 = '\0';
294 p1 = p1 + 3;
295 } else {
296 p1 = p0 + strlen(p0);
298 fonts->append(makeWindowsFont(p0, fontNum,
299 fontPath->getCString()));
300 p0 = p1;
301 ++fontNum;
303 delete fontPath;
306 ++idx;
308 RegCloseKey(regKey);
312 SysFontInfo *SysFontList::makeWindowsFont(char *name, int fontNum,
313 char *path) {
314 int n;
315 GBool bold, italic, oblique, fixedWidth;
316 GooString *s;
317 char c;
318 int i;
319 SysFontType type;
320 GooString substituteName;
322 n = strlen(name);
323 bold = italic = oblique = fixedWidth = gFalse;
325 // remove trailing ' (TrueType)'
326 if (n > 11 && !strncmp(name + n - 11, " (TrueType)", 11)) {
327 n -= 11;
330 // remove trailing ' (OpenType)'
331 if (n > 11 && !strncmp(name + n - 11, " (OpenType)", 11)) {
332 n -= 11;
335 // remove trailing ' Italic'
336 if (n > 7 && !strncmp(name + n - 7, " Italic", 7)) {
337 n -= 7;
338 italic = gTrue;
341 // remove trailing ' Oblique'
342 if (n > 7 && !strncmp(name + n - 8, " Oblique", 8)) {
343 n -= 8;
344 oblique = gTrue;
347 // remove trailing ' Bold'
348 if (n > 5 && !strncmp(name + n - 5, " Bold", 5)) {
349 n -= 5;
350 bold = gTrue;
353 // remove trailing ' Regular'
354 if (n > 5 && !strncmp(name + n - 8, " Regular", 8)) {
355 n -= 8;
358 // the familyname cannot indicate whether a font is fixedWidth or not.
359 // some well-known fixedWidth typeface family names or keyword are checked.
360 if ( strstr(name, "Courier") ||
361 strstr(name, "Fixed") ||
362 (strstr(name, "Mono") && !strstr(name, "Monotype")) ||
363 strstr(name, "Typewriter") )
364 fixedWidth = gTrue;
365 else
366 fixedWidth = gFalse;
369 //----- normalize the font name
370 s = new GooString(name, n);
371 i = 0;
372 while (i < s->getLength()) {
373 c = s->getChar(i);
374 if (c == ' ' || c == ',' || c == '-') {
375 s->del(i);
376 } else {
377 ++i;
381 if (!strcasecmp(path + strlen(path) - 4, ".ttc")) {
382 type = sysFontTTC;
383 } else {
384 type = sysFontTTF;
387 return new SysFontInfo(s, bold, italic, oblique, fixedWidth,
388 new GooString(path), type, fontNum, substituteName.copy());
391 static GooString* replaceSuffix(GooString *path,
392 const char* suffixA, const char* suffixB)
394 int suffLenA = strlen(suffixA);
395 int suffLenB = strlen(suffixB);
396 int baseLenA = path->getLength() - suffLenA;
397 int baseLenB = path->getLength() - suffLenB;
399 if (!strcasecmp(path->getCString()+baseLenA, suffixA)) {
400 path->del(baseLenA,suffLenA)->append(suffixB);
401 } else if (!strcasecmp(path->getCString()+baseLenB, suffixB)) {
402 path->del(baseLenB,suffLenB)->append(suffixA);
405 return path;
409 void GlobalParams::setupBaseFonts(char * dir)
411 const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
412 GooString *fileName = NULL;
413 GooFile *file;
415 if (baseFontsInitialized)
416 return;
417 baseFontsInitialized = true;
419 char winFontDir[MAX_PATH];
420 GetWindowsFontDir(winFontDir, sizeof(winFontDir));
422 for (int i = 0; displayFontTab[i].name; ++i) {
423 GooString *fontName = new GooString(displayFontTab[i].name);
424 if (fontFiles->lookup(fontName))
425 continue;
427 if (dir) {
428 GooString *fontPath = appendToPath(new GooString(dir), displayFontTab[i].t1FileName);
429 if (FileExists(fontPath->getCString()) ||
430 FileExists(replaceSuffix(fontPath, ".pfb", ".pfa")->getCString())) {
431 addFontFile(fontName, fontPath);
432 continue;
434 delete fontPath;
437 if (winFontDir[0] && displayFontTab[i].ttFileName) {
438 GooString *fontPath = appendToPath(new GooString(winFontDir), displayFontTab[i].ttFileName);
439 if (FileExists(fontPath->getCString()) ||
440 FileExists(replaceSuffix(fontPath, ".ttc", ".ttf")->getCString())) {
441 addFontFile(fontName, fontPath);
442 continue;
444 delete fontPath;
447 if (displayFontTab[i].warnIfMissing) {
448 error(errSyntaxError, -1, "No display font for '{0:s}'", displayFontTab[i].name);
449 delete fontName;
452 if (winFontDir[0]) {
453 GooString gooWinFontsDir(winFontDir);
454 sysFonts->scanWindowsFonts(&gooWinFontsDir);
457 fileName = new GooString(dataRoot);
458 fileName->append("/cidfmap");
460 // try to open file
461 file = GooFile::open(fileName);
463 if (file != NULL) {
464 Parser *parser;
465 Object obj1, obj2;
467 obj1.initNull();
468 parser = new Parser(NULL,
469 new Lexer(NULL,
470 new FileStream(file, 0, gFalse, file->size(), &obj1)),
471 gTrue);
472 obj1.free();
473 parser->getObj(&obj1);
474 while (!obj1.isEOF()) {
475 parser->getObj(&obj2);
476 if (obj1.isName()) {
477 // Substitutions
478 if (obj2.isDict()) {
479 Object obj3;
480 obj2.getDict()->lookup("Path", &obj3);
481 if (obj3.isString())
482 addFontFile(new GooString(obj1.getName()), obj3.getString()->copy());
483 obj3.free();
484 // Aliases
485 } else if (obj2.isName()) {
486 substFiles->add(new GooString(obj1.getName()), new GooString(obj2.getName()));
489 obj2.free();
490 obj1.free();
491 parser->getObj(&obj1);
492 // skip trailing ';'
493 while (obj1.isCmd(";")) {
494 obj1.free();
495 parser->getObj(&obj1);
498 delete file;
499 delete parser;
501 else {
502 delete fileName;
506 static const char *findSubstituteName(GfxFont *font, GooHash *fontFiles,
507 GooHash *substFiles,
508 const char *origName)
510 assert(origName);
511 if (!origName) return NULL;
512 GooString *name2 = new GooString(origName);
513 int n = strlen(origName);
514 // remove trailing "-Identity-H"
515 if (n > 11 && !strcmp(name2->getCString() + n - 11, "-Identity-H")) {
516 name2->del(n - 11, 11);
517 n -= 11;
519 // remove trailing "-Identity-V"
520 if (n > 11 && !strcmp(name2->getCString() + n - 11, "-Identity-V")) {
521 name2->del(n - 11, 11);
522 n -= 11;
524 GooString *substName = (GooString *)substFiles->lookup(name2);
525 if (substName != NULL) {
526 delete name2;
527 return substName->getCString();
530 /* TODO: try to at least guess bold/italic/bolditalic from the name */
531 delete name2;
532 if (font->isCIDFont()) {
533 GooString *collection = ((GfxCIDFont *)font)->getCollection();
535 const char* name3 = NULL;
536 if ( !collection->cmp("Adobe-CNS1") )
537 name3 = DEFAULT_CID_FONT_AC1_MSWIN;
538 else if ( !collection->cmp("Adobe-GB1") )
539 name3 = DEFAULT_CID_FONT_AG1_MSWIN;
540 else if ( !collection->cmp("Adobe-Japan1") )
541 name3 = DEFAULT_CID_FONT_AJ1_MSWIN;
542 else if ( !collection->cmp("Adobe-Japan2") )
543 name3 = DEFAULT_CID_FONT_AJ2_MSWIN;
544 else if ( !collection->cmp("Adobe-Korea1") )
545 name3 = DEFAULT_CID_FONT_AK1_MSWIN;
547 if (name3 && fontFiles->lookup(name3))
548 return name3;
550 if (fontFiles->lookup(DEFAULT_CID_FONT_MSWIN))
551 return DEFAULT_CID_FONT_MSWIN;
553 return DEFAULT_SUBSTITUTE_FONT;
556 /* Windows implementation of external font matching code */
557 GooString *GlobalParams::findSystemFontFile(GfxFont *font,
558 SysFontType *type,
559 int *fontNum, GooString *substituteFontName,
560 GooString *base14Name) {
561 SysFontInfo *fi;
562 GooString *path = NULL;
563 GooString *fontName = font->getName();
564 if (!fontName) return NULL;
565 lockGlobalParams;
566 setupBaseFonts(NULL);
568 // TODO: base14Name should be changed?
569 // In the system using FontConfig, findSystemFontFile() uses
570 // base14Name only for the creation of query pattern.
572 if ((fi = sysFonts->find(fontName, gFalse, gFalse))) {
573 path = fi->path->copy();
574 *type = fi->type;
575 *fontNum = fi->fontNum;
576 if (substituteFontName)
577 substituteFontName->Set(fi->substituteName->getCString());
578 } else {
579 GooString *substFontName = new GooString(findSubstituteName(font, fontFiles,
580 substFiles,
581 fontName->getCString()));
582 GooString *path2 = NULL;
583 error(errSyntaxError, -1, "Couldn't find a font for '{0:t}', subst is '{1:t}'", fontName, substFontName);
584 if ((path2 = (GooString *)fontFiles->lookup(substFontName))) {
585 path = new GooString(path2);
586 if (substituteFontName)
587 substituteFontName->Set(path->getCString());
588 if (!strcasecmp(path->getCString() + path->getLength() - 4, ".ttc")) {
589 *type = sysFontTTC;
590 } else {
591 *type = sysFontTTF;
593 *fontNum = 0;
596 unlockGlobalParams;
597 return path;