1 //========================================================================
2 //
3 // GlobalParams.cc
4 //
5 // Copyright 2001-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 //========================================================================
10 //
11 // Modified under the Poppler project - http://poppler.freedesktop.org
12 //
13 // Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org>
14 // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
15 // Copyright (C) 2005, 2007-2010 Albert Astals Cid <aacid@kde.org>
16 // Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
17 // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
18 // Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
19 // Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk>
20 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
21 // Copyright (C) 2007, 2009 Jonathan Kew <jonathan_kew@sil.org>
22 // Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
23 // Copyright (C) 2009 William Bader <williambader@hotmail.com>
24 // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
25 // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
26 // Copyright (C) 2010 Patrick Spendrin <ps_ml@gmx.de>
27 // Copyright (C) 2010 Jakub Wilk <ubanus@users.sf.net>
28 //
29 // To see a description of the changes please see the Changelog file that
30 // came with your tarball or type make ChangeLog if you are building from git
31 //
32 //========================================================================
33
34 #include <config.h>
35
36 #ifdef USE_GCC_PRAGMAS
37 #pragma implementation
38 #endif
39
40 #include <string.h>
41 #include <stdio.h>
42 #include <ctype.h>
43 #ifdef ENABLE_PLUGINS
44 # ifndef _WIN32
45 # include <dlfcn.h>
46 # endif
47 #endif
48 #ifdef _WIN32
49 # include <shlobj.h>
50 # include <mbstring.h>
51 #endif
52 #include "goo/gmem.h"
53 #include "goo/GooString.h"
54 #include "goo/GooList.h"
55 #include "goo/GooHash.h"
56 #include "goo/gfile.h"
57 #include "Error.h"
58 #include "NameToCharCode.h"
59 #include "CharCodeToUnicode.h"
60 #include "UnicodeMap.h"
61 #include "CMap.h"
62 #include "BuiltinFontTables.h"
63 #include "FontEncodingTables.h"
64 #ifdef ENABLE_PLUGINS
65 # include "XpdfPluginAPI.h"
66 #endif
67 #include "GlobalParams.h"
68 #include "GfxFont.h"
69
70 #ifdef _WIN32
71 # define strcasecmp stricmp
72 #else
73 # include <strings.h>
74 #endif
75
76 #if MULTITHREADED
77 # define lockGlobalParams gLockMutex(&mutex)
78 # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
79 # define lockCMapCache gLockMutex(&cMapCacheMutex)
80 # define unlockGlobalParams gUnlockMutex(&mutex)
81 # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
82 # define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
83 #else
84 # define lockGlobalParams
85 # define lockUnicodeMapCache
86 # define lockCMapCache
87 # define unlockGlobalParams
88 # define unlockUnicodeMapCache
89 # define unlockCMapCache
90 #endif
91
92 #ifndef FC_WEIGHT_BOOK
93 #define FC_WEIGHT_BOOK 75
94 #endif
95
96 #include "NameToUnicodeTable.h"
97 #include "UnicodeMapTables.h"
98 #include "UTF8.h"
99
100 #ifdef ENABLE_PLUGINS
101 # ifdef _WIN32
102 extern XpdfPluginVecTable xpdfPluginVecTable;
103 # endif
104 #endif
105
106 //------------------------------------------------------------------------
107
108 #define cidToUnicodeCacheSize 4
109 #define unicodeToUnicodeCacheSize 4
110
111 //------------------------------------------------------------------------
112
113 GlobalParams *globalParams = NULL;
114
115 //------------------------------------------------------------------------
116 // DisplayFontParam
117 //------------------------------------------------------------------------
118
DisplayFontParam(GooString * nameA,DisplayFontParamKind kindA)119 DisplayFontParam::DisplayFontParam(GooString *nameA,
120 DisplayFontParamKind kindA) {
121 name = nameA;
122 kind = kindA;
123 switch (kind) {
124 case displayFontT1:
125 t1.fileName = NULL;
126 break;
127 case displayFontTT:
128 tt.fileName = NULL;
129 break;
130 }
131 }
132
~DisplayFontParam()133 DisplayFontParam::~DisplayFontParam() {
134 delete name;
135 switch (kind) {
136 case displayFontT1:
137 if (t1.fileName) {
138 delete t1.fileName;
139 }
140 break;
141 case displayFontTT:
142 if (tt.fileName) {
143 delete tt.fileName;
144 }
145 break;
146 }
147 }
148
149 #if ENABLE_RELOCATABLE && defined(_WIN32)
150
151 /* search for data relative to where we are installed */
152
153 static HMODULE hmodule;
154
155 extern "C" {
156 BOOL WINAPI
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)157 DllMain (HINSTANCE hinstDLL,
158 DWORD fdwReason,
159 LPVOID lpvReserved)
160 {
161 switch (fdwReason)
162 {
163 case DLL_PROCESS_ATTACH:
164 hmodule = hinstDLL;
165 break;
166 }
167
168 return TRUE;
169 }
170 }
171
172 static char *
get_poppler_datadir(void)173 get_poppler_datadir (void)
174 {
175 static char retval[MAX_PATH];
176 static int beenhere = 0;
177
178 unsigned char *p;
179
180 if (beenhere)
181 return retval;
182
183 if (!GetModuleFileName (hmodule, (CHAR *) retval, sizeof(retval) - 20))
184 return POPPLER_DATADIR;
185
186 p = _mbsrchr ((unsigned char *) retval, '\\');
187 *p = '\0';
188 p = _mbsrchr ((unsigned char *) retval, '\\');
189 if (p) {
190 if (stricmp ((const char *) (p+1), "bin") == 0)
191 *p = '\0';
192 }
193 strcat (retval, "\\share\\poppler");
194
195 beenhere = 1;
196
197 return retval;
198 }
199
200 #undef POPPLER_DATADIR
201 #define POPPLER_DATADIR get_poppler_datadir ()
202
203 #endif
204
205 #ifdef _WIN32
206
207 //------------------------------------------------------------------------
208 // WinFontInfo
209 //------------------------------------------------------------------------
210
211 class WinFontInfo: public DisplayFontParam {
212 public:
213
214 GBool bold, italic;
215
216 static WinFontInfo *make(GooString *nameA, GBool boldA, GBool italicA,
217 HKEY regKey, char *winFontDir);
218 WinFontInfo(GooString *nameA, GBool boldA, GBool italicA,
219 GooString *fileNameA);
220 virtual ~WinFontInfo();
221 GBool equals(WinFontInfo *fi);
222 };
223
make(GooString * nameA,GBool boldA,GBool italicA,HKEY regKey,char * winFontDir)224 WinFontInfo *WinFontInfo::make(GooString *nameA, GBool boldA, GBool italicA,
225 HKEY regKey, char *winFontDir) {
226 GooString *regName;
227 GooString *fileNameA;
228 char buf[MAX_PATH];
229 DWORD n;
230 char c;
231 int i;
232
233 //----- find the font file
234 fileNameA = NULL;
235 regName = nameA->copy();
236 if (boldA) {
237 regName->append(" Bold");
238 }
239 if (italicA) {
240 regName->append(" Italic");
241 }
242 regName->append(" (TrueType)");
243 n = sizeof(buf);
244 if (RegQueryValueEx(regKey, regName->getCString(), NULL, NULL,
245 (LPBYTE)buf, &n) == ERROR_SUCCESS) {
246 fileNameA = new GooString(winFontDir);
247 fileNameA->append('\\')->append(buf);
248 }
249 delete regName;
250 if (!fileNameA) {
251 delete nameA;
252 return NULL;
253 }
254
255 //----- normalize the font name
256 i = 0;
257 while (i < nameA->getLength()) {
258 c = nameA->getChar(i);
259 if (c == ' ' || c == ',' || c == '-') {
260 nameA->del(i);
261 } else {
262 ++i;
263 }
264 }
265
266 return new WinFontInfo(nameA, boldA, italicA, fileNameA);
267 }
268
WinFontInfo(GooString * nameA,GBool boldA,GBool italicA,GooString * fileNameA)269 WinFontInfo::WinFontInfo(GooString *nameA, GBool boldA, GBool italicA,
270 GooString *fileNameA):
271 DisplayFontParam(nameA, displayFontTT)
272 {
273 bold = boldA;
274 italic = italicA;
275 tt.fileName = fileNameA;
276 }
277
~WinFontInfo()278 WinFontInfo::~WinFontInfo() {
279 }
280
equals(WinFontInfo * fi)281 GBool WinFontInfo::equals(WinFontInfo *fi) {
282 return !name->cmp(fi->name) && bold == fi->bold && italic == fi->italic;
283 }
284
285 //------------------------------------------------------------------------
286 // WinFontList
287 //------------------------------------------------------------------------
288
289 class WinFontList {
290 public:
291
292 WinFontList(char *winFontDirA);
293 ~WinFontList();
294 WinFontInfo *find(GooString *font);
295
296 private:
297
298 void add(WinFontInfo *fi);
299 static int CALLBACK enumFunc1(CONST LOGFONT *font,
300 CONST TEXTMETRIC *metrics,
301 DWORD type, LPARAM data);
302 static int CALLBACK enumFunc2(CONST LOGFONT *font,
303 CONST TEXTMETRIC *metrics,
304 DWORD type, LPARAM data);
305
306 GooList *fonts; // [WinFontInfo]
307 HDC dc; // (only used during enumeration)
308 HKEY regKey; // (only used during enumeration)
309 char *winFontDir; // (only used during enumeration)
310 };
311
WinFontList(char * winFontDirA)312 WinFontList::WinFontList(char *winFontDirA) {
313 OSVERSIONINFO version;
314 char *path;
315
316 fonts = new GooList();
317 dc = GetDC(NULL);
318 winFontDir = winFontDirA;
319 version.dwOSVersionInfoSize = sizeof(version);
320 GetVersionEx(&version);
321 if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
322 path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
323 } else {
324 path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
325 }
326 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
327 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
328 ®Key) == ERROR_SUCCESS) {
329 EnumFonts(dc, NULL, &WinFontList::enumFunc1, (LPARAM)this);
330 RegCloseKey(regKey);
331 }
332 ReleaseDC(NULL, dc);
333 }
334
~WinFontList()335 WinFontList::~WinFontList() {
336 deleteGooList(fonts, WinFontInfo);
337 }
338
add(WinFontInfo * fi)339 void WinFontList::add(WinFontInfo *fi) {
340 int i;
341
342 for (i = 0; i < fonts->getLength(); ++i) {
343 if (((WinFontInfo *)fonts->get(i))->equals(fi)) {
344 delete fi;
345 return;
346 }
347 }
348 fonts->append(fi);
349 }
350
find(GooString * font)351 WinFontInfo *WinFontList::find(GooString *font) {
352 GooString *name;
353 GBool bold, italic;
354 WinFontInfo *fi;
355 char c;
356 int n, i;
357
358 name = font->copy();
359
360 // remove space, comma, dash chars
361 i = 0;
362 while (i < name->getLength()) {
363 c = name->getChar(i);
364 if (c == ' ' || c == ',' || c == '-') {
365 name->del(i);
366 } else {
367 ++i;
368 }
369 }
370 n = name->getLength();
371
372 // remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
373 if (!strcmp(name->getCString() + n - 2, "MT")) {
374 name->del(n - 2, 2);
375 n -= 2;
376 }
377
378 // look for "Italic"
379 if (!strcmp(name->getCString() + n - 6, "Italic")) {
380 name->del(n - 6, 6);
381 italic = gTrue;
382 n -= 6;
383 } else {
384 italic = gFalse;
385 }
386
387 // look for "Bold"
388 if (!strcmp(name->getCString() + n - 4, "Bold")) {
389 name->del(n - 4, 4);
390 bold = gTrue;
391 n -= 4;
392 } else {
393 bold = gFalse;
394 }
395
396 // remove trailing "MT" (FooMT-Bold, etc.)
397 if (!strcmp(name->getCString() + n - 2, "MT")) {
398 name->del(n - 2, 2);
399 n -= 2;
400 }
401
402 // remove trailing "PS"
403 if (!strcmp(name->getCString() + n - 2, "PS")) {
404 name->del(n - 2, 2);
405 n -= 2;
406 }
407
408 // search for the font
409 fi = NULL;
410 for (i = 0; i < fonts->getLength(); ++i) {
411 fi = (WinFontInfo *)fonts->get(i);
412 if (!fi->name->cmp(name) && fi->bold == bold && fi->italic == italic) {
413 break;
414 }
415 fi = NULL;
416 }
417
418 delete name;
419 return fi;
420 }
421
enumFunc1(CONST LOGFONT * font,CONST TEXTMETRIC * metrics,DWORD type,LPARAM data)422 int CALLBACK WinFontList::enumFunc1(CONST LOGFONT *font,
423 CONST TEXTMETRIC *metrics,
424 DWORD type, LPARAM data) {
425 WinFontList *fl = (WinFontList *)data;
426
427 EnumFonts(fl->dc, font->lfFaceName, &WinFontList::enumFunc2, (LPARAM)fl);
428 return 1;
429 }
430
enumFunc2(CONST LOGFONT * font,CONST TEXTMETRIC * metrics,DWORD type,LPARAM data)431 int CALLBACK WinFontList::enumFunc2(CONST LOGFONT *font,
432 CONST TEXTMETRIC *metrics,
433 DWORD type, LPARAM data) {
434 WinFontList *fl = (WinFontList *)data;
435 WinFontInfo *fi;
436
437 if (type & TRUETYPE_FONTTYPE) {
438 if ((fi = WinFontInfo::make(new GooString(font->lfFaceName),
439 font->lfWeight >= 600,
440 font->lfItalic ? gTrue : gFalse,
441 fl->regKey, fl->winFontDir))) {
442 fl->add(fi);
443 }
444 }
445 return 1;
446 }
447
448 #endif // _WIN32
449
450 //------------------------------------------------------------------------
451 // PSFontParam
452 //------------------------------------------------------------------------
453
PSFontParam(GooString * pdfFontNameA,int wModeA,GooString * psFontNameA,GooString * encodingA)454 PSFontParam::PSFontParam(GooString *pdfFontNameA, int wModeA,
455 GooString *psFontNameA, GooString *encodingA) {
456 pdfFontName = pdfFontNameA;
457 wMode = wModeA;
458 psFontName = psFontNameA;
459 encoding = encodingA;
460 }
461
~PSFontParam()462 PSFontParam::~PSFontParam() {
463 delete pdfFontName;
464 delete psFontName;
465 if (encoding) {
466 delete encoding;
467 }
468 }
469
470 #ifdef ENABLE_PLUGINS
471 //------------------------------------------------------------------------
472 // Plugin
473 //------------------------------------------------------------------------
474
475 class Plugin {
476 public:
477
478 static Plugin *load(char *type, char *name);
479 ~Plugin();
480
481 private:
482
483 #ifdef _WIN32
484 Plugin(HMODULE libA);
485 HMODULE lib;
486 #else
487 Plugin(void *dlA);
488 void *dl;
489 #endif
490 };
491
load(char * type,char * name)492 Plugin *Plugin::load(char *type, char *name) {
493 GooString *path;
494 Plugin *plugin;
495 XpdfPluginVecTable *vt;
496 XpdfBool (*xpdfInitPlugin)(void);
497 #ifdef _WIN32
498 HMODULE libA;
499 #else
500 void *dlA;
501 #endif
502
503 path = globalParams->getBaseDir();
504 appendToPath(path, "plugins");
505 appendToPath(path, type);
506 appendToPath(path, name);
507
508 #ifdef _WIN32
509 path->append(".dll");
510 if (!(libA = LoadLibrary(path->getCString()))) {
511 error(-1, "Failed to load plugin '%s'",
512 path->getCString());
513 goto err1;
514 }
515 if (!(vt = (XpdfPluginVecTable *)
516 GetProcAddress(libA, "xpdfPluginVecTable"))) {
517 error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
518 path->getCString());
519 goto err2;
520 }
521 #else
522 //~ need to deal with other extensions here
523 path->append(".so");
524 if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
525 error(-1, "Failed to load plugin '%s': %s",
526 path->getCString(), dlerror());
527 goto err1;
528 }
529 if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
530 error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
531 path->getCString());
532 goto err2;
533 }
534 #endif
535
536 if (vt->version != xpdfPluginVecTable.version) {
537 error(-1, "Plugin '%s' is wrong version", path->getCString());
538 goto err2;
539 }
540 memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
541
542 #ifdef _WIN32
543 if (!(xpdfInitPlugin = (XpdfBool (*)(void))
544 GetProcAddress(libA, "xpdfInitPlugin"))) {
545 error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
546 path->getCString());
547 goto err2;
548 }
549 #else
550 if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
551 error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
552 path->getCString());
553 goto err2;
554 }
555 #endif
556
557 if (!(*xpdfInitPlugin)()) {
558 error(-1, "Initialization of plugin '%s' failed",
559 path->getCString());
560 goto err2;
561 }
562
563 #ifdef _WIN32
564 plugin = new Plugin(libA);
565 #else
566 plugin = new Plugin(dlA);
567 #endif
568
569 delete path;
570 return plugin;
571
572 err2:
573 #ifdef _WIN32
574 FreeLibrary(libA);
575 #else
576 dlclose(dlA);
577 #endif
578 err1:
579 delete path;
580 return NULL;
581 }
582
583 #ifdef _WIN32
Plugin(HMODULE libA)584 Plugin::Plugin(HMODULE libA) {
585 lib = libA;
586 }
587 #else
Plugin(void * dlA)588 Plugin::Plugin(void *dlA) {
589 dl = dlA;
590 }
591 #endif
592
~Plugin()593 Plugin::~Plugin() {
594 void (*xpdfFreePlugin)(void);
595
596 #ifdef _WIN32
597 if ((xpdfFreePlugin = (void (*)(void))
598 GetProcAddress(lib, "xpdfFreePlugin"))) {
599 (*xpdfFreePlugin)();
600 }
601 FreeLibrary(lib);
602 #else
603 if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
604 (*xpdfFreePlugin)();
605 }
606 dlclose(dl);
607 #endif
608 }
609
610 #endif // ENABLE_PLUGINS
611
612 //------------------------------------------------------------------------
613 // parsing
614 //------------------------------------------------------------------------
615
GlobalParams(const char * customPopplerDataDir)616 GlobalParams::GlobalParams(const char *customPopplerDataDir)
617 : popplerDataDir(customPopplerDataDir)
618 {
619 UnicodeMap *map;
620 int i;
621
622 #if MULTITHREADED
623 gInitMutex(&mutex);
624 gInitMutex(&unicodeMapCacheMutex);
625 gInitMutex(&cMapCacheMutex);
626 #endif
627
628 initBuiltinFontTables();
629
630 // scan the encoding in reverse because we want the lowest-numbered
631 // index for each char name ('space' is encoded twice)
632 macRomanReverseMap = new NameToCharCode();
633 for (i = 255; i >= 0; --i) {
634 if (macRomanEncoding[i]) {
635 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
636 }
637 }
638
639 #ifdef _WIN32
640 // baseDir will be set by a call to setBaseDir
641 baseDir = new GooString();
642 #else
643 baseDir = appendToPath(getHomeDir(), ".xpdf");
644 #endif
645 nameToUnicode = new NameToCharCode();
646 cidToUnicodes = new GooHash(gTrue);
647 unicodeToUnicodes = new GooHash(gTrue);
648 residentUnicodeMaps = new GooHash();
649 unicodeMaps = new GooHash(gTrue);
650 cMapDirs = new GooHash(gTrue);
651 toUnicodeDirs = new GooList();
652 displayFonts = new GooHash();
653 psExpandSmaller = gFalse;
654 psShrinkLarger = gTrue;
655 psCenter = gTrue;
656 psLevel = psLevel2;
657 psFonts = new GooHash();
658 psNamedFonts16 = new GooList();
659 psFonts16 = new GooList();
660 psEmbedType1 = gTrue;
661 psEmbedTrueType = gTrue;
662 psEmbedCIDPostScript = gTrue;
663 psEmbedCIDTrueType = gTrue;
664 psSubstFonts = gTrue;
665 psPreload = gFalse;
666 psOPI = gFalse;
667 psASCIIHex = gFalse;
668 textEncoding = new GooString("UTF-8");
669 #if defined(_WIN32)
670 textEOL = eolDOS;
671 #elif defined(MACOS)
672 textEOL = eolMac;
673 #else
674 textEOL = eolUnix;
675 #endif
676 textPageBreaks = gTrue;
677 textKeepTinyChars = gFalse;
678 fontDirs = new GooList();
679 enableFreeType = gTrue;
680 antialias = gTrue;
681 vectorAntialias = gTrue;
682 strokeAdjust = gTrue;
683 screenType = screenUnset;
684 screenSize = -1;
685 screenDotRadius = -1;
686 screenGamma = 1.0;
687 screenBlackThreshold = 0.0;
688 screenWhiteThreshold = 1.0;
689 mapNumericCharNames = gTrue;
690 mapUnknownCharNames = gFalse;
691 printCommands = gFalse;
692 profileCommands = gFalse;
693 errQuiet = gFalse;
694
695 cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
696 unicodeToUnicodeCache =
697 new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
698 unicodeMapCache = new UnicodeMapCache();
699 cMapCache = new CMapCache();
700
701 #ifdef _WIN32
702 baseFontsInitialized = gFalse;
703 winFontList = NULL;
704 #endif
705
706 #ifdef ENABLE_PLUGINS
707 plugins = new GooList();
708 securityHandlers = new GooList();
709 #endif
710
711 // set up the initial nameToUnicode table
712 for (i = 0; nameToUnicodeTab[i].name; ++i) {
713 nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
714 }
715
716 // set up the residentUnicodeMaps table
717 map = new UnicodeMap("Latin1", gFalse,
718 latin1UnicodeMapRanges, latin1UnicodeMapLen);
719 residentUnicodeMaps->add(map->getEncodingName(), map);
720 map = new UnicodeMap("ASCII7", gFalse,
721 ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
722 residentUnicodeMaps->add(map->getEncodingName(), map);
723 map = new UnicodeMap("Symbol", gFalse,
724 symbolUnicodeMapRanges, symbolUnicodeMapLen);
725 residentUnicodeMaps->add(map->getEncodingName(), map);
726 map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
727 zapfDingbatsUnicodeMapLen);
728 residentUnicodeMaps->add(map->getEncodingName(), map);
729 map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
730 residentUnicodeMaps->add(map->getEncodingName(), map);
731 map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
732 residentUnicodeMaps->add(map->getEncodingName(), map);
733
734 scanEncodingDirs();
735 }
736
scanEncodingDirs()737 void GlobalParams::scanEncodingDirs() {
738 GDir *dir;
739 GDirEntry *entry;
740 const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
741
742 // allocate buffer large enough to append "/nameToUnicode"
743 size_t bufSize = strlen(dataRoot) + strlen("/nameToUnicode") + 1;
744 char *dataPathBuffer = new char[bufSize];
745
746 snprintf(dataPathBuffer, bufSize, "%s/nameToUnicode", dataRoot);
747 dir = new GDir(dataPathBuffer, gTrue);
748 while (entry = dir->getNextEntry(), entry != NULL) {
749 if (!entry->isDir()) {
750 parseNameToUnicode(entry->getFullPath());
751 }
752 delete entry;
753 }
754 delete dir;
755
756 snprintf(dataPathBuffer, bufSize, "%s/cidToUnicode", dataRoot);
757 dir = new GDir(dataPathBuffer, gFalse);
758 while (entry = dir->getNextEntry(), entry != NULL) {
759 addCIDToUnicode(entry->getName(), entry->getFullPath());
760 delete entry;
761 }
762 delete dir;
763
764 snprintf(dataPathBuffer, bufSize, "%s/unicodeMap", dataRoot);
765 dir = new GDir(dataPathBuffer, gFalse);
766 while (entry = dir->getNextEntry(), entry != NULL) {
767 addUnicodeMap(entry->getName(), entry->getFullPath());
768 delete entry;
769 }
770 delete dir;
771
772 snprintf(dataPathBuffer, bufSize, "%s/cMap", dataRoot);
773 dir = new GDir(dataPathBuffer, gFalse);
774 while (entry = dir->getNextEntry(), entry != NULL) {
775 addCMapDir(entry->getName(), entry->getFullPath());
776 toUnicodeDirs->append(entry->getFullPath()->copy());
777 delete entry;
778 }
779 delete dir;
780
781 delete[] dataPathBuffer;
782 }
783
parseNameToUnicode(GooString * name)784 void GlobalParams::parseNameToUnicode(GooString *name) {
785 char *tok1, *tok2;
786 FILE *f;
787 char buf[256];
788 int line;
789 Unicode u;
790 char *tokptr;
791
792 if (!(f = fopen(name->getCString(), "r"))) {
793 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
794 name->getCString());
795 return;
796 }
797 line = 1;
798 while (getLine(buf, sizeof(buf), f)) {
799 tok1 = strtok_r(buf, " \t\r\n", &tokptr);
800 tok2 = strtok_r(NULL, " \t\r\n", &tokptr);
801 if (tok1 && tok2) {
802 sscanf(tok1, "%x", &u);
803 nameToUnicode->add(tok2, u);
804 } else {
805 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)",
806 name->getCString(), line);
807 }
808 ++line;
809 }
810 fclose(f);
811 }
812
addCIDToUnicode(GooString * collection,GooString * fileName)813 void GlobalParams::addCIDToUnicode(GooString *collection,
814 GooString *fileName) {
815 GooString *old;
816
817 if ((old = (GooString *)cidToUnicodes->remove(collection))) {
818 delete old;
819 }
820 cidToUnicodes->add(collection->copy(), fileName->copy());
821 }
822
addUnicodeMap(GooString * encodingName,GooString * fileName)823 void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName)
824 {
825 GooString *old;
826
827 if ((old = (GooString *)unicodeMaps->remove(encodingName))) {
828 delete old;
829 }
830 unicodeMaps->add(encodingName->copy(), fileName->copy());
831 }
832
addCMapDir(GooString * collection,GooString * dir)833 void GlobalParams::addCMapDir(GooString *collection, GooString *dir) {
834 GooList *list;
835
836 if (!(list = (GooList *)cMapDirs->lookup(collection))) {
837 list = new GooList();
838 cMapDirs->add(collection->copy(), list);
839 }
840 list->append(dir->copy());
841 }
842
parseYesNo2(char * token,GBool * flag)843 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
844 if (!strcmp(token, "yes")) {
845 *flag = gTrue;
846 } else if (!strcmp(token, "no")) {
847 *flag = gFalse;
848 } else {
849 return gFalse;
850 }
851 return gTrue;
852 }
853
~GlobalParams()854 GlobalParams::~GlobalParams() {
855 freeBuiltinFontTables();
856
857 delete macRomanReverseMap;
858
859 delete baseDir;
860 delete nameToUnicode;
861 deleteGooHash(cidToUnicodes, GooString);
862 deleteGooHash(unicodeToUnicodes, GooString);
863 deleteGooHash(residentUnicodeMaps, UnicodeMap);
864 deleteGooHash(unicodeMaps, GooString);
865 deleteGooList(toUnicodeDirs, GooString);
866 deleteGooHash(displayFonts, DisplayFontParam);
867 #ifdef _WIN32
868 delete winFontList;
869 #endif
870 deleteGooHash(psFonts, PSFontParam);
871 deleteGooList(psNamedFonts16, PSFontParam);
872 deleteGooList(psFonts16, PSFontParam);
873 delete textEncoding;
874 deleteGooList(fontDirs, GooString);
875
876 GooHashIter *iter;
877 GooString *key;
878 cMapDirs->startIter(&iter);
879 void *val;
880 while (cMapDirs->getNext(&iter, &key, &val)) {
881 GooList* list = (GooList*)val;
882 deleteGooList(list, GooString);
883 }
884 delete cMapDirs;
885
886 delete cidToUnicodeCache;
887 delete unicodeToUnicodeCache;
888 delete unicodeMapCache;
889 delete cMapCache;
890
891 #ifdef ENABLE_PLUGINS
892 delete securityHandlers;
893 deleteGooList(plugins, Plugin);
894 #endif
895
896 #if MULTITHREADED
897 gDestroyMutex(&mutex);
898 gDestroyMutex(&unicodeMapCacheMutex);
899 gDestroyMutex(&cMapCacheMutex);
900 #endif
901 }
902
903 //------------------------------------------------------------------------
904
setBaseDir(char * dir)905 void GlobalParams::setBaseDir(char *dir) {
906 delete baseDir;
907 baseDir = new GooString(dir);
908 }
909
910 //------------------------------------------------------------------------
911 // accessors
912 //------------------------------------------------------------------------
913
getMacRomanCharCode(char * charName)914 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
915 // no need to lock - macRomanReverseMap is constant
916 return macRomanReverseMap->lookup(charName);
917 }
918
getBaseDir()919 GooString *GlobalParams::getBaseDir() {
920 GooString *s;
921
922 lockGlobalParams;
923 s = baseDir->copy();
924 unlockGlobalParams;
925 return s;
926 }
927
mapNameToUnicode(char * charName)928 Unicode GlobalParams::mapNameToUnicode(char *charName) {
929 // no need to lock - nameToUnicode is constant
930 return nameToUnicode->lookup(charName);
931 }
932
getResidentUnicodeMap(GooString * encodingName)933 UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) {
934 UnicodeMap *map;
935
936 lockGlobalParams;
937 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
938 unlockGlobalParams;
939 if (map) {
940 map->incRefCnt();
941 }
942 return map;
943 }
944
getUnicodeMapFile(GooString * encodingName)945 FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) {
946 GooString *fileName;
947 FILE *f;
948
949 lockGlobalParams;
950 if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) {
951 f = fopen(fileName->getCString(), "r");
952 } else {
953 f = NULL;
954 }
955 unlockGlobalParams;
956 return f;
957 }
958
findCMapFile(GooString * collection,GooString * cMapName)959 FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) {
960 GooList *list;
961 GooString *dir;
962 GooString *fileName;
963 FILE *f;
964 int i;
965
966 lockGlobalParams;
967 if (!(list = (GooList *)cMapDirs->lookup(collection))) {
968 unlockGlobalParams;
969 return NULL;
970 }
971 for (i = 0; i < list->getLength(); ++i) {
972 dir = (GooString *)list->get(i);
973 fileName = appendToPath(dir->copy(), cMapName->getCString());
974 f = fopen(fileName->getCString(), "r");
975 delete fileName;
976 if (f) {
977 unlockGlobalParams;
978 return f;
979 }
980 }
981 unlockGlobalParams;
982 return NULL;
983 }
984
findToUnicodeFile(GooString * name)985 FILE *GlobalParams::findToUnicodeFile(GooString *name) {
986 GooString *dir, *fileName;
987 FILE *f;
988 int i;
989
990 lockGlobalParams;
991 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
992 dir = (GooString *)toUnicodeDirs->get(i);
993 fileName = appendToPath(dir->copy(), name->getCString());
994 f = fopen(fileName->getCString(), "r");
995 delete fileName;
996 if (f) {
997 unlockGlobalParams;
998 return f;
999 }
1000 }
1001 unlockGlobalParams;
1002 return NULL;
1003 }
1004
1005 #if WITH_FONTCONFIGURATION_FONTCONFIG
findModifier(const char * name,const char * modifier,const char ** start)1006 static GBool findModifier(const char *name, const char *modifier, const char **start)
1007 {
1008 const char *match;
1009
1010 if (name == NULL)
1011 return gFalse;
1012
1013 match = strstr(name, modifier);
1014 if (match) {
1015 if (*start == NULL || match < *start)
1016 *start = match;
1017 return gTrue;
1018 }
1019 else {
1020 return gFalse;
1021 }
1022 }
1023
buildFcPattern(GfxFont * font)1024 static FcPattern *buildFcPattern(GfxFont *font)
1025 {
1026 int weight = -1,
1027 slant = -1,
1028 width = -1,
1029 spacing = -1;
1030 bool deleteFamily = false;
1031 char *family, *name, *lang, *modifiers;
1032 const char *start;
1033 FcPattern *p;
1034
1035 // this is all heuristics will be overwritten if font had proper info
1036 name = font->getName()->getCString();
1037
1038 modifiers = strchr (name, ',');
1039 if (modifiers == NULL)
1040 modifiers = strchr (name, '-');
1041
1042 // remove the - from the names, for some reason, Fontconfig does not
1043 // understand "MS-Mincho" but does with "MS Mincho"
1044 int len = strlen(name);
1045 for (int i = 0; i < len; i++)
1046 name[i] = (name[i] == '-' ? ' ' : name[i]);
1047
1048 start = NULL;
1049 findModifier(modifiers, "Regular", &start);
1050 findModifier(modifiers, "Roman", &start);
1051
1052 if (findModifier(modifiers, "Oblique", &start))
1053 slant = FC_SLANT_OBLIQUE;
1054 if (findModifier(modifiers, "Italic", &start))
1055 slant = FC_SLANT_ITALIC;
1056 if (findModifier(modifiers, "Bold", &start))
1057 weight = FC_WEIGHT_BOLD;
1058 if (findModifier(modifiers, "Light", &start))
1059 weight = FC_WEIGHT_LIGHT;
1060 if (findModifier(modifiers, "Condensed", &start))
1061 width = FC_WIDTH_CONDENSED;
1062
1063 if (start) {
1064 // There have been "modifiers" in the name, crop them to obtain
1065 // the family name
1066 family = new char[len+1];
1067 strcpy(family, name);
1068 int pos = (modifiers - name);
1069 family[pos] = '\0';
1070 deleteFamily = true;
1071 }
1072 else {
1073 family = name;
1074 }
1075
1076 // use font flags
1077 if (font->isFixedWidth())
1078 spacing = FC_MONO;
1079 if (font->isBold())
1080 weight = FC_WEIGHT_BOLD;
1081 if (font->isItalic())
1082 slant = FC_SLANT_ITALIC;
1083
1084 // if the FontDescriptor specified a family name use it
1085 if (font->getFamily()) {
1086 if (deleteFamily) {
1087 delete[] family;
1088 deleteFamily = false;
1089 }
1090 family = font->getFamily()->getCString();
1091 }
1092
1093 // if the FontDescriptor specified a weight use it
1094 switch (font -> getWeight())
1095 {
1096 case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break;
1097 case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break;
1098 case GfxFont::W300: weight = FC_WEIGHT_BOOK; break;
1099 case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break;
1100 case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break;
1101 case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break;
1102 case GfxFont::W700: weight = FC_WEIGHT_BOLD; break;
1103 case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break;
1104 case GfxFont::W900: weight = FC_WEIGHT_BLACK; break;
1105 default: break;
1106 }
1107
1108 // if the FontDescriptor specified a width use it
1109 switch (font -> getStretch())
1110 {
1111 case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break;
1112 case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break;
1113 case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break;
1114 case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break;
1115 case GfxFont::Normal: width = FC_WIDTH_NORMAL; break;
1116 case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break;
1117 case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break;
1118 case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break;
1119 case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break;
1120 default: break;
1121 }
1122
1123 // find the language we want the font to support
1124 if (font->isCIDFont())
1125 {
1126 GooString *collection = ((GfxCIDFont *)font)->getCollection();
1127 if (collection)
1128 {
1129 if (strcmp(collection->getCString(), "Adobe-GB1") == 0)
1130 lang = "zh-cn"; // Simplified Chinese
1131 else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0)
1132 lang = "zh-tw"; // Traditional Chinese
1133 else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0)
1134 lang = "ja"; // Japanese
1135 else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0)
1136 lang = "ja"; // Japanese
1137 else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0)
1138 lang = "ko"; // Korean
1139 else if (strcmp(collection->getCString(), "Adobe-UCS") == 0)
1140 lang = "xx";
1141 else if (strcmp(collection->getCString(), "Adobe-Identity") == 0)
1142 lang = "xx";
1143 else
1144 {
1145 error(-1, "Unknown CID font collection, please report to poppler bugzilla.");
1146 lang = "xx";
1147 }
1148 }
1149 else lang = "xx";
1150 }
1151 else lang = "xx";
1152
1153 p = FcPatternBuild(NULL,
1154 FC_FAMILY, FcTypeString, family,
1155 FC_LANG, FcTypeString, lang,
1156 NULL);
1157 if (slant != -1) FcPatternAddInteger(p, FC_SLANT, slant);
1158 if (weight != -1) FcPatternAddInteger(p, FC_WEIGHT, weight);
1159 if (width != -1) FcPatternAddInteger(p, FC_WIDTH, width);
1160 if (spacing != -1) FcPatternAddInteger(p, FC_SPACING, spacing);
1161
1162 if (deleteFamily)
1163 delete[] family;
1164 return p;
1165 }
1166 #endif
1167
1168 /* if you can't or don't want to use Fontconfig, you need to implement
1169 this function for your platform. For Windows, it's in GlobalParamsWin.cc
1170 */
1171 #if WITH_FONTCONFIGURATION_FONTCONFIG
getDisplayFont(GfxFont * font)1172 DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
1173 DisplayFontParam *dfp;
1174 FcPattern *p=0;
1175
1176 GooString *fontName = font->getName();
1177 if (!fontName) return NULL;
1178
1179 lockGlobalParams;
1180 dfp = font->dfp;
1181 if (!dfp)
1182 {
1183 FcChar8* s;
1184 char * ext;
1185 FcResult res;
1186 FcFontSet *set;
1187 int i;
1188 p = buildFcPattern(font);
1189
1190 if (!p)
1191 goto fin;
1192 FcConfigSubstitute(NULL, p, FcMatchPattern);
1193 FcDefaultSubstitute(p);
1194 set = FcFontSort(NULL, p, FcFalse, NULL, &res);
1195 if (!set)
1196 goto fin;
1197 for (i = 0; i < set->nfont; ++i)
1198 {
1199 res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
1200 if (res != FcResultMatch || !s)
1201 continue;
1202 ext = strrchr((char*)s,'.');
1203 if (!ext)
1204 continue;
1205 if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4))
1206 {
1207 dfp = new DisplayFontParam(fontName->copy(), displayFontTT);
1208 dfp->tt.fileName = new GooString((char*)s);
1209 FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex));
1210 }
1211 else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4))
1212 {
1213 dfp = new DisplayFontParam(fontName->copy(), displayFontT1);
1214 dfp->t1.fileName = new GooString((char*)s);
1215 }
1216 else
1217 continue;
1218 font->dfp = dfp;
1219 break;
1220 }
1221 FcFontSetDestroy(set);
1222 }
1223 fin:
1224 if (p)
1225 FcPatternDestroy(p);
1226
1227 unlockGlobalParams;
1228 return dfp;
1229 }
1230 #endif
1231 #if WITH_FONTCONFIGURATION_WIN32
1232 #include "GlobalParamsWin.cc"
1233 #endif
1234
getPSExpandSmaller()1235 GBool GlobalParams::getPSExpandSmaller() {
1236 GBool f;
1237
1238 lockGlobalParams;
1239 f = psExpandSmaller;
1240 unlockGlobalParams;
1241 return f;
1242 }
1243
getPSShrinkLarger()1244 GBool GlobalParams::getPSShrinkLarger() {
1245 GBool f;
1246
1247 lockGlobalParams;
1248 f = psShrinkLarger;
1249 unlockGlobalParams;
1250 return f;
1251 }
1252
getPSCenter()1253 GBool GlobalParams::getPSCenter() {
1254 GBool f;
1255
1256 lockGlobalParams;
1257 f = psCenter;
1258 unlockGlobalParams;
1259 return f;
1260 }
1261
getPSLevel()1262 PSLevel GlobalParams::getPSLevel() {
1263 PSLevel level;
1264
1265 lockGlobalParams;
1266 level = psLevel;
1267 unlockGlobalParams;
1268 return level;
1269 }
1270
getPSFont(GooString * fontName)1271 PSFontParam *GlobalParams::getPSFont(GooString *fontName) {
1272 PSFontParam *p;
1273
1274 lockGlobalParams;
1275 p = (PSFontParam *)psFonts->lookup(fontName);
1276 unlockGlobalParams;
1277 return p;
1278 }
1279
getPSFont16(GooString * fontName,GooString * collection,int wMode)1280 PSFontParam *GlobalParams::getPSFont16(GooString *fontName,
1281 GooString *collection, int wMode) {
1282 PSFontParam *p;
1283 int i;
1284
1285 lockGlobalParams;
1286 p = NULL;
1287 if (fontName) {
1288 for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1289 p = (PSFontParam *)psNamedFonts16->get(i);
1290 if (!p->pdfFontName->cmp(fontName) &&
1291 p->wMode == wMode) {
1292 break;
1293 }
1294 p = NULL;
1295 }
1296 }
1297 if (!p && collection) {
1298 for (i = 0; i < psFonts16->getLength(); ++i) {
1299 p = (PSFontParam *)psFonts16->get(i);
1300 if (!p->pdfFontName->cmp(collection) &&
1301 p->wMode == wMode) {
1302 break;
1303 }
1304 p = NULL;
1305 }
1306 }
1307 unlockGlobalParams;
1308 return p;
1309 }
1310
getPSEmbedType1()1311 GBool GlobalParams::getPSEmbedType1() {
1312 GBool e;
1313
1314 lockGlobalParams;
1315 e = psEmbedType1;
1316 unlockGlobalParams;
1317 return e;
1318 }
1319
getPSEmbedTrueType()1320 GBool GlobalParams::getPSEmbedTrueType() {
1321 GBool e;
1322
1323 lockGlobalParams;
1324 e = psEmbedTrueType;
1325 unlockGlobalParams;
1326 return e;
1327 }
1328
getPSEmbedCIDPostScript()1329 GBool GlobalParams::getPSEmbedCIDPostScript() {
1330 GBool e;
1331
1332 lockGlobalParams;
1333 e = psEmbedCIDPostScript;
1334 unlockGlobalParams;
1335 return e;
1336 }
1337
getPSEmbedCIDTrueType()1338 GBool GlobalParams::getPSEmbedCIDTrueType() {
1339 GBool e;
1340
1341 lockGlobalParams;
1342 e = psEmbedCIDTrueType;
1343 unlockGlobalParams;
1344 return e;
1345 }
1346
getPSSubstFonts()1347 GBool GlobalParams::getPSSubstFonts() {
1348 GBool e;
1349
1350 lockGlobalParams;
1351 e = psSubstFonts;
1352 unlockGlobalParams;
1353 return e;
1354 }
1355
getPSPreload()1356 GBool GlobalParams::getPSPreload() {
1357 GBool preload;
1358
1359 lockGlobalParams;
1360 preload = psPreload;
1361 unlockGlobalParams;
1362 return preload;
1363 }
1364
getPSOPI()1365 GBool GlobalParams::getPSOPI() {
1366 GBool opi;
1367
1368 lockGlobalParams;
1369 opi = psOPI;
1370 unlockGlobalParams;
1371 return opi;
1372 }
1373
getPSASCIIHex()1374 GBool GlobalParams::getPSASCIIHex() {
1375 GBool ah;
1376
1377 lockGlobalParams;
1378 ah = psASCIIHex;
1379 unlockGlobalParams;
1380 return ah;
1381 }
1382
getTextEncodingName()1383 GooString *GlobalParams::getTextEncodingName() {
1384 GooString *s;
1385
1386 lockGlobalParams;
1387 s = textEncoding->copy();
1388 unlockGlobalParams;
1389 return s;
1390 }
1391
getTextEOL()1392 EndOfLineKind GlobalParams::getTextEOL() {
1393 EndOfLineKind eol;
1394
1395 lockGlobalParams;
1396 eol = textEOL;
1397 unlockGlobalParams;
1398 return eol;
1399 }
1400
getTextPageBreaks()1401 GBool GlobalParams::getTextPageBreaks() {
1402 GBool pageBreaks;
1403
1404 lockGlobalParams;
1405 pageBreaks = textPageBreaks;
1406 unlockGlobalParams;
1407 return pageBreaks;
1408 }
1409
getTextKeepTinyChars()1410 GBool GlobalParams::getTextKeepTinyChars() {
1411 GBool tiny;
1412
1413 lockGlobalParams;
1414 tiny = textKeepTinyChars;
1415 unlockGlobalParams;
1416 return tiny;
1417 }
1418
findFontFile(GooString * fontName,char ** exts)1419 GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) {
1420 GooString *dir, *fileName;
1421 char **ext;
1422 FILE *f;
1423 int i;
1424
1425 lockGlobalParams;
1426 for (i = 0; i < fontDirs->getLength(); ++i) {
1427 dir = (GooString *)fontDirs->get(i);
1428 for (ext = exts; *ext; ++ext) {
1429 fileName = appendToPath(dir->copy(), fontName->getCString());
1430 fileName->append(*ext);
1431 if ((f = fopen(fileName->getCString(), "rb"))) {
1432 fclose(f);
1433 unlockGlobalParams;
1434 return fileName;
1435 }
1436 delete fileName;
1437 }
1438 }
1439 unlockGlobalParams;
1440 return NULL;
1441 }
1442
getEnableFreeType()1443 GBool GlobalParams::getEnableFreeType() {
1444 GBool f;
1445
1446 lockGlobalParams;
1447 f = enableFreeType;
1448 unlockGlobalParams;
1449 return f;
1450 }
1451
1452
getAntialias()1453 GBool GlobalParams::getAntialias() {
1454 GBool f;
1455
1456 lockGlobalParams;
1457 f = antialias;
1458 unlockGlobalParams;
1459 return f;
1460 }
1461
getVectorAntialias()1462 GBool GlobalParams::getVectorAntialias() {
1463 GBool f;
1464
1465 lockGlobalParams;
1466 f = vectorAntialias;
1467 unlockGlobalParams;
1468 return f;
1469 }
1470
getStrokeAdjust()1471 GBool GlobalParams::getStrokeAdjust() {
1472 GBool f;
1473
1474 lockGlobalParams;
1475 f = strokeAdjust;
1476 unlockGlobalParams;
1477 return f;
1478 }
1479
getScreenType()1480 ScreenType GlobalParams::getScreenType() {
1481 ScreenType t;
1482
1483 lockGlobalParams;
1484 t = screenType;
1485 unlockGlobalParams;
1486 return t;
1487 }
1488
getScreenSize()1489 int GlobalParams::getScreenSize() {
1490 int size;
1491
1492 lockGlobalParams;
1493 size = screenSize;
1494 unlockGlobalParams;
1495 return size;
1496 }
1497
getScreenDotRadius()1498 int GlobalParams::getScreenDotRadius() {
1499 int r;
1500
1501 lockGlobalParams;
1502 r = screenDotRadius;
1503 unlockGlobalParams;
1504 return r;
1505 }
1506
getScreenGamma()1507 double GlobalParams::getScreenGamma() {
1508 double gamma;
1509
1510 lockGlobalParams;
1511 gamma = screenGamma;
1512 unlockGlobalParams;
1513 return gamma;
1514 }
1515
getScreenBlackThreshold()1516 double GlobalParams::getScreenBlackThreshold() {
1517 double thresh;
1518
1519 lockGlobalParams;
1520 thresh = screenBlackThreshold;
1521 unlockGlobalParams;
1522 return thresh;
1523 }
1524
getScreenWhiteThreshold()1525 double GlobalParams::getScreenWhiteThreshold() {
1526 double thresh;
1527
1528 lockGlobalParams;
1529 thresh = screenWhiteThreshold;
1530 unlockGlobalParams;
1531 return thresh;
1532 }
1533
getMapNumericCharNames()1534 GBool GlobalParams::getMapNumericCharNames() {
1535 GBool map;
1536
1537 lockGlobalParams;
1538 map = mapNumericCharNames;
1539 unlockGlobalParams;
1540 return map;
1541 }
1542
getMapUnknownCharNames()1543 GBool GlobalParams::getMapUnknownCharNames() {
1544 GBool map;
1545
1546 lockGlobalParams;
1547 map = mapUnknownCharNames;
1548 unlockGlobalParams;
1549 return map;
1550 }
1551
getPrintCommands()1552 GBool GlobalParams::getPrintCommands() {
1553 GBool p;
1554
1555 lockGlobalParams;
1556 p = printCommands;
1557 unlockGlobalParams;
1558 return p;
1559 }
1560
getProfileCommands()1561 GBool GlobalParams::getProfileCommands() {
1562 GBool p;
1563
1564 lockGlobalParams;
1565 p = profileCommands;
1566 unlockGlobalParams;
1567 return p;
1568 }
1569
getErrQuiet()1570 GBool GlobalParams::getErrQuiet() {
1571 // no locking -- this function may get called from inside a locked
1572 // section
1573 return errQuiet;
1574 }
1575
getCIDToUnicode(GooString * collection)1576 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
1577 GooString *fileName;
1578 CharCodeToUnicode *ctu;
1579
1580 lockGlobalParams;
1581 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1582 if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) &&
1583 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1584 cidToUnicodeCache->add(ctu);
1585 }
1586 }
1587 unlockGlobalParams;
1588 return ctu;
1589 }
1590
getUnicodeToUnicode(GooString * fontName)1591 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) {
1592 lockGlobalParams;
1593 GooHashIter *iter;
1594 unicodeToUnicodes->startIter(&iter);
1595 GooString *fileName = NULL;
1596 GooString *fontPattern;
1597 void *val;
1598 while (!fileName && unicodeToUnicodes->getNext(&iter, &fontPattern, &val)) {
1599 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1600 unicodeToUnicodes->killIter(&iter);
1601 fileName = (GooString*)val;
1602 }
1603 }
1604 CharCodeToUnicode *ctu = NULL;
1605 if (fileName) {
1606 ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName);
1607 if (!ctu) {
1608 ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName);
1609 if (ctu)
1610 unicodeToUnicodeCache->add(ctu);
1611 }
1612 }
1613 unlockGlobalParams;
1614 return ctu;
1615 }
1616
getUnicodeMap(GooString * encodingName)1617 UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
1618 return getUnicodeMap2(encodingName);
1619 }
1620
getUnicodeMap2(GooString * encodingName)1621 UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
1622 UnicodeMap *map;
1623
1624 if (!(map = getResidentUnicodeMap(encodingName))) {
1625 lockUnicodeMapCache;
1626 map = unicodeMapCache->getUnicodeMap(encodingName);
1627 unlockUnicodeMapCache;
1628 }
1629 return map;
1630 }
1631
getCMap(GooString * collection,GooString * cMapName,Stream * stream)1632 CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName, Stream *stream) {
1633 CMap *cMap;
1634
1635 lockCMapCache;
1636 cMap = cMapCache->getCMap(collection, cMapName, stream);
1637 unlockCMapCache;
1638 return cMap;
1639 }
1640
getTextEncoding()1641 UnicodeMap *GlobalParams::getTextEncoding() {
1642 return getUnicodeMap2(textEncoding);
1643 }
1644
getEncodingNames()1645 GooList *GlobalParams::getEncodingNames()
1646 {
1647 GooList *result = new GooList;
1648 GooHashIter *iter;
1649 GooString *key;
1650 void *val;
1651 residentUnicodeMaps->startIter(&iter);
1652 while (residentUnicodeMaps->getNext(&iter, &key, &val)) {
1653 result->append(key);
1654 }
1655 residentUnicodeMaps->killIter(&iter);
1656 unicodeMaps->startIter(&iter);
1657 while (unicodeMaps->getNext(&iter, &key, &val)) {
1658 result->append(key);
1659 }
1660 unicodeMaps->killIter(&iter);
1661 return result;
1662 }
1663
1664 //------------------------------------------------------------------------
1665 // functions to set parameters
1666 //------------------------------------------------------------------------
1667
setPSExpandSmaller(GBool expand)1668 void GlobalParams::setPSExpandSmaller(GBool expand) {
1669 lockGlobalParams;
1670 psExpandSmaller = expand;
1671 unlockGlobalParams;
1672 }
1673
setPSShrinkLarger(GBool shrink)1674 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1675 lockGlobalParams;
1676 psShrinkLarger = shrink;
1677 unlockGlobalParams;
1678 }
1679
setPSCenter(GBool center)1680 void GlobalParams::setPSCenter(GBool center) {
1681 lockGlobalParams;
1682 psCenter = center;
1683 unlockGlobalParams;
1684 }
1685
setPSLevel(PSLevel level)1686 void GlobalParams::setPSLevel(PSLevel level) {
1687 lockGlobalParams;
1688 psLevel = level;
1689 unlockGlobalParams;
1690 }
1691
setPSEmbedType1(GBool embed)1692 void GlobalParams::setPSEmbedType1(GBool embed) {
1693 lockGlobalParams;
1694 psEmbedType1 = embed;
1695 unlockGlobalParams;
1696 }
1697
setPSEmbedTrueType(GBool embed)1698 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1699 lockGlobalParams;
1700 psEmbedTrueType = embed;
1701 unlockGlobalParams;
1702 }
1703
setPSEmbedCIDPostScript(GBool embed)1704 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1705 lockGlobalParams;
1706 psEmbedCIDPostScript = embed;
1707 unlockGlobalParams;
1708 }
1709
setPSEmbedCIDTrueType(GBool embed)1710 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1711 lockGlobalParams;
1712 psEmbedCIDTrueType = embed;
1713 unlockGlobalParams;
1714 }
1715
setPSSubstFonts(GBool substFonts)1716 void GlobalParams::setPSSubstFonts(GBool substFonts) {
1717 lockGlobalParams;
1718 psSubstFonts = substFonts;
1719 unlockGlobalParams;
1720 }
1721
setPSPreload(GBool preload)1722 void GlobalParams::setPSPreload(GBool preload) {
1723 lockGlobalParams;
1724 psPreload = preload;
1725 unlockGlobalParams;
1726 }
1727
setPSOPI(GBool opi)1728 void GlobalParams::setPSOPI(GBool opi) {
1729 lockGlobalParams;
1730 psOPI = opi;
1731 unlockGlobalParams;
1732 }
1733
setPSASCIIHex(GBool hex)1734 void GlobalParams::setPSASCIIHex(GBool hex) {
1735 lockGlobalParams;
1736 psASCIIHex = hex;
1737 unlockGlobalParams;
1738 }
1739
setTextEncoding(char * encodingName)1740 void GlobalParams::setTextEncoding(char *encodingName) {
1741 lockGlobalParams;
1742 delete textEncoding;
1743 textEncoding = new GooString(encodingName);
1744 unlockGlobalParams;
1745 }
1746
setTextEOL(char * s)1747 GBool GlobalParams::setTextEOL(char *s) {
1748 lockGlobalParams;
1749 if (!strcmp(s, "unix")) {
1750 textEOL = eolUnix;
1751 } else if (!strcmp(s, "dos")) {
1752 textEOL = eolDOS;
1753 } else if (!strcmp(s, "mac")) {
1754 textEOL = eolMac;
1755 } else {
1756 unlockGlobalParams;
1757 return gFalse;
1758 }
1759 unlockGlobalParams;
1760 return gTrue;
1761 }
1762
setTextPageBreaks(GBool pageBreaks)1763 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1764 lockGlobalParams;
1765 textPageBreaks = pageBreaks;
1766 unlockGlobalParams;
1767 }
1768
setTextKeepTinyChars(GBool keep)1769 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1770 lockGlobalParams;
1771 textKeepTinyChars = keep;
1772 unlockGlobalParams;
1773 }
1774
setEnableFreeType(char * s)1775 GBool GlobalParams::setEnableFreeType(char *s) {
1776 GBool ok;
1777
1778 lockGlobalParams;
1779 ok = parseYesNo2(s, &enableFreeType);
1780 unlockGlobalParams;
1781 return ok;
1782 }
1783
1784
setAntialias(char * s)1785 GBool GlobalParams::setAntialias(char *s) {
1786 GBool ok;
1787
1788 lockGlobalParams;
1789 ok = parseYesNo2(s, &antialias);
1790 unlockGlobalParams;
1791 return ok;
1792 }
1793
setVectorAntialias(char * s)1794 GBool GlobalParams::setVectorAntialias(char *s) {
1795 GBool ok;
1796
1797 lockGlobalParams;
1798 ok = parseYesNo2(s, &vectorAntialias);
1799 unlockGlobalParams;
1800 return ok;
1801 }
1802
setStrokeAdjust(GBool adjust)1803 void GlobalParams::setStrokeAdjust(GBool adjust)
1804 {
1805 lockGlobalParams;
1806 strokeAdjust = adjust;
1807 unlockGlobalParams;
1808 }
1809
setScreenType(ScreenType st)1810 void GlobalParams::setScreenType(ScreenType st)
1811 {
1812 lockGlobalParams;
1813 screenType = st;
1814 unlockGlobalParams;
1815 }
1816
setScreenSize(int size)1817 void GlobalParams::setScreenSize(int size)
1818 {
1819 lockGlobalParams;
1820 screenSize = size;
1821 unlockGlobalParams;
1822 }
1823
setScreenDotRadius(int radius)1824 void GlobalParams::setScreenDotRadius(int radius)
1825 {
1826 lockGlobalParams;
1827 screenDotRadius = radius;
1828 unlockGlobalParams;
1829 }
1830
setScreenGamma(double gamma)1831 void GlobalParams::setScreenGamma(double gamma)
1832 {
1833 lockGlobalParams;
1834 screenGamma = gamma;
1835 unlockGlobalParams;
1836 }
1837
setScreenBlackThreshold(double blackThreshold)1838 void GlobalParams::setScreenBlackThreshold(double blackThreshold)
1839 {
1840 lockGlobalParams;
1841 screenBlackThreshold = blackThreshold;
1842 unlockGlobalParams;
1843 }
1844
setScreenWhiteThreshold(double whiteThreshold)1845 void GlobalParams::setScreenWhiteThreshold(double whiteThreshold)
1846 {
1847 lockGlobalParams;
1848 screenWhiteThreshold = whiteThreshold;
1849 unlockGlobalParams;
1850 }
1851
setMapNumericCharNames(GBool map)1852 void GlobalParams::setMapNumericCharNames(GBool map) {
1853 lockGlobalParams;
1854 mapNumericCharNames = map;
1855 unlockGlobalParams;
1856 }
1857
setMapUnknownCharNames(GBool map)1858 void GlobalParams::setMapUnknownCharNames(GBool map) {
1859 lockGlobalParams;
1860 mapUnknownCharNames = map;
1861 unlockGlobalParams;
1862 }
1863
setPrintCommands(GBool printCommandsA)1864 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1865 lockGlobalParams;
1866 printCommands = printCommandsA;
1867 unlockGlobalParams;
1868 }
1869
setProfileCommands(GBool profileCommandsA)1870 void GlobalParams::setProfileCommands(GBool profileCommandsA) {
1871 lockGlobalParams;
1872 profileCommands = profileCommandsA;
1873 unlockGlobalParams;
1874 }
1875
setErrQuiet(GBool errQuietA)1876 void GlobalParams::setErrQuiet(GBool errQuietA) {
1877 lockGlobalParams;
1878 errQuiet = errQuietA;
1879 unlockGlobalParams;
1880 }
1881
addSecurityHandler(XpdfSecurityHandler * handler)1882 void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1883 #ifdef ENABLE_PLUGINS
1884 lockGlobalParams;
1885 securityHandlers->append(handler);
1886 unlockGlobalParams;
1887 #endif
1888 }
1889
getSecurityHandler(char * name)1890 XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1891 #ifdef ENABLE_PLUGINS
1892 XpdfSecurityHandler *hdlr;
1893 int i;
1894
1895 lockGlobalParams;
1896 for (i = 0; i < securityHandlers->getLength(); ++i) {
1897 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1898 if (!strcasecmp(hdlr->name, name)) {
1899 unlockGlobalParams;
1900 return hdlr;
1901 }
1902 }
1903 unlockGlobalParams;
1904
1905 if (!loadPlugin("security", name)) {
1906 return NULL;
1907 }
1908 deleteGooList(keyBindings, KeyBinding);
1909
1910 lockGlobalParams;
1911 for (i = 0; i < securityHandlers->getLength(); ++i) {
1912 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1913 if (!strcmp(hdlr->name, name)) {
1914 unlockGlobalParams;
1915 return hdlr;
1916 }
1917 }
1918 unlockGlobalParams;
1919 #else
1920 (void)name;
1921 #endif
1922
1923 return NULL;
1924 }
1925
1926 #ifdef ENABLE_PLUGINS
1927 //------------------------------------------------------------------------
1928 // plugins
1929 //------------------------------------------------------------------------
1930
loadPlugin(char * type,char * name)1931 GBool GlobalParams::loadPlugin(char *type, char *name) {
1932 Plugin *plugin;
1933
1934 if (!(plugin = Plugin::load(type, name))) {
1935 return gFalse;
1936 }
1937 lockGlobalParams;
1938 plugins->append(plugin);
1939 unlockGlobalParams;
1940 return gTrue;
1941 }
1942
1943 #endif // ENABLE_PLUGINS
1944