1
//========================================================================
5
// Copyright 2001-2003 Glyph & Cog, LLC
7
//========================================================================
9
//========================================================================
11
// Modified under the Poppler project - http://poppler.freedesktop.org
13
// Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org>
14
// Copyright (C) 2005, 2006 Kristian HĆøgsberg <krh@redhat.com>
15
// Copyright (C) 2005, 2007-2010 Albert Astals Cid <aacid@kde.org>
16
// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
17
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
18
// Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
19
// Copyright (C) 2006 Ed Catmur <ed@catmur.co.uk>
20
// Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
21
// Copyright (C) 2007, 2009 Jonathan Kew <jonathan_kew@sil.org>
22
// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
23
// Copyright (C) 2009 William Bader <williambader@hotmail.com>
24
// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
25
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
26
// Copyright (C) 2010 Patrick Spendrin <ps_ml@gmx.de>
27
// Copyright (C) 2010 Jakub Wilk <ubanus@users.sf.net>
29
// To see a description of the changes please see the Changelog file that
30
// came with your tarball or type make ChangeLog if you are building from git
32
//========================================================================
36
#ifdef USE_GCC_PRAGMAS
37
#pragma implementation
50
# include <mbstring.h>
53
#include "goo/GooString.h"
54
#include "goo/GooList.h"
55
#include "goo/GooHash.h"
56
#include "goo/gfile.h"
58
#include "NameToCharCode.h"
59
#include "CharCodeToUnicode.h"
60
#include "UnicodeMap.h"
62
#include "BuiltinFontTables.h"
63
#include "FontEncodingTables.h"
65
# include "XpdfPluginAPI.h"
67
#include "GlobalParams.h"
71
# define strcasecmp stricmp
77
# define lockGlobalParams gLockMutex(&mutex)
78
# define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
79
# define lockCMapCache gLockMutex(&cMapCacheMutex)
80
# define unlockGlobalParams gUnlockMutex(&mutex)
81
# define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
82
# define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
84
# define lockGlobalParams
85
# define lockUnicodeMapCache
86
# define lockCMapCache
87
# define unlockGlobalParams
88
# define unlockUnicodeMapCache
89
# define unlockCMapCache
92
#ifndef FC_WEIGHT_BOOK
93
#define FC_WEIGHT_BOOK 75
96
#include "NameToUnicodeTable.h"
97
#include "UnicodeMapTables.h"
100
#ifdef ENABLE_PLUGINS
102
extern XpdfPluginVecTable xpdfPluginVecTable;
106
//------------------------------------------------------------------------
108
#define cidToUnicodeCacheSize 4
109
#define unicodeToUnicodeCacheSize 4
111
//------------------------------------------------------------------------
113
GlobalParams *globalParams = NULL;
115
//------------------------------------------------------------------------
117
//------------------------------------------------------------------------
119
DisplayFontParam::DisplayFontParam(GooString *nameA,
120
DisplayFontParamKind kindA) {
133
DisplayFontParam::~DisplayFontParam() {
149
#if ENABLE_RELOCATABLE && defined(_WIN32)
151
/* search for data relative to where we are installed */
153
static HMODULE hmodule;
157
DllMain (HINSTANCE hinstDLL,
163
case DLL_PROCESS_ATTACH:
173
get_poppler_datadir (void)
175
static char retval[MAX_PATH];
176
static int beenhere = 0;
183
if (!GetModuleFileName (hmodule, (CHAR *) retval, sizeof(retval) - 20))
184
return POPPLER_DATADIR;
186
p = _mbsrchr ((unsigned char *) retval, '\\');
188
p = _mbsrchr ((unsigned char *) retval, '\\');
190
if (stricmp ((const char *) (p+1), "bin") == 0)
193
strcat (retval, "\\share\\poppler");
200
#undef POPPLER_DATADIR
201
#define POPPLER_DATADIR get_poppler_datadir ()
207
//------------------------------------------------------------------------
209
//------------------------------------------------------------------------
211
class WinFontInfo: public DisplayFontParam {
216
static WinFontInfo *make(GooString *nameA, GBool boldA, GBool italicA,
217
HKEY regKey, char *winFontDir);
218
WinFontInfo(GooString *nameA, GBool boldA, GBool italicA,
219
GooString *fileNameA);
220
virtual ~WinFontInfo();
221
GBool equals(WinFontInfo *fi);
224
WinFontInfo *WinFontInfo::make(GooString *nameA, GBool boldA, GBool italicA,
225
HKEY regKey, char *winFontDir) {
227
GooString *fileNameA;
233
//----- find the font file
235
regName = nameA->copy();
237
regName->append(" Bold");
240
regName->append(" Italic");
242
regName->append(" (TrueType)");
244
if (RegQueryValueEx(regKey, regName->getCString(), NULL, NULL,
245
(LPBYTE)buf, &n) == ERROR_SUCCESS) {
246
fileNameA = new GooString(winFontDir);
247
fileNameA->append('\\')->append(buf);
255
//----- normalize the font name
257
while (i < nameA->getLength()) {
258
c = nameA->getChar(i);
259
if (c == ' ' || c == ',' || c == '-') {
266
return new WinFontInfo(nameA, boldA, italicA, fileNameA);
269
WinFontInfo::WinFontInfo(GooString *nameA, GBool boldA, GBool italicA,
270
GooString *fileNameA):
271
DisplayFontParam(nameA, displayFontTT)
275
tt.fileName = fileNameA;
278
WinFontInfo::~WinFontInfo() {
281
GBool WinFontInfo::equals(WinFontInfo *fi) {
282
return !name->cmp(fi->name) && bold == fi->bold && italic == fi->italic;
285
//------------------------------------------------------------------------
287
//------------------------------------------------------------------------
292
WinFontList(char *winFontDirA);
294
WinFontInfo *find(GooString *font);
298
void add(WinFontInfo *fi);
299
static int CALLBACK enumFunc1(CONST LOGFONT *font,
300
CONST TEXTMETRIC *metrics,
301
DWORD type, LPARAM data);
302
static int CALLBACK enumFunc2(CONST LOGFONT *font,
303
CONST TEXTMETRIC *metrics,
304
DWORD type, LPARAM data);
306
GooList *fonts; // [WinFontInfo]
307
HDC dc; // (only used during enumeration)
308
HKEY regKey; // (only used during enumeration)
309
char *winFontDir; // (only used during enumeration)
312
WinFontList::WinFontList(char *winFontDirA) {
313
OSVERSIONINFO version;
316
fonts = new GooList();
318
winFontDir = winFontDirA;
319
version.dwOSVersionInfoSize = sizeof(version);
320
GetVersionEx(&version);
321
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
322
path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
324
path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
326
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
327
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
328
®Key) == ERROR_SUCCESS) {
329
EnumFonts(dc, NULL, &WinFontList::enumFunc1, (LPARAM)this);
335
WinFontList::~WinFontList() {
336
deleteGooList(fonts, WinFontInfo);
339
void WinFontList::add(WinFontInfo *fi) {
342
for (i = 0; i < fonts->getLength(); ++i) {
343
if (((WinFontInfo *)fonts->get(i))->equals(fi)) {
351
WinFontInfo *WinFontList::find(GooString *font) {
360
// remove space, comma, dash chars
362
while (i < name->getLength()) {
363
c = name->getChar(i);
364
if (c == ' ' || c == ',' || c == '-') {
370
n = name->getLength();
372
// remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
373
if (!strcmp(name->getCString() + n - 2, "MT")) {
379
if (!strcmp(name->getCString() + n - 6, "Italic")) {
388
if (!strcmp(name->getCString() + n - 4, "Bold")) {
396
// remove trailing "MT" (FooMT-Bold, etc.)
397
if (!strcmp(name->getCString() + n - 2, "MT")) {
402
// remove trailing "PS"
403
if (!strcmp(name->getCString() + n - 2, "PS")) {
408
// search for the font
410
for (i = 0; i < fonts->getLength(); ++i) {
411
fi = (WinFontInfo *)fonts->get(i);
412
if (!fi->name->cmp(name) && fi->bold == bold && fi->italic == italic) {
422
int CALLBACK WinFontList::enumFunc1(CONST LOGFONT *font,
423
CONST TEXTMETRIC *metrics,
424
DWORD type, LPARAM data) {
425
WinFontList *fl = (WinFontList *)data;
427
EnumFonts(fl->dc, font->lfFaceName, &WinFontList::enumFunc2, (LPARAM)fl);
431
int CALLBACK WinFontList::enumFunc2(CONST LOGFONT *font,
432
CONST TEXTMETRIC *metrics,
433
DWORD type, LPARAM data) {
434
WinFontList *fl = (WinFontList *)data;
437
if (type & TRUETYPE_FONTTYPE) {
438
if ((fi = WinFontInfo::make(new GooString(font->lfFaceName),
439
font->lfWeight >= 600,
440
font->lfItalic ? gTrue : gFalse,
441
fl->regKey, fl->winFontDir))) {
450
//------------------------------------------------------------------------
452
//------------------------------------------------------------------------
454
PSFontParam::PSFontParam(GooString *pdfFontNameA, int wModeA,
455
GooString *psFontNameA, GooString *encodingA) {
456
pdfFontName = pdfFontNameA;
458
psFontName = psFontNameA;
459
encoding = encodingA;
462
PSFontParam::~PSFontParam() {
470
#ifdef ENABLE_PLUGINS
471
//------------------------------------------------------------------------
473
//------------------------------------------------------------------------
478
static Plugin *load(char *type, char *name);
484
Plugin(HMODULE libA);
492
Plugin *Plugin::load(char *type, char *name) {
495
XpdfPluginVecTable *vt;
496
XpdfBool (*xpdfInitPlugin)(void);
503
path = globalParams->getBaseDir();
504
appendToPath(path, "plugins");
505
appendToPath(path, type);
506
appendToPath(path, name);
509
path->append(".dll");
510
if (!(libA = LoadLibrary(path->getCString()))) {
511
error(-1, "Failed to load plugin '%s'",
515
if (!(vt = (XpdfPluginVecTable *)
516
GetProcAddress(libA, "xpdfPluginVecTable"))) {
517
error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
522
//~ need to deal with other extensions here
524
if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
525
error(-1, "Failed to load plugin '%s': %s",
526
path->getCString(), dlerror());
529
if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
530
error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
536
if (vt->version != xpdfPluginVecTable.version) {
537
error(-1, "Plugin '%s' is wrong version", path->getCString());
540
memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
543
if (!(xpdfInitPlugin = (XpdfBool (*)(void))
544
GetProcAddress(libA, "xpdfInitPlugin"))) {
545
error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
550
if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
551
error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
557
if (!(*xpdfInitPlugin)()) {
558
error(-1, "Initialization of plugin '%s' failed",
564
plugin = new Plugin(libA);
566
plugin = new Plugin(dlA);
584
Plugin::Plugin(HMODULE libA) {
588
Plugin::Plugin(void *dlA) {
594
void (*xpdfFreePlugin)(void);
597
if ((xpdfFreePlugin = (void (*)(void))
598
GetProcAddress(lib, "xpdfFreePlugin"))) {
603
if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
610
#endif // ENABLE_PLUGINS
612
//------------------------------------------------------------------------
614
//------------------------------------------------------------------------
616
GlobalParams::GlobalParams(const char *customPopplerDataDir)
617
: popplerDataDir(customPopplerDataDir)
624
gInitMutex(&unicodeMapCacheMutex);
625
gInitMutex(&cMapCacheMutex);
628
initBuiltinFontTables();
630
// scan the encoding in reverse because we want the lowest-numbered
631
// index for each char name ('space' is encoded twice)
632
macRomanReverseMap = new NameToCharCode();
633
for (i = 255; i >= 0; --i) {
634
if (macRomanEncoding[i]) {
635
macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
640
// baseDir will be set by a call to setBaseDir
641
baseDir = new GooString();
643
baseDir = appendToPath(getHomeDir(), ".xpdf");
645
nameToUnicode = new NameToCharCode();
646
cidToUnicodes = new GooHash(gTrue);
647
unicodeToUnicodes = new GooHash(gTrue);
648
residentUnicodeMaps = new GooHash();
649
unicodeMaps = new GooHash(gTrue);
650
cMapDirs = new GooHash(gTrue);
651
toUnicodeDirs = new GooList();
652
displayFonts = new GooHash();
653
psExpandSmaller = gFalse;
654
psShrinkLarger = gTrue;
657
psFonts = new GooHash();
658
psNamedFonts16 = new GooList();
659
psFonts16 = new GooList();
660
psEmbedType1 = gTrue;
661
psEmbedTrueType = gTrue;
662
psEmbedCIDPostScript = gTrue;
663
psEmbedCIDTrueType = gTrue;
664
psSubstFonts = gTrue;
668
textEncoding = new GooString("UTF-8");
676
textPageBreaks = gTrue;
677
textKeepTinyChars = gFalse;
678
fontDirs = new GooList();
679
enableFreeType = gTrue;
681
vectorAntialias = gTrue;
682
strokeAdjust = gTrue;
683
screenType = screenUnset;
685
screenDotRadius = -1;
687
screenBlackThreshold = 0.0;
688
screenWhiteThreshold = 1.0;
689
mapNumericCharNames = gTrue;
690
mapUnknownCharNames = gFalse;
691
printCommands = gFalse;
692
profileCommands = gFalse;
695
cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
696
unicodeToUnicodeCache =
697
new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
698
unicodeMapCache = new UnicodeMapCache();
699
cMapCache = new CMapCache();
702
baseFontsInitialized = gFalse;
706
#ifdef ENABLE_PLUGINS
707
plugins = new GooList();
708
securityHandlers = new GooList();
711
// set up the initial nameToUnicode table
712
for (i = 0; nameToUnicodeTab[i].name; ++i) {
713
nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
716
// set up the residentUnicodeMaps table
717
map = new UnicodeMap("Latin1", gFalse,
718
latin1UnicodeMapRanges, latin1UnicodeMapLen);
719
residentUnicodeMaps->add(map->getEncodingName(), map);
720
map = new UnicodeMap("ASCII7", gFalse,
721
ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
722
residentUnicodeMaps->add(map->getEncodingName(), map);
723
map = new UnicodeMap("Symbol", gFalse,
724
symbolUnicodeMapRanges, symbolUnicodeMapLen);
725
residentUnicodeMaps->add(map->getEncodingName(), map);
726
map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
727
zapfDingbatsUnicodeMapLen);
728
residentUnicodeMaps->add(map->getEncodingName(), map);
729
map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
730
residentUnicodeMaps->add(map->getEncodingName(), map);
731
map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
732
residentUnicodeMaps->add(map->getEncodingName(), map);
737
void GlobalParams::scanEncodingDirs() {
740
const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
742
// allocate buffer large enough to append "/nameToUnicode"
743
size_t bufSize = strlen(dataRoot) + strlen("/nameToUnicode") + 1;
744
char *dataPathBuffer = new char[bufSize];
746
snprintf(dataPathBuffer, bufSize, "%s/nameToUnicode", dataRoot);
747
dir = new GDir(dataPathBuffer, gTrue);
748
while (entry = dir->getNextEntry(), entry != NULL) {
749
if (!entry->isDir()) {
750
parseNameToUnicode(entry->getFullPath());
756
snprintf(dataPathBuffer, bufSize, "%s/cidToUnicode", dataRoot);
757
dir = new GDir(dataPathBuffer, gFalse);
758
while (entry = dir->getNextEntry(), entry != NULL) {
759
addCIDToUnicode(entry->getName(), entry->getFullPath());
764
snprintf(dataPathBuffer, bufSize, "%s/unicodeMap", dataRoot);
765
dir = new GDir(dataPathBuffer, gFalse);
766
while (entry = dir->getNextEntry(), entry != NULL) {
767
addUnicodeMap(entry->getName(), entry->getFullPath());
772
snprintf(dataPathBuffer, bufSize, "%s/cMap", dataRoot);
773
dir = new GDir(dataPathBuffer, gFalse);
774
while (entry = dir->getNextEntry(), entry != NULL) {
775
addCMapDir(entry->getName(), entry->getFullPath());
776
toUnicodeDirs->append(entry->getFullPath()->copy());
781
delete[] dataPathBuffer;
784
void GlobalParams::parseNameToUnicode(GooString *name) {
792
if (!(f = fopen(name->getCString(), "r"))) {
793
error(-1, "Couldn't open 'nameToUnicode' file '%s'",
798
while (getLine(buf, sizeof(buf), f)) {
799
tok1 = strtok_r(buf, " \t\r\n", &tokptr);
800
tok2 = strtok_r(NULL, " \t\r\n", &tokptr);
802
sscanf(tok1, "%x", &u);
803
nameToUnicode->add(tok2, u);
805
error(-1, "Bad line in 'nameToUnicode' file (%s:%d)",
806
name->getCString(), line);
813
void GlobalParams::addCIDToUnicode(GooString *collection,
814
GooString *fileName) {
817
if ((old = (GooString *)cidToUnicodes->remove(collection))) {
820
cidToUnicodes->add(collection->copy(), fileName->copy());
823
void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName)
827
if ((old = (GooString *)unicodeMaps->remove(encodingName))) {
830
unicodeMaps->add(encodingName->copy(), fileName->copy());
833
void GlobalParams::addCMapDir(GooString *collection, GooString *dir) {
836
if (!(list = (GooList *)cMapDirs->lookup(collection))) {
837
list = new GooList();
838
cMapDirs->add(collection->copy(), list);
840
list->append(dir->copy());
843
GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
844
if (!strcmp(token, "yes")) {
846
} else if (!strcmp(token, "no")) {
854
GlobalParams::~GlobalParams() {
855
freeBuiltinFontTables();
857
delete macRomanReverseMap;
860
delete nameToUnicode;
861
deleteGooHash(cidToUnicodes, GooString);
862
deleteGooHash(unicodeToUnicodes, GooString);
863
deleteGooHash(residentUnicodeMaps, UnicodeMap);
864
deleteGooHash(unicodeMaps, GooString);
865
deleteGooList(toUnicodeDirs, GooString);
866
deleteGooHash(displayFonts, DisplayFontParam);
870
deleteGooHash(psFonts, PSFontParam);
871
deleteGooList(psNamedFonts16, PSFontParam);
872
deleteGooList(psFonts16, PSFontParam);
874
deleteGooList(fontDirs, GooString);
878
cMapDirs->startIter(&iter);
880
while (cMapDirs->getNext(&iter, &key, &val)) {
881
GooList* list = (GooList*)val;
882
deleteGooList(list, GooString);
886
delete cidToUnicodeCache;
887
delete unicodeToUnicodeCache;
888
delete unicodeMapCache;
891
#ifdef ENABLE_PLUGINS
892
delete securityHandlers;
893
deleteGooList(plugins, Plugin);
897
gDestroyMutex(&mutex);
898
gDestroyMutex(&unicodeMapCacheMutex);
899
gDestroyMutex(&cMapCacheMutex);
903
//------------------------------------------------------------------------
905
void GlobalParams::setBaseDir(char *dir) {
907
baseDir = new GooString(dir);
910
//------------------------------------------------------------------------
912
//------------------------------------------------------------------------
914
CharCode GlobalParams::getMacRomanCharCode(char *charName) {
915
// no need to lock - macRomanReverseMap is constant
916
return macRomanReverseMap->lookup(charName);
919
GooString *GlobalParams::getBaseDir() {
928
Unicode GlobalParams::mapNameToUnicode(char *charName) {
929
// no need to lock - nameToUnicode is constant
930
return nameToUnicode->lookup(charName);
933
UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) {
937
map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
945
FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) {
950
if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) {
951
f = fopen(fileName->getCString(), "r");
959
FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) {
967
if (!(list = (GooList *)cMapDirs->lookup(collection))) {
971
for (i = 0; i < list->getLength(); ++i) {
972
dir = (GooString *)list->get(i);
973
fileName = appendToPath(dir->copy(), cMapName->getCString());
974
f = fopen(fileName->getCString(), "r");
985
FILE *GlobalParams::findToUnicodeFile(GooString *name) {
986
GooString *dir, *fileName;
991
for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
992
dir = (GooString *)toUnicodeDirs->get(i);
993
fileName = appendToPath(dir->copy(), name->getCString());
994
f = fopen(fileName->getCString(), "r");
1005
#if WITH_FONTCONFIGURATION_FONTCONFIG
1006
static GBool findModifier(const char *name, const char *modifier, const char **start)
1013
match = strstr(name, modifier);
1015
if (*start == NULL || match < *start)
1024
static FcPattern *buildFcPattern(GfxFont *font)
1030
bool deleteFamily = false;
1031
char *family, *name, *lang, *modifiers;
1035
// this is all heuristics will be overwritten if font had proper info
1036
name = font->getName()->getCString();
1038
modifiers = strchr (name, ',');
1039
if (modifiers == NULL)
1040
modifiers = strchr (name, '-');
1042
// remove the - from the names, for some reason, Fontconfig does not
1043
// understand "MS-Mincho" but does with "MS Mincho"
1044
int len = strlen(name);
1045
for (int i = 0; i < len; i++)
1046
name[i] = (name[i] == '-' ? ' ' : name[i]);
1049
findModifier(modifiers, "Regular", &start);
1050
findModifier(modifiers, "Roman", &start);
1052
if (findModifier(modifiers, "Oblique", &start))
1053
slant = FC_SLANT_OBLIQUE;
1054
if (findModifier(modifiers, "Italic", &start))
1055
slant = FC_SLANT_ITALIC;
1056
if (findModifier(modifiers, "Bold", &start))
1057
weight = FC_WEIGHT_BOLD;
1058
if (findModifier(modifiers, "Light", &start))
1059
weight = FC_WEIGHT_LIGHT;
1060
if (findModifier(modifiers, "Condensed", &start))
1061
width = FC_WIDTH_CONDENSED;
1064
// There have been "modifiers" in the name, crop them to obtain
1066
family = new char[len+1];
1067
strcpy(family, name);
1068
int pos = (modifiers - name);
1070
deleteFamily = true;
1077
if (font->isFixedWidth())
1080
weight = FC_WEIGHT_BOLD;
1081
if (font->isItalic())
1082
slant = FC_SLANT_ITALIC;
1084
// if the FontDescriptor specified a family name use it
1085
if (font->getFamily()) {
1088
deleteFamily = false;
1090
family = font->getFamily()->getCString();
1093
// if the FontDescriptor specified a weight use it
1094
switch (font -> getWeight())
1096
case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break;
1097
case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break;
1098
case GfxFont::W300: weight = FC_WEIGHT_BOOK; break;
1099
case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break;
1100
case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break;
1101
case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break;
1102
case GfxFont::W700: weight = FC_WEIGHT_BOLD; break;
1103
case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break;
1104
case GfxFont::W900: weight = FC_WEIGHT_BLACK; break;
1108
// if the FontDescriptor specified a width use it
1109
switch (font -> getStretch())
1111
case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break;
1112
case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break;
1113
case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break;
1114
case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break;
1115
case GfxFont::Normal: width = FC_WIDTH_NORMAL; break;
1116
case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break;
1117
case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break;
1118
case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break;
1119
case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break;
1123
// find the language we want the font to support
1124
if (font->isCIDFont())
1126
GooString *collection = ((GfxCIDFont *)font)->getCollection();
1129
if (strcmp(collection->getCString(), "Adobe-GB1") == 0)
1130
lang = "zh-cn"; // Simplified Chinese
1131
else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0)
1132
lang = "zh-tw"; // Traditional Chinese
1133
else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0)
1134
lang = "ja"; // Japanese
1135
else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0)
1136
lang = "ja"; // Japanese
1137
else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0)
1138
lang = "ko"; // Korean
1139
else if (strcmp(collection->getCString(), "Adobe-UCS") == 0)
1141
else if (strcmp(collection->getCString(), "Adobe-Identity") == 0)
1145
error(-1, "Unknown CID font collection, please report to poppler bugzilla.");
1153
p = FcPatternBuild(NULL,
1154
FC_FAMILY, FcTypeString, family,
1155
FC_LANG, FcTypeString, lang,
1157
if (slant != -1) FcPatternAddInteger(p, FC_SLANT, slant);
1158
if (weight != -1) FcPatternAddInteger(p, FC_WEIGHT, weight);
1159
if (width != -1) FcPatternAddInteger(p, FC_WIDTH, width);
1160
if (spacing != -1) FcPatternAddInteger(p, FC_SPACING, spacing);
1168
/* if you can't or don't want to use Fontconfig, you need to implement
1169
this function for your platform. For Windows, it's in GlobalParamsWin.cc
1171
#if WITH_FONTCONFIGURATION_FONTCONFIG
1172
DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
1173
DisplayFontParam *dfp;
1176
GooString *fontName = font->getName();
1177
if (!fontName) return NULL;
1188
p = buildFcPattern(font);
1192
FcConfigSubstitute(NULL, p, FcMatchPattern);
1193
FcDefaultSubstitute(p);
1194
set = FcFontSort(NULL, p, FcFalse, NULL, &res);
1197
for (i = 0; i < set->nfont; ++i)
1199
res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
1200
if (res != FcResultMatch || !s)
1202
ext = strrchr((char*)s,'.');
1205
if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4))
1207
dfp = new DisplayFontParam(fontName->copy(), displayFontTT);
1208
dfp->tt.fileName = new GooString((char*)s);
1209
FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex));
1211
else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4))
1213
dfp = new DisplayFontParam(fontName->copy(), displayFontT1);
1214
dfp->t1.fileName = new GooString((char*)s);
1221
FcFontSetDestroy(set);
1225
FcPatternDestroy(p);
1231
#if WITH_FONTCONFIGURATION_WIN32
1232
#include "GlobalParamsWin.cc"
1235
GBool GlobalParams::getPSExpandSmaller() {
1239
f = psExpandSmaller;
1244
GBool GlobalParams::getPSShrinkLarger() {
1253
GBool GlobalParams::getPSCenter() {
1262
PSLevel GlobalParams::getPSLevel() {
1271
PSFontParam *GlobalParams::getPSFont(GooString *fontName) {
1275
p = (PSFontParam *)psFonts->lookup(fontName);
1280
PSFontParam *GlobalParams::getPSFont16(GooString *fontName,
1281
GooString *collection, int wMode) {
1288
for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1289
p = (PSFontParam *)psNamedFonts16->get(i);
1290
if (!p->pdfFontName->cmp(fontName) &&
1291
p->wMode == wMode) {
1297
if (!p && collection) {
1298
for (i = 0; i < psFonts16->getLength(); ++i) {
1299
p = (PSFontParam *)psFonts16->get(i);
1300
if (!p->pdfFontName->cmp(collection) &&
1301
p->wMode == wMode) {
1311
GBool GlobalParams::getPSEmbedType1() {
1320
GBool GlobalParams::getPSEmbedTrueType() {
1324
e = psEmbedTrueType;
1329
GBool GlobalParams::getPSEmbedCIDPostScript() {
1333
e = psEmbedCIDPostScript;
1338
GBool GlobalParams::getPSEmbedCIDTrueType() {
1342
e = psEmbedCIDTrueType;
1347
GBool GlobalParams::getPSSubstFonts() {
1356
GBool GlobalParams::getPSPreload() {
1360
preload = psPreload;
1365
GBool GlobalParams::getPSOPI() {
1374
GBool GlobalParams::getPSASCIIHex() {
1383
GooString *GlobalParams::getTextEncodingName() {
1387
s = textEncoding->copy();
1392
EndOfLineKind GlobalParams::getTextEOL() {
1401
GBool GlobalParams::getTextPageBreaks() {
1405
pageBreaks = textPageBreaks;
1410
GBool GlobalParams::getTextKeepTinyChars() {
1414
tiny = textKeepTinyChars;
1419
GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) {
1420
GooString *dir, *fileName;
1426
for (i = 0; i < fontDirs->getLength(); ++i) {
1427
dir = (GooString *)fontDirs->get(i);
1428
for (ext = exts; *ext; ++ext) {
1429
fileName = appendToPath(dir->copy(), fontName->getCString());
1430
fileName->append(*ext);
1431
if ((f = fopen(fileName->getCString(), "rb"))) {
1443
GBool GlobalParams::getEnableFreeType() {
1453
GBool GlobalParams::getAntialias() {
1462
GBool GlobalParams::getVectorAntialias() {
1466
f = vectorAntialias;
1471
GBool GlobalParams::getStrokeAdjust() {
1480
ScreenType GlobalParams::getScreenType() {
1489
int GlobalParams::getScreenSize() {
1498
int GlobalParams::getScreenDotRadius() {
1502
r = screenDotRadius;
1507
double GlobalParams::getScreenGamma() {
1511
gamma = screenGamma;
1516
double GlobalParams::getScreenBlackThreshold() {
1520
thresh = screenBlackThreshold;
1525
double GlobalParams::getScreenWhiteThreshold() {
1529
thresh = screenWhiteThreshold;
1534
GBool GlobalParams::getMapNumericCharNames() {
1538
map = mapNumericCharNames;
1543
GBool GlobalParams::getMapUnknownCharNames() {
1547
map = mapUnknownCharNames;
1552
GBool GlobalParams::getPrintCommands() {
1561
GBool GlobalParams::getProfileCommands() {
1565
p = profileCommands;
1570
GBool GlobalParams::getErrQuiet() {
1571
// no locking -- this function may get called from inside a locked
1576
CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
1577
GooString *fileName;
1578
CharCodeToUnicode *ctu;
1581
if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1582
if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) &&
1583
(ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1584
cidToUnicodeCache->add(ctu);
1591
CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) {
1594
unicodeToUnicodes->startIter(&iter);
1595
GooString *fileName = NULL;
1596
GooString *fontPattern;
1598
while (!fileName && unicodeToUnicodes->getNext(&iter, &fontPattern, &val)) {
1599
if (strstr(fontName->getCString(), fontPattern->getCString())) {
1600
unicodeToUnicodes->killIter(&iter);
1601
fileName = (GooString*)val;
1604
CharCodeToUnicode *ctu = NULL;
1606
ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName);
1608
ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName);
1610
unicodeToUnicodeCache->add(ctu);
1617
UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
1618
return getUnicodeMap2(encodingName);
1621
UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
1624
if (!(map = getResidentUnicodeMap(encodingName))) {
1625
lockUnicodeMapCache;
1626
map = unicodeMapCache->getUnicodeMap(encodingName);
1627
unlockUnicodeMapCache;
1632
CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName, Stream *stream) {
1636
cMap = cMapCache->getCMap(collection, cMapName, stream);
1641
UnicodeMap *GlobalParams::getTextEncoding() {
1642
return getUnicodeMap2(textEncoding);
1645
GooList *GlobalParams::getEncodingNames()
1647
GooList *result = new GooList;
1651
residentUnicodeMaps->startIter(&iter);
1652
while (residentUnicodeMaps->getNext(&iter, &key, &val)) {
1653
result->append(key);
1655
residentUnicodeMaps->killIter(&iter);
1656
unicodeMaps->startIter(&iter);
1657
while (unicodeMaps->getNext(&iter, &key, &val)) {
1658
result->append(key);
1660
unicodeMaps->killIter(&iter);
1664
//------------------------------------------------------------------------
1665
// functions to set parameters
1666
//------------------------------------------------------------------------
1668
void GlobalParams::setPSExpandSmaller(GBool expand) {
1670
psExpandSmaller = expand;
1674
void GlobalParams::setPSShrinkLarger(GBool shrink) {
1676
psShrinkLarger = shrink;
1680
void GlobalParams::setPSCenter(GBool center) {
1686
void GlobalParams::setPSLevel(PSLevel level) {
1692
void GlobalParams::setPSEmbedType1(GBool embed) {
1694
psEmbedType1 = embed;
1698
void GlobalParams::setPSEmbedTrueType(GBool embed) {
1700
psEmbedTrueType = embed;
1704
void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1706
psEmbedCIDPostScript = embed;
1710
void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1712
psEmbedCIDTrueType = embed;
1716
void GlobalParams::setPSSubstFonts(GBool substFonts) {
1718
psSubstFonts = substFonts;
1722
void GlobalParams::setPSPreload(GBool preload) {
1724
psPreload = preload;
1728
void GlobalParams::setPSOPI(GBool opi) {
1734
void GlobalParams::setPSASCIIHex(GBool hex) {
1740
void GlobalParams::setTextEncoding(char *encodingName) {
1742
delete textEncoding;
1743
textEncoding = new GooString(encodingName);
1747
GBool GlobalParams::setTextEOL(char *s) {
1749
if (!strcmp(s, "unix")) {
1751
} else if (!strcmp(s, "dos")) {
1753
} else if (!strcmp(s, "mac")) {
1763
void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1765
textPageBreaks = pageBreaks;
1769
void GlobalParams::setTextKeepTinyChars(GBool keep) {
1771
textKeepTinyChars = keep;
1775
GBool GlobalParams::setEnableFreeType(char *s) {
1779
ok = parseYesNo2(s, &enableFreeType);
1785
GBool GlobalParams::setAntialias(char *s) {
1789
ok = parseYesNo2(s, &antialias);
1794
GBool GlobalParams::setVectorAntialias(char *s) {
1798
ok = parseYesNo2(s, &vectorAntialias);
1803
void GlobalParams::setStrokeAdjust(GBool adjust)
1806
strokeAdjust = adjust;
1810
void GlobalParams::setScreenType(ScreenType st)
1817
void GlobalParams::setScreenSize(int size)
1824
void GlobalParams::setScreenDotRadius(int radius)
1827
screenDotRadius = radius;
1831
void GlobalParams::setScreenGamma(double gamma)
1834
screenGamma = gamma;
1838
void GlobalParams::setScreenBlackThreshold(double blackThreshold)
1841
screenBlackThreshold = blackThreshold;
1845
void GlobalParams::setScreenWhiteThreshold(double whiteThreshold)
1848
screenWhiteThreshold = whiteThreshold;
1852
void GlobalParams::setMapNumericCharNames(GBool map) {
1854
mapNumericCharNames = map;
1858
void GlobalParams::setMapUnknownCharNames(GBool map) {
1860
mapUnknownCharNames = map;
1864
void GlobalParams::setPrintCommands(GBool printCommandsA) {
1866
printCommands = printCommandsA;
1870
void GlobalParams::setProfileCommands(GBool profileCommandsA) {
1872
profileCommands = profileCommandsA;
1876
void GlobalParams::setErrQuiet(GBool errQuietA) {
1878
errQuiet = errQuietA;
1882
void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1883
#ifdef ENABLE_PLUGINS
1885
securityHandlers->append(handler);
1890
XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1891
#ifdef ENABLE_PLUGINS
1892
XpdfSecurityHandler *hdlr;
1896
for (i = 0; i < securityHandlers->getLength(); ++i) {
1897
hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1898
if (!strcasecmp(hdlr->name, name)) {
1905
if (!loadPlugin("security", name)) {
1908
deleteGooList(keyBindings, KeyBinding);
1911
for (i = 0; i < securityHandlers->getLength(); ++i) {
1912
hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1913
if (!strcmp(hdlr->name, name)) {
1926
#ifdef ENABLE_PLUGINS
1927
//------------------------------------------------------------------------
1929
//------------------------------------------------------------------------
1931
GBool GlobalParams::loadPlugin(char *type, char *name) {
1934
if (!(plugin = Plugin::load(type, name))) {
1938
plugins->append(plugin);
1943
#endif // ENABLE_PLUGINS