]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/GlobalParams.cc
944fc9e7cec1c4e8ab191a7b5c6c64cc01fd7cb1
[evince.git] / pdf / 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 <fontconfig/fontconfig.h>
22 #include "gmem.h"
23 #include "GString.h"
24 #include "GList.h"
25 #include "GHash.h"
26 #include "gfile.h"
27 #include "Error.h"
28 #include "NameToCharCode.h"
29 #include "CharCodeToUnicode.h"
30 #include "UnicodeMap.h"
31 #include "CMap.h"
32 #include "BuiltinFontTables.h"
33 #include "FontEncodingTables.h"
34 #include "GlobalParams.h"
35
36 #if MULTITHREADED
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)
43 #else
44 #  define lockGlobalParams
45 #  define lockUnicodeMapCache
46 #  define lockCMapCache
47 #  define unlockGlobalParams
48 #  define unlockUnicodeMapCache
49 #  define unlockCMapCache
50 #endif
51
52 #include "NameToUnicodeTable.h"
53 #include "UnicodeMapTables.h"
54 #include "UTF8.h"
55
56 //------------------------------------------------------------------------
57
58 #define cidToUnicodeCacheSize     4
59 #define unicodeToUnicodeCacheSize 4
60
61 //------------------------------------------------------------------------
62
63 static struct {
64   char *name;
65   char *fileName;
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"},
81   {NULL}
82 };
83
84 static char *displayFontDirs[] = {
85   "/usr/share/ghostscript/fonts",
86   "/usr/local/share/ghostscript/fonts",
87   "/usr/share/fonts/default/Type1",
88   NULL
89 };
90
91 /* patterns originally from mupdf; added agfa fonts*/ 
92 static struct {
93   const char *name;
94   const char *pattern;
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"},
112   {NULL}
113 };
114
115 //------------------------------------------------------------------------
116
117 GlobalParams *globalParams = NULL;
118
119 //------------------------------------------------------------------------
120 // DisplayFontParam
121 //------------------------------------------------------------------------
122
123 DisplayFontParam::DisplayFontParam(GString *nameA,
124                                    DisplayFontParamKind kindA) {
125   name = nameA;
126   kind = kindA;
127   switch (kind) {
128   case displayFontT1:
129     t1.fileName = NULL;
130     break;
131   case displayFontTT:
132     tt.fileName = NULL;
133     break;
134   }
135 }
136
137 DisplayFontParam::~DisplayFontParam() {
138   delete name;
139   switch (kind) {
140   case displayFontT1:
141     if (t1.fileName) {
142       delete t1.fileName;
143     }
144     break;
145   case displayFontTT:
146     if (tt.fileName) {
147       delete tt.fileName;
148     }
149     break;
150   }
151 }
152
153 //------------------------------------------------------------------------
154 // PSFontParam
155 //------------------------------------------------------------------------
156
157 PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
158                          GString *psFontNameA, GString *encodingA) {
159   pdfFontName = pdfFontNameA;
160   wMode = wModeA;
161   psFontName = psFontNameA;
162   encoding = encodingA;
163 }
164
165 PSFontParam::~PSFontParam() {
166   delete pdfFontName;
167   delete psFontName;
168   if (encoding) {
169     delete encoding;
170   }
171 }
172
173 //------------------------------------------------------------------------
174 // parsing
175 //------------------------------------------------------------------------
176
177 GlobalParams::GlobalParams(char *cfgFileName) {
178   UnicodeMap *map;
179   GString *fileName;
180   FILE *f;
181   int i;
182
183 #if MULTITHREADED
184   gInitMutex(&mutex);
185   gInitMutex(&unicodeMapCacheMutex);
186   gInitMutex(&cMapCacheMutex);
187 #endif
188
189   initBuiltinFontTables();
190
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);
197     }
198   }
199
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();
210 #if HAVE_PAPER_H
211   char *paperName;
212   const struct paper *paperType;
213   paperinit();
214   if ((paperName = systempapername())) {
215     paperType = paperinfo(paperName);
216     psPaperWidth = (int)paperpswidth(paperType);
217     psPaperHeight = (int)paperpsheight(paperType);
218   } else {
219     error(-1, "No paper information available - using defaults");
220     psPaperWidth = defPaperWidth;
221     psPaperHeight = defPaperHeight;
222   }
223   paperdone();
224 #else
225   psPaperWidth = defPaperWidth;
226   psPaperHeight = defPaperHeight;
227 #endif
228   psImageableLLX = psImageableLLY = 0;
229   psImageableURX = psPaperWidth;
230   psImageableURY = psPaperHeight;
231   psCrop = gTrue;
232   psExpandSmaller = gFalse;
233   psShrinkLarger = gTrue;
234   psCenter = gTrue;
235   psDuplex = gFalse;
236   psLevel = psLevel2;
237   psFile = NULL;
238   psFonts = new GHash();
239   psNamedFonts16 = new GList();
240   psFonts16 = new GList();
241   psEmbedType1 = gTrue;
242   psEmbedTrueType = gTrue;
243   psEmbedCIDPostScript = gTrue;
244   psEmbedCIDTrueType = gTrue;
245   psOPI = gFalse;
246   psASCIIHex = gFalse;
247   textEncoding = new GString("Latin1");
248 #if defined(WIN32)
249   textEOL = eolDOS;
250 #elif defined(MACOS)
251   textEOL = eolMac;
252 #else
253   textEOL = eolUnix;
254 #endif
255   textPageBreaks = gTrue;
256   textKeepTinyChars = gFalse;
257   fontDirs = new GList();
258   initialZoom = new GString("125");
259   enableT1lib = gTrue;
260   enableFreeType = gTrue;
261   antialias = gTrue;
262   urlCommand = NULL;
263   movieCommand = NULL;
264   mapNumericCharNames = gTrue;
265   printCommands = gFalse;
266   errQuiet = gFalse;
267
268   cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
269   unicodeToUnicodeCache =
270       new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
271   unicodeMapCache = new UnicodeMapCache();
272   cMapCache = new CMapCache();
273
274   // set up the initial nameToUnicode table
275   for (i = 0; nameToUnicodeTab[i].name; ++i) {
276     nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
277   }
278
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);
296
297   // look for a user config file, then a system-wide config file
298   f = NULL;
299   fileName = NULL;
300   if (cfgFileName && cfgFileName[0]) {
301     fileName = new GString(cfgFileName);
302     if (!(f = fopen(fileName->getCString(), "r"))) {
303       delete fileName;
304     }
305   }
306   if (!f) {
307     fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
308     if (!(f = fopen(fileName->getCString(), "r"))) {
309       delete fileName;
310     }
311   }
312   if (!f) {
313 #if defined(WIN32) && !defined(__CYGWIN32__)
314     char buf[512];
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
318       buf[0] = '\0';
319     }
320     fileName = grabPath(buf);
321     appendToPath(fileName, xpdfSysConfigFile);
322 #else
323     fileName = new GString(xpdfSysConfigFile);
324 #endif
325     if (!(f = fopen(fileName->getCString(), "r"))) {
326       delete fileName;
327     }
328   }
329   if (f) {
330     parseFile(fileName, f);
331     delete fileName;
332     fclose(f);
333   }
334 }
335
336 void GlobalParams::parseFile(GString *fileName, FILE *f) {
337   int line;
338   GList *tokens;
339   GString *cmd, *incFile;
340   char *p1, *p2;
341   char buf[512];
342   FILE *f2;
343
344   line = 1;
345   while (getLine(buf, sizeof(buf) - 1, f)) {
346
347     // break the line into tokens
348     tokens = new GList();
349     p1 = buf;
350     while (*p1) {
351       for (; *p1 && isspace(*p1); ++p1) ;
352       if (!*p1) {
353         break;
354       }
355       if (*p1 == '"' || *p1 == '\'') {
356         for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
357         ++p1;
358       } else {
359         for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
360       }
361       tokens->append(new GString(p1, p2 - p1));
362       p1 = *p2 ? p2 + 1 : p2;
363     }
364
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);
373             fclose(f2);
374           } else {
375             error(-1, "Couldn't find included config file: '%s' (%s:%d)",
376                   incFile->getCString(), fileName->getCString(), line);
377           }
378         } else {
379           error(-1, "Bad 'include' config file command (%s:%d)",
380                 fileName->getCString(), line);
381         }
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);
482       } else {
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");
494         }
495       }
496     }
497
498     deleteGList(tokens, GString);
499     ++line;
500   }
501 }
502
503 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
504                                          int line) {
505   GString *name;
506   char *tok1, *tok2;
507   FILE *f;
508   char buf[256];
509   int line2;
510   Unicode u;
511
512   if (tokens->getLength() != 2) {
513     error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
514           fileName->getCString(), line);
515     return;
516   }
517   name = (GString *)tokens->get(1);
518   if (!(f = fopen(name->getCString(), "r"))) {
519     error(-1, "Couldn't open 'nameToUnicode' file '%s'",
520           name->getCString());
521     return;
522   }
523   line2 = 1;
524   while (getLine(buf, sizeof(buf), f)) {
525     tok1 = strtok(buf, " \t\r\n");
526     tok2 = strtok(NULL, " \t\r\n");
527     if (tok1 && tok2) {
528       sscanf(tok1, "%x", &u);
529       nameToUnicode->add(tok2, u);
530     } else {
531       error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
532     }
533     ++line2;
534   }
535   fclose(f);
536 }
537
538 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
539                                      int line) {
540   GString *collection, *name, *old;
541
542   if (tokens->getLength() != 3) {
543     error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
544           fileName->getCString(), line);
545     return;
546   }
547   collection = (GString *)tokens->get(1);
548   name = (GString *)tokens->get(2);
549   if ((old = (GString *)cidToUnicodes->remove(collection))) {
550     delete old;
551   }
552   cidToUnicodes->add(collection->copy(), name->copy());
553 }
554
555 void GlobalParams::parseUnicodeToUnicode(GList *tokens, GString *fileName,
556                                          int line) {
557   GString *font, *file, *old;
558
559   if (tokens->getLength() != 3) {
560     error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
561           fileName->getCString(), line);
562     return;
563   }
564   font = (GString *)tokens->get(1);
565   file = (GString *)tokens->get(2);
566   if ((old = (GString *)unicodeToUnicodes->remove(font))) {
567     delete old;
568   }
569   unicodeToUnicodes->add(font->copy(), file->copy());
570 }
571
572 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
573                                    int line) {
574   GString *encodingName, *name, *old;
575
576   if (tokens->getLength() != 3) {
577     error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
578           fileName->getCString(), line);
579     return;
580   }
581   encodingName = (GString *)tokens->get(1);
582   name = (GString *)tokens->get(2);
583   if ((old = (GString *)unicodeMaps->remove(encodingName))) {
584     delete old;
585   }
586   unicodeMaps->add(encodingName->copy(), name->copy());
587 }
588
589 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
590   GString *collection, *dir;
591   GList *list;
592
593   if (tokens->getLength() != 3) {
594     error(-1, "Bad 'cMapDir' config file command (%s:%d)",
595           fileName->getCString(), line);
596     return;
597   }
598   collection = (GString *)tokens->get(1);
599   dir = (GString *)tokens->get(2);
600   if (!(list = (GList *)cMapDirs->lookup(collection))) {
601     list = new GList();
602     cMapDirs->add(collection->copy(), list);
603   }
604   list->append(dir->copy());
605 }
606
607 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
608                                      int line) {
609   if (tokens->getLength() != 2) {
610     error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
611           fileName->getCString(), line);
612     return;
613   }
614   toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
615 }
616
617 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
618                                     DisplayFontParamKind kind,
619                                     GString *fileName, int line) {
620   DisplayFontParam *param, *old;
621
622   if (tokens->getLength() < 2) {
623     goto err1;
624   }
625   param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
626   
627   switch (kind) {
628   case displayFontT1:
629     if (tokens->getLength() != 3) {
630       goto err2;
631     }
632     param->t1.fileName = ((GString *)tokens->get(2))->copy();
633     break;
634   case displayFontTT:
635     if (tokens->getLength() != 3) {
636       goto err2;
637     }
638     param->tt.fileName = ((GString *)tokens->get(2))->copy();
639     break;
640   }
641
642   if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
643     delete old;
644   }
645   fontHash->add(param->name, param);
646   return;
647
648  err2:
649   delete param;
650  err1:
651   error(-1, "Bad 'display*Font*' config file command (%s:%d)",
652         fileName->getCString(), line);
653 }
654
655 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
656                                     int line) {
657   GString *tok;
658
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);
664     }
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;
673   } else {
674     error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
675           fileName->getCString(), line);
676   }
677 }
678
679 void GlobalParams::parsePSImageableArea(GList *tokens, GString *fileName,
680                                         int line) {
681   if (tokens->getLength() != 5) {
682     error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
683           fileName->getCString(), line);
684     return;
685   }
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());
690 }
691
692 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
693   GString *tok;
694
695   if (tokens->getLength() != 2) {
696     error(-1, "Bad 'psLevel' config file command (%s:%d)",
697           fileName->getCString(), line);
698     return;
699   }
700   tok = (GString *)tokens->get(1);
701   if (!tok->cmp("level1")) {
702     psLevel = psLevel1;
703   } else if (!tok->cmp("level1sep")) {
704     psLevel = psLevel1Sep;
705   } else if (!tok->cmp("level2")) {
706     psLevel = psLevel2;
707   } else if (!tok->cmp("level2sep")) {
708     psLevel = psLevel2Sep;
709   } else if (!tok->cmp("level3")) {
710     psLevel = psLevel3;
711   } else if (!tok->cmp("level3Sep")) {
712     psLevel = psLevel3Sep;
713   } else {
714     error(-1, "Bad 'psLevel' config file command (%s:%d)",
715           fileName->getCString(), line);
716   }
717 }
718
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);
723     return;
724   }
725   if (psFile) {
726     delete psFile;
727   }
728   psFile = ((GString *)tokens->get(1))->copy();
729 }
730
731 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
732   PSFontParam *param;
733
734   if (tokens->getLength() != 3) {
735     error(-1, "Bad 'psFont' config file command (%s:%d)",
736           fileName->getCString(), line);
737     return;
738   }
739   param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
740                           ((GString *)tokens->get(2))->copy(), NULL);
741   psFonts->add(param->pdfFontName, param);
742 }
743
744 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
745                                  GList *tokens, GString *fileName, int line) {
746   PSFontParam *param;
747   int wMode;
748   GString *tok;
749
750   if (tokens->getLength() != 5) {
751     error(-1, "Bad '%s' config file command (%s:%d)",
752           cmdName, fileName->getCString(), line);
753     return;
754   }
755   tok = (GString *)tokens->get(2);
756   if (!tok->cmp("H")) {
757     wMode = 0;
758   } else if (!tok->cmp("V")) {
759     wMode = 1;
760   } else {
761     error(-1, "Bad '%s' config file command (%s:%d)",
762           cmdName, fileName->getCString(), line);
763     return;
764   }
765   param = new PSFontParam(((GString *)tokens->get(1))->copy(),
766                           wMode,
767                           ((GString *)tokens->get(3))->copy(),
768                           ((GString *)tokens->get(4))->copy());
769   fontList->append(param);
770 }
771
772 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
773                                      int line) {
774   if (tokens->getLength() != 2) {
775     error(-1, "Bad 'textEncoding' config file command (%s:%d)",
776           fileName->getCString(), line);
777     return;
778   }
779   delete textEncoding;
780   textEncoding = ((GString *)tokens->get(1))->copy();
781 }
782
783 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
784   GString *tok;
785
786   if (tokens->getLength() != 2) {
787     error(-1, "Bad 'textEOL' config file command (%s:%d)",
788           fileName->getCString(), line);
789     return;
790   }
791   tok = (GString *)tokens->get(1);
792   if (!tok->cmp("unix")) {
793     textEOL = eolUnix;
794   } else if (!tok->cmp("dos")) {
795     textEOL = eolDOS;
796   } else if (!tok->cmp("mac")) {
797     textEOL = eolMac;
798   } else {
799     error(-1, "Bad 'textEOL' config file command (%s:%d)",
800           fileName->getCString(), line);
801   }
802 }
803
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);
808     return;
809   }
810   fontDirs->append(((GString *)tokens->get(1))->copy());
811 }
812
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);
818     return;
819   }
820   delete initialZoom;
821   initialZoom = ((GString *)tokens->get(1))->copy();
822 }
823
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);
829     return;
830   }
831   if (*val) {
832     delete *val;
833   }
834   *val = ((GString *)tokens->get(1))->copy();
835 }
836
837 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
838                               GList *tokens, GString *fileName, int line) {
839   GString *tok;
840
841   if (tokens->getLength() != 2) {
842     error(-1, "Bad '%s' config file command (%s:%d)",
843           cmdName, fileName->getCString(), line);
844     return;
845   }
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);
850   }
851 }
852
853 GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
854   if (!strcmp(token, "yes")) {
855     *flag = gTrue;
856   } else if (!strcmp(token, "no")) {
857     *flag = gFalse;
858   } else {
859     return gFalse;
860   }
861   return gTrue;
862 }
863
864 GlobalParams::~GlobalParams() {
865   GHashIter *iter;
866   GString *key;
867   GList *list;
868
869   freeBuiltinFontTables();
870
871   delete macRomanReverseMap;
872
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);
882   if (psFile) {
883     delete psFile;
884   }
885   deleteGHash(psFonts, PSFontParam);
886   deleteGList(psNamedFonts16, PSFontParam);
887   deleteGList(psFonts16, PSFontParam);
888   delete textEncoding;
889   deleteGList(fontDirs, GString);
890   delete initialZoom;
891   if (urlCommand) {
892     delete urlCommand;
893   }
894   if (movieCommand) {
895     delete movieCommand;
896   }
897
898   cMapDirs->startIter(&iter);
899   while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
900     deleteGList(list, GString);
901   }
902   delete cMapDirs;
903
904   delete cidToUnicodeCache;
905   delete unicodeToUnicodeCache;
906   delete unicodeMapCache;
907   delete cMapCache;
908
909 #if MULTITHREADED
910   gDestroyMutex(&mutex);
911   gDestroyMutex(&unicodeMapCacheMutex);
912   gDestroyMutex(&cMapCacheMutex);
913 #endif
914 }
915
916 //------------------------------------------------------------------------
917
918 void GlobalParams::setupBaseFonts(char *dir) {
919   GString *fontName;
920   GString *fileName;
921   FILE *f;
922   DisplayFontParam *dfp;
923   int i, j;
924
925   for (i = 0; displayFontTab[i].name; ++i) {
926     fontName = new GString(displayFontTab[i].name);
927     if (getDisplayFont(fontName)) {
928       delete fontName;
929       continue;
930     }
931     fileName = NULL;
932     if (dir) {
933       fileName = appendToPath(new GString(dir), displayFontTab[i].fileName);
934       if ((f = fopen(fileName->getCString(), "rb"))) {
935         fclose(f);
936       } else {
937         delete fileName;
938         fileName = NULL;
939       }
940     }
941 #ifndef WIN32
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"))) {
946         fclose(f);
947       } else {
948         delete fileName;
949         fileName = NULL;
950       }
951     }
952 #endif
953     if (!fileName) {
954       error(-1, "No display font for '%s'", displayFontTab[i].name);
955       delete fontName;
956       continue;
957     }
958     dfp = new DisplayFontParam(fontName, displayFontT1);
959     dfp->t1.fileName = fileName;
960     globalParams->addDisplayFont(dfp);
961   }
962 }
963
964 //------------------------------------------------------------------------
965
966 void GlobalParams::setupBaseFontsFc(FcConfig *fcConfig) {
967   GString *fontName;
968   GString *fileName;
969   DisplayFontParam *dfp;
970   FcPattern *namePat, *matchPat;
971   FcResult result;
972   FcChar8 *fcFileName;
973   int i;
974   DisplayFontParamKind kind;
975
976   for (i = 0; displayFontTabFc[i].name; ++i) {
977     fontName = new GString(displayFontTabFc[i].name);
978     if (getDisplayFont(fontName)) {
979       delete fontName;
980       continue;
981     }
982     fileName = NULL;
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);
988
989     if (result == FcResultMatch) {
990       result = FcPatternGetString(matchPat, "file", 0, &fcFileName);
991       if (result == FcResultMatch)
992         fileName = new GString((const char *)fcFileName);
993     }
994
995     FcPatternDestroy(matchPat);
996     FcPatternDestroy(namePat);
997
998     if (fileName) {
999       char *ext;
1000
1001       /* FIXME */
1002       ext = strrchr(fileName->getCString(), '.');
1003       if (ext) {
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;
1012         else {
1013           delete fileName;
1014           fileName = NULL;
1015         }
1016       } else {
1017         delete fileName;
1018         fileName = NULL;
1019       }
1020     }
1021
1022     if (!fileName) {
1023       error(-1, "No display font for '%s'", displayFontTabFc[i].name);
1024       delete fontName;
1025       continue;
1026     }
1027
1028     dfp = new DisplayFontParam(fontName, kind);
1029     switch (kind) {
1030     case displayFontT1:
1031       dfp->t1.fileName = fileName;
1032       break;
1033     case displayFontTT:
1034       dfp->tt.fileName = fileName;
1035     }
1036       
1037     globalParams->addDisplayFont(dfp);
1038   }
1039 }
1040
1041 //------------------------------------------------------------------------
1042 // accessors
1043 //------------------------------------------------------------------------
1044
1045 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
1046   // no need to lock - macRomanReverseMap is constant
1047   return macRomanReverseMap->lookup(charName);
1048 }
1049
1050 Unicode GlobalParams::mapNameToUnicode(char *charName) {
1051   // no need to lock - nameToUnicode is constant
1052   return nameToUnicode->lookup(charName);
1053 }
1054
1055 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
1056   UnicodeMap *map;
1057
1058   lockGlobalParams;
1059   map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1060   unlockGlobalParams;
1061   if (map) {
1062     map->incRefCnt();
1063   }
1064   return map;
1065 }
1066
1067 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
1068   GString *fileName;
1069   FILE *f;
1070
1071   lockGlobalParams;
1072   if ((fileName = (GString *)unicodeMaps->lookup(encodingName))) {
1073     f = fopen(fileName->getCString(), "r");
1074   } else {
1075     f = NULL;
1076   }
1077   unlockGlobalParams;
1078   return f;
1079 }
1080
1081 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
1082   GList *list;
1083   GString *dir;
1084   GString *fileName;
1085   FILE *f;
1086   int i;
1087
1088   lockGlobalParams;
1089   if (!(list = (GList *)cMapDirs->lookup(collection))) {
1090     unlockGlobalParams;
1091     return NULL;
1092   }
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");
1097     delete fileName;
1098     if (f) {
1099       unlockGlobalParams;
1100       return f;
1101     }
1102   }
1103   unlockGlobalParams;
1104   return NULL;
1105 }
1106
1107 FILE *GlobalParams::findToUnicodeFile(GString *name) {
1108   GString *dir, *fileName;
1109   FILE *f;
1110   int i;
1111
1112   lockGlobalParams;
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");
1117     delete fileName;
1118     if (f) {
1119       unlockGlobalParams;
1120       return f;
1121     }
1122   }
1123   unlockGlobalParams;
1124   return NULL;
1125 }
1126
1127 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
1128   DisplayFontParam *dfp;
1129
1130   lockGlobalParams;
1131   dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1132   unlockGlobalParams;
1133   return dfp;
1134 }
1135
1136 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
1137                                                   GString *collection) {
1138   DisplayFontParam *dfp;
1139
1140   lockGlobalParams;
1141   if (!fontName ||
1142       !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
1143     dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
1144   }
1145   unlockGlobalParams;
1146   return dfp;
1147 }
1148
1149 GString *GlobalParams::getPSFile() {
1150   GString *s;
1151
1152   lockGlobalParams;
1153   s = psFile ? psFile->copy() : (GString *)NULL;
1154   unlockGlobalParams;
1155   return s;
1156 }
1157
1158 int GlobalParams::getPSPaperWidth() {
1159   int w;
1160
1161   lockGlobalParams;
1162   w = psPaperWidth;
1163   unlockGlobalParams;
1164   return w;
1165 }
1166
1167 int GlobalParams::getPSPaperHeight() {
1168   int h;
1169
1170   lockGlobalParams;
1171   h = psPaperHeight;
1172   unlockGlobalParams;
1173   return h;
1174 }
1175
1176 void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1177   lockGlobalParams;
1178   *llx = psImageableLLX;
1179   *lly = psImageableLLY;
1180   *urx = psImageableURX;
1181   *ury = psImageableURY;
1182   unlockGlobalParams;
1183 }
1184
1185 GBool GlobalParams::getPSCrop() {
1186   GBool f;
1187
1188   lockGlobalParams;
1189   f = psCrop;
1190   unlockGlobalParams;
1191   return f;
1192 }
1193
1194 GBool GlobalParams::getPSExpandSmaller() {
1195   GBool f;
1196
1197   lockGlobalParams;
1198   f = psExpandSmaller;
1199   unlockGlobalParams;
1200   return f;
1201 }
1202
1203 GBool GlobalParams::getPSShrinkLarger() {
1204   GBool f;
1205
1206   lockGlobalParams;
1207   f = psShrinkLarger;
1208   unlockGlobalParams;
1209   return f;
1210 }
1211
1212 GBool GlobalParams::getPSCenter() {
1213   GBool f;
1214
1215   lockGlobalParams;
1216   f = psCenter;
1217   unlockGlobalParams;
1218   return f;
1219 }
1220
1221 GBool GlobalParams::getPSDuplex() {
1222   GBool d;
1223
1224   lockGlobalParams;
1225   d = psDuplex;
1226   unlockGlobalParams;
1227   return d;
1228 }
1229
1230 PSLevel GlobalParams::getPSLevel() {
1231   PSLevel level;
1232
1233   lockGlobalParams;
1234   level = psLevel;
1235   unlockGlobalParams;
1236   return level;
1237 }
1238
1239 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
1240   PSFontParam *p;
1241
1242   lockGlobalParams;
1243   p = (PSFontParam *)psFonts->lookup(fontName);
1244   unlockGlobalParams;
1245   return p;
1246 }
1247
1248 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
1249                                        GString *collection, int wMode) {
1250   PSFontParam *p;
1251   int i;
1252
1253   lockGlobalParams;
1254   p = NULL;
1255   if (fontName) {
1256     for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1257       p = (PSFontParam *)psNamedFonts16->get(i);
1258       if (!p->pdfFontName->cmp(fontName) &&
1259           p->wMode == wMode) {
1260         break;
1261       }
1262       p = NULL;
1263     }
1264   }
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) {
1270         break;
1271       }
1272       p = NULL;
1273     }
1274   }
1275   unlockGlobalParams;
1276   return p;
1277 }
1278
1279 GBool GlobalParams::getPSEmbedType1() {
1280   GBool e;
1281
1282   lockGlobalParams;
1283   e = psEmbedType1;
1284   unlockGlobalParams;
1285   return e;
1286 }
1287
1288 GBool GlobalParams::getPSEmbedTrueType() {
1289   GBool e;
1290
1291   lockGlobalParams;
1292   e = psEmbedTrueType;
1293   unlockGlobalParams;
1294   return e;
1295 }
1296
1297 GBool GlobalParams::getPSEmbedCIDPostScript() {
1298   GBool e;
1299
1300   lockGlobalParams;
1301   e = psEmbedCIDPostScript;
1302   unlockGlobalParams;
1303   return e;
1304 }
1305
1306 GBool GlobalParams::getPSEmbedCIDTrueType() {
1307   GBool e;
1308
1309   lockGlobalParams;
1310   e = psEmbedCIDTrueType;
1311   unlockGlobalParams;
1312   return e;
1313 }
1314
1315 GBool GlobalParams::getPSOPI() {
1316   GBool opi;
1317
1318   lockGlobalParams;
1319   opi = psOPI;
1320   unlockGlobalParams;
1321   return opi;
1322 }
1323
1324 GBool GlobalParams::getPSASCIIHex() {
1325   GBool ah;
1326
1327   lockGlobalParams;
1328   ah = psASCIIHex;
1329   unlockGlobalParams;
1330   return ah;
1331 }
1332
1333 GString *GlobalParams::getTextEncodingName() {
1334   GString *s;
1335
1336   lockGlobalParams;
1337   s = textEncoding->copy();
1338   unlockGlobalParams;
1339   return s;
1340 }
1341
1342 EndOfLineKind GlobalParams::getTextEOL() {
1343   EndOfLineKind eol;
1344
1345   lockGlobalParams;
1346   eol = textEOL;
1347   unlockGlobalParams;
1348   return eol;
1349 }
1350
1351 GBool GlobalParams::getTextPageBreaks() {
1352   GBool pageBreaks;
1353
1354   lockGlobalParams;
1355   pageBreaks = textPageBreaks;
1356   unlockGlobalParams;
1357   return pageBreaks;
1358 }
1359
1360 GBool GlobalParams::getTextKeepTinyChars() {
1361   GBool tiny;
1362
1363   lockGlobalParams;
1364   tiny = textKeepTinyChars;
1365   unlockGlobalParams;
1366   return tiny;
1367 }
1368
1369 GString *GlobalParams::findFontFile(GString *fontName, char **exts) {
1370   GString *dir, *fileName;
1371   char **ext;
1372   FILE *f;
1373   int i;
1374
1375   lockGlobalParams;
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"))) {
1382         fclose(f);
1383         unlockGlobalParams;
1384         return fileName;
1385       }
1386       delete fileName;
1387     }
1388   }
1389   unlockGlobalParams;
1390   return NULL;
1391 }
1392
1393 GString *GlobalParams::getInitialZoom() {
1394   GString *s;
1395
1396   lockGlobalParams;
1397   s = initialZoom->copy();
1398   unlockGlobalParams;
1399   return s;
1400 }
1401
1402 GBool GlobalParams::getEnableT1lib() {
1403   GBool f;
1404
1405   lockGlobalParams;
1406   f = enableT1lib;
1407   unlockGlobalParams;
1408   return f;
1409 }
1410
1411 GBool GlobalParams::getEnableFreeType() {
1412   GBool f;
1413
1414   lockGlobalParams;
1415   f = enableFreeType;
1416   unlockGlobalParams;
1417   return f;
1418 }
1419
1420
1421 GBool GlobalParams::getAntialias() {
1422   GBool f;
1423
1424   lockGlobalParams;
1425   f = antialias;
1426   unlockGlobalParams;
1427   return f;
1428 }
1429
1430 GBool GlobalParams::getMapNumericCharNames() {
1431   GBool map;
1432
1433   lockGlobalParams;
1434   map = mapNumericCharNames;
1435   unlockGlobalParams;
1436   return map;
1437 }
1438
1439 GBool GlobalParams::getPrintCommands() {
1440   GBool p;
1441
1442   lockGlobalParams;
1443   p = printCommands;
1444   unlockGlobalParams;
1445   return p;
1446 }
1447
1448 GBool GlobalParams::getErrQuiet() {
1449   GBool q;
1450
1451   lockGlobalParams;
1452   q = errQuiet;
1453   unlockGlobalParams;
1454   return q;
1455 }
1456
1457 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
1458   GString *fileName;
1459   CharCodeToUnicode *ctu;
1460
1461   lockGlobalParams;
1462   if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1463     if ((fileName = (GString *)cidToUnicodes->lookup(collection)) &&
1464         (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1465       cidToUnicodeCache->add(ctu);
1466     }
1467   }
1468   unlockGlobalParams;
1469   return ctu;
1470 }
1471
1472 CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GString *fontName) {
1473   CharCodeToUnicode *ctu;
1474   GHashIter *iter;
1475   GString *fontPattern, *fileName;
1476
1477   lockGlobalParams;
1478   fileName = NULL;
1479   unicodeToUnicodes->startIter(&iter);
1480   while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1481     if (strstr(fontName->getCString(), fontPattern->getCString())) {
1482       unicodeToUnicodes->killIter(&iter);
1483       break;
1484     }
1485     fileName = NULL;
1486   }
1487   if (fileName) {
1488     if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1489       if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1490         unicodeToUnicodeCache->add(ctu);
1491       }
1492     }
1493   } else {
1494     ctu = NULL;
1495   }
1496   unlockGlobalParams;
1497   return ctu;
1498 }
1499
1500 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
1501   return getUnicodeMap2(encodingName);
1502 }
1503
1504 UnicodeMap *GlobalParams::getUnicodeMap2(GString *encodingName) {
1505   UnicodeMap *map;
1506
1507   if (!(map = getResidentUnicodeMap(encodingName))) {
1508     lockUnicodeMapCache;
1509     map = unicodeMapCache->getUnicodeMap(encodingName);
1510     unlockUnicodeMapCache;
1511   }
1512   return map;
1513 }
1514
1515 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
1516   CMap *cMap;
1517
1518   lockCMapCache;
1519   cMap = cMapCache->getCMap(collection, cMapName);
1520   unlockCMapCache;
1521   return cMap;
1522 }
1523
1524 UnicodeMap *GlobalParams::getTextEncoding() {
1525   return getUnicodeMap2(textEncoding);
1526 }
1527
1528 //------------------------------------------------------------------------
1529 // functions to set parameters
1530 //------------------------------------------------------------------------
1531
1532 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
1533   DisplayFontParam *old;
1534
1535   lockGlobalParams;
1536   if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
1537     delete old;
1538   }
1539   displayFonts->add(param->name, param);
1540   unlockGlobalParams;
1541 }
1542
1543 void GlobalParams::setPSFile(char *file) {
1544   lockGlobalParams;
1545   if (psFile) {
1546     delete psFile;
1547   }
1548   psFile = new GString(file);
1549   unlockGlobalParams;
1550 }
1551
1552 GBool GlobalParams::setPSPaperSize(char *size) {
1553   lockGlobalParams;
1554   if (!strcmp(size, "match")) {
1555     psPaperWidth = psPaperHeight = -1;
1556   } else if (!strcmp(size, "letter")) {
1557     psPaperWidth = 612;
1558     psPaperHeight = 792;
1559   } else if (!strcmp(size, "legal")) {
1560     psPaperWidth = 612;
1561     psPaperHeight = 1008;
1562   } else if (!strcmp(size, "A4")) {
1563     psPaperWidth = 595;
1564     psPaperHeight = 842;
1565   } else if (!strcmp(size, "A3")) {
1566     psPaperWidth = 842;
1567     psPaperHeight = 1190;
1568   } else {
1569     unlockGlobalParams;
1570     return gFalse;
1571   }
1572   psImageableLLX = psImageableLLY = 0;
1573   psImageableURX = psPaperWidth;
1574   psImageableURY = psPaperHeight;
1575   unlockGlobalParams;
1576   return gTrue;
1577 }
1578
1579 void GlobalParams::setPSPaperWidth(int width) {
1580   lockGlobalParams;
1581   psPaperWidth = width;
1582   psImageableLLX = 0;
1583   psImageableURX = psPaperWidth;
1584   unlockGlobalParams;
1585 }
1586
1587 void GlobalParams::setPSPaperHeight(int height) {
1588   lockGlobalParams;
1589   psPaperHeight = height;
1590   psImageableLLY = 0;
1591   psImageableURY = psPaperHeight;
1592   unlockGlobalParams;
1593 }
1594
1595 void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1596   lockGlobalParams;
1597   psImageableLLX = llx;
1598   psImageableLLY = lly;
1599   psImageableURX = urx;
1600   psImageableURY = ury;
1601   unlockGlobalParams;
1602 }
1603
1604 void GlobalParams::setPSCrop(GBool crop) {
1605   lockGlobalParams;
1606   psCrop = crop;
1607   unlockGlobalParams;
1608 }
1609
1610 void GlobalParams::setPSExpandSmaller(GBool expand) {
1611   lockGlobalParams;
1612   psExpandSmaller = expand;
1613   unlockGlobalParams;
1614 }
1615
1616 void GlobalParams::setPSShrinkLarger(GBool shrink) {
1617   lockGlobalParams;
1618   psShrinkLarger = shrink;
1619   unlockGlobalParams;
1620 }
1621
1622 void GlobalParams::setPSCenter(GBool center) {
1623   lockGlobalParams;
1624   psCenter = center;
1625   unlockGlobalParams;
1626 }
1627
1628 void GlobalParams::setPSDuplex(GBool duplex) {
1629   lockGlobalParams;
1630   psDuplex = duplex;
1631   unlockGlobalParams;
1632 }
1633
1634 void GlobalParams::setPSLevel(PSLevel level) {
1635   lockGlobalParams;
1636   psLevel = level;
1637   unlockGlobalParams;
1638 }
1639
1640 void GlobalParams::setPSEmbedType1(GBool embed) {
1641   lockGlobalParams;
1642   psEmbedType1 = embed;
1643   unlockGlobalParams;
1644 }
1645
1646 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1647   lockGlobalParams;
1648   psEmbedTrueType = embed;
1649   unlockGlobalParams;
1650 }
1651
1652 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1653   lockGlobalParams;
1654   psEmbedCIDPostScript = embed;
1655   unlockGlobalParams;
1656 }
1657
1658 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1659   lockGlobalParams;
1660   psEmbedCIDTrueType = embed;
1661   unlockGlobalParams;
1662 }
1663
1664 void GlobalParams::setPSOPI(GBool opi) {
1665   lockGlobalParams;
1666   psOPI = opi;
1667   unlockGlobalParams;
1668 }
1669
1670 void GlobalParams::setPSASCIIHex(GBool hex) {
1671   lockGlobalParams;
1672   psASCIIHex = hex;
1673   unlockGlobalParams;
1674 }
1675
1676 void GlobalParams::setTextEncoding(char *encodingName) {
1677   lockGlobalParams;
1678   delete textEncoding;
1679   textEncoding = new GString(encodingName);
1680   unlockGlobalParams;
1681 }
1682
1683 GBool GlobalParams::setTextEOL(char *s) {
1684   lockGlobalParams;
1685   if (!strcmp(s, "unix")) {
1686     textEOL = eolUnix;
1687   } else if (!strcmp(s, "dos")) {
1688     textEOL = eolDOS;
1689   } else if (!strcmp(s, "mac")) {
1690     textEOL = eolMac;
1691   } else {
1692     unlockGlobalParams;
1693     return gFalse;
1694   }
1695   unlockGlobalParams;
1696   return gTrue;
1697 }
1698
1699 void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1700   lockGlobalParams;
1701   textPageBreaks = pageBreaks;
1702   unlockGlobalParams;
1703 }
1704
1705 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1706   lockGlobalParams;
1707   textKeepTinyChars = keep;
1708   unlockGlobalParams;
1709 }
1710
1711 void GlobalParams::setInitialZoom(char *s) {
1712   lockGlobalParams;
1713   delete initialZoom;
1714   initialZoom = new GString(s);
1715   unlockGlobalParams;
1716 }
1717
1718 GBool GlobalParams::setEnableT1lib(char *s) {
1719   GBool ok;
1720
1721   lockGlobalParams;
1722   ok = parseYesNo2(s, &enableT1lib);
1723   unlockGlobalParams;
1724   return ok;
1725 }
1726
1727 GBool GlobalParams::setEnableFreeType(char *s) {
1728   GBool ok;
1729
1730   lockGlobalParams;
1731   ok = parseYesNo2(s, &enableFreeType);
1732   unlockGlobalParams;
1733   return ok;
1734 }
1735
1736
1737 GBool GlobalParams::setAntialias(char *s) {
1738   GBool ok;
1739
1740   lockGlobalParams;
1741   ok = parseYesNo2(s, &antialias);
1742   unlockGlobalParams;
1743   return ok;
1744 }
1745
1746 void GlobalParams::setMapNumericCharNames(GBool map) {
1747   lockGlobalParams;
1748   mapNumericCharNames = map;
1749   unlockGlobalParams;
1750 }
1751
1752 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1753   lockGlobalParams;
1754   printCommands = printCommandsA;
1755   unlockGlobalParams;
1756 }
1757
1758 void GlobalParams::setErrQuiet(GBool errQuietA) {
1759   lockGlobalParams;
1760   errQuiet = errQuietA;
1761   unlockGlobalParams;
1762 }