beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / poppler / GlobalParams.cc
blobe5434084c311bde60cca86ff057e2b0f42aa2e87
1 //========================================================================
2 //
3 // GlobalParams.cc
4 //
5 // Copyright 2001-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
16 // Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org>
17 // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com>
18 // Copyright (C) 2005, 2007-2010, 2012, 2015 Albert Astals Cid <aacid@kde.org>
19 // Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
20 // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
21 // Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
22 // Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk>
23 // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
24 // Copyright (C) 2007, 2009 Jonathan Kew <jonathan_kew@sil.org>
25 // Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
26 // Copyright (C) 2009, 2011, 2012, 2015 William Bader <williambader@hotmail.com>
27 // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
28 // Copyright (C) 2010, 2012 Hib Eris <hib@hiberis.nl>
29 // Copyright (C) 2010 Patrick Spendrin <ps_ml@gmx.de>
30 // Copyright (C) 2010 Jakub Wilk <jwilk@jwilk.net>
31 // Copyright (C) 2011 Pino Toscano <pino@kde.org>
32 // Copyright (C) 2011 Koji Otani <sho@bbr.jp>
33 // Copyright (C) 2012 Yi Yang <ahyangyi@gmail.com>
34 // Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com>
35 // Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
36 // Copyright (C) 2012 Peter Breitenlohner <peb@mppmu.mpg.de>
37 // Copyright (C) 2013, 2014 Jason Crain <jason@aquaticape.us>
39 // To see a description of the changes please see the Changelog file that
40 // came with your tarball or type make ChangeLog if you are building from git
42 //========================================================================
44 #include <config.h>
46 #ifdef USE_GCC_PRAGMAS
47 #pragma implementation
48 #endif
50 #include <string.h>
51 #include <stdio.h>
52 #include <ctype.h>
53 #ifdef ENABLE_PLUGINS
54 # ifndef _WIN32
55 # include <dlfcn.h>
56 # endif
57 #endif
58 #ifdef _WIN32
59 # include <shlobj.h>
60 # include <mbstring.h>
61 #endif
62 #include "goo/gmem.h"
63 #include "goo/GooString.h"
64 #include "goo/GooList.h"
65 #include "goo/GooHash.h"
66 #include "goo/gfile.h"
67 #include "Error.h"
68 #include "NameToCharCode.h"
69 #include "CharCodeToUnicode.h"
70 #include "UnicodeMap.h"
71 #include "CMap.h"
72 #include "BuiltinFontTables.h"
73 #include "FontEncodingTables.h"
74 #ifdef ENABLE_PLUGINS
75 # include "XpdfPluginAPI.h"
76 #endif
77 #include "GlobalParams.h"
78 #include "GfxFont.h"
80 #if WITH_FONTCONFIGURATION_FONTCONFIG
81 #include <fontconfig/fontconfig.h>
82 #endif
84 #ifdef _WIN32
85 # define strcasecmp stricmp
86 #else
87 # include <strings.h>
88 #endif
90 #if MULTITHREADED
91 # define lockGlobalParams gLockMutex(&mutex)
92 # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
93 # define lockCMapCache gLockMutex(&cMapCacheMutex)
94 # define unlockGlobalParams gUnlockMutex(&mutex)
95 # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
96 # define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
97 #else
98 # define lockGlobalParams
99 # define lockUnicodeMapCache
100 # define lockCMapCache
101 # define unlockGlobalParams
102 # define unlockUnicodeMapCache
103 # define unlockCMapCache
104 #endif
106 #ifndef FC_WEIGHT_BOOK
107 #define FC_WEIGHT_BOOK 75
108 #endif
110 #include "NameToUnicodeTable.h"
111 #include "UnicodeMapTables.h"
112 #include "UTF8.h"
114 #ifdef ENABLE_PLUGINS
115 # ifdef _WIN32
116 extern XpdfPluginVecTable xpdfPluginVecTable;
117 # endif
118 #endif
120 //------------------------------------------------------------------------
122 #define cidToUnicodeCacheSize 4
123 #define unicodeToUnicodeCacheSize 4
125 //------------------------------------------------------------------------
127 GlobalParams *globalParams = NULL;
129 //------------------------------------------------------------------------
130 // PSFontParam16
131 //------------------------------------------------------------------------
133 PSFontParam16::PSFontParam16(GooString *nameA, int wModeA,
134 GooString *psFontNameA, GooString *encodingA) {
135 name = nameA;
136 wMode = wModeA;
137 psFontName = psFontNameA;
138 encoding = encodingA;
141 PSFontParam16::~PSFontParam16() {
142 delete name;
143 delete psFontName;
144 delete encoding;
147 #if ENABLE_RELOCATABLE && defined(_WIN32)
149 /* search for data relative to where we are installed */
151 static HMODULE hmodule;
153 extern "C" {
154 BOOL WINAPI
155 DllMain (HINSTANCE hinstDLL,
156 DWORD fdwReason,
157 LPVOID lpvReserved)
159 switch (fdwReason)
161 case DLL_PROCESS_ATTACH:
162 hmodule = hinstDLL;
163 break;
166 return TRUE;
170 static const char *
171 get_poppler_datadir (void)
173 static char retval[MAX_PATH];
174 static int beenhere = 0;
176 unsigned char *p;
178 if (beenhere)
179 return retval;
181 if (!GetModuleFileName (hmodule, (CHAR *) retval, sizeof(retval) - 20))
182 return POPPLER_DATADIR;
184 p = _mbsrchr ((unsigned char *) retval, '\\');
185 *p = '\0';
186 p = _mbsrchr ((unsigned char *) retval, '\\');
187 if (p) {
188 if (stricmp ((const char *) (p+1), "bin") == 0)
189 *p = '\0';
191 strcat (retval, "\\share\\poppler");
193 beenhere = 1;
195 return retval;
198 #undef POPPLER_DATADIR
199 #define POPPLER_DATADIR get_poppler_datadir ()
201 #endif
203 //------------------------------------------------------------------------
204 // SysFontInfo
205 //------------------------------------------------------------------------
207 class SysFontInfo {
208 public:
210 GooString *name;
211 GBool bold;
212 GBool italic;
213 GBool oblique;
214 GBool fixedWidth;
215 GooString *path;
216 SysFontType type;
217 int fontNum; // for TrueType collections
218 GooString *substituteName;
220 SysFontInfo(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA,
221 GooString *pathA, SysFontType typeA, int fontNumA, GooString *substituteNameA);
222 ~SysFontInfo();
223 GBool match(SysFontInfo *fi);
224 GBool match(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA);
225 GBool match(GooString *nameA, GBool boldA, GBool italicA);
228 SysFontInfo::SysFontInfo(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA,
229 GooString *pathA, SysFontType typeA, int fontNumA, GooString *substituteNameA) {
230 name = nameA;
231 bold = boldA;
232 italic = italicA;
233 oblique = obliqueA;
234 fixedWidth = fixedWidthA;
235 path = pathA;
236 type = typeA;
237 fontNum = fontNumA;
238 substituteName = substituteNameA;
241 SysFontInfo::~SysFontInfo() {
242 delete name;
243 delete path;
244 delete substituteName;
247 GBool SysFontInfo::match(SysFontInfo *fi) {
248 return !strcasecmp(name->getCString(), fi->name->getCString()) &&
249 bold == fi->bold && italic == fi->italic && oblique == fi->oblique && fixedWidth == fi->fixedWidth;
252 GBool SysFontInfo::match(GooString *nameA, GBool boldA, GBool italicA, GBool obliqueA, GBool fixedWidthA) {
253 return !strcasecmp(name->getCString(), nameA->getCString()) &&
254 bold == boldA && italic == italicA && oblique == obliqueA && fixedWidth == fixedWidthA;
257 GBool SysFontInfo::match(GooString *nameA, GBool boldA, GBool italicA) {
258 return !strcasecmp(name->getCString(), nameA->getCString()) &&
259 bold == boldA && italic == italicA;
262 //------------------------------------------------------------------------
263 // SysFontList
264 //------------------------------------------------------------------------
266 class SysFontList {
267 public:
269 SysFontList();
270 ~SysFontList();
271 SysFontInfo *find(GooString *name, GBool isFixedWidth, GBool exact);
273 #ifdef WIN32
274 void scanWindowsFonts(GooString *winFontDir);
275 #endif
276 #ifdef WITH_FONTCONFIGURATION_FONTCONFIG
277 void addFcFont(SysFontInfo *si) {fonts->append(si);}
278 #endif
279 private:
281 #ifdef WIN32
282 SysFontInfo *makeWindowsFont(char *name, int fontNum,
283 char *path);
284 #endif
286 GooList *fonts; // [SysFontInfo]
289 SysFontList::SysFontList() {
290 fonts = new GooList();
293 SysFontList::~SysFontList() {
294 deleteGooList(fonts, SysFontInfo);
297 SysFontInfo *SysFontList::find(GooString *name, GBool fixedWidth, GBool exact) {
298 GooString *name2;
299 GBool bold, italic, oblique;
300 SysFontInfo *fi;
301 char c;
302 int n, i;
304 name2 = name->copy();
306 // remove space, comma, dash chars
307 i = 0;
308 while (i < name2->getLength()) {
309 c = name2->getChar(i);
310 if (c == ' ' || c == ',' || c == '-') {
311 name2->del(i);
312 } else {
313 ++i;
316 n = name2->getLength();
318 // remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
319 if (n > 2 && !strcmp(name2->getCString() + n - 2, "MT")) {
320 name2->del(n - 2, 2);
321 n -= 2;
324 // look for "Regular"
325 if (n > 7 && !strcmp(name2->getCString() + n - 7, "Regular")) {
326 name2->del(n - 7, 7);
327 n -= 7;
330 // look for "Italic"
331 if (n > 6 && !strcmp(name2->getCString() + n - 6, "Italic")) {
332 name2->del(n - 6, 6);
333 italic = gTrue;
334 n -= 6;
335 } else {
336 italic = gFalse;
339 // look for "Oblique"
340 if (n > 6 && !strcmp(name2->getCString() + n - 7, "Oblique")) {
341 name2->del(n - 7, 7);
342 oblique = gTrue;
343 n -= 6;
344 } else {
345 oblique = gFalse;
348 // look for "Bold"
349 if (n > 4 && !strcmp(name2->getCString() + n - 4, "Bold")) {
350 name2->del(n - 4, 4);
351 bold = gTrue;
352 n -= 4;
353 } else {
354 bold = gFalse;
357 // remove trailing "MT" (FooMT-Bold, etc.)
358 if (n > 2 && !strcmp(name2->getCString() + n - 2, "MT")) {
359 name2->del(n - 2, 2);
360 n -= 2;
363 // remove trailing "PS"
364 if (n > 2 && !strcmp(name2->getCString() + n - 2, "PS")) {
365 name2->del(n - 2, 2);
366 n -= 2;
369 // remove trailing "IdentityH"
370 if (n > 9 && !strcmp(name2->getCString() + n - 9, "IdentityH")) {
371 name2->del(n - 9, 9);
372 n -= 9;
375 // search for the font
376 fi = NULL;
377 for (i = 0; i < fonts->getLength(); ++i) {
378 fi = (SysFontInfo *)fonts->get(i);
379 if (fi->match(name2, bold, italic, oblique, fixedWidth)) {
380 break;
382 fi = NULL;
384 if (!fi && !exact && bold) {
385 // try ignoring the bold flag
386 for (i = 0; i < fonts->getLength(); ++i) {
387 fi = (SysFontInfo *)fonts->get(i);
388 if (fi->match(name2, gFalse, italic)) {
389 break;
391 fi = NULL;
394 if (!fi && !exact && (bold || italic)) {
395 // try ignoring the bold and italic flags
396 for (i = 0; i < fonts->getLength(); ++i) {
397 fi = (SysFontInfo *)fonts->get(i);
398 if (fi->match(name2, gFalse, gFalse)) {
399 break;
401 fi = NULL;
405 delete name2;
406 return fi;
410 #ifdef ENABLE_PLUGINS
411 //------------------------------------------------------------------------
412 // Plugin
413 //------------------------------------------------------------------------
415 class Plugin {
416 public:
418 static Plugin *load(char *type, char *name);
419 ~Plugin();
421 private:
423 #ifdef _WIN32
424 Plugin(HMODULE libA);
425 HMODULE lib;
426 #else
427 Plugin(void *dlA);
428 void *dl;
429 #endif
432 Plugin *Plugin::load(char *type, char *name) {
433 GooString *path;
434 Plugin *plugin;
435 XpdfPluginVecTable *vt;
436 XpdfBool (*xpdfInitPlugin)(void);
437 #ifdef _WIN32
438 HMODULE libA;
439 #else
440 void *dlA;
441 #endif
443 path = new GooString(POPPLER_DATADIR);
444 appendToPath(path, "plugins");
445 appendToPath(path, type);
446 appendToPath(path, name);
448 #ifdef _WIN32
449 path->append(".dll");
450 if (!(libA = LoadLibrary(path->getCString()))) {
451 error(errIO, -1, "Failed to load plugin '{0:t}'", path);
452 goto err1;
454 if (!(vt = (XpdfPluginVecTable *)
455 GetProcAddress(libA, "xpdfPluginVecTable"))) {
456 error(errIO, -1, "Failed to find xpdfPluginVecTable in plugin '{0:t}'",
457 path);
458 goto err2;
460 #else
461 //~ need to deal with other extensions here
462 path->append(".so");
463 if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
464 error(errIO, -1, "Failed to load plugin '{0:t}': {1:s}",
465 path, dlerror());
466 goto err1;
468 if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
469 error(errIO, -1, "Failed to find xpdfPluginVecTable in plugin '{0:t}'",
470 path);
471 goto err2;
473 #endif
475 if (vt->version != xpdfPluginVecTable.version) {
476 error(errIO, -1, "Plugin '{0:t}' is wrong version", path);
477 goto err2;
479 memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
481 #ifdef _WIN32
482 if (!(xpdfInitPlugin = (XpdfBool (*)(void))
483 GetProcAddress(libA, "xpdfInitPlugin"))) {
484 error(errIO, -1, "Failed to find xpdfInitPlugin in plugin '{0:t}'",
485 path);
486 goto err2;
488 #else
489 if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
490 error(errIO, -1, "Failed to find xpdfInitPlugin in plugin '{0:t}'",
491 path);
492 goto err2;
494 #endif
496 if (!(*xpdfInitPlugin)()) {
497 error(errIO, -1, "Initialization of plugin '{0:t}' failed", path);
498 goto err2;
501 #ifdef _WIN32
502 plugin = new Plugin(libA);
503 #else
504 plugin = new Plugin(dlA);
505 #endif
507 delete path;
508 return plugin;
510 err2:
511 #ifdef _WIN32
512 FreeLibrary(libA);
513 #else
514 dlclose(dlA);
515 #endif
516 err1:
517 delete path;
518 return NULL;
521 #ifdef _WIN32
522 Plugin::Plugin(HMODULE libA) {
523 lib = libA;
525 #else
526 Plugin::Plugin(void *dlA) {
527 dl = dlA;
529 #endif
531 Plugin::~Plugin() {
532 void (*xpdfFreePlugin)(void);
534 #ifdef _WIN32
535 if ((xpdfFreePlugin = (void (*)(void))
536 GetProcAddress(lib, "xpdfFreePlugin"))) {
537 (*xpdfFreePlugin)();
539 FreeLibrary(lib);
540 #else
541 if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
542 (*xpdfFreePlugin)();
544 dlclose(dl);
545 #endif
548 #endif // ENABLE_PLUGINS
550 //------------------------------------------------------------------------
551 // parsing
552 //------------------------------------------------------------------------
554 GlobalParams::GlobalParams(const char *customPopplerDataDir)
555 : popplerDataDir(customPopplerDataDir)
557 UnicodeMap *map;
558 int i;
560 #if MULTITHREADED
561 gInitMutex(&mutex);
562 gInitMutex(&unicodeMapCacheMutex);
563 gInitMutex(&cMapCacheMutex);
564 #endif
566 initBuiltinFontTables();
568 // scan the encoding in reverse because we want the lowest-numbered
569 // index for each char name ('space' is encoded twice)
570 macRomanReverseMap = new NameToCharCode();
571 for (i = 255; i >= 0; --i) {
572 if (macRomanEncoding[i]) {
573 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
577 #ifdef _WIN32
578 substFiles = new GooHash(gTrue);
579 #endif
580 nameToUnicodeZapfDingbats = new NameToCharCode();
581 nameToUnicodeText = new NameToCharCode();
582 cidToUnicodes = new GooHash(gTrue);
583 unicodeToUnicodes = new GooHash(gTrue);
584 residentUnicodeMaps = new GooHash();
585 unicodeMaps = new GooHash(gTrue);
586 cMapDirs = new GooHash(gTrue);
587 toUnicodeDirs = new GooList();
588 fontFiles = new GooHash(gTrue);
589 fontDirs = new GooList();
590 ccFontFiles = new GooHash(gTrue);
591 sysFonts = new SysFontList();
592 psExpandSmaller = gFalse;
593 psShrinkLarger = gTrue;
594 psCenter = gTrue;
595 psLevel = psLevel2;
596 psFile = NULL;
597 psResidentFonts = new GooHash(gTrue);
598 psResidentFonts16 = new GooList();
599 psResidentFontsCC = new GooList();
600 textEncoding = new GooString("UTF-8");
601 #if defined(_WIN32)
602 textEOL = eolDOS;
603 #elif defined(MACOS)
604 textEOL = eolMac;
605 #else
606 textEOL = eolUnix;
607 #endif
608 textPageBreaks = gTrue;
609 textKeepTinyChars = gFalse;
610 enableFreeType = gTrue;
611 strokeAdjust = gTrue;
612 screenType = screenUnset;
613 screenSize = -1;
614 screenDotRadius = -1;
615 screenGamma = 1.0;
616 screenBlackThreshold = 0.0;
617 screenWhiteThreshold = 1.0;
618 minLineWidth = 0.0;
619 overprintPreview = gFalse;
620 mapNumericCharNames = gTrue;
621 mapUnknownCharNames = gTrue;
622 printCommands = gFalse;
623 profileCommands = gFalse;
624 errQuiet = gFalse;
626 cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
627 unicodeToUnicodeCache =
628 new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
629 unicodeMapCache = new UnicodeMapCache();
630 cMapCache = new CMapCache();
632 baseFontsInitialized = gFalse;
633 #ifdef ENABLE_PLUGINS
634 plugins = new GooList();
635 securityHandlers = new GooList();
636 #endif
638 // set up the initial nameToUnicode tables
639 for (i = 0; nameToUnicodeZapfDingbatsTab[i].name; ++i) {
640 nameToUnicodeZapfDingbats->add(nameToUnicodeZapfDingbatsTab[i].name, nameToUnicodeZapfDingbatsTab[i].u);
643 for (i = 0; nameToUnicodeTextTab[i].name; ++i) {
644 nameToUnicodeText->add(nameToUnicodeTextTab[i].name, nameToUnicodeTextTab[i].u);
647 // set up the residentUnicodeMaps table
648 map = new UnicodeMap("Latin1", gFalse,
649 latin1UnicodeMapRanges, latin1UnicodeMapLen);
650 residentUnicodeMaps->add(map->getEncodingName(), map);
651 map = new UnicodeMap("ASCII7", gFalse,
652 ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
653 residentUnicodeMaps->add(map->getEncodingName(), map);
654 map = new UnicodeMap("Symbol", gFalse,
655 symbolUnicodeMapRanges, symbolUnicodeMapLen);
656 residentUnicodeMaps->add(map->getEncodingName(), map);
657 map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
658 zapfDingbatsUnicodeMapLen);
659 residentUnicodeMaps->add(map->getEncodingName(), map);
660 map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
661 residentUnicodeMaps->add(map->getEncodingName(), map);
662 map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
663 residentUnicodeMaps->add(map->getEncodingName(), map);
665 scanEncodingDirs();
668 void GlobalParams::scanEncodingDirs() {
669 GDir *dir;
670 GDirEntry *entry;
671 const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
673 // allocate buffer large enough to append "/nameToUnicode"
674 size_t bufSize = strlen(dataRoot) + strlen("/nameToUnicode") + 1;
675 char *dataPathBuffer = new char[bufSize];
677 snprintf(dataPathBuffer, bufSize, "%s/nameToUnicode", dataRoot);
678 dir = new GDir(dataPathBuffer, gTrue);
679 while (entry = dir->getNextEntry(), entry != NULL) {
680 if (!entry->isDir()) {
681 parseNameToUnicode(entry->getFullPath());
683 delete entry;
685 delete dir;
687 snprintf(dataPathBuffer, bufSize, "%s/cidToUnicode", dataRoot);
688 dir = new GDir(dataPathBuffer, gFalse);
689 while (entry = dir->getNextEntry(), entry != NULL) {
690 addCIDToUnicode(entry->getName(), entry->getFullPath());
691 delete entry;
693 delete dir;
695 snprintf(dataPathBuffer, bufSize, "%s/unicodeMap", dataRoot);
696 dir = new GDir(dataPathBuffer, gFalse);
697 while (entry = dir->getNextEntry(), entry != NULL) {
698 addUnicodeMap(entry->getName(), entry->getFullPath());
699 delete entry;
701 delete dir;
703 snprintf(dataPathBuffer, bufSize, "%s/cMap", dataRoot);
704 dir = new GDir(dataPathBuffer, gFalse);
705 while (entry = dir->getNextEntry(), entry != NULL) {
706 addCMapDir(entry->getName(), entry->getFullPath());
707 toUnicodeDirs->append(entry->getFullPath()->copy());
708 delete entry;
710 delete dir;
712 delete[] dataPathBuffer;
715 void GlobalParams::parseNameToUnicode(GooString *name) {
716 char *tok1, *tok2;
717 FILE *f;
718 char buf[256];
719 int line;
720 Unicode u;
721 char *tokptr;
723 if (!(f = openFile(name->getCString(), "r"))) {
724 error(errIO, -1, "Couldn't open 'nameToUnicode' file '{0:t}'",
725 name);
726 return;
728 line = 1;
729 while (getLine(buf, sizeof(buf), f)) {
730 tok1 = strtok_r(buf, " \t\r\n", &tokptr);
731 tok2 = strtok_r(NULL, " \t\r\n", &tokptr);
732 if (tok1 && tok2) {
733 sscanf(tok1, "%x", &u);
734 nameToUnicodeText->add(tok2, u);
735 } else {
736 error(errConfig, -1, "Bad line in 'nameToUnicode' file ({0:t}:{1:d})",
737 name, line);
739 ++line;
741 fclose(f);
744 void GlobalParams::addCIDToUnicode(GooString *collection,
745 GooString *fileName) {
746 GooString *old;
748 if ((old = (GooString *)cidToUnicodes->remove(collection))) {
749 delete old;
751 cidToUnicodes->add(collection->copy(), fileName->copy());
754 void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName)
756 GooString *old;
758 if ((old = (GooString *)unicodeMaps->remove(encodingName))) {
759 delete old;
761 unicodeMaps->add(encodingName->copy(), fileName->copy());
764 void GlobalParams::addCMapDir(GooString *collection, GooString *dir) {
765 GooList *list;
767 if (!(list = (GooList *)cMapDirs->lookup(collection))) {
768 list = new GooList();
769 cMapDirs->add(collection->copy(), list);
771 list->append(dir->copy());
774 GBool GlobalParams::parseYesNo2(const char *token, GBool *flag) {
775 if (!strcmp(token, "yes")) {
776 *flag = gTrue;
777 } else if (!strcmp(token, "no")) {
778 *flag = gFalse;
779 } else {
780 return gFalse;
782 return gTrue;
785 GlobalParams::~GlobalParams() {
786 freeBuiltinFontTables();
788 delete macRomanReverseMap;
790 delete nameToUnicodeZapfDingbats;
791 delete nameToUnicodeText;
792 deleteGooHash(cidToUnicodes, GooString);
793 deleteGooHash(unicodeToUnicodes, GooString);
794 deleteGooHash(residentUnicodeMaps, UnicodeMap);
795 deleteGooHash(unicodeMaps, GooString);
796 deleteGooList(toUnicodeDirs, GooString);
797 deleteGooHash(fontFiles, GooString);
798 deleteGooList(fontDirs, GooString);
799 deleteGooHash(ccFontFiles, GooString);
800 #ifdef _WIN32
801 deleteGooHash(substFiles, GooString);
802 #endif
803 delete sysFonts;
804 if (psFile) {
805 delete psFile;
807 deleteGooHash(psResidentFonts, GooString);
808 deleteGooList(psResidentFonts16, PSFontParam16);
809 deleteGooList(psResidentFontsCC, PSFontParam16);
810 delete textEncoding;
812 GooHashIter *iter;
813 GooString *key;
814 cMapDirs->startIter(&iter);
815 void *val;
816 while (cMapDirs->getNext(&iter, &key, &val)) {
817 GooList* list = (GooList*)val;
818 deleteGooList(list, GooString);
820 delete cMapDirs;
822 delete cidToUnicodeCache;
823 delete unicodeToUnicodeCache;
824 delete unicodeMapCache;
825 delete cMapCache;
827 #ifdef ENABLE_PLUGINS
828 delete securityHandlers;
829 deleteGooList(plugins, Plugin);
830 #endif
832 #if MULTITHREADED
833 gDestroyMutex(&mutex);
834 gDestroyMutex(&unicodeMapCacheMutex);
835 gDestroyMutex(&cMapCacheMutex);
836 #endif
839 //------------------------------------------------------------------------
840 // accessors
841 //------------------------------------------------------------------------
843 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
844 // no need to lock - macRomanReverseMap is constant
845 return macRomanReverseMap->lookup(charName);
848 Unicode GlobalParams::mapNameToUnicodeAll(const char *charName) {
849 // no need to lock - nameToUnicodeZapfDingbats and nameToUnicodeText are constant
850 Unicode u = nameToUnicodeZapfDingbats->lookup(charName);
851 if (!u)
852 u = nameToUnicodeText->lookup(charName);
853 return u;
856 Unicode GlobalParams::mapNameToUnicodeText(const char *charName) {
857 // no need to lock - nameToUnicodeText is constant
858 return nameToUnicodeText->lookup(charName);
861 UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) {
862 UnicodeMap *map;
864 lockGlobalParams;
865 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
866 unlockGlobalParams;
867 if (map) {
868 map->incRefCnt();
870 return map;
873 FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) {
874 GooString *fileName;
875 FILE *f;
877 lockGlobalParams;
878 if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) {
879 f = openFile(fileName->getCString(), "r");
880 } else {
881 f = NULL;
883 unlockGlobalParams;
884 return f;
887 FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) {
888 GooList *list;
889 GooString *dir;
890 GooString *fileName;
891 FILE *f;
892 int i;
894 lockGlobalParams;
895 if (!(list = (GooList *)cMapDirs->lookup(collection))) {
896 unlockGlobalParams;
897 return NULL;
899 for (i = 0; i < list->getLength(); ++i) {
900 dir = (GooString *)list->get(i);
901 fileName = appendToPath(dir->copy(), cMapName->getCString());
902 f = openFile(fileName->getCString(), "r");
903 delete fileName;
904 if (f) {
905 unlockGlobalParams;
906 return f;
909 unlockGlobalParams;
910 return NULL;
913 FILE *GlobalParams::findToUnicodeFile(GooString *name) {
914 GooString *dir, *fileName;
915 FILE *f;
916 int i;
918 lockGlobalParams;
919 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
920 dir = (GooString *)toUnicodeDirs->get(i);
921 fileName = appendToPath(dir->copy(), name->getCString());
922 f = openFile(fileName->getCString(), "r");
923 delete fileName;
924 if (f) {
925 unlockGlobalParams;
926 return f;
929 unlockGlobalParams;
930 return NULL;
933 #if WITH_FONTCONFIGURATION_FONTCONFIG
934 static GBool findModifier(const char *name, const char *modifier, const char **start)
936 const char *match;
938 if (name == NULL)
939 return gFalse;
941 match = strstr(name, modifier);
942 if (match) {
943 if (*start == NULL || match < *start)
944 *start = match;
945 return gTrue;
947 else {
948 return gFalse;
952 static const char *getFontLang(GfxFont *font)
954 const char *lang;
956 // find the language we want the font to support
957 if (font->isCIDFont())
959 GooString *collection = ((GfxCIDFont *)font)->getCollection();
960 if (collection)
962 if (strcmp(collection->getCString(), "Adobe-GB1") == 0)
963 lang = "zh-cn"; // Simplified Chinese
964 else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0)
965 lang = "zh-tw"; // Traditional Chinese
966 else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0)
967 lang = "ja"; // Japanese
968 else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0)
969 lang = "ja"; // Japanese
970 else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0)
971 lang = "ko"; // Korean
972 else if (strcmp(collection->getCString(), "Adobe-UCS") == 0)
973 lang = "xx";
974 else if (strcmp(collection->getCString(), "Adobe-Identity") == 0)
975 lang = "xx";
976 else
978 error(errUnimplemented, -1, "Unknown CID font collection, please report to poppler bugzilla.");
979 lang = "xx";
982 else lang = "xx";
984 else lang = "xx";
985 return lang;
988 static FcPattern *buildFcPattern(GfxFont *font, GooString *base14Name)
990 int weight = -1,
991 slant = -1,
992 width = -1,
993 spacing = -1;
994 bool deleteFamily = false;
995 char *family, *name, *modifiers;
996 const char *start;
997 FcPattern *p;
999 // this is all heuristics will be overwritten if font had proper info
1000 name = (base14Name == NULL) ? font->getName()->getCString() : base14Name->getCString();
1002 modifiers = strchr (name, ',');
1003 if (modifiers == NULL)
1004 modifiers = strchr (name, '-');
1006 // remove the - from the names, for some reason, Fontconfig does not
1007 // understand "MS-Mincho" but does with "MS Mincho"
1008 int len = strlen(name);
1009 for (int i = 0; i < len; i++)
1010 name[i] = (name[i] == '-' ? ' ' : name[i]);
1012 start = NULL;
1013 findModifier(modifiers, "Regular", &start);
1014 findModifier(modifiers, "Roman", &start);
1016 if (findModifier(modifiers, "Oblique", &start))
1017 slant = FC_SLANT_OBLIQUE;
1018 if (findModifier(modifiers, "Italic", &start))
1019 slant = FC_SLANT_ITALIC;
1020 if (findModifier(modifiers, "Bold", &start))
1021 weight = FC_WEIGHT_BOLD;
1022 if (findModifier(modifiers, "Light", &start))
1023 weight = FC_WEIGHT_LIGHT;
1024 if (findModifier(modifiers, "Medium", &start))
1025 weight = FC_WEIGHT_MEDIUM;
1026 if (findModifier(modifiers, "Condensed", &start))
1027 width = FC_WIDTH_CONDENSED;
1029 if (start) {
1030 // There have been "modifiers" in the name, crop them to obtain
1031 // the family name
1032 family = new char[len+1];
1033 strcpy(family, name);
1034 int pos = (modifiers - name);
1035 family[pos] = '\0';
1036 deleteFamily = true;
1038 else {
1039 family = name;
1042 // use font flags
1043 if (font->isFixedWidth())
1044 spacing = FC_MONO;
1045 if (font->isBold())
1046 weight = FC_WEIGHT_BOLD;
1047 if (font->isItalic())
1048 slant = FC_SLANT_ITALIC;
1050 // if the FontDescriptor specified a family name use it
1051 if (font->getFamily()) {
1052 if (deleteFamily) {
1053 delete[] family;
1054 deleteFamily = false;
1056 family = font->getFamily()->getCString();
1059 // if the FontDescriptor specified a weight use it
1060 switch (font -> getWeight())
1062 case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break;
1063 case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break;
1064 case GfxFont::W300: weight = FC_WEIGHT_BOOK; break;
1065 case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break;
1066 case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break;
1067 case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break;
1068 case GfxFont::W700: weight = FC_WEIGHT_BOLD; break;
1069 case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break;
1070 case GfxFont::W900: weight = FC_WEIGHT_BLACK; break;
1071 default: break;
1074 // if the FontDescriptor specified a width use it
1075 switch (font -> getStretch())
1077 case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break;
1078 case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break;
1079 case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break;
1080 case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break;
1081 case GfxFont::Normal: width = FC_WIDTH_NORMAL; break;
1082 case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break;
1083 case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break;
1084 case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break;
1085 case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break;
1086 default: break;
1089 const char *lang = getFontLang(font);
1091 p = FcPatternBuild(NULL,
1092 FC_FAMILY, FcTypeString, family,
1093 FC_LANG, FcTypeString, lang,
1094 NULL);
1095 if (slant != -1) FcPatternAddInteger(p, FC_SLANT, slant);
1096 if (weight != -1) FcPatternAddInteger(p, FC_WEIGHT, weight);
1097 if (width != -1) FcPatternAddInteger(p, FC_WIDTH, width);
1098 if (spacing != -1) FcPatternAddInteger(p, FC_SPACING, spacing);
1100 if (deleteFamily)
1101 delete[] family;
1102 return p;
1104 #endif
1106 GooString *GlobalParams::findFontFile(GooString *fontName) {
1107 static const char *exts[] = { ".pfa", ".pfb", ".ttf", ".ttc", ".otf" };
1108 GooString *path, *dir;
1109 #ifdef WIN32
1110 GooString *fontNameU;
1111 #endif
1112 const char *ext;
1113 FILE *f;
1114 int i, j;
1116 setupBaseFonts(NULL);
1117 lockGlobalParams;
1118 if ((path = (GooString *)fontFiles->lookup(fontName))) {
1119 path = path->copy();
1120 unlockGlobalParams;
1121 return path;
1123 for (i = 0; i < fontDirs->getLength(); ++i) {
1124 dir = (GooString *)fontDirs->get(i);
1125 for (j = 0; j < (int)(sizeof(exts) / sizeof(exts[0])); ++j) {
1126 ext = exts[j];
1127 #ifdef WIN32
1128 fontNameU = fileNameToUTF8(fontName->getCString());
1129 path = appendToPath(dir->copy(), fontNameU->getCString());
1130 delete fontNameU;
1131 #else
1132 path = appendToPath(dir->copy(), fontName->getCString());
1133 #endif
1134 path->append(ext);
1135 if ((f = openFile(path->getCString(), "rb"))) {
1136 fclose(f);
1137 unlockGlobalParams;
1138 return path;
1140 delete path;
1143 unlockGlobalParams;
1144 return NULL;
1147 /* if you can't or don't want to use Fontconfig, you need to implement
1148 this function for your platform. For Windows, it's in GlobalParamsWin.cc
1150 #if WITH_FONTCONFIGURATION_FONTCONFIG
1151 // not needed for fontconfig
1152 void GlobalParams::setupBaseFonts(char *dir) {
1155 GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
1156 SysFontType type;
1157 int fontNum;
1159 return findSystemFontFile(font, &type, &fontNum, NULL, base14Name);
1162 GooString *GlobalParams::findSystemFontFile(GfxFont *font,
1163 SysFontType *type,
1164 int *fontNum, GooString *substituteFontName, GooString *base14Name) {
1165 SysFontInfo *fi = NULL;
1166 FcPattern *p=0;
1167 GooString *path = NULL;
1168 GooString *fontName = font->getName();
1169 GooString substituteName;
1170 if (!fontName) return NULL;
1171 lockGlobalParams;
1173 if ((fi = sysFonts->find(fontName, font->isFixedWidth(), gTrue))) {
1174 path = fi->path->copy();
1175 *type = fi->type;
1176 *fontNum = fi->fontNum;
1177 substituteName.Set(fi->substituteName->getCString());
1178 } else {
1179 FcChar8* s;
1180 char * ext;
1181 FcResult res;
1182 FcFontSet *set;
1183 int i;
1184 FcLangSet *lb = NULL;
1185 p = buildFcPattern(font, base14Name);
1187 if (!p)
1188 goto fin;
1189 FcConfigSubstitute(NULL, p, FcMatchPattern);
1190 FcDefaultSubstitute(p);
1191 set = FcFontSort(NULL, p, FcFalse, NULL, &res);
1192 if (!set)
1193 goto fin;
1195 // find the language we want the font to support
1196 const char *lang = getFontLang(font);
1197 if (strcmp(lang,"xx") != 0) {
1198 lb = FcLangSetCreate();
1199 FcLangSetAdd(lb,(FcChar8 *)lang);
1203 scan twice.
1204 first: fonts support the language
1205 second: all fonts (fall back)
1207 while (fi == NULL)
1209 for (i = 0; i < set->nfont; ++i)
1211 res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
1212 if (res != FcResultMatch || !s)
1213 continue;
1214 if (lb != NULL) {
1215 FcLangSet *l;
1216 res = FcPatternGetLangSet(set->fonts[i], FC_LANG, 0, &l);
1217 if (res != FcResultMatch || !FcLangSetContains(l,lb)) {
1218 continue;
1221 FcChar8* s2;
1222 res = FcPatternGetString(set->fonts[i], FC_FULLNAME, 0, &s2);
1223 if (res == FcResultMatch && s2) {
1224 substituteName.Set((char*)s2);
1225 } else {
1226 // fontconfig does not extract fullname for some fonts
1227 // create the fullname from family and style
1228 res = FcPatternGetString(set->fonts[i], FC_FAMILY, 0, &s2);
1229 if (res == FcResultMatch && s2) {
1230 substituteName.Set((char*)s2);
1231 res = FcPatternGetString(set->fonts[i], FC_STYLE, 0, &s2);
1232 if (res == FcResultMatch && s2) {
1233 GooString *style = new GooString((char*)s2);
1234 if (style->cmp("Regular") != 0) {
1235 substituteName.append(" ");
1236 substituteName.append(style);
1238 delete style;
1242 ext = strrchr((char*)s,'.');
1243 if (!ext)
1244 continue;
1245 if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4) || !strncasecmp(ext, ".otf", 4))
1247 int weight, slant;
1248 GBool bold = font->isBold();
1249 GBool italic = font->isItalic();
1250 GBool oblique = gFalse;
1251 FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
1252 FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
1253 if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD
1254 || weight == FC_WEIGHT_EXTRABOLD || weight == FC_WEIGHT_BLACK)
1256 bold = gTrue;
1258 if (slant == FC_SLANT_ITALIC)
1259 italic = gTrue;
1260 if (slant == FC_SLANT_OBLIQUE)
1261 oblique = gTrue;
1262 *fontNum = 0;
1263 *type = (!strncasecmp(ext,".ttc",4)) ? sysFontTTC : sysFontTTF;
1264 FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
1265 fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
1266 new GooString((char*)s), *type, *fontNum, substituteName.copy());
1267 sysFonts->addFcFont(fi);
1268 path = new GooString((char*)s);
1270 else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4))
1272 int weight, slant;
1273 GBool bold = font->isBold();
1274 GBool italic = font->isItalic();
1275 GBool oblique = gFalse;
1276 FcPatternGetInteger(set->fonts[i], FC_WEIGHT, 0, &weight);
1277 FcPatternGetInteger(set->fonts[i], FC_SLANT, 0, &slant);
1278 if (weight == FC_WEIGHT_DEMIBOLD || weight == FC_WEIGHT_BOLD
1279 || weight == FC_WEIGHT_EXTRABOLD || weight == FC_WEIGHT_BLACK)
1281 bold = gTrue;
1283 if (slant == FC_SLANT_ITALIC)
1284 italic = gTrue;
1285 if (slant == FC_SLANT_OBLIQUE)
1286 oblique = gTrue;
1287 *fontNum = 0;
1288 *type = (!strncasecmp(ext,".pfa",4)) ? sysFontPFA : sysFontPFB;
1289 FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, fontNum);
1290 fi = new SysFontInfo(fontName->copy(), bold, italic, oblique, font->isFixedWidth(),
1291 new GooString((char*)s), *type, *fontNum, substituteName.copy());
1292 sysFonts->addFcFont(fi);
1293 path = new GooString((char*)s);
1295 else
1296 continue;
1297 break;
1299 if (lb != NULL) {
1300 FcLangSetDestroy(lb);
1301 lb = NULL;
1302 } else {
1303 /* scan all fonts of the list */
1304 break;
1307 FcFontSetDestroy(set);
1309 if (path == NULL && (fi = sysFonts->find(fontName, font->isFixedWidth(), gFalse))) {
1310 path = fi->path->copy();
1311 *type = fi->type;
1312 *fontNum = fi->fontNum;
1314 if (substituteFontName) {
1315 substituteFontName->Set(substituteName.getCString());
1317 fin:
1318 if (p)
1319 FcPatternDestroy(p);
1320 unlockGlobalParams;
1321 return path;
1324 #elif WITH_FONTCONFIGURATION_WIN32
1325 #include "GlobalParamsWin.cc"
1327 GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
1328 return findFontFile(base14Name);
1330 #else
1331 GooString *GlobalParams::findBase14FontFile(GooString *base14Name, GfxFont *font) {
1332 return findFontFile(base14Name);
1335 static struct {
1336 const char *name;
1337 const char *t1FileName;
1338 const char *ttFileName;
1339 } displayFontTab[] = {
1340 {"Courier", "n022003l.pfb", "cour.ttf"},
1341 {"Courier-Bold", "n022004l.pfb", "courbd.ttf"},
1342 {"Courier-BoldOblique", "n022024l.pfb", "courbi.ttf"},
1343 {"Courier-Oblique", "n022023l.pfb", "couri.ttf"},
1344 {"Helvetica", "n019003l.pfb", "arial.ttf"},
1345 {"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf"},
1346 {"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf"},
1347 {"Helvetica-Oblique", "n019023l.pfb", "ariali.ttf"},
1348 {"Symbol", "s050000l.pfb", NULL},
1349 {"Times-Bold", "n021004l.pfb", "timesbd.ttf"},
1350 {"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf"},
1351 {"Times-Italic", "n021023l.pfb", "timesi.ttf"},
1352 {"Times-Roman", "n021003l.pfb", "times.ttf"},
1353 {"ZapfDingbats", "d050000l.pfb", NULL},
1354 {NULL}
1357 static const char *displayFontDirs[] = {
1358 "/usr/share/ghostscript/fonts",
1359 "/usr/local/share/ghostscript/fonts",
1360 "/usr/share/fonts/default/Type1",
1361 "/usr/share/fonts/default/ghostscript",
1362 "/usr/share/fonts/type1/gsfonts",
1363 NULL
1366 void GlobalParams::setupBaseFonts(char *dir) {
1367 GooString *fontName;
1368 GooString *fileName;
1369 FILE *f;
1370 int i, j;
1372 for (i = 0; displayFontTab[i].name; ++i) {
1373 if (fontFiles->lookup(displayFontTab[i].name)) {
1374 continue;
1376 fontName = new GooString(displayFontTab[i].name);
1377 fileName = NULL;
1378 if (dir) {
1379 fileName = appendToPath(new GooString(dir), displayFontTab[i].t1FileName);
1380 if ((f = fopen(fileName->getCString(), "rb"))) {
1381 fclose(f);
1382 } else {
1383 delete fileName;
1384 fileName = NULL;
1387 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
1388 fileName = appendToPath(new GooString(displayFontDirs[j]),
1389 displayFontTab[i].t1FileName);
1390 if ((f = fopen(fileName->getCString(), "rb"))) {
1391 fclose(f);
1392 } else {
1393 delete fileName;
1394 fileName = NULL;
1397 if (!fileName) {
1398 error(errConfig, -1, "No display font for '{0:s}'",
1399 displayFontTab[i].name);
1400 delete fontName;
1401 continue;
1403 addFontFile(fontName, fileName);
1408 GooString *GlobalParams::findSystemFontFile(GfxFont *font,
1409 SysFontType *type,
1410 int *fontNum, GooString * /*substituteFontName*/,
1411 GooString * /*base14Name*/) {
1412 SysFontInfo *fi;
1413 GooString *path;
1415 path = NULL;
1416 lockGlobalParams;
1417 if ((fi = sysFonts->find(font->getName(), font->isFixedWidth(), gFalse))) {
1418 path = fi->path->copy();
1419 *type = fi->type;
1420 *fontNum = fi->fontNum;
1422 unlockGlobalParams;
1423 return path;
1425 #endif
1427 GooString *GlobalParams::findCCFontFile(GooString *collection) {
1428 GooString *path;
1430 lockGlobalParams;
1431 if ((path = (GooString *)ccFontFiles->lookup(collection))) {
1432 path = path->copy();
1434 unlockGlobalParams;
1435 return path;
1439 GBool GlobalParams::getPSExpandSmaller() {
1440 GBool f;
1442 lockGlobalParams;
1443 f = psExpandSmaller;
1444 unlockGlobalParams;
1445 return f;
1448 GBool GlobalParams::getPSShrinkLarger() {
1449 GBool f;
1451 lockGlobalParams;
1452 f = psShrinkLarger;
1453 unlockGlobalParams;
1454 return f;
1457 GBool GlobalParams::getPSCenter() {
1458 GBool f;
1460 lockGlobalParams;
1461 f = psCenter;
1462 unlockGlobalParams;
1463 return f;
1466 PSLevel GlobalParams::getPSLevel() {
1467 PSLevel level;
1469 lockGlobalParams;
1470 level = psLevel;
1471 unlockGlobalParams;
1472 return level;
1475 GooString *GlobalParams::getPSResidentFont(GooString *fontName) {
1476 GooString *psName;
1478 lockGlobalParams;
1479 psName = (GooString *)psResidentFonts->lookup(fontName);
1480 unlockGlobalParams;
1481 return psName;
1484 GooList *GlobalParams::getPSResidentFonts() {
1485 GooList *names;
1486 GooHashIter *iter;
1487 GooString *name;
1488 GooString *psName;
1490 names = new GooList();
1491 lockGlobalParams;
1492 psResidentFonts->startIter(&iter);
1493 while (psResidentFonts->getNext(&iter, &name, (void **)&psName)) {
1494 names->append(psName->copy());
1496 unlockGlobalParams;
1497 return names;
1500 PSFontParam16 *GlobalParams::getPSResidentFont16(GooString *fontName,
1501 int wMode) {
1502 PSFontParam16 *p;
1503 int i;
1505 lockGlobalParams;
1506 p = NULL;
1507 for (i = 0; i < psResidentFonts16->getLength(); ++i) {
1508 p = (PSFontParam16 *)psResidentFonts16->get(i);
1509 if (!(p->name->cmp(fontName)) && p->wMode == wMode) {
1510 break;
1512 p = NULL;
1514 unlockGlobalParams;
1515 return p;
1518 PSFontParam16 *GlobalParams::getPSResidentFontCC(GooString *collection,
1519 int wMode) {
1520 PSFontParam16 *p;
1521 int i;
1523 lockGlobalParams;
1524 p = NULL;
1525 for (i = 0; i < psResidentFontsCC->getLength(); ++i) {
1526 p = (PSFontParam16 *)psResidentFontsCC->get(i);
1527 if (!(p->name->cmp(collection)) && p->wMode == wMode) {
1528 break;
1530 p = NULL;
1532 unlockGlobalParams;
1533 return p;
1536 GooString *GlobalParams::getTextEncodingName() {
1537 GooString *s;
1539 lockGlobalParams;
1540 s = textEncoding->copy();
1541 unlockGlobalParams;
1542 return s;
1545 EndOfLineKind GlobalParams::getTextEOL() {
1546 EndOfLineKind eol;
1548 lockGlobalParams;
1549 eol = textEOL;
1550 unlockGlobalParams;
1551 return eol;
1554 GBool GlobalParams::getTextPageBreaks() {
1555 GBool pageBreaks;
1557 lockGlobalParams;
1558 pageBreaks = textPageBreaks;
1559 unlockGlobalParams;
1560 return pageBreaks;
1563 GBool GlobalParams::getTextKeepTinyChars() {
1564 GBool tiny;
1566 lockGlobalParams;
1567 tiny = textKeepTinyChars;
1568 unlockGlobalParams;
1569 return tiny;
1572 GBool GlobalParams::getEnableFreeType() {
1573 GBool f;
1575 lockGlobalParams;
1576 f = enableFreeType;
1577 unlockGlobalParams;
1578 return f;
1581 GBool GlobalParams::getStrokeAdjust() {
1582 GBool f;
1584 lockGlobalParams;
1585 f = strokeAdjust;
1586 unlockGlobalParams;
1587 return f;
1590 ScreenType GlobalParams::getScreenType() {
1591 ScreenType t;
1593 lockGlobalParams;
1594 t = screenType;
1595 unlockGlobalParams;
1596 return t;
1599 int GlobalParams::getScreenSize() {
1600 int size;
1602 lockGlobalParams;
1603 size = screenSize;
1604 unlockGlobalParams;
1605 return size;
1608 int GlobalParams::getScreenDotRadius() {
1609 int r;
1611 lockGlobalParams;
1612 r = screenDotRadius;
1613 unlockGlobalParams;
1614 return r;
1617 double GlobalParams::getScreenGamma() {
1618 double gamma;
1620 lockGlobalParams;
1621 gamma = screenGamma;
1622 unlockGlobalParams;
1623 return gamma;
1626 double GlobalParams::getScreenBlackThreshold() {
1627 double thresh;
1629 lockGlobalParams;
1630 thresh = screenBlackThreshold;
1631 unlockGlobalParams;
1632 return thresh;
1635 double GlobalParams::getScreenWhiteThreshold() {
1636 double thresh;
1638 lockGlobalParams;
1639 thresh = screenWhiteThreshold;
1640 unlockGlobalParams;
1641 return thresh;
1644 double GlobalParams::getMinLineWidth() {
1645 double minLineWidthA;
1647 lockGlobalParams;
1648 minLineWidthA = minLineWidth;
1649 unlockGlobalParams;
1650 return minLineWidthA;
1653 GBool GlobalParams::getMapNumericCharNames() {
1654 GBool map;
1656 lockGlobalParams;
1657 map = mapNumericCharNames;
1658 unlockGlobalParams;
1659 return map;
1662 GBool GlobalParams::getMapUnknownCharNames() {
1663 GBool map;
1665 lockGlobalParams;
1666 map = mapUnknownCharNames;
1667 unlockGlobalParams;
1668 return map;
1671 GBool GlobalParams::getPrintCommands() {
1672 GBool p;
1674 lockGlobalParams;
1675 p = printCommands;
1676 unlockGlobalParams;
1677 return p;
1680 GBool GlobalParams::getProfileCommands() {
1681 GBool p;
1683 lockGlobalParams;
1684 p = profileCommands;
1685 unlockGlobalParams;
1686 return p;
1689 GBool GlobalParams::getErrQuiet() {
1690 // no locking -- this function may get called from inside a locked
1691 // section
1692 return errQuiet;
1695 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
1696 GooString *fileName;
1697 CharCodeToUnicode *ctu;
1699 lockGlobalParams;
1700 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1701 if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) &&
1702 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1703 cidToUnicodeCache->add(ctu);
1706 unlockGlobalParams;
1707 return ctu;
1710 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) {
1711 lockGlobalParams;
1712 GooHashIter *iter;
1713 unicodeToUnicodes->startIter(&iter);
1714 GooString *fileName = NULL;
1715 GooString *fontPattern;
1716 void *val;
1717 while (!fileName && unicodeToUnicodes->getNext(&iter, &fontPattern, &val)) {
1718 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1719 unicodeToUnicodes->killIter(&iter);
1720 fileName = (GooString*)val;
1723 CharCodeToUnicode *ctu = NULL;
1724 if (fileName) {
1725 ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName);
1726 if (!ctu) {
1727 ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName);
1728 if (ctu)
1729 unicodeToUnicodeCache->add(ctu);
1732 unlockGlobalParams;
1733 return ctu;
1736 UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
1737 return getUnicodeMap2(encodingName);
1740 UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
1741 UnicodeMap *map;
1743 if (!(map = getResidentUnicodeMap(encodingName))) {
1744 lockUnicodeMapCache;
1745 map = unicodeMapCache->getUnicodeMap(encodingName);
1746 unlockUnicodeMapCache;
1748 return map;
1751 CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName, Stream *stream) {
1752 CMap *cMap;
1754 lockCMapCache;
1755 cMap = cMapCache->getCMap(collection, cMapName, stream);
1756 unlockCMapCache;
1757 return cMap;
1760 UnicodeMap *GlobalParams::getTextEncoding() {
1761 return getUnicodeMap2(textEncoding);
1764 GooList *GlobalParams::getEncodingNames()
1766 GooList *result = new GooList;
1767 GooHashIter *iter;
1768 GooString *key;
1769 void *val;
1770 residentUnicodeMaps->startIter(&iter);
1771 while (residentUnicodeMaps->getNext(&iter, &key, &val)) {
1772 result->append(key);
1774 residentUnicodeMaps->killIter(&iter);
1775 unicodeMaps->startIter(&iter);
1776 while (unicodeMaps->getNext(&iter, &key, &val)) {
1777 result->append(key);
1779 unicodeMaps->killIter(&iter);
1780 return result;
1783 //------------------------------------------------------------------------
1784 // functions to set parameters
1785 //------------------------------------------------------------------------
1787 void GlobalParams::addFontFile(GooString *fontName, GooString *path) {
1788 lockGlobalParams;
1789 fontFiles->add(fontName, path);
1790 unlockGlobalParams;
1793 void GlobalParams::setPSFile(char *file) {
1794 lockGlobalParams;
1795 if (psFile) {
1796 delete psFile;
1798 psFile = new GooString(file);
1799 unlockGlobalParams;
1802 void GlobalParams::setPSExpandSmaller(GBool expand) {
1803 lockGlobalParams;
1804 psExpandSmaller = expand;
1805 unlockGlobalParams;
1808 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1809 lockGlobalParams;
1810 psShrinkLarger = shrink;
1811 unlockGlobalParams;
1814 void GlobalParams::setPSCenter(GBool center) {
1815 lockGlobalParams;
1816 psCenter = center;
1817 unlockGlobalParams;
1820 void GlobalParams::setPSLevel(PSLevel level) {
1821 lockGlobalParams;
1822 psLevel = level;
1823 unlockGlobalParams;
1826 void GlobalParams::setTextEncoding(char *encodingName) {
1827 lockGlobalParams;
1828 delete textEncoding;
1829 textEncoding = new GooString(encodingName);
1830 unlockGlobalParams;
1833 GBool GlobalParams::setTextEOL(char *s) {
1834 lockGlobalParams;
1835 if (!strcmp(s, "unix")) {
1836 textEOL = eolUnix;
1837 } else if (!strcmp(s, "dos")) {
1838 textEOL = eolDOS;
1839 } else if (!strcmp(s, "mac")) {
1840 textEOL = eolMac;
1841 } else {
1842 unlockGlobalParams;
1843 return gFalse;
1845 unlockGlobalParams;
1846 return gTrue;
1849 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1850 lockGlobalParams;
1851 textPageBreaks = pageBreaks;
1852 unlockGlobalParams;
1855 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1856 lockGlobalParams;
1857 textKeepTinyChars = keep;
1858 unlockGlobalParams;
1861 GBool GlobalParams::setEnableFreeType(char *s) {
1862 GBool ok;
1864 lockGlobalParams;
1865 ok = parseYesNo2(s, &enableFreeType);
1866 unlockGlobalParams;
1867 return ok;
1870 GBool GlobalParams::setDisableFreeTypeHinting(char *s) {
1871 GBool ok;
1873 lockGlobalParams;
1874 ok = parseYesNo2(s, &disableFreeTypeHinting);
1875 unlockGlobalParams;
1876 return ok;
1879 void GlobalParams::setStrokeAdjust(GBool adjust)
1881 lockGlobalParams;
1882 strokeAdjust = adjust;
1883 unlockGlobalParams;
1886 void GlobalParams::setScreenType(ScreenType st)
1888 lockGlobalParams;
1889 screenType = st;
1890 unlockGlobalParams;
1893 void GlobalParams::setScreenSize(int size)
1895 lockGlobalParams;
1896 screenSize = size;
1897 unlockGlobalParams;
1900 void GlobalParams::setScreenDotRadius(int radius)
1902 lockGlobalParams;
1903 screenDotRadius = radius;
1904 unlockGlobalParams;
1907 void GlobalParams::setScreenGamma(double gamma)
1909 lockGlobalParams;
1910 screenGamma = gamma;
1911 unlockGlobalParams;
1914 void GlobalParams::setScreenBlackThreshold(double blackThreshold)
1916 lockGlobalParams;
1917 screenBlackThreshold = blackThreshold;
1918 unlockGlobalParams;
1921 void GlobalParams::setScreenWhiteThreshold(double whiteThreshold)
1923 lockGlobalParams;
1924 screenWhiteThreshold = whiteThreshold;
1925 unlockGlobalParams;
1928 void GlobalParams::setMinLineWidth(double minLineWidthA)
1930 lockGlobalParams;
1931 minLineWidth = minLineWidthA;
1932 unlockGlobalParams;
1935 void GlobalParams::setOverprintPreview(GBool overprintPreviewA) {
1936 lockGlobalParams;
1937 overprintPreview = overprintPreviewA;
1938 unlockGlobalParams;
1941 void GlobalParams::setMapNumericCharNames(GBool map) {
1942 lockGlobalParams;
1943 mapNumericCharNames = map;
1944 unlockGlobalParams;
1947 void GlobalParams::setMapUnknownCharNames(GBool map) {
1948 lockGlobalParams;
1949 mapUnknownCharNames = map;
1950 unlockGlobalParams;
1953 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1954 lockGlobalParams;
1955 printCommands = printCommandsA;
1956 unlockGlobalParams;
1959 void GlobalParams::setProfileCommands(GBool profileCommandsA) {
1960 lockGlobalParams;
1961 profileCommands = profileCommandsA;
1962 unlockGlobalParams;
1965 void GlobalParams::setErrQuiet(GBool errQuietA) {
1966 lockGlobalParams;
1967 errQuiet = errQuietA;
1968 unlockGlobalParams;
1971 void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1972 #ifdef ENABLE_PLUGINS
1973 lockGlobalParams;
1974 securityHandlers->append(handler);
1975 unlockGlobalParams;
1976 #endif
1979 XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1980 #ifdef ENABLE_PLUGINS
1981 XpdfSecurityHandler *hdlr;
1982 int i;
1984 lockGlobalParams;
1985 for (i = 0; i < securityHandlers->getLength(); ++i) {
1986 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1987 if (!strcasecmp(hdlr->name, name)) {
1988 unlockGlobalParams;
1989 return hdlr;
1992 unlockGlobalParams;
1994 if (!loadPlugin("security", name)) {
1995 return NULL;
1998 lockGlobalParams;
1999 for (i = 0; i < securityHandlers->getLength(); ++i) {
2000 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
2001 if (!strcmp(hdlr->name, name)) {
2002 unlockGlobalParams;
2003 return hdlr;
2006 unlockGlobalParams;
2007 #else
2008 (void)name;
2009 #endif
2011 return NULL;
2014 #ifdef ENABLE_PLUGINS
2015 //------------------------------------------------------------------------
2016 // plugins
2017 //------------------------------------------------------------------------
2019 GBool GlobalParams::loadPlugin(char *type, char *name) {
2020 Plugin *plugin;
2022 if (!(plugin = Plugin::load(type, name))) {
2023 return gFalse;
2025 lockGlobalParams;
2026 plugins->append(plugin);
2027 unlockGlobalParams;
2028 return gTrue;
2031 #endif // ENABLE_PLUGINS