upgrade to xpdf 3.00.
[swftools.git] / pdf2swf / xpdf / GlobalParams.cc
1 //========================================================================
2 //
3 // GlobalParams.cc
4 //
5 // Copyright 2001-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8
9 #include <aconf.h>
10
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
13 #endif
14
15 #include <string.h>
16 #include <stdio.h>
17 #include <ctype.h>
18 #if HAVE_PAPER_H
19 #include <paper.h>
20 #endif
21 #include "gmem.h"
22 #include "GString.h"
23 #include "GList.h"
24 #include "GHash.h"
25 #include "gfile.h"
26 #include "Error.h"
27 #include "NameToCharCode.h"
28 #include "CharCodeToUnicode.h"
29 #include "UnicodeMap.h"
30 #include "CMap.h"
31 #include "BuiltinFontTables.h"
32 #include "FontEncodingTables.h"
33 #include "GlobalParams.h"
34
35 #if MULTITHREADED
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)
42 #else
43 #  define lockGlobalParams
44 #  define lockUnicodeMapCache
45 #  define lockCMapCache
46 #  define unlockGlobalParams
47 #  define unlockUnicodeMapCache
48 #  define unlockCMapCache
49 #endif
50
51 #include "NameToUnicodeTable.h"
52 #include "UnicodeMapTables.h"
53 #include "UTF8.h"
54
55 //------------------------------------------------------------------------
56
57 #define cidToUnicodeCacheSize     4
58 #define unicodeToUnicodeCacheSize 4
59
60 //------------------------------------------------------------------------
61
62 static struct {
63   char *name;
64   char *fileName;
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"},
80   {NULL}
81 };
82
83 static char *displayFontDirs[] = {
84   "/usr/share/ghostscript/fonts",
85   "/usr/local/share/ghostscript/fonts",
86   "/usr/share/fonts/default/Type1",
87   NULL
88 };
89
90 //------------------------------------------------------------------------
91
92 GlobalParams *globalParams = NULL;
93
94 //------------------------------------------------------------------------
95 // DisplayFontParam
96 //------------------------------------------------------------------------
97
98 DisplayFontParam::DisplayFontParam(GString *nameA,
99                                    DisplayFontParamKind kindA) {
100   name = nameA;
101   kind = kindA;
102   switch (kind) {
103   case displayFontT1:
104     t1.fileName = NULL;
105     break;
106   case displayFontTT:
107     tt.fileName = NULL;
108     break;
109   }
110 }
111
112 DisplayFontParam::~DisplayFontParam() {
113   delete name;
114   switch (kind) {
115   case displayFontT1:
116     if (t1.fileName) {
117       delete t1.fileName;
118     }
119     break;
120   case displayFontTT:
121     if (tt.fileName) {
122       delete tt.fileName;
123     }
124     break;
125   }
126 }
127
128 //------------------------------------------------------------------------
129 // PSFontParam
130 //------------------------------------------------------------------------
131
132 PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
133                          GString *psFontNameA, GString *encodingA) {
134   pdfFontName = pdfFontNameA;
135   wMode = wModeA;
136   psFontName = psFontNameA;
137   encoding = encodingA;
138 }
139
140 PSFontParam::~PSFontParam() {
141   delete pdfFontName;
142   delete psFontName;
143   if (encoding) {
144     delete encoding;
145   }
146 }
147
148 //------------------------------------------------------------------------
149 // parsing
150 //------------------------------------------------------------------------
151
152 GlobalParams::GlobalParams(char *cfgFileName) {
153   UnicodeMap *map;
154   GString *fileName;
155   FILE *f;
156   int i;
157
158 #if MULTITHREADED
159   gInitMutex(&mutex);
160   gInitMutex(&unicodeMapCacheMutex);
161   gInitMutex(&cMapCacheMutex);
162 #endif
163
164   initBuiltinFontTables();
165
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);
172     }
173   }
174
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();
185 #if HAVE_PAPER_H
186   char *paperName;
187   const struct paper *paperType;
188   paperinit();
189   if ((paperName = systempapername())) {
190     paperType = paperinfo(paperName);
191     psPaperWidth = (int)paperpswidth(paperType);
192     psPaperHeight = (int)paperpsheight(paperType);
193   } else {
194     error(-1, "No paper information available - using defaults");
195     psPaperWidth = defPaperWidth;
196     psPaperHeight = defPaperHeight;
197   }
198   paperdone();
199 #else
200   psPaperWidth = defPaperWidth;
201   psPaperHeight = defPaperHeight;
202 #endif
203   psImageableLLX = psImageableLLY = 0;
204   psImageableURX = psPaperWidth;
205   psImageableURY = psPaperHeight;
206   psCrop = gTrue;
207   psExpandSmaller = gFalse;
208   psShrinkLarger = gTrue;
209   psCenter = gTrue;
210   psDuplex = gFalse;
211   psLevel = psLevel2;
212   psFile = NULL;
213   psFonts = new GHash();
214   psNamedFonts16 = new GList();
215   psFonts16 = new GList();
216   psEmbedType1 = gTrue;
217   psEmbedTrueType = gTrue;
218   psEmbedCIDPostScript = gTrue;
219   psEmbedCIDTrueType = gTrue;
220   psOPI = gFalse;
221   psASCIIHex = gFalse;
222   textEncoding = new GString("Latin1");
223 #if defined(WIN32)
224   textEOL = eolDOS;
225 #elif defined(MACOS)
226   textEOL = eolMac;
227 #else
228   textEOL = eolUnix;
229 #endif
230   textPageBreaks = gTrue;
231   textKeepTinyChars = gFalse;
232   fontDirs = new GList();
233   initialZoom = new GString("125");
234   enableT1lib = gTrue;
235   enableFreeType = gTrue;
236   antialias = gTrue;
237   urlCommand = NULL;
238   movieCommand = NULL;
239   mapNumericCharNames = gTrue;
240   printCommands = gFalse;
241   errQuiet = gFalse;
242
243   cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
244   unicodeToUnicodeCache =
245       new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
246   unicodeMapCache = new UnicodeMapCache();
247   cMapCache = new CMapCache();
248
249   // set up the initial nameToUnicode table
250   for (i = 0; nameToUnicodeTab[i].name; ++i) {
251     nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
252   }
253
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);
271
272   // look for a user config file, then a system-wide config file
273   f = NULL;
274   fileName = NULL;
275   if (cfgFileName && cfgFileName[0]) {
276     fileName = new GString(cfgFileName);
277     if (!(f = fopen(fileName->getCString(), "r"))) {
278       delete fileName;
279     }
280   }
281   if (!f) {
282     fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
283     if (!(f = fopen(fileName->getCString(), "r"))) {
284       delete fileName;
285     }
286   }
287   if (!f) {
288 #if defined(WIN32) && !defined(__CYGWIN32__)
289     char buf[512];
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
293       buf[0] = '\0';
294     }
295     fileName = grabPath(buf);
296     appendToPath(fileName, xpdfSysConfigFile);
297 #else
298     fileName = new GString(xpdfSysConfigFile);
299 #endif
300     if (!(f = fopen(fileName->getCString(), "r"))) {
301       delete fileName;
302     }
303   }
304   if (f) {
305     parseFile(fileName, f);
306     delete fileName;
307     fclose(f);
308   }
309 }
310
311 void GlobalParams::parseFile(GString *fileName, FILE *f) {
312   int line;
313   GList *tokens;
314   GString *cmd, *incFile;
315   char *p1, *p2;
316   char buf[512];
317   FILE *f2;
318
319   line = 1;
320   while (getLine(buf, sizeof(buf) - 1, f)) {
321
322     // break the line into tokens
323     tokens = new GList();
324     p1 = buf;
325     while (*p1) {
326       for (; *p1 && isspace(*p1); ++p1) ;
327       if (!*p1) {
328         break;
329       }
330       if (*p1 == '"' || *p1 == '\'') {
331         for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
332         ++p1;
333       } else {
334         for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
335       }
336       tokens->append(new GString(p1, p2 - p1));
337       p1 = *p2 ? p2 + 1 : p2;
338     }
339
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);
348             fclose(f2);
349           } else {
350             error(-1, "Couldn't find included config file: '%s' (%s:%d)",
351                   incFile->getCString(), fileName->getCString(), line);
352           }
353         } else {
354           error(-1, "Bad 'include' config file command (%s:%d)",
355                 fileName->getCString(), line);
356         }
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);
457       } else {
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");
469         }
470       }
471     }
472
473     deleteGList(tokens, GString);
474     ++line;
475   }
476 }
477
478 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
479                                          int line) {
480   GString *name;
481   char *tok1, *tok2;
482   FILE *f;
483   char buf[256];
484   int line2;
485   Unicode u;
486
487   if (tokens->getLength() != 2) {
488     error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
489           fileName->getCString(), line);
490     return;
491   }
492   name = (GString *)tokens->get(1);
493   if (!(f = fopen(name->getCString(), "r"))) {
494     error(-1, "Couldn't open 'nameToUnicode' file '%s'",
495           name->getCString());
496     return;
497   }
498   line2 = 1;
499   while (getLine(buf, sizeof(buf), f)) {
500     tok1 = strtok(buf, " \t\r\n");
501     tok2 = strtok(NULL, " \t\r\n");
502     if (tok1 && tok2) {
503       sscanf(tok1, "%x", &u);
504       nameToUnicode->add(tok2, u);
505     } else {
506       error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
507     }
508     ++line2;
509   }
510   fclose(f);
511 }
512
513 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
514                                      int line) {
515   GString *collection, *name, *old;
516
517   if (tokens->getLength() != 3) {
518     error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
519           fileName->getCString(), line);
520     return;
521   }
522   collection = (GString *)tokens->get(1);
523   name = (GString *)tokens->get(2);
524   if ((old = (GString *)cidToUnicodes->remove(collection))) {
525     delete old;
526   }
527   cidToUnicodes->add(collection->copy(), name->copy());
528 }
529
530 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
531                                          int line) {
532   GString *font, *file, *old;
533
534   if (tokens->getLength() != 3) {
535     error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
536           fileName->getCString(), line);
537     return;
538   }
539   font = (GString *)tokens->get(1);
540   file = (GString *)tokens->get(2);
541   if ((old = (GString *)unicodeToUnicodes->remove(font))) {
542     delete old;
543   }
544   unicodeToUnicodes->add(font->copy(), file->copy());
545 }
546
547 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
548                                    int line) {
549   GString *encodingName, *name, *old;
550
551   if (tokens->getLength() != 3) {
552     error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
553           fileName->getCString(), line);
554     return;
555   }
556   encodingName = (GString *)tokens->get(1);
557   name = (GString *)tokens->get(2);
558   if ((old = (GString *)unicodeMaps->remove(encodingName))) {
559     delete old;
560   }
561   unicodeMaps->add(encodingName->copy(), name->copy());
562 }
563
564 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
565   GString *collection, *dir;
566   GList *list;
567
568   if (tokens->getLength() != 3) {
569     error(-1, "Bad 'cMapDir' config file command (%s:%d)",
570           fileName->getCString(), line);
571     return;
572   }
573   collection = (GString *)tokens->get(1);
574   dir = (GString *)tokens->get(2);
575   if (!(list = (GList *)cMapDirs->lookup(collection))) {
576     list = new GList();
577     cMapDirs->add(collection->copy(), list);
578   }
579   list->append(dir->copy());
580 }
581
582 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
583                                      int line) {
584   if (tokens->getLength() != 2) {
585     error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
586           fileName->getCString(), line);
587     return;
588   }
589   toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
590 }
591
592 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
593                                     DisplayFontParamKind kind,
594                                     GString *fileName, int line) {
595   DisplayFontParam *param, *old;
596
597   if (tokens->getLength() < 2) {
598     goto err1;
599   }
600   param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
601   
602   switch (kind) {
603   case displayFontT1:
604     if (tokens->getLength() != 3) {
605       goto err2;
606     }
607     param->t1.fileName = ((GString *)tokens->get(2))->copy();
608     break;
609   case displayFontTT:
610     if (tokens->getLength() != 3) {
611       goto err2;
612     }
613     param->tt.fileName = ((GString *)tokens->get(2))->copy();
614     break;
615   }
616
617   if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
618     delete old;
619   }
620   fontHash->add(param->name, param);
621   return;
622
623  err2:
624   delete param;
625  err1:
626   error(-1, "Bad 'display*Font*' config file command (%s:%d)",
627         fileName->getCString(), line);
628 }
629
630 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
631                                     int line) {
632   GString *tok;
633
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);
639     }
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;
648   } else {
649     error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
650           fileName->getCString(), line);
651   }
652 }
653
654 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
655                                         int line) {
656   if (tokens->getLength() != 5) {
657     error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
658           fileName->getCString(), line);
659     return;
660   }
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());
665 }
666
667 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
668   GString *tok;
669
670   if (tokens->getLength() != 2) {
671     error(-1, "Bad 'psLevel' config file command (%s:%d)",
672           fileName->getCString(), line);
673     return;
674   }
675   tok = (GString *)tokens->get(1);
676   if (!tok->cmp("level1")) {
677     psLevel = psLevel1;
678   } else if (!tok->cmp("level1sep")) {
679     psLevel = psLevel1Sep;
680   } else if (!tok->cmp("level2")) {
681     psLevel = psLevel2;
682   } else if (!tok->cmp("level2sep")) {
683     psLevel = psLevel2Sep;
684   } else if (!tok->cmp("level3")) {
685     psLevel = psLevel3;
686   } else if (!tok->cmp("level3Sep")) {
687     psLevel = psLevel3Sep;
688   } else {
689     error(-1, "Bad 'psLevel' config file command (%s:%d)",
690           fileName->getCString(), line);
691   }
692 }
693
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);
698     return;
699   }
700   if (psFile) {
701     delete psFile;
702   }
703   psFile = ((GString *)tokens->get(1))->copy();
704 }
705
706 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
707   PSFontParam *param;
708
709   if (tokens->getLength() != 3) {
710     error(-1, "Bad 'psFont' config file command (%s:%d)",
711           fileName->getCString(), line);
712     return;
713   }
714   param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
715                           ((GString *)tokens->get(2))->copy(), NULL);
716   psFonts->add(param->pdfFontName, param);
717 }
718
719 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
720                                  GList *tokens, GString *fileName, int line) {
721   PSFontParam *param;
722   int wMode;
723   GString *tok;
724
725   if (tokens->getLength() != 5) {
726     error(-1, "Bad '%s' config file command (%s:%d)",
727           cmdName, fileName->getCString(), line);
728     return;
729   }
730   tok = (GString *)tokens->get(2);
731   if (!tok->cmp("H")) {
732     wMode = 0;
733   } else if (!tok->cmp("V")) {
734     wMode = 1;
735   } else {
736     error(-1, "Bad '%s' config file command (%s:%d)",
737           cmdName, fileName->getCString(), line);
738     return;
739   }
740   param = new PSFontParam(((GString *)tokens->get(1))->copy(),
741                           wMode,
742                           ((GString *)tokens->get(3))->copy(),
743                           ((GString *)tokens->get(4))->copy());
744   fontList->append(param);
745 }
746
747 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
748                                      int line) {
749   if (tokens->getLength() != 2) {
750     error(-1, "Bad 'textEncoding' config file command (%s:%d)",
751           fileName->getCString(), line);
752     return;
753   }
754   delete textEncoding;
755   textEncoding = ((GString *)tokens->get(1))->copy();
756 }
757
758 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
759   GString *tok;
760
761   if (tokens->getLength() != 2) {
762     error(-1, "Bad 'textEOL' config file command (%s:%d)",
763           fileName->getCString(), line);
764     return;
765   }
766   tok = (GString *)tokens->get(1);
767   if (!tok->cmp("unix")) {
768     textEOL = eolUnix;
769   } else if (!tok->cmp("dos")) {
770     textEOL = eolDOS;
771   } else if (!tok->cmp("mac")) {
772     textEOL = eolMac;
773   } else {
774     error(-1, "Bad 'textEOL' config file command (%s:%d)",
775           fileName->getCString(), line);
776   }
777 }
778
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);
783     return;
784   }
785   fontDirs->append(((GString *)tokens->get(1))->copy());
786 }
787
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);
793     return;
794   }
795   delete initialZoom;
796   initialZoom = ((GString *)tokens->get(1))->copy();
797 }
798
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);
804     return;
805   }
806   if (*val) {
807     delete *val;
808   }
809   *val = ((GString *)tokens->get(1))->copy();
810 }
811
812 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
813                               GList *tokens, GString *fileName, int line) {
814   GString *tok;
815
816   if (tokens->getLength() != 2) {
817     error(-1, "Bad '%s' config file command (%s:%d)",
818           cmdName, fileName->getCString(), line);
819     return;
820   }
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);
825   }
826 }
827
828 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
829   if (!strcmp(token, "yes")) {
830     *flag = gTrue;
831   } else if (!strcmp(token, "no")) {
832     *flag = gFalse;
833   } else {
834     return gFalse;
835   }
836   return gTrue;
837 }
838
839 GlobalParams::~GlobalParams() {
840   GHashIter *iter;
841   GString *key;
842   GList *list;
843
844   freeBuiltinFontTables();
845
846   delete macRomanReverseMap;
847
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);
857   if (psFile) {
858     delete psFile;
859   }
860   deleteGHash(psFonts, PSFontParam);
861   deleteGList(psNamedFonts16, PSFontParam);
862   deleteGList(psFonts16, PSFontParam);
863   delete textEncoding;
864   deleteGList(fontDirs, GString);
865   delete initialZoom;
866   if (urlCommand) {
867     delete urlCommand;
868   }
869   if (movieCommand) {
870     delete movieCommand;
871   }
872
873   cMapDirs->startIter(&iter);
874   while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
875     deleteGList(list, GString);
876   }
877   delete cMapDirs;
878
879   delete cidToUnicodeCache;
880   delete unicodeToUnicodeCache;
881   delete unicodeMapCache;
882   delete cMapCache;
883
884 #if MULTITHREADED
885   gDestroyMutex(&mutex);
886   gDestroyMutex(&unicodeMapCacheMutex);
887   gDestroyMutex(&cMapCacheMutex);
888 #endif
889 }
890
891 //------------------------------------------------------------------------
892
893 void GlobalParams::setupBaseFonts(char *dir) {
894   GString *fontName;
895   GString *fileName;
896   FILE *f;
897   DisplayFontParam *dfp;
898   int i, j;
899
900   for (i = 0; displayFontTab[i].name; ++i) {
901     fontName = new GString(displayFontTab[i].name);
902     if (getDisplayFont(fontName)) {
903       delete fontName;
904       continue;
905     }
906     fileName = NULL;
907     if (dir) {
908       fileName = appendToPath(new GString(dir), displayFontTab[i].fileName);
909       if ((f = fopen(fileName->getCString(), "rb"))) {
910         fclose(f);
911       } else {
912         delete fileName;
913         fileName = NULL;
914       }
915     }
916 #ifndef WIN32
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"))) {
921         fclose(f);
922       } else {
923         delete fileName;
924         fileName = NULL;
925       }
926     }
927 #endif
928     if (!fileName) {
929       error(-1, "No display font for '%s'", displayFontTab[i].name);
930       delete fontName;
931       continue;
932     }
933     dfp = new DisplayFontParam(fontName, displayFontT1);
934     dfp->t1.fileName = fileName;
935     globalParams->addDisplayFont(dfp);
936   }
937 }
938
939 //------------------------------------------------------------------------
940 // accessors
941 //------------------------------------------------------------------------
942
943 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
944   // no need to lock - macRomanReverseMap is constant
945   return macRomanReverseMap->lookup(charName);
946 }
947
948 Unicode GlobalParams::mapNameToUnicode(char *charName) {
949   // no need to lock - nameToUnicode is constant
950   return nameToUnicode->lookup(charName);
951 }
952
953 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
954   UnicodeMap *map;
955
956   lockGlobalParams;
957   map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
958   unlockGlobalParams;
959   if (map) {
960     map->incRefCnt();
961   }
962   return map;
963 }
964
965 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
966   GString *fileName;
967   FILE *f;
968
969   lockGlobalParams;
970   if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
971     f = fopen(fileName->getCString(), "r");
972   } else {
973     f = NULL;
974   }
975   unlockGlobalParams;
976   return f;
977 }
978
979 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
980   GList *list;
981   GString *dir;
982   GString *fileName;
983   FILE *f;
984   int i;
985
986   lockGlobalParams;
987   if (!(list = (GList *)cMapDirs->lookup(collection))) {
988     unlockGlobalParams;
989     return NULL;
990   }
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");
995     delete fileName;
996     if (f) {
997       unlockGlobalParams;
998       return f;
999     }
1000   }
1001   unlockGlobalParams;
1002   return NULL;
1003 }
1004
1005 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1006   GString *dir, *fileName;
1007   FILE *f;
1008   int i;
1009
1010   lockGlobalParams;
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");
1015     delete fileName;
1016     if (f) {
1017       unlockGlobalParams;
1018       return f;
1019     }
1020   }
1021   unlockGlobalParams;
1022   return NULL;
1023 }
1024
1025 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1026   DisplayFontParam *dfp;
1027
1028   lockGlobalParams;
1029   dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1030   unlockGlobalParams;
1031   return dfp;
1032 }
1033
1034 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1035                                                   GString *collection) {
1036   DisplayFontParam *dfp;
1037
1038   lockGlobalParams;
1039   if (!fontName ||
1040       !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1041     dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1042   }
1043   unlockGlobalParams;
1044   return dfp;
1045 }
1046
1047 GString *GlobalParams::getPSFile() {
1048   GString *s;
1049
1050   lockGlobalParams;
1051   s = psFile ? psFile->copy() : (GString *)NULL;
1052   unlockGlobalParams;
1053   return s;
1054 }
1055
1056 int GlobalParams::getPSPaperWidth() {
1057   int w;
1058
1059   lockGlobalParams;
1060   w = psPaperWidth;
1061   unlockGlobalParams;
1062   return w;
1063 }
1064
1065 int GlobalParams::getPSPaperHeight() {
1066   int h;
1067
1068   lockGlobalParams;
1069   h = psPaperHeight;
1070   unlockGlobalParams;
1071   return h;
1072 }
1073
1074 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1075   lockGlobalParams;
1076   *llx = psImageableLLX;
1077   *lly = psImageableLLY;
1078   *urx = psImageableURX;
1079   *ury = psImageableURY;
1080   unlockGlobalParams;
1081 }
1082
1083 GBool GlobalParams::getPSCrop() {
1084   GBool f;
1085
1086   lockGlobalParams;
1087   f = psCrop;
1088   unlockGlobalParams;
1089   return f;
1090 }
1091
1092 GBool GlobalParams::getPSExpandSmaller() {
1093   GBool f;
1094
1095   lockGlobalParams;
1096   f = psExpandSmaller;
1097   unlockGlobalParams;
1098   return f;
1099 }
1100
1101 GBool GlobalParams::getPSShrinkLarger() {
1102   GBool f;
1103
1104   lockGlobalParams;
1105   f = psShrinkLarger;
1106   unlockGlobalParams;
1107   return f;
1108 }
1109
1110 GBool GlobalParams::getPSCenter() {
1111   GBool f;
1112
1113   lockGlobalParams;
1114   f = psCenter;
1115   unlockGlobalParams;
1116   return f;
1117 }
1118
1119 GBool GlobalParams::getPSDuplex() {
1120   GBool d;
1121
1122   lockGlobalParams;
1123   d = psDuplex;
1124   unlockGlobalParams;
1125   return d;
1126 }
1127
1128 PSLevel GlobalParams::getPSLevel() {
1129   PSLevel level;
1130
1131   lockGlobalParams;
1132   level = psLevel;
1133   unlockGlobalParams;
1134   return level;
1135 }
1136
1137 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1138   PSFontParam *p;
1139
1140   lockGlobalParams;
1141   p = (PSFontParam *)psFonts->lookup(fontName);
1142   unlockGlobalParams;
1143   return p;
1144 }
1145
1146 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1147                                        GString *collection, int wMode) {
1148   PSFontParam *p;
1149   int i;
1150
1151   lockGlobalParams;
1152   p = NULL;
1153   if (fontName) {
1154     for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1155       p = (PSFontParam *)psNamedFonts16->get(i);
1156       if (!p->pdfFontName->cmp(fontName) &&
1157           p->wMode == wMode) {
1158         break;
1159       }
1160       p = NULL;
1161     }
1162   }
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) {
1168         break;
1169       }
1170       p = NULL;
1171     }
1172   }
1173   unlockGlobalParams;
1174   return p;
1175 }
1176
1177 GBool GlobalParams::getPSEmbedType1() {
1178   GBool e;
1179
1180   lockGlobalParams;
1181   e = psEmbedType1;
1182   unlockGlobalParams;
1183   return e;
1184 }
1185
1186 GBool GlobalParams::getPSEmbedTrueType() {
1187   GBool e;
1188
1189   lockGlobalParams;
1190   e = psEmbedTrueType;
1191   unlockGlobalParams;
1192   return e;
1193 }
1194
1195 GBool GlobalParams::getPSEmbedCIDPostScript() {
1196   GBool e;
1197
1198   lockGlobalParams;
1199   e = psEmbedCIDPostScript;
1200   unlockGlobalParams;
1201   return e;
1202 }
1203
1204 GBool GlobalParams::getPSEmbedCIDTrueType() {
1205   GBool e;
1206
1207   lockGlobalParams;
1208   e = psEmbedCIDTrueType;
1209   unlockGlobalParams;
1210   return e;
1211 }
1212
1213 GBool GlobalParams::getPSOPI() {
1214   GBool opi;
1215
1216   lockGlobalParams;
1217   opi = psOPI;
1218   unlockGlobalParams;
1219   return opi;
1220 }
1221
1222 GBool GlobalParams::getPSASCIIHex() {
1223   GBool ah;
1224
1225   lockGlobalParams;
1226   ah = psASCIIHex;
1227   unlockGlobalParams;
1228   return ah;
1229 }
1230
1231 GString *GlobalParams::getTextEncodingName() {
1232   GString *s;
1233
1234   lockGlobalParams;
1235   s = textEncoding->copy();
1236   unlockGlobalParams;
1237   return s;
1238 }
1239
1240 EndOfLineKind GlobalParams::getTextEOL() {
1241   EndOfLineKind eol;
1242
1243   lockGlobalParams;
1244   eol = textEOL;
1245   unlockGlobalParams;
1246   return eol;
1247 }
1248
1249 GBool GlobalParams::getTextPageBreaks() {
1250   GBool pageBreaks;
1251
1252   lockGlobalParams;
1253   pageBreaks = textPageBreaks;
1254   unlockGlobalParams;
1255   return pageBreaks;
1256 }
1257
1258 GBool GlobalParams::getTextKeepTinyChars() {
1259   GBool tiny;
1260
1261   lockGlobalParams;
1262   tiny = textKeepTinyChars;
1263   unlockGlobalParams;
1264   return tiny;
1265 }
1266
1267 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1268   GString *dir, *fileName;
1269   char **ext;
1270   FILE *f;
1271   int i;
1272
1273   lockGlobalParams;
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"))) {
1280         fclose(f);
1281         unlockGlobalParams;
1282         return fileName;
1283       }
1284       delete fileName;
1285     }
1286   }
1287   unlockGlobalParams;
1288   return NULL;
1289 }
1290
1291 GString *GlobalParams::getInitialZoom() {
1292   GString *s;
1293
1294   lockGlobalParams;
1295   s = initialZoom->copy();
1296   unlockGlobalParams;
1297   return s;
1298 }
1299
1300 GBool GlobalParams::getEnableT1lib() {
1301   GBool f;
1302
1303   lockGlobalParams;
1304   f = enableT1lib;
1305   unlockGlobalParams;
1306   return f;
1307 }
1308
1309 GBool GlobalParams::getEnableFreeType() {
1310   GBool f;
1311
1312   lockGlobalParams;
1313   f = enableFreeType;
1314   unlockGlobalParams;
1315   return f;
1316 }
1317
1318
1319 GBool GlobalParams::getAntialias() {
1320   GBool f;
1321
1322   lockGlobalParams;
1323   f = antialias;
1324   unlockGlobalParams;
1325   return f;
1326 }
1327
1328 GBool GlobalParams::getMapNumericCharNames() {
1329   GBool map;
1330
1331   lockGlobalParams;
1332   map = mapNumericCharNames;
1333   unlockGlobalParams;
1334   return map;
1335 }
1336
1337 GBool GlobalParams::getPrintCommands() {
1338   GBool p;
1339
1340   lockGlobalParams;
1341   p = printCommands;
1342   unlockGlobalParams;
1343   return p;
1344 }
1345
1346 GBool GlobalParams::getErrQuiet() {
1347   GBool q;
1348
1349   lockGlobalParams;
1350   q = errQuiet;
1351   unlockGlobalParams;
1352   return q;
1353 }
1354
1355 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1356   GString *fileName;
1357   CharCodeToUnicode *ctu;
1358
1359   lockGlobalParams;
1360   if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1361     if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1362         (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1363       cidToUnicodeCache->add(ctu);
1364     }
1365   }
1366   unlockGlobalParams;
1367   return ctu;
1368 }
1369
1370 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1371   CharCodeToUnicode *ctu;
1372   GHashIter *iter;
1373   GString *fontPattern, *fileName;
1374
1375   lockGlobalParams;
1376   fileName = NULL;
1377   unicodeToUnicodes->startIter(&iter);
1378   while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1379     if (strstr(fontName->getCString(), fontPattern->getCString())) {
1380       unicodeToUnicodes->killIter(&iter);
1381       break;
1382     }
1383     fileName = NULL;
1384   }
1385   if (fileName) {
1386     if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1387       if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1388         unicodeToUnicodeCache->add(ctu);
1389       }
1390     }
1391   } else {
1392     ctu = NULL;
1393   }
1394   unlockGlobalParams;
1395   return ctu;
1396 }
1397
1398 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1399   return getUnicodeMap2(encodingName);
1400 }
1401
1402 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1403   UnicodeMap *map;
1404
1405   if (!(map = getResidentUnicodeMap(encodingName))) {
1406     lockUnicodeMapCache;
1407     map = unicodeMapCache->getUnicodeMap(encodingName);
1408     unlockUnicodeMapCache;
1409   }
1410   return map;
1411 }
1412
1413 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1414   CMap *cMap;
1415
1416   lockCMapCache;
1417   cMap = cMapCache->getCMap(collection, cMapName);
1418   unlockCMapCache;
1419   return cMap;
1420 }
1421
1422 UnicodeMap *GlobalParams::getTextEncoding() {
1423   return getUnicodeMap2(textEncoding);
1424 }
1425
1426 //------------------------------------------------------------------------
1427 // functions to set parameters
1428 //------------------------------------------------------------------------
1429
1430 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1431   DisplayFontParam *old;
1432
1433   lockGlobalParams;
1434   if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1435     delete old;
1436   }
1437   displayFonts->add(param->name, param);
1438   unlockGlobalParams;
1439 }
1440
1441 void GlobalParams::setPSFile(char *file) {
1442   lockGlobalParams;
1443   if (psFile) {
1444     delete psFile;
1445   }
1446   psFile = new GString(file);
1447   unlockGlobalParams;
1448 }
1449
1450 GBool GlobalParams::setPSPaperSize(char *size) {
1451   lockGlobalParams;
1452   if (!strcmp(size, "match")) {
1453     psPaperWidth = psPaperHeight = -1;
1454   } else if (!strcmp(size, "letter")) {
1455     psPaperWidth = 612;
1456     psPaperHeight = 792;
1457   } else if (!strcmp(size, "legal")) {
1458     psPaperWidth = 612;
1459     psPaperHeight = 1008;
1460   } else if (!strcmp(size, "A4")) {
1461     psPaperWidth = 595;
1462     psPaperHeight = 842;
1463   } else if (!strcmp(size, "A3")) {
1464     psPaperWidth = 842;
1465     psPaperHeight = 1190;
1466   } else {
1467     unlockGlobalParams;
1468     return gFalse;
1469   }
1470   psImageableLLX = psImageableLLY = 0;
1471   psImageableURX = psPaperWidth;
1472   psImageableURY = psPaperHeight;
1473   unlockGlobalParams;
1474   return gTrue;
1475 }
1476
1477 void GlobalParams::setPSPaperWidth(int width) {
1478   lockGlobalParams;
1479   psPaperWidth = width;
1480   psImageableLLX = 0;
1481   psImageableURX = psPaperWidth;
1482   unlockGlobalParams;
1483 }
1484
1485 void GlobalParams::setPSPaperHeight(int height) {
1486   lockGlobalParams;
1487   psPaperHeight = height;
1488   psImageableLLY = 0;
1489   psImageableURY = psPaperHeight;
1490   unlockGlobalParams;
1491 }
1492
1493 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1494   lockGlobalParams;
1495   psImageableLLX = llx;
1496   psImageableLLY = lly;
1497   psImageableURX = urx;
1498   psImageableURY = ury;
1499   unlockGlobalParams;
1500 }
1501
1502 void GlobalParams::setPSCrop(GBool crop) {
1503   lockGlobalParams;
1504   psCrop = crop;
1505   unlockGlobalParams;
1506 }
1507
1508 void GlobalParams::setPSExpandSmaller(GBool expand) {
1509   lockGlobalParams;
1510   psExpandSmaller = expand;
1511   unlockGlobalParams;
1512 }
1513
1514 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1515   lockGlobalParams;
1516   psShrinkLarger = shrink;
1517   unlockGlobalParams;
1518 }
1519
1520 void GlobalParams::setPSCenter(GBool center) {
1521   lockGlobalParams;
1522   psCenter = center;
1523   unlockGlobalParams;
1524 }
1525
1526 void GlobalParams::setPSDuplex(GBool duplex) {
1527   lockGlobalParams;
1528   psDuplex = duplex;
1529   unlockGlobalParams;
1530 }
1531
1532 void GlobalParams::setPSLevel(PSLevel level) {
1533   lockGlobalParams;
1534   psLevel = level;
1535   unlockGlobalParams;
1536 }
1537
1538 void GlobalParams::setPSEmbedType1(GBool embed) {
1539   lockGlobalParams;
1540   psEmbedType1 = embed;
1541   unlockGlobalParams;
1542 }
1543
1544 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1545   lockGlobalParams;
1546   psEmbedTrueType = embed;
1547   unlockGlobalParams;
1548 }
1549
1550 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1551   lockGlobalParams;
1552   psEmbedCIDPostScript = embed;
1553   unlockGlobalParams;
1554 }
1555
1556 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1557   lockGlobalParams;
1558   psEmbedCIDTrueType = embed;
1559   unlockGlobalParams;
1560 }
1561
1562 void GlobalParams::setPSOPI(GBool opi) {
1563   lockGlobalParams;
1564   psOPI = opi;
1565   unlockGlobalParams;
1566 }
1567
1568 void GlobalParams::setPSASCIIHex(GBool hex) {
1569   lockGlobalParams;
1570   psASCIIHex = hex;
1571   unlockGlobalParams;
1572 }
1573
1574 void GlobalParams::setTextEncoding(char *encodingName) {
1575   lockGlobalParams;
1576   delete textEncoding;
1577   textEncoding = new GString(encodingName);
1578   unlockGlobalParams;
1579 }
1580
1581 GBool GlobalParams::setTextEOL(char *s) {
1582   lockGlobalParams;
1583   if (!strcmp(s, "unix")) {
1584     textEOL = eolUnix;
1585   } else if (!strcmp(s, "dos")) {
1586     textEOL = eolDOS;
1587   } else if (!strcmp(s, "mac")) {
1588     textEOL = eolMac;
1589   } else {
1590     unlockGlobalParams;
1591     return gFalse;
1592   }
1593   unlockGlobalParams;
1594   return gTrue;
1595 }
1596
1597 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1598   lockGlobalParams;
1599   textPageBreaks = pageBreaks;
1600   unlockGlobalParams;
1601 }
1602
1603 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1604   lockGlobalParams;
1605   textKeepTinyChars = keep;
1606   unlockGlobalParams;
1607 }
1608
1609 void GlobalParams::setInitialZoom(char *s) {
1610   lockGlobalParams;
1611   delete initialZoom;
1612   initialZoom = new GString(s);
1613   unlockGlobalParams;
1614 }
1615
1616 GBool GlobalParams::setEnableT1lib(char *s) {
1617   GBool ok;
1618
1619   lockGlobalParams;
1620   ok = parseYesNo2(s, &enableT1lib);
1621   unlockGlobalParams;
1622   return ok;
1623 }
1624
1625 GBool GlobalParams::setEnableFreeType(char *s) {
1626   GBool ok;
1627
1628   lockGlobalParams;
1629   ok = parseYesNo2(s, &enableFreeType);
1630   unlockGlobalParams;
1631   return ok;
1632 }
1633
1634
1635 GBool GlobalParams::setAntialias(char *s) {
1636   GBool ok;
1637
1638   lockGlobalParams;
1639   ok = parseYesNo2(s, &antialias);
1640   unlockGlobalParams;
1641   return ok;
1642 }
1643
1644 void GlobalParams::setMapNumericCharNames(GBool map) {
1645   lockGlobalParams;
1646   mapNumericCharNames = map;
1647   unlockGlobalParams;
1648 }
1649
1650 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1651   lockGlobalParams;
1652   printCommands = printCommandsA;
1653   unlockGlobalParams;
1654 }
1655
1656 void GlobalParams::setErrQuiet(GBool errQuietA) {
1657   lockGlobalParams;
1658   errQuiet = errQuietA;
1659   unlockGlobalParams;
1660 }