1 //========================================================================
5 // Copyright 2001-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
27 #include "NameToCharCode.h"
28 #include "CharCodeToUnicode.h"
29 #include "UnicodeMap.h"
31 #include "BuiltinFontTables.h"
32 #include "FontEncodingTables.h"
33 #include "GlobalParams.h"
36 # define lockGlobalParams gLockMutex(&mutex)
37 # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
38 # define lockCMapCache gLockMutex(&cMapCacheMutex)
39 # define unlockGlobalParams gUnlockMutex(&mutex)
40 # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
41 # define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
43 # define lockGlobalParams
44 # define lockUnicodeMapCache
45 # define lockCMapCache
46 # define unlockGlobalParams
47 # define unlockUnicodeMapCache
48 # define unlockCMapCache
51 #include "NameToUnicodeTable.h"
52 #include "UnicodeMapTables.h"
55 //------------------------------------------------------------------------
57 #define cidToUnicodeCacheSize 4
58 #define unicodeToUnicodeCacheSize 4
60 //------------------------------------------------------------------------
65 } displayFontTab[] = {
66 {"Courier", "n022003l.pfb"},
67 {"Courier-Bold", "n022004l.pfb"},
68 {"Courier-BoldOblique", "n022024l.pfb"},
69 {"Courier-Oblique", "n022023l.pfb"},
70 {"Helvetica", "n019003l.pfb"},
71 {"Helvetica-Bold", "n019004l.pfb"},
72 {"Helvetica-BoldOblique", "n019024l.pfb"},
73 {"Helvetica-Oblique", "n019023l.pfb"},
74 {"Symbol", "s050000l.pfb"},
75 {"Times-Bold", "n021004l.pfb"},
76 {"Times-BoldItalic", "n021024l.pfb"},
77 {"Times-Italic", "n021023l.pfb"},
78 {"Times-Roman", "n021003l.pfb"},
79 {"ZapfDingbats", "d050000l.pfb"},
83 static char *displayFontDirs[] = {
84 "/usr/share/ghostscript/fonts",
85 "/usr/local/share/ghostscript/fonts",
86 "/usr/share/fonts/default/Type1",
90 //------------------------------------------------------------------------
92 GlobalParams *globalParams = NULL;
94 //------------------------------------------------------------------------
96 //------------------------------------------------------------------------
98 DisplayFontParam::DisplayFontParam(GString *nameA,
99 DisplayFontParamKind kindA) {
112 DisplayFontParam::~DisplayFontParam() {
128 //------------------------------------------------------------------------
130 //------------------------------------------------------------------------
132 PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
133 GString *psFontNameA, GString *encodingA) {
134 pdfFontName = pdfFontNameA;
136 psFontName = psFontNameA;
137 encoding = encodingA;
140 PSFontParam::~PSFontParam() {
148 //------------------------------------------------------------------------
150 //------------------------------------------------------------------------
152 GlobalParams::GlobalParams(char *cfgFileName) {
160 gInitMutex(&unicodeMapCacheMutex);
161 gInitMutex(&cMapCacheMutex);
164 initBuiltinFontTables();
166 // scan the encoding in reverse because we want the lowest-numbered
167 // index for each char name ('space' is encoded twice)
168 macRomanReverseMap = new NameToCharCode();
169 for (i = 255; i >= 0; --i) {
170 if (macRomanEncoding[i]) {
171 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
175 nameToUnicode = new NameToCharCode();
176 cidToUnicodes = new GHash(gTrue);
177 unicodeToUnicodes = new GHash(gTrue);
178 residentUnicodeMaps = new GHash();
179 unicodeMaps = new GHash(gTrue);
180 cMapDirs = new GHash(gTrue);
181 toUnicodeDirs = new GList();
182 displayFonts = new GHash();
183 displayCIDFonts = new GHash();
184 displayNamedCIDFonts = new GHash();
187 const struct paper *paperType;
189 if ((paperName = systempapername())) {
190 paperType = paperinfo(paperName);
191 psPaperWidth = (int)paperpswidth(paperType);
192 psPaperHeight = (int)paperpsheight(paperType);
194 error(-1, "No paper information available - using defaults");
195 psPaperWidth = defPaperWidth;
196 psPaperHeight = defPaperHeight;
200 psPaperWidth = defPaperWidth;
201 psPaperHeight = defPaperHeight;
203 psImageableLLX = psImageableLLY = 0;
204 psImageableURX = psPaperWidth;
205 psImageableURY = psPaperHeight;
207 psExpandSmaller = gFalse;
208 psShrinkLarger = gTrue;
213 psFonts = new GHash();
214 psNamedFonts16 = new GList();
215 psFonts16 = new GList();
216 psEmbedType1 = gTrue;
217 psEmbedTrueType = gTrue;
218 psEmbedCIDPostScript = gTrue;
219 psEmbedCIDTrueType = gTrue;
222 textEncoding = new GString("Latin1");
230 textPageBreaks = gTrue;
231 textKeepTinyChars = gFalse;
232 fontDirs = new GList();
233 initialZoom = new GString("125");
235 enableFreeType = gTrue;
239 mapNumericCharNames = gTrue;
240 printCommands = gFalse;
243 cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
244 unicodeToUnicodeCache =
245 new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
246 unicodeMapCache = new UnicodeMapCache();
247 cMapCache = new CMapCache();
249 // set up the initial nameToUnicode table
250 for (i = 0; nameToUnicodeTab[i].name; ++i) {
251 nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
254 // set up the residentUnicodeMaps table
255 map = new UnicodeMap("Latin1", gFalse,
256 latin1UnicodeMapRanges, latin1UnicodeMapLen);
257 residentUnicodeMaps->add(map->getEncodingName(), map);
258 map = new UnicodeMap("ASCII7", gFalse,
259 ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
260 residentUnicodeMaps->add(map->getEncodingName(), map);
261 map = new UnicodeMap("Symbol", gFalse,
262 symbolUnicodeMapRanges, symbolUnicodeMapLen);
263 residentUnicodeMaps->add(map->getEncodingName(), map);
264 map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
265 zapfDingbatsUnicodeMapLen);
266 residentUnicodeMaps->add(map->getEncodingName(), map);
267 map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
268 residentUnicodeMaps->add(map->getEncodingName(), map);
269 map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
270 residentUnicodeMaps->add(map->getEncodingName(), map);
272 // look for a user config file, then a system-wide config file
275 if (cfgFileName && cfgFileName[0]) {
276 fileName = new GString(cfgFileName);
277 if (!(f = fopen(fileName->getCString(), "r"))) {
282 fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
283 if (!(f = fopen(fileName->getCString(), "r"))) {
288 #if defined(WIN32) && !defined(__CYGWIN32__)
290 i = GetModuleFileName(NULL, buf, sizeof(buf));
291 if (i <= 0 || i >= sizeof(buf)) {
292 // error or path too long for buffer - just use the current dir
295 fileName = grabPath(buf);
296 appendToPath(fileName, xpdfSysConfigFile);
298 fileName = new GString(xpdfSysConfigFile);
300 if (!(f = fopen(fileName->getCString(), "r"))) {
305 parseFile(fileName, f);
311 void GlobalParams::parseFile(GString *fileName, FILE *f) {
314 GString *cmd, *incFile;
320 while (getLine(buf, sizeof(buf) - 1, f)) {
322 // break the line into tokens
323 tokens = new GList();
326 for (; *p1 && isspace(*p1); ++p1) ;
330 if (*p1 == '"' || *p1 == '\'') {
331 for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
334 for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
336 tokens->append(new GString(p1, p2 - p1));
337 p1 = *p2 ? p2 + 1 : p2;
340 if (tokens->getLength() > 0 &&
341 ((GString *)tokens->get(0))->getChar(0) != '#') {
342 cmd = (GString *)tokens->get(0);
343 if (!cmd->cmp("include")) {
344 if (tokens->getLength() == 2) {
345 incFile = (GString *)tokens->get(1);
346 if ((f2 = fopen(incFile->getCString(), "r"))) {
347 parseFile(incFile, f2);
350 error(-1, "Couldn't find included config file: '%s' (%s:%d)",
351 incFile->getCString(), fileName->getCString(), line);
354 error(-1, "Bad 'include' config file command (%s:%d)",
355 fileName->getCString(), line);
357 } else if (!cmd->cmp("nameToUnicode")) {
358 parseNameToUnicode(tokens, fileName, line);
359 } else if (!cmd->cmp("cidToUnicode")) {
360 parseCIDToUnicode(tokens, fileName, line);
361 } else if (!cmd->cmp("unicodeToUnicode")) {
362 parseUnicodeToUnicode(tokens, fileName, line);
363 } else if (!cmd->cmp("unicodeMap")) {
364 parseUnicodeMap(tokens, fileName, line);
365 } else if (!cmd->cmp("cMapDir")) {
366 parseCMapDir(tokens, fileName, line);
367 } else if (!cmd->cmp("toUnicodeDir")) {
368 parseToUnicodeDir(tokens, fileName, line);
369 } else if (!cmd->cmp("displayFontT1")) {
370 parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
371 } else if (!cmd->cmp("displayFontTT")) {
372 parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
373 } else if (!cmd->cmp("displayNamedCIDFontT1")) {
374 parseDisplayFont(tokens, displayNamedCIDFonts,
375 displayFontT1, fileName, line);
376 } else if (!cmd->cmp("displayCIDFontT1")) {
377 parseDisplayFont(tokens, displayCIDFonts,
378 displayFontT1, fileName, line);
379 } else if (!cmd->cmp("displayNamedCIDFontTT")) {
380 parseDisplayFont(tokens, displayNamedCIDFonts,
381 displayFontTT, fileName, line);
382 } else if (!cmd->cmp("displayCIDFontTT")) {
383 parseDisplayFont(tokens, displayCIDFonts,
384 displayFontTT, fileName, line);
385 } else if (!cmd->cmp("psFile")) {
386 parsePSFile(tokens, fileName, line);
387 } else if (!cmd->cmp("psFont")) {
388 parsePSFont(tokens, fileName, line);
389 } else if (!cmd->cmp("psNamedFont16")) {
390 parsePSFont16("psNamedFont16", psNamedFonts16,
391 tokens, fileName, line);
392 } else if (!cmd->cmp("psFont16")) {
393 parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
394 } else if (!cmd->cmp("psPaperSize")) {
395 parsePSPaperSize(tokens, fileName, line);
396 } else if (!cmd->cmp("psImageableArea")) {
397 parsePSImageableArea(tokens, fileName, line);
398 } else if (!cmd->cmp("psCrop")) {
399 parseYesNo("psCrop", &psCrop, tokens, fileName, line);
400 } else if (!cmd->cmp("psExpandSmaller")) {
401 parseYesNo("psExpandSmaller", &psExpandSmaller,
402 tokens, fileName, line);
403 } else if (!cmd->cmp("psShrinkLarger")) {
404 parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
405 } else if (!cmd->cmp("psCenter")) {
406 parseYesNo("psCenter", &psCenter, tokens, fileName, line);
407 } else if (!cmd->cmp("psDuplex")) {
408 parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
409 } else if (!cmd->cmp("psLevel")) {
410 parsePSLevel(tokens, fileName, line);
411 } else if (!cmd->cmp("psEmbedType1Fonts")) {
412 parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
413 } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
414 parseYesNo("psEmbedTrueType", &psEmbedTrueType,
415 tokens, fileName, line);
416 } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
417 parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
418 tokens, fileName, line);
419 } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
420 parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
421 tokens, fileName, line);
422 } else if (!cmd->cmp("psOPI")) {
423 parseYesNo("psOPI", &psOPI, tokens, fileName, line);
424 } else if (!cmd->cmp("psASCIIHex")) {
425 parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
426 } else if (!cmd->cmp("textEncoding")) {
427 parseTextEncoding(tokens, fileName, line);
428 } else if (!cmd->cmp("textEOL")) {
429 parseTextEOL(tokens, fileName, line);
430 } else if (!cmd->cmp("textPageBreaks")) {
431 parseYesNo("textPageBreaks", &textPageBreaks,
432 tokens, fileName, line);
433 } else if (!cmd->cmp("textKeepTinyChars")) {
434 parseYesNo("textKeepTinyChars", &textKeepTinyChars,
435 tokens, fileName, line);
436 } else if (!cmd->cmp("fontDir")) {
437 parseFontDir(tokens, fileName, line);
438 } else if (!cmd->cmp("initialZoom")) {
439 parseInitialZoom(tokens, fileName, line);
440 } else if (!cmd->cmp("enableT1lib")) {
441 parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
442 } else if (!cmd->cmp("enableFreeType")) {
443 parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
444 } else if (!cmd->cmp("antialias")) {
445 parseYesNo("antialias", &antialias, tokens, fileName, line);
446 } else if (!cmd->cmp("urlCommand")) {
447 parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
448 } else if (!cmd->cmp("movieCommand")) {
449 parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
450 } else if (!cmd->cmp("mapNumericCharNames")) {
451 parseYesNo("mapNumericCharNames", &mapNumericCharNames,
452 tokens, fileName, line);
453 } else if (!cmd->cmp("printCommands")) {
454 parseYesNo("printCommands", &printCommands, tokens, fileName, line);
455 } else if (!cmd->cmp("errQuiet")) {
456 parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
458 error(-1, "Unknown config file command '%s' (%s:%d)",
459 cmd->getCString(), fileName->getCString(), line);
460 if (!cmd->cmp("displayFontX") ||
461 !cmd->cmp("displayNamedCIDFontX") ||
462 !cmd->cmp("displayCIDFontX")) {
463 error(-1, "-- Xpdf no longer supports X fonts");
464 } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
465 error(-1, "-- The t1libControl and freetypeControl options have been replaced");
466 error(-1, " by the enableT1lib, enableFreeType, and antialias options");
467 } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
468 error(-1, "-- the config file format has changed since Xpdf 0.9x");
473 deleteGList(tokens, GString);
478 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
487 if (tokens->getLength() != 2) {
488 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
489 fileName->getCString(), line);
492 name = (GString *)tokens->get(1);
493 if (!(f = fopen(name->getCString(), "r"))) {
494 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
499 while (getLine(buf, sizeof(buf), f)) {
500 tok1 = strtok(buf, " \t\r\n");
501 tok2 = strtok(NULL, " \t\r\n");
503 sscanf(tok1, "%x", &u);
504 nameToUnicode->add(tok2, u);
506 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
513 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
515 GString *collection, *name, *old;
517 if (tokens->getLength() != 3) {
518 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
519 fileName->getCString(), line);
522 collection = (GString *)tokens->get(1);
523 name = (GString *)tokens->get(2);
524 if ((old = (GString *)cidToUnicodes->remove(collection))) {
527 cidToUnicodes->add(collection->copy(), name->copy());
530 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
532 GString *font, *file, *old;
534 if (tokens->getLength() != 3) {
535 error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
536 fileName->getCString(), line);
539 font = (GString *)tokens->get(1);
540 file = (GString *)tokens->get(2);
541 if ((old = (GString *)unicodeToUnicodes->remove(font))) {
544 unicodeToUnicodes->add(font->copy(), file->copy());
547 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
549 GString *encodingName, *name, *old;
551 if (tokens->getLength() != 3) {
552 error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
553 fileName->getCString(), line);
556 encodingName = (GString *)tokens->get(1);
557 name = (GString *)tokens->get(2);
558 if ((old = (GString *)unicodeMaps->remove(encodingName))) {
561 unicodeMaps->add(encodingName->copy(), name->copy());
564 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
565 GString *collection, *dir;
568 if (tokens->getLength() != 3) {
569 error(-1, "Bad 'cMapDir' config file command (%s:%d)",
570 fileName->getCString(), line);
573 collection = (GString *)tokens->get(1);
574 dir = (GString *)tokens->get(2);
575 if (!(list = (GList *)cMapDirs->lookup(collection))) {
577 cMapDirs->add(collection->copy(), list);
579 list->append(dir->copy());
582 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
584 if (tokens->getLength() != 2) {
585 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
586 fileName->getCString(), line);
589 toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
592 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
593 DisplayFontParamKind kind,
594 GString *fileName, int line) {
595 DisplayFontParam *param, *old;
597 if (tokens->getLength() < 2) {
600 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
604 if (tokens->getLength() != 3) {
607 param->t1.fileName = ((GString *)tokens->get(2))->copy();
610 if (tokens->getLength() != 3) {
613 param->tt.fileName = ((GString *)tokens->get(2))->copy();
617 if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
620 fontHash->add(param->name, param);
626 error(-1, "Bad 'display*Font*' config file command (%s:%d)",
627 fileName->getCString(), line);
630 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
634 if (tokens->getLength() == 2) {
635 tok = (GString *)tokens->get(1);
636 if (!setPSPaperSize(tok->getCString())) {
637 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
638 fileName->getCString(), line);
640 } else if (tokens->getLength() == 3) {
641 tok = (GString *)tokens->get(1);
642 psPaperWidth = atoi(tok->getCString());
643 tok = (GString *)tokens->get(2);
644 psPaperHeight = atoi(tok->getCString());
645 psImageableLLX = psImageableLLY = 0;
646 psImageableURX = psPaperWidth;
647 psImageableURY = psPaperHeight;
649 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
650 fileName->getCString(), line);
654 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
656 if (tokens->getLength() != 5) {
657 error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
658 fileName->getCString(), line);
661 psImageableLLX = atoi(((GString *)tokens->get(1))->getCString());
662 psImageableLLY = atoi(((GString *)tokens->get(2))->getCString());
663 psImageableURX = atoi(((GString *)tokens->get(3))->getCString());
664 psImageableURY = atoi(((GString *)tokens->get(4))->getCString());
667 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
670 if (tokens->getLength() != 2) {
671 error(-1, "Bad 'psLevel' config file command (%s:%d)",
672 fileName->getCString(), line);
675 tok = (GString *)tokens->get(1);
676 if (!tok->cmp("level1")) {
678 } else if (!tok->cmp("level1sep")) {
679 psLevel = psLevel1Sep;
680 } else if (!tok->cmp("level2")) {
682 } else if (!tok->cmp("level2sep")) {
683 psLevel = psLevel2Sep;
684 } else if (!tok->cmp("level3")) {
686 } else if (!tok->cmp("level3Sep")) {
687 psLevel = psLevel3Sep;
689 error(-1, "Bad 'psLevel' config file command (%s:%d)",
690 fileName->getCString(), line);
694 void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
695 if (tokens->getLength() != 2) {
696 error(-1, "Bad 'psFile' config file command (%s:%d)",
697 fileName->getCString(), line);
703 psFile = ((GString *)tokens->get(1))->copy();
706 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
709 if (tokens->getLength() != 3) {
710 error(-1, "Bad 'psFont' config file command (%s:%d)",
711 fileName->getCString(), line);
714 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
715 ((GString *)tokens->get(2))->copy(), NULL);
716 psFonts->add(param->pdfFontName, param);
719 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
720 GList *tokens, GString *fileName, int line) {
725 if (tokens->getLength() != 5) {
726 error(-1, "Bad '%s' config file command (%s:%d)",
727 cmdName, fileName->getCString(), line);
730 tok = (GString *)tokens->get(2);
731 if (!tok->cmp("H")) {
733 } else if (!tok->cmp("V")) {
736 error(-1, "Bad '%s' config file command (%s:%d)",
737 cmdName, fileName->getCString(), line);
740 param = new PSFontParam(((GString *)tokens->get(1))->copy(),
742 ((GString *)tokens->get(3))->copy(),
743 ((GString *)tokens->get(4))->copy());
744 fontList->append(param);
747 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
749 if (tokens->getLength() != 2) {
750 error(-1, "Bad 'textEncoding' config file command (%s:%d)",
751 fileName->getCString(), line);
755 textEncoding = ((GString *)tokens->get(1))->copy();
758 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
761 if (tokens->getLength() != 2) {
762 error(-1, "Bad 'textEOL' config file command (%s:%d)",
763 fileName->getCString(), line);
766 tok = (GString *)tokens->get(1);
767 if (!tok->cmp("unix")) {
769 } else if (!tok->cmp("dos")) {
771 } else if (!tok->cmp("mac")) {
774 error(-1, "Bad 'textEOL' config file command (%s:%d)",
775 fileName->getCString(), line);
779 void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
780 if (tokens->getLength() != 2) {
781 error(-1, "Bad 'fontDir' config file command (%s:%d)",
782 fileName->getCString(), line);
785 fontDirs->append(((GString *)tokens->get(1))->copy());
788 void GlobalParams::parseInitialZoom(GList *tokens,
789 GString *fileName, int line) {
790 if (tokens->getLength() != 2) {
791 error(-1, "Bad 'initialZoom' config file command (%s:%d)",
792 fileName->getCString(), line);
796 initialZoom = ((GString *)tokens->get(1))->copy();
799 void GlobalParams::parseCommand(char *cmdName, GString **val,
800 GList *tokens, GString *fileName, int line) {
801 if (tokens->getLength() != 2) {
802 error(-1, "Bad '%s' config file command (%s:%d)",
803 cmdName, fileName->getCString(), line);
809 *val = ((GString *)tokens->get(1))->copy();
812 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
813 GList *tokens, GString *fileName, int line) {
816 if (tokens->getLength() != 2) {
817 error(-1, "Bad '%s' config file command (%s:%d)",
818 cmdName, fileName->getCString(), line);
821 tok = (GString *)tokens->get(1);
822 if (!parseYesNo2(tok->getCString(), flag)) {
823 error(-1, "Bad '%s' config file command (%s:%d)",
824 cmdName, fileName->getCString(), line);
828 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
829 if (!strcmp(token, "yes")) {
831 } else if (!strcmp(token, "no")) {
839 GlobalParams::~GlobalParams() {
844 freeBuiltinFontTables();
846 delete macRomanReverseMap;
848 delete nameToUnicode;
849 deleteGHash(cidToUnicodes, GString);
850 deleteGHash(unicodeToUnicodes, GString);
851 deleteGHash(residentUnicodeMaps, UnicodeMap);
852 deleteGHash(unicodeMaps, GString);
853 deleteGList(toUnicodeDirs, GString);
854 deleteGHash(displayFonts, DisplayFontParam);
855 deleteGHash(displayCIDFonts, DisplayFontParam);
856 deleteGHash(displayNamedCIDFonts, DisplayFontParam);
860 deleteGHash(psFonts, PSFontParam);
861 deleteGList(psNamedFonts16, PSFontParam);
862 deleteGList(psFonts16, PSFontParam);
864 deleteGList(fontDirs, GString);
873 cMapDirs->startIter(&iter);
874 while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
875 deleteGList(list, GString);
879 delete cidToUnicodeCache;
880 delete unicodeToUnicodeCache;
881 delete unicodeMapCache;
885 gDestroyMutex(&mutex);
886 gDestroyMutex(&unicodeMapCacheMutex);
887 gDestroyMutex(&cMapCacheMutex);
891 //------------------------------------------------------------------------
893 void GlobalParams::setupBaseFonts(char *dir) {
897 DisplayFontParam *dfp;
900 for (i = 0; displayFontTab[i].name; ++i) {
901 fontName = new GString(displayFontTab[i].name);
902 if (getDisplayFont(fontName)) {
908 fileName = appendToPath(new GString(dir), displayFontTab[i].fileName);
909 if ((f = fopen(fileName->getCString(), "rb"))) {
917 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
918 fileName = appendToPath(new GString(displayFontDirs[j]),
919 displayFontTab[i].fileName);
920 if ((f = fopen(fileName->getCString(), "rb"))) {
929 error(-1, "No display font for '%s'", displayFontTab[i].name);
933 dfp = new DisplayFontParam(fontName, displayFontT1);
934 dfp->t1.fileName = fileName;
935 globalParams->addDisplayFont(dfp);
939 //------------------------------------------------------------------------
941 //------------------------------------------------------------------------
943 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
944 // no need to lock - macRomanReverseMap is constant
945 return macRomanReverseMap->lookup(charName);
948 Unicode GlobalParams::mapNameToUnicode(char *charName) {
949 // no need to lock - nameToUnicode is constant
950 return nameToUnicode->lookup(charName);
953 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
957 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
965 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
970 if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
971 f = fopen(fileName->getCString(), "r");
979 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
987 if (!(list = (GList *)cMapDirs->lookup(collection))) {
991 for (i = 0; i < list->getLength(); ++i) {
992 dir = (GString *)list->get(i);
993 fileName = appendToPath(dir->copy(), cMapName->getCString());
994 f = fopen(fileName->getCString(), "r");
1005 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1006 GString *dir, *fileName;
1011 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1012 dir = (GString *)toUnicodeDirs->get(i);
1013 fileName = appendToPath(dir->copy(), name->getCString());
1014 f = fopen(fileName->getCString(), "r");
1025 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1026 DisplayFontParam *dfp;
1029 dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1034 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1035 GString *collection) {
1036 DisplayFontParam *dfp;
1040 !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1041 dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1047 GString *GlobalParams::getPSFile() {
1051 s = psFile ? psFile->copy() : (GString *)NULL;
1056 int GlobalParams::getPSPaperWidth() {
1065 int GlobalParams::getPSPaperHeight() {
1074 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1076 *llx = psImageableLLX;
1077 *lly = psImageableLLY;
1078 *urx = psImageableURX;
1079 *ury = psImageableURY;
1083 GBool GlobalParams::getPSCrop() {
1092 GBool GlobalParams::getPSExpandSmaller() {
1096 f = psExpandSmaller;
1101 GBool GlobalParams::getPSShrinkLarger() {
1110 GBool GlobalParams::getPSCenter() {
1119 GBool GlobalParams::getPSDuplex() {
1128 PSLevel GlobalParams::getPSLevel() {
1137 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1141 p = (PSFontParam *)psFonts->lookup(fontName);
1146 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1147 GString *collection, int wMode) {
1154 for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1155 p = (PSFontParam *)psNamedFonts16->get(i);
1156 if (!p->pdfFontName->cmp(fontName) &&
1157 p->wMode == wMode) {
1163 if (!p && collection) {
1164 for (i = 0; i < psFonts16->getLength(); ++i) {
1165 p = (PSFontParam *)psFonts16->get(i);
1166 if (!p->pdfFontName->cmp(collection) &&
1167 p->wMode == wMode) {
1177 GBool GlobalParams::getPSEmbedType1() {
1186 GBool GlobalParams::getPSEmbedTrueType() {
1190 e = psEmbedTrueType;
1195 GBool GlobalParams::getPSEmbedCIDPostScript() {
1199 e = psEmbedCIDPostScript;
1204 GBool GlobalParams::getPSEmbedCIDTrueType() {
1208 e = psEmbedCIDTrueType;
1213 GBool GlobalParams::getPSOPI() {
1222 GBool GlobalParams::getPSASCIIHex() {
1231 GString *GlobalParams::getTextEncodingName() {
1235 s = textEncoding->copy();
1240 EndOfLineKind GlobalParams::getTextEOL() {
1249 GBool GlobalParams::getTextPageBreaks() {
1253 pageBreaks = textPageBreaks;
1258 GBool GlobalParams::getTextKeepTinyChars() {
1262 tiny = textKeepTinyChars;
1267 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1268 GString *dir, *fileName;
1274 for (i = 0; i < fontDirs->getLength(); ++i) {
1275 dir = (GString *)fontDirs->get(i);
1276 for (ext = exts; *ext; ++ext) {
1277 fileName = appendToPath(dir->copy(), fontName->getCString());
1278 fileName->append(*ext);
1279 if ((f = fopen(fileName->getCString(), "rb"))) {
1291 GString *GlobalParams::getInitialZoom() {
1295 s = initialZoom->copy();
1300 GBool GlobalParams::getEnableT1lib() {
1309 GBool GlobalParams::getEnableFreeType() {
1319 GBool GlobalParams::getAntialias() {
1328 GBool GlobalParams::getMapNumericCharNames() {
1332 map = mapNumericCharNames;
1337 GBool GlobalParams::getPrintCommands() {
1346 GBool GlobalParams::getErrQuiet() {
1355 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1357 CharCodeToUnicode *ctu;
1360 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1361 if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1362 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1363 cidToUnicodeCache->add(ctu);
1370 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1371 CharCodeToUnicode *ctu;
1373 GString *fontPattern, *fileName;
1377 unicodeToUnicodes->startIter(&iter);
1378 while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1379 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1380 unicodeToUnicodes->killIter(&iter);
1386 if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1387 if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1388 unicodeToUnicodeCache->add(ctu);
1398 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1399 return getUnicodeMap2(encodingName);
1402 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1405 if (!(map = getResidentUnicodeMap(encodingName))) {
1406 lockUnicodeMapCache;
1407 map = unicodeMapCache->getUnicodeMap(encodingName);
1408 unlockUnicodeMapCache;
1413 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1417 cMap = cMapCache->getCMap(collection, cMapName);
1422 UnicodeMap *GlobalParams::getTextEncoding() {
1423 return getUnicodeMap2(textEncoding);
1426 //------------------------------------------------------------------------
1427 // functions to set parameters
1428 //------------------------------------------------------------------------
1430 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1431 DisplayFontParam *old;
1434 if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1437 displayFonts->add(param->name, param);
1441 void GlobalParams::setPSFile(char *file) {
1446 psFile = new GString(file);
1450 GBool GlobalParams::setPSPaperSize(char *size) {
1452 if (!strcmp(size, "match")) {
1453 psPaperWidth = psPaperHeight = -1;
1454 } else if (!strcmp(size, "letter")) {
1456 psPaperHeight = 792;
1457 } else if (!strcmp(size, "legal")) {
1459 psPaperHeight = 1008;
1460 } else if (!strcmp(size, "A4")) {
1462 psPaperHeight = 842;
1463 } else if (!strcmp(size, "A3")) {
1465 psPaperHeight = 1190;
1470 psImageableLLX = psImageableLLY = 0;
1471 psImageableURX = psPaperWidth;
1472 psImageableURY = psPaperHeight;
1477 void GlobalParams::setPSPaperWidth(int width) {
1479 psPaperWidth = width;
1481 psImageableURX = psPaperWidth;
1485 void GlobalParams::setPSPaperHeight(int height) {
1487 psPaperHeight = height;
1489 psImageableURY = psPaperHeight;
1493 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1495 psImageableLLX = llx;
1496 psImageableLLY = lly;
1497 psImageableURX = urx;
1498 psImageableURY = ury;
1502 void GlobalParams::setPSCrop(GBool crop) {
1508 void GlobalParams::setPSExpandSmaller(GBool expand) {
1510 psExpandSmaller = expand;
1514 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1516 psShrinkLarger = shrink;
1520 void GlobalParams::setPSCenter(GBool center) {
1526 void GlobalParams::setPSDuplex(GBool duplex) {
1532 void GlobalParams::setPSLevel(PSLevel level) {
1538 void GlobalParams::setPSEmbedType1(GBool embed) {
1540 psEmbedType1 = embed;
1544 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1546 psEmbedTrueType = embed;
1550 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1552 psEmbedCIDPostScript = embed;
1556 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1558 psEmbedCIDTrueType = embed;
1562 void GlobalParams::setPSOPI(GBool opi) {
1568 void GlobalParams::setPSASCIIHex(GBool hex) {
1574 void GlobalParams::setTextEncoding(char *encodingName) {
1576 delete textEncoding;
1577 textEncoding = new GString(encodingName);
1581 GBool GlobalParams::setTextEOL(char *s) {
1583 if (!strcmp(s, "unix")) {
1585 } else if (!strcmp(s, "dos")) {
1587 } else if (!strcmp(s, "mac")) {
1597 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1599 textPageBreaks = pageBreaks;
1603 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1605 textKeepTinyChars = keep;
1609 void GlobalParams::setInitialZoom(char *s) {
1612 initialZoom = new GString(s);
1616 GBool GlobalParams::setEnableT1lib(char *s) {
1620 ok = parseYesNo2(s, &enableT1lib);
1625 GBool GlobalParams::setEnableFreeType(char *s) {
1629 ok = parseYesNo2(s, &enableFreeType);
1635 GBool GlobalParams::setAntialias(char *s) {
1639 ok = parseYesNo2(s, &antialias);
1644 void GlobalParams::setMapNumericCharNames(GBool map) {
1646 mapNumericCharNames = map;
1650 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1652 printCommands = printCommandsA;
1656 void GlobalParams::setErrQuiet(GBool errQuietA) {
1658 errQuiet = errQuietA;