1
/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
2
but mostly based on xpdf code.
4
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
6
TODO: instead of a fixed mapping defined in displayFontTab, it could
7
scan the whole fonts directory, parse TTF files and build font
8
description for all fonts available in Windows. That's how MuPDF works.
15
#ifdef USE_GCC_PRAGMAS
16
#pragma implementation
20
#if !(_WIN32_IE >= 0x0500)
21
#error "_WIN32_IE must be defined >= 0x0500 for SHGFP_TYPE_CURRENT from shlobj.h"
30
#include "goo/GooString.h"
31
#include "goo/GooList.h"
32
#include "goo/GooHash.h"
33
#include "goo/gfile.h"
35
#include "NameToCharCode.h"
36
#include "CharCodeToUnicode.h"
37
#include "UnicodeMap.h"
39
#include "BuiltinFontTables.h"
40
#include "FontEncodingTables.h"
41
#include "GlobalParams.h"
45
# define lockGlobalParams gLockMutex(&mutex)
46
# define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
47
# define lockCMapCache gLockMutex(&cMapCacheMutex)
48
# define unlockGlobalParams gUnlockMutex(&mutex)
49
# define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
50
# define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
52
# define lockGlobalParams
53
# define lockUnicodeMapCache
54
# define lockCMapCache
55
# define unlockGlobalParams
56
# define unlockUnicodeMapCache
57
# define unlockCMapCache
60
#define DEFAULT_SUBSTITUTE_FONT "Helvetica"
66
} displayFontTab[] = {
67
{"Courier", "n022003l.pfb", "cour.ttf"},
68
{"Courier-Bold", "n022004l.pfb", "courbd.ttf"},
69
{"Courier-BoldOblique", "n022024l.pfb", "courbi.ttf"},
70
{"Courier-Oblique", "n022023l.pfb", "couri.ttf"},
71
{"Helvetica", "n019003l.pfb", "arial.ttf"},
72
{"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf"},
73
{"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf"},
74
{"Helvetica-Oblique", "n019023l.pfb", "ariali.ttf"},
75
// TODO: not sure if "symbol.ttf" is right
76
{"Symbol", "s050000l.pfb", "symbol.ttf"},
77
{"Times-Bold", "n021004l.pfb", "timesbd.ttf"},
78
{"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf"},
79
{"Times-Italic", "n021023l.pfb", "timesi.ttf"},
80
{"Times-Roman", "n021003l.pfb", "times.ttf"},
81
// TODO: not sure if "wingding.ttf" is right
82
{"ZapfDingbats", "d050000l.pfb", "wingding.ttf"},
84
// those seem to be frequently accessed by PDF files and I kind of guess
85
// which font file do the refer to
86
{"Palatino", NULL, "pala.ttf"},
87
{"Palatino-Roman", NULL, "pala.ttf"},
88
{"Palatino-Bold", NULL, "palab.ttf"},
89
{"Palatino-Italic", NULL, "palai.ttf"},
90
{"Palatino,Italic", NULL, "palai.ttf"},
91
{"Palatino-BoldItalic", NULL, "palabi.ttf"},
93
{"ArialBlack", NULL, "arialbd.ttf"},
95
{"ArialNarrow", NULL, "arialn.ttf"},
96
{"ArialNarrow,Bold", NULL, "arialnb.ttf"},
97
{"ArialNarrow,Italic", NULL, "arialni.ttf"},
98
{"ArialNarrow,BoldItalic", NULL, "arialnbi.ttf"},
99
{"ArialNarrow-Bold", NULL, "arialnb.ttf"},
100
{"ArialNarrow-Italic", NULL, "arialni.ttf"},
101
{"ArialNarrow-BoldItalic", NULL, "arialnbi.ttf"},
103
{"HelveticaNarrow", NULL, "arialn.ttf"},
104
{"HelveticaNarrow,Bold", NULL, "arialnb.ttf"},
105
{"HelveticaNarrow,Italic", NULL, "arialni.ttf"},
106
{"HelveticaNarrow,BoldItalic", NULL, "arialnbi.ttf"},
107
{"HelveticaNarrow-Bold", NULL, "arialnb.ttf"},
108
{"HelveticaNarrow-Italic", NULL, "arialni.ttf"},
109
{"HelveticaNarrow-BoldItalic", NULL, "arialnbi.ttf"},
111
{"BookAntiqua", NULL, "bkant.ttf"},
112
{"BookAntiqua,Bold", NULL, "bkant.ttf"},
113
{"BookAntiqua,Italic", NULL, "bkant.ttf"},
114
{"BookAntiqua,BoldItalic", NULL, "bkant.ttf"},
115
{"BookAntiqua-Bold", NULL, "bkant.ttf"},
116
{"BookAntiqua-Italic", NULL, "bkant.ttf"},
117
{"BookAntiqua-BoldItalic", NULL, "bkant.ttf"},
119
{"Verdana", NULL, "verdana.ttf"},
120
{"Verdana,Bold", NULL, "verdanab.ttf"},
121
{"Verdana,Italic", NULL, "verdanai.ttf"},
122
{"Verdana,BoldItalic", NULL, "verdanaz.ttf"},
123
{"Verdana-Bold", NULL, "verdanab.ttf"},
124
{"Verdana-Italic", NULL, "verdanai.ttf"},
125
{"Verdana-BoldItalic", NULL, "verdanaz.ttf"},
127
{"Tahoma", NULL, "tahoma.ttf"},
128
{"Tahoma,Bold", NULL, "tahomabd.ttf"},
129
{"Tahoma,Italic", NULL, "tahoma.ttf"},
130
{"Tahoma,BoldItalic", NULL, "tahomabd.ttf"},
131
{"Tahoma-Bold", NULL, "tahomabd.ttf"},
132
{"Tahoma-Italic", NULL, "tahoma.ttf"},
133
{"Tahoma-BoldItalic", NULL, "tahomabd.ttf"},
135
{"CCRIKH+Verdana", NULL, "verdana.ttf"},
136
{"CCRIKH+Verdana,Bold", NULL, "verdanab.ttf"},
137
{"CCRIKH+Verdana,Italic", NULL, "verdanai.ttf"},
138
{"CCRIKH+Verdana,BoldItalic", NULL, "verdanaz.ttf"},
139
{"CCRIKH+Verdana-Bold", NULL, "verdanab.ttf"},
140
{"CCRIKH+Verdana-Italic", NULL, "verdanai.ttf"},
141
{"CCRIKH+Verdana-BoldItalic", NULL, "verdanaz.ttf"},
143
{"Georgia", NULL, "georgia.ttf"},
144
{"Georgia,Bold", NULL, "georgiab.ttf"},
145
{"Georgia,Italic", NULL, "georgiai.ttf"},
146
{"Georgia,BoldItalic", NULL, "georgiaz.ttf"},
147
{"Georgia-Bold", NULL, "georgiab.ttf"},
148
{"Georgia-Italic", NULL, "georgiai.ttf"},
149
{"Georgia-BoldItalic", NULL, "georgiaz.ttf"},
154
#define FONTS_SUBDIR "\\fonts"
156
static void GetWindowsFontDir(char *winFontDir, int cbWinFontDirLen)
158
BOOL (__stdcall *SHGetSpecialFolderPathFunc)(HWND hwndOwner,
162
HRESULT (__stdcall *SHGetFolderPathFunc)(HWND hwndOwner,
168
// SHGetSpecialFolderPath isn't available in older versions of shell32.dll (Win95 and
169
// WinNT4), so do a dynamic load of ANSI versions.
170
winFontDir[0] = '\0';
172
HMODULE hLib = LoadLibrary("shell32.dll");
174
SHGetFolderPathFunc = (HRESULT (__stdcall *)(HWND, int, HANDLE, DWORD, LPTSTR))
175
GetProcAddress(hLib, "SHGetFolderPathA");
176
if (SHGetFolderPathFunc)
177
(*SHGetFolderPathFunc)(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, winFontDir);
179
if (!winFontDir[0]) {
180
// Try an older function
181
SHGetSpecialFolderPathFunc = (BOOL (__stdcall *)(HWND, LPTSTR, int, BOOL))
182
GetProcAddress(hLib, "SHGetSpecialFolderPathA");
183
if (SHGetSpecialFolderPathFunc)
184
(*SHGetSpecialFolderPathFunc)(NULL, winFontDir, CSIDL_FONTS, FALSE);
192
hLib = LoadLibrary("SHFolder.dll");
194
SHGetFolderPathFunc = (HRESULT (__stdcall *)(HWND, int, HANDLE, DWORD, LPTSTR))
195
GetProcAddress(hLib, "SHGetFolderPathA");
196
if (SHGetFolderPathFunc)
197
(*SHGetFolderPathFunc)(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, winFontDir);
203
// Everything else failed so the standard fonts directory.
204
GetWindowsDirectory(winFontDir, cbWinFontDirLen);
206
strncat(winFontDir, FONTS_SUBDIR, cbWinFontDirLen);
207
winFontDir[cbWinFontDirLen-1] = 0;
211
static bool FileExists(const char *path)
213
FILE * f = fopen(path, "rb");
221
static void AddFont(GooHash *displayFonts, char *fontName, GooString *fontPath, DisplayFontParamKind kind)
223
DisplayFontParam *dfp = new DisplayFontParam(new GooString(fontName), kind);
224
dfp->setFileName(fontPath);
225
displayFonts->add(dfp->name, dfp);
228
void GlobalParams::setupBaseFonts(char * dir)
230
if (baseFontsInitialized)
232
baseFontsInitialized = true;
234
char winFontDir[MAX_PATH];
235
GetWindowsFontDir(winFontDir, sizeof(winFontDir));
237
for (int i = 0; displayFontTab[i].name; ++i) {
238
char *fontName = displayFontTab[i].name;
239
if (displayFonts->lookup(fontName))
243
GooString *fontPath = appendToPath(new GooString(dir), displayFontTab[i].t1FileName);
244
if (FileExists(fontPath->getCString())) {
245
AddFont(displayFonts, fontName, fontPath, displayFontT1);
251
if (winFontDir[0] && displayFontTab[i].ttFileName) {
252
GooString *fontPath = appendToPath(new GooString(winFontDir), displayFontTab[i].ttFileName);
253
if (FileExists(fontPath->getCString())) {
254
AddFont(displayFonts, fontName, fontPath, displayFontTT);
260
error(-1, "No display font for '%s'", fontName);
264
static char *findSubstituteName(const char *origName)
267
if (!origName) return NULL;
268
/* TODO: try to at least guess bold/italic/bolditalic from the name */
269
return DEFAULT_SUBSTITUTE_FONT;
272
/* Windows implementation of external font matching code */
273
DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
274
DisplayFontParam * dfp;
275
GooString * fontName = font->getName();
276
char * substFontName = NULL;
278
if (!fontName) return NULL;
280
setupBaseFonts(NULL);
281
dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
283
substFontName = findSubstituteName(fontName->getCString());
284
error(-1, "Couldn't find a font for '%s', subst is '%s'", fontName->getCString(), substFontName);
285
dfp = (DisplayFontParam *)displayFonts->lookup(substFontName);