1 //========================================================================
5 // Copyright 2001-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
35 #include "NameToCharCode.h"
36 #include "CharCodeToUnicode.h"
37 #include "UnicodeMap.h"
39 #include "BuiltinFontTables.h"
40 #include "FontEncodingTables.h"
42 # include "XpdfPluginAPI.h"
44 #include "GlobalParams.h"
47 # define lockGlobalParams gLockMutex(&mutex)
48 # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
49 # define lockCMapCache gLockMutex(&cMapCacheMutex)
50 # define unlockGlobalParams gUnlockMutex(&mutex)
51 # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
52 # define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
54 # define lockGlobalParams
55 # define lockUnicodeMapCache
56 # define lockCMapCache
57 # define unlockGlobalParams
58 # define unlockUnicodeMapCache
59 # define unlockCMapCache
62 #include "NameToUnicodeTable.h"
63 #include "UnicodeMapTables.h"
68 extern XpdfPluginVecTable xpdfPluginVecTable;
72 //------------------------------------------------------------------------
74 #define cidToUnicodeCacheSize 4
75 #define unicodeToUnicodeCacheSize 4
77 //------------------------------------------------------------------------
83 } displayFontTab[] = {
84 {"Courier", "n022003l.pfb", "cour.ttf"},
85 {"Courier-Bold", "n022004l.pfb", "courbd.ttf"},
86 {"Courier-BoldOblique", "n022024l.pfb", "courbi.ttf"},
87 {"Courier-Oblique", "n022023l.pfb", "couri.ttf"},
88 {"Helvetica", "n019003l.pfb", "arial.ttf"},
89 {"Helvetica-Bold", "n019004l.pfb", "arialbd.ttf"},
90 {"Helvetica-BoldOblique", "n019024l.pfb", "arialbi.ttf"},
91 {"Helvetica-Oblique", "n019023l.pfb", "ariali.ttf"},
92 {"Symbol", "s050000l.pfb", NULL},
93 {"Times-Bold", "n021004l.pfb", "timesbd.ttf"},
94 {"Times-BoldItalic", "n021024l.pfb", "timesbi.ttf"},
95 {"Times-Italic", "n021023l.pfb", "timesi.ttf"},
96 {"Times-Roman", "n021003l.pfb", "times.ttf"},
97 {"ZapfDingbats", "d050000l.pfb", NULL},
102 static char *displayFontDirs[] = {
108 static char *displayFontDirs[] = {
109 "/usr/share/ghostscript/fonts",
110 "/usr/local/share/ghostscript/fonts",
111 "/usr/share/fonts/default/Type1",
112 "/usr/share/fonts/default/ghostscript",
113 "/usr/share/fonts/type1/gsfonts",
118 //------------------------------------------------------------------------
120 GlobalParams *globalParams = NULL;
122 //------------------------------------------------------------------------
124 //------------------------------------------------------------------------
126 DisplayFontParam::DisplayFontParam(GString *nameA,
127 DisplayFontParamKind kindA) {
140 DisplayFontParam::~DisplayFontParam() {
156 //------------------------------------------------------------------------
158 //------------------------------------------------------------------------
160 PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
161 GString *psFontNameA, GString *encodingA) {
162 pdfFontName = pdfFontNameA;
164 psFontName = psFontNameA;
165 encoding = encodingA;
168 PSFontParam::~PSFontParam() {
176 #ifdef ENABLE_PLUGINS
177 //------------------------------------------------------------------------
179 //------------------------------------------------------------------------
184 static Plugin *load(char *type, char *name);
190 Plugin(HMODULE libA);
198 Plugin *Plugin::load(char *type, char *name) {
201 XpdfPluginVecTable *vt;
202 XpdfBool (*xpdfInitPlugin)(void);
209 path = globalParams->getBaseDir();
210 appendToPath(path, "plugins");
211 appendToPath(path, type);
212 appendToPath(path, name);
215 path->append(".dll");
216 if (!(libA = LoadLibrary(path->getCString()))) {
217 error(-1, "Failed to load plugin '%s'",
221 if (!(vt = (XpdfPluginVecTable *)
222 GetProcAddress(libA, "xpdfPluginVecTable"))) {
223 error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
228 //~ need to deal with other extensions here
230 if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
231 error(-1, "Failed to load plugin '%s': %s",
232 path->getCString(), dlerror());
235 if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
236 error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
242 if (vt->version != xpdfPluginVecTable.version) {
243 error(-1, "Plugin '%s' is wrong version", path->getCString());
246 memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
249 if (!(xpdfInitPlugin = (XpdfBool (*)(void))
250 GetProcAddress(libA, "xpdfInitPlugin"))) {
251 error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
256 if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
257 error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
263 if (!(*xpdfInitPlugin)()) {
264 error(-1, "Initialization of plugin '%s' failed",
270 plugin = new Plugin(libA);
272 plugin = new Plugin(dlA);
290 Plugin::Plugin(HMODULE libA) {
294 Plugin::Plugin(void *dlA) {
300 void (*xpdfFreePlugin)(void);
303 if ((xpdfFreePlugin = (void (*)(void))
304 GetProcAddress(lib, "xpdfFreePlugin"))) {
309 if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
316 #endif // ENABLE_PLUGINS
318 //------------------------------------------------------------------------
320 //------------------------------------------------------------------------
322 GlobalParams::GlobalParams(char *cfgFileName) {
330 gInitMutex(&unicodeMapCacheMutex);
331 gInitMutex(&cMapCacheMutex);
334 initBuiltinFontTables();
336 // scan the encoding in reverse because we want the lowest-numbered
337 // index for each char name ('space' is encoded twice)
338 macRomanReverseMap = new NameToCharCode();
339 for (i = 255; i >= 0; --i) {
340 if (macRomanEncoding[i]) {
341 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
346 // baseDir will be set by a call to setBaseDir
347 baseDir = new GString();
349 baseDir = appendToPath(getHomeDir(), ".xpdf");
351 nameToUnicode = new NameToCharCode();
352 cidToUnicodes = new GHash(gTrue);
353 unicodeToUnicodes = new GHash(gTrue);
354 residentUnicodeMaps = new GHash();
355 unicodeMaps = new GHash(gTrue);
356 cMapDirs = new GHash(gTrue);
357 toUnicodeDirs = new GList();
358 displayFonts = new GHash();
359 displayCIDFonts = new GHash();
360 displayNamedCIDFonts = new GHash();
363 const struct paper *paperType;
365 if ((paperName = systempapername())) {
366 paperType = paperinfo(paperName);
367 psPaperWidth = (int)paperpswidth(paperType);
368 psPaperHeight = (int)paperpsheight(paperType);
370 error(-1, "No paper information available - using defaults");
371 psPaperWidth = defPaperWidth;
372 psPaperHeight = defPaperHeight;
376 psPaperWidth = defPaperWidth;
377 psPaperHeight = defPaperHeight;
379 psImageableLLX = psImageableLLY = 0;
380 psImageableURX = psPaperWidth;
381 psImageableURY = psPaperHeight;
383 psExpandSmaller = gFalse;
384 psShrinkLarger = gTrue;
389 psFonts = new GHash();
390 psNamedFonts16 = new GList();
391 psFonts16 = new GList();
392 psEmbedType1 = gTrue;
393 psEmbedTrueType = gTrue;
394 psEmbedCIDPostScript = gTrue;
395 psEmbedCIDTrueType = gTrue;
398 textEncoding = new GString("Latin1");
406 textPageBreaks = gTrue;
407 textKeepTinyChars = gFalse;
408 fontDirs = new GList();
409 initialZoom = new GString("125");
410 continuousView = gFalse;
412 enableFreeType = gTrue;
416 mapNumericCharNames = gTrue;
417 printCommands = gFalse;
420 cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
421 unicodeToUnicodeCache =
422 new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
423 unicodeMapCache = new UnicodeMapCache();
424 cMapCache = new CMapCache();
426 #ifdef ENABLE_PLUGINS
427 plugins = new GList();
428 securityHandlers = new GList();
431 // set up the initial nameToUnicode table
432 for (i = 0; nameToUnicodeTab[i].name; ++i) {
433 nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
436 // set up the residentUnicodeMaps table
437 map = new UnicodeMap("Latin1", gFalse,
438 latin1UnicodeMapRanges, latin1UnicodeMapLen);
439 residentUnicodeMaps->add(map->getEncodingName(), map);
440 map = new UnicodeMap("ASCII7", gFalse,
441 ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
442 residentUnicodeMaps->add(map->getEncodingName(), map);
443 map = new UnicodeMap("Symbol", gFalse,
444 symbolUnicodeMapRanges, symbolUnicodeMapLen);
445 residentUnicodeMaps->add(map->getEncodingName(), map);
446 map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
447 zapfDingbatsUnicodeMapLen);
448 residentUnicodeMaps->add(map->getEncodingName(), map);
449 map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
450 residentUnicodeMaps->add(map->getEncodingName(), map);
451 map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
452 residentUnicodeMaps->add(map->getEncodingName(), map);
454 // look for a user config file, then a system-wide config file
457 if (cfgFileName && cfgFileName[0]) {
458 fileName = new GString(cfgFileName);
459 if (!(f = fopen(fileName->getCString(), "r"))) {
464 fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
465 if (!(f = fopen(fileName->getCString(), "r"))) {
470 #if defined(WIN32) && !defined(__CYGWIN32__)
472 i = GetModuleFileName(NULL, buf, sizeof(buf));
473 if (i <= 0 || i >= sizeof(buf)) {
474 // error or path too long for buffer - just use the current dir
477 fileName = grabPath(buf);
478 appendToPath(fileName, xpdfSysConfigFile);
480 fileName = new GString(xpdfSysConfigFile);
482 if (!(f = fopen(fileName->getCString(), "r"))) {
487 parseFile(fileName, f);
493 void GlobalParams::parseFile(GString *fileName, FILE *f) {
496 GString *cmd, *incFile;
502 while (getLine(buf, sizeof(buf) - 1, f)) {
504 // break the line into tokens
505 tokens = new GList();
508 for (; *p1 && isspace(*p1); ++p1) ;
512 if (*p1 == '"' || *p1 == '\'') {
513 for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
516 for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
518 tokens->append(new GString(p1, p2 - p1));
519 p1 = *p2 ? p2 + 1 : p2;
522 if (tokens->getLength() > 0 &&
523 ((GString *)tokens->get(0))->getChar(0) != '#') {
524 cmd = (GString *)tokens->get(0);
525 if (!cmd->cmp("include")) {
526 if (tokens->getLength() == 2) {
527 incFile = (GString *)tokens->get(1);
528 if ((f2 = fopen(incFile->getCString(), "r"))) {
529 parseFile(incFile, f2);
532 error(-1, "Couldn't find included config file: '%s' (%s:%d)",
533 incFile->getCString(), fileName->getCString(), line);
536 error(-1, "Bad 'include' config file command (%s:%d)",
537 fileName->getCString(), line);
539 } else if (!cmd->cmp("nameToUnicode")) {
540 parseNameToUnicode(tokens, fileName, line);
541 } else if (!cmd->cmp("cidToUnicode")) {
542 parseCIDToUnicode(tokens, fileName, line);
543 } else if (!cmd->cmp("unicodeToUnicode")) {
544 parseUnicodeToUnicode(tokens, fileName, line);
545 } else if (!cmd->cmp("unicodeMap")) {
546 parseUnicodeMap(tokens, fileName, line);
547 } else if (!cmd->cmp("cMapDir")) {
548 parseCMapDir(tokens, fileName, line);
549 } else if (!cmd->cmp("toUnicodeDir")) {
550 parseToUnicodeDir(tokens, fileName, line);
551 } else if (!cmd->cmp("displayFontT1")) {
552 parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
553 } else if (!cmd->cmp("displayFontTT")) {
554 parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
555 } else if (!cmd->cmp("displayNamedCIDFontT1")) {
556 parseDisplayFont(tokens, displayNamedCIDFonts,
557 displayFontT1, fileName, line);
558 } else if (!cmd->cmp("displayCIDFontT1")) {
559 parseDisplayFont(tokens, displayCIDFonts,
560 displayFontT1, fileName, line);
561 } else if (!cmd->cmp("displayNamedCIDFontTT")) {
562 parseDisplayFont(tokens, displayNamedCIDFonts,
563 displayFontTT, fileName, line);
564 } else if (!cmd->cmp("displayCIDFontTT")) {
565 parseDisplayFont(tokens, displayCIDFonts,
566 displayFontTT, fileName, line);
567 } else if (!cmd->cmp("psFile")) {
568 parsePSFile(tokens, fileName, line);
569 } else if (!cmd->cmp("psFont")) {
570 parsePSFont(tokens, fileName, line);
571 } else if (!cmd->cmp("psNamedFont16")) {
572 parsePSFont16("psNamedFont16", psNamedFonts16,
573 tokens, fileName, line);
574 } else if (!cmd->cmp("psFont16")) {
575 parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
576 } else if (!cmd->cmp("psPaperSize")) {
577 parsePSPaperSize(tokens, fileName, line);
578 } else if (!cmd->cmp("psImageableArea")) {
579 parsePSImageableArea(tokens, fileName, line);
580 } else if (!cmd->cmp("psCrop")) {
581 parseYesNo("psCrop", &psCrop, tokens, fileName, line);
582 } else if (!cmd->cmp("psExpandSmaller")) {
583 parseYesNo("psExpandSmaller", &psExpandSmaller,
584 tokens, fileName, line);
585 } else if (!cmd->cmp("psShrinkLarger")) {
586 parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
587 } else if (!cmd->cmp("psCenter")) {
588 parseYesNo("psCenter", &psCenter, tokens, fileName, line);
589 } else if (!cmd->cmp("psDuplex")) {
590 parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
591 } else if (!cmd->cmp("psLevel")) {
592 parsePSLevel(tokens, fileName, line);
593 } else if (!cmd->cmp("psEmbedType1Fonts")) {
594 parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
595 } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
596 parseYesNo("psEmbedTrueType", &psEmbedTrueType,
597 tokens, fileName, line);
598 } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
599 parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
600 tokens, fileName, line);
601 } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
602 parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
603 tokens, fileName, line);
604 } else if (!cmd->cmp("psOPI")) {
605 parseYesNo("psOPI", &psOPI, tokens, fileName, line);
606 } else if (!cmd->cmp("psASCIIHex")) {
607 parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
608 } else if (!cmd->cmp("textEncoding")) {
609 parseTextEncoding(tokens, fileName, line);
610 } else if (!cmd->cmp("textEOL")) {
611 parseTextEOL(tokens, fileName, line);
612 } else if (!cmd->cmp("textPageBreaks")) {
613 parseYesNo("textPageBreaks", &textPageBreaks,
614 tokens, fileName, line);
615 } else if (!cmd->cmp("textKeepTinyChars")) {
616 parseYesNo("textKeepTinyChars", &textKeepTinyChars,
617 tokens, fileName, line);
618 } else if (!cmd->cmp("fontDir")) {
619 parseFontDir(tokens, fileName, line);
620 } else if (!cmd->cmp("initialZoom")) {
621 parseInitialZoom(tokens, fileName, line);
622 } else if (!cmd->cmp("continuousView")) {
623 parseYesNo("continuousView", &continuousView, tokens, fileName, line);
624 } else if (!cmd->cmp("enableT1lib")) {
625 parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
626 } else if (!cmd->cmp("enableFreeType")) {
627 parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
628 } else if (!cmd->cmp("antialias")) {
629 parseYesNo("antialias", &antialias, tokens, fileName, line);
630 } else if (!cmd->cmp("urlCommand")) {
631 parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
632 } else if (!cmd->cmp("movieCommand")) {
633 parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
634 } else if (!cmd->cmp("mapNumericCharNames")) {
635 parseYesNo("mapNumericCharNames", &mapNumericCharNames,
636 tokens, fileName, line);
637 } else if (!cmd->cmp("printCommands")) {
638 parseYesNo("printCommands", &printCommands, tokens, fileName, line);
639 } else if (!cmd->cmp("errQuiet")) {
640 parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
642 error(-1, "Unknown config file command '%s' (%s:%d)",
643 cmd->getCString(), fileName->getCString(), line);
644 if (!cmd->cmp("displayFontX") ||
645 !cmd->cmp("displayNamedCIDFontX") ||
646 !cmd->cmp("displayCIDFontX")) {
647 error(-1, "-- Xpdf no longer supports X fonts");
648 } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
649 error(-1, "-- The t1libControl and freetypeControl options have been replaced");
650 error(-1, " by the enableT1lib, enableFreeType, and antialias options");
651 } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
652 error(-1, "-- the config file format has changed since Xpdf 0.9x");
657 deleteGList(tokens, GString);
662 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
671 if (tokens->getLength() != 2) {
672 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
673 fileName->getCString(), line);
676 name = (GString *)tokens->get(1);
677 if (!(f = fopen(name->getCString(), "r"))) {
678 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
683 while (getLine(buf, sizeof(buf), f)) {
684 tok1 = strtok(buf, " \t\r\n");
685 tok2 = strtok(NULL, " \t\r\n");
687 sscanf(tok1, "%x", &u);
688 nameToUnicode->add(tok2, u);
690 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
697 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
699 GString *collection, *name, *old;
701 if (tokens->getLength() != 3) {
702 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
703 fileName->getCString(), line);
706 collection = (GString *)tokens->get(1);
707 name = (GString *)tokens->get(2);
708 if ((old = (GString *)cidToUnicodes->remove(collection))) {
711 cidToUnicodes->add(collection->copy(), name->copy());
714 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
716 GString *font, *file, *old;
718 if (tokens->getLength() != 3) {
719 error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
720 fileName->getCString(), line);
723 font = (GString *)tokens->get(1);
724 file = (GString *)tokens->get(2);
725 if ((old = (GString *)unicodeToUnicodes->remove(font))) {
728 unicodeToUnicodes->add(font->copy(), file->copy());
731 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
733 GString *encodingName, *name, *old;
735 if (tokens->getLength() != 3) {
736 error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
737 fileName->getCString(), line);
740 encodingName = (GString *)tokens->get(1);
741 name = (GString *)tokens->get(2);
742 if ((old = (GString *)unicodeMaps->remove(encodingName))) {
745 unicodeMaps->add(encodingName->copy(), name->copy());
748 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
749 GString *collection, *dir;
752 if (tokens->getLength() != 3) {
753 error(-1, "Bad 'cMapDir' config file command (%s:%d)",
754 fileName->getCString(), line);
757 collection = (GString *)tokens->get(1);
758 dir = (GString *)tokens->get(2);
759 if (!(list = (GList *)cMapDirs->lookup(collection))) {
761 cMapDirs->add(collection->copy(), list);
763 list->append(dir->copy());
766 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
768 if (tokens->getLength() != 2) {
769 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
770 fileName->getCString(), line);
773 toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
776 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
777 DisplayFontParamKind kind,
778 GString *fileName, int line) {
779 DisplayFontParam *param, *old;
781 if (tokens->getLength() < 2) {
784 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
788 if (tokens->getLength() != 3) {
791 param->t1.fileName = ((GString *)tokens->get(2))->copy();
794 if (tokens->getLength() != 3) {
797 param->tt.fileName = ((GString *)tokens->get(2))->copy();
801 if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
804 fontHash->add(param->name, param);
810 error(-1, "Bad 'display*Font*' config file command (%s:%d)",
811 fileName->getCString(), line);
814 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
818 if (tokens->getLength() == 2) {
819 tok = (GString *)tokens->get(1);
820 if (!setPSPaperSize(tok->getCString())) {
821 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
822 fileName->getCString(), line);
824 } else if (tokens->getLength() == 3) {
825 tok = (GString *)tokens->get(1);
826 psPaperWidth = atoi(tok->getCString());
827 tok = (GString *)tokens->get(2);
828 psPaperHeight = atoi(tok->getCString());
829 psImageableLLX = psImageableLLY = 0;
830 psImageableURX = psPaperWidth;
831 psImageableURY = psPaperHeight;
833 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
834 fileName->getCString(), line);
838 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
840 if (tokens->getLength() != 5) {
841 error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
842 fileName->getCString(), line);
845 psImageableLLX = atoi(((GString *)tokens->get(1))->getCString());
846 psImageableLLY = atoi(((GString *)tokens->get(2))->getCString());
847 psImageableURX = atoi(((GString *)tokens->get(3))->getCString());
848 psImageableURY = atoi(((GString *)tokens->get(4))->getCString());
851 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
854 if (tokens->getLength() != 2) {
855 error(-1, "Bad 'psLevel' config file command (%s:%d)",
856 fileName->getCString(), line);
859 tok = (GString *)tokens->get(1);
860 if (!tok->cmp("level1")) {
862 } else if (!tok->cmp("level1sep")) {
863 psLevel = psLevel1Sep;
864 } else if (!tok->cmp("level2")) {
866 } else if (!tok->cmp("level2sep")) {
867 psLevel = psLevel2Sep;
868 } else if (!tok->cmp("level3")) {
870 } else if (!tok->cmp("level3Sep")) {
871 psLevel = psLevel3Sep;
873 error(-1, "Bad 'psLevel' config file command (%s:%d)",
874 fileName->getCString(), line);
878 void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
879 if (tokens->getLength() != 2) {
880 error(-1, "Bad 'psFile' config file command (%s:%d)",
881 fileName->getCString(), line);
887 psFile = ((GString *)tokens->get(1))->copy();
890 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
893 if (tokens->getLength() != 3) {
894 error(-1, "Bad 'psFont' config file command (%s:%d)",
895 fileName->getCString(), line);
898 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
899 ((GString *)tokens->get(2))->copy(), NULL);
900 psFonts->add(param->pdfFontName, param);
903 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
904 GList *tokens, GString *fileName, int line) {
909 if (tokens->getLength() != 5) {
910 error(-1, "Bad '%s' config file command (%s:%d)",
911 cmdName, fileName->getCString(), line);
914 tok = (GString *)tokens->get(2);
915 if (!tok->cmp("H")) {
917 } else if (!tok->cmp("V")) {
920 error(-1, "Bad '%s' config file command (%s:%d)",
921 cmdName, fileName->getCString(), line);
924 param = new PSFontParam(((GString *)tokens->get(1))->copy(),
926 ((GString *)tokens->get(3))->copy(),
927 ((GString *)tokens->get(4))->copy());
928 fontList->append(param);
931 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
933 if (tokens->getLength() != 2) {
934 error(-1, "Bad 'textEncoding' config file command (%s:%d)",
935 fileName->getCString(), line);
939 textEncoding = ((GString *)tokens->get(1))->copy();
942 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
945 if (tokens->getLength() != 2) {
946 error(-1, "Bad 'textEOL' config file command (%s:%d)",
947 fileName->getCString(), line);
950 tok = (GString *)tokens->get(1);
951 if (!tok->cmp("unix")) {
953 } else if (!tok->cmp("dos")) {
955 } else if (!tok->cmp("mac")) {
958 error(-1, "Bad 'textEOL' config file command (%s:%d)",
959 fileName->getCString(), line);
963 void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
964 if (tokens->getLength() != 2) {
965 error(-1, "Bad 'fontDir' config file command (%s:%d)",
966 fileName->getCString(), line);
969 fontDirs->append(((GString *)tokens->get(1))->copy());
972 void GlobalParams::parseInitialZoom(GList *tokens,
973 GString *fileName, int line) {
974 if (tokens->getLength() != 2) {
975 error(-1, "Bad 'initialZoom' config file command (%s:%d)",
976 fileName->getCString(), line);
980 initialZoom = ((GString *)tokens->get(1))->copy();
983 void GlobalParams::parseCommand(char *cmdName, GString **val,
984 GList *tokens, GString *fileName, int line) {
985 if (tokens->getLength() != 2) {
986 error(-1, "Bad '%s' config file command (%s:%d)",
987 cmdName, fileName->getCString(), line);
993 *val = ((GString *)tokens->get(1))->copy();
996 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
997 GList *tokens, GString *fileName, int line) {
1000 if (tokens->getLength() != 2) {
1001 error(-1, "Bad '%s' config file command (%s:%d)",
1002 cmdName, fileName->getCString(), line);
1005 tok = (GString *)tokens->get(1);
1006 if (!parseYesNo2(tok->getCString(), flag)) {
1007 error(-1, "Bad '%s' config file command (%s:%d)",
1008 cmdName, fileName->getCString(), line);
1012 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
1013 if (!strcmp(token, "yes")) {
1015 } else if (!strcmp(token, "no")) {
1023 GlobalParams::~GlobalParams() {
1028 freeBuiltinFontTables();
1030 delete macRomanReverseMap;
1033 delete nameToUnicode;
1034 deleteGHash(cidToUnicodes, GString);
1035 deleteGHash(unicodeToUnicodes, GString);
1036 deleteGHash(residentUnicodeMaps, UnicodeMap);
1037 deleteGHash(unicodeMaps, GString);
1038 deleteGList(toUnicodeDirs, GString);
1039 deleteGHash(displayFonts, DisplayFontParam);
1040 deleteGHash(displayCIDFonts, DisplayFontParam);
1041 deleteGHash(displayNamedCIDFonts, DisplayFontParam);
1045 deleteGHash(psFonts, PSFontParam);
1046 deleteGList(psNamedFonts16, PSFontParam);
1047 deleteGList(psFonts16, PSFontParam);
1048 delete textEncoding;
1049 deleteGList(fontDirs, GString);
1055 delete movieCommand;
1058 cMapDirs->startIter(&iter);
1059 while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
1060 deleteGList(list, GString);
1064 delete cidToUnicodeCache;
1065 delete unicodeToUnicodeCache;
1066 delete unicodeMapCache;
1069 #ifdef ENABLE_PLUGINS
1070 delete securityHandlers;
1071 deleteGList(plugins, Plugin);
1075 gDestroyMutex(&mutex);
1076 gDestroyMutex(&unicodeMapCacheMutex);
1077 gDestroyMutex(&cMapCacheMutex);
1081 //------------------------------------------------------------------------
1083 void GlobalParams::setBaseDir(char *dir) {
1085 baseDir = new GString(dir);
1088 void GlobalParams::setupBaseFonts(char *dir) {
1093 BOOL (__stdcall *SHGetSpecialFolderPathFunc)(HWND hwndOwner,
1097 char winFontDir[MAX_PATH];
1100 DisplayFontParamKind kind;
1101 DisplayFontParam *dfp;
1105 // SHGetSpecialFolderPath isn't available in older versions of
1106 // shell32.dll (Win95 and WinNT4), so do a dynamic load
1107 winFontDir[0] = '\0';
1108 if ((shell32Lib = LoadLibrary("shell32.dll"))) {
1109 if ((SHGetSpecialFolderPathFunc =
1110 (BOOL (__stdcall *)(HWND hwndOwner, LPTSTR lpszPath,
1111 int nFolder, BOOL fCreate))
1112 GetProcAddress(shell32Lib, "SHGetSpecialFolderPath"))) {
1113 if (!(*SHGetSpecialFolderPathFunc)(NULL, winFontDir,
1114 CSIDL_FONTS, FALSE)) {
1115 winFontDir[0] = '\0';
1120 for (i = 0; displayFontTab[i].name; ++i) {
1121 fontName = new GString(displayFontTab[i].name);
1122 if (getDisplayFont(fontName)) {
1127 kind = displayFontT1; // make gcc happy
1129 fileName = appendToPath(new GString(dir), displayFontTab[i].t1FileName);
1130 kind = displayFontT1;
1131 if ((f = fopen(fileName->getCString(), "rb"))) {
1139 if (!fileName && winFontDir[0] && displayFontTab[i].ttFileName) {
1140 fileName = appendToPath(new GString(winFontDir),
1141 displayFontTab[i].ttFileName);
1142 kind = displayFontTT;
1143 if ((f = fopen(fileName->getCString(), "rb"))) {
1150 // SHGetSpecialFolderPath(CSIDL_FONTS) doesn't work on Win 2k Server
1151 // or Win2003 Server, or with older versions of shell32.dll, so check
1152 // the "standard" directories
1153 if (displayFontTab[i].ttFileName) {
1154 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
1155 fileName = appendToPath(new GString(displayFontDirs[j]),
1156 displayFontTab[i].ttFileName);
1157 kind = displayFontTT;
1158 if ((f = fopen(fileName->getCString(), "rb"))) {
1167 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
1168 fileName = appendToPath(new GString(displayFontDirs[j]),
1169 displayFontTab[i].t1FileName);
1170 kind = displayFontT1;
1171 if ((f = fopen(fileName->getCString(), "rb"))) {
1180 error(-1, "No display font for '%s'", displayFontTab[i].name);
1184 dfp = new DisplayFontParam(fontName, kind);
1185 dfp->t1.fileName = fileName;
1186 globalParams->addDisplayFont(dfp);
1190 //------------------------------------------------------------------------
1192 //------------------------------------------------------------------------
1194 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
1195 // no need to lock - macRomanReverseMap is constant
1196 return macRomanReverseMap->lookup(charName);
1199 GString *GlobalParams::getBaseDir() {
1203 s = baseDir->copy();
1208 Unicode GlobalParams::mapNameToUnicode(char *charName) {
1209 // no need to lock - nameToUnicode is constant
1210 return nameToUnicode->lookup(charName);
1213 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
1217 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1225 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
1230 if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
1231 f = fopen(fileName->getCString(), "r");
1239 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
1247 if (!(list = (GList *)cMapDirs->lookup(collection))) {
1251 for (i = 0; i < list->getLength(); ++i) {
1252 dir = (GString *)list->get(i);
1253 fileName = appendToPath(dir->copy(), cMapName->getCString());
1254 f = fopen(fileName->getCString(), "r");
1265 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1266 GString *dir, *fileName;
1271 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1272 dir = (GString *)toUnicodeDirs->get(i);
1273 fileName = appendToPath(dir->copy(), name->getCString());
1274 f = fopen(fileName->getCString(), "r");
1285 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1286 DisplayFontParam *dfp;
1289 dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1294 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1295 GString *collection) {
1296 DisplayFontParam *dfp;
1300 !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1301 dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1307 GString *GlobalParams::getPSFile() {
1311 s = psFile ? psFile->copy() : (GString *)NULL;
1316 int GlobalParams::getPSPaperWidth() {
1325 int GlobalParams::getPSPaperHeight() {
1334 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1336 *llx = psImageableLLX;
1337 *lly = psImageableLLY;
1338 *urx = psImageableURX;
1339 *ury = psImageableURY;
1343 GBool GlobalParams::getPSCrop() {
1352 GBool GlobalParams::getPSExpandSmaller() {
1356 f = psExpandSmaller;
1361 GBool GlobalParams::getPSShrinkLarger() {
1370 GBool GlobalParams::getPSCenter() {
1379 GBool GlobalParams::getPSDuplex() {
1388 PSLevel GlobalParams::getPSLevel() {
1397 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1401 p = (PSFontParam *)psFonts->lookup(fontName);
1406 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1407 GString *collection, int wMode) {
1414 for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1415 p = (PSFontParam *)psNamedFonts16->get(i);
1416 if (!p->pdfFontName->cmp(fontName) &&
1417 p->wMode == wMode) {
1423 if (!p && collection) {
1424 for (i = 0; i < psFonts16->getLength(); ++i) {
1425 p = (PSFontParam *)psFonts16->get(i);
1426 if (!p->pdfFontName->cmp(collection) &&
1427 p->wMode == wMode) {
1437 GBool GlobalParams::getPSEmbedType1() {
1446 GBool GlobalParams::getPSEmbedTrueType() {
1450 e = psEmbedTrueType;
1455 GBool GlobalParams::getPSEmbedCIDPostScript() {
1459 e = psEmbedCIDPostScript;
1464 GBool GlobalParams::getPSEmbedCIDTrueType() {
1468 e = psEmbedCIDTrueType;
1473 GBool GlobalParams::getPSOPI() {
1482 GBool GlobalParams::getPSASCIIHex() {
1491 GString *GlobalParams::getTextEncodingName() {
1495 s = textEncoding->copy();
1500 EndOfLineKind GlobalParams::getTextEOL() {
1509 GBool GlobalParams::getTextPageBreaks() {
1513 pageBreaks = textPageBreaks;
1518 GBool GlobalParams::getTextKeepTinyChars() {
1522 tiny = textKeepTinyChars;
1527 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1528 GString *dir, *fileName;
1534 for (i = 0; i < fontDirs->getLength(); ++i) {
1535 dir = (GString *)fontDirs->get(i);
1536 for (ext = exts; *ext; ++ext) {
1537 fileName = appendToPath(dir->copy(), fontName->getCString());
1538 fileName->append(*ext);
1539 if ((f = fopen(fileName->getCString(), "rb"))) {
1551 GString *GlobalParams::getInitialZoom() {
1555 s = initialZoom->copy();
1560 GBool GlobalParams::getContinuousView() {
1569 GBool GlobalParams::getEnableT1lib() {
1578 GBool GlobalParams::getEnableFreeType() {
1588 GBool GlobalParams::getAntialias() {
1597 GBool GlobalParams::getMapNumericCharNames() {
1601 map = mapNumericCharNames;
1606 GBool GlobalParams::getPrintCommands() {
1615 GBool GlobalParams::getErrQuiet() {
1624 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1626 CharCodeToUnicode *ctu;
1629 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1630 if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1631 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1632 cidToUnicodeCache->add(ctu);
1639 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1640 CharCodeToUnicode *ctu;
1642 GString *fontPattern, *fileName;
1646 unicodeToUnicodes->startIter(&iter);
1647 while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1648 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1649 unicodeToUnicodes->killIter(&iter);
1655 if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1656 if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1657 unicodeToUnicodeCache->add(ctu);
1667 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1668 return getUnicodeMap2(encodingName);
1671 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1674 if (!(map = getResidentUnicodeMap(encodingName))) {
1675 lockUnicodeMapCache;
1676 map = unicodeMapCache->getUnicodeMap(encodingName);
1677 unlockUnicodeMapCache;
1682 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1686 cMap = cMapCache->getCMap(collection, cMapName);
1691 UnicodeMap *GlobalParams::getTextEncoding() {
1692 return getUnicodeMap2(textEncoding);
1695 //------------------------------------------------------------------------
1696 // functions to set parameters
1697 //------------------------------------------------------------------------
1699 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1700 DisplayFontParam *old;
1703 if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1706 displayFonts->add(param->name, param);
1710 void GlobalParams::setPSFile(char *file) {
1715 psFile = new GString(file);
1719 GBool GlobalParams::setPSPaperSize(char *size) {
1721 if (!strcmp(size, "match")) {
1722 psPaperWidth = psPaperHeight = -1;
1723 } else if (!strcmp(size, "letter")) {
1725 psPaperHeight = 792;
1726 } else if (!strcmp(size, "legal")) {
1728 psPaperHeight = 1008;
1729 } else if (!strcmp(size, "A4")) {
1731 psPaperHeight = 842;
1732 } else if (!strcmp(size, "A3")) {
1734 psPaperHeight = 1190;
1739 psImageableLLX = psImageableLLY = 0;
1740 psImageableURX = psPaperWidth;
1741 psImageableURY = psPaperHeight;
1746 void GlobalParams::setPSPaperWidth(int width) {
1748 psPaperWidth = width;
1750 psImageableURX = psPaperWidth;
1754 void GlobalParams::setPSPaperHeight(int height) {
1756 psPaperHeight = height;
1758 psImageableURY = psPaperHeight;
1762 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1764 psImageableLLX = llx;
1765 psImageableLLY = lly;
1766 psImageableURX = urx;
1767 psImageableURY = ury;
1771 void GlobalParams::setPSCrop(GBool crop) {
1777 void GlobalParams::setPSExpandSmaller(GBool expand) {
1779 psExpandSmaller = expand;
1783 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1785 psShrinkLarger = shrink;
1789 void GlobalParams::setPSCenter(GBool center) {
1795 void GlobalParams::setPSDuplex(GBool duplex) {
1801 void GlobalParams::setPSLevel(PSLevel level) {
1807 void GlobalParams::setPSEmbedType1(GBool embed) {
1809 psEmbedType1 = embed;
1813 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1815 psEmbedTrueType = embed;
1819 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1821 psEmbedCIDPostScript = embed;
1825 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1827 psEmbedCIDTrueType = embed;
1831 void GlobalParams::setPSOPI(GBool opi) {
1837 void GlobalParams::setPSASCIIHex(GBool hex) {
1843 void GlobalParams::setTextEncoding(char *encodingName) {
1845 delete textEncoding;
1846 textEncoding = new GString(encodingName);
1850 GBool GlobalParams::setTextEOL(char *s) {
1852 if (!strcmp(s, "unix")) {
1854 } else if (!strcmp(s, "dos")) {
1856 } else if (!strcmp(s, "mac")) {
1866 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1868 textPageBreaks = pageBreaks;
1872 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1874 textKeepTinyChars = keep;
1878 void GlobalParams::setInitialZoom(char *s) {
1881 initialZoom = new GString(s);
1885 void GlobalParams::setContinuousView(GBool cont) {
1887 continuousView = cont;
1891 GBool GlobalParams::setEnableT1lib(char *s) {
1895 ok = parseYesNo2(s, &enableT1lib);
1900 GBool GlobalParams::setEnableFreeType(char *s) {
1904 ok = parseYesNo2(s, &enableFreeType);
1910 GBool GlobalParams::setAntialias(char *s) {
1914 ok = parseYesNo2(s, &antialias);
1919 void GlobalParams::setMapNumericCharNames(GBool map) {
1921 mapNumericCharNames = map;
1925 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1927 printCommands = printCommandsA;
1931 void GlobalParams::setErrQuiet(GBool errQuietA) {
1933 errQuiet = errQuietA;
1937 void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1938 #ifdef ENABLE_PLUGINS
1940 securityHandlers->append(handler);
1945 XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1946 #ifdef ENABLE_PLUGINS
1947 XpdfSecurityHandler *hdlr;
1951 for (i = 0; i < securityHandlers->getLength(); ++i) {
1952 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1953 if (!stricmp(hdlr->name, name)) {
1960 if (!loadPlugin("security", name)) {
1965 for (i = 0; i < securityHandlers->getLength(); ++i) {
1966 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1967 if (!strcmp(hdlr->name, name)) {
1978 #ifdef ENABLE_PLUGINS
1979 //------------------------------------------------------------------------
1981 //------------------------------------------------------------------------
1983 GBool GlobalParams::loadPlugin(char *type, char *name) {
1986 if (!(plugin = Plugin::load(type, name))) {
1990 plugins->append(plugin);
1995 #endif // ENABLE_PLUGINS