source: trunk/poppler/mypoppler/poppler/GlobalParams.cc @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 49.5 KB
Line 
1//========================================================================
2//
3// GlobalParams.cc
4//
5// Copyright 2001-2003 Glyph & Cog, LLC
6//
7//========================================================================
8
9#include <config.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#ifdef ENABLE_PLUGINS
19#  ifndef WIN32
20#    include <dlfcn.h>
21#  endif
22#endif
23#ifdef WIN32
24#  include <shlobj.h>
25#endif
26#include <fontconfig/fontconfig.h>
27#include "goo/gmem.h"
28#include "goo/GooString.h"
29#include "goo/GooList.h"
30#include "goo/GooHash.h"
31#include "goo/gfile.h"
32#include "Error.h"
33#include "NameToCharCode.h"
34#include "CharCodeToUnicode.h"
35#include "UnicodeMap.h"
36#include "CMap.h"
37#include "BuiltinFontTables.h"
38#include "FontEncodingTables.h"
39#ifdef ENABLE_PLUGINS
40#  include "XpdfPluginAPI.h"
41#endif
42#include "GlobalParams.h"
43#include "GfxFont.h"
44
45#if MULTITHREADED
46#  define lockGlobalParams            gLockMutex(&mutex)
47#  define lockUnicodeMapCache         gLockMutex(&unicodeMapCacheMutex)
48#  define lockCMapCache               gLockMutex(&cMapCacheMutex)
49#  define unlockGlobalParams          gUnlockMutex(&mutex)
50#  define unlockUnicodeMapCache       gUnlockMutex(&unicodeMapCacheMutex)
51#  define unlockCMapCache             gUnlockMutex(&cMapCacheMutex)
52#else
53#  define lockGlobalParams
54#  define lockUnicodeMapCache
55#  define lockCMapCache
56#  define unlockGlobalParams
57#  define unlockUnicodeMapCache
58#  define unlockCMapCache
59#endif
60
61#ifndef FC_WEIGHT_BOOK
62#define FC_WEIGHT_BOOK 75
63#endif
64
65#include "NameToUnicodeTable.h"
66#include "UnicodeMapTables.h"
67#include "UTF8.h"
68
69#ifdef ENABLE_PLUGINS
70#  ifdef WIN32
71extern XpdfPluginVecTable xpdfPluginVecTable;
72#  endif
73#endif
74
75//------------------------------------------------------------------------
76
77#define cidToUnicodeCacheSize     4
78#define unicodeToUnicodeCacheSize 4
79
80//------------------------------------------------------------------------
81
82GlobalParams *globalParams = NULL;
83
84//------------------------------------------------------------------------
85// DisplayFontParam
86//------------------------------------------------------------------------
87
88DisplayFontParam::DisplayFontParam(GooString *nameA,
89                                   DisplayFontParamKind kindA) {
90  name = nameA;
91  kind = kindA;
92  switch (kind) {
93  case displayFontT1:
94    t1.fileName = NULL;
95    break;
96  case displayFontTT:
97    tt.fileName = NULL;
98    break;
99  }
100}
101
102DisplayFontParam::~DisplayFontParam() {
103  delete name;
104  switch (kind) {
105  case displayFontT1:
106    if (t1.fileName) {
107      delete t1.fileName;
108    }
109    break;
110  case displayFontTT:
111    if (tt.fileName) {
112      delete tt.fileName;
113    }
114    break;
115  }
116}
117
118//------------------------------------------------------------------------
119// PSFontParam
120//------------------------------------------------------------------------
121
122PSFontParam::PSFontParam(GooString *pdfFontNameA, int wModeA,
123                         GooString *psFontNameA, GooString *encodingA) {
124  pdfFontName = pdfFontNameA;
125  wMode = wModeA;
126  psFontName = psFontNameA;
127  encoding = encodingA;
128}
129
130PSFontParam::~PSFontParam() {
131  delete pdfFontName;
132  delete psFontName;
133  if (encoding) {
134    delete encoding;
135  }
136}
137
138#ifdef ENABLE_PLUGINS
139//------------------------------------------------------------------------
140// Plugin
141//------------------------------------------------------------------------
142
143class Plugin {
144public:
145
146  static Plugin *load(char *type, char *name);
147  ~Plugin();
148
149private:
150
151#ifdef WIN32
152  Plugin(HMODULE libA);
153  HMODULE lib;
154#else
155  Plugin(void *dlA);
156  void *dl;
157#endif
158};
159
160Plugin *Plugin::load(char *type, char *name) {
161  GooString *path;
162  Plugin *plugin;
163  XpdfPluginVecTable *vt;
164  XpdfBool (*xpdfInitPlugin)(void);
165#ifdef WIN32
166  HMODULE libA;
167#else
168  void *dlA;
169#endif
170
171  path = globalParams->getBaseDir();
172  appendToPath(path, "plugins");
173  appendToPath(path, type);
174  appendToPath(path, name);
175
176#ifdef WIN32
177  path->append(".dll");
178  if (!(libA = LoadLibrary(path->getCString()))) {
179    error(-1, "Failed to load plugin '%s'",
180          path->getCString());
181    goto err1;
182  }
183  if (!(vt = (XpdfPluginVecTable *)
184                 GetProcAddress(libA, "xpdfPluginVecTable"))) {
185    error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
186          path->getCString());
187    goto err2;
188  }
189#else
190  //~ need to deal with other extensions here
191  path->append(".so");
192  if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
193    error(-1, "Failed to load plugin '%s': %s",
194          path->getCString(), dlerror());
195    goto err1;
196  }
197  if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
198    error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
199          path->getCString());
200    goto err2;
201  }
202#endif
203
204  if (vt->version != xpdfPluginVecTable.version) {
205    error(-1, "Plugin '%s' is wrong version", path->getCString());
206    goto err2;
207  }
208  memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
209
210#ifdef WIN32
211  if (!(xpdfInitPlugin = (XpdfBool (*)(void))
212                             GetProcAddress(libA, "xpdfInitPlugin"))) {
213    error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
214          path->getCString());
215    goto err2;
216  }
217#else
218  if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
219    error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
220          path->getCString());
221    goto err2;
222  }
223#endif
224
225  if (!(*xpdfInitPlugin)()) {
226    error(-1, "Initialization of plugin '%s' failed",
227          path->getCString());
228    goto err2;
229  }
230
231#ifdef WIN32
232  plugin = new Plugin(libA);
233#else
234  plugin = new Plugin(dlA);
235#endif
236
237  delete path;
238  return plugin;
239
240 err2:
241#ifdef WIN32
242  FreeLibrary(libA);
243#else
244  dlclose(dlA);
245#endif
246 err1:
247  delete path;
248  return NULL;
249}
250
251#ifdef WIN32
252Plugin::Plugin(HMODULE libA) {
253  lib = libA;
254}
255#else
256Plugin::Plugin(void *dlA) {
257  dl = dlA;
258}
259#endif
260
261Plugin::~Plugin() {
262  void (*xpdfFreePlugin)(void);
263
264#ifdef WIN32
265  if ((xpdfFreePlugin = (void (*)(void))
266                            GetProcAddress(lib, "xpdfFreePlugin"))) {
267    (*xpdfFreePlugin)();
268  }
269  FreeLibrary(lib);
270#else
271  if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
272    (*xpdfFreePlugin)();
273  }
274  dlclose(dl);
275#endif
276}
277
278#endif // ENABLE_PLUGINS
279
280//------------------------------------------------------------------------
281// parsing
282//------------------------------------------------------------------------
283
284GlobalParams::GlobalParams(char *cfgFileName) {
285  UnicodeMap *map;
286  GooString *fileName;
287  FILE *f;
288  int i;
289 
290  FcInit();
291  FCcfg = FcConfigGetCurrent();
292
293#if MULTITHREADED
294  gInitMutex(&mutex);
295  gInitMutex(&unicodeMapCacheMutex);
296  gInitMutex(&cMapCacheMutex);
297#endif
298
299  initBuiltinFontTables();
300
301  // scan the encoding in reverse because we want the lowest-numbered
302  // index for each char name ('space' is encoded twice)
303  macRomanReverseMap = new NameToCharCode();
304  for (i = 255; i >= 0; --i) {
305    if (macRomanEncoding[i]) {
306      macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
307    }
308  }
309
310#ifdef WIN32
311  // baseDir will be set by a call to setBaseDir
312  baseDir = new GooString();
313#else
314  baseDir = appendToPath(getHomeDir(), ".xpdf");
315#endif
316  nameToUnicode = new NameToCharCode();
317  cidToUnicodes = new GooHash(gTrue);
318  unicodeToUnicodes = new GooHash(gTrue);
319  residentUnicodeMaps = new GooHash();
320  unicodeMaps = new GooHash(gTrue);
321  cMapDirs = new GooHash(gTrue);
322  toUnicodeDirs = new GooList();
323  displayFonts = new GooHash();
324  psPaperWidth = -1;
325  psPaperHeight = -1;
326  psImageableLLX = psImageableLLY = 0;
327  psImageableURX = psPaperWidth;
328  psImageableURY = psPaperHeight;
329  psCrop = gTrue;
330  psExpandSmaller = gFalse;
331  psShrinkLarger = gTrue;
332  psCenter = gTrue;
333  psDuplex = gFalse;
334  psLevel = psLevel2;
335  psFile = NULL;
336  psFonts = new GooHash();
337  psNamedFonts16 = new GooList();
338  psFonts16 = new GooList();
339  psEmbedType1 = gTrue;
340  psEmbedTrueType = gTrue;
341  psEmbedCIDPostScript = gTrue;
342  psEmbedCIDTrueType = gTrue;
343  psOPI = gFalse;
344  psASCIIHex = gFalse;
345  textEncoding = new GooString("UTF-8");
346#if defined(WIN32)
347  textEOL = eolDOS;
348#elif defined(MACOS)
349  textEOL = eolMac;
350#else
351  textEOL = eolUnix;
352#endif
353  textPageBreaks = gTrue;
354  textKeepTinyChars = gFalse;
355  fontDirs = new GooList();
356  initialZoom = new GooString("125");
357  continuousView = gFalse;
358  enableT1lib = gTrue;
359  enableFreeType = gTrue;
360  antialias = gTrue;
361  urlCommand = NULL;
362  movieCommand = NULL;
363  mapNumericCharNames = gTrue;
364  printCommands = gFalse;
365  profileCommands = gFalse;
366  errQuiet = gFalse;
367
368  cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
369  unicodeToUnicodeCache =
370      new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
371  unicodeMapCache = new UnicodeMapCache();
372  cMapCache = new CMapCache();
373
374#ifdef ENABLE_PLUGINS
375  plugins = new GooList();
376  securityHandlers = new GooList();
377#endif
378
379  // set up the initial nameToUnicode table
380  for (i = 0; nameToUnicodeTab[i].name; ++i) {
381    nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
382  }
383
384  // set up the residentUnicodeMaps table
385  map = new UnicodeMap("Latin1", gFalse,
386                       latin1UnicodeMapRanges, latin1UnicodeMapLen);
387  residentUnicodeMaps->add(map->getEncodingName(), map);
388  map = new UnicodeMap("ASCII7", gFalse,
389                       ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
390  residentUnicodeMaps->add(map->getEncodingName(), map);
391  map = new UnicodeMap("Symbol", gFalse,
392                       symbolUnicodeMapRanges, symbolUnicodeMapLen);
393  residentUnicodeMaps->add(map->getEncodingName(), map);
394  map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
395                       zapfDingbatsUnicodeMapLen);
396  residentUnicodeMaps->add(map->getEncodingName(), map);
397  map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
398  residentUnicodeMaps->add(map->getEncodingName(), map);
399  map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
400  residentUnicodeMaps->add(map->getEncodingName(), map);
401
402  // look for a user config file, then a system-wide config file
403  f = NULL;
404  fileName = NULL;
405  if (cfgFileName && cfgFileName[0]) {
406    fileName = new GooString(cfgFileName);
407    if (!(f = fopen(fileName->getCString(), "r"))) {
408      delete fileName;
409    }
410  }
411  if (!f) {
412    fileName = appendToPath(getHomeDir(), xpdfUserConfigFile);
413    if (!(f = fopen(fileName->getCString(), "r"))) {
414      delete fileName;
415    }
416  }
417  if (!f) {
418#if defined(WIN32) && !defined(__CYGWIN32__)
419    char buf[512];
420    i = GetModuleFileName(NULL, buf, sizeof(buf));
421    if (i <= 0 || i >= sizeof(buf)) {
422      // error or path too long for buffer - just use the current dir
423      buf[0] = '\0';
424    }
425    fileName = grabPath(buf);
426    appendToPath(fileName, xpdfSysConfigFile);
427#else
428    fileName = new GooString(xpdfSysConfigFile);
429#endif
430    if (!(f = fopen(fileName->getCString(), "r"))) {
431      delete fileName;
432    }
433  }
434  if (f) {
435    parseFile(fileName, f);
436    delete fileName;
437    fclose(f);
438  }
439}
440
441void GlobalParams::parseFile(GooString *fileName, FILE *f) {
442  int line;
443  GooList *tokens;
444  GooString *cmd, *incFile;
445  char *p1, *p2;
446  char buf[512];
447  FILE *f2;
448
449  line = 1;
450  while (getLine(buf, sizeof(buf) - 1, f)) {
451
452    // break the line into tokens
453    tokens = new GooList();
454    p1 = buf;
455    while (*p1) {
456      for (; *p1 && isspace(*p1); ++p1) ;
457      if (!*p1) {
458        break;
459      }
460      if (*p1 == '"' || *p1 == '\'') {
461        for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
462        ++p1;
463      } else {
464        for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
465      }
466      tokens->append(new GooString(p1, p2 - p1));
467      p1 = *p2 ? p2 + 1 : p2;
468    }
469
470    if (tokens->getLength() > 0 &&
471        ((GooString *)tokens->get(0))->getChar(0) != '#') {
472      cmd = (GooString *)tokens->get(0);
473      if (!cmd->cmp("include")) {
474        if (tokens->getLength() == 2) {
475          incFile = (GooString *)tokens->get(1);
476          if ((f2 = fopen(incFile->getCString(), "r"))) {
477            parseFile(incFile, f2);
478            fclose(f2);
479          } else {
480            error(-1, "Couldn't find included config file: '%s' (%s:%d)",
481                  incFile->getCString(), fileName->getCString(), line);
482          }
483        } else {
484          error(-1, "Bad 'include' config file command (%s:%d)",
485                fileName->getCString(), line);
486        }
487      } else if (!cmd->cmp("nameToUnicode")) {
488        parseNameToUnicode(tokens, fileName, line);
489      } else if (!cmd->cmp("cidToUnicode")) {
490        parseCIDToUnicode(tokens, fileName, line);
491      } else if (!cmd->cmp("unicodeToUnicode")) {
492        parseUnicodeToUnicode(tokens, fileName, line);
493      } else if (!cmd->cmp("unicodeMap")) {
494        parseUnicodeMap(tokens, fileName, line);
495      } else if (!cmd->cmp("cMapDir")) {
496        parseCMapDir(tokens, fileName, line);
497      } else if (!cmd->cmp("toUnicodeDir")) {
498        parseToUnicodeDir(tokens, fileName, line);
499      } else if (!cmd->cmp("displayFontT1")) {
500        // deprecated
501      } else if (!cmd->cmp("displayFontTT")) {
502        // deprecated
503      } else if (!cmd->cmp("displayNamedCIDFontT1")) {
504        // deprecated
505      } else if (!cmd->cmp("displayCIDFontT1")) {
506        // deprecated
507      } else if (!cmd->cmp("displayNamedCIDFontTT")) {
508        // deprecated
509      } else if (!cmd->cmp("displayCIDFontTT")) {
510        // deprecated
511      } else if (!cmd->cmp("psFile")) {
512        parsePSFile(tokens, fileName, line);
513      } else if (!cmd->cmp("psFont")) {
514        parsePSFont(tokens, fileName, line);
515      } else if (!cmd->cmp("psNamedFont16")) {
516        parsePSFont16("psNamedFont16", psNamedFonts16,
517                      tokens, fileName, line);
518      } else if (!cmd->cmp("psFont16")) {
519        parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
520      } else if (!cmd->cmp("psPaperSize")) {
521        parsePSPaperSize(tokens, fileName, line);
522      } else if (!cmd->cmp("psImageableArea")) {
523        parsePSImageableArea(tokens, fileName, line);
524      } else if (!cmd->cmp("psCrop")) {
525        parseYesNo("psCrop", &psCrop, tokens, fileName, line);
526      } else if (!cmd->cmp("psExpandSmaller")) {
527        parseYesNo("psExpandSmaller", &psExpandSmaller,
528                   tokens, fileName, line);
529      } else if (!cmd->cmp("psShrinkLarger")) {
530        parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
531      } else if (!cmd->cmp("psCenter")) {
532        parseYesNo("psCenter", &psCenter, tokens, fileName, line);
533      } else if (!cmd->cmp("psDuplex")) {
534        parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
535      } else if (!cmd->cmp("psLevel")) {
536        parsePSLevel(tokens, fileName, line);
537      } else if (!cmd->cmp("psEmbedType1Fonts")) {
538        parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
539      } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
540        parseYesNo("psEmbedTrueType", &psEmbedTrueType,
541                   tokens, fileName, line);
542      } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
543        parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
544                   tokens, fileName, line);
545      } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
546        parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
547                   tokens, fileName, line);
548      } else if (!cmd->cmp("psOPI")) {
549        parseYesNo("psOPI", &psOPI, tokens, fileName, line);
550      } else if (!cmd->cmp("psASCIIHex")) {
551        parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
552      } else if (!cmd->cmp("textEncoding")) {
553        parseTextEncoding(tokens, fileName, line);
554      } else if (!cmd->cmp("textEOL")) {
555        parseTextEOL(tokens, fileName, line);
556      } else if (!cmd->cmp("textPageBreaks")) {
557        parseYesNo("textPageBreaks", &textPageBreaks,
558                   tokens, fileName, line);
559      } else if (!cmd->cmp("textKeepTinyChars")) {
560        parseYesNo("textKeepTinyChars", &textKeepTinyChars,
561                   tokens, fileName, line);
562      } else if (!cmd->cmp("fontDir")) {
563        parseFontDir(tokens, fileName, line);
564      } else if (!cmd->cmp("initialZoom")) {
565        parseInitialZoom(tokens, fileName, line);
566      } else if (!cmd->cmp("continuousView")) {
567        parseYesNo("continuousView", &continuousView, tokens, fileName, line);
568      } else if (!cmd->cmp("enableT1lib")) {
569        parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
570      } else if (!cmd->cmp("enableFreeType")) {
571        parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
572      } else if (!cmd->cmp("antialias")) {
573        parseYesNo("antialias", &antialias, tokens, fileName, line);
574      } else if (!cmd->cmp("urlCommand")) {
575        parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
576      } else if (!cmd->cmp("movieCommand")) {
577        parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
578      } else if (!cmd->cmp("mapNumericCharNames")) {
579        parseYesNo("mapNumericCharNames", &mapNumericCharNames,
580                   tokens, fileName, line);
581      } else if (!cmd->cmp("printCommands")) {
582        parseYesNo("printCommands", &printCommands, tokens, fileName, line);
583      } else if (!cmd->cmp("errQuiet")) {
584        parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
585      } else {
586        error(-1, "Unknown config file command '%s' (%s:%d)",
587              cmd->getCString(), fileName->getCString(), line);
588        if (!cmd->cmp("displayFontX") ||
589            !cmd->cmp("displayNamedCIDFontX") ||
590            !cmd->cmp("displayCIDFontX")) {
591          error(-1, "-- Xpdf no longer supports X fonts");
592        } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
593          error(-1, "-- The t1libControl and freetypeControl options have been replaced");
594          error(-1, "   by the enableT1lib, enableFreeType, and antialias options");
595        } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
596          error(-1, "-- the config file format has changed since Xpdf 0.9x");
597        }
598      }
599    }
600
601    deleteGooList(tokens, GooString);
602    ++line;
603  }
604}
605
606void GlobalParams::parseNameToUnicode(GooList *tokens, GooString *fileName,
607                                         int line) {
608  GooString *name;
609  char *tok1, *tok2;
610  FILE *f;
611  char buf[256];
612  int line2;
613  Unicode u;
614
615  if (tokens->getLength() != 2) {
616    error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
617          fileName->getCString(), line);
618    return;
619  }
620  name = (GooString *)tokens->get(1);
621  if (!(f = fopen(name->getCString(), "r"))) {
622    error(-1, "Couldn't open 'nameToUnicode' file '%s'",
623          name->getCString());
624    return;
625  }
626  line2 = 1;
627  while (getLine(buf, sizeof(buf), f)) {
628    tok1 = strtok(buf, " \t\r\n");
629    tok2 = strtok(NULL, " \t\r\n");
630    if (tok1 && tok2) {
631      sscanf(tok1, "%x", &u);
632      nameToUnicode->add(tok2, u);
633    } else {
634      error(-1, "Bad line in 'nameToUnicode' file (%s:%d)",
635            name->getCString(), line2);
636    }
637    ++line2;
638  }
639  fclose(f);
640}
641
642void GlobalParams::parseCIDToUnicode(GooList *tokens, GooString *fileName,
643                                     int line) {
644  GooString *collection, *name, *old;
645
646  if (tokens->getLength() != 3) {
647    error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
648          fileName->getCString(), line);
649    return;
650  }
651  collection = (GooString *)tokens->get(1);
652  name = (GooString *)tokens->get(2);
653  if ((old = (GooString *)cidToUnicodes->remove(collection))) {
654    delete old;
655  }
656  cidToUnicodes->add(collection->copy(), name->copy());
657}
658
659void GlobalParams::parseUnicodeToUnicode(GooList *tokens, GooString *fileName,
660                                         int line) {
661  GooString *font, *file, *old;
662
663  if (tokens->getLength() != 3) {
664    error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
665          fileName->getCString(), line);
666    return;
667  }
668  font = (GooString *)tokens->get(1);
669  file = (GooString *)tokens->get(2);
670  if ((old = (GooString *)unicodeToUnicodes->remove(font))) {
671    delete old;
672  }
673  unicodeToUnicodes->add(font->copy(), file->copy());
674}
675
676void GlobalParams::parseUnicodeMap(GooList *tokens, GooString *fileName,
677                                   int line) {
678  GooString *encodingName, *name, *old;
679
680  if (tokens->getLength() != 3) {
681    error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
682          fileName->getCString(), line);
683    return;
684  }
685  encodingName = (GooString *)tokens->get(1);
686  name = (GooString *)tokens->get(2);
687  if ((old = (GooString *)unicodeMaps->remove(encodingName))) {
688    delete old;
689  }
690  unicodeMaps->add(encodingName->copy(), name->copy());
691}
692
693void GlobalParams::parseCMapDir(GooList *tokens, GooString *fileName, int line) {
694  GooString *collection, *dir;
695  GooList *list;
696
697  if (tokens->getLength() != 3) {
698    error(-1, "Bad 'cMapDir' config file command (%s:%d)",
699          fileName->getCString(), line);
700    return;
701  }
702  collection = (GooString *)tokens->get(1);
703  dir = (GooString *)tokens->get(2);
704  if (!(list = (GooList *)cMapDirs->lookup(collection))) {
705    list = new GooList();
706    cMapDirs->add(collection->copy(), list);
707  }
708  list->append(dir->copy());
709}
710
711void GlobalParams::parseToUnicodeDir(GooList *tokens, GooString *fileName,
712                                     int line) {
713  if (tokens->getLength() != 2) {
714    error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
715          fileName->getCString(), line);
716    return;
717  }
718  toUnicodeDirs->append(((GooString *)tokens->get(1))->copy());
719}
720
721void GlobalParams::parsePSPaperSize(GooList *tokens, GooString *fileName,
722                                    int line) {
723  GooString *tok;
724
725  if (tokens->getLength() == 2) {
726    tok = (GooString *)tokens->get(1);
727    if (!setPSPaperSize(tok->getCString())) {
728      error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
729            fileName->getCString(), line);
730    }
731  } else if (tokens->getLength() == 3) {
732    tok = (GooString *)tokens->get(1);
733    psPaperWidth = atoi(tok->getCString());
734    tok = (GooString *)tokens->get(2);
735    psPaperHeight = atoi(tok->getCString());
736    psImageableLLX = psImageableLLY = 0;
737    psImageableURX = psPaperWidth;
738    psImageableURY = psPaperHeight;
739  } else {
740    error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
741          fileName->getCString(), line);
742  }
743}
744
745void GlobalParams::parsePSImageableArea(GooList *tokens, GooString *fileName,
746                                        int line) {
747  if (tokens->getLength() != 5) {
748    error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
749          fileName->getCString(), line);
750    return;
751  }
752  psImageableLLX = atoi(((GooString *)tokens->get(1))->getCString());
753  psImageableLLY = atoi(((GooString *)tokens->get(2))->getCString());
754  psImageableURX = atoi(((GooString *)tokens->get(3))->getCString());
755  psImageableURY = atoi(((GooString *)tokens->get(4))->getCString());
756}
757
758void GlobalParams::parsePSLevel(GooList *tokens, GooString *fileName, int line) {
759  GooString *tok;
760
761  if (tokens->getLength() != 2) {
762    error(-1, "Bad 'psLevel' config file command (%s:%d)",
763          fileName->getCString(), line);
764    return;
765  }
766  tok = (GooString *)tokens->get(1);
767  if (!tok->cmp("level1")) {
768    psLevel = psLevel1;
769  } else if (!tok->cmp("level1sep")) {
770    psLevel = psLevel1Sep;
771  } else if (!tok->cmp("level2")) {
772    psLevel = psLevel2;
773  } else if (!tok->cmp("level2sep")) {
774    psLevel = psLevel2Sep;
775  } else if (!tok->cmp("level3")) {
776    psLevel = psLevel3;
777  } else if (!tok->cmp("level3Sep")) {
778    psLevel = psLevel3Sep;
779  } else {
780    error(-1, "Bad 'psLevel' config file command (%s:%d)",
781          fileName->getCString(), line);
782  }
783}
784
785void GlobalParams::parsePSFile(GooList *tokens, GooString *fileName, int line) {
786  if (tokens->getLength() != 2) {
787    error(-1, "Bad 'psFile' config file command (%s:%d)",
788          fileName->getCString(), line);
789    return;
790  }
791  if (psFile) {
792    delete psFile;
793  }
794  psFile = ((GooString *)tokens->get(1))->copy();
795}
796
797void GlobalParams::parsePSFont(GooList *tokens, GooString *fileName, int line) {
798  PSFontParam *param;
799
800  if (tokens->getLength() != 3) {
801    error(-1, "Bad 'psFont' config file command (%s:%d)",
802          fileName->getCString(), line);
803    return;
804  }
805  param = new PSFontParam(((GooString *)tokens->get(1))->copy(), 0,
806                          ((GooString *)tokens->get(2))->copy(), NULL);
807  psFonts->add(param->pdfFontName, param);
808}
809
810void GlobalParams::parsePSFont16(char *cmdName, GooList *fontList,
811                                 GooList *tokens, GooString *fileName, int line) {
812  PSFontParam *param;
813  int wMode;
814  GooString *tok;
815
816  if (tokens->getLength() != 5) {
817    error(-1, "Bad '%s' config file command (%s:%d)",
818          cmdName, fileName->getCString(), line);
819    return;
820  }
821  tok = (GooString *)tokens->get(2);
822  if (!tok->cmp("H")) {
823    wMode = 0;
824  } else if (!tok->cmp("V")) {
825    wMode = 1;
826  } else {
827    error(-1, "Bad '%s' config file command (%s:%d)",
828          cmdName, fileName->getCString(), line);
829    return;
830  }
831  param = new PSFontParam(((GooString *)tokens->get(1))->copy(),
832                          wMode,
833                          ((GooString *)tokens->get(3))->copy(),
834                          ((GooString *)tokens->get(4))->copy());
835  fontList->append(param);
836}
837
838void GlobalParams::parseTextEncoding(GooList *tokens, GooString *fileName,
839                                     int line) {
840  if (tokens->getLength() != 2) {
841    error(-1, "Bad 'textEncoding' config file command (%s:%d)",
842          fileName->getCString(), line);
843    return;
844  }
845  delete textEncoding;
846  textEncoding = ((GooString *)tokens->get(1))->copy();
847}
848
849void GlobalParams::parseTextEOL(GooList *tokens, GooString *fileName, int line) {
850  GooString *tok;
851
852  if (tokens->getLength() != 2) {
853    error(-1, "Bad 'textEOL' config file command (%s:%d)",
854          fileName->getCString(), line);
855    return;
856  }
857  tok = (GooString *)tokens->get(1);
858  if (!tok->cmp("unix")) {
859    textEOL = eolUnix;
860  } else if (!tok->cmp("dos")) {
861    textEOL = eolDOS;
862  } else if (!tok->cmp("mac")) {
863    textEOL = eolMac;
864  } else {
865    error(-1, "Bad 'textEOL' config file command (%s:%d)",
866          fileName->getCString(), line);
867  }
868}
869
870void GlobalParams::parseFontDir(GooList *tokens, GooString *fileName, int line) {
871  if (tokens->getLength() != 2) {
872    error(-1, "Bad 'fontDir' config file command (%s:%d)",
873          fileName->getCString(), line);
874    return;
875  }
876  fontDirs->append(((GooString *)tokens->get(1))->copy());
877}
878
879void GlobalParams::parseInitialZoom(GooList *tokens,
880                                    GooString *fileName, int line) {
881  if (tokens->getLength() != 2) {
882    error(-1, "Bad 'initialZoom' config file command (%s:%d)",
883          fileName->getCString(), line);
884    return;
885  }
886  delete initialZoom;
887  initialZoom = ((GooString *)tokens->get(1))->copy();
888}
889
890void GlobalParams::parseCommand(char *cmdName, GooString **val,
891                                GooList *tokens, GooString *fileName, int line) {
892  if (tokens->getLength() != 2) {
893    error(-1, "Bad '%s' config file command (%s:%d)",
894          cmdName, fileName->getCString(), line);
895    return;
896  }
897  if (*val) {
898    delete *val;
899  }
900  *val = ((GooString *)tokens->get(1))->copy();
901}
902
903void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
904                              GooList *tokens, GooString *fileName, int line) {
905  GooString *tok;
906
907  if (tokens->getLength() != 2) {
908    error(-1, "Bad '%s' config file command (%s:%d)",
909          cmdName, fileName->getCString(), line);
910    return;
911  }
912  tok = (GooString *)tokens->get(1);
913  if (!parseYesNo2(tok->getCString(), flag)) {
914    error(-1, "Bad '%s' config file command (%s:%d)",
915          cmdName, fileName->getCString(), line);
916  }
917}
918
919GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
920  if (!strcmp(token, "yes")) {
921    *flag = gTrue;
922  } else if (!strcmp(token, "no")) {
923    *flag = gFalse;
924  } else {
925    return gFalse;
926  }
927  return gTrue;
928}
929
930GlobalParams::~GlobalParams() {
931  GooHashIter *iter;
932  GooString *key;
933  GooList *list;
934
935  freeBuiltinFontTables();
936
937  delete macRomanReverseMap;
938
939  delete baseDir;
940  delete nameToUnicode;
941  deleteGooHash(cidToUnicodes, GooString);
942  deleteGooHash(unicodeToUnicodes, GooString);
943  deleteGooHash(residentUnicodeMaps, UnicodeMap);
944  deleteGooHash(unicodeMaps, GooString);
945  deleteGooList(toUnicodeDirs, GooString);
946  deleteGooHash(displayFonts, DisplayFontParam);
947  if (psFile) {
948    delete psFile;
949  }
950  deleteGooHash(psFonts, PSFontParam);
951  deleteGooList(psNamedFonts16, PSFontParam);
952  deleteGooList(psFonts16, PSFontParam);
953  delete textEncoding;
954  deleteGooList(fontDirs, GooString);
955  delete initialZoom;
956  if (urlCommand) {
957    delete urlCommand;
958  }
959  if (movieCommand) {
960    delete movieCommand;
961  }
962
963  cMapDirs->startIter(&iter);
964  while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
965    deleteGooList(list, GooString);
966  }
967  delete cMapDirs;
968
969  delete cidToUnicodeCache;
970  delete unicodeToUnicodeCache;
971  delete unicodeMapCache;
972  delete cMapCache;
973
974#ifdef ENABLE_PLUGINS
975  delete securityHandlers;
976  deleteGooList(plugins, Plugin);
977#endif
978
979#if MULTITHREADED
980  gDestroyMutex(&mutex);
981  gDestroyMutex(&unicodeMapCacheMutex);
982  gDestroyMutex(&cMapCacheMutex);
983#endif
984}
985
986//------------------------------------------------------------------------
987
988void GlobalParams::setBaseDir(char *dir) {
989  delete baseDir;
990  baseDir = new GooString(dir);
991}
992
993//------------------------------------------------------------------------
994// accessors
995//------------------------------------------------------------------------
996
997CharCode GlobalParams::getMacRomanCharCode(char *charName) {
998  // no need to lock - macRomanReverseMap is constant
999  return macRomanReverseMap->lookup(charName);
1000}
1001
1002GooString *GlobalParams::getBaseDir() {
1003  GooString *s;
1004
1005  lockGlobalParams;
1006  s = baseDir->copy();
1007  unlockGlobalParams;
1008  return s;
1009}
1010
1011Unicode GlobalParams::mapNameToUnicode(char *charName) {
1012  // no need to lock - nameToUnicode is constant
1013  return nameToUnicode->lookup(charName);
1014}
1015
1016UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) {
1017  UnicodeMap *map;
1018
1019  lockGlobalParams;
1020  map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1021  unlockGlobalParams;
1022  if (map) {
1023    map->incRefCnt();
1024  }
1025  return map;
1026}
1027
1028FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) {
1029  GooString *fileName;
1030  FILE *f;
1031
1032  lockGlobalParams;
1033  if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) {
1034    f = fopen(fileName->getCString(), "r");
1035  } else {
1036    f = NULL;
1037  }
1038  unlockGlobalParams;
1039  return f;
1040}
1041
1042FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) {
1043  GooList *list;
1044  GooString *dir;
1045  GooString *fileName;
1046  FILE *f;
1047  int i;
1048
1049  lockGlobalParams;
1050  if (!(list = (GooList *)cMapDirs->lookup(collection))) {
1051    unlockGlobalParams;
1052    return NULL;
1053  }
1054  for (i = 0; i < list->getLength(); ++i) {
1055    dir = (GooString *)list->get(i);
1056    fileName = appendToPath(dir->copy(), cMapName->getCString());
1057    f = fopen(fileName->getCString(), "r");
1058    delete fileName;
1059    if (f) {
1060      unlockGlobalParams;
1061      return f;
1062    }
1063  }
1064  unlockGlobalParams;
1065  return NULL;
1066}
1067
1068FILE *GlobalParams::findToUnicodeFile(GooString *name) {
1069  GooString *dir, *fileName;
1070  FILE *f;
1071  int i;
1072
1073  lockGlobalParams;
1074  for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1075    dir = (GooString *)toUnicodeDirs->get(i);
1076    fileName = appendToPath(dir->copy(), name->getCString());
1077    f = fopen(fileName->getCString(), "r");
1078    delete fileName;
1079    if (f) {
1080      unlockGlobalParams;
1081      return f;
1082    }
1083  }
1084  unlockGlobalParams;
1085  return NULL;
1086}
1087
1088GBool findModifier(const char *name, const char *modifier, const char **start)
1089{
1090  const char *match;
1091
1092  if (name == NULL)
1093    return gFalse;
1094
1095  match = strstr(name, modifier);
1096  if (match) {
1097    if (*start == NULL || match < *start)
1098      *start = match;
1099    return gTrue;
1100  }
1101  else {
1102    return gFalse;
1103  }
1104}
1105
1106static FcPattern *buildFcPattern(GfxFont *font)
1107{
1108  int weight = FC_WEIGHT_NORMAL,
1109      slant = FC_SLANT_ROMAN,
1110      width = FC_WIDTH_NORMAL,
1111      spacing = FC_PROPORTIONAL;
1112  bool deleteFamily = false;
1113  char *family, *name, *lang, *modifiers;
1114  const char *start;
1115  FcPattern *p;
1116
1117  // this is all heuristics will be overwritten if font had proper info
1118  name = font->getName()->getCString();
1119 
1120  modifiers = strchr (name, ',');
1121  if (modifiers == NULL)
1122    modifiers = strchr (name, '-');
1123 
1124  // remove the - from the names, for some reason, Fontconfig does not
1125  // understand "MS-Mincho" but does with "MS Mincho"
1126  int len = strlen(name);
1127  for (int i = 0; i < len; i++)
1128    name[i] = (name[i] == '-' ? ' ' : name[i]);
1129
1130  start = NULL;
1131  findModifier(modifiers, "Regular", &start);
1132  findModifier(modifiers, "Roman", &start);
1133 
1134  if (findModifier(modifiers, "Oblique", &start))
1135    slant = FC_SLANT_OBLIQUE;
1136  if (findModifier(modifiers, "Italic", &start))
1137    slant = FC_SLANT_ITALIC;
1138  if (findModifier(modifiers, "Bold", &start))
1139    weight = FC_WEIGHT_BOLD;
1140  if (findModifier(modifiers, "Light", &start))
1141    weight = FC_WEIGHT_LIGHT;
1142  if (findModifier(modifiers, "Condensed", &start))
1143    width = FC_WIDTH_CONDENSED;
1144 
1145  if (start) {
1146    // There have been "modifiers" in the name, crop them to obtain
1147    // the family name
1148    family = new char[len+1];
1149    strcpy(family, name);
1150    int pos = (modifiers - name);
1151    family[pos] = '\0';
1152    deleteFamily = true;
1153  }
1154  else {
1155    family = name;
1156  }
1157 
1158  // use font flags
1159  if (font->isFixedWidth())
1160    spacing = FC_MONO;
1161  if (font->isBold())
1162    weight = FC_WEIGHT_BOLD;
1163  if (font->isItalic())
1164    slant = FC_SLANT_ITALIC;
1165 
1166  // if the FontDescriptor specified a family name use it
1167  if (font->getFamily()) {
1168    if (deleteFamily) {
1169      delete[] family;
1170      deleteFamily = false;
1171    }
1172    family = font->getFamily()->getCString();
1173  }
1174 
1175  // if the FontDescriptor specified a weight use it
1176  switch (font -> getWeight())
1177  {
1178    case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break; 
1179    case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break; 
1180    case GfxFont::W300: weight = FC_WEIGHT_BOOK; break; 
1181    case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break; 
1182    case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break; 
1183    case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break; 
1184    case GfxFont::W700: weight = FC_WEIGHT_BOLD; break; 
1185    case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break; 
1186    case GfxFont::W900: weight = FC_WEIGHT_BLACK; break; 
1187    default: break; 
1188  }
1189 
1190  // if the FontDescriptor specified a width use it
1191  switch (font -> getStretch())
1192  {
1193    case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break; 
1194    case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break; 
1195    case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break; 
1196    case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break; 
1197    case GfxFont::Normal: width = FC_WIDTH_NORMAL; break; 
1198    case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break; 
1199    case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break; 
1200    case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break; 
1201    case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break; 
1202    default: break; 
1203  }
1204 
1205  // find the language we want the font to support
1206  if (font->isCIDFont())
1207  {
1208    GooString *collection = ((GfxCIDFont *)font)->getCollection();
1209    if (collection)
1210    {
1211      if (strcmp(collection->getCString(), "Adobe-GB1") == 0)
1212        lang = "zh-cn"; // Simplified Chinese
1213      else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0)
1214        lang = "zh-tw"; // Traditional Chinese
1215      else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0)
1216        lang = "ja"; // Japanese
1217      else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0)
1218        lang = "ja"; // Japanese
1219      else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0)
1220        lang = "ko"; // Korean
1221      else if (strcmp(collection->getCString(), "Adobe-UCS") == 0)
1222        lang = "xx";
1223      else if (strcmp(collection->getCString(), "Adobe-Identity") == 0)
1224        lang = "xx";
1225      else
1226      {
1227        error(-1, "Unknown CID font collection, please report to poppler bugzilla.");
1228        lang = "xx";
1229      }
1230    }
1231    else lang = "xx";
1232  }
1233  else lang = "xx";
1234 
1235  p = FcPatternBuild(NULL,
1236                    FC_FAMILY, FcTypeString, family,
1237                    FC_SLANT, FcTypeInteger, slant, 
1238                    FC_WEIGHT, FcTypeInteger, weight,
1239                    FC_WIDTH, FcTypeInteger, width, 
1240                    FC_SPACING, FcTypeInteger, spacing,
1241                    FC_LANG, FcTypeString, lang,
1242                    NULL);
1243  if (deleteFamily)
1244    delete[] family;
1245  return p;
1246}
1247
1248DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
1249  DisplayFontParam *dfp;
1250  FcPattern *p=0;
1251
1252  GooString *fontName = font->getName();
1253  if (!fontName) return NULL;
1254 
1255  lockGlobalParams;
1256  dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1257  if (!dfp)
1258  {
1259    FcChar8* s;
1260    char * ext;
1261    FcResult res;
1262    FcFontSet *set;
1263    int i;
1264    p = buildFcPattern(font);
1265
1266    if (!p)
1267      goto fin;
1268    FcConfigSubstitute(FCcfg, p, FcMatchPattern);
1269    FcDefaultSubstitute(p);
1270    set = FcFontSort(FCcfg, p, FcFalse, NULL, &res);
1271    if (!set)
1272      goto fin;
1273    for (i = 0; i < set->nfont; ++i)
1274    {
1275      res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
1276      if (res != FcResultMatch || !s)
1277        continue;
1278      ext = strrchr((char*)s,'.');
1279      if (!ext)
1280        continue;
1281      if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4))
1282      {
1283        dfp = new DisplayFontParam(fontName->copy(), displayFontTT); 
1284        dfp->tt.fileName = new GooString((char*)s);
1285        FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex));
1286      }
1287      else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) 
1288      {
1289        dfp = new DisplayFontParam(fontName->copy(), displayFontT1); 
1290        dfp->t1.fileName = new GooString((char*)s);
1291      }
1292      else
1293        continue;
1294      displayFonts->add(dfp->name,dfp);
1295      break;
1296    }
1297    FcFontSetDestroy(set);
1298  }
1299fin:
1300  if (p)
1301    FcPatternDestroy(p);
1302
1303  unlockGlobalParams;
1304  return dfp;
1305}
1306
1307GooString *GlobalParams::getPSFile() {
1308  GooString *s;
1309
1310  lockGlobalParams;
1311  s = psFile ? psFile->copy() : (GooString *)NULL;
1312  unlockGlobalParams;
1313  return s;
1314}
1315
1316int GlobalParams::getPSPaperWidth() {
1317  int w;
1318
1319  lockGlobalParams;
1320  w = psPaperWidth;
1321  unlockGlobalParams;
1322  return w;
1323}
1324
1325int GlobalParams::getPSPaperHeight() {
1326  int h;
1327
1328  lockGlobalParams;
1329  h = psPaperHeight;
1330  unlockGlobalParams;
1331  return h;
1332}
1333
1334void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1335  lockGlobalParams;
1336  *llx = psImageableLLX;
1337  *lly = psImageableLLY;
1338  *urx = psImageableURX;
1339  *ury = psImageableURY;
1340  unlockGlobalParams;
1341}
1342
1343GBool GlobalParams::getPSCrop() {
1344  GBool f;
1345
1346  lockGlobalParams;
1347  f = psCrop;
1348  unlockGlobalParams;
1349  return f;
1350}
1351
1352GBool GlobalParams::getPSExpandSmaller() {
1353  GBool f;
1354
1355  lockGlobalParams;
1356  f = psExpandSmaller;
1357  unlockGlobalParams;
1358  return f;
1359}
1360
1361GBool GlobalParams::getPSShrinkLarger() {
1362  GBool f;
1363
1364  lockGlobalParams;
1365  f = psShrinkLarger;
1366  unlockGlobalParams;
1367  return f;
1368}
1369
1370GBool GlobalParams::getPSCenter() {
1371  GBool f;
1372
1373  lockGlobalParams;
1374  f = psCenter;
1375  unlockGlobalParams;
1376  return f;
1377}
1378
1379GBool GlobalParams::getPSDuplex() {
1380  GBool d;
1381
1382  lockGlobalParams;
1383  d = psDuplex;
1384  unlockGlobalParams;
1385  return d;
1386}
1387
1388PSLevel GlobalParams::getPSLevel() {
1389  PSLevel level;
1390
1391  lockGlobalParams;
1392  level = psLevel;
1393  unlockGlobalParams;
1394  return level;
1395}
1396
1397PSFontParam *GlobalParams::getPSFont(GooString *fontName) {
1398  PSFontParam *p;
1399
1400  lockGlobalParams;
1401  p = (PSFontParam *)psFonts->lookup(fontName);
1402  unlockGlobalParams;
1403  return p;
1404}
1405
1406PSFontParam *GlobalParams::getPSFont16(GooString *fontName,
1407                                       GooString *collection, int wMode) {
1408  PSFontParam *p;
1409  int i;
1410
1411  lockGlobalParams;
1412  p = NULL;
1413  if (fontName) {
1414    for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1415      p = (PSFontParam *)psNamedFonts16->get(i);
1416      if (!p->pdfFontName->cmp(fontName) &&
1417          p->wMode == wMode) {
1418        break;
1419      }
1420      p = NULL;
1421    }
1422  }
1423  if (!p && collection) {
1424    for (i = 0; i < psFonts16->getLength(); ++i) {
1425      p = (PSFontParam *)psFonts16->get(i);
1426      if (!p->pdfFontName->cmp(collection) &&
1427          p->wMode == wMode) {
1428        break;
1429      }
1430      p = NULL;
1431    }
1432  }
1433  unlockGlobalParams;
1434  return p;
1435}
1436
1437GBool GlobalParams::getPSEmbedType1() {
1438  GBool e;
1439
1440  lockGlobalParams;
1441  e = psEmbedType1;
1442  unlockGlobalParams;
1443  return e;
1444}
1445
1446GBool GlobalParams::getPSEmbedTrueType() {
1447  GBool e;
1448
1449  lockGlobalParams;
1450  e = psEmbedTrueType;
1451  unlockGlobalParams;
1452  return e;
1453}
1454
1455GBool GlobalParams::getPSEmbedCIDPostScript() {
1456  GBool e;
1457
1458  lockGlobalParams;
1459  e = psEmbedCIDPostScript;
1460  unlockGlobalParams;
1461  return e;
1462}
1463
1464GBool GlobalParams::getPSEmbedCIDTrueType() {
1465  GBool e;
1466
1467  lockGlobalParams;
1468  e = psEmbedCIDTrueType;
1469  unlockGlobalParams;
1470  return e;
1471}
1472
1473GBool GlobalParams::getPSOPI() {
1474  GBool opi;
1475
1476  lockGlobalParams;
1477  opi = psOPI;
1478  unlockGlobalParams;
1479  return opi;
1480}
1481
1482GBool GlobalParams::getPSASCIIHex() {
1483  GBool ah;
1484
1485  lockGlobalParams;
1486  ah = psASCIIHex;
1487  unlockGlobalParams;
1488  return ah;
1489}
1490
1491GooString *GlobalParams::getTextEncodingName() {
1492  GooString *s;
1493
1494  lockGlobalParams;
1495  s = textEncoding->copy();
1496  unlockGlobalParams;
1497  return s;
1498}
1499
1500EndOfLineKind GlobalParams::getTextEOL() {
1501  EndOfLineKind eol;
1502
1503  lockGlobalParams;
1504  eol = textEOL;
1505  unlockGlobalParams;
1506  return eol;
1507}
1508
1509GBool GlobalParams::getTextPageBreaks() {
1510  GBool pageBreaks;
1511
1512  lockGlobalParams;
1513  pageBreaks = textPageBreaks;
1514  unlockGlobalParams;
1515  return pageBreaks;
1516}
1517
1518GBool GlobalParams::getTextKeepTinyChars() {
1519  GBool tiny;
1520
1521  lockGlobalParams;
1522  tiny = textKeepTinyChars;
1523  unlockGlobalParams;
1524  return tiny;
1525}
1526
1527GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) {
1528  GooString *dir, *fileName;
1529  char **ext;
1530  FILE *f;
1531  int i;
1532
1533  lockGlobalParams;
1534  for (i = 0; i < fontDirs->getLength(); ++i) {
1535    dir = (GooString *)fontDirs->get(i);
1536    for (ext = exts; *ext; ++ext) {
1537      fileName = appendToPath(dir->copy(), fontName->getCString());
1538      fileName->append(*ext);
1539      if ((f = fopen(fileName->getCString(), "rb"))) {
1540        fclose(f);
1541        unlockGlobalParams;
1542        return fileName;
1543      }
1544      delete fileName;
1545    }
1546  }
1547  unlockGlobalParams;
1548  return NULL;
1549}
1550
1551GooString *GlobalParams::getInitialZoom() {
1552  GooString *s;
1553
1554  lockGlobalParams;
1555  s = initialZoom->copy();
1556  unlockGlobalParams;
1557  return s;
1558}
1559
1560GBool GlobalParams::getContinuousView() {
1561  GBool f;
1562
1563  lockGlobalParams;
1564  f = continuousView;
1565  unlockGlobalParams;
1566  return f;
1567}
1568
1569GBool GlobalParams::getEnableT1lib() {
1570  GBool f;
1571
1572  lockGlobalParams;
1573  f = enableT1lib;
1574  unlockGlobalParams;
1575  return f;
1576}
1577
1578GBool GlobalParams::getEnableFreeType() {
1579  GBool f;
1580
1581  lockGlobalParams;
1582  f = enableFreeType;
1583  unlockGlobalParams;
1584  return f;
1585}
1586
1587
1588GBool GlobalParams::getAntialias() {
1589  GBool f;
1590
1591  lockGlobalParams;
1592  f = antialias;
1593  unlockGlobalParams;
1594  return f;
1595}
1596
1597GBool GlobalParams::getMapNumericCharNames() {
1598  GBool map;
1599
1600  lockGlobalParams;
1601  map = mapNumericCharNames;
1602  unlockGlobalParams;
1603  return map;
1604}
1605
1606GBool GlobalParams::getPrintCommands() {
1607  GBool p;
1608
1609  lockGlobalParams;
1610  p = printCommands;
1611  unlockGlobalParams;
1612  return p;
1613}
1614
1615GBool GlobalParams::getProfileCommands() {
1616  GBool p;
1617
1618  lockGlobalParams;
1619  p = profileCommands;
1620  unlockGlobalParams;
1621  return p;
1622}
1623
1624GBool GlobalParams::getErrQuiet() {
1625  GBool q;
1626
1627  lockGlobalParams;
1628  q = errQuiet;
1629  unlockGlobalParams;
1630  return q;
1631}
1632
1633CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
1634  GooString *fileName;
1635  CharCodeToUnicode *ctu;
1636
1637  lockGlobalParams;
1638  if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1639    if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) &&
1640        (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1641      cidToUnicodeCache->add(ctu);
1642    }
1643  }
1644  unlockGlobalParams;
1645  return ctu;
1646}
1647
1648CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) {
1649  CharCodeToUnicode *ctu;
1650  GooHashIter *iter;
1651  GooString *fontPattern, *fileName;
1652
1653  lockGlobalParams;
1654  fileName = NULL;
1655  unicodeToUnicodes->startIter(&iter);
1656  while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1657    if (strstr(fontName->getCString(), fontPattern->getCString())) {
1658      unicodeToUnicodes->killIter(&iter);
1659      break;
1660    }
1661    fileName = NULL;
1662  }
1663  if (fileName) {
1664    if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1665      if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1666        unicodeToUnicodeCache->add(ctu);
1667      }
1668    }
1669  } else {
1670    ctu = NULL;
1671  }
1672  unlockGlobalParams;
1673  return ctu;
1674}
1675
1676UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
1677  return getUnicodeMap2(encodingName);
1678}
1679
1680UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
1681  UnicodeMap *map;
1682
1683  if (!(map = getResidentUnicodeMap(encodingName))) {
1684    lockUnicodeMapCache;
1685    map = unicodeMapCache->getUnicodeMap(encodingName);
1686    unlockUnicodeMapCache;
1687  }
1688  return map;
1689}
1690
1691CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName) {
1692  CMap *cMap;
1693
1694  lockCMapCache;
1695  cMap = cMapCache->getCMap(collection, cMapName);
1696  unlockCMapCache;
1697  return cMap;
1698}
1699
1700UnicodeMap *GlobalParams::getTextEncoding() {
1701  return getUnicodeMap2(textEncoding);
1702}
1703
1704//------------------------------------------------------------------------
1705// functions to set parameters
1706//------------------------------------------------------------------------
1707
1708void GlobalParams::setPSFile(char *file) {
1709  lockGlobalParams;
1710  if (psFile) {
1711    delete psFile;
1712  }
1713  psFile = new GooString(file);
1714  unlockGlobalParams;
1715}
1716
1717GBool GlobalParams::setPSPaperSize(char *size) {
1718  lockGlobalParams;
1719  if (!strcmp(size, "match")) {
1720    psPaperWidth = psPaperHeight = -1;
1721  } else if (!strcmp(size, "letter")) {
1722    psPaperWidth = 612;
1723    psPaperHeight = 792;
1724  } else if (!strcmp(size, "legal")) {
1725    psPaperWidth = 612;
1726    psPaperHeight = 1008;
1727  } else if (!strcmp(size, "A4")) {
1728    psPaperWidth = 595;
1729    psPaperHeight = 842;
1730  } else if (!strcmp(size, "A3")) {
1731    psPaperWidth = 842;
1732    psPaperHeight = 1190;
1733  } else {
1734    unlockGlobalParams;
1735    return gFalse;
1736  }
1737  psImageableLLX = psImageableLLY = 0;
1738  psImageableURX = psPaperWidth;
1739  psImageableURY = psPaperHeight;
1740  unlockGlobalParams;
1741  return gTrue;
1742}
1743
1744void GlobalParams::setPSPaperWidth(int width) {
1745  lockGlobalParams;
1746  psPaperWidth = width;
1747  psImageableLLX = 0;
1748  psImageableURX = psPaperWidth;
1749  unlockGlobalParams;
1750}
1751
1752void GlobalParams::setPSPaperHeight(int height) {
1753  lockGlobalParams;
1754  psPaperHeight = height;
1755  psImageableLLY = 0;
1756  psImageableURY = psPaperHeight;
1757  unlockGlobalParams;
1758}
1759
1760void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1761  lockGlobalParams;
1762  psImageableLLX = llx;
1763  psImageableLLY = lly;
1764  psImageableURX = urx;
1765  psImageableURY = ury;
1766  unlockGlobalParams;
1767}
1768
1769void GlobalParams::setPSCrop(GBool crop) {
1770  lockGlobalParams;
1771  psCrop = crop;
1772  unlockGlobalParams;
1773}
1774
1775void GlobalParams::setPSExpandSmaller(GBool expand) {
1776  lockGlobalParams;
1777  psExpandSmaller = expand;
1778  unlockGlobalParams;
1779}
1780
1781void GlobalParams::setPSShrinkLarger(GBool shrink) {
1782  lockGlobalParams;
1783  psShrinkLarger = shrink;
1784  unlockGlobalParams;
1785}
1786
1787void GlobalParams::setPSCenter(GBool center) {
1788  lockGlobalParams;
1789  psCenter = center;
1790  unlockGlobalParams;
1791}
1792
1793void GlobalParams::setPSDuplex(GBool duplex) {
1794  lockGlobalParams;
1795  psDuplex = duplex;
1796  unlockGlobalParams;
1797}
1798
1799void GlobalParams::setPSLevel(PSLevel level) {
1800  lockGlobalParams;
1801  psLevel = level;
1802  unlockGlobalParams;
1803}
1804
1805void GlobalParams::setPSEmbedType1(GBool embed) {
1806  lockGlobalParams;
1807  psEmbedType1 = embed;
1808  unlockGlobalParams;
1809}
1810
1811void GlobalParams::setPSEmbedTrueType(GBool embed) {
1812  lockGlobalParams;
1813  psEmbedTrueType = embed;
1814  unlockGlobalParams;
1815}
1816
1817void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1818  lockGlobalParams;
1819  psEmbedCIDPostScript = embed;
1820  unlockGlobalParams;
1821}
1822
1823void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1824  lockGlobalParams;
1825  psEmbedCIDTrueType = embed;
1826  unlockGlobalParams;
1827}
1828
1829void GlobalParams::setPSOPI(GBool opi) {
1830  lockGlobalParams;
1831  psOPI = opi;
1832  unlockGlobalParams;
1833}
1834
1835void GlobalParams::setPSASCIIHex(GBool hex) {
1836  lockGlobalParams;
1837  psASCIIHex = hex;
1838  unlockGlobalParams;
1839}
1840
1841void GlobalParams::setTextEncoding(char *encodingName) {
1842  lockGlobalParams;
1843  delete textEncoding;
1844  textEncoding = new GooString(encodingName);
1845  unlockGlobalParams;
1846}
1847
1848GBool GlobalParams::setTextEOL(char *s) {
1849  lockGlobalParams;
1850  if (!strcmp(s, "unix")) {
1851    textEOL = eolUnix;
1852  } else if (!strcmp(s, "dos")) {
1853    textEOL = eolDOS;
1854  } else if (!strcmp(s, "mac")) {
1855    textEOL = eolMac;
1856  } else {
1857    unlockGlobalParams;
1858    return gFalse;
1859  }
1860  unlockGlobalParams;
1861  return gTrue;
1862}
1863
1864void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1865  lockGlobalParams;
1866  textPageBreaks = pageBreaks;
1867  unlockGlobalParams;
1868}
1869
1870void GlobalParams::setTextKeepTinyChars(GBool keep) {
1871  lockGlobalParams;
1872  textKeepTinyChars = keep;
1873  unlockGlobalParams;
1874}
1875
1876void GlobalParams::setInitialZoom(char *s) {
1877  lockGlobalParams;
1878  delete initialZoom;
1879  initialZoom = new GooString(s);
1880  unlockGlobalParams;
1881}
1882
1883void GlobalParams::setContinuousView(GBool cont) {
1884  lockGlobalParams;
1885  continuousView = cont;
1886  unlockGlobalParams;
1887}
1888
1889GBool GlobalParams::setEnableT1lib(char *s) {
1890  GBool ok;
1891
1892  lockGlobalParams;
1893  ok = parseYesNo2(s, &enableT1lib);
1894  unlockGlobalParams;
1895  return ok;
1896}
1897
1898GBool GlobalParams::setEnableFreeType(char *s) {
1899  GBool ok;
1900
1901  lockGlobalParams;
1902  ok = parseYesNo2(s, &enableFreeType);
1903  unlockGlobalParams;
1904  return ok;
1905}
1906
1907
1908GBool GlobalParams::setAntialias(char *s) {
1909  GBool ok;
1910
1911  lockGlobalParams;
1912  ok = parseYesNo2(s, &antialias);
1913  unlockGlobalParams;
1914  return ok;
1915}
1916
1917void GlobalParams::setMapNumericCharNames(GBool map) {
1918  lockGlobalParams;
1919  mapNumericCharNames = map;
1920  unlockGlobalParams;
1921}
1922
1923void GlobalParams::setPrintCommands(GBool printCommandsA) {
1924  lockGlobalParams;
1925  printCommands = printCommandsA;
1926  unlockGlobalParams;
1927}
1928
1929void GlobalParams::setProfileCommands(GBool profileCommandsA) {
1930  lockGlobalParams;
1931  profileCommands = profileCommandsA;
1932  unlockGlobalParams;
1933}
1934
1935void GlobalParams::setErrQuiet(GBool errQuietA) {
1936  lockGlobalParams;
1937  errQuiet = errQuietA;
1938  unlockGlobalParams;
1939}
1940
1941void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1942#ifdef ENABLE_PLUGINS
1943  lockGlobalParams;
1944  securityHandlers->append(handler);
1945  unlockGlobalParams;
1946#endif
1947}
1948
1949XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1950#ifdef ENABLE_PLUGINS
1951  XpdfSecurityHandler *hdlr;
1952  int i;
1953
1954  lockGlobalParams;
1955  for (i = 0; i < securityHandlers->getLength(); ++i) {
1956    hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1957    if (!stricmp(hdlr->name, name)) {
1958      unlockGlobalParams;
1959      return hdlr;
1960    }
1961  }
1962  unlockGlobalParams;
1963
1964  if (!loadPlugin("security", name)) {
1965    return NULL;
1966  }
1967
1968  lockGlobalParams;
1969  for (i = 0; i < securityHandlers->getLength(); ++i) {
1970    hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1971    if (!strcmp(hdlr->name, name)) {
1972      unlockGlobalParams;
1973      return hdlr;
1974    }
1975  }
1976  unlockGlobalParams;
1977#endif
1978
1979  return NULL;
1980}
1981
1982#ifdef ENABLE_PLUGINS
1983//------------------------------------------------------------------------
1984// plugins
1985//------------------------------------------------------------------------
1986
1987GBool GlobalParams::loadPlugin(char *type, char *name) {
1988  Plugin *plugin;
1989
1990  if (!(plugin = Plugin::load(type, name))) {
1991    return gFalse;
1992  }
1993  lockGlobalParams;
1994  plugins->append(plugin);
1995  unlockGlobalParams;
1996  return gTrue;
1997}
1998
1999#endif // ENABLE_PLUGINS
Note: See TracBrowser for help on using the repository browser.