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
;