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;
321 char* cfgFileName = fileName->getCString();
322 char* pos1 = strrchr(cfgFileName, '/');
323 char* pos2 = strrchr(cfgFileName, '\\');
324 char* p = pos1>pos2?pos1:pos2;
325 int pos = p ? p-cfgFileName : -1;
326 GString*path = new GString(new GString(cfgFileName), 0, (pos < 0 ? strlen(cfgFileName): pos));
339 this->path = new GString();
343 while (getLine(buf, sizeof(buf) - 1, f)) {
345 // break the line into tokens
346 tokens = new GList();
349 for (; *p1 && isspace(*p1); ++p1) ;
353 if (*p1 == '"' || *p1 == '\'') {
354 for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
357 for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
359 tokens->append(new GString(p1, p2 - p1));
360 p1 = *p2 ? p2 + 1 : p2;
363 if (tokens->getLength() > 0 &&
364 ((GString *)tokens->get(0))->getChar(0) != '#') {
365 cmd = (GString *)tokens->get(0);
366 if (!cmd->cmp("include")) {
367 if (tokens->getLength() == 2) {
368 incFile = (GString *)tokens->get(1);
369 if ((f2 = fopen(incFile->getCString(), "r"))) {
370 parseFile(incFile, f2);
373 error(-1, "Couldn't find included config file: '%s' (%s:%d)",
374 incFile->getCString(), fileName->getCString(), line);
377 error(-1, "Bad 'include' config file command (%s:%d)",
378 fileName->getCString(), line);
380 } else if (!cmd->cmp("nameToUnicode")) {
381 parseNameToUnicode(tokens, fileName, line);
382 } else if (!cmd->cmp("cidToUnicode")) {
383 parseCIDToUnicode(tokens, fileName, line);
384 } else if (!cmd->cmp("unicodeToUnicode")) {
385 parseUnicodeToUnicode(tokens, fileName, line);
386 } else if (!cmd->cmp("unicodeMap")) {
387 parseUnicodeMap(tokens, fileName, line);
388 } else if (!cmd->cmp("cMapDir")) {
389 parseCMapDir(tokens, fileName, line);
390 } else if (!cmd->cmp("toUnicodeDir")) {
391 parseToUnicodeDir(tokens, fileName, line);
392 } else if (!cmd->cmp("displayFontT1")) {
393 parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
394 } else if (!cmd->cmp("displayFontTT")) {
395 parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
396 } else if (!cmd->cmp("displayNamedCIDFontT1")) {
397 parseDisplayFont(tokens, displayNamedCIDFonts,
398 displayFontT1, fileName, line);
399 } else if (!cmd->cmp("displayCIDFontT1")) {
400 parseDisplayFont(tokens, displayCIDFonts,
401 displayFontT1, fileName, line);
402 } else if (!cmd->cmp("displayNamedCIDFontTT")) {
403 parseDisplayFont(tokens, displayNamedCIDFonts,
404 displayFontTT, fileName, line);
405 } else if (!cmd->cmp("displayCIDFontTT")) {
406 parseDisplayFont(tokens, displayCIDFonts,
407 displayFontTT, fileName, line);
408 } else if (!cmd->cmp("psFile")) {
409 parsePSFile(tokens, fileName, line);
410 } else if (!cmd->cmp("psFont")) {
411 parsePSFont(tokens, fileName, line);
412 } else if (!cmd->cmp("psNamedFont16")) {
413 parsePSFont16("psNamedFont16", psNamedFonts16,
414 tokens, fileName, line);
415 } else if (!cmd->cmp("psFont16")) {
416 parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
417 } else if (!cmd->cmp("psPaperSize")) {
418 parsePSPaperSize(tokens, fileName, line);
419 } else if (!cmd->cmp("psImageableArea")) {
420 parsePSImageableArea(tokens, fileName, line);
421 } else if (!cmd->cmp("psCrop")) {
422 parseYesNo("psCrop", &psCrop, tokens, fileName, line);
423 } else if (!cmd->cmp("psExpandSmaller")) {
424 parseYesNo("psExpandSmaller", &psExpandSmaller,
425 tokens, fileName, line);
426 } else if (!cmd->cmp("psShrinkLarger")) {
427 parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
428 } else if (!cmd->cmp("psCenter")) {
429 parseYesNo("psCenter", &psCenter, tokens, fileName, line);
430 } else if (!cmd->cmp("psDuplex")) {
431 parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
432 } else if (!cmd->cmp("psLevel")) {
433 parsePSLevel(tokens, fileName, line);
434 } else if (!cmd->cmp("psEmbedType1Fonts")) {
435 parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
436 } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
437 parseYesNo("psEmbedTrueType", &psEmbedTrueType,
438 tokens, fileName, line);
439 } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
440 parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
441 tokens, fileName, line);
442 } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
443 parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
444 tokens, fileName, line);
445 } else if (!cmd->cmp("psOPI")) {
446 parseYesNo("psOPI", &psOPI, tokens, fileName, line);
447 } else if (!cmd->cmp("psASCIIHex")) {
448 parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
449 } else if (!cmd->cmp("textEncoding")) {
450 parseTextEncoding(tokens, fileName, line);
451 } else if (!cmd->cmp("textEOL")) {
452 parseTextEOL(tokens, fileName, line);
453 } else if (!cmd->cmp("textPageBreaks")) {
454 parseYesNo("textPageBreaks", &textPageBreaks,
455 tokens, fileName, line);
456 } else if (!cmd->cmp("textKeepTinyChars")) {
457 parseYesNo("textKeepTinyChars", &textKeepTinyChars,
458 tokens, fileName, line);
459 } else if (!cmd->cmp("fontDir")) {
460 parseFontDir(tokens, fileName, line);
461 } else if (!cmd->cmp("initialZoom")) {
462 parseInitialZoom(tokens, fileName, line);
463 } else if (!cmd->cmp("enableT1lib")) {
464 parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
465 } else if (!cmd->cmp("enableFreeType")) {
466 parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
467 } else if (!cmd->cmp("antialias")) {
468 parseYesNo("antialias", &antialias, tokens, fileName, line);
469 } else if (!cmd->cmp("urlCommand")) {
470 parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
471 } else if (!cmd->cmp("movieCommand")) {
472 parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
473 } else if (!cmd->cmp("mapNumericCharNames")) {
474 parseYesNo("mapNumericCharNames", &mapNumericCharNames,
475 tokens, fileName, line);
476 } else if (!cmd->cmp("printCommands")) {
477 parseYesNo("printCommands", &printCommands, tokens, fileName, line);
478 } else if (!cmd->cmp("errQuiet")) {
479 parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
481 error(-1, "Unknown config file command '%s' (%s:%d)",
482 cmd->getCString(), fileName->getCString(), line);
483 if (!cmd->cmp("displayFontX") ||
484 !cmd->cmp("displayNamedCIDFontX") ||
485 !cmd->cmp("displayCIDFontX")) {
486 error(-1, "-- Xpdf no longer supports X fonts");
487 } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
488 error(-1, "-- The t1libControl and freetypeControl options have been replaced");
489 error(-1, " by the enableT1lib, enableFreeType, and antialias options");
490 } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
491 error(-1, "-- the config file format has changed since Xpdf 0.9x");
496 deleteGList(tokens, GString);
501 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
510 if (tokens->getLength() != 2) {
511 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
512 fileName->getCString(), line);
515 name = (GString *)tokens->get(1);
516 if (!(f = fopen(name->getCString(), "r"))) {
517 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
522 while (getLine(buf, sizeof(buf), f)) {
523 tok1 = strtok(buf, " \t\r\n");
524 tok2 = strtok(NULL, " \t\r\n");
526 sscanf(tok1, "%x", &u);
527 nameToUnicode->add(tok2, u);
529 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
536 static GString* qualify_filename(GString*path, GString*filename)
538 GString*fullpath = 0;
539 char*prefix = "/usr/local/share/xpdf/";
541 if (filename->getChar(0) != '\\' && filename->getChar(0) != '/') {
543 fullpath = path->copy();
544 fullpath->append(filename);
545 } else if (!strncmp(filename->getCString(), prefix, strlen(prefix))) {
546 /* xpdf default path */
547 char*s = strchr(filename->getCString()+strlen(prefix), '/');
549 fullpath = path->copy();
550 fullpath->append(s+1);
552 fullpath = filename->copy();
556 fullpath = filename->copy();
558 printf("%s -%s-> %s\n", filename->getCString(), path->getCString(), fullpath->getCString());
562 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
564 GString *collection, *name, *old;
566 if (tokens->getLength() != 3) {
567 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
568 fileName->getCString(), line);
571 collection = (GString *)tokens->get(1);
572 name = (GString *)tokens->get(2);
574 if ((old = (GString *)cidToUnicodes->remove(collection))) {
578 cidToUnicodes->add(collection->copy(), qualify_filename(this->path, name));
581 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
583 GString *font, *file, *old;
585 if (tokens->getLength() != 3) {
586 error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
587 fileName->getCString(), line);
590 font = (GString *)tokens->get(1);
591 file = (GString *)tokens->get(2);
592 if ((old = (GString *)unicodeToUnicodes->remove(font))) {
596 unicodeToUnicodes->add(font->copy(), qualify_filename(this->path, file));
599 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
601 GString *encodingName, *name, *old;
603 if (tokens->getLength() != 3) {
604 error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
605 fileName->getCString(), line);
608 encodingName = (GString *)tokens->get(1);
609 name = (GString *)tokens->get(2);
610 if ((old = (GString *)unicodeMaps->remove(encodingName))) {
614 unicodeMaps->add(encodingName->copy(), qualify_filename(this->path, name));
617 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
618 GString *collection, *dir;
621 if (tokens->getLength() != 3) {
622 error(-1, "Bad 'cMapDir' config file command (%s:%d)",
623 fileName->getCString(), line);
626 collection = (GString *)tokens->get(1);
627 dir = (GString *)tokens->get(2);
628 if (!(list = (GList *)cMapDirs->lookup(collection))) {
630 cMapDirs->add(collection->copy(), list);
633 list->append(qualify_filename(this->path, dir));
636 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
640 if (tokens->getLength() != 2) {
641 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
642 fileName->getCString(), line);
646 dir = (GString *)tokens->get(1);
648 toUnicodeDirs->append(qualify_filename(this->path, dir));
651 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
652 DisplayFontParamKind kind,
653 GString *fileName, int line) {
654 DisplayFontParam *param, *old;
657 if (tokens->getLength() < 2) {
660 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
664 if (tokens->getLength() != 3) {
667 file = (GString *)tokens->get(2);
668 param->t1.fileName = qualify_filename(this->path, file);
671 if (tokens->getLength() != 3) {
674 file = (GString *)tokens->get(2);
675 param->tt.fileName = qualify_filename(this->path, file);
679 if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
682 fontHash->add(param->name, param);
688 error(-1, "Bad 'display*Font*' config file command (%s:%d)",
689 fileName->getCString(), line);
692 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
696 if (tokens->getLength() == 2) {
697 tok = (GString *)tokens->get(1);
698 if (!setPSPaperSize(tok->getCString())) {
699 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
700 fileName->getCString(), line);
702 } else if (tokens->getLength() == 3) {
703 tok = (GString *)tokens->get(1);
704 psPaperWidth = atoi(tok->getCString());
705 tok = (GString *)tokens->get(2);
706 psPaperHeight = atoi(tok->getCString());
707 psImageableLLX = psImageableLLY = 0;
708 psImageableURX = psPaperWidth;
709 psImageableURY = psPaperHeight;
711 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
712 fileName->getCString(), line);
716 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
718 if (tokens->getLength() != 5) {
719 error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
720 fileName->getCString(), line);
723 psImageableLLX = atoi(((GString *)tokens->get(1))->getCString());
724 psImageableLLY = atoi(((GString *)tokens->get(2))->getCString());
725 psImageableURX = atoi(((GString *)tokens->get(3))->getCString());
726 psImageableURY = atoi(((GString *)tokens->get(4))->getCString());
729 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
732 if (tokens->getLength() != 2) {
733 error(-1, "Bad 'psLevel' config file command (%s:%d)",
734 fileName->getCString(), line);
737 tok = (GString *)tokens->get(1);
738 if (!tok->cmp("level1")) {
740 } else if (!tok->cmp("level1sep")) {
741 psLevel = psLevel1Sep;
742 } else if (!tok->cmp("level2")) {
744 } else if (!tok->cmp("level2sep")) {
745 psLevel = psLevel2Sep;
746 } else if (!tok->cmp("level3")) {
748 } else if (!tok->cmp("level3Sep")) {
749 psLevel = psLevel3Sep;
751 error(-1, "Bad 'psLevel' config file command (%s:%d)",
752 fileName->getCString(), line);
756 void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
757 if (tokens->getLength() != 2) {
758 error(-1, "Bad 'psFile' config file command (%s:%d)",
759 fileName->getCString(), line);
765 psFile = ((GString *)tokens->get(1))->copy();
768 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
771 if (tokens->getLength() != 3) {
772 error(-1, "Bad 'psFont' config file command (%s:%d)",
773 fileName->getCString(), line);
776 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
777 ((GString *)tokens->get(2))->copy(), NULL);
778 psFonts->add(param->pdfFontName, param);
781 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
782 GList *tokens, GString *fileName, int line) {
787 if (tokens->getLength() != 5) {
788 error(-1, "Bad '%s' config file command (%s:%d)",
789 cmdName, fileName->getCString(), line);
792 tok = (GString *)tokens->get(2);
793 if (!tok->cmp("H")) {
795 } else if (!tok->cmp("V")) {
798 error(-1, "Bad '%s' config file command (%s:%d)",
799 cmdName, fileName->getCString(), line);
802 param = new PSFontParam(((GString *)tokens->get(1))->copy(),
804 ((GString *)tokens->get(3))->copy(),
805 ((GString *)tokens->get(4))->copy());
806 fontList->append(param);
809 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
811 if (tokens->getLength() != 2) {
812 error(-1, "Bad 'textEncoding' config file command (%s:%d)",
813 fileName->getCString(), line);
817 textEncoding = ((GString *)tokens->get(1))->copy();
820 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
823 if (tokens->getLength() != 2) {
824 error(-1, "Bad 'textEOL' config file command (%s:%d)",
825 fileName->getCString(), line);
828 tok = (GString *)tokens->get(1);
829 if (!tok->cmp("unix")) {
831 } else if (!tok->cmp("dos")) {
833 } else if (!tok->cmp("mac")) {
836 error(-1, "Bad 'textEOL' config file command (%s:%d)",
837 fileName->getCString(), line);
841 void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
842 if (tokens->getLength() != 2) {
843 error(-1, "Bad 'fontDir' config file command (%s:%d)",
844 fileName->getCString(), line);
847 fontDirs->append(((GString *)tokens->get(1))->copy());
850 void GlobalParams::parseInitialZoom(GList *tokens,
851 GString *fileName, int line) {
852 if (tokens->getLength() != 2) {
853 error(-1, "Bad 'initialZoom' config file command (%s:%d)",
854 fileName->getCString(), line);
858 initialZoom = ((GString *)tokens->get(1))->copy();
861 void GlobalParams::parseCommand(char *cmdName, GString **val,
862 GList *tokens, GString *fileName, int line) {
863 if (tokens->getLength() != 2) {
864 error(-1, "Bad '%s' config file command (%s:%d)",
865 cmdName, fileName->getCString(), line);
871 *val = ((GString *)tokens->get(1))->copy();
874 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
875 GList *tokens, GString *fileName, int line) {
878 if (tokens->getLength() != 2) {
879 error(-1, "Bad '%s' config file command (%s:%d)",
880 cmdName, fileName->getCString(), line);
883 tok = (GString *)tokens->get(1);
884 if (!parseYesNo2(tok->getCString(), flag)) {
885 error(-1, "Bad '%s' config file command (%s:%d)",
886 cmdName, fileName->getCString(), line);
890 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
891 if (!strcmp(token, "yes")) {
893 } else if (!strcmp(token, "no")) {
901 GlobalParams::~GlobalParams() {
906 freeBuiltinFontTables();
908 delete macRomanReverseMap;
910 delete nameToUnicode;
911 deleteGHash(cidToUnicodes, GString);
912 deleteGHash(unicodeToUnicodes, GString);
913 deleteGHash(residentUnicodeMaps, UnicodeMap);
914 deleteGHash(unicodeMaps, GString);
915 deleteGList(toUnicodeDirs, GString);
916 deleteGHash(displayFonts, DisplayFontParam);
917 deleteGHash(displayCIDFonts, DisplayFontParam);
918 deleteGHash(displayNamedCIDFonts, DisplayFontParam);
922 deleteGHash(psFonts, PSFontParam);
923 deleteGList(psNamedFonts16, PSFontParam);
924 deleteGList(psFonts16, PSFontParam);
926 deleteGList(fontDirs, GString);
935 cMapDirs->startIter(&iter);
936 while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
937 deleteGList(list, GString);
941 delete cidToUnicodeCache;
942 delete unicodeToUnicodeCache;
943 delete unicodeMapCache;
947 gDestroyMutex(&mutex);
948 gDestroyMutex(&unicodeMapCacheMutex);
949 gDestroyMutex(&cMapCacheMutex);
953 //------------------------------------------------------------------------
955 void GlobalParams::setupBaseFonts(char *dir) {
959 DisplayFontParam *dfp;
962 for (i = 0; displayFontTab[i].name; ++i) {
963 fontName = new GString(displayFontTab[i].name);
964 if (getDisplayFont(fontName)) {
970 fileName = appendToPath(new GString(dir), displayFontTab[i].fileName);
971 if ((f = fopen(fileName->getCString(), "rb"))) {
979 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
980 fileName = appendToPath(new GString(displayFontDirs[j]),
981 displayFontTab[i].fileName);
982 if ((f = fopen(fileName->getCString(), "rb"))) {
991 error(-1, "No display font for '%s'", displayFontTab[i].name);
995 dfp = new DisplayFontParam(fontName, displayFontT1);
996 dfp->t1.fileName = fileName;
997 globalParams->addDisplayFont(dfp);
1001 //------------------------------------------------------------------------
1003 //------------------------------------------------------------------------
1005 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
1006 // no need to lock - macRomanReverseMap is constant
1007 return macRomanReverseMap->lookup(charName);
1010 Unicode GlobalParams::mapNameToUnicode(char *charName) {
1011 // no need to lock - nameToUnicode is constant
1012 return nameToUnicode->lookup(charName);
1015 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
1019 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1027 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
1032 if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
1033 f = fopen(fileName->getCString(), "r");
1041 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
1049 if (!(list = (GList *)cMapDirs->lookup(collection))) {
1053 for (i = 0; i < list->getLength(); ++i) {
1054 dir = (GString *)list->get(i);
1055 fileName = appendToPath(dir->copy(), cMapName->getCString());
1056 f = fopen(fileName->getCString(), "r");
1067 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1068 GString *dir, *fileName;
1073 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1074 dir = (GString *)toUnicodeDirs->get(i);
1075 fileName = appendToPath(dir->copy(), name->getCString());
1076 f = fopen(fileName->getCString(), "r");
1087 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1088 DisplayFontParam *dfp;
1091 dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1096 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1097 GString *collection) {
1098 DisplayFontParam *dfp;
1102 !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1103 dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1109 GString *GlobalParams::getPSFile() {
1113 s = psFile ? psFile->copy() : (GString *)NULL;
1118 int GlobalParams::getPSPaperWidth() {
1127 int GlobalParams::getPSPaperHeight() {
1136 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1138 *llx = psImageableLLX;
1139 *lly = psImageableLLY;
1140 *urx = psImageableURX;
1141 *ury = psImageableURY;
1145 GBool GlobalParams::getPSCrop() {
1154 GBool GlobalParams::getPSExpandSmaller() {
1158 f = psExpandSmaller;
1163 GBool GlobalParams::getPSShrinkLarger() {
1172 GBool GlobalParams::getPSCenter() {
1181 GBool GlobalParams::getPSDuplex() {
1190 PSLevel GlobalParams::getPSLevel() {
1199 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1203 p = (PSFontParam *)psFonts->lookup(fontName);
1208 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1209 GString *collection, int wMode) {
1216 for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1217 p = (PSFontParam *)psNamedFonts16->get(i);
1218 if (!p->pdfFontName->cmp(fontName) &&
1219 p->wMode == wMode) {
1225 if (!p && collection) {
1226 for (i = 0; i < psFonts16->getLength(); ++i) {
1227 p = (PSFontParam *)psFonts16->get(i);
1228 if (!p->pdfFontName->cmp(collection) &&
1229 p->wMode == wMode) {
1239 GBool GlobalParams::getPSEmbedType1() {
1248 GBool GlobalParams::getPSEmbedTrueType() {
1252 e = psEmbedTrueType;
1257 GBool GlobalParams::getPSEmbedCIDPostScript() {
1261 e = psEmbedCIDPostScript;
1266 GBool GlobalParams::getPSEmbedCIDTrueType() {
1270 e = psEmbedCIDTrueType;
1275 GBool GlobalParams::getPSOPI() {
1284 GBool GlobalParams::getPSASCIIHex() {
1293 GString *GlobalParams::getTextEncodingName() {
1297 s = textEncoding->copy();
1302 EndOfLineKind GlobalParams::getTextEOL() {
1311 GBool GlobalParams::getTextPageBreaks() {
1315 pageBreaks = textPageBreaks;
1320 GBool GlobalParams::getTextKeepTinyChars() {
1324 tiny = textKeepTinyChars;
1329 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1330 GString *dir, *fileName;
1336 for (i = 0; i < fontDirs->getLength(); ++i) {
1337 dir = (GString *)fontDirs->get(i);
1338 for (ext = exts; *ext; ++ext) {
1339 fileName = appendToPath(dir->copy(), fontName->getCString());
1340 fileName->append(*ext);
1341 if ((f = fopen(fileName->getCString(), "rb"))) {
1353 GString *GlobalParams::getInitialZoom() {
1357 s = initialZoom->copy();
1362 GBool GlobalParams::getEnableT1lib() {
1371 GBool GlobalParams::getEnableFreeType() {
1381 GBool GlobalParams::getAntialias() {
1390 GBool GlobalParams::getMapNumericCharNames() {
1394 map = mapNumericCharNames;
1399 GBool GlobalParams::getPrintCommands() {
1408 GBool GlobalParams::getErrQuiet() {
1417 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1419 CharCodeToUnicode *ctu;
1422 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1423 if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1424 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1425 cidToUnicodeCache->add(ctu);
1432 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1433 CharCodeToUnicode *ctu;
1435 GString *fontPattern, *fileName;
1439 unicodeToUnicodes->startIter(&iter);
1440 while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1441 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1442 unicodeToUnicodes->killIter(&iter);
1448 if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1449 if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1450 unicodeToUnicodeCache->add(ctu);
1460 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1461 return getUnicodeMap2(encodingName);
1464 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1467 if (!(map = getResidentUnicodeMap(encodingName))) {
1468 lockUnicodeMapCache;
1469 map = unicodeMapCache->getUnicodeMap(encodingName);
1470 unlockUnicodeMapCache;
1475 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1479 cMap = cMapCache->getCMap(collection, cMapName);
1484 UnicodeMap *GlobalParams::getTextEncoding() {
1485 return getUnicodeMap2(textEncoding);
1488 //------------------------------------------------------------------------
1489 // functions to set parameters
1490 //------------------------------------------------------------------------
1492 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1493 DisplayFontParam *old;
1496 if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1499 displayFonts->add(param->name, param);
1503 void GlobalParams::setPSFile(char *file) {
1508 psFile = new GString(file);
1512 GBool GlobalParams::setPSPaperSize(char *size) {
1514 if (!strcmp(size, "match")) {
1515 psPaperWidth = psPaperHeight = -1;
1516 } else if (!strcmp(size, "letter")) {
1518 psPaperHeight = 792;
1519 } else if (!strcmp(size, "legal")) {
1521 psPaperHeight = 1008;
1522 } else if (!strcmp(size, "A4")) {
1524 psPaperHeight = 842;
1525 } else if (!strcmp(size, "A3")) {
1527 psPaperHeight = 1190;
1532 psImageableLLX = psImageableLLY = 0;
1533 psImageableURX = psPaperWidth;
1534 psImageableURY = psPaperHeight;
1539 void GlobalParams::setPSPaperWidth(int width) {
1541 psPaperWidth = width;
1543 psImageableURX = psPaperWidth;
1547 void GlobalParams::setPSPaperHeight(int height) {
1549 psPaperHeight = height;
1551 psImageableURY = psPaperHeight;
1555 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1557 psImageableLLX = llx;
1558 psImageableLLY = lly;
1559 psImageableURX = urx;
1560 psImageableURY = ury;
1564 void GlobalParams::setPSCrop(GBool crop) {
1570 void GlobalParams::setPSExpandSmaller(GBool expand) {
1572 psExpandSmaller = expand;
1576 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1578 psShrinkLarger = shrink;
1582 void GlobalParams::setPSCenter(GBool center) {
1588 void GlobalParams::setPSDuplex(GBool duplex) {
1594 void GlobalParams::setPSLevel(PSLevel level) {
1600 void GlobalParams::setPSEmbedType1(GBool embed) {
1602 psEmbedType1 = embed;
1606 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1608 psEmbedTrueType = embed;
1612 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1614 psEmbedCIDPostScript = embed;
1618 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1620 psEmbedCIDTrueType = embed;
1624 void GlobalParams::setPSOPI(GBool opi) {
1630 void GlobalParams::setPSASCIIHex(GBool hex) {
1636 void GlobalParams::setTextEncoding(char *encodingName) {
1638 delete textEncoding;
1639 textEncoding = new GString(encodingName);
1643 GBool GlobalParams::setTextEOL(char *s) {
1645 if (!strcmp(s, "unix")) {
1647 } else if (!strcmp(s, "dos")) {
1649 } else if (!strcmp(s, "mac")) {
1659 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1661 textPageBreaks = pageBreaks;
1665 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1667 textKeepTinyChars = keep;
1671 void GlobalParams::setInitialZoom(char *s) {
1674 initialZoom = new GString(s);
1678 GBool GlobalParams::setEnableT1lib(char *s) {
1682 ok = parseYesNo2(s, &enableT1lib);
1687 GBool GlobalParams::setEnableFreeType(char *s) {
1691 ok = parseYesNo2(s, &enableFreeType);
1697 GBool GlobalParams::setAntialias(char *s) {
1701 ok = parseYesNo2(s, &antialias);
1706 void GlobalParams::setMapNumericCharNames(GBool map) {
1708 mapNumericCharNames = map;
1712 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1714 printCommands = printCommandsA;
1718 void GlobalParams::setErrQuiet(GBool errQuietA) {
1720 errQuiet = errQuietA;