| //======================================================================== |
| // |
| // GlobalParams.cc |
| // |
| // Copyright 2001-2003 Glyph & Cog, LLC |
| // |
| //======================================================================== |
| |
| //======================================================================== |
| // |
| // Modified under the Poppler project - http://poppler.freedesktop.org |
| // |
| // All changes made under the Poppler project to this file are licensed |
| // under GPL version 2 or later |
| // |
| // Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org> |
| // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com> |
| // Copyright (C) 2005, 2007-2010 Albert Astals Cid <aacid@kde.org> |
| // Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com> |
| // Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net> |
| // Copyright (C) 2006 Takashi Iwai <tiwai@suse.de> |
| // Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk> |
| // Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com> |
| // Copyright (C) 2007, 2009 Jonathan Kew <jonathan_kew@sil.org> |
| // Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com> |
| // Copyright (C) 2009, 2011 William Bader <williambader@hotmail.com> |
| // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net> |
| // Copyright (C) 2010 Hib Eris <hib@hiberis.nl> |
| // Copyright (C) 2010 Patrick Spendrin <ps_ml@gmx.de> |
| // Copyright (C) 2010 Jakub Wilk <ubanus@users.sf.net> |
| // Copyright (C) 2011 Pino Toscano <pino@kde.org> |
| // Copyright (C) 2011 Koji Otani <sho@bbr.jp> |
| // Copyright (C) 2012 Yi Yang <ahyangyi@gmail.com> |
| // |
| // To see a description of the changes please see the Changelog file that |
| // came with your tarball or type make ChangeLog if you are building from git |
| // |
| //======================================================================== |
| |
| #include <config.h> |
| |
| #ifdef USE_GCC_PRAGMAS |
| #pragma implementation |
| #endif |
| |
| #include <string.h> |
| #include <stdio.h> |
| #include <ctype.h> |
| #ifdef ENABLE_PLUGINS |
| # ifndef _WIN32 |
| # include <dlfcn.h> |
| # endif |
| #endif |
| #ifdef _WIN32 |
| # include <shlobj.h> |
| # include <mbstring.h> |
| #endif |
| #include "goo/gmem.h" |
| #include "goo/GooString.h" |
| #include "goo/GooList.h" |
| #include "goo/GooHash.h" |
| #include "goo/gfile.h" |
| #include "Error.h" |
| #include "NameToCharCode.h" |
| #include "CharCodeToUnicode.h" |
| #include "UnicodeMap.h" |
| #include "CMap.h" |
| #include "BuiltinFontTables.h" |
| #include "FontEncodingTables.h" |
| #ifdef ENABLE_PLUGINS |
| # include "XpdfPluginAPI.h" |
| #endif |
| #include "GlobalParams.h" |
| #include "GfxFont.h" |
| |
| #if WITH_FONTCONFIGURATION_FONTCONFIG |
| #include <fontconfig/fontconfig.h> |
| #endif |
| |
| #ifdef _WIN32 |
| # define strcasecmp stricmp |
| #else |
| # include <strings.h> |
| #endif |
| |
| #if MULTITHREADED |
| # define lockGlobalParams gLockMutex(&mutex) |
| # define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex) |
| # define lockCMapCache gLockMutex(&cMapCacheMutex) |
| # define unlockGlobalParams gUnlockMutex(&mutex) |
| # define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex) |
| # define unlockCMapCache gUnlockMutex(&cMapCacheMutex) |
| #else |
| # define lockGlobalParams |
| # define lockUnicodeMapCache |
| # define lockCMapCache |
| # define unlockGlobalParams |
| # define unlockUnicodeMapCache |
| # define unlockCMapCache |
| #endif |
| |
| #ifndef FC_WEIGHT_BOOK |
| #define FC_WEIGHT_BOOK 75 |
| #endif |
| |
| #include "NameToUnicodeTable.h" |
| #include "UnicodeMapTables.h" |
| #include "UTF8.h" |
| |
| #ifdef ENABLE_PLUGINS |
| # ifdef _WIN32 |
| extern XpdfPluginVecTable xpdfPluginVecTable; |
| # endif |
| #endif |
| |
| //------------------------------------------------------------------------ |
| |
| #define cidToUnicodeCacheSize 4 |
| #define unicodeToUnicodeCacheSize 4 |
| |
| //------------------------------------------------------------------------ |
| |
| GlobalParams *globalParams = NULL; |
| |
| //------------------------------------------------------------------------ |
| // DisplayFontParam |
| //------------------------------------------------------------------------ |
| |
| DisplayFontParam::DisplayFontParam(GooString *nameA, |
| DisplayFontParamKind kindA) { |
| name = nameA; |
| kind = kindA; |
| switch (kind) { |
| case displayFontT1: |
| t1.fileName = NULL; |
| break; |
| case displayFontTT: |
| tt.fileName = NULL; |
| break; |
| } |
| } |
| |
| DisplayFontParam::~DisplayFontParam() { |
| delete name; |
| switch (kind) { |
| case displayFontT1: |
| if (t1.fileName) { |
| delete t1.fileName; |
| } |
| break; |
| case displayFontTT: |
| if (tt.fileName) { |
| delete tt.fileName; |
| } |
| break; |
| } |
| } |
| |
| #if ENABLE_RELOCATABLE && defined(_WIN32) |
| |
| /* search for data relative to where we are installed */ |
| |
| static HMODULE hmodule; |
| |
| extern "C" { |
| BOOL WINAPI |
| DllMain (HINSTANCE hinstDLL, |
| DWORD fdwReason, |
| LPVOID lpvReserved) |
| { |
| switch (fdwReason) |
| { |
| case DLL_PROCESS_ATTACH: |
| hmodule = hinstDLL; |
| break; |
| } |
| |
| return TRUE; |
| } |
| } |
| |
| static char * |
| get_poppler_datadir (void) |
| { |
| static char retval[MAX_PATH]; |
| static int beenhere = 0; |
| |
| unsigned char *p; |
| |
| if (beenhere) |
| return retval; |
| |
| if (!GetModuleFileName (hmodule, (CHAR *) retval, sizeof(retval) - 20)) |
| return POPPLER_DATADIR; |
| |
| p = _mbsrchr ((unsigned char *) retval, '\\'); |
| *p = '\0'; |
| p = _mbsrchr ((unsigned char *) retval, '\\'); |
| if (p) { |
| if (stricmp ((const char *) (p+1), "bin") == 0) |
| *p = '\0'; |
| } |
| strcat (retval, "\\share\\poppler"); |
| |
| beenhere = 1; |
| |
| return retval; |
| } |
| |
| #undef POPPLER_DATADIR |
| #define POPPLER_DATADIR get_poppler_datadir () |
| |
| #endif |
| |
| #ifdef _WIN32 |
| |
| //------------------------------------------------------------------------ |
| // WinFontInfo |
| //------------------------------------------------------------------------ |
| |
| class WinFontInfo: public DisplayFontParam { |
| public: |
| |
| GBool bold, italic; |
| |
| static WinFontInfo *make(GooString *nameA, GBool boldA, GBool italicA, |
| HKEY regKey, char *winFontDir); |
| WinFontInfo(GooString *nameA, GBool boldA, GBool italicA, |
| GooString *fileNameA); |
| virtual ~WinFontInfo(); |
| GBool equals(WinFontInfo *fi); |
| }; |
| |
| WinFontInfo *WinFontInfo::make(GooString *nameA, GBool boldA, GBool italicA, |
| HKEY regKey, char *winFontDir) { |
| GooString *regName; |
| GooString *fileNameA; |
| char buf[MAX_PATH]; |
| DWORD n; |
| char c; |
| int i; |
| |
| //----- find the font file |
| fileNameA = NULL; |
| regName = nameA->copy(); |
| if (boldA) { |
| regName->append(" Bold"); |
| } |
| if (italicA) { |
| regName->append(" Italic"); |
| } |
| regName->append(" (TrueType)"); |
| n = sizeof(buf); |
| if (RegQueryValueEx(regKey, regName->getCString(), NULL, NULL, |
| (LPBYTE)buf, &n) == ERROR_SUCCESS) { |
| fileNameA = new GooString(winFontDir); |
| fileNameA->append('\\')->append(buf); |
| } |
| delete regName; |
| if (!fileNameA) { |
| delete nameA; |
| return NULL; |
| } |
| |
| //----- normalize the font name |
| i = 0; |
| while (i < nameA->getLength()) { |
| c = nameA->getChar(i); |
| if (c == ' ' || c == ',' || c == '-') { |
| nameA->del(i); |
| } else { |
| ++i; |
| } |
| } |
| |
| return new WinFontInfo(nameA, boldA, italicA, fileNameA); |
| } |
| |
| WinFontInfo::WinFontInfo(GooString *nameA, GBool boldA, GBool italicA, |
| GooString *fileNameA): |
| DisplayFontParam(nameA, displayFontTT) |
| { |
| bold = boldA; |
| italic = italicA; |
| tt.fileName = fileNameA; |
| } |
| |
| WinFontInfo::~WinFontInfo() { |
| } |
| |
| GBool WinFontInfo::equals(WinFontInfo *fi) { |
| return !name->cmp(fi->name) && bold == fi->bold && italic == fi->italic; |
| } |
| |
| //------------------------------------------------------------------------ |
| // WinFontList |
| //------------------------------------------------------------------------ |
| |
| class WinFontList { |
| public: |
| |
| WinFontList(char *winFontDirA); |
| ~WinFontList(); |
| WinFontInfo *find(GooString *font); |
| |
| private: |
| |
| void add(WinFontInfo *fi); |
| static int CALLBACK enumFunc1(CONST LOGFONT *font, |
| CONST TEXTMETRIC *metrics, |
| DWORD type, LPARAM data); |
| static int CALLBACK enumFunc2(CONST LOGFONT *font, |
| CONST TEXTMETRIC *metrics, |
| DWORD type, LPARAM data); |
| |
| GooList *fonts; // [WinFontInfo] |
| HDC dc; // (only used during enumeration) |
| HKEY regKey; // (only used during enumeration) |
| char *winFontDir; // (only used during enumeration) |
| }; |
| |
| WinFontList::WinFontList(char *winFontDirA) { |
| OSVERSIONINFO version; |
| char *path; |
| |
| fonts = new GooList(); |
| dc = GetDC(NULL); |
| winFontDir = winFontDirA; |
| version.dwOSVersionInfoSize = sizeof(version); |
| GetVersionEx(&version); |
| if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) { |
| path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\"; |
| } else { |
| path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\"; |
| } |
| if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, |
| KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, |
| ®Key) == ERROR_SUCCESS) { |
| EnumFonts(dc, NULL, &WinFontList::enumFunc1, (LPARAM)this); |
| RegCloseKey(regKey); |
| } |
| ReleaseDC(NULL, dc); |
| } |
| |
| WinFontList::~WinFontList() { |
| deleteGooList(fonts, WinFontInfo); |
| } |
| |
| void WinFontList::add(WinFontInfo *fi) { |
| int i; |
| |
| for (i = 0; i < fonts->getLength(); ++i) { |
| if (((WinFontInfo *)fonts->get(i))->equals(fi)) { |
| delete fi; |
| return; |
| } |
| } |
| fonts->append(fi); |
| } |
| |
| WinFontInfo *WinFontList::find(GooString *font) { |
| GooString *name; |
| GBool bold, italic; |
| WinFontInfo *fi; |
| char c; |
| int n, i; |
| |
| name = font->copy(); |
| |
| // remove space, comma, dash chars |
| i = 0; |
| while (i < name->getLength()) { |
| c = name->getChar(i); |
| if (c == ' ' || c == ',' || c == '-') { |
| name->del(i); |
| } else { |
| ++i; |
| } |
| } |
| n = name->getLength(); |
| |
| // remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.) |
| if (!strcmp(name->getCString() + n - 2, "MT")) { |
| name->del(n - 2, 2); |
| n -= 2; |
| } |
| |
| // look for "Italic" |
| if (!strcmp(name->getCString() + n - 6, "Italic")) { |
| name->del(n - 6, 6); |
| italic = gTrue; |
| n -= 6; |
| } else { |
| italic = gFalse; |
| } |
| |
| // look for "Bold" |
| if (!strcmp(name->getCString() + n - 4, "Bold")) { |
| name->del(n - 4, 4); |
| bold = gTrue; |
| n -= 4; |
| } else { |
| bold = gFalse; |
| } |
| |
| // remove trailing "MT" (FooMT-Bold, etc.) |
| if (!strcmp(name->getCString() + n - 2, "MT")) { |
| name->del(n - 2, 2); |
| n -= 2; |
| } |
| |
| // remove trailing "PS" |
| if (!strcmp(name->getCString() + n - 2, "PS")) { |
| name->del(n - 2, 2); |
| n -= 2; |
| } |
| |
| // search for the font |
| fi = NULL; |
| for (i = 0; i < fonts->getLength(); ++i) { |
| fi = (WinFontInfo *)fonts->get(i); |
| if (!fi->name->cmp(name) && fi->bold == bold && fi->italic == italic) { |
| break; |
| } |
| fi = NULL; |
| } |
| |
| delete name; |
| return fi; |
| } |
| |
| int CALLBACK WinFontList::enumFunc1(CONST LOGFONT *font, |
| CONST TEXTMETRIC *metrics, |
| DWORD type, LPARAM data) { |
| WinFontList *fl = (WinFontList *)data; |
| |
| EnumFonts(fl->dc, font->lfFaceName, &WinFontList::enumFunc2, (LPARAM)fl); |
| return 1; |
| } |
| |
| int CALLBACK WinFontList::enumFunc2(CONST LOGFONT *font, |
| CONST TEXTMETRIC *metrics, |
| DWORD type, LPARAM data) { |
| WinFontList *fl = (WinFontList *)data; |
| WinFontInfo *fi; |
| |
| if (type & TRUETYPE_FONTTYPE) { |
| if ((fi = WinFontInfo::make(new GooString(font->lfFaceName), |
| font->lfWeight >= 600, |
| font->lfItalic ? gTrue : gFalse, |
| fl->regKey, fl->winFontDir))) { |
| fl->add(fi); |
| } |
| } |
| return 1; |
| } |
| |
| #endif // _WIN32 |
| |
| //------------------------------------------------------------------------ |
| // PSFontParam |
| //------------------------------------------------------------------------ |
| |
| PSFontParam::PSFontParam(GooString *pdfFontNameA, int wModeA, |
| GooString *psFontNameA, GooString *encodingA) { |
| pdfFontName = pdfFontNameA; |
| wMode = wModeA; |
| psFontName = psFontNameA; |
| encoding = encodingA; |
| } |
| |
| PSFontParam::~PSFontParam() { |
| delete pdfFontName; |
| delete psFontName; |
| if (encoding) { |
| delete encoding; |
| } |
| } |
| |
| #ifdef ENABLE_PLUGINS |
| //------------------------------------------------------------------------ |
| // Plugin |
| //------------------------------------------------------------------------ |
| |
| class Plugin { |
| public: |
| |
| static Plugin *load(char *type, char *name); |
| ~Plugin(); |
| |
| private: |
| |
| #ifdef _WIN32 |
| Plugin(HMODULE libA); |
| HMODULE lib; |
| #else |
| Plugin(void *dlA); |
| void *dl; |
| #endif |
| }; |
| |
| Plugin *Plugin::load(char *type, char *name) { |
| GooString *path; |
| Plugin *plugin; |
| XpdfPluginVecTable *vt; |
| XpdfBool (*xpdfInitPlugin)(void); |
| #ifdef _WIN32 |
| HMODULE libA; |
| #else |
| void *dlA; |
| #endif |
| |
| path = globalParams->getBaseDir(); |
| appendToPath(path, "plugins"); |
| appendToPath(path, type); |
| appendToPath(path, name); |
| |
| #ifdef _WIN32 |
| path->append(".dll"); |
| if (!(libA = LoadLibrary(path->getCString()))) { |
| error(-1, "Failed to load plugin '%s'", |
| path->getCString()); |
| goto err1; |
| } |
| if (!(vt = (XpdfPluginVecTable *) |
| GetProcAddress(libA, "xpdfPluginVecTable"))) { |
| error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'", |
| path->getCString()); |
| goto err2; |
| } |
| #else |
| //~ need to deal with other extensions here |
| path->append(".so"); |
| if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) { |
| error(-1, "Failed to load plugin '%s': %s", |
| path->getCString(), dlerror()); |
| goto err1; |
| } |
| if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) { |
| error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'", |
| path->getCString()); |
| goto err2; |
| } |
| #endif |
| |
| if (vt->version != xpdfPluginVecTable.version) { |
| error(-1, "Plugin '%s' is wrong version", path->getCString()); |
| goto err2; |
| } |
| memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable)); |
| |
| #ifdef _WIN32 |
| if (!(xpdfInitPlugin = (XpdfBool (*)(void)) |
| GetProcAddress(libA, "xpdfInitPlugin"))) { |
| error(-1, "Failed to find xpdfInitPlugin in plugin '%s'", |
| path->getCString()); |
| goto err2; |
| } |
| #else |
| if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) { |
| error(-1, "Failed to find xpdfInitPlugin in plugin '%s'", |
| path->getCString()); |
| goto err2; |
| } |
| #endif |
| |
| if (!(*xpdfInitPlugin)()) { |
| error(-1, "Initialization of plugin '%s' failed", |
| path->getCString()); |
| goto err2; |
| } |
| |
| #ifdef _WIN32 |
| plugin = new Plugin(libA); |
| #else |
| plugin = new Plugin(dlA); |
| #endif |
| |
| delete path; |
| return plugin; |
| |
| err2: |
| #ifdef _WIN32 |
| FreeLibrary(libA); |
| #else |
| dlclose(dlA); |
| #endif |
| err1: |
| delete path; |
| return NULL; |
| } |
| |
| #ifdef _WIN32 |
| Plugin::Plugin(HMODULE libA) { |
| lib = libA; |
| } |
| #else |
| Plugin::Plugin(void *dlA) { |
| dl = dlA; |
| } |
| #endif |
| |
| Plugin::~Plugin() { |
| void (*xpdfFreePlugin)(void); |
| |
| #ifdef _WIN32 |
| if ((xpdfFreePlugin = (void (*)(void)) |
| GetProcAddress(lib, "xpdfFreePlugin"))) { |
| (*xpdfFreePlugin)(); |
| } |
| FreeLibrary(lib); |
| #else |
| if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) { |
| (*xpdfFreePlugin)(); |
| } |
| dlclose(dl); |
| #endif |
| } |
| |
| #endif // ENABLE_PLUGINS |
| |
| //------------------------------------------------------------------------ |
| // parsing |
| //------------------------------------------------------------------------ |
| |
| GlobalParams::GlobalParams(const char *customPopplerDataDir) |
| : popplerDataDir(customPopplerDataDir) |
| { |
| UnicodeMap *map; |
| int i; |
| |
| #if MULTITHREADED |
| gInitMutex(&mutex); |
| gInitMutex(&unicodeMapCacheMutex); |
| gInitMutex(&cMapCacheMutex); |
| #endif |
| |
| initBuiltinFontTables(); |
| |
| // scan the encoding in reverse because we want the lowest-numbered |
| // index for each char name ('space' is encoded twice) |
| macRomanReverseMap = new NameToCharCode(); |
| for (i = 255; i >= 0; --i) { |
| if (macRomanEncoding[i]) { |
| macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i); |
| } |
| } |
| |
| #ifdef _WIN32 |
| // baseDir will be set by a call to setBaseDir |
| baseDir = new GooString(); |
| #else |
| baseDir = appendToPath(getHomeDir(), ".xpdf"); |
| #endif |
| nameToUnicode = new NameToCharCode(); |
| cidToUnicodes = new GooHash(gTrue); |
| unicodeToUnicodes = new GooHash(gTrue); |
| residentUnicodeMaps = new GooHash(); |
| unicodeMaps = new GooHash(gTrue); |
| cMapDirs = new GooHash(gTrue); |
| toUnicodeDirs = new GooList(); |
| displayFonts = new GooHash(); |
| psExpandSmaller = gFalse; |
| psShrinkLarger = gTrue; |
| psCenter = gTrue; |
| psLevel = psLevel2; |
| psFonts = new GooHash(); |
| psNamedFonts16 = new GooList(); |
| psFonts16 = new GooList(); |
| psEmbedType1 = gTrue; |
| psEmbedTrueType = gTrue; |
| psEmbedCIDPostScript = gTrue; |
| psEmbedCIDTrueType = gTrue; |
| psSubstFonts = gTrue; |
| psPreload = gFalse; |
| psOPI = gFalse; |
| psASCIIHex = gFalse; |
| psBinary = gFalse; |
| textEncoding = new GooString("UTF-8"); |
| #if defined(_WIN32) |
| textEOL = eolDOS; |
| #elif defined(MACOS) |
| textEOL = eolMac; |
| #else |
| textEOL = eolUnix; |
| #endif |
| textPageBreaks = gTrue; |
| textKeepTinyChars = gFalse; |
| fontDirs = new GooList(); |
| enableFreeType = gTrue; |
| antialias = gTrue; |
| vectorAntialias = gTrue; |
| strokeAdjust = gTrue; |
| screenType = screenUnset; |
| screenSize = -1; |
| screenDotRadius = -1; |
| screenGamma = 1.0; |
| screenBlackThreshold = 0.0; |
| screenWhiteThreshold = 1.0; |
| mapNumericCharNames = gTrue; |
| mapUnknownCharNames = gFalse; |
| printCommands = gFalse; |
| profileCommands = gFalse; |
| errQuiet = gFalse; |
| splashResolution = 0.0; |
| |
| cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize); |
| unicodeToUnicodeCache = |
| new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize); |
| unicodeMapCache = new UnicodeMapCache(); |
| cMapCache = new CMapCache(); |
| |
| #ifdef _WIN32 |
| baseFontsInitialized = gFalse; |
| winFontList = NULL; |
| #endif |
| |
| #ifdef ENABLE_PLUGINS |
| plugins = new GooList(); |
| securityHandlers = new GooList(); |
| #endif |
| |
| // set up the initial nameToUnicode table |
| for (i = 0; nameToUnicodeTab[i].name; ++i) { |
| nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u); |
| } |
| |
| // set up the residentUnicodeMaps table |
| map = new UnicodeMap("Latin1", gFalse, |
| latin1UnicodeMapRanges, latin1UnicodeMapLen); |
| residentUnicodeMaps->add(map->getEncodingName(), map); |
| map = new UnicodeMap("ASCII7", gFalse, |
| ascii7UnicodeMapRanges, ascii7UnicodeMapLen); |
| residentUnicodeMaps->add(map->getEncodingName(), map); |
| map = new UnicodeMap("Symbol", gFalse, |
| symbolUnicodeMapRanges, symbolUnicodeMapLen); |
| residentUnicodeMaps->add(map->getEncodingName(), map); |
| map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges, |
| zapfDingbatsUnicodeMapLen); |
| residentUnicodeMaps->add(map->getEncodingName(), map); |
| map = new UnicodeMap("UTF-8", gTrue, &mapUTF8); |
| residentUnicodeMaps->add(map->getEncodingName(), map); |
| map = new UnicodeMap("UCS-2", gTrue, &mapUCS2); |
| residentUnicodeMaps->add(map->getEncodingName(), map); |
| |
| scanEncodingDirs(); |
| } |
| |
| void GlobalParams::scanEncodingDirs() { |
| GDir *dir; |
| GDirEntry *entry; |
| const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR; |
| |
| // allocate buffer large enough to append "/nameToUnicode" |
| size_t bufSize = strlen(dataRoot) + strlen("/nameToUnicode") + 1; |
| char *dataPathBuffer = new char[bufSize]; |
| |
| snprintf(dataPathBuffer, bufSize, "%s/nameToUnicode", dataRoot); |
| dir = new GDir(dataPathBuffer, gTrue); |
| while (entry = dir->getNextEntry(), entry != NULL) { |
| if (!entry->isDir()) { |
| parseNameToUnicode(entry->getFullPath()); |
| } |
| delete entry; |
| } |
| delete dir; |
| |
| snprintf(dataPathBuffer, bufSize, "%s/cidToUnicode", dataRoot); |
| dir = new GDir(dataPathBuffer, gFalse); |
| while (entry = dir->getNextEntry(), entry != NULL) { |
| addCIDToUnicode(entry->getName(), entry->getFullPath()); |
| delete entry; |
| } |
| delete dir; |
| |
| snprintf(dataPathBuffer, bufSize, "%s/unicodeMap", dataRoot); |
| dir = new GDir(dataPathBuffer, gFalse); |
| while (entry = dir->getNextEntry(), entry != NULL) { |
| addUnicodeMap(entry->getName(), entry->getFullPath()); |
| delete entry; |
| } |
| delete dir; |
| |
| snprintf(dataPathBuffer, bufSize, "%s/cMap", dataRoot); |
| dir = new GDir(dataPathBuffer, gFalse); |
| while (entry = dir->getNextEntry(), entry != NULL) { |
| addCMapDir(entry->getName(), entry->getFullPath()); |
| toUnicodeDirs->append(entry->getFullPath()->copy()); |
| delete entry; |
| } |
| delete dir; |
| |
| delete[] dataPathBuffer; |
| } |
| |
| void GlobalParams::parseNameToUnicode(GooString *name) { |
| char *tok1, *tok2; |
| FILE *f; |
| char buf[256]; |
| int line; |
| Unicode u; |
| char *tokptr; |
| |
| if (!(f = fopen(name->getCString(), "r"))) { |
| error(-1, "Couldn't open 'nameToUnicode' file '%s'", |
| name->getCString()); |
| return; |
| } |
| line = 1; |
| while (getLine(buf, sizeof(buf), f)) { |
| tok1 = strtok_r(buf, " \t\r\n", &tokptr); |
| tok2 = strtok_r(NULL, " \t\r\n", &tokptr); |
| if (tok1 && tok2) { |
| sscanf(tok1, "%x", &u); |
| nameToUnicode->add(tok2, u); |
| } else { |
| error(-1, "Bad line in 'nameToUnicode' file (%s:%d)", |
| name->getCString(), line); |
| } |
| ++line; |
| } |
| fclose(f); |
| } |
| |
| void GlobalParams::addCIDToUnicode(GooString *collection, |
| GooString *fileName) { |
| GooString *old; |
| |
| if ((old = (GooString *)cidToUnicodes->remove(collection))) { |
| delete old; |
| } |
| cidToUnicodes->add(collection->copy(), fileName->copy()); |
| } |
| |
| void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName) |
| { |
| GooString *old; |
| |
| if ((old = (GooString *)unicodeMaps->remove(encodingName))) { |
| delete old; |
| } |
| unicodeMaps->add(encodingName->copy(), fileName->copy()); |
| } |
| |
| void GlobalParams::addCMapDir(GooString *collection, GooString *dir) { |
| GooList *list; |
| |
| if (!(list = (GooList *)cMapDirs->lookup(collection))) { |
| list = new GooList(); |
| cMapDirs->add(collection->copy(), list); |
| } |
| list->append(dir->copy()); |
| } |
| |
| GBool GlobalParams::parseYesNo2(char *token, GBool *flag) { |
| if (!strcmp(token, "yes")) { |
| *flag = gTrue; |
| } else if (!strcmp(token, "no")) { |
| *flag = gFalse; |
| } else { |
| return gFalse; |
| } |
| return gTrue; |
| } |
| |
| GlobalParams::~GlobalParams() { |
| freeBuiltinFontTables(); |
| |
| delete macRomanReverseMap; |
| |
| delete baseDir; |
| delete nameToUnicode; |
| deleteGooHash(cidToUnicodes, GooString); |
| deleteGooHash(unicodeToUnicodes, GooString); |
| deleteGooHash(residentUnicodeMaps, UnicodeMap); |
| deleteGooHash(unicodeMaps, GooString); |
| deleteGooList(toUnicodeDirs, GooString); |
| deleteGooHash(displayFonts, DisplayFontParam); |
| #ifdef _WIN32 |
| delete winFontList; |
| #endif |
| deleteGooHash(psFonts, PSFontParam); |
| deleteGooList(psNamedFonts16, PSFontParam); |
| deleteGooList(psFonts16, PSFontParam); |
| delete textEncoding; |
| deleteGooList(fontDirs, GooString); |
| |
| GooHashIter *iter; |
| GooString *key; |
| cMapDirs->startIter(&iter); |
| void *val; |
| while (cMapDirs->getNext(&iter, &key, &val)) { |
| GooList* list = (GooList*)val; |
| deleteGooList(list, GooString); |
| } |
| delete cMapDirs; |
| |
| delete cidToUnicodeCache; |
| delete unicodeToUnicodeCache; |
| delete unicodeMapCache; |
| delete cMapCache; |
| |
| #ifdef ENABLE_PLUGINS |
| delete securityHandlers; |
| deleteGooList(plugins, Plugin); |
| #endif |
| |
| #if MULTITHREADED |
| gDestroyMutex(&mutex); |
| gDestroyMutex(&unicodeMapCacheMutex); |
| gDestroyMutex(&cMapCacheMutex); |
| #endif |
| } |
| |
| //------------------------------------------------------------------------ |
| |
| void GlobalParams::setBaseDir(char *dir) { |
| delete baseDir; |
| baseDir = new GooString(dir); |
| } |
| |
| //------------------------------------------------------------------------ |
| // accessors |
| //------------------------------------------------------------------------ |
| |
| CharCode GlobalParams::getMacRomanCharCode(char *charName) { |
| // no need to lock - macRomanReverseMap is constant |
| return macRomanReverseMap->lookup(charName); |
| } |
| |
| GooString *GlobalParams::getBaseDir() { |
| GooString *s; |
| |
| lockGlobalParams; |
| s = baseDir->copy(); |
| unlockGlobalParams; |
| return s; |
| } |
| |
| Unicode GlobalParams::mapNameToUnicode(char *charName) { |
| // no need to lock - nameToUnicode is constant |
| return nameToUnicode->lookup(charName); |
| } |
| |
| UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) { |
| UnicodeMap *map; |
| |
| lockGlobalParams; |
| map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName); |
| unlockGlobalParams; |
| if (map) { |
| map->incRefCnt(); |
| } |
| return map; |
| } |
| |
| FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) { |
| GooString *fileName; |
| FILE *f; |
| |
| lockGlobalParams; |
| if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) { |
| f = fopen(fileName->getCString(), "r"); |
| } else { |
| f = NULL; |
| } |
| unlockGlobalParams; |
| return f; |
| } |
| |
| FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) { |
| GooList *list; |
| GooString *dir; |
| GooString *fileName; |
| FILE *f; |
| int i; |
| |
| lockGlobalParams; |
| if (!(list = (GooList *)cMapDirs->lookup(collection))) { |
| unlockGlobalParams; |
| return NULL; |
| } |
| for (i = 0; i < list->getLength(); ++i) { |
| dir = (GooString *)list->get(i); |
| fileName = appendToPath(dir->copy(), cMapName->getCString()); |
| f = fopen(fileName->getCString(), "r"); |
| delete fileName; |
| if (f) { |
| unlockGlobalParams; |
| return f; |
| } |
| } |
| unlockGlobalParams; |
| return NULL; |
| } |
| |
| FILE *GlobalParams::findToUnicodeFile(GooString *name) { |
| GooString *dir, *fileName; |
| FILE *f; |
| int i; |
| |
| lockGlobalParams; |
| for (i = 0; i < toUnicodeDirs->getLength(); ++i) { |
| dir = (GooString *)toUnicodeDirs->get(i); |
| fileName = appendToPath(dir->copy(), name->getCString()); |
| f = fopen(fileName->getCString(), "r"); |
| delete fileName; |
| if (f) { |
| unlockGlobalParams; |
| return f; |
| } |
| } |
| unlockGlobalParams; |
| return NULL; |
| } |
| |
| #if WITH_FONTCONFIGURATION_FONTCONFIG |
| static GBool findModifier(const char *name, const char *modifier, const char **start) |
| { |
| const char *match; |
| |
| if (name == NULL) |
| return gFalse; |
| |
| match = strstr(name, modifier); |
| if (match) { |
| if (*start == NULL || match < *start) |
| *start = match; |
| return gTrue; |
| } |
| else { |
| return gFalse; |
| } |
| } |
| |
| static char *getFontLang(GfxFont *font) |
| { |
| char *lang; |
| |
| // find the language we want the font to support |
| if (font->isCIDFont()) |
| { |
| GooString *collection = ((GfxCIDFont *)font)->getCollection(); |
| if (collection) |
| { |
| if (strcmp(collection->getCString(), "Adobe-GB1") == 0) |
| lang = "zh-cn"; // Simplified Chinese |
| else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0) |
| lang = "zh-tw"; // Traditional Chinese |
| else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0) |
| lang = "ja"; // Japanese |
| else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0) |
| lang = "ja"; // Japanese |
| else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0) |
| lang = "ko"; // Korean |
| else if (strcmp(collection->getCString(), "Adobe-UCS") == 0) |
| lang = "xx"; |
| else if (strcmp(collection->getCString(), "Adobe-Identity") == 0) |
| lang = "xx"; |
| else |
| { |
| error(-1, "Unknown CID font collection, please report to poppler bugzilla."); |
| lang = "xx"; |
| } |
| } |
| else lang = "xx"; |
| } |
| else lang = "xx"; |
| return lang; |
| } |
| |
| static FcPattern *buildFcPattern(GfxFont *font) |
| { |
| int weight = -1, |
| slant = -1, |
| width = -1, |
| spacing = -1; |
| bool deleteFamily = false; |
| char *family, *name, *lang, *modifiers; |
| const char *start; |
| FcPattern *p; |
| |
| // this is all heuristics will be overwritten if font had proper info |
| name = font->getName()->getCString(); |
| |
| modifiers = strchr (name, ','); |
| if (modifiers == NULL) |
| modifiers = strchr (name, '-'); |
| |
| // remove the - from the names, for some reason, Fontconfig does not |
| // understand "MS-Mincho" but does with "MS Mincho" |
| int len = strlen(name); |
| for (int i = 0; i < len; i++) |
| name[i] = (name[i] == '-' ? ' ' : name[i]); |
| |
| start = NULL; |
| findModifier(modifiers, "Regular", &start); |
| findModifier(modifiers, "Roman", &start); |
| |
| if (findModifier(modifiers, "Oblique", &start)) |
| slant = FC_SLANT_OBLIQUE; |
| if (findModifier(modifiers, "Italic", &start)) |
| slant = FC_SLANT_ITALIC; |
| if (findModifier(modifiers, "Bold", &start)) |
| weight = FC_WEIGHT_BOLD; |
| if (findModifier(modifiers, "Light", &start)) |
| weight = FC_WEIGHT_LIGHT; |
| if (findModifier(modifiers, "Medium", &start)) |
| weight = FC_WEIGHT_MEDIUM; |
| if (findModifier(modifiers, "Condensed", &start)) |
| width = FC_WIDTH_CONDENSED; |
| |
| if (start) { |
| // There have been "modifiers" in the name, crop them to obtain |
| // the family name |
| family = new char[len+1]; |
| strcpy(family, name); |
| int pos = (modifiers - name); |
| family[pos] = '\0'; |
| deleteFamily = true; |
| } |
| else { |
| family = name; |
| } |
| |
| // use font flags |
| if (font->isFixedWidth()) |
| spacing = FC_MONO; |
| if (font->isBold()) |
| weight = FC_WEIGHT_BOLD; |
| if (font->isItalic()) |
| slant = FC_SLANT_ITALIC; |
| |
| // if the FontDescriptor specified a family name use it |
| if (font->getFamily()) { |
| if (deleteFamily) { |
| delete[] family; |
| deleteFamily = false; |
| } |
| family = font->getFamily()->getCString(); |
| } |
| |
| // if the FontDescriptor specified a weight use it |
| switch (font -> getWeight()) |
| { |
| case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break; |
| case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break; |
| case GfxFont::W300: weight = FC_WEIGHT_BOOK; break; |
| case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break; |
| case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break; |
| case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break; |
| case GfxFont::W700: weight = FC_WEIGHT_BOLD; break; |
| case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break; |
| case GfxFont::W900: weight = FC_WEIGHT_BLACK; break; |
| default: break; |
| } |
| |
| // if the FontDescriptor specified a width use it |
| switch (font -> getStretch()) |
| { |
| case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break; |
| case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break; |
| case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break; |
| case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break; |
| case GfxFont::Normal: width = FC_WIDTH_NORMAL; break; |
| case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break; |
| case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break; |
| case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break; |
| case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break; |
| default: break; |
| } |
| |
| lang = getFontLang(font); |
| |
| p = FcPatternBuild(NULL, |
| FC_FAMILY, FcTypeString, family, |
| FC_LANG, FcTypeString, lang, |
| NULL); |
| if (slant != -1) FcPatternAddInteger(p, FC_SLANT, slant); |
| if (weight != -1) FcPatternAddInteger(p, FC_WEIGHT, weight); |
| if (width != -1) FcPatternAddInteger(p, FC_WIDTH, width); |
| if (spacing != -1) FcPatternAddInteger(p, FC_SPACING, spacing); |
| |
| if (deleteFamily) |
| delete[] family; |
| return p; |
| } |
| #endif |
| |
| /* if you can't or don't want to use Fontconfig, you need to implement |
| this function for your platform. For Windows, it's in GlobalParamsWin.cc |
| */ |
| #if WITH_FONTCONFIGURATION_FONTCONFIG |
| DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) { |
| DisplayFontParam *dfp; |
| FcPattern *p=0; |
| |
| GooString *fontName = font->getName(); |
| if (!fontName) return NULL; |
| |
| lockGlobalParams; |
| dfp = font->dfp; |
| if (!dfp) |
| { |
| FcChar8* s; |
| char * ext; |
| FcResult res; |
| FcFontSet *set; |
| int i; |
| FcLangSet *lb = NULL; |
| char *lang; |
| p = buildFcPattern(font); |
| |
| if (!p) |
| goto fin; |
| FcConfigSubstitute(NULL, p, FcMatchPattern); |
| FcDefaultSubstitute(p); |
| set = FcFontSort(NULL, p, FcFalse, NULL, &res); |
| if (!set) |
| goto fin; |
| |
| // find the language we want the font to support |
| lang = getFontLang(font); |
| if (strcmp(lang,"xx") != 0) { |
| lb = FcLangSetCreate(); |
| FcLangSetAdd(lb,(FcChar8 *)lang); |
| } |
| |
| /* |
| scan twice. |
| first: fonts support the language |
| second: all fonts (fall back) |
| */ |
| while (dfp == NULL) |
| { |
| for (i = 0; i < set->nfont; ++i) |
| { |
| res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s); |
| if (res != FcResultMatch || !s) |
| continue; |
| if (lb != NULL) { |
| FcLangSet *l; |
| res = FcPatternGetLangSet(set->fonts[i], FC_LANG, 0, &l); |
| if (res != FcResultMatch || !FcLangSetContains(l,lb)) { |
| continue; |
| } |
| } |
| ext = strrchr((char*)s,'.'); |
| if (!ext) |
| continue; |
| if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4) || !strncasecmp(ext, ".otf", 4)) |
| { |
| dfp = new DisplayFontParam(fontName->copy(), displayFontTT); |
| dfp->tt.fileName = new GooString((char*)s); |
| FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex)); |
| } |
| else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4)) |
| { |
| dfp = new DisplayFontParam(fontName->copy(), displayFontT1); |
| dfp->t1.fileName = new GooString((char*)s); |
| } |
| else |
| continue; |
| font->dfp = dfp; |
| break; |
| } |
| if (lb != NULL) { |
| FcLangSetDestroy(lb); |
| lb = NULL; |
| } else { |
| /* scan all fonts of the list */ |
| break; |
| } |
| } |
| FcFontSetDestroy(set); |
| } |
| fin: |
| if (p) |
| FcPatternDestroy(p); |
| |
| unlockGlobalParams; |
| return dfp; |
| } |
| #endif |
| #if WITH_FONTCONFIGURATION_WIN32 |
| #include "GlobalParamsWin.cc" |
| #endif |
| |
| GBool GlobalParams::getPSExpandSmaller() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = psExpandSmaller; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| GBool GlobalParams::getPSShrinkLarger() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = psShrinkLarger; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| GBool GlobalParams::getPSCenter() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = psCenter; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| PSLevel GlobalParams::getPSLevel() { |
| PSLevel level; |
| |
| lockGlobalParams; |
| level = psLevel; |
| unlockGlobalParams; |
| return level; |
| } |
| |
| PSFontParam *GlobalParams::getPSFont(GooString *fontName) { |
| PSFontParam *p; |
| |
| lockGlobalParams; |
| p = (PSFontParam *)psFonts->lookup(fontName); |
| unlockGlobalParams; |
| return p; |
| } |
| |
| PSFontParam *GlobalParams::getPSFont16(GooString *fontName, |
| GooString *collection, int wMode) { |
| PSFontParam *p; |
| int i; |
| |
| lockGlobalParams; |
| p = NULL; |
| if (fontName) { |
| for (i = 0; i < psNamedFonts16->getLength(); ++i) { |
| p = (PSFontParam *)psNamedFonts16->get(i); |
| if (!p->pdfFontName->cmp(fontName) && |
| p->wMode == wMode) { |
| break; |
| } |
| p = NULL; |
| } |
| } |
| if (!p && collection) { |
| for (i = 0; i < psFonts16->getLength(); ++i) { |
| p = (PSFontParam *)psFonts16->get(i); |
| if (!p->pdfFontName->cmp(collection) && |
| p->wMode == wMode) { |
| break; |
| } |
| p = NULL; |
| } |
| } |
| unlockGlobalParams; |
| return p; |
| } |
| |
| GBool GlobalParams::getPSEmbedType1() { |
| GBool e; |
| |
| lockGlobalParams; |
| e = psEmbedType1; |
| unlockGlobalParams; |
| return e; |
| } |
| |
| GBool GlobalParams::getPSEmbedTrueType() { |
| GBool e; |
| |
| lockGlobalParams; |
| e = psEmbedTrueType; |
| unlockGlobalParams; |
| return e; |
| } |
| |
| GBool GlobalParams::getPSEmbedCIDPostScript() { |
| GBool e; |
| |
| lockGlobalParams; |
| e = psEmbedCIDPostScript; |
| unlockGlobalParams; |
| return e; |
| } |
| |
| GBool GlobalParams::getPSEmbedCIDTrueType() { |
| GBool e; |
| |
| lockGlobalParams; |
| e = psEmbedCIDTrueType; |
| unlockGlobalParams; |
| return e; |
| } |
| |
| GBool GlobalParams::getPSSubstFonts() { |
| GBool e; |
| |
| lockGlobalParams; |
| e = psSubstFonts; |
| unlockGlobalParams; |
| return e; |
| } |
| |
| GBool GlobalParams::getPSPreload() { |
| GBool preload; |
| |
| lockGlobalParams; |
| preload = psPreload; |
| unlockGlobalParams; |
| return preload; |
| } |
| |
| GBool GlobalParams::getPSOPI() { |
| GBool opi; |
| |
| lockGlobalParams; |
| opi = psOPI; |
| unlockGlobalParams; |
| return opi; |
| } |
| |
| GBool GlobalParams::getPSASCIIHex() { |
| GBool ah; |
| |
| lockGlobalParams; |
| ah = psASCIIHex; |
| unlockGlobalParams; |
| return ah; |
| } |
| |
| GBool GlobalParams::getPSBinary() { |
| GBool binary; |
| |
| lockGlobalParams; |
| binary = psBinary; |
| unlockGlobalParams; |
| return binary; |
| } |
| |
| GooString *GlobalParams::getTextEncodingName() { |
| GooString *s; |
| |
| lockGlobalParams; |
| s = textEncoding->copy(); |
| unlockGlobalParams; |
| return s; |
| } |
| |
| EndOfLineKind GlobalParams::getTextEOL() { |
| EndOfLineKind eol; |
| |
| lockGlobalParams; |
| eol = textEOL; |
| unlockGlobalParams; |
| return eol; |
| } |
| |
| GBool GlobalParams::getTextPageBreaks() { |
| GBool pageBreaks; |
| |
| lockGlobalParams; |
| pageBreaks = textPageBreaks; |
| unlockGlobalParams; |
| return pageBreaks; |
| } |
| |
| GBool GlobalParams::getTextKeepTinyChars() { |
| GBool tiny; |
| |
| lockGlobalParams; |
| tiny = textKeepTinyChars; |
| unlockGlobalParams; |
| return tiny; |
| } |
| |
| GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) { |
| GooString *dir, *fileName; |
| char **ext; |
| FILE *f; |
| int i; |
| |
| lockGlobalParams; |
| for (i = 0; i < fontDirs->getLength(); ++i) { |
| dir = (GooString *)fontDirs->get(i); |
| for (ext = exts; *ext; ++ext) { |
| fileName = appendToPath(dir->copy(), fontName->getCString()); |
| fileName->append(*ext); |
| if ((f = fopen(fileName->getCString(), "rb"))) { |
| fclose(f); |
| unlockGlobalParams; |
| return fileName; |
| } |
| delete fileName; |
| } |
| } |
| unlockGlobalParams; |
| return NULL; |
| } |
| |
| GBool GlobalParams::getEnableFreeType() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = enableFreeType; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| |
| GBool GlobalParams::getAntialias() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = antialias; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| GBool GlobalParams::getVectorAntialias() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = vectorAntialias; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| GBool GlobalParams::getStrokeAdjust() { |
| GBool f; |
| |
| lockGlobalParams; |
| f = strokeAdjust; |
| unlockGlobalParams; |
| return f; |
| } |
| |
| ScreenType GlobalParams::getScreenType() { |
| ScreenType t; |
| |
| lockGlobalParams; |
| t = screenType; |
| unlockGlobalParams; |
| return t; |
| } |
| |
| int GlobalParams::getScreenSize() { |
| int size; |
| |
| lockGlobalParams; |
| size = screenSize; |
| unlockGlobalParams; |
| return size; |
| } |
| |
| int GlobalParams::getScreenDotRadius() { |
| int r; |
| |
| lockGlobalParams; |
| r = screenDotRadius; |
| unlockGlobalParams; |
| return r; |
| } |
| |
| double GlobalParams::getScreenGamma() { |
| double gamma; |
| |
| lockGlobalParams; |
| gamma = screenGamma; |
| unlockGlobalParams; |
| return gamma; |
| } |
| |
| double GlobalParams::getScreenBlackThreshold() { |
| double thresh; |
| |
| lockGlobalParams; |
| thresh = screenBlackThreshold; |
| unlockGlobalParams; |
| return thresh; |
| } |
| |
| double GlobalParams::getScreenWhiteThreshold() { |
| double thresh; |
| |
| lockGlobalParams; |
| thresh = screenWhiteThreshold; |
| unlockGlobalParams; |
| return thresh; |
| } |
| |
| GBool GlobalParams::getMapNumericCharNames() { |
| GBool map; |
| |
| lockGlobalParams; |
| map = mapNumericCharNames; |
| unlockGlobalParams; |
| return map; |
| } |
| |
| GBool GlobalParams::getMapUnknownCharNames() { |
| GBool map; |
| |
| lockGlobalParams; |
| map = mapUnknownCharNames; |
| unlockGlobalParams; |
| return map; |
| } |
| |
| GBool GlobalParams::getPrintCommands() { |
| GBool p; |
| |
| lockGlobalParams; |
| p = printCommands; |
| unlockGlobalParams; |
| return p; |
| } |
| |
| GBool GlobalParams::getProfileCommands() { |
| GBool p; |
| |
| lockGlobalParams; |
| p = profileCommands; |
| unlockGlobalParams; |
| return p; |
| } |
| |
| GBool GlobalParams::getErrQuiet() { |
| // no locking -- this function may get called from inside a locked |
| // section |
| return errQuiet; |
| } |
| |
| double GlobalParams::getSplashResolution() { |
| double r; |
| lockGlobalParams; |
| r = splashResolution; |
| unlockGlobalParams; |
| return r; |
| } |
| |
| CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) { |
| GooString *fileName; |
| CharCodeToUnicode *ctu; |
| |
| lockGlobalParams; |
| if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) { |
| if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) && |
| (ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) { |
| cidToUnicodeCache->add(ctu); |
| } |
| } |
| unlockGlobalParams; |
| return ctu; |
| } |
| |
| CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) { |
| lockGlobalParams; |
| GooHashIter *iter; |
| unicodeToUnicodes->startIter(&iter); |
| GooString *fileName = NULL; |
| GooString *fontPattern; |
| void *val; |
| while (!fileName && unicodeToUnicodes->getNext(&iter, &fontPattern, &val)) { |
| if (strstr(fontName->getCString(), fontPattern->getCString())) { |
| unicodeToUnicodes->killIter(&iter); |
| fileName = (GooString*)val; |
| } |
| } |
| CharCodeToUnicode *ctu = NULL; |
| if (fileName) { |
| ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName); |
| if (!ctu) { |
| ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName); |
| if (ctu) |
| unicodeToUnicodeCache->add(ctu); |
| } |
| } |
| unlockGlobalParams; |
| return ctu; |
| } |
| |
| UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) { |
| return getUnicodeMap2(encodingName); |
| } |
| |
| UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) { |
| UnicodeMap *map; |
| |
| if (!(map = getResidentUnicodeMap(encodingName))) { |
| lockUnicodeMapCache; |
| map = unicodeMapCache->getUnicodeMap(encodingName); |
| unlockUnicodeMapCache; |
| } |
| return map; |
| } |
| |
| CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName, Stream *stream) { |
| CMap *cMap; |
| |
| lockCMapCache; |
| cMap = cMapCache->getCMap(collection, cMapName, stream); |
| unlockCMapCache; |
| return cMap; |
| } |
| |
| UnicodeMap *GlobalParams::getTextEncoding() { |
| return getUnicodeMap2(textEncoding); |
| } |
| |
| GooList *GlobalParams::getEncodingNames() |
| { |
| GooList *result = new GooList; |
| GooHashIter *iter; |
| GooString *key; |
| void *val; |
| residentUnicodeMaps->startIter(&iter); |
| while (residentUnicodeMaps->getNext(&iter, &key, &val)) { |
| result->append(key); |
| } |
| residentUnicodeMaps->killIter(&iter); |
| unicodeMaps->startIter(&iter); |
| while (unicodeMaps->getNext(&iter, &key, &val)) { |
| result->append(key); |
| } |
| unicodeMaps->killIter(&iter); |
| return result; |
| } |
| |
| //------------------------------------------------------------------------ |
| // functions to set parameters |
| //------------------------------------------------------------------------ |
| |
| void GlobalParams::setPSExpandSmaller(GBool expand) { |
| lockGlobalParams; |
| psExpandSmaller = expand; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSShrinkLarger(GBool shrink) { |
| lockGlobalParams; |
| psShrinkLarger = shrink; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSCenter(GBool center) { |
| lockGlobalParams; |
| psCenter = center; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSLevel(PSLevel level) { |
| lockGlobalParams; |
| psLevel = level; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSEmbedType1(GBool embed) { |
| lockGlobalParams; |
| psEmbedType1 = embed; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSEmbedTrueType(GBool embed) { |
| lockGlobalParams; |
| psEmbedTrueType = embed; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSEmbedCIDPostScript(GBool embed) { |
| lockGlobalParams; |
| psEmbedCIDPostScript = embed; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSEmbedCIDTrueType(GBool embed) { |
| lockGlobalParams; |
| psEmbedCIDTrueType = embed; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSSubstFonts(GBool substFonts) { |
| lockGlobalParams; |
| psSubstFonts = substFonts; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSPreload(GBool preload) { |
| lockGlobalParams; |
| psPreload = preload; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSOPI(GBool opi) { |
| lockGlobalParams; |
| psOPI = opi; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSASCIIHex(GBool hex) { |
| lockGlobalParams; |
| psASCIIHex = hex; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPSBinary(GBool binary) { |
| lockGlobalParams; |
| psBinary = binary; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setTextEncoding(char *encodingName) { |
| lockGlobalParams; |
| delete textEncoding; |
| textEncoding = new GooString(encodingName); |
| unlockGlobalParams; |
| } |
| |
| GBool GlobalParams::setTextEOL(char *s) { |
| lockGlobalParams; |
| if (!strcmp(s, "unix")) { |
| textEOL = eolUnix; |
| } else if (!strcmp(s, "dos")) { |
| textEOL = eolDOS; |
| } else if (!strcmp(s, "mac")) { |
| textEOL = eolMac; |
| } else { |
| unlockGlobalParams; |
| return gFalse; |
| } |
| unlockGlobalParams; |
| return gTrue; |
| } |
| |
| void GlobalParams::setTextPageBreaks(GBool pageBreaks) { |
| lockGlobalParams; |
| textPageBreaks = pageBreaks; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setTextKeepTinyChars(GBool keep) { |
| lockGlobalParams; |
| textKeepTinyChars = keep; |
| unlockGlobalParams; |
| } |
| |
| GBool GlobalParams::setEnableFreeType(char *s) { |
| GBool ok; |
| |
| lockGlobalParams; |
| ok = parseYesNo2(s, &enableFreeType); |
| unlockGlobalParams; |
| return ok; |
| } |
| |
| |
| GBool GlobalParams::setAntialias(char *s) { |
| GBool ok; |
| |
| lockGlobalParams; |
| ok = parseYesNo2(s, &antialias); |
| unlockGlobalParams; |
| return ok; |
| } |
| |
| GBool GlobalParams::setVectorAntialias(char *s) { |
| GBool ok; |
| |
| lockGlobalParams; |
| ok = parseYesNo2(s, &vectorAntialias); |
| unlockGlobalParams; |
| return ok; |
| } |
| |
| void GlobalParams::setStrokeAdjust(GBool adjust) |
| { |
| lockGlobalParams; |
| strokeAdjust = adjust; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setScreenType(ScreenType st) |
| { |
| lockGlobalParams; |
| screenType = st; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setScreenSize(int size) |
| { |
| lockGlobalParams; |
| screenSize = size; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setScreenDotRadius(int radius) |
| { |
| lockGlobalParams; |
| screenDotRadius = radius; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setScreenGamma(double gamma) |
| { |
| lockGlobalParams; |
| screenGamma = gamma; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setScreenBlackThreshold(double blackThreshold) |
| { |
| lockGlobalParams; |
| screenBlackThreshold = blackThreshold; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setScreenWhiteThreshold(double whiteThreshold) |
| { |
| lockGlobalParams; |
| screenWhiteThreshold = whiteThreshold; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setMapNumericCharNames(GBool map) { |
| lockGlobalParams; |
| mapNumericCharNames = map; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setMapUnknownCharNames(GBool map) { |
| lockGlobalParams; |
| mapUnknownCharNames = map; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setPrintCommands(GBool printCommandsA) { |
| lockGlobalParams; |
| printCommands = printCommandsA; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setProfileCommands(GBool profileCommandsA) { |
| lockGlobalParams; |
| profileCommands = profileCommandsA; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setErrQuiet(GBool errQuietA) { |
| lockGlobalParams; |
| errQuiet = errQuietA; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::setSplashResolution(double SplashResolutionA) { |
| lockGlobalParams; |
| splashResolution = SplashResolutionA; |
| unlockGlobalParams; |
| } |
| |
| void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) { |
| #ifdef ENABLE_PLUGINS |
| lockGlobalParams; |
| securityHandlers->append(handler); |
| unlockGlobalParams; |
| #endif |
| } |
| |
| XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) { |
| #ifdef ENABLE_PLUGINS |
| XpdfSecurityHandler *hdlr; |
| int i; |
| |
| lockGlobalParams; |
| for (i = 0; i < securityHandlers->getLength(); ++i) { |
| hdlr = (XpdfSecurityHandler *)securityHandlers->get(i); |
| if (!strcasecmp(hdlr->name, name)) { |
| unlockGlobalParams; |
| return hdlr; |
| } |
| } |
| unlockGlobalParams; |
| |
| if (!loadPlugin("security", name)) { |
| return NULL; |
| } |
| deleteGooList(keyBindings, KeyBinding); |
| |
| lockGlobalParams; |
| for (i = 0; i < securityHandlers->getLength(); ++i) { |
| hdlr = (XpdfSecurityHandler *)securityHandlers->get(i); |
| if (!strcmp(hdlr->name, name)) { |
| unlockGlobalParams; |
| return hdlr; |
| } |
| } |
| unlockGlobalParams; |
| #else |
| (void)name; |
| #endif |
| |
| return NULL; |
| } |
| |
| #ifdef ENABLE_PLUGINS |
| //------------------------------------------------------------------------ |
| // plugins |
| //------------------------------------------------------------------------ |
| |
| GBool GlobalParams::loadPlugin(char *type, char *name) { |
| Plugin *plugin; |
| |
| if (!(plugin = Plugin::load(type, name))) { |
| return gFalse; |
| } |
| lockGlobalParams; |
| plugins->append(plugin); |
| unlockGlobalParams; |
| return gTrue; |
| } |
| |
| #endif // ENABLE_PLUGINS |