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

Last change on this file since 134 was 134, checked in by Eugene Romanenko, 15 years ago

poppler updated to version 0.5.4

File size: 50.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  scanEncodingDirs();
441}
442
443void GlobalParams::parseFile(GooString *fileName, FILE *f) {
444  int line;
445  GooList *tokens;
446  GooString *cmd, *incFile;
447  char *p1, *p2;
448  char buf[512];
449  FILE *f2;
450
451  line = 1;
452  while (getLine(buf, sizeof(buf) - 1, f)) {
453
454    // break the line into tokens
455    tokens = new GooList();
456    p1 = buf;
457    while (*p1) {
458      for (; *p1 && isspace(*p1); ++p1) ;
459      if (!*p1) {
460        break;
461      }
462      if (*p1 == '"' || *p1 == '\'') {
463        for (p2 = p1 + 1; *p2 && *p2 != *p1; ++p2) ;
464        ++p1;
465      } else {
466        for (p2 = p1 + 1; *p2 && !isspace(*p2); ++p2) ;
467      }
468      tokens->append(new GooString(p1, p2 - p1));
469      p1 = *p2 ? p2 + 1 : p2;
470    }
471
472    if (tokens->getLength() > 0 &&
473        ((GooString *)tokens->get(0))->getChar(0) != '#') {
474      cmd = (GooString *)tokens->get(0);
475      if (!cmd->cmp("include")) {
476        if (tokens->getLength() == 2) {
477          incFile = (GooString *)tokens->get(1);
478          if ((f2 = fopen(incFile->getCString(), "r"))) {
479            parseFile(incFile, f2);
480            fclose(f2);
481          } else {
482            error(-1, "Couldn't find included config file: '%s' (%s:%d)",
483                  incFile->getCString(), fileName->getCString(), line);
484          }
485        } else {
486          error(-1, "Bad 'include' config file command (%s:%d)",
487                fileName->getCString(), line);
488        }
489      } else if (!cmd->cmp("nameToUnicode")) {
490        if (tokens->getLength() != 2)
491          error(-1, "Bad 'nameToUnicode' config file command (%s:%d)",
492                fileName->getCString(), line);
493        else
494          parseNameToUnicode((GooString *) tokens->get(1));
495      } else if (!cmd->cmp("cidToUnicode")) {
496        parseCIDToUnicode(tokens, fileName, line);
497      } else if (!cmd->cmp("unicodeToUnicode")) {
498        parseUnicodeToUnicode(tokens, fileName, line);
499      } else if (!cmd->cmp("unicodeMap")) {
500        parseUnicodeMap(tokens, fileName, line);
501      } else if (!cmd->cmp("cMapDir")) {
502        parseCMapDir(tokens, fileName, line);
503      } else if (!cmd->cmp("toUnicodeDir")) {
504        parseToUnicodeDir(tokens, fileName, line);
505      } else if (!cmd->cmp("displayFontT1")) {
506        // deprecated
507      } else if (!cmd->cmp("displayFontTT")) {
508        // deprecated
509      } else if (!cmd->cmp("displayNamedCIDFontT1")) {
510        // deprecated
511      } else if (!cmd->cmp("displayCIDFontT1")) {
512        // deprecated
513      } else if (!cmd->cmp("displayNamedCIDFontTT")) {
514        // deprecated
515      } else if (!cmd->cmp("displayCIDFontTT")) {
516        // deprecated
517      } else if (!cmd->cmp("psFile")) {
518        parsePSFile(tokens, fileName, line);
519      } else if (!cmd->cmp("psFont")) {
520        parsePSFont(tokens, fileName, line);
521      } else if (!cmd->cmp("psNamedFont16")) {
522        parsePSFont16("psNamedFont16", psNamedFonts16,
523                      tokens, fileName, line);
524      } else if (!cmd->cmp("psFont16")) {
525        parsePSFont16("psFont16", psFonts16, tokens, fileName, line);
526      } else if (!cmd->cmp("psPaperSize")) {
527        parsePSPaperSize(tokens, fileName, line);
528      } else if (!cmd->cmp("psImageableArea")) {
529        parsePSImageableArea(tokens, fileName, line);
530      } else if (!cmd->cmp("psCrop")) {
531        parseYesNo("psCrop", &psCrop, tokens, fileName, line);
532      } else if (!cmd->cmp("psExpandSmaller")) {
533        parseYesNo("psExpandSmaller", &psExpandSmaller,
534                   tokens, fileName, line);
535      } else if (!cmd->cmp("psShrinkLarger")) {
536        parseYesNo("psShrinkLarger", &psShrinkLarger, tokens, fileName, line);
537      } else if (!cmd->cmp("psCenter")) {
538        parseYesNo("psCenter", &psCenter, tokens, fileName, line);
539      } else if (!cmd->cmp("psDuplex")) {
540        parseYesNo("psDuplex", &psDuplex, tokens, fileName, line);
541      } else if (!cmd->cmp("psLevel")) {
542        parsePSLevel(tokens, fileName, line);
543      } else if (!cmd->cmp("psEmbedType1Fonts")) {
544        parseYesNo("psEmbedType1", &psEmbedType1, tokens, fileName, line);
545      } else if (!cmd->cmp("psEmbedTrueTypeFonts")) {
546        parseYesNo("psEmbedTrueType", &psEmbedTrueType,
547                   tokens, fileName, line);
548      } else if (!cmd->cmp("psEmbedCIDPostScriptFonts")) {
549        parseYesNo("psEmbedCIDPostScript", &psEmbedCIDPostScript,
550                   tokens, fileName, line);
551      } else if (!cmd->cmp("psEmbedCIDTrueTypeFonts")) {
552        parseYesNo("psEmbedCIDTrueType", &psEmbedCIDTrueType,
553                   tokens, fileName, line);
554      } else if (!cmd->cmp("psOPI")) {
555        parseYesNo("psOPI", &psOPI, tokens, fileName, line);
556      } else if (!cmd->cmp("psASCIIHex")) {
557        parseYesNo("psASCIIHex", &psASCIIHex, tokens, fileName, line);
558      } else if (!cmd->cmp("textEncoding")) {
559        parseTextEncoding(tokens, fileName, line);
560      } else if (!cmd->cmp("textEOL")) {
561        parseTextEOL(tokens, fileName, line);
562      } else if (!cmd->cmp("textPageBreaks")) {
563        parseYesNo("textPageBreaks", &textPageBreaks,
564                   tokens, fileName, line);
565      } else if (!cmd->cmp("textKeepTinyChars")) {
566        parseYesNo("textKeepTinyChars", &textKeepTinyChars,
567                   tokens, fileName, line);
568      } else if (!cmd->cmp("fontDir")) {
569        parseFontDir(tokens, fileName, line);
570      } else if (!cmd->cmp("initialZoom")) {
571        parseInitialZoom(tokens, fileName, line);
572      } else if (!cmd->cmp("continuousView")) {
573        parseYesNo("continuousView", &continuousView, tokens, fileName, line);
574      } else if (!cmd->cmp("enableT1lib")) {
575        parseYesNo("enableT1lib", &enableT1lib, tokens, fileName, line);
576      } else if (!cmd->cmp("enableFreeType")) {
577        parseYesNo("enableFreeType", &enableFreeType, tokens, fileName, line);
578      } else if (!cmd->cmp("antialias")) {
579        parseYesNo("antialias", &antialias, tokens, fileName, line);
580      } else if (!cmd->cmp("urlCommand")) {
581        parseCommand("urlCommand", &urlCommand, tokens, fileName, line);
582      } else if (!cmd->cmp("movieCommand")) {
583        parseCommand("movieCommand", &movieCommand, tokens, fileName, line);
584      } else if (!cmd->cmp("mapNumericCharNames")) {
585        parseYesNo("mapNumericCharNames", &mapNumericCharNames,
586                   tokens, fileName, line);
587      } else if (!cmd->cmp("printCommands")) {
588        parseYesNo("printCommands", &printCommands, tokens, fileName, line);
589      } else if (!cmd->cmp("errQuiet")) {
590        parseYesNo("errQuiet", &errQuiet, tokens, fileName, line);
591      } else {
592        error(-1, "Unknown config file command '%s' (%s:%d)",
593              cmd->getCString(), fileName->getCString(), line);
594        if (!cmd->cmp("displayFontX") ||
595            !cmd->cmp("displayNamedCIDFontX") ||
596            !cmd->cmp("displayCIDFontX")) {
597          error(-1, "-- Xpdf no longer supports X fonts");
598        } else if (!cmd->cmp("t1libControl") || !cmd->cmp("freetypeControl")) {
599          error(-1, "-- The t1libControl and freetypeControl options have been replaced");
600          error(-1, "   by the enableT1lib, enableFreeType, and antialias options");
601        } else if (!cmd->cmp("fontpath") || !cmd->cmp("fontmap")) {
602          error(-1, "-- the config file format has changed since Xpdf 0.9x");
603        }
604      }
605    }
606
607    deleteGooList(tokens, GooString);
608    ++line;
609  }
610}
611
612void GlobalParams::scanEncodingDirs() {
613  GDir *dir;
614  GDirEntry *entry;
615
616  dir = new GDir(POPPLER_DATADIR "/nameToUnicode", gFalse);
617  while (entry = dir->getNextEntry(), entry != NULL) {
618    parseNameToUnicode(entry->getFullPath());
619    delete entry;
620  }
621  delete dir;
622
623  dir = new GDir(POPPLER_DATADIR "/cidToUnicode", gFalse);
624  while (entry = dir->getNextEntry(), entry != NULL) {
625    addCIDToUnicode(entry->getName(), entry->getFullPath());
626    delete entry;
627  }
628  delete dir;
629
630  dir = new GDir(POPPLER_DATADIR "/unicodeMap", gFalse);
631  while (entry = dir->getNextEntry(), entry != NULL) {
632    addUnicodeMap(entry->getName(), entry->getFullPath());
633    delete entry;
634  }
635  delete dir;
636
637  dir = new GDir(POPPLER_DATADIR "/cMap", gFalse);
638  while (entry = dir->getNextEntry(), entry != NULL) {
639    addCMapDir(entry->getName(), entry->getFullPath());
640    toUnicodeDirs->append(entry->getFullPath()->copy());
641    delete entry;
642  }
643  delete dir;
644}
645
646void GlobalParams::parseNameToUnicode(GooString *name) {
647  char *tok1, *tok2;
648  FILE *f;
649  char buf[256];
650  int line;
651  Unicode u;
652
653  if (!(f = fopen(name->getCString(), "r"))) {
654    error(-1, "Couldn't open 'nameToUnicode' file '%s'",
655          name->getCString());
656    return;
657  }
658  line = 1;
659  while (getLine(buf, sizeof(buf), f)) {
660    tok1 = strtok(buf, " \t\r\n");
661    tok2 = strtok(NULL, " \t\r\n");
662    if (tok1 && tok2) {
663      sscanf(tok1, "%x", &u);
664      nameToUnicode->add(tok2, u);
665    } else {
666      error(-1, "Bad line in 'nameToUnicode' file (%s:%d)",
667            name->getCString(), line);
668    }
669    ++line;
670  }
671  fclose(f);
672}
673
674void GlobalParams::addCIDToUnicode(GooString *collection,
675                                   GooString *fileName) {
676  GooString *old;
677
678  if ((old = (GooString *)cidToUnicodes->remove(collection))) {
679    delete old;
680  }
681  cidToUnicodes->add(collection->copy(), fileName->copy());
682}
683
684void GlobalParams::parseCIDToUnicode(GooList *tokens, GooString *fileName,
685                                     int line) {
686  if (tokens->getLength() != 3) {
687    error(-1, "Bad 'cidToUnicode' config file command (%s:%d)",
688          fileName->getCString(), line);
689    return;
690  }
691  addCIDToUnicode((GooString *)tokens->get(1), (GooString *)tokens->get(2));
692}
693
694void GlobalParams::parseUnicodeToUnicode(GooList *tokens, GooString *fileName,
695                                         int line) {
696  GooString *font, *file, *old;
697
698  if (tokens->getLength() != 3) {
699    error(-1, "Bad 'unicodeToUnicode' config file command (%s:%d)",
700          fileName->getCString(), line);
701    return;
702  }
703  font = (GooString *)tokens->get(1);
704  file = (GooString *)tokens->get(2);
705  if ((old = (GooString *)unicodeToUnicodes->remove(font))) {
706    delete old;
707  }
708  unicodeToUnicodes->add(font->copy(), file->copy());
709}
710
711void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName)
712{
713  GooString *old;
714
715  if ((old = (GooString *)unicodeMaps->remove(encodingName))) {
716    delete old;
717  }
718  unicodeMaps->add(encodingName->copy(), fileName->copy());
719}
720
721void GlobalParams::parseUnicodeMap(GooList *tokens, GooString *fileName,
722                                   int line) {
723
724  if (tokens->getLength() != 3) {
725    error(-1, "Bad 'unicodeMap' config file command (%s:%d)",
726          fileName->getCString(), line);
727    return;
728  }
729  addUnicodeMap((GooString *)tokens->get(1), (GooString *)tokens->get(2));
730}
731
732void GlobalParams::addCMapDir(GooString *collection, GooString *dir) {
733  GooList *list;
734
735  if (!(list = (GooList *)cMapDirs->lookup(collection))) {
736    list = new GooList();
737    cMapDirs->add(collection->copy(), list);
738  }
739  list->append(dir->copy());
740}
741
742void GlobalParams::parseCMapDir(GooList *tokens, GooString *fileName, int line) {
743  if (tokens->getLength() != 3) {
744    error(-1, "Bad 'cMapDir' config file command (%s:%d)",
745          fileName->getCString(), line);
746    return;
747  }
748  addCMapDir((GooString *)tokens->get(1), (GooString *)tokens->get(2));
749}
750
751void GlobalParams::parseToUnicodeDir(GooList *tokens, GooString *fileName,
752                                     int line) {
753  if (tokens->getLength() != 2) {
754    error(-1, "Bad 'toUnicodeDir' config file command (%s:%d)",
755          fileName->getCString(), line);
756    return;
757  }
758  toUnicodeDirs->append(((GooString *)tokens->get(1))->copy());
759}
760
761void GlobalParams::parsePSPaperSize(GooList *tokens, GooString *fileName,
762                                    int line) {
763  GooString *tok;
764
765  if (tokens->getLength() == 2) {
766    tok = (GooString *)tokens->get(1);
767    if (!setPSPaperSize(tok->getCString())) {
768      error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
769            fileName->getCString(), line);
770    }
771  } else if (tokens->getLength() == 3) {
772    tok = (GooString *)tokens->get(1);
773    psPaperWidth = atoi(tok->getCString());
774    tok = (GooString *)tokens->get(2);
775    psPaperHeight = atoi(tok->getCString());
776    psImageableLLX = psImageableLLY = 0;
777    psImageableURX = psPaperWidth;
778    psImageableURY = psPaperHeight;
779  } else {
780    error(-1, "Bad 'psPaperSize' config file command (%s:%d)",
781          fileName->getCString(), line);
782  }
783}
784
785void GlobalParams::parsePSImageableArea(GooList *tokens, GooString *fileName,
786                                        int line) {
787  if (tokens->getLength() != 5) {
788    error(-1, "Bad 'psImageableArea' config file command (%s:%d)",
789          fileName->getCString(), line);
790    return;
791  }
792  psImageableLLX = atoi(((GooString *)tokens->get(1))->getCString());
793  psImageableLLY = atoi(((GooString *)tokens->get(2))->getCString());
794  psImageableURX = atoi(((GooString *)tokens->get(3))->getCString());
795  psImageableURY = atoi(((GooString *)tokens->get(4))->getCString());
796}
797
798void GlobalParams::parsePSLevel(GooList *tokens, GooString *fileName, int line) {
799  GooString *tok;
800
801  if (tokens->getLength() != 2) {
802    error(-1, "Bad 'psLevel' config file command (%s:%d)",
803          fileName->getCString(), line);
804    return;
805  }
806  tok = (GooString *)tokens->get(1);
807  if (!tok->cmp("level1")) {
808    psLevel = psLevel1;
809  } else if (!tok->cmp("level1sep")) {
810    psLevel = psLevel1Sep;
811  } else if (!tok->cmp("level2")) {
812    psLevel = psLevel2;
813  } else if (!tok->cmp("level2sep")) {
814    psLevel = psLevel2Sep;
815  } else if (!tok->cmp("level3")) {
816    psLevel = psLevel3;
817  } else if (!tok->cmp("level3Sep")) {
818    psLevel = psLevel3Sep;
819  } else {
820    error(-1, "Bad 'psLevel' config file command (%s:%d)",
821          fileName->getCString(), line);
822  }
823}
824
825void GlobalParams::parsePSFile(GooList *tokens, GooString *fileName, int line) {
826  if (tokens->getLength() != 2) {
827    error(-1, "Bad 'psFile' config file command (%s:%d)",
828          fileName->getCString(), line);
829    return;
830  }
831  if (psFile) {
832    delete psFile;
833  }
834  psFile = ((GooString *)tokens->get(1))->copy();
835}
836
837void GlobalParams::parsePSFont(GooList *tokens, GooString *fileName, int line) {
838  PSFontParam *param;
839
840  if (tokens->getLength() != 3) {
841    error(-1, "Bad 'psFont' config file command (%s:%d)",
842          fileName->getCString(), line);
843    return;
844  }
845  param = new PSFontParam(((GooString *)tokens->get(1))->copy(), 0,
846                          ((GooString *)tokens->get(2))->copy(), NULL);
847  psFonts->add(param->pdfFontName, param);
848}
849
850void GlobalParams::parsePSFont16(char *cmdName, GooList *fontList,
851                                 GooList *tokens, GooString *fileName, int line) {
852  PSFontParam *param;
853  int wMode;
854  GooString *tok;
855
856  if (tokens->getLength() != 5) {
857    error(-1, "Bad '%s' config file command (%s:%d)",
858          cmdName, fileName->getCString(), line);
859    return;
860  }
861  tok = (GooString *)tokens->get(2);
862  if (!tok->cmp("H")) {
863    wMode = 0;
864  } else if (!tok->cmp("V")) {
865    wMode = 1;
866  } else {
867    error(-1, "Bad '%s' config file command (%s:%d)",
868          cmdName, fileName->getCString(), line);
869    return;
870  }
871  param = new PSFontParam(((GooString *)tokens->get(1))->copy(),
872                          wMode,
873                          ((GooString *)tokens->get(3))->copy(),
874                          ((GooString *)tokens->get(4))->copy());
875  fontList->append(param);
876}
877
878void GlobalParams::parseTextEncoding(GooList *tokens, GooString *fileName,
879                                     int line) {
880  if (tokens->getLength() != 2) {
881    error(-1, "Bad 'textEncoding' config file command (%s:%d)",
882          fileName->getCString(), line);
883    return;
884  }
885  delete textEncoding;
886  textEncoding = ((GooString *)tokens->get(1))->copy();
887}
888
889void GlobalParams::parseTextEOL(GooList *tokens, GooString *fileName, int line) {
890  GooString *tok;
891
892  if (tokens->getLength() != 2) {
893    error(-1, "Bad 'textEOL' config file command (%s:%d)",
894          fileName->getCString(), line);
895    return;
896  }
897  tok = (GooString *)tokens->get(1);
898  if (!tok->cmp("unix")) {
899    textEOL = eolUnix;
900  } else if (!tok->cmp("dos")) {
901    textEOL = eolDOS;
902  } else if (!tok->cmp("mac")) {
903    textEOL = eolMac;
904  } else {
905    error(-1, "Bad 'textEOL' config file command (%s:%d)",
906          fileName->getCString(), line);
907  }
908}
909
910void GlobalParams::parseFontDir(GooList *tokens, GooString *fileName, int line) {
911  if (tokens->getLength() != 2) {
912    error(-1, "Bad 'fontDir' config file command (%s:%d)",
913          fileName->getCString(), line);
914    return;
915  }
916  fontDirs->append(((GooString *)tokens->get(1))->copy());
917}
918
919void GlobalParams::parseInitialZoom(GooList *tokens,
920                                    GooString *fileName, int line) {
921  if (tokens->getLength() != 2) {
922    error(-1, "Bad 'initialZoom' config file command (%s:%d)",
923          fileName->getCString(), line);
924    return;
925  }
926  delete initialZoom;
927  initialZoom = ((GooString *)tokens->get(1))->copy();
928}
929
930void GlobalParams::parseCommand(char *cmdName, GooString **val,
931                                GooList *tokens, GooString *fileName, int line) {
932  if (tokens->getLength() != 2) {
933    error(-1, "Bad '%s' config file command (%s:%d)",
934          cmdName, fileName->getCString(), line);
935    return;
936  }
937  if (*val) {
938    delete *val;
939  }
940  *val = ((GooString *)tokens->get(1))->copy();
941}
942
943void GlobalParams::parseYesNo(char *cmdName, GBool *flag,
944                              GooList *tokens, GooString *fileName, int line) {
945  GooString *tok;
946
947  if (tokens->getLength() != 2) {
948    error(-1, "Bad '%s' config file command (%s:%d)",
949          cmdName, fileName->getCString(), line);
950    return;
951  }
952  tok = (GooString *)tokens->get(1);
953  if (!parseYesNo2(tok->getCString(), flag)) {
954    error(-1, "Bad '%s' config file command (%s:%d)",
955          cmdName, fileName->getCString(), line);
956  }
957}
958
959GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
960  if (!strcmp(token, "yes")) {
961    *flag = gTrue;
962  } else if (!strcmp(token, "no")) {
963    *flag = gFalse;
964  } else {
965    return gFalse;
966  }
967  return gTrue;
968}
969
970GlobalParams::~GlobalParams() {
971  GooHashIter *iter;
972  GooString *key;
973  GooList *list;
974
975  freeBuiltinFontTables();
976
977  delete macRomanReverseMap;
978
979  delete baseDir;
980  delete nameToUnicode;
981  deleteGooHash(cidToUnicodes, GooString);
982  deleteGooHash(unicodeToUnicodes, GooString);
983  deleteGooHash(residentUnicodeMaps, UnicodeMap);
984  deleteGooHash(unicodeMaps, GooString);
985  deleteGooList(toUnicodeDirs, GooString);
986  deleteGooHash(displayFonts, DisplayFontParam);
987  if (psFile) {
988    delete psFile;
989  }
990  deleteGooHash(psFonts, PSFontParam);
991  deleteGooList(psNamedFonts16, PSFontParam);
992  deleteGooList(psFonts16, PSFontParam);
993  delete textEncoding;
994  deleteGooList(fontDirs, GooString);
995  delete initialZoom;
996  if (urlCommand) {
997    delete urlCommand;
998  }
999  if (movieCommand) {
1000    delete movieCommand;
1001  }
1002
1003  cMapDirs->startIter(&iter);
1004  while (cMapDirs->getNext(&iter, &key, (void **)&list)) {
1005    deleteGooList(list, GooString);
1006  }
1007  delete cMapDirs;
1008
1009  delete cidToUnicodeCache;
1010  delete unicodeToUnicodeCache;
1011  delete unicodeMapCache;
1012  delete cMapCache;
1013
1014#ifdef ENABLE_PLUGINS
1015  delete securityHandlers;
1016  deleteGooList(plugins, Plugin);
1017#endif
1018
1019#if MULTITHREADED
1020  gDestroyMutex(&mutex);
1021  gDestroyMutex(&unicodeMapCacheMutex);
1022  gDestroyMutex(&cMapCacheMutex);
1023#endif
1024}
1025
1026//------------------------------------------------------------------------
1027
1028void GlobalParams::setBaseDir(char *dir) {
1029  delete baseDir;
1030  baseDir = new GooString(dir);
1031}
1032
1033//------------------------------------------------------------------------
1034// accessors
1035//------------------------------------------------------------------------
1036
1037CharCode GlobalParams::getMacRomanCharCode(char *charName) {
1038  // no need to lock - macRomanReverseMap is constant
1039  return macRomanReverseMap->lookup(charName);
1040}
1041
1042GooString *GlobalParams::getBaseDir() {
1043  GooString *s;
1044
1045  lockGlobalParams;
1046  s = baseDir->copy();
1047  unlockGlobalParams;
1048  return s;
1049}
1050
1051Unicode GlobalParams::mapNameToUnicode(char *charName) {
1052  // no need to lock - nameToUnicode is constant
1053  return nameToUnicode->lookup(charName);
1054}
1055
1056UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) {
1057  UnicodeMap *map;
1058
1059  lockGlobalParams;
1060  map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
1061  unlockGlobalParams;
1062  if (map) {
1063    map->incRefCnt();
1064  }
1065  return map;
1066}
1067
1068FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) {
1069  GooString *fileName;
1070  FILE *f;
1071
1072  lockGlobalParams;
1073  if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) {
1074    f = fopen(fileName->getCString(), "r");
1075  } else {
1076    f = NULL;
1077  }
1078  unlockGlobalParams;
1079  return f;
1080}
1081
1082FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) {
1083  GooList *list;
1084  GooString *dir;
1085  GooString *fileName;
1086  FILE *f;
1087  int i;
1088
1089  lockGlobalParams;
1090  if (!(list = (GooList *)cMapDirs->lookup(collection))) {
1091    unlockGlobalParams;
1092    return NULL;
1093  }
1094  for (i = 0; i < list->getLength(); ++i) {
1095    dir = (GooString *)list->get(i);
1096    fileName = appendToPath(dir->copy(), cMapName->getCString());
1097    f = fopen(fileName->getCString(), "r");
1098    delete fileName;
1099    if (f) {
1100      unlockGlobalParams;
1101      return f;
1102    }
1103  }
1104  unlockGlobalParams;
1105  return NULL;
1106}
1107
1108FILE *GlobalParams::findToUnicodeFile(GooString *name) {
1109  GooString *dir, *fileName;
1110  FILE *f;
1111  int i;
1112
1113  lockGlobalParams;
1114  for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
1115    dir = (GooString *)toUnicodeDirs->get(i);
1116    fileName = appendToPath(dir->copy(), name->getCString());
1117    f = fopen(fileName->getCString(), "r");
1118    delete fileName;
1119    if (f) {
1120      unlockGlobalParams;
1121      return f;
1122    }
1123  }
1124  unlockGlobalParams;
1125  return NULL;
1126}
1127
1128GBool findModifier(const char *name, const char *modifier, const char **start)
1129{
1130  const char *match;
1131
1132  if (name == NULL)
1133    return gFalse;
1134
1135  match = strstr(name, modifier);
1136  if (match) {
1137    if (*start == NULL || match < *start)
1138      *start = match;
1139    return gTrue;
1140  }
1141  else {
1142    return gFalse;
1143  }
1144}
1145
1146static FcPattern *buildFcPattern(GfxFont *font)
1147{
1148  int weight = FC_WEIGHT_NORMAL,
1149      slant = FC_SLANT_ROMAN,
1150      width = FC_WIDTH_NORMAL,
1151      spacing = FC_PROPORTIONAL;
1152  bool deleteFamily = false;
1153  char *family, *name, *lang, *modifiers;
1154  const char *start;
1155  FcPattern *p;
1156
1157  // this is all heuristics will be overwritten if font had proper info
1158  name = font->getName()->getCString();
1159 
1160  modifiers = strchr (name, ',');
1161  if (modifiers == NULL)
1162    modifiers = strchr (name, '-');
1163 
1164  // remove the - from the names, for some reason, Fontconfig does not
1165  // understand "MS-Mincho" but does with "MS Mincho"
1166  int len = strlen(name);
1167  for (int i = 0; i < len; i++)
1168    name[i] = (name[i] == '-' ? ' ' : name[i]);
1169
1170  start = NULL;
1171  findModifier(modifiers, "Regular", &start);
1172  findModifier(modifiers, "Roman", &start);
1173 
1174  if (findModifier(modifiers, "Oblique", &start))
1175    slant = FC_SLANT_OBLIQUE;
1176  if (findModifier(modifiers, "Italic", &start))
1177    slant = FC_SLANT_ITALIC;
1178  if (findModifier(modifiers, "Bold", &start))
1179    weight = FC_WEIGHT_BOLD;
1180  if (findModifier(modifiers, "Light", &start))
1181    weight = FC_WEIGHT_LIGHT;
1182  if (findModifier(modifiers, "Condensed", &start))
1183    width = FC_WIDTH_CONDENSED;
1184 
1185  if (start) {
1186    // There have been "modifiers" in the name, crop them to obtain
1187    // the family name
1188    family = new char[len+1];
1189    strcpy(family, name);
1190    int pos = (modifiers - name);
1191    family[pos] = '\0';
1192    deleteFamily = true;
1193  }
1194  else {
1195    family = name;
1196  }
1197 
1198  // use font flags
1199  if (font->isFixedWidth())
1200    spacing = FC_MONO;
1201  if (font->isBold())
1202    weight = FC_WEIGHT_BOLD;
1203  if (font->isItalic())
1204    slant = FC_SLANT_ITALIC;
1205 
1206  // if the FontDescriptor specified a family name use it
1207  if (font->getFamily()) {
1208    if (deleteFamily) {
1209      delete[] family;
1210      deleteFamily = false;
1211    }
1212    family = font->getFamily()->getCString();
1213  }
1214 
1215  // if the FontDescriptor specified a weight use it
1216  switch (font -> getWeight())
1217  {
1218    case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break; 
1219    case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break; 
1220    case GfxFont::W300: weight = FC_WEIGHT_BOOK; break; 
1221    case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break; 
1222    case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break; 
1223    case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break; 
1224    case GfxFont::W700: weight = FC_WEIGHT_BOLD; break; 
1225    case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break; 
1226    case GfxFont::W900: weight = FC_WEIGHT_BLACK; break; 
1227    default: break; 
1228  }
1229 
1230  // if the FontDescriptor specified a width use it
1231  switch (font -> getStretch())
1232  {
1233    case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break; 
1234    case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break; 
1235    case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break; 
1236    case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break; 
1237    case GfxFont::Normal: width = FC_WIDTH_NORMAL; break; 
1238    case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break; 
1239    case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break; 
1240    case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break; 
1241    case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break; 
1242    default: break; 
1243  }
1244 
1245  // find the language we want the font to support
1246  if (font->isCIDFont())
1247  {
1248    GooString *collection = ((GfxCIDFont *)font)->getCollection();
1249    if (collection)
1250    {
1251      if (strcmp(collection->getCString(), "Adobe-GB1") == 0)
1252        lang = "zh-cn"; // Simplified Chinese
1253      else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0)
1254        lang = "zh-tw"; // Traditional Chinese
1255      else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0)
1256        lang = "ja"; // Japanese
1257      else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0)
1258        lang = "ja"; // Japanese
1259      else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0)
1260        lang = "ko"; // Korean
1261      else if (strcmp(collection->getCString(), "Adobe-UCS") == 0)
1262        lang = "xx";
1263      else if (strcmp(collection->getCString(), "Adobe-Identity") == 0)
1264        lang = "xx";
1265      else
1266      {
1267        error(-1, "Unknown CID font collection, please report to poppler bugzilla.");
1268        lang = "xx";
1269      }
1270    }
1271    else lang = "xx";
1272  }
1273  else lang = "xx";
1274 
1275  p = FcPatternBuild(NULL,
1276                    FC_FAMILY, FcTypeString, family,
1277                    FC_SLANT, FcTypeInteger, slant, 
1278                    FC_WEIGHT, FcTypeInteger, weight,
1279                    FC_WIDTH, FcTypeInteger, width, 
1280                    FC_SPACING, FcTypeInteger, spacing,
1281                    FC_LANG, FcTypeString, lang,
1282                    NULL);
1283  if (deleteFamily)
1284    delete[] family;
1285  return p;
1286}
1287
1288DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
1289  DisplayFontParam *dfp;
1290  FcPattern *p=0;
1291
1292  GooString *fontName = font->getName();
1293  if (!fontName) return NULL;
1294 
1295  lockGlobalParams;
1296  dfp = (DisplayFontParam *)displayFonts->lookup(fontName);
1297  if (!dfp)
1298  {
1299    FcChar8* s;
1300    char * ext;
1301    FcResult res;
1302    FcFontSet *set;
1303    int i;
1304    p = buildFcPattern(font);
1305
1306    if (!p)
1307      goto fin;
1308    FcConfigSubstitute(FCcfg, p, FcMatchPattern);
1309    FcDefaultSubstitute(p);
1310    set = FcFontSort(FCcfg, p, FcFalse, NULL, &res);
1311    if (!set)
1312      goto fin;
1313    for (i = 0; i < set->nfont; ++i)
1314    {
1315      res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
1316      if (res != FcResultMatch || !s)
1317        continue;
1318      ext = strrchr((char*)s,'.');
1319      if (!ext)
1320        continue;
1321      if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4))
1322      {
1323        dfp = new DisplayFontParam(fontName->copy(), displayFontTT); 
1324        dfp->tt.fileName = new GooString((char*)s);
1325        FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex));
1326      }
1327      else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) 
1328      {
1329        dfp = new DisplayFontParam(fontName->copy(), displayFontT1); 
1330        dfp->t1.fileName = new GooString((char*)s);
1331      }
1332      else
1333        continue;
1334      displayFonts->add(dfp->name,dfp);
1335      break;
1336    }
1337    FcFontSetDestroy(set);
1338  }
1339fin:
1340  if (p)
1341    FcPatternDestroy(p);
1342
1343  unlockGlobalParams;
1344  return dfp;
1345}
1346
1347GooString *GlobalParams::getPSFile() {
1348  GooString *s;
1349
1350  lockGlobalParams;
1351  s = psFile ? psFile->copy() : (GooString *)NULL;
1352  unlockGlobalParams;
1353  return s;
1354}
1355
1356int GlobalParams::getPSPaperWidth() {
1357  int w;
1358
1359  lockGlobalParams;
1360  w = psPaperWidth;
1361  unlockGlobalParams;
1362  return w;
1363}
1364
1365int GlobalParams::getPSPaperHeight() {
1366  int h;
1367
1368  lockGlobalParams;
1369  h = psPaperHeight;
1370  unlockGlobalParams;
1371  return h;
1372}
1373
1374void GlobalParams::getPSImageableArea(int *llx, int *lly, int *urx, int *ury) {
1375  lockGlobalParams;
1376  *llx = psImageableLLX;
1377  *lly = psImageableLLY;
1378  *urx = psImageableURX;
1379  *ury = psImageableURY;
1380  unlockGlobalParams;
1381}
1382
1383GBool GlobalParams::getPSCrop() {
1384  GBool f;
1385
1386  lockGlobalParams;
1387  f = psCrop;
1388  unlockGlobalParams;
1389  return f;
1390}
1391
1392GBool GlobalParams::getPSExpandSmaller() {
1393  GBool f;
1394
1395  lockGlobalParams;
1396  f = psExpandSmaller;
1397  unlockGlobalParams;
1398  return f;
1399}
1400
1401GBool GlobalParams::getPSShrinkLarger() {
1402  GBool f;
1403
1404  lockGlobalParams;
1405  f = psShrinkLarger;
1406  unlockGlobalParams;
1407  return f;
1408}
1409
1410GBool GlobalParams::getPSCenter() {
1411  GBool f;
1412
1413  lockGlobalParams;
1414  f = psCenter;
1415  unlockGlobalParams;
1416  return f;
1417}
1418
1419GBool GlobalParams::getPSDuplex() {
1420  GBool d;
1421
1422  lockGlobalParams;
1423  d = psDuplex;
1424  unlockGlobalParams;
1425  return d;
1426}
1427
1428PSLevel GlobalParams::getPSLevel() {
1429  PSLevel level;
1430
1431  lockGlobalParams;
1432  level = psLevel;
1433  unlockGlobalParams;
1434  return level;
1435}
1436
1437PSFontParam *GlobalParams::getPSFont(GooString *fontName) {
1438  PSFontParam *p;
1439
1440  lockGlobalParams;
1441  p = (PSFontParam *)psFonts->lookup(fontName);
1442  unlockGlobalParams;
1443  return p;
1444}
1445
1446PSFontParam *GlobalParams::getPSFont16(GooString *fontName,
1447                                       GooString *collection, int wMode) {
1448  PSFontParam *p;
1449  int i;
1450
1451  lockGlobalParams;
1452  p = NULL;
1453  if (fontName) {
1454    for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1455      p = (PSFontParam *)psNamedFonts16->get(i);
1456      if (!p->pdfFontName->cmp(fontName) &&
1457          p->wMode == wMode) {
1458        break;
1459      }
1460      p = NULL;
1461    }
1462  }
1463  if (!p && collection) {
1464    for (i = 0; i < psFonts16->getLength(); ++i) {
1465      p = (PSFontParam *)psFonts16->get(i);
1466      if (!p->pdfFontName->cmp(collection) &&
1467          p->wMode == wMode) {
1468        break;
1469      }
1470      p = NULL;
1471    }
1472  }
1473  unlockGlobalParams;
1474  return p;
1475}
1476
1477GBool GlobalParams::getPSEmbedType1() {
1478  GBool e;
1479
1480  lockGlobalParams;
1481  e = psEmbedType1;
1482  unlockGlobalParams;
1483  return e;
1484}
1485
1486GBool GlobalParams::getPSEmbedTrueType() {
1487  GBool e;
1488
1489  lockGlobalParams;
1490  e = psEmbedTrueType;
1491  unlockGlobalParams;
1492  return e;
1493}
1494
1495GBool GlobalParams::getPSEmbedCIDPostScript() {
1496  GBool e;
1497
1498  lockGlobalParams;
1499  e = psEmbedCIDPostScript;
1500  unlockGlobalParams;
1501  return e;
1502}
1503
1504GBool GlobalParams::getPSEmbedCIDTrueType() {
1505  GBool e;
1506
1507  lockGlobalParams;
1508  e = psEmbedCIDTrueType;
1509  unlockGlobalParams;
1510  return e;
1511}
1512
1513GBool GlobalParams::getPSOPI() {
1514  GBool opi;
1515
1516  lockGlobalParams;
1517  opi = psOPI;
1518  unlockGlobalParams;
1519  return opi;
1520}
1521
1522GBool GlobalParams::getPSASCIIHex() {
1523  GBool ah;
1524
1525  lockGlobalParams;
1526  ah = psASCIIHex;
1527  unlockGlobalParams;
1528  return ah;
1529}
1530
1531GooString *GlobalParams::getTextEncodingName() {
1532  GooString *s;
1533
1534  lockGlobalParams;
1535  s = textEncoding->copy();
1536  unlockGlobalParams;
1537  return s;
1538}
1539
1540EndOfLineKind GlobalParams::getTextEOL() {
1541  EndOfLineKind eol;
1542
1543  lockGlobalParams;
1544  eol = textEOL;
1545  unlockGlobalParams;
1546  return eol;
1547}
1548
1549GBool GlobalParams::getTextPageBreaks() {
1550  GBool pageBreaks;
1551
1552  lockGlobalParams;
1553  pageBreaks = textPageBreaks;
1554  unlockGlobalParams;
1555  return pageBreaks;
1556}
1557
1558GBool GlobalParams::getTextKeepTinyChars() {
1559  GBool tiny;
1560
1561  lockGlobalParams;
1562  tiny = textKeepTinyChars;
1563  unlockGlobalParams;
1564  return tiny;
1565}
1566
1567GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) {
1568  GooString *dir, *fileName;
1569  char **ext;
1570  FILE *f;
1571  int i;
1572
1573  lockGlobalParams;
1574  for (i = 0; i < fontDirs->getLength(); ++i) {
1575    dir = (GooString *)fontDirs->get(i);
1576    for (ext = exts; *ext; ++ext) {
1577      fileName = appendToPath(dir->copy(), fontName->getCString());
1578      fileName->append(*ext);
1579      if ((f = fopen(fileName->getCString(), "rb"))) {
1580        fclose(f);
1581        unlockGlobalParams;
1582        return fileName;
1583      }
1584      delete fileName;
1585    }
1586  }
1587  unlockGlobalParams;
1588  return NULL;
1589}
1590
1591GooString *GlobalParams::getInitialZoom() {
1592  GooString *s;
1593
1594  lockGlobalParams;
1595  s = initialZoom->copy();
1596  unlockGlobalParams;
1597  return s;
1598}
1599
1600GBool GlobalParams::getContinuousView() {
1601  GBool f;
1602
1603  lockGlobalParams;
1604  f = continuousView;
1605  unlockGlobalParams;
1606  return f;
1607}
1608
1609GBool GlobalParams::getEnableT1lib() {
1610  GBool f;
1611
1612  lockGlobalParams;
1613  f = enableT1lib;
1614  unlockGlobalParams;
1615  return f;
1616}
1617
1618GBool GlobalParams::getEnableFreeType() {
1619  GBool f;
1620
1621  lockGlobalParams;
1622  f = enableFreeType;
1623  unlockGlobalParams;
1624  return f;
1625}
1626
1627
1628GBool GlobalParams::getAntialias() {
1629  GBool f;
1630
1631  lockGlobalParams;
1632  f = antialias;
1633  unlockGlobalParams;
1634  return f;
1635}
1636
1637GBool GlobalParams::getMapNumericCharNames() {
1638  GBool map;
1639
1640  lockGlobalParams;
1641  map = mapNumericCharNames;
1642  unlockGlobalParams;
1643  return map;
1644}
1645
1646GBool GlobalParams::getPrintCommands() {
1647  GBool p;
1648
1649  lockGlobalParams;
1650  p = printCommands;
1651  unlockGlobalParams;
1652  return p;
1653}
1654
1655GBool GlobalParams::getProfileCommands() {
1656  GBool p;
1657
1658  lockGlobalParams;
1659  p = profileCommands;
1660  unlockGlobalParams;
1661  return p;
1662}
1663
1664GBool GlobalParams::getErrQuiet() {
1665  GBool q;
1666
1667  lockGlobalParams;
1668  q = errQuiet;
1669  unlockGlobalParams;
1670  return q;
1671}
1672
1673CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
1674  GooString *fileName;
1675  CharCodeToUnicode *ctu;
1676
1677  lockGlobalParams;
1678  if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1679    if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) &&
1680        (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1681      cidToUnicodeCache->add(ctu);
1682    }
1683  }
1684  unlockGlobalParams;
1685  return ctu;
1686}
1687
1688CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) {
1689  CharCodeToUnicode *ctu;
1690  GooHashIter *iter;
1691  GooString *fontPattern, *fileName;
1692
1693  lockGlobalParams;
1694  fileName = NULL;
1695  unicodeToUnicodes->startIter(&iter);
1696  while (unicodeToUnicodes->getNext(&iter, &fontPattern, (void **)&fileName)) {
1697    if (strstr(fontName->getCString(), fontPattern->getCString())) {
1698      unicodeToUnicodes->killIter(&iter);
1699      break;
1700    }
1701    fileName = NULL;
1702  }
1703  if (fileName) {
1704    if (!(ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName))) {
1705      if ((ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName))) {
1706        unicodeToUnicodeCache->add(ctu);
1707      }
1708    }
1709  } else {
1710    ctu = NULL;
1711  }
1712  unlockGlobalParams;
1713  return ctu;
1714}
1715
1716UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
1717  return getUnicodeMap2(encodingName);
1718}
1719
1720UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
1721  UnicodeMap *map;
1722
1723  if (!(map = getResidentUnicodeMap(encodingName))) {
1724    lockUnicodeMapCache;
1725    map = unicodeMapCache->getUnicodeMap(encodingName);
1726    unlockUnicodeMapCache;
1727  }
1728  return map;
1729}
1730
1731CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName) {
1732  CMap *cMap;
1733
1734  lockCMapCache;
1735  cMap = cMapCache->getCMap(collection, cMapName);
1736  unlockCMapCache;
1737  return cMap;
1738}
1739
1740UnicodeMap *GlobalParams::getTextEncoding() {
1741  return getUnicodeMap2(textEncoding);
1742}
1743
1744//------------------------------------------------------------------------
1745// functions to set parameters
1746//------------------------------------------------------------------------
1747
1748void GlobalParams::setPSFile(char *file) {
1749  lockGlobalParams;
1750  if (psFile) {
1751    delete psFile;
1752  }
1753  psFile = new GooString(file);
1754  unlockGlobalParams;
1755}
1756
1757GBool GlobalParams::setPSPaperSize(char *size) {
1758  lockGlobalParams;
1759  if (!strcmp(size, "match")) {
1760    psPaperWidth = psPaperHeight = -1;
1761  } else if (!strcmp(size, "letter")) {
1762    psPaperWidth = 612;
1763    psPaperHeight = 792;
1764  } else if (!strcmp(size, "legal")) {
1765    psPaperWidth = 612;
1766    psPaperHeight = 1008;
1767  } else if (!strcmp(size, "A4")) {
1768    psPaperWidth = 595;
1769    psPaperHeight = 842;
1770  } else if (!strcmp(size, "A3")) {
1771    psPaperWidth = 842;
1772    psPaperHeight = 1190;
1773  } else {
1774    unlockGlobalParams;
1775    return gFalse;
1776  }
1777  psImageableLLX = psImageableLLY = 0;
1778  psImageableURX = psPaperWidth;
1779  psImageableURY = psPaperHeight;
1780  unlockGlobalParams;
1781  return gTrue;
1782}
1783
1784void GlobalParams::setPSPaperWidth(int width) {
1785  lockGlobalParams;
1786  psPaperWidth = width;
1787  psImageableLLX = 0;
1788  psImageableURX = psPaperWidth;
1789  unlockGlobalParams;
1790}
1791
1792void GlobalParams::setPSPaperHeight(int height) {
1793  lockGlobalParams;
1794  psPaperHeight = height;
1795  psImageableLLY = 0;
1796  psImageableURY = psPaperHeight;
1797  unlockGlobalParams;
1798}
1799
1800void GlobalParams::setPSImageableArea(int llx, int lly, int urx, int ury) {
1801  lockGlobalParams;
1802  psImageableLLX = llx;
1803  psImageableLLY = lly;
1804  psImageableURX = urx;
1805  psImageableURY = ury;
1806  unlockGlobalParams;
1807}
1808
1809void GlobalParams::setPSCrop(GBool crop) {
1810  lockGlobalParams;
1811  psCrop = crop;
1812  unlockGlobalParams;
1813}
1814
1815void GlobalParams::setPSExpandSmaller(GBool expand) {
1816  lockGlobalParams;
1817  psExpandSmaller = expand;
1818  unlockGlobalParams;
1819}
1820
1821void GlobalParams::setPSShrinkLarger(GBool shrink) {
1822  lockGlobalParams;
1823  psShrinkLarger = shrink;
1824  unlockGlobalParams;
1825}
1826
1827void GlobalParams::setPSCenter(GBool center) {
1828  lockGlobalParams;
1829  psCenter = center;
1830  unlockGlobalParams;
1831}
1832
1833void GlobalParams::setPSDuplex(GBool duplex) {
1834  lockGlobalParams;
1835  psDuplex = duplex;
1836  unlockGlobalParams;
1837}
1838
1839void GlobalParams::setPSLevel(PSLevel level) {
1840  lockGlobalParams;
1841  psLevel = level;
1842  unlockGlobalParams;
1843}
1844
1845void GlobalParams::setPSEmbedType1(GBool embed) {
1846  lockGlobalParams;
1847  psEmbedType1 = embed;
1848  unlockGlobalParams;
1849}
1850
1851void GlobalParams::setPSEmbedTrueType(GBool embed) {
1852  lockGlobalParams;
1853  psEmbedTrueType = embed;
1854  unlockGlobalParams;
1855}
1856
1857void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1858  lockGlobalParams;
1859  psEmbedCIDPostScript = embed;
1860  unlockGlobalParams;
1861}
1862
1863void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1864  lockGlobalParams;
1865  psEmbedCIDTrueType = embed;
1866  unlockGlobalParams;
1867}
1868
1869void GlobalParams::setPSOPI(GBool opi) {
1870  lockGlobalParams;
1871  psOPI = opi;
1872  unlockGlobalParams;
1873}
1874
1875void GlobalParams::setPSASCIIHex(GBool hex) {
1876  lockGlobalParams;
1877  psASCIIHex = hex;
1878  unlockGlobalParams;
1879}
1880
1881void GlobalParams::setTextEncoding(char *encodingName) {
1882  lockGlobalParams;
1883  delete textEncoding;
1884  textEncoding = new GooString(encodingName);
1885  unlockGlobalParams;
1886}
1887
1888GBool GlobalParams::setTextEOL(char *s) {
1889  lockGlobalParams;
1890  if (!strcmp(s, "unix")) {
1891    textEOL = eolUnix;
1892  } else if (!strcmp(s, "dos")) {
1893    textEOL = eolDOS;
1894  } else if (!strcmp(s, "mac")) {
1895    textEOL = eolMac;
1896  } else {
1897    unlockGlobalParams;
1898    return gFalse;
1899  }
1900  unlockGlobalParams;
1901  return gTrue;
1902}
1903
1904void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1905  lockGlobalParams;
1906  textPageBreaks = pageBreaks;
1907  unlockGlobalParams;
1908}
1909
1910void GlobalParams::setTextKeepTinyChars(GBool keep) {
1911  lockGlobalParams;
1912  textKeepTinyChars = keep;
1913  unlockGlobalParams;
1914}
1915
1916void GlobalParams::setInitialZoom(char *s) {
1917  lockGlobalParams;
1918  delete initialZoom;
1919  initialZoom = new GooString(s);
1920  unlockGlobalParams;
1921}
1922
1923void GlobalParams::setContinuousView(GBool cont) {
1924  lockGlobalParams;
1925  continuousView = cont;
1926  unlockGlobalParams;
1927}
1928
1929GBool GlobalParams::setEnableT1lib(char *s) {
1930  GBool ok;
1931
1932  lockGlobalParams;
1933  ok = parseYesNo2(s, &enableT1lib);
1934  unlockGlobalParams;
1935  return ok;
1936}
1937
1938GBool GlobalParams::setEnableFreeType(char *s) {
1939  GBool ok;
1940
1941  lockGlobalParams;
1942  ok = parseYesNo2(s, &enableFreeType);
1943  unlockGlobalParams;
1944  return ok;
1945}
1946
1947
1948GBool GlobalParams::setAntialias(char *s) {
1949  GBool ok;
1950
1951  lockGlobalParams;
1952  ok = parseYesNo2(s, &antialias);
1953  unlockGlobalParams;
1954  return ok;
1955}
1956
1957void GlobalParams::setMapNumericCharNames(GBool map) {
1958  lockGlobalParams;
1959  mapNumericCharNames = map;
1960  unlockGlobalParams;
1961}
1962
1963void GlobalParams::setPrintCommands(GBool printCommandsA) {
1964  lockGlobalParams;
1965  printCommands = printCommandsA;
1966  unlockGlobalParams;
1967}
1968
1969void GlobalParams::setProfileCommands(GBool profileCommandsA) {
1970  lockGlobalParams;
1971  profileCommands = profileCommandsA;
1972  unlockGlobalParams;
1973}
1974
1975void GlobalParams::setErrQuiet(GBool errQuietA) {
1976  lockGlobalParams;
1977  errQuiet = errQuietA;
1978  unlockGlobalParams;
1979}
1980
1981void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1982#ifdef ENABLE_PLUGINS
1983  lockGlobalParams;
1984  securityHandlers->append(handler);
1985  unlockGlobalParams;
1986#endif
1987}
1988
1989XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1990#ifdef ENABLE_PLUGINS
1991  XpdfSecurityHandler *hdlr;
1992  int i;
1993
1994  lockGlobalParams;
1995  for (i = 0; i < securityHandlers->getLength(); ++i) {
1996    hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1997    if (!stricmp(hdlr->name, name)) {
1998      unlockGlobalParams;
1999      return hdlr;
2000    }
2001  }
2002  unlockGlobalParams;
2003
2004  if (!loadPlugin("security", name)) {
2005    return NULL;
2006  }
2007
2008  lockGlobalParams;
2009  for (i = 0; i < securityHandlers->getLength(); ++i) {
2010    hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
2011    if (!strcmp(hdlr->name, name)) {
2012      unlockGlobalParams;
2013      return hdlr;
2014    }
2015  }
2016  unlockGlobalParams;
2017#endif
2018
2019  return NULL;
2020}
2021
2022#ifdef ENABLE_PLUGINS
2023//------------------------------------------------------------------------
2024// plugins
2025//------------------------------------------------------------------------
2026
2027GBool GlobalParams::loadPlugin(char *type, char *name) {
2028  Plugin *plugin;
2029
2030  if (!(plugin = Plugin::load(type, name))) {
2031    return gFalse;
2032  }
2033  lockGlobalParams;
2034  plugins->append(plugin);
2035  unlockGlobalParams;
2036  return gTrue;
2037}
2038
2039#endif // ENABLE_PLUGINS
Note: See TracBrowser for help on using the repository browser.