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 		   &regKey) == 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