]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/GlobalParams.cc
Import of Xpdf 2.00 for merge
[evince.git] / pdf / xpdf / GlobalParams.cc
1 //========================================================================
2 //
3 // GlobalParams.cc
4 //
5 // Copyright 2001-2002 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 <ctype.h>
17 #if HAVE_PAPER_H
18 #include <paper.h>
19 #endif
20 #include "gmem.h"
21 #include "GString.h"
22 #include "GList.h"
23 #include "GHash.h"
24 #include "gfile.h"
25 #include "Error.h"
26 #include "NameToCharCode.h"
27 #include "CharCodeToUnicode.h"
28 #include "UnicodeMap.h"
29 #include "CMap.h"
30 #include "BuiltinFontTables.h"
31 #include "FontEncodingTables.h"
32 #include "GlobalParams.h"
33
34 #include "NameToUnicodeTable.h"
35 #include "UnicodeMapTables.h"
36 #include "DisplayFontTable.h"
37 #include "UTF8.h"
38
39 //------------------------------------------------------------------------
40
41 GlobalParams *globalParams = NULL;
42
43 //------------------------------------------------------------------------
44 // DisplayFontParam
45 //------------------------------------------------------------------------
46
47 DisplayFontParam::DisplayFontParam(GString *nameA,
48                                    DisplayFontParamKind kindA) {
49   name = nameA;
50   kind = kindA;
51   switch (kind) {
52   case displayFontX:
53     x.xlfd = NULL;
54     x.encoding = NULL;
55     break;
56   case displayFontT1:
57     t1.fileName = NULL;
58     break;
59   case displayFontTT:
60     tt.fileName = NULL;
61     break;
62   }
63 }
64
65 DisplayFontParam::DisplayFontParam(char *nameA, char *xlfdA, char *encodingA) {
66   name = new GString(nameA);
67   kind = displayFontX;
68   x.xlfd = new GString(xlfdA);
69   x.encoding = new GString(encodingA);
70 }
71
72 DisplayFontParam::~DisplayFontParam() {
73   delete name;
74   switch (kind) {
75   case displayFontX:
76     if (x.xlfd) {
77       delete x.xlfd;
78     }
79     if (x.encoding) {
80       delete x.encoding;
81     }
82     break;
83   case displayFontT1:
84     if (t1.fileName) {
85       delete t1.fileName;
86     }
87     break;
88   case displayFontTT:
89     if (tt.fileName) {
90       delete tt.fileName;
91     }
92     break;
93   }
94 }
95
96 //------------------------------------------------------------------------
97 // PSFontParam
98 //------------------------------------------------------------------------
99
100 PSFontParam::PSFontParam(GString *pdfFontNameA, int wModeA,
101                          GString *psFontNameA, GString *encodingA) {
102   pdfFontName = pdfFontNameA;
103   wMode = wModeA;
104   psFontName = psFontNameA;
105   encoding = encodingA;
106 }
107
108 PSFontParam::~PSFontParam() {
109   delete pdfFontName;
110   delete psFontName;
111   if (encoding) {
112     delete encoding;
113   }
114 }
115
116 //------------------------------------------------------------------------
117 // parsing
118 //------------------------------------------------------------------------
119
120 GlobalParams::GlobalParams(char *cfgFileName) {
121   UnicodeMap *map;
122   DisplayFontParam *dfp;
123   GString *fileName;
124   FILE *f;
125   int i;
126
127   initBuiltinFontTables();
128
129   // scan the encoding in reverse because we want the lowest-numbered
130   // index for each char name ('space' is encoded twice)
131   macRomanReverseMap = new NameToCharCode();
132   for (i = 255; i >= 0; --i) {
133     if (macRomanEncoding[i]) {
134       macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
135     }
136   }
137
138   nameToUnicode = new NameToCharCode();
139   cidToUnicodes = new GHash(gTrue);
140   residentUnicodeMaps = new GHash();
141   unicodeMaps = new GHash(gTrue);
142   cMapDirs = new GHash(gTrue);
143   toUnicodeDirs = new GList();
144   displayFonts = new GHash();
145   displayCIDFonts = new GHash();
146   displayNamedCIDFonts = new GHash();
147 #if HAVE_PAPER_H
148   char *paperName;
149   const struct paper *paperType;
150   paperinit();
151   if ((paperName = systempapername())) {
152     paperType = paperinfo(paperName);
153     psPaperWidth = (int)paperpswidth(paperType);
154     psPaperHeight = (int)paperpsheight(paperType);
155   } else {
156     error(-1, "No paper information available - using defaults");
157     psPaperWidth = defPaperWidth;
158     psPaperHeight = defPaperHeight;
159   }
160   paperdone();
161 #else
162   psPaperWidth = defPaperWidth;
163   psPaperHeight = defPaperHeight;
164 #endif
165   psDuplex = gFalse;
166   psLevel = psLevel2;
167   psFile = NULL;
168   psFonts = new GHash();
169   psNamedFonts16 = new GList();
170   psFonts16 = new GList();
171   psEmbedType1 = gTrue;
172   psEmbedTrueType = gTrue;
173   psEmbedCIDPostScript = gTrue;
174   psEmbedCIDTrueType = gTrue;
175   psOPI = gFalse;
176   psASCIIHex = gFalse;
177   textEncoding = new GString("Latin1");
178 #if defined(WIN32)
179   textEOL = eolDOS;
180 #elif defined(MACOS)
181   textEOL = eolMac;
182 #else
183   textEOL = eolUnix;
184 #endif
185   textKeepTinyChars = gFalse;
186   fontDirs = new GList();
187   initialZoom = new GString("1");
188   t1libControl = fontRastAALow;
189   freetypeControl = fontRastAALow;
190   urlCommand = NULL;
191   movieCommand = NULL;
192   mapNumericCharNames = gTrue;
193   printCommands = gFalse;
194   errQuiet = gFalse;
195
196   cidToUnicodeCache = new CIDToUnicodeCache();
197   unicodeMapCache = new UnicodeMapCache();
198   cMapCache = new CMapCache();
199
200   // set up the initial nameToUnicode table
201   for (i = 0; nameToUnicodeTab[i].name; ++i) {
202     nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
203   }
204
205   // set up the residentUnicodeMaps table
206   map = new UnicodeMap("Latin1", gFalse,
207                        latin1UnicodeMapRanges, latin1UnicodeMapLen);
208   residentUnicodeMaps->add(map->getEncodingName(), map);
209   map = new UnicodeMap("ASCII7", gFalse,
210                        ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
211   residentUnicodeMaps->add(map->getEncodingName(), map);
212   map = new UnicodeMap("Symbol", gFalse,
213                        symbolUnicodeMapRanges, symbolUnicodeMapLen);
214   residentUnicodeMaps->add(map->getEncodingName(), map);
215   map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
216                        zapfDingbatsUnicodeMapLen);
217   residentUnicodeMaps->add(map->getEncodingName(), map);
218   map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
219   residentUnicodeMaps->add(map->getEncodingName(), map);
220   map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
221   residentUnicodeMaps->add(map->getEncodingName(), map);
222
223   // default displayFonts table
224   for (i = 0; displayFontTab[i].name; ++i) {
225     dfp = new DisplayFontParam(displayFontTab[i].name,
226                                displayFontTab[i].xlfd,
227                                displayFontTab[i].encoding);
228     displayFonts->add(dfp->name, dfp);
229   }
230
231   // look for a user config file, then a system-wide config file
232   f = NULL;
233   fileName = NULL;
234   if (cfgFileName && cfgFileName[0]) {
235     fileName = new GString(cfgFileName);
236     if (!(f = fopen(fileName->getCString(), "r"))) {
237       delete fileName;
238     }
239   }
240   if (!f) {
241     fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
242     if (!(f = fopen(fileName->getCString(), "r"))) {
243       delete fileName;
244     }
245   }
246   if (!f) {
247 #if defined(WIN32) && !defined(__CYGWIN32__)
248     char buf[512];
249     i = GetModuleFileName(NULL, buf, sizeof(buf));
250     if (i <= 0 || i >= sizeof(buf)) {
251       // error or path too long for buffer - just use the current dir
252       buf[0] = '\0';
253     }
254     fileName = grabPath(buf);
255     appendToPath(fileName, xpdfSysConfigFile);
256 #else
257     fileName = new GString(xpdfSysConfigFile);
258 #endif
259     if (!(f = fopen(fileName->getCString(), "r"))) {
260       delete fileName;
261     }
262   }
263   if (f) {
264     parseFile(fileName, f);
265     delete fileName;
266     fclose(f);
267   }
268 }
269
270 void GlobalParams::parseFile(GString *fileName, FILE *f) {
271   int line;
272   GList *tokens;
273   GString *cmd, *incFile;
274   char *p1, *p2;
275   char buf[512];
276   FILE *f2;
277
278   line = 1;
279   while (fgets(buf, sizeof(buf) - 1, f)) {
280
281     // break the line into tokens
282     tokens = new GList();
283     p1 = buf;
284     while (*p1) {
285       for (; *p1 && isspace(*p1); ++p1) ;
286       if (!*p1) {
287         break;
288       }
289       if (*p1 == '"' || *p1 == '\'') {
290         for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
291         ++p1;
292       } else {
293         for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
294       }
295       tokens->append(new GString(p1, p2 - p1));
296       p1 = p2 + 1;
297     }
298
299     if (tokens->getLength() > 0 &&
300         ((GString *)tokens->get(0))->getChar(0) != '#') {
301       cmd = (GString *)tokens->get(0);
302       if (!cmd->cmp("include")) {
303         if (tokens->getLength() == 2) {
304           incFile = (GString *)tokens->get(1);
305           if ((f2 = fopen(incFile->getCString(), "r"))) {
306             parseFile(incFile, f2);
307             fclose(f2);
308           } else {
309             error(-1, "Couldn't find included config file: '%s' (%s:%d)",
310                   incFile->getCString(), fileName->getCString(), line);
311           }
312         } else {
313           error(-1, "Bad 'include' config file command (%s:%d)",
314                 fileName->getCString(), line);
315         }
316       } else if (!cmd->cmp("nameToUnicode")) {
317         parseNameToUnicode(tokens, fileName, line);
318       } else if (!cmd->cmp("cidToUnicode")) {
319         parseCIDToUnicode(tokens, fileName, line);
320       } else if (!cmd->cmp("unicodeMap")) {
321         parseUnicodeMap(tokens, fileName, line);
322       } else if (!cmd->cmp("cMapDir")) {
323         parseCMapDir(tokens, fileName, line);
324       } else if (!cmd->cmp("toUnicodeDir")) {
325         parseToUnicodeDir(tokens, fileName, line);
326       } else if (!cmd->cmp("displayFontX")) {
327         parseDisplayFont(tokens, displayFonts, displayFontX, fileName, line);
328       } else if (!cmd->cmp("displayFontT1")) {
329         parseDisplayFont(tokens, displayFonts, displayFontT1, fileName, line);
330       } else if (!cmd->cmp("displayFontTT")) {
331         parseDisplayFont(tokens, displayFonts, displayFontTT, fileName, line);
332       } else if (!cmd->cmp("displayCIDFontX")) {
333         parseDisplayFont(tokens, displayCIDFonts,
334                          displayFontX, fileName, line);
335       } else if (!cmd->cmp("displayNamedCIDFontX")) {
336         parseDisplayFont(tokens, displayNamedCIDFonts,
337                          displayFontX, fileName, line);
338       } else if (!cmd->cmp("psFile")) {
339         parsePSFile(tokens, fileName, line);
340       } else if (!cmd->cmp("psFont")) {
341         parsePSFont(tokens, fileName, line);
342       } else if (!cmd->cmp("psNamedFont16")) {
343         parsePSFont16("psNamedFont16", psNamedFonts16,
344                       tokens, fileName, line);
345       } else if (!cmd->cmp("psFont16")) {
346         parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
347       } else if (!cmd->cmp("psPaperSize")) {
348         parsePSPaperSize(tokens, fileName, line);
349       } else if (!cmd->cmp("psDuplex")) {
350         parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
351       } else if (!cmd->cmp("psLevel")) {
352         parsePSLevel(tokens, fileName, line);
353       } else if (!cmd->cmp("psEmbedType1Fonts")) {
354         parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
355       } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
356         parseYesNo("psEmbedTrueType", &psEmbedTrueType,
357                    tokens, fileName, line);
358       } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
359         parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
360                    tokens, fileName, line);
361       } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
362         parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
363                    tokens, fileName, line);
364       } else if (!cmd->cmp("psOPI")) {
365         parseYesNo("psOPI", &psOPI, tokens, fileName, line);
366       } else if (!cmd->cmp("psASCIIHex")) {
367         parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
368       } else if (!cmd->cmp("textEncoding")) {
369         parseTextEncoding(tokens, fileName, line);
370       } else if (!cmd->cmp("textEOL")) {
371         parseTextEOL(tokens, fileName, line);
372       } else if (!cmd->cmp("textKeepTinyChars")) {
373         parseYesNo("textKeepTinyChars", &textKeepTinyChars,
374                    tokens, fileName, line);
375       } else if (!cmd->cmp("fontDir")) {
376         parseFontDir(tokens, fileName, line);
377       } else if (!cmd->cmp("initialZoom")) {
378         parseInitialZoom(tokens, fileName, line);
379       } else if (!cmd->cmp("t1libControl")) {
380         parseFontRastControl("t1libControl", &t1libControl,
381                              tokens, fileName, line);
382       } else if (!cmd->cmp("freetypeControl")) {
383         parseFontRastControl("freetypeControl", &freetypeControl,
384                              tokens, fileName, line);
385       } else if (!cmd->cmp("urlCommand")) {
386         parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
387       } else if (!cmd->cmp("movieCommand")) {
388         parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
389       } else if (!cmd->cmp("mapNumericCharNames")) {
390         parseYesNo("mapNumericCharNames", &mapNumericCharNames,
391                    tokens, fileName, line);
392       } else if (!cmd->cmp("printCommands")) {
393         parseYesNo("printCommands", &printCommands, tokens, fileName, line);
394       } else if (!cmd->cmp("errQuiet")) {
395         parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
396       } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
397         error(-1, "Unknown config file command");
398         error(-1, "-- the config file format has changed since Xpdf 0.9x");
399       } else {
400         error(-1, "Unknown config file command '%s' (%s:%d)",
401               cmd->getCString(), fileName->getCString(), line);
402       }
403     }
404
405     deleteGList(tokens, GString);
406     ++line;
407   }
408 }
409
410 void GlobalParams::parseNameToUnicode(GList *tokens, GString *fileName,
411                                          int line) {
412   GString *name;
413   char *tok1, *tok2;
414   FILE *f;
415   char buf[256];
416   int line2;
417   Unicode u;
418
419   if (tokens->getLength() != 2) {
420     error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
421           fileName->getCString(), line);
422     return;
423   }
424   name = (GString *)tokens->get(1);
425   if (!(f = fopen(name->getCString(), "r"))) {
426     error(-1, "Couldn't open 'nameToUnicode' file '%s'",
427           name->getCString());
428     return;
429   }
430   line2 = 1;
431   while (fgets(buf, sizeof(buf), f)) {
432     tok1 = strtok(buf, " \t\r\n");
433     tok2 = strtok(NULL, " \t\r\n");
434     if (tok1 && tok2) {
435       sscanf(tok1, "%x", &u);
436       nameToUnicode->add(tok2, u);
437     } else {
438       error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", name, line2);
439     }
440     ++line2;
441   }
442   fclose(f);
443 }
444
445 void GlobalParams::parseCIDToUnicode(GList *tokens, GString *fileName,
446                                      int line) {
447   GString *collection, *name, *old;
448
449   if (tokens->getLength() != 3) {
450     error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
451           fileName->getCString(), line);
452     return;
453   }
454   collection = (GString *)tokens->get(1);
455   name = (GString *)tokens->get(2);
456   if ((old = (GString *)cidToUnicodes->remove(collection))) {
457     delete old;
458   }
459   cidToUnicodes->add(collection->copy(), name->copy());
460 }
461
462 void GlobalParams::parseUnicodeMap(GList *tokens, GString *fileName,
463                                    int line) {
464   GString *encodingName, *name, *old;
465
466   if (tokens->getLength() != 3) {
467     error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
468           fileName->getCString(), line);
469     return;
470   }
471   encodingName = (GString *)tokens->get(1);
472   name = (GString *)tokens->get(2);
473   if ((old = (GString *)unicodeMaps->remove(encodingName))) {
474     delete old;
475   }
476   unicodeMaps->add(encodingName->copy(), name->copy());
477 }
478
479 void GlobalParams::parseCMapDir(GList *tokens, GString *fileName, int line) {
480   GString *collection, *dir;
481   GList *list;
482
483   if (tokens->getLength() != 3) {
484     error(-1, "Bad 'cMapDir' config file command (%s:%d)",
485           fileName->getCString(), line);
486     return;
487   }
488   collection = (GString *)tokens->get(1);
489   dir = (GString *)tokens->get(2);
490   if (!(list = (GList *)cMapDirs->lookup(collection))) {
491     list = new GList();
492     cMapDirs->add(collection->copy(), list);
493   }
494   list->append(dir->copy());
495 }
496
497 void GlobalParams::parseToUnicodeDir(GList *tokens, GString *fileName,
498                                      int line) {
499   if (tokens->getLength() != 2) {
500     error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
501           fileName->getCString(), line);
502     return;
503   }
504   toUnicodeDirs->append(((GString *)tokens->get(1))->copy());
505 }
506
507 void GlobalParams::parseDisplayFont(GList *tokens, GHash *fontHash,
508                                     DisplayFontParamKind kind,
509                                     GString *fileName, int line) {
510   DisplayFontParam *param, *old;
511
512   if (tokens->getLength() < 2) {
513     goto err1;
514   }
515   param = new DisplayFontParam(((GString *)tokens->get(1))->copy(), kind);
516   
517   switch (kind) {
518   case displayFontX:
519     if (tokens->getLength() != 4) {
520       goto err2;
521     }
522     param->x.xlfd = ((GString *)tokens->get(2))->copy();
523     param->x.encoding = ((GString *)tokens->get(3))->copy();
524     break;
525   case displayFontT1:
526     if (tokens->getLength() != 3) {
527       goto err2;
528     }
529     param->t1.fileName = ((GString *)tokens->get(2))->copy();
530     break;
531   case displayFontTT:
532     if (tokens->getLength() != 3) {
533       goto err2;
534     }
535     param->tt.fileName = ((GString *)tokens->get(2))->copy();
536     break;
537   }
538
539   if ((old = (DisplayFontParam *)fontHash->remove(param->name))) {
540     delete old;
541   }
542   fontHash->add(param->name, param);
543   return;
544
545  err2:
546   delete param;
547  err1:
548   error(-1, "Bad 'display*Font*' config file command (%s:%d)",
549         fileName->getCString(), line);
550 }
551
552 void GlobalParams::parsePSPaperSize(GList *tokens, GString *fileName,
553                                     int line) {
554   GString *tok;
555
556   if (tokens->getLength() == 2) {
557     tok = (GString *)tokens->get(1);
558     if (!setPSPaperSize(tok->getCString())) {
559       error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
560             fileName->getCString(), line);
561     }
562   } else if (tokens->getLength() == 3) {
563     tok = (GString *)tokens->get(1);
564     psPaperWidth = atoi(tok->getCString());
565     tok = (GString *)tokens->get(2);
566     psPaperHeight = atoi(tok->getCString());
567   } else {
568     error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
569           fileName->getCString(), line);
570   }
571 }
572
573 void GlobalParams::parsePSLevel(GList *tokens, GString *fileName, int line) {
574   GString *tok;
575
576   if (tokens->getLength() != 2) {
577     error(-1, "Bad 'psLevel' config file command (%s:%d)",
578           fileName->getCString(), line);
579     return;
580   }
581   tok = (GString *)tokens->get(1);
582   if (!tok->cmp("level1")) {
583     psLevel = psLevel1;
584   } else if (!tok->cmp("level1sep")) {
585     psLevel = psLevel1Sep;
586   } else if (!tok->cmp("level2")) {
587     psLevel = psLevel2;
588   } else if (!tok->cmp("level2sep")) {
589     psLevel = psLevel2Sep;
590   } else if (!tok->cmp("level3")) {
591     psLevel = psLevel3;
592   } else if (!tok->cmp("level3Sep")) {
593     psLevel = psLevel3Sep;
594   } else {
595     error(-1, "Bad 'psLevel' config file command (%s:%d)",
596           fileName->getCString(), line);
597   }
598 }
599
600 void GlobalParams::parsePSFile(GList *tokens, GString *fileName, int line) {
601   if (tokens->getLength() != 2) {
602     error(-1, "Bad 'psFile' config file command (%s:%d)",
603           fileName->getCString(), line);
604     return;
605   }
606   if (psFile) {
607     delete psFile;
608   }
609   psFile = ((GString *)tokens->get(1))->copy();
610 }
611
612 void GlobalParams::parsePSFont(GList *tokens, GString *fileName, int line) {
613   PSFontParam *param;
614
615   if (tokens->getLength() != 3) {
616     error(-1, "Bad 'psFont' config file command (%s:%d)",
617           fileName->getCString(), line);
618     return;
619   }
620   param = new PSFontParam(((GString *)tokens->get(1))->copy(), 0,
621                           ((GString *)tokens->get(2))->copy(), NULL);
622   psFonts->add(param->pdfFontName, param);
623 }
624
625 void GlobalParams::parsePSFont16(char *cmdName, GList *fontList,
626                                  GList *tokens, GString *fileName, int line) {
627   PSFontParam *param;
628   int wMode;
629   GString *tok;
630
631   if (tokens->getLength() != 5) {
632     error(-1, "Bad '%s' config file command (%s:%d)",
633           cmdName, fileName->getCString(), line);
634     return;
635   }
636   tok = (GString *)tokens->get(2);
637   if (!tok->cmp("H")) {
638     wMode = 0;
639   } else if (!tok->cmp("V")) {
640     wMode = 1;
641   } else {
642     error(-1, "Bad '%s' config file command (%s:%d)",
643           cmdName, fileName->getCString(), line);
644     return;
645   }
646   param = new PSFontParam(((GString *)tokens->get(1))->copy(),
647                           wMode,
648                           ((GString *)tokens->get(3))->copy(),
649                           ((GString *)tokens->get(4))->copy());
650   fontList->append(param);
651 }
652
653 void GlobalParams::parseTextEncoding(GList *tokens, GString *fileName,
654                                      int line) {
655   if (tokens->getLength() != 2) {
656     error(-1, "Bad 'textEncoding' config file command (%s:%d)",
657           fileName->getCString(), line);
658     return;
659   }
660   delete textEncoding;
661   textEncoding = ((GString *)tokens->get(1))->copy();
662 }
663
664 void GlobalParams::parseTextEOL(GList *tokens, GString *fileName, int line) {
665   GString *tok;
666
667   if (tokens->getLength() != 2) {
668     error(-1, "Bad 'textEOL' config file command (%s:%d)",
669           fileName->getCString(), line);
670     return;
671   }
672   tok = (GString *)tokens->get(1);
673   if (!tok->cmp("unix")) {
674     textEOL = eolUnix;
675   } else if (!tok->cmp("dos")) {
676     textEOL = eolDOS;
677   } else if (!tok->cmp("mac")) {
678     textEOL = eolMac;
679   } else {
680     error(-1, "Bad 'textEOL' config file command (%s:%d)",
681           fileName->getCString(), line);
682   }
683 }
684
685 void GlobalParams::parseFontDir(GList *tokens, GString *fileName, int line) {
686   if (tokens->getLength() != 2) {
687     error(-1, "Bad 'fontDir' config file command (%s:%d)",
688           fileName->getCString(), line);
689     return;
690   }
691   fontDirs->append(((GString *)tokens->get(1))->copy());
692 }
693
694 void GlobalParams::parseInitialZoom(GList *tokens,
695                                     GString *fileName, int line) {
696   if (tokens->getLength() != 2) {
697     error(-1, "Bad 'initialZoom' config file command (%s:%d)",
698           fileName->getCString(), line);
699     return;
700   }
701   delete initialZoom;
702   initialZoom = ((GString *)tokens->get(1))->copy();
703 }
704
705 void GlobalParams::parseFontRastControl(char *cmdName, FontRastControl *val,
706                                         GList *tokens, GString *fileName,
707                                         int line) {
708   GString *tok;
709
710   if (tokens->getLength() != 2) {
711     error(-1, "Bad '%s' config file command (%s:%d)",
712           cmdName, fileName->getCString(), line);
713     return;
714   }
715   tok = (GString *)tokens->get(1);
716   if (!setFontRastControl(val, tok->getCString())) {
717     error(-1, "Bad '%s' config file command (%s:%d)",
718           cmdName, fileName->getCString(), line);
719   }
720 }
721
722 void GlobalParams::parseCommand(char *cmdName, GString **val,
723                                 GList *tokens, GString *fileName, int line) {
724   if (tokens->getLength() != 2) {
725     error(-1, "Bad '%s' config file command (%s:%d)",
726           cmdName, fileName->getCString(), line);
727     return;
728   }
729   if (*val) {
730     delete *val;
731   }
732   *val = ((GString *)tokens->get(1))->copy();
733 }
734
735 void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
736                               GList *tokens, GString *fileName, int line) {
737   GString *tok;
738
739   if (tokens->getLength() != 2) {
740     error(-1, "Bad '%s' config file command (%s:%d)",
741           cmdName, fileName->getCString(), line);
742     return;
743   }
744   tok = (GString *)tokens->get(1);
745   if (!tok->cmp("yes")) {
746     *flag = gTrue;
747   } else if (!tok->cmp("no")) {
748     *flag = gFalse;
749   } else {
750     error(-1, "Bad '%s' config file command (%s:%d)",
751           cmdName, fileName->getCString(), line);
752   }
753 }
754
755 GlobalParams::~GlobalParams() {
756   GHashIter *iter;
757   GString *key;
758   GList *list;
759
760   freeBuiltinFontTables();
761
762   delete macRomanReverseMap;
763
764   delete nameToUnicode;
765   deleteGHash(cidToUnicodes, GString);
766   deleteGHash(residentUnicodeMaps, UnicodeMap);
767   deleteGHash(unicodeMaps, GString);
768   deleteGList(toUnicodeDirs, GString);
769   deleteGHash(displayFonts, DisplayFontParam);
770   deleteGHash(displayCIDFonts, DisplayFontParam);
771   deleteGHash(displayNamedCIDFonts, DisplayFontParam);
772   if (psFile) {
773     delete psFile;
774   }
775   deleteGHash(psFonts, PSFontParam);
776   deleteGList(psNamedFonts16, PSFontParam);
777   deleteGList(psFonts16, PSFontParam);
778   delete textEncoding;
779   deleteGList(fontDirs, GString);
780   delete initialZoom;
781   if (urlCommand) {
782     delete urlCommand;
783   }
784   if (movieCommand) {
785     delete movieCommand;
786   }
787
788   cMapDirs->startIter(&iter);
789   while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
790     deleteGList(list, GString);
791   }
792   delete cMapDirs;
793
794   delete cidToUnicodeCache;
795   delete unicodeMapCache;
796   delete cMapCache;
797 }
798
799 //------------------------------------------------------------------------
800 // accessors
801 //------------------------------------------------------------------------
802
803 CharCode GlobalParams::getMacRomanCharCode(char *charName) {
804   return macRomanReverseMap->lookup(charName);
805 }
806
807 Unicode GlobalParams::mapNameToUnicode(char *charName) {
808   return nameToUnicode->lookup(charName);
809 }
810
811 FILE *GlobalParams::getCIDToUnicodeFile(GString *collection) {
812   GString *fileName;
813
814   if (!(fileName = (GString *)cidToUnicodes->lookup(collection))) {
815     return NULL;
816   }
817   return fopen(fileName->getCString(), "r");
818 }
819
820 UnicodeMap *GlobalParams::getResidentUnicodeMap(GString *encodingName) {
821   return (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
822 }
823
824 FILE *GlobalParams::getUnicodeMapFile(GString *encodingName) {
825   GString *fileName;
826
827   if (!(fileName = (GString *)unicodeMaps->lookup(encodingName))) {
828     return NULL;
829   }
830   return fopen(fileName->getCString(), "r");
831 }
832
833 FILE *GlobalParams::findCMapFile(GString *collection, GString *cMapName) {
834   GList *list;
835   GString *dir;
836   GString *fileName;
837   FILE *f;
838   int i;
839
840   if (!(list = (GList *)cMapDirs->lookup(collection))) {
841     return NULL;
842   }
843   for (i = 0; i < list->getLength(); ++i) {
844     dir = (GString *)list->get(i);
845     fileName = appendToPath(dir->copy(), cMapName->getCString());
846     f = fopen(fileName->getCString(), "r");
847     delete fileName;
848     if (f) {
849       return f;
850     }
851   }
852   return NULL;
853 }
854
855 FILE *GlobalParams::findToUnicodeFile(GString *name) {
856   GString *dir, *fileName;
857   FILE *f;
858   int i;
859
860   for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
861     dir = (GString *)toUnicodeDirs->get(i);
862     fileName = appendToPath(dir->copy(), name->getCString());
863     f = fopen(fileName->getCString(), "r");
864     delete fileName;
865     if (f) {
866       return f;
867     }
868   }
869   return NULL;
870 }
871
872 DisplayFontParam *GlobalParams::getDisplayFont(GString *fontName) {
873   return (DisplayFontParam *)displayFonts->lookup(fontName);
874 }
875
876 DisplayFontParam *GlobalParams::getDisplayCIDFont(GString *fontName,
877                                                   GString *collection) {
878   DisplayFontParam *dfp;
879
880   if (!fontName ||
881       !(dfp = (DisplayFontParam *)displayNamedCIDFonts->lookup(fontName))) {
882     dfp = (DisplayFontParam *)displayCIDFonts->lookup(collection);
883   }
884   return dfp;
885 }
886
887 PSFontParam *GlobalParams::getPSFont(GString *fontName) {
888   return (PSFontParam *)psFonts->lookup(fontName);
889 }
890
891 PSFontParam *GlobalParams::getPSFont16(GString *fontName,
892                                        GString *collection, int wMode) {
893   PSFontParam *p;
894   int i;
895
896   p = NULL;
897   if (fontName) {
898     for (i = 0; i < psNamedFonts16->getLength(); ++i) {
899       p = (PSFontParam *)psNamedFonts16->get(i);
900       if (!p->pdfFontName->cmp(fontName) &&
901           p->wMode == wMode) {
902         break;
903       }
904       p = NULL;
905     }
906   }
907   if (!p && collection) {
908     for (i = 0; i < psFonts16->getLength(); ++i) {
909       p = (PSFontParam *)psFonts16->get(i);
910       if (!p->pdfFontName->cmp(collection) &&
911           p->wMode == wMode) {
912         break;
913       }
914       p = NULL;
915     }
916   }
917   return p;
918 }
919
920 GString *GlobalParams::findFontFile(GString *fontName,
921                                     char *ext1, char *ext2) {
922   GString *dir, *fileName;
923   FILE *f;
924   int i;
925
926   for (i = 0; i < fontDirs->getLength(); ++i) {
927     dir = (GString *)fontDirs->get(i);
928     if (ext1) {
929       fileName = appendToPath(dir->copy(), fontName->getCString());
930       fileName->append(ext1);
931       if ((f = fopen(fileName->getCString(), "r"))) {
932         fclose(f);
933         return fileName;
934       }
935       delete fileName;
936     }
937     if (ext2) {
938       fileName = appendToPath(dir->copy(), fontName->getCString());
939       fileName->append(ext2);
940       if ((f = fopen(fileName->getCString(), "r"))) {
941         fclose(f);
942         return fileName;
943       }
944       delete fileName;
945     }
946   }
947   return NULL;
948 }
949
950 CharCodeToUnicode *GlobalParams::getCIDToUnicode(GString *collection) {
951   return cidToUnicodeCache->getCIDToUnicode(collection);
952 }
953
954 UnicodeMap *GlobalParams::getUnicodeMap(GString *encodingName) {
955   UnicodeMap *map;
956
957   if ((map = getResidentUnicodeMap(encodingName))) {
958     map->incRefCnt();
959     return map;
960   }
961   return unicodeMapCache->getUnicodeMap(encodingName);
962 }
963
964 CMap *GlobalParams::getCMap(GString *collection, GString *cMapName) {
965   return cMapCache->getCMap(collection, cMapName);
966 }
967
968 UnicodeMap *GlobalParams::getTextEncoding() {
969   return getUnicodeMap(textEncoding);
970 }
971
972 //------------------------------------------------------------------------
973 // functions to set parameters
974 //------------------------------------------------------------------------
975
976 void GlobalParams::addDisplayFont(DisplayFontParam *param) {
977   DisplayFontParam *old;
978
979   if ((old = (DisplayFontParam *)displayFonts->remove(param->name))) {
980     delete old;
981   }
982   displayFonts->add(param->name, param);
983 }
984
985 void GlobalParams::setPSFile(char *file) {
986   if (psFile) {
987     delete psFile;
988   }
989   psFile = new GString(file);
990 }
991
992 GBool GlobalParams::setPSPaperSize(char *size) {
993   if (!strcmp(size, "letter")) {
994     psPaperWidth = 612;
995     psPaperHeight = 792;
996   } else if (!strcmp(size, "legal")) {
997     psPaperWidth = 612;
998     psPaperHeight = 1008;
999   } else if (!strcmp(size, "A4")) {
1000     psPaperWidth = 595;
1001     psPaperHeight = 842;
1002   } else if (!strcmp(size, "A3")) {
1003     psPaperWidth = 842;
1004     psPaperHeight = 1190;
1005   } else {
1006     return gFalse;
1007   }
1008   return gTrue;
1009 }
1010
1011 void GlobalParams::setPSPaperWidth(int width) {
1012   psPaperWidth = width;
1013 }
1014
1015 void GlobalParams::setPSPaperHeight(int height) {
1016   psPaperHeight = height;
1017 }
1018
1019 void GlobalParams::setPSDuplex(GBool duplex) {
1020   psDuplex = duplex;
1021 }
1022
1023 void GlobalParams::setPSLevel(PSLevel level) {
1024   psLevel = level;
1025 }
1026
1027 void GlobalParams::setPSEmbedType1(GBool embed) {
1028   psEmbedType1 = embed;
1029 }
1030
1031 void GlobalParams::setPSEmbedTrueType(GBool embed) {
1032   psEmbedTrueType = embed;
1033 }
1034
1035 void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1036   psEmbedCIDPostScript = embed;
1037 }
1038
1039 void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1040   psEmbedCIDTrueType = embed;
1041 }
1042
1043 void GlobalParams::setPSOPI(GBool opi) {
1044   psOPI = opi;
1045 }
1046
1047 void GlobalParams::setPSASCIIHex(GBool hex) {
1048   psASCIIHex = hex;
1049 }
1050
1051 void GlobalParams::setTextEncoding(char *encodingName) {
1052   delete textEncoding;
1053   textEncoding = new GString(encodingName);
1054 }
1055
1056 GBool GlobalParams::setTextEOL(char *s) {
1057   if (!strcmp(s, "unix")) {
1058     textEOL = eolUnix;
1059   } else if (!strcmp(s, "dos")) {
1060     textEOL = eolDOS;
1061   } else if (!strcmp(s, "mac")) {
1062     textEOL = eolMac;
1063   } else {
1064     return gFalse;
1065   }
1066   return gTrue;
1067 }
1068
1069 void GlobalParams::setTextKeepTinyChars(GBool keep) {
1070   textKeepTinyChars = keep;
1071 }
1072
1073 void GlobalParams::setInitialZoom(char *s) {
1074   delete initialZoom;
1075   initialZoom = new GString(s);
1076 }
1077
1078 GBool GlobalParams::setT1libControl(char *s) {
1079   return setFontRastControl(&t1libControl, s);
1080 }
1081
1082 GBool GlobalParams::setFreeTypeControl(char *s) {
1083   return setFontRastControl(&freetypeControl, s);
1084 }
1085
1086 GBool GlobalParams::setFontRastControl(FontRastControl *val, char *s) {
1087   if (!strcmp(s, "none")) {
1088     *val = fontRastNone;
1089   } else if (!strcmp(s, "plain")) {
1090     *val = fontRastPlain;
1091   } else if (!strcmp(s, "low")) {
1092     *val = fontRastAALow;
1093   } else if (!strcmp(s, "high")) {
1094     *val = fontRastAAHigh;
1095   } else {
1096     return gFalse;
1097   }
1098   return gTrue;
1099 }
1100
1101 void GlobalParams::setMapNumericCharNames(GBool map) {
1102   mapNumericCharNames = map;
1103 }
1104
1105 void GlobalParams::setPrintCommands(GBool printCommandsA) {
1106   printCommands = printCommandsA;
1107 }
1108
1109 void GlobalParams::setErrQuiet(GBool errQuietA) {
1110   errQuiet = errQuietA;
1111 }