source: trunk/poppler/mypoppler/poppler/GlobalParamsWin.cc @ 461

Last change on this file since 461 was 461, checked in by Silvan Scherrer, 11 years ago

poppler update to 0.14.2

File size: 10.2 KB
Line 
1/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
2   but mostly based on xpdf code.
3   
4   // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
5
6TODO: instead of a fixed mapping defined in displayFontTab, it could
7scan the whole fonts directory, parse TTF files and build font
8description for all fonts available in Windows. That's how MuPDF works.
9*/
10
11#ifndef PACKAGE_NAME
12#include <config.h>
13#endif
14
15#ifdef USE_GCC_PRAGMAS
16#pragma implementation
17#endif
18
19#include <windows.h>
20#if !(_WIN32_IE >= 0x0500)
21#error "_WIN32_IE must be defined >= 0x0500 for SHGFP_TYPE_CURRENT from shlobj.h"
22#endif
23#include <shlobj.h>
24#include <string.h>
25#include <stdio.h>
26#include <ctype.h>
27#include <assert.h>
28
29#include "goo/gmem.h"
30#include "goo/GooString.h"
31#include "goo/GooList.h"
32#include "goo/GooHash.h"
33#include "goo/gfile.h"
34#include "Error.h"
35#include "NameToCharCode.h"
36#include "CharCodeToUnicode.h"
37#include "UnicodeMap.h"
38#include "CMap.h"
39#include "BuiltinFontTables.h"
40#include "FontEncodingTables.h"
41#include "GlobalParams.h"
42#include "GfxFont.h"
43
44#if MULTITHREADED
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)
51#else
52#  define lockGlobalParams
53#  define lockUnicodeMapCache
54#  define lockCMapCache
55#  define unlockGlobalParams
56#  define unlockUnicodeMapCache
57#  define unlockCMapCache
58#endif
59
60#define DEFAULT_SUBSTITUTE_FONT "Helvetica"
61
62static struct {
63    char *name;
64    char *t1FileName;
65    char *ttFileName;
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"},
83
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"},
92
93    {"ArialBlack",        NULL, "arialbd.ttf"},
94
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"},
102
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"},
110
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"},
118
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"},
126
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"},
134
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"},
142
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"},
150
151    {NULL}
152};
153
154#define FONTS_SUBDIR "\\fonts"
155
156static void GetWindowsFontDir(char *winFontDir, int cbWinFontDirLen)
157{
158    BOOL (__stdcall *SHGetSpecialFolderPathFunc)(HWND  hwndOwner,
159                                                  LPTSTR lpszPath,
160                                                  int    nFolder,
161                                                  BOOL  fCreate);
162    HRESULT (__stdcall *SHGetFolderPathFunc)(HWND  hwndOwner,
163                                              int    nFolder,
164                                              HANDLE hToken,
165                                              DWORD  dwFlags,
166                                              LPTSTR pszPath);
167
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';
171
172    HMODULE hLib = LoadLibrary("shell32.dll");
173    if (hLib) {
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);
178
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);
185        }
186        FreeLibrary(hLib);
187    }
188    if (winFontDir[0])
189        return;
190
191    // Try older DLL
192    hLib = LoadLibrary("SHFolder.dll");
193    if (hLib) {
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);
198        FreeLibrary(hLib);
199    }
200    if (winFontDir[0])
201        return;
202
203    // Everything else failed so the standard fonts directory.
204    GetWindowsDirectory(winFontDir, cbWinFontDirLen);                                                       
205    if (winFontDir[0]) {
206        strncat(winFontDir, FONTS_SUBDIR, cbWinFontDirLen);
207        winFontDir[cbWinFontDirLen-1] = 0;
208    }
209}
210
211static bool FileExists(const char *path)
212{
213    FILE * f = fopen(path, "rb");
214    if (f) {
215        fclose(f);
216        return true;
217    }
218    return false;
219}
220
221static void AddFont(GooHash *displayFonts, char *fontName, GooString *fontPath, DisplayFontParamKind kind)
222{
223    DisplayFontParam *dfp = new DisplayFontParam(new GooString(fontName), kind);
224    dfp->setFileName(fontPath);
225    displayFonts->add(dfp->name, dfp);
226}
227
228void GlobalParams::setupBaseFonts(char * dir)
229{
230    if (baseFontsInitialized)
231        return;
232    baseFontsInitialized = true;
233
234    char winFontDir[MAX_PATH];
235    GetWindowsFontDir(winFontDir, sizeof(winFontDir));
236
237    for (int i = 0; displayFontTab[i].name; ++i) {
238        char *fontName = displayFontTab[i].name;
239        if (displayFonts->lookup(fontName))
240            continue;
241
242        if (dir) {
243            GooString *fontPath = appendToPath(new GooString(dir), displayFontTab[i].t1FileName);
244            if (FileExists(fontPath->getCString())) {
245                AddFont(displayFonts, fontName, fontPath, displayFontT1);
246                continue;
247            }
248            delete fontPath;
249        }
250
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);
255                continue;
256            }
257            delete fontPath;
258        }
259
260        error(-1, "No display font for '%s'", fontName);
261    }
262}
263
264static char *findSubstituteName(const char *origName)
265{
266    assert(origName);
267    if (!origName) return NULL;
268    /* TODO: try to at least guess bold/italic/bolditalic from the name */
269    return DEFAULT_SUBSTITUTE_FONT;
270}
271
272/* Windows implementation of external font matching code */
273DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
274    DisplayFontParam *  dfp;
275    GooString *         fontName = font->getName();
276    char *              substFontName = NULL;
277
278    if (!fontName) return NULL;
279    lockGlobalParams;
280    setupBaseFonts(NULL);
281    dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
282    if (!dfp) {
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);
286        assert(dfp);
287    }
288    unlockGlobalParams;
289    return dfp;
290}
291
Note: See TracBrowser for help on using the repository browser.