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;
503 char* cfgFileName = fileName->getCString();
504 char* pos1 = strrchr(cfgFileName, '/');
505 char* pos2 = strrchr(cfgFileName, '\\');
506 char* p = pos1>pos2?pos1:pos2;
507 int pos = p ? p-cfgFileName : -1;
508 GString*path = new GString(new GString(cfgFileName), 0, (pos < 0 ? strlen(cfgFileName): pos));
521 this->path = new GString();
525 while (getLine(buf, sizeof(buf) - 1, f)) {
527 // break the line into tokens
528 tokens = new GList();
531 for (; *p1 && isspace(*p1); ++p1) ;
535 if (*p1 == '"' || *p1 == '\'') {
536 for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
539 for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
541 tokens->append(new GString(p1, p2 - p1));
542 p1 = *p2 ? p2 + 1 : p2;
545 if (tokens->getLength() > 0 &&
546 ((GString *)tokens->get(0))->getChar(0) != '#') {
547 cmd = (GString *)tokens->get(0);
548 if (!cmd->cmp("include")) {
549 if (tokens->getLength() == 2) {
550 incFile = (GString *)tokens->get(1);
551 if ((f2 = fopen(incFile->getCString(), "r"))) {
552 parseFile(incFile, f2);
555 error(-1, "Couldn't find included config file: '%s' (%s:%d)",
556 incFile->getCString(), fileName->getCString(), line);
559 error(-1, "Bad 'include' config file command (%s:%d)",
560 fileName->getCString(), line);
562 } else if (!cmd->cmp("nameToUnicode")) {
563 parseNameToUnicode(tokens, fileName, line);
564 } else if (!cmd->cmp("cidToUnicode")) {
565 parseCIDToUnicode(tokens, fileName, line);
566 } else if (!cmd->cmp("unicodeToUnicode")) {
567 parseUnicodeToUnicode(tokens, fileName, line);
568 } else if (!cmd->cmp("unicodeMap")) {
569 parseUnicodeMap(tokens, fileName, line);
570 } else if (!cmd->cmp("cMapDir")) {
571 parseCMapDir(tokens, fileName, line);
572 } else if (!cmd->cmp("toUnicodeDir")) {
573 parseToUnicodeDir(tokens, fileName, line);
574 } else if (!cmd->cmp("displayFontT1")) {
575 parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
576 } else if (!cmd->cmp("displayFontTT")) {
577 parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
578 } else if (!cmd->cmp("displayNamedCIDFontT1")) {
579 parseDisplayFont(tokens, displayNamedCIDFonts,
580 displayFontT1, fileName, line);
581 } else if (!cmd->cmp("displayCIDFontT1")) {
582 parseDisplayFont(tokens, displayCIDFonts,
583 displayFontT1, fileName, line);
584 } else if (!cmd->cmp("displayNamedCIDFontTT")) {
585 parseDisplayFont(tokens, displayNamedCIDFonts,
586 displayFontTT, fileName, line);
587 } else if (!cmd->cmp("displayCIDFontTT")) {
588 parseDisplayFont(tokens, displayCIDFonts,
589 displayFontTT, fileName, line);
590 } else if (!cmd->cmp("psFile")) {
591 parsePSFile(tokens, fileName, line);
592 } else if (!cmd->cmp("psFont")) {
593 parsePSFont(tokens, fileName, line);
594 } else if (!cmd->cmp("psNamedFont16")) {
595 parsePSFont16("psNamedFont16", psNamedFonts16,
596 tokens, fileName, line);
597 } else if (!cmd->cmp("psFont16")) {
598 parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
599 } else if (!cmd->cmp("psPaperSize")) {
600 parsePSPaperSize(tokens, fileName, line);
601 } else if (!cmd->cmp("psImageableArea")) {
602 parsePSImageableArea(tokens, fileName, line);
603 } else if (!cmd->cmp("psCrop")) {
604 parseYesNo("psCrop", &psCrop, tokens, fileName, line);
605 } else if (!cmd->cmp("psExpandSmaller")) {
606 parseYesNo("psExpandSmaller", &psExpandSmaller,
607 tokens, fileName, line);
608 } else if (!cmd->cmp("psShrinkLarger")) {
609 parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
610 } else if (!cmd->cmp("psCenter")) {
611 parseYesNo("psCenter", &psCenter, tokens, fileName, line);
612 } else if (!cmd->cmp("psDuplex")) {
613 parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
614 } else if (!cmd->cmp("psLevel")) {
615 parsePSLevel(tokens, fileName, line);
616 } else if (!cmd->cmp("psEmbedType1Fonts")) {
617 parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
618 } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
619 parseYesNo("psEmbedTrueType", &psEmbedTrueType,
620 tokens, fileName, line);
621 } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
622 parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
623 tokens, fileName, line);
624 } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
625 parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
626 tokens, fileName, line);
627 } else if (!cmd->cmp("psOPI")) {
628 parseYesNo("psOPI", &psOPI, tokens, fileName, line);
629 } else if (!cmd->cmp("psASCIIHex")) {
630 parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
631 } else if (!cmd->cmp("textEncoding")) {
632 parseTextEncoding(tokens, fileName, line);
633 } else if (!cmd->cmp("textEOL")) {
634 parseTextEOL(tokens, fileName, line);
635 } else if (!cmd->cmp("textPageBreaks")) {
636 parseYesNo("textPageBreaks", &textPageBreaks,
637 tokens, fileName, line);
638 } else if (!cmd->cmp("textKeepTinyChars")) {
639 parseYesNo("textKeepTinyChars", &textKeepTinyChars,
640 tokens, fileName, line);
641 } else if (!cmd->cmp("fontDir")) {
642 parseFontDir(tokens, fileName, line);
643 } else if (!cmd->cmp("initialZoom")) {
644 parseInitialZoom(tokens, fileName, line);
645 } else if (!cmd->cmp("continuousView")) {
646 parseYesNo("continuousView", &continuousView, tokens, fileName, line);
647 } else if (!cmd->cmp("enableT1lib")) {
648 parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
649 } else if (!cmd->cmp("enableFreeType")) {
650 parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
651 } else if (!cmd->cmp("antialias")) {
652 parseYesNo("antialias", &antialias, tokens, fileName, line);
653 } else if (!cmd->cmp("urlCommand")) {
654 parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
655 } else if (!cmd->cmp("movieCommand")) {
656 parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
657 } else if (!cmd->cmp("mapNumericCharNames")) {
658 parseYesNo("mapNumericCharNames", &mapNumericCharNames,
659 tokens, fileName, line);
660 } else if (!cmd->cmp("printCommands")) {
661 parseYesNo("printCommands", &printCommands, tokens, fileName, line);
662 } else if (!cmd->cmp("errQuiet")) {
663 parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
665 error(-1, "Unknown config file command '%s' (%s:%d)",
666 cmd->getCString(), fileName->getCString(), line);
667 if (!cmd->cmp("displayFontX") ||
668 !cmd->cmp("displayNamedCIDFontX") ||
669 !cmd->cmp("displayCIDFontX")) {
670 error(-1, "-- Xpdf no longer supports X fonts");
671 } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
672 error(-1, "-- The t1libControl and freetypeControl options have been replaced");
673 error(-1, " by the enableT1lib, enableFreeType, and antialias options");
674 } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
675 error(-1, "-- the config file format has changed since Xpdf 0.9x");
680 deleteGList(tokens, GString);
685 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
694 if (tokens->getLength() != 2) {
695 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
696 fileName->getCString(), line);
699 name = (GString *)tokens->get(1);
700 if (!(f = fopen(name->getCString(), "r"))) {
701 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
706 while (getLine(buf, sizeof(buf), f)) {
707 tok1 = strtok(buf, " \t\r\n");
708 tok2 = strtok(NULL, " \t\r\n");
710 sscanf(tok1, "%x", &u);
711 nameToUnicode->add(tok2, u);
713 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
720 static GString* qualify_filename(GString*path, GString*filename)
722 GString*fullpath = 0;
723 char*prefix = "/usr/local/share/xpdf/";
725 if (filename->getChar(0) != '\\' && filename->getChar(0) != '/') {
727 fullpath = path->copy();
728 fullpath->append(filename);
729 } else if (!strncmp(filename->getCString(), prefix, strlen(prefix))) {
730 /* xpdf default path */
731 char*s = strchr(filename->getCString()+strlen(prefix), '/');
733 fullpath = path->copy();
734 fullpath->append(s+1);
736 fullpath = filename->copy();
740 fullpath = filename->copy();
742 printf("%s -%s-> %s\n", filename->getCString(), path->getCString(), fullpath->getCString());
746 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
748 GString *collection, *name, *old;
750 if (tokens->getLength() != 3) {
751 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
752 fileName->getCString(), line);
755 collection = (GString *)tokens->get(1);
756 name = (GString *)tokens->get(2);
758 if ((old = (GString *)cidToUnicodes->remove(collection))) {
762 cidToUnicodes->add(collection->copy(), qualify_filename(this->path, name));
765 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
767 GString *font, *file, *old;
769 if (tokens->getLength() != 3) {
770 error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
771 fileName->getCString(), line);
774 font = (GString *)tokens->get(1);
775 file = (GString *)tokens->get(2);
776 if ((old = (GString *)unicodeToUnicodes->remove(font))) {
780 unicodeToUnicodes->add(font->copy(), qualify_filename(this->path, file));
783 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
785 GString *encodingName, *name, *old;
787 if (tokens->getLength() != 3) {
788 error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
789 fileName->getCString(), line);
792 encodingName = (GString *)tokens->get(1);
793 name = (GString *)tokens->get(2);
794 if ((old = (GString *)unicodeMaps->remove(encodingName))) {
798 unicodeMaps->add(encodingName->copy(), qualify_filename(this->path, name));
801 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
802 GString *collection, *dir;
805 if (tokens->getLength() != 3) {
806 error(-1, "Bad 'cMapDir' config file command (%s:%d)",
807 fileName->getCString(), line);
810 collection = (GString *)tokens->get(1);
811 dir = (GString *)tokens->get(2);
812 if (!(list = (GList *)cMapDirs->lookup(collection))) {
814 cMapDirs->add(collection->copy(), list);
817 list->append(qualify_filename(this->path, dir));
820 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
824 if (tokens->getLength() != 2) {
825 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
826 fileName->getCString(), line);
830 dir = (GString *)tokens->get(1);
832 toUnicodeDirs->append(qualify_filename(this->path, dir));
835 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
836 DisplayFontParamKind kind,
837 GString *fileName, int line) {
838 DisplayFontParam *param, *old;
841 if (tokens->getLength() < 2) {
844 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
848 if (tokens->getLength() != 3) {
851 file = (GString *)tokens->get(2);
852 param->t1.fileName = qualify_filename(this->path, file);
855 if (tokens->getLength() != 3) {
858 file = (GString *)tokens->get(2);
859 param->tt.fileName = qualify_filename(this->path, file);
863 if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
866 fontHash->add(param->name, param);
872 error(-1, "Bad 'display*Font*' config file command (%s:%d)",
873 fileName->getCString(), line);
876 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
880 if (tokens->getLength() == 2) {
881 tok = (GString *)tokens->get(1);
882 if (!setPSPaperSize(tok->getCString())) {
883 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
884 fileName->getCString(), line);
886 } else if (tokens->getLength() == 3) {
887 tok = (GString *)tokens->get(1);
888 psPaperWidth = atoi(tok->getCString());
889 tok = (GString *)tokens->get(2);
890 psPaperHeight = atoi(tok->getCString());
891 psImageableLLX = psImageableLLY = 0;
892 psImageableURX = psPaperWidth;
893 psImageableURY = psPaperHeight;
895 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
896 fileName->getCString(), line);
900 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
902 if (tokens->getLength() != 5) {
903 error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
904 fileName->getCString(), line);
907 psImageableLLX = atoi(((GString *)tokens->get(1))->getCString());
908 psImageableLLY = atoi(((GString *)tokens->get(2))->getCString());
909 psImageableURX = atoi(((GString *)tokens->get(3))->getCString());
910 psImageableURY = atoi(((GString *)tokens->get(4))->getCString());
913 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
916 if (tokens->getLength() != 2) {
917 error(-1, "Bad 'psLevel' config file command (%s:%d)",
918 fileName->getCString(), line);
921 tok = (GString *)tokens->get(1);
922 if (!tok->cmp("level1")) {
924 } else if (!tok->cmp("level1sep")) {
925 psLevel = psLevel1Sep;
926 } else if (!tok->cmp("level2")) {
928 } else if (!tok->cmp("level2sep")) {
929 psLevel = psLevel2Sep;
930 } else if (!tok->cmp("level3")) {
932 } else if (!tok->cmp("level3Sep")) {
933 psLevel = psLevel3Sep;
935 error(-1, "Bad 'psLevel' config file command (%s:%d)",
936 fileName->getCString(), line);
940 void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
941 if (tokens->getLength() != 2) {
942 error(-1, "Bad 'psFile' config file command (%s:%d)",
943 fileName->getCString(), line);
949 psFile = ((GString *)tokens->get(1))->copy();
952 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
955 if (tokens->getLength() != 3) {
956 error(-1, "Bad 'psFont' config file command (%s:%d)",
957 fileName->getCString(), line);
960 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
961 ((GString *)tokens->get(2))->copy(), NULL);
962 psFonts->add(param->pdfFontName, param);
965 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
966 GList *tokens, GString *fileName, int line) {
971 if (tokens->getLength() != 5) {
972 error(-1, "Bad '%s' config file command (%s:%d)",
973 cmdName, fileName->getCString(), line);
976 tok = (GString *)tokens->get(2);
977 if (!tok->cmp("H")) {
979 } else if (!tok->cmp("V")) {
982 error(-1, "Bad '%s' config file command (%s:%d)",
983 cmdName, fileName->getCString(), line);
986 param = new PSFontParam(((GString *)tokens->get(1))->copy(),
988 ((GString *)tokens->get(3))->copy(),
989 ((GString *)tokens->get(4))->copy());
990 fontList->append(param);
993 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
995 if (tokens->getLength() != 2) {
996 error(-1, "Bad 'textEncoding' config file command (%s:%d)",
997 fileName->getCString(), line);
1000 delete textEncoding;
1001 textEncoding = ((GString *)tokens->get(1))->copy();
1004 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
1007 if (tokens->getLength() != 2) {
1008 error(-1, "Bad 'textEOL' config file command (%s:%d)",
1009 fileName->getCString(), line);
1012 tok = (GString *)tokens->get(1);
1013 if (!tok->cmp("unix")) {
1015 } else if (!tok->cmp("dos")) {
1017 } else if (!tok->cmp("mac")) {
1020 error(-1, "Bad 'textEOL' config file command (%s:%d)",
1021 fileName->getCString(), line);
1025 void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
1026 if (tokens->getLength() != 2) {
1027 error(-1, "Bad 'fontDir' config file command (%s:%d)",
1028 fileName->getCString(), line);
1031 fontDirs->append(((GString *)tokens->get(1))->copy());
1034 void GlobalParams::parseInitialZoom(GList *tokens,
1035 GString *fileName, int line) {
1036 if (tokens->getLength() != 2) {
1037 error(-1, "Bad 'initialZoom' config file command (%s:%d)",
1038 fileName->getCString(), line);
1042 initialZoom = ((GString *)tokens->get(1))->copy();
1045 void GlobalParams::parseCommand(char *cmdName, GString **val,
1046 GList *tokens, GString *fileName, int line) {
1047 if (tokens->getLength() != 2) {
1048 error(-1, "Bad '%s' config file command (%s:%d)",
1049 cmdName, fileName->getCString(), line);
1055 *val = ((GString *)tokens->get(1))->copy();
1058 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
1059 GList *tokens, GString *fileName, int line) {
1062 if (tokens->getLength() != 2) {
1063 error(-1, "Bad '%s' config file command (%s:%d)",
1064 cmdName, fileName->getCString(), line);
1067 tok = (GString *)tokens->get(1);
1068 if (!parseYesNo2(tok->getCString(), flag)) {
1069 error(-1, "Bad '%s' config file command (%s:%d)",
1070 cmdName, fileName->getCString(), line);
1074 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
1075 if (!strcmp(token, "yes")) {
1077 } else if (!strcmp(token, "no")) {
1085 GlobalParams::~GlobalParams() {
1090 freeBuiltinFontTables();
1092 delete macRomanReverseMap;
1095 delete nameToUnicode;
1096 deleteGHash(cidToUnicodes, GString);
1097 deleteGHash(unicodeToUnicodes, GString);
1098 deleteGHash(residentUnicodeMaps, UnicodeMap);
1099 deleteGHash(unicodeMaps, GString);
1100 deleteGList(toUnicodeDirs, GString);
1101 deleteGHash(displayFonts, DisplayFontParam);
1102 deleteGHash(displayCIDFonts, DisplayFontParam);
1103 deleteGHash(displayNamedCIDFonts, DisplayFontParam);
1107 deleteGHash(psFonts, PSFontParam);
1108 deleteGList(psNamedFonts16, PSFontParam);
1109 deleteGList(psFonts16, PSFontParam);
1110 delete textEncoding;
1111 deleteGList(fontDirs, GString);
1117 delete movieCommand;
1120 cMapDirs->startIter(&iter);
1121 while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
1122 deleteGList(list, GString);
1126 delete cidToUnicodeCache;
1127 delete unicodeToUnicodeCache;
1128 delete unicodeMapCache;
1131 #ifdef ENABLE_PLUGINS
1132 delete securityHandlers;
1133 deleteGList(plugins, Plugin);
1137 gDestroyMutex(&mutex);
1138 gDestroyMutex(&unicodeMapCacheMutex);
1139 gDestroyMutex(&cMapCacheMutex);
1143 //------------------------------------------------------------------------
1145 void GlobalParams::setBaseDir(char *dir) {
1147 baseDir = new GString(dir);
1150 void GlobalParams::setupBaseFonts(char *dir) {
1155 BOOL (__stdcall *SHGetSpecialFolderPathFunc)(HWND hwndOwner,
1159 char winFontDir[MAX_PATH];
1162 DisplayFontParamKind kind;
1163 DisplayFontParam *dfp;
1167 // SHGetSpecialFolderPath isn't available in older versions of
1168 // shell32.dll (Win95 and WinNT4), so do a dynamic load
1169 winFontDir[0] = '\0';
1170 if ((shell32Lib = LoadLibrary("shell32.dll"))) {
1171 if ((SHGetSpecialFolderPathFunc =
1172 (BOOL (__stdcall *)(HWND hwndOwner, LPTSTR lpszPath,
1173 int nFolder, BOOL fCreate))
1174 GetProcAddress(shell32Lib, "SHGetSpecialFolderPath"))) {
1175 if (!(*SHGetSpecialFolderPathFunc)(NULL, winFontDir,
1176 CSIDL_FONTS, FALSE)) {
1177 winFontDir[0] = '\0';
1182 for (i = 0; displayFontTab[i].name; ++i) {
1183 fontName = new GString(displayFontTab[i].name);
1184 if (getDisplayFont(fontName)) {
1189 kind = displayFontT1; // make gcc happy
1191 fileName = appendToPath(new GString(dir), displayFontTab[i].t1FileName);
1192 kind = displayFontT1;
1193 if ((f = fopen(fileName->getCString(), "rb"))) {
1201 if (!fileName && winFontDir[0] && displayFontTab[i].ttFileName) {
1202 fileName = appendToPath(new GString(winFontDir),
1203 displayFontTab[i].ttFileName);
1204 kind = displayFontTT;
1205 if ((f = fopen(fileName->getCString(), "rb"))) {
1212 // SHGetSpecialFolderPath(CSIDL_FONTS) doesn't work on Win 2k Server
1213 // or Win2003 Server, or with older versions of shell32.dll, so check
1214 // the "standard" directories
1215 if (displayFontTab[i].ttFileName) {
1216 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
1217 fileName = appendToPath(new GString(displayFontDirs[j]),
1218 displayFontTab[i].ttFileName);
1219 kind = displayFontTT;
1220 if ((f = fopen(fileName->getCString(), "rb"))) {
1229 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
1230 fileName = appendToPath(new GString(displayFontDirs[j]),
1231 displayFontTab[i].t1FileName);
1232 kind = displayFontT1;
1233 if ((f = fopen(fileName->getCString(), "rb"))) {
1242 error(-1, "No display font for '%s'", displayFontTab[i].name);
1246 dfp = new DisplayFontParam(fontName, kind);
1247 dfp->t1.fileName = fileName;
1248 globalParams->addDisplayFont(dfp);
1252 //------------------------------------------------------------------------
1254 //------------------------------------------------------------------------
1256 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
1257 // no need to lock - macRomanReverseMap is constant
1258 return macRomanReverseMap->lookup(charName);
1261 GString *GlobalParams::getBaseDir() {
1265 s = baseDir->copy();
1270 Unicode GlobalParams::mapNameToUnicode(char *charName) {
1271 // no need to lock - nameToUnicode is constant
1272 return nameToUnicode->lookup(charName);
1275 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
1279 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1287 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
1292 if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
1293 f = fopen(fileName->getCString(), "r");
1301 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
1309 if (!(list = (GList *)cMapDirs->lookup(collection))) {
1313 for (i = 0; i < list->getLength(); ++i) {
1314 dir = (GString *)list->get(i);
1315 fileName = appendToPath(dir->copy(), cMapName->getCString());
1316 f = fopen(fileName->getCString(), "r");
1327 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1328 GString *dir, *fileName;
1333 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1334 dir = (GString *)toUnicodeDirs->get(i);
1335 fileName = appendToPath(dir->copy(), name->getCString());
1336 f = fopen(fileName->getCString(), "r");
1347 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1348 DisplayFontParam *dfp;
1351 dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1356 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1357 GString *collection) {
1358 DisplayFontParam *dfp;
1362 !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1363 dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1369 GString *GlobalParams::getPSFile() {
1373 s = psFile ? psFile->copy() : (GString *)NULL;
1378 int GlobalParams::getPSPaperWidth() {
1387 int GlobalParams::getPSPaperHeight() {
1396 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1398 *llx = psImageableLLX;
1399 *lly = psImageableLLY;
1400 *urx = psImageableURX;
1401 *ury = psImageableURY;
1405 GBool GlobalParams::getPSCrop() {
1414 GBool GlobalParams::getPSExpandSmaller() {
1418 f = psExpandSmaller;
1423 GBool GlobalParams::getPSShrinkLarger() {
1432 GBool GlobalParams::getPSCenter() {
1441 GBool GlobalParams::getPSDuplex() {
1450 PSLevel GlobalParams::getPSLevel() {
1459 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1463 p = (PSFontParam *)psFonts->lookup(fontName);
1468 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1469 GString *collection, int wMode) {
1476 for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1477 p = (PSFontParam *)psNamedFonts16->get(i);
1478 if (!p->pdfFontName->cmp(fontName) &&
1479 p->wMode == wMode) {
1485 if (!p && collection) {
1486 for (i = 0; i < psFonts16->getLength(); ++i) {
1487 p = (PSFontParam *)psFonts16->get(i);
1488 if (!p->pdfFontName->cmp(collection) &&
1489 p->wMode == wMode) {
1499 GBool GlobalParams::getPSEmbedType1() {
1508 GBool GlobalParams::getPSEmbedTrueType() {
1512 e = psEmbedTrueType;
1517 GBool GlobalParams::getPSEmbedCIDPostScript() {
1521 e = psEmbedCIDPostScript;
1526 GBool GlobalParams::getPSEmbedCIDTrueType() {
1530 e = psEmbedCIDTrueType;
1535 GBool GlobalParams::getPSOPI() {
1544 GBool GlobalParams::getPSASCIIHex() {
1553 GString *GlobalParams::getTextEncodingName() {
1557 s = textEncoding->copy();
1562 EndOfLineKind GlobalParams::getTextEOL() {
1571 GBool GlobalParams::getTextPageBreaks() {
1575 pageBreaks = textPageBreaks;
1580 GBool GlobalParams::getTextKeepTinyChars() {
1584 tiny = textKeepTinyChars;
1589 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1590 GString *dir, *fileName;
1596 for (i = 0; i < fontDirs->getLength(); ++i) {
1597 dir = (GString *)fontDirs->get(i);
1598 for (ext = exts; *ext; ++ext) {
1599 fileName = appendToPath(dir->copy(), fontName->getCString());
1600 fileName->append(*ext);
1601 if ((f = fopen(fileName->getCString(), "rb"))) {
1613 GString *GlobalParams::getInitialZoom() {
1617 s = initialZoom->copy();
1622 GBool GlobalParams::getContinuousView() {
1631 GBool GlobalParams::getEnableT1lib() {
1640 GBool GlobalParams::getEnableFreeType() {
1650 GBool GlobalParams::getAntialias() {
1659 GBool GlobalParams::getMapNumericCharNames() {
1663 map = mapNumericCharNames;
1668 GBool GlobalParams::getPrintCommands() {
1677 GBool GlobalParams::getErrQuiet() {
1686 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1688 CharCodeToUnicode *ctu;
1691 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1692 if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1693 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1694 cidToUnicodeCache->add(ctu);
1701 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1702 CharCodeToUnicode *ctu;
1704 GString *fontPattern, *fileName;
1708 unicodeToUnicodes->startIter(&iter);
1709 while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1710 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1711 unicodeToUnicodes->killIter(&iter);
1717 if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1718 if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1719 unicodeToUnicodeCache->add(ctu);
1729 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1730 return getUnicodeMap2(encodingName);
1733 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1736 if (!(map = getResidentUnicodeMap(encodingName))) {
1737 lockUnicodeMapCache;
1738 map = unicodeMapCache->getUnicodeMap(encodingName);
1739 unlockUnicodeMapCache;
1744 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1748 cMap = cMapCache->getCMap(collection, cMapName);
1753 UnicodeMap *GlobalParams::getTextEncoding() {
1754 return getUnicodeMap2(textEncoding);
1757 //------------------------------------------------------------------------
1758 // functions to set parameters
1759 //------------------------------------------------------------------------
1761 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1762 DisplayFontParam *old;
1765 if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1768 displayFonts->add(param->name, param);
1772 void GlobalParams::setPSFile(char *file) {
1777 psFile = new GString(file);
1781 GBool GlobalParams::setPSPaperSize(char *size) {
1783 if (!strcmp(size, "match")) {
1784 psPaperWidth = psPaperHeight = -1;
1785 } else if (!strcmp(size, "letter")) {
1787 psPaperHeight = 792;
1788 } else if (!strcmp(size, "legal")) {
1790 psPaperHeight = 1008;
1791 } else if (!strcmp(size, "A4")) {
1793 psPaperHeight = 842;
1794 } else if (!strcmp(size, "A3")) {
1796 psPaperHeight = 1190;
1801 psImageableLLX = psImageableLLY = 0;
1802 psImageableURX = psPaperWidth;
1803 psImageableURY = psPaperHeight;
1808 void GlobalParams::setPSPaperWidth(int width) {
1810 psPaperWidth = width;
1812 psImageableURX = psPaperWidth;
1816 void GlobalParams::setPSPaperHeight(int height) {
1818 psPaperHeight = height;
1820 psImageableURY = psPaperHeight;
1824 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1826 psImageableLLX = llx;
1827 psImageableLLY = lly;
1828 psImageableURX = urx;
1829 psImageableURY = ury;
1833 void GlobalParams::setPSCrop(GBool crop) {
1839 void GlobalParams::setPSExpandSmaller(GBool expand) {
1841 psExpandSmaller = expand;
1845 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1847 psShrinkLarger = shrink;
1851 void GlobalParams::setPSCenter(GBool center) {
1857 void GlobalParams::setPSDuplex(GBool duplex) {
1863 void GlobalParams::setPSLevel(PSLevel level) {
1869 void GlobalParams::setPSEmbedType1(GBool embed) {
1871 psEmbedType1 = embed;
1875 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1877 psEmbedTrueType = embed;
1881 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1883 psEmbedCIDPostScript = embed;
1887 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1889 psEmbedCIDTrueType = embed;
1893 void GlobalParams::setPSOPI(GBool opi) {
1899 void GlobalParams::setPSASCIIHex(GBool hex) {
1905 void GlobalParams::setTextEncoding(char *encodingName) {
1907 delete textEncoding;
1908 textEncoding = new GString(encodingName);
1912 GBool GlobalParams::setTextEOL(char *s) {
1914 if (!strcmp(s, "unix")) {
1916 } else if (!strcmp(s, "dos")) {
1918 } else if (!strcmp(s, "mac")) {
1928 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1930 textPageBreaks = pageBreaks;
1934 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1936 textKeepTinyChars = keep;
1940 void GlobalParams::setInitialZoom(char *s) {
1943 initialZoom = new GString(s);
1947 void GlobalParams::setContinuousView(GBool cont) {
1949 continuousView = cont;
1953 GBool GlobalParams::setEnableT1lib(char *s) {
1957 ok = parseYesNo2(s, &enableT1lib);
1962 GBool GlobalParams::setEnableFreeType(char *s) {
1966 ok = parseYesNo2(s, &enableFreeType);
1972 GBool GlobalParams::setAntialias(char *s) {
1976 ok = parseYesNo2(s, &antialias);
1981 void GlobalParams::setMapNumericCharNames(GBool map) {
1983 mapNumericCharNames = map;
1987 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1989 printCommands = printCommandsA;
1993 void GlobalParams::setErrQuiet(GBool errQuietA) {
1995 errQuiet = errQuietA;
1999 void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
2000 #ifdef ENABLE_PLUGINS
2002 securityHandlers->append(handler);
2007 XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
2008 #ifdef ENABLE_PLUGINS
2009 XpdfSecurityHandler *hdlr;
2013 for (i = 0; i < securityHandlers->getLength(); ++i) {
2014 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
2015 if (!stricmp(hdlr->name, name)) {
2022 if (!loadPlugin("security", name)) {
2027 for (i = 0; i < securityHandlers->getLength(); ++i) {
2028 hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
2029 if (!strcmp(hdlr->name, name)) {
2040 #ifdef ENABLE_PLUGINS
2041 //------------------------------------------------------------------------
2043 //------------------------------------------------------------------------
2045 GBool GlobalParams::loadPlugin(char *type, char *name) {
2048 if (!(plugin = Plugin::load(type, name))) {
2052 plugins->append(plugin);
2057 #endif // ENABLE_PLUGINS