1 //========================================================================
5 // Copyright 2001-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
21 #include <fontconfig/fontconfig.h>
28 #include "NameToCharCode.h"
29 #include "CharCodeToUnicode.h"
30 #include "UnicodeMap.h"
32 #include "BuiltinFontTables.h"
33 #include "FontEncodingTables.h"
34 #include "GlobalParams.h"
37 # define lockGlobalParams gLockMutex(&mutex)
38 # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
39 # define lockCMapCache gLockMutex(&cMapCacheMutex)
40 # define unlockGlobalParams gUnlockMutex(&mutex)
41 # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
42 # define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
44 # define lockGlobalParams
45 # define lockUnicodeMapCache
46 # define lockCMapCache
47 # define unlockGlobalParams
48 # define unlockUnicodeMapCache
49 # define unlockCMapCache
52 #include "NameToUnicodeTable.h"
53 #include "UnicodeMapTables.h"
56 //------------------------------------------------------------------------
58 #define cidToUnicodeCacheSize 4
59 #define unicodeToUnicodeCacheSize 4
61 //------------------------------------------------------------------------
66 } displayFontTab[] = {
67 {"Courier", "n022003l.pfb"},
68 {"Courier-Bold", "n022004l.pfb"},
69 {"Courier-BoldOblique", "n022024l.pfb"},
70 {"Courier-Oblique", "n022023l.pfb"},
71 {"Helvetica", "n019003l.pfb"},
72 {"Helvetica-Bold", "n019004l.pfb"},
73 {"Helvetica-BoldOblique", "n019024l.pfb"},
74 {"Helvetica-Oblique", "n019023l.pfb"},
75 {"Symbol", "s050000l.pfb"},
76 {"Times-Bold", "n021004l.pfb"},
77 {"Times-BoldItalic", "n021024l.pfb"},
78 {"Times-Italic", "n021023l.pfb"},
79 {"Times-Roman", "n021003l.pfb"},
80 {"ZapfDingbats", "d050000l.pfb"},
84 static char *displayFontDirs[] = {
85 "/usr/share/ghostscript/fonts",
86 "/usr/local/share/ghostscript/fonts",
87 "/usr/share/fonts/default/Type1",
91 /* patterns originally from mupdf; added agfa fonts*/
95 } displayFontTabFc[] = {
96 {"Courier", "Courier,Nimbus Mono L,Courier New,Cumberland AMT,Cumberland:style=Regular,Roman:outline=true"},
97 {"Courier-Bold", "Courier,Nimbus Mono L,Courier New,Cumberland AMT,Cumberland:style=Bold:outline=true"},
98 {"Courier-BoldOblique", "Courier,Nimbus Mono L,Courier New,Cumberland AMT,Cumberland:style=Oblique,Italic:outline=true"},
99 {"Courier-Oblique", "Courier,Nimbus Mono L,Courier New,Cumberland AMT,Cumberland:style=BoldOblique,BoldItalic:outline=true"},
100 {"Helvetica", "Helvetica,Nimbus Sans L,Arial,Albany AMT,Albany:style=Regular,Roman:outline=true"},
101 {"Helvetica-Bold", "Helvetica,Nimbus Sans L,Arial,Albany AMT,Albany:style=Bold:outline=true"},
102 {"Helvetica-BoldOblique", "Helvetica,Nimbus Sans L,Arial,Albany AMT,Albany:style=Oblique,Italic:outline=true"},
103 {"Helvetica-Oblique", "Helvetica,Nimbus Sans L,Arial,Albany AMT,Albany:style=BoldOblique,BoldItalic:outline=true"},
104 /* FIXME Symbol should be first,
105 but that matches windows ttf which gets wrong encoding */
106 {"Symbol", "Standard Symbols L,Symbol:outline=true"},
107 {"Times-Bold", "Times,Nimbus Roman No9 L,Times New Roman,Thorndale AMT,Thorndale:style=Bold,Medium:outline=true"},
108 {"Times-BoldItalic", "Times,Nimbus Roman No9 L,Times New Roman,Thorndale AMT,Thorndale:style=BoldItalic,Medium Italic:outline=true"},
109 {"Times-Italic", "Times,Nimbus Roman No9 L,Times New Roman,Thorndale AMT,Thorndale:style=Italic,Regular Italic:outline=true"},
110 {"Times-Roman", "Times,Nimbus Roman No9 L,Times New Roman,Thorndale AMT,Thorndale:style=Regular,Roman:outline=true"},
111 {"ZapfDingbats", "Zapf Dingbats,Dingbats:outline=true"},
115 //------------------------------------------------------------------------
117 GlobalParams *globalParams = NULL;
119 //------------------------------------------------------------------------
121 //------------------------------------------------------------------------
123 DisplayFontParam::DisplayFontParam(GString *nameA,
124 DisplayFontParamKind kindA) {
137 DisplayFontParam::~DisplayFontParam() {
153 //------------------------------------------------------------------------
155 //------------------------------------------------------------------------
157 PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
158 GString *psFontNameA, GString *encodingA) {
159 pdfFontName = pdfFontNameA;
161 psFontName = psFontNameA;
162 encoding = encodingA;
165 PSFontParam::~PSFontParam() {
173 //------------------------------------------------------------------------
175 //------------------------------------------------------------------------
177 GlobalParams::GlobalParams(char *cfgFileName) {
185 gInitMutex(&unicodeMapCacheMutex);
186 gInitMutex(&cMapCacheMutex);
189 initBuiltinFontTables();
191 // scan the encoding in reverse because we want the lowest-numbered
192 // index for each char name ('space' is encoded twice)
193 macRomanReverseMap = new NameToCharCode();
194 for (i = 255; i >= 0; --i) {
195 if (macRomanEncoding[i]) {
196 macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
200 nameToUnicode = new NameToCharCode();
201 cidToUnicodes = new GHash(gTrue);
202 unicodeToUnicodes = new GHash(gTrue);
203 residentUnicodeMaps = new GHash();
204 unicodeMaps = new GHash(gTrue);
205 cMapDirs = new GHash(gTrue);
206 toUnicodeDirs = new GList();
207 displayFonts = new GHash();
208 displayCIDFonts = new GHash();
209 displayNamedCIDFonts = new GHash();
212 const struct paper *paperType;
214 if ((paperName = systempapername())) {
215 paperType = paperinfo(paperName);
216 psPaperWidth = (int)paperpswidth(paperType);
217 psPaperHeight = (int)paperpsheight(paperType);
219 error(-1, "No paper information available - using defaults");
220 psPaperWidth = defPaperWidth;
221 psPaperHeight = defPaperHeight;
225 psPaperWidth = defPaperWidth;
226 psPaperHeight = defPaperHeight;
228 psImageableLLX = psImageableLLY = 0;
229 psImageableURX = psPaperWidth;
230 psImageableURY = psPaperHeight;
232 psExpandSmaller = gFalse;
233 psShrinkLarger = gTrue;
238 psFonts = new GHash();
239 psNamedFonts16 = new GList();
240 psFonts16 = new GList();
241 psEmbedType1 = gTrue;
242 psEmbedTrueType = gTrue;
243 psEmbedCIDPostScript = gTrue;
244 psEmbedCIDTrueType = gTrue;
247 textEncoding = new GString("Latin1");
255 textPageBreaks = gTrue;
256 textKeepTinyChars = gFalse;
257 fontDirs = new GList();
258 initialZoom = new GString("125");
260 enableFreeType = gTrue;
264 mapNumericCharNames = gTrue;
265 printCommands = gFalse;
268 cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
269 unicodeToUnicodeCache =
270 new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
271 unicodeMapCache = new UnicodeMapCache();
272 cMapCache = new CMapCache();
274 // set up the initial nameToUnicode table
275 for (i = 0; nameToUnicodeTab[i].name; ++i) {
276 nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
279 // set up the residentUnicodeMaps table
280 map = new UnicodeMap("Latin1", gFalse,
281 latin1UnicodeMapRanges, latin1UnicodeMapLen);
282 residentUnicodeMaps->add(map->getEncodingName(), map);
283 map = new UnicodeMap("ASCII7", gFalse,
284 ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
285 residentUnicodeMaps->add(map->getEncodingName(), map);
286 map = new UnicodeMap("Symbol", gFalse,
287 symbolUnicodeMapRanges, symbolUnicodeMapLen);
288 residentUnicodeMaps->add(map->getEncodingName(), map);
289 map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
290 zapfDingbatsUnicodeMapLen);
291 residentUnicodeMaps->add(map->getEncodingName(), map);
292 map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
293 residentUnicodeMaps->add(map->getEncodingName(), map);
294 map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
295 residentUnicodeMaps->add(map->getEncodingName(), map);
297 // look for a user config file, then a system-wide config file
300 if (cfgFileName && cfgFileName[0]) {
301 fileName = new GString(cfgFileName);
302 if (!(f = fopen(fileName->getCString(), "r"))) {
307 fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
308 if (!(f = fopen(fileName->getCString(), "r"))) {
313 #if defined(WIN32) && !defined(__CYGWIN32__)
315 i = GetModuleFileName(NULL, buf, sizeof(buf));
316 if (i <= 0 || i >= sizeof(buf)) {
317 // error or path too long for buffer - just use the current dir
320 fileName = grabPath(buf);
321 appendToPath(fileName, xpdfSysConfigFile);
323 fileName = new GString(xpdfSysConfigFile);
325 if (!(f = fopen(fileName->getCString(), "r"))) {
330 parseFile(fileName, f);
336 void GlobalParams::parseFile(GString *fileName, FILE *f) {
339 GString *cmd, *incFile;
345 while (getLine(buf, sizeof(buf) - 1, f)) {
347 // break the line into tokens
348 tokens = new GList();
351 for (; *p1 && isspace(*p1); ++p1) ;
355 if (*p1 == '"' || *p1 == '\'') {
356 for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
359 for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
361 tokens->append(new GString(p1, p2 - p1));
362 p1 = *p2 ? p2 + 1 : p2;
365 if (tokens->getLength() > 0 &&
366 ((GString *)tokens->get(0))->getChar(0) != '#') {
367 cmd = (GString *)tokens->get(0);
368 if (!cmd->cmp("include")) {
369 if (tokens->getLength() == 2) {
370 incFile = (GString *)tokens->get(1);
371 if ((f2 = fopen(incFile->getCString(), "r"))) {
372 parseFile(incFile, f2);
375 error(-1, "Couldn't find included config file: '%s' (%s:%d)",
376 incFile->getCString(), fileName->getCString(), line);
379 error(-1, "Bad 'include' config file command (%s:%d)",
380 fileName->getCString(), line);
382 } else if (!cmd->cmp("nameToUnicode")) {
383 parseNameToUnicode(tokens, fileName, line);
384 } else if (!cmd->cmp("cidToUnicode")) {
385 parseCIDToUnicode(tokens, fileName, line);
386 } else if (!cmd->cmp("unicodeToUnicode")) {
387 parseUnicodeToUnicode(tokens, fileName, line);
388 } else if (!cmd->cmp("unicodeMap")) {
389 parseUnicodeMap(tokens, fileName, line);
390 } else if (!cmd->cmp("cMapDir")) {
391 parseCMapDir(tokens, fileName, line);
392 } else if (!cmd->cmp("toUnicodeDir")) {
393 parseToUnicodeDir(tokens, fileName, line);
394 } else if (!cmd->cmp("displayFontT1")) {
395 parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
396 } else if (!cmd->cmp("displayFontTT")) {
397 parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
398 } else if (!cmd->cmp("displayNamedCIDFontT1")) {
399 parseDisplayFont(tokens, displayNamedCIDFonts,
400 displayFontT1, fileName, line);
401 } else if (!cmd->cmp("displayCIDFontT1")) {
402 parseDisplayFont(tokens, displayCIDFonts,
403 displayFontT1, fileName, line);
404 } else if (!cmd->cmp("displayNamedCIDFontTT")) {
405 parseDisplayFont(tokens, displayNamedCIDFonts,
406 displayFontTT, fileName, line);
407 } else if (!cmd->cmp("displayCIDFontTT")) {
408 parseDisplayFont(tokens, displayCIDFonts,
409 displayFontTT, fileName, line);
410 } else if (!cmd->cmp("psFile")) {
411 parsePSFile(tokens, fileName, line);
412 } else if (!cmd->cmp("psFont")) {
413 parsePSFont(tokens, fileName, line);
414 } else if (!cmd->cmp("psNamedFont16")) {
415 parsePSFont16("psNamedFont16", psNamedFonts16,
416 tokens, fileName, line);
417 } else if (!cmd->cmp("psFont16")) {
418 parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
419 } else if (!cmd->cmp("psPaperSize")) {
420 parsePSPaperSize(tokens, fileName, line);
421 } else if (!cmd->cmp("psImageableArea")) {
422 parsePSImageableArea(tokens, fileName, line);
423 } else if (!cmd->cmp("psCrop")) {
424 parseYesNo("psCrop", &psCrop, tokens, fileName, line);
425 } else if (!cmd->cmp("psExpandSmaller")) {
426 parseYesNo("psExpandSmaller", &psExpandSmaller,
427 tokens, fileName, line);
428 } else if (!cmd->cmp("psShrinkLarger")) {
429 parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
430 } else if (!cmd->cmp("psCenter")) {
431 parseYesNo("psCenter", &psCenter, tokens, fileName, line);
432 } else if (!cmd->cmp("psDuplex")) {
433 parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
434 } else if (!cmd->cmp("psLevel")) {
435 parsePSLevel(tokens, fileName, line);
436 } else if (!cmd->cmp("psEmbedType1Fonts")) {
437 parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
438 } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
439 parseYesNo("psEmbedTrueType", &psEmbedTrueType,
440 tokens, fileName, line);
441 } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
442 parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
443 tokens, fileName, line);
444 } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
445 parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
446 tokens, fileName, line);
447 } else if (!cmd->cmp("psOPI")) {
448 parseYesNo("psOPI", &psOPI, tokens, fileName, line);
449 } else if (!cmd->cmp("psASCIIHex")) {
450 parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
451 } else if (!cmd->cmp("textEncoding")) {
452 parseTextEncoding(tokens, fileName, line);
453 } else if (!cmd->cmp("textEOL")) {
454 parseTextEOL(tokens, fileName, line);
455 } else if (!cmd->cmp("textPageBreaks")) {
456 parseYesNo("textPageBreaks", &textPageBreaks,
457 tokens, fileName, line);
458 } else if (!cmd->cmp("textKeepTinyChars")) {
459 parseYesNo("textKeepTinyChars", &textKeepTinyChars,
460 tokens, fileName, line);
461 } else if (!cmd->cmp("fontDir")) {
462 parseFontDir(tokens, fileName, line);
463 } else if (!cmd->cmp("initialZoom")) {
464 parseInitialZoom(tokens, fileName, line);
465 } else if (!cmd->cmp("enableT1lib")) {
466 parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
467 } else if (!cmd->cmp("enableFreeType")) {
468 parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
469 } else if (!cmd->cmp("antialias")) {
470 parseYesNo("antialias", &antialias, tokens, fileName, line);
471 } else if (!cmd->cmp("urlCommand")) {
472 parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
473 } else if (!cmd->cmp("movieCommand")) {
474 parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
475 } else if (!cmd->cmp("mapNumericCharNames")) {
476 parseYesNo("mapNumericCharNames", &mapNumericCharNames,
477 tokens, fileName, line);
478 } else if (!cmd->cmp("printCommands")) {
479 parseYesNo("printCommands", &printCommands, tokens, fileName, line);
480 } else if (!cmd->cmp("errQuiet")) {
481 parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
483 error(-1, "Unknown config file command '%s' (%s:%d)",
484 cmd->getCString(), fileName->getCString(), line);
485 if (!cmd->cmp("displayFontX") ||
486 !cmd->cmp("displayNamedCIDFontX") ||
487 !cmd->cmp("displayCIDFontX")) {
488 error(-1, "-- Xpdf no longer supports X fonts");
489 } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
490 error(-1, "-- The t1libControl and freetypeControl options have been replaced");
491 error(-1, " by the enableT1lib, enableFreeType, and antialias options");
492 } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
493 error(-1, "-- the config file format has changed since Xpdf 0.9x");
498 deleteGList(tokens, GString);
503 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
512 if (tokens->getLength() != 2) {
513 error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
514 fileName->getCString(), line);
517 name = (GString *)tokens->get(1);
518 if (!(f = fopen(name->getCString(), "r"))) {
519 error(-1, "Couldn't open 'nameToUnicode' file '%s'",
524 while (getLine(buf, sizeof(buf), f)) {
525 tok1 = strtok(buf, " \t\r\n");
526 tok2 = strtok(NULL, " \t\r\n");
528 sscanf(tok1, "%x", &u);
529 nameToUnicode->add(tok2, u);
531 error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
538 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
540 GString *collection, *name, *old;
542 if (tokens->getLength() != 3) {
543 error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
544 fileName->getCString(), line);
547 collection = (GString *)tokens->get(1);
548 name = (GString *)tokens->get(2);
549 if ((old = (GString *)cidToUnicodes->remove(collection))) {
552 cidToUnicodes->add(collection->copy(), name->copy());
555 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
557 GString *font, *file, *old;
559 if (tokens->getLength() != 3) {
560 error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
561 fileName->getCString(), line);
564 font = (GString *)tokens->get(1);
565 file = (GString *)tokens->get(2);
566 if ((old = (GString *)unicodeToUnicodes->remove(font))) {
569 unicodeToUnicodes->add(font->copy(), file->copy());
572 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
574 GString *encodingName, *name, *old;
576 if (tokens->getLength() != 3) {
577 error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
578 fileName->getCString(), line);
581 encodingName = (GString *)tokens->get(1);
582 name = (GString *)tokens->get(2);
583 if ((old = (GString *)unicodeMaps->remove(encodingName))) {
586 unicodeMaps->add(encodingName->copy(), name->copy());
589 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
590 GString *collection, *dir;
593 if (tokens->getLength() != 3) {
594 error(-1, "Bad 'cMapDir' config file command (%s:%d)",
595 fileName->getCString(), line);
598 collection = (GString *)tokens->get(1);
599 dir = (GString *)tokens->get(2);
600 if (!(list = (GList *)cMapDirs->lookup(collection))) {
602 cMapDirs->add(collection->copy(), list);
604 list->append(dir->copy());
607 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
609 if (tokens->getLength() != 2) {
610 error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
611 fileName->getCString(), line);
614 toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
617 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
618 DisplayFontParamKind kind,
619 GString *fileName, int line) {
620 DisplayFontParam *param, *old;
622 if (tokens->getLength() < 2) {
625 param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
629 if (tokens->getLength() != 3) {
632 param->t1.fileName = ((GString *)tokens->get(2))->copy();
635 if (tokens->getLength() != 3) {
638 param->tt.fileName = ((GString *)tokens->get(2))->copy();
642 if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
645 fontHash->add(param->name, param);
651 error(-1, "Bad 'display*Font*' config file command (%s:%d)",
652 fileName->getCString(), line);
655 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
659 if (tokens->getLength() == 2) {
660 tok = (GString *)tokens->get(1);
661 if (!setPSPaperSize(tok->getCString())) {
662 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
663 fileName->getCString(), line);
665 } else if (tokens->getLength() == 3) {
666 tok = (GString *)tokens->get(1);
667 psPaperWidth = atoi(tok->getCString());
668 tok = (GString *)tokens->get(2);
669 psPaperHeight = atoi(tok->getCString());
670 psImageableLLX = psImageableLLY = 0;
671 psImageableURX = psPaperWidth;
672 psImageableURY = psPaperHeight;
674 error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
675 fileName->getCString(), line);
679 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
681 if (tokens->getLength() != 5) {
682 error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
683 fileName->getCString(), line);
686 psImageableLLX = atoi(((GString *)tokens->get(1))->getCString());
687 psImageableLLY = atoi(((GString *)tokens->get(2))->getCString());
688 psImageableURX = atoi(((GString *)tokens->get(3))->getCString());
689 psImageableURY = atoi(((GString *)tokens->get(4))->getCString());
692 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
695 if (tokens->getLength() != 2) {
696 error(-1, "Bad 'psLevel' config file command (%s:%d)",
697 fileName->getCString(), line);
700 tok = (GString *)tokens->get(1);
701 if (!tok->cmp("level1")) {
703 } else if (!tok->cmp("level1sep")) {
704 psLevel = psLevel1Sep;
705 } else if (!tok->cmp("level2")) {
707 } else if (!tok->cmp("level2sep")) {
708 psLevel = psLevel2Sep;
709 } else if (!tok->cmp("level3")) {
711 } else if (!tok->cmp("level3Sep")) {
712 psLevel = psLevel3Sep;
714 error(-1, "Bad 'psLevel' config file command (%s:%d)",
715 fileName->getCString(), line);
719 void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
720 if (tokens->getLength() != 2) {
721 error(-1, "Bad 'psFile' config file command (%s:%d)",
722 fileName->getCString(), line);
728 psFile = ((GString *)tokens->get(1))->copy();
731 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
734 if (tokens->getLength() != 3) {
735 error(-1, "Bad 'psFont' config file command (%s:%d)",
736 fileName->getCString(), line);
739 param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
740 ((GString *)tokens->get(2))->copy(), NULL);
741 psFonts->add(param->pdfFontName, param);
744 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
745 GList *tokens, GString *fileName, int line) {
750 if (tokens->getLength() != 5) {
751 error(-1, "Bad '%s' config file command (%s:%d)",
752 cmdName, fileName->getCString(), line);
755 tok = (GString *)tokens->get(2);
756 if (!tok->cmp("H")) {
758 } else if (!tok->cmp("V")) {
761 error(-1, "Bad '%s' config file command (%s:%d)",
762 cmdName, fileName->getCString(), line);
765 param = new PSFontParam(((GString *)tokens->get(1))->copy(),
767 ((GString *)tokens->get(3))->copy(),
768 ((GString *)tokens->get(4))->copy());
769 fontList->append(param);
772 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
774 if (tokens->getLength() != 2) {
775 error(-1, "Bad 'textEncoding' config file command (%s:%d)",
776 fileName->getCString(), line);
780 textEncoding = ((GString *)tokens->get(1))->copy();
783 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
786 if (tokens->getLength() != 2) {
787 error(-1, "Bad 'textEOL' config file command (%s:%d)",
788 fileName->getCString(), line);
791 tok = (GString *)tokens->get(1);
792 if (!tok->cmp("unix")) {
794 } else if (!tok->cmp("dos")) {
796 } else if (!tok->cmp("mac")) {
799 error(-1, "Bad 'textEOL' config file command (%s:%d)",
800 fileName->getCString(), line);
804 void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
805 if (tokens->getLength() != 2) {
806 error(-1, "Bad 'fontDir' config file command (%s:%d)",
807 fileName->getCString(), line);
810 fontDirs->append(((GString *)tokens->get(1))->copy());
813 void GlobalParams::parseInitialZoom(GList *tokens,
814 GString *fileName, int line) {
815 if (tokens->getLength() != 2) {
816 error(-1, "Bad 'initialZoom' config file command (%s:%d)",
817 fileName->getCString(), line);
821 initialZoom = ((GString *)tokens->get(1))->copy();
824 void GlobalParams::parseCommand(char *cmdName, GString **val,
825 GList *tokens, GString *fileName, int line) {
826 if (tokens->getLength() != 2) {
827 error(-1, "Bad '%s' config file command (%s:%d)",
828 cmdName, fileName->getCString(), line);
834 *val = ((GString *)tokens->get(1))->copy();
837 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
838 GList *tokens, GString *fileName, int line) {
841 if (tokens->getLength() != 2) {
842 error(-1, "Bad '%s' config file command (%s:%d)",
843 cmdName, fileName->getCString(), line);
846 tok = (GString *)tokens->get(1);
847 if (!parseYesNo2(tok->getCString(), flag)) {
848 error(-1, "Bad '%s' config file command (%s:%d)",
849 cmdName, fileName->getCString(), line);
853 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
854 if (!strcmp(token, "yes")) {
856 } else if (!strcmp(token, "no")) {
864 GlobalParams::~GlobalParams() {
869 freeBuiltinFontTables();
871 delete macRomanReverseMap;
873 delete nameToUnicode;
874 deleteGHash(cidToUnicodes, GString);
875 deleteGHash(unicodeToUnicodes, GString);
876 deleteGHash(residentUnicodeMaps, UnicodeMap);
877 deleteGHash(unicodeMaps, GString);
878 deleteGList(toUnicodeDirs, GString);
879 deleteGHash(displayFonts, DisplayFontParam);
880 deleteGHash(displayCIDFonts, DisplayFontParam);
881 deleteGHash(displayNamedCIDFonts, DisplayFontParam);
885 deleteGHash(psFonts, PSFontParam);
886 deleteGList(psNamedFonts16, PSFontParam);
887 deleteGList(psFonts16, PSFontParam);
889 deleteGList(fontDirs, GString);
898 cMapDirs->startIter(&iter);
899 while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
900 deleteGList(list, GString);
904 delete cidToUnicodeCache;
905 delete unicodeToUnicodeCache;
906 delete unicodeMapCache;
910 gDestroyMutex(&mutex);
911 gDestroyMutex(&unicodeMapCacheMutex);
912 gDestroyMutex(&cMapCacheMutex);
916 //------------------------------------------------------------------------
918 void GlobalParams::setupBaseFonts(char *dir) {
922 DisplayFontParam *dfp;
925 for (i = 0; displayFontTab[i].name; ++i) {
926 fontName = new GString(displayFontTab[i].name);
927 if (getDisplayFont(fontName)) {
933 fileName = appendToPath(new GString(dir), displayFontTab[i].fileName);
934 if ((f = fopen(fileName->getCString(), "rb"))) {
942 for (j = 0; !fileName && displayFontDirs[j]; ++j) {
943 fileName = appendToPath(new GString(displayFontDirs[j]),
944 displayFontTab[i].fileName);
945 if ((f = fopen(fileName->getCString(), "rb"))) {
954 error(-1, "No display font for '%s'", displayFontTab[i].name);
958 dfp = new DisplayFontParam(fontName, displayFontT1);
959 dfp->t1.fileName = fileName;
960 globalParams->addDisplayFont(dfp);
964 //------------------------------------------------------------------------
966 void GlobalParams::setupBaseFontsFc(FcConfig *fcConfig) {
969 DisplayFontParam *dfp;
970 FcPattern *namePat, *matchPat;
974 DisplayFontParamKind kind;
976 for (i = 0; displayFontTabFc[i].name; ++i) {
977 fontName = new GString(displayFontTabFc[i].name);
978 if (getDisplayFont(fontName)) {
983 result = FcResultMatch;
984 namePat = FcNameParse((const FcChar8 *)displayFontTabFc[i].pattern);
985 FcConfigSubstitute(fcConfig, namePat, FcMatchPattern);
986 FcDefaultSubstitute(namePat);
987 matchPat = FcFontMatch(fcConfig, namePat, &result);
989 if (result == FcResultMatch) {
990 result = FcPatternGetString(matchPat, "file", 0, &fcFileName);
991 if (result == FcResultMatch)
992 fileName = new GString((const char *)fcFileName);
995 FcPatternDestroy(matchPat);
996 FcPatternDestroy(namePat);
1002 ext = strrchr(fileName->getCString(), '.');
1004 if (strcasecmp (ext, ".pfb") == 0)
1005 kind = displayFontT1;
1006 else if (strcasecmp (ext, ".pfa") == 0)
1007 kind = displayFontT1;
1008 else if (strcasecmp (ext, ".ttf") == 0)
1009 kind = displayFontTT;
1010 else if (strcasecmp (ext, ".ttc") == 0)
1011 kind = displayFontTT;
1023 error(-1, "No display font for '%s'", displayFontTabFc[i].name);
1028 dfp = new DisplayFontParam(fontName, kind);
1031 dfp->t1.fileName = fileName;
1034 dfp->tt.fileName = fileName;
1037 globalParams->addDisplayFont(dfp);
1041 //------------------------------------------------------------------------
1043 //------------------------------------------------------------------------
1045 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
1046 // no need to lock - macRomanReverseMap is constant
1047 return macRomanReverseMap->lookup(charName);
1050 Unicode GlobalParams::mapNameToUnicode(char *charName) {
1051 // no need to lock - nameToUnicode is constant
1052 return nameToUnicode->lookup(charName);
1055 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
1059 map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1067 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
1072 if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
1073 f = fopen(fileName->getCString(), "r");
1081 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
1089 if (!(list = (GList *)cMapDirs->lookup(collection))) {
1093 for (i = 0; i < list->getLength(); ++i) {
1094 dir = (GString *)list->get(i);
1095 fileName = appendToPath(dir->copy(), cMapName->getCString());
1096 f = fopen(fileName->getCString(), "r");
1107 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1108 GString *dir, *fileName;
1113 for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1114 dir = (GString *)toUnicodeDirs->get(i);
1115 fileName = appendToPath(dir->copy(), name->getCString());
1116 f = fopen(fileName->getCString(), "r");
1127 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1128 DisplayFontParam *dfp;
1131 dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1136 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1137 GString *collection) {
1138 DisplayFontParam *dfp;
1142 !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1143 dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1149 GString *GlobalParams::getPSFile() {
1153 s = psFile ? psFile->copy() : (GString *)NULL;
1158 int GlobalParams::getPSPaperWidth() {
1167 int GlobalParams::getPSPaperHeight() {
1176 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1178 *llx = psImageableLLX;
1179 *lly = psImageableLLY;
1180 *urx = psImageableURX;
1181 *ury = psImageableURY;
1185 GBool GlobalParams::getPSCrop() {
1194 GBool GlobalParams::getPSExpandSmaller() {
1198 f = psExpandSmaller;
1203 GBool GlobalParams::getPSShrinkLarger() {
1212 GBool GlobalParams::getPSCenter() {
1221 GBool GlobalParams::getPSDuplex() {
1230 PSLevel GlobalParams::getPSLevel() {
1239 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1243 p = (PSFontParam *)psFonts->lookup(fontName);
1248 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1249 GString *collection, int wMode) {
1256 for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1257 p = (PSFontParam *)psNamedFonts16->get(i);
1258 if (!p->pdfFontName->cmp(fontName) &&
1259 p->wMode == wMode) {
1265 if (!p && collection) {
1266 for (i = 0; i < psFonts16->getLength(); ++i) {
1267 p = (PSFontParam *)psFonts16->get(i);
1268 if (!p->pdfFontName->cmp(collection) &&
1269 p->wMode == wMode) {
1279 GBool GlobalParams::getPSEmbedType1() {
1288 GBool GlobalParams::getPSEmbedTrueType() {
1292 e = psEmbedTrueType;
1297 GBool GlobalParams::getPSEmbedCIDPostScript() {
1301 e = psEmbedCIDPostScript;
1306 GBool GlobalParams::getPSEmbedCIDTrueType() {
1310 e = psEmbedCIDTrueType;
1315 GBool GlobalParams::getPSOPI() {
1324 GBool GlobalParams::getPSASCIIHex() {
1333 GString *GlobalParams::getTextEncodingName() {
1337 s = textEncoding->copy();
1342 EndOfLineKind GlobalParams::getTextEOL() {
1351 GBool GlobalParams::getTextPageBreaks() {
1355 pageBreaks = textPageBreaks;
1360 GBool GlobalParams::getTextKeepTinyChars() {
1364 tiny = textKeepTinyChars;
1369 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1370 GString *dir, *fileName;
1376 for (i = 0; i < fontDirs->getLength(); ++i) {
1377 dir = (GString *)fontDirs->get(i);
1378 for (ext = exts; *ext; ++ext) {
1379 fileName = appendToPath(dir->copy(), fontName->getCString());
1380 fileName->append(*ext);
1381 if ((f = fopen(fileName->getCString(), "rb"))) {
1393 GString *GlobalParams::getInitialZoom() {
1397 s = initialZoom->copy();
1402 GBool GlobalParams::getEnableT1lib() {
1411 GBool GlobalParams::getEnableFreeType() {
1421 GBool GlobalParams::getAntialias() {
1430 GBool GlobalParams::getMapNumericCharNames() {
1434 map = mapNumericCharNames;
1439 GBool GlobalParams::getPrintCommands() {
1448 GBool GlobalParams::getErrQuiet() {
1457 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1459 CharCodeToUnicode *ctu;
1462 if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1463 if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1464 (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1465 cidToUnicodeCache->add(ctu);
1472 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1473 CharCodeToUnicode *ctu;
1475 GString *fontPattern, *fileName;
1479 unicodeToUnicodes->startIter(&iter);
1480 while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1481 if (strstr(fontName->getCString(), fontPattern->getCString())) {
1482 unicodeToUnicodes->killIter(&iter);
1488 if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1489 if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1490 unicodeToUnicodeCache->add(ctu);
1500 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1501 return getUnicodeMap2(encodingName);
1504 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1507 if (!(map = getResidentUnicodeMap(encodingName))) {
1508 lockUnicodeMapCache;
1509 map = unicodeMapCache->getUnicodeMap(encodingName);
1510 unlockUnicodeMapCache;
1515 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1519 cMap = cMapCache->getCMap(collection, cMapName);
1524 UnicodeMap *GlobalParams::getTextEncoding() {
1525 return getUnicodeMap2(textEncoding);
1528 //------------------------------------------------------------------------
1529 // functions to set parameters
1530 //------------------------------------------------------------------------
1532 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1533 DisplayFontParam *old;
1536 if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1539 displayFonts->add(param->name, param);
1543 void GlobalParams::setPSFile(char *file) {
1548 psFile = new GString(file);
1552 GBool GlobalParams::setPSPaperSize(char *size) {
1554 if (!strcmp(size, "match")) {
1555 psPaperWidth = psPaperHeight = -1;
1556 } else if (!strcmp(size, "letter")) {
1558 psPaperHeight = 792;
1559 } else if (!strcmp(size, "legal")) {
1561 psPaperHeight = 1008;
1562 } else if (!strcmp(size, "A4")) {
1564 psPaperHeight = 842;
1565 } else if (!strcmp(size, "A3")) {
1567 psPaperHeight = 1190;
1572 psImageableLLX = psImageableLLY = 0;
1573 psImageableURX = psPaperWidth;
1574 psImageableURY = psPaperHeight;
1579 void GlobalParams::setPSPaperWidth(int width) {
1581 psPaperWidth = width;
1583 psImageableURX = psPaperWidth;
1587 void GlobalParams::setPSPaperHeight(int height) {
1589 psPaperHeight = height;
1591 psImageableURY = psPaperHeight;
1595 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1597 psImageableLLX = llx;
1598 psImageableLLY = lly;
1599 psImageableURX = urx;
1600 psImageableURY = ury;
1604 void GlobalParams::setPSCrop(GBool crop) {
1610 void GlobalParams::setPSExpandSmaller(GBool expand) {
1612 psExpandSmaller = expand;
1616 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1618 psShrinkLarger = shrink;
1622 void GlobalParams::setPSCenter(GBool center) {
1628 void GlobalParams::setPSDuplex(GBool duplex) {
1634 void GlobalParams::setPSLevel(PSLevel level) {
1640 void GlobalParams::setPSEmbedType1(GBool embed) {
1642 psEmbedType1 = embed;
1646 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1648 psEmbedTrueType = embed;
1652 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1654 psEmbedCIDPostScript = embed;
1658 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1660 psEmbedCIDTrueType = embed;
1664 void GlobalParams::setPSOPI(GBool opi) {
1670 void GlobalParams::setPSASCIIHex(GBool hex) {
1676 void GlobalParams::setTextEncoding(char *encodingName) {
1678 delete textEncoding;
1679 textEncoding = new GString(encodingName);
1683 GBool GlobalParams::setTextEOL(char *s) {
1685 if (!strcmp(s, "unix")) {
1687 } else if (!strcmp(s, "dos")) {
1689 } else if (!strcmp(s, "mac")) {
1699 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1701 textPageBreaks = pageBreaks;
1705 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1707 textKeepTinyChars = keep;
1711 void GlobalParams::setInitialZoom(char *s) {
1714 initialZoom = new GString(s);
1718 GBool GlobalParams::setEnableT1lib(char *s) {
1722 ok = parseYesNo2(s, &enableT1lib);
1727 GBool GlobalParams::setEnableFreeType(char *s) {
1731 ok = parseYesNo2(s, &enableFreeType);
1737 GBool GlobalParams::setAntialias(char *s) {
1741 ok = parseYesNo2(s, &antialias);
1746 void GlobalParams::setMapNumericCharNames(GBool map) {
1748 mapNumericCharNames = map;
1752 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1754 printCommands = printCommandsA;
1758 void GlobalParams::setErrQuiet(GBool errQuietA) {
1760 errQuiet = errQuietA;