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-2009 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>
26
// To see a description of the changes please see the Changelog file that
27
// came with your tarball or type make ChangeLog if you are building from git
29
//========================================================================
33
#ifdef USE_GCC_PRAGMAS
34
#pragma implementation
49
#include "goo/GooString.h"
50
#include "goo/GooList.h"
51
#include "goo/GooHash.h"
52
#include "goo/gfile.h"
54
#include "NameToCharCode.h"
55
#include "CharCodeToUnicode.h"
56
#include "UnicodeMap.h"
58
#include "BuiltinFontTables.h"
59
#include "FontEncodingTables.h"
61
# include "XpdfPluginAPI.h"
63
#include "GlobalParams.h"
67
# define strcasecmp stricmp
71
# define lockGlobalParams gLockMutex(&mutex)
72
# define lockUnicodeMapCache gLockMutex(&unicodeMapCacheMutex)
73
# define lockCMapCache gLockMutex(&cMapCacheMutex)
74
# define unlockGlobalParams gUnlockMutex(&mutex)
75
# define unlockUnicodeMapCache gUnlockMutex(&unicodeMapCacheMutex)
76
# define unlockCMapCache gUnlockMutex(&cMapCacheMutex)
78
# define lockGlobalParams
79
# define lockUnicodeMapCache
80
# define lockCMapCache
81
# define unlockGlobalParams
82
# define unlockUnicodeMapCache
83
# define unlockCMapCache
86
#ifndef FC_WEIGHT_BOOK
87
#define FC_WEIGHT_BOOK 75
90
#include "NameToUnicodeTable.h"
91
#include "UnicodeMapTables.h"
96
extern XpdfPluginVecTable xpdfPluginVecTable;
100
//------------------------------------------------------------------------
102
#define cidToUnicodeCacheSize 4
103
#define unicodeToUnicodeCacheSize 4
105
//------------------------------------------------------------------------
107
GlobalParams *globalParams = NULL;
109
//------------------------------------------------------------------------
111
//------------------------------------------------------------------------
113
DisplayFontParam::DisplayFontParam(GooString *nameA,
114
DisplayFontParamKind kindA) {
127
DisplayFontParam::~DisplayFontParam() {
143
#ifndef PDF_PARSER_ONLY
146
//------------------------------------------------------------------------
148
//------------------------------------------------------------------------
150
class WinFontInfo: public DisplayFontParam {
155
static WinFontInfo *make(GooString *nameA, GBool boldA, GBool italicA,
156
HKEY regKey, char *winFontDir);
157
WinFontInfo(GooString *nameA, GBool boldA, GBool italicA,
158
GooString *fileNameA);
159
virtual ~WinFontInfo();
160
GBool equals(WinFontInfo *fi);
163
WinFontInfo *WinFontInfo::make(GooString *nameA, GBool boldA, GBool italicA,
164
HKEY regKey, char *winFontDir) {
166
GooString *fileNameA;
172
//----- find the font file
174
regName = nameA->copy();
176
regName->append(" Bold");
179
regName->append(" Italic");
181
regName->append(" (TrueType)");
183
if (RegQueryValueEx(regKey, regName->getCString(), NULL, NULL,
184
(LPBYTE)buf, &n) == ERROR_SUCCESS) {
185
fileNameA = new GooString(winFontDir);
186
fileNameA->append('\\')->append(buf);
194
//----- normalize the font name
196
while (i < nameA->getLength()) {
197
c = nameA->getChar(i);
198
if (c == ' ' || c == ',' || c == '-') {
205
return new WinFontInfo(nameA, boldA, italicA, fileNameA);
208
WinFontInfo::WinFontInfo(GooString *nameA, GBool boldA, GBool italicA,
209
GooString *fileNameA):
210
DisplayFontParam(nameA, displayFontTT)
214
tt.fileName = fileNameA;
217
WinFontInfo::~WinFontInfo() {
220
GBool WinFontInfo::equals(WinFontInfo *fi) {
221
return !name->cmp(fi->name) && bold == fi->bold && italic == fi->italic;
224
//------------------------------------------------------------------------
226
//------------------------------------------------------------------------
231
WinFontList(char *winFontDirA);
233
WinFontInfo *find(GooString *font);
237
void add(WinFontInfo *fi);
238
static int CALLBACK enumFunc1(CONST LOGFONT *font,
239
CONST TEXTMETRIC *metrics,
240
DWORD type, LPARAM data);
241
static int CALLBACK enumFunc2(CONST LOGFONT *font,
242
CONST TEXTMETRIC *metrics,
243
DWORD type, LPARAM data);
245
GooList *fonts; // [WinFontInfo]
246
HDC dc; // (only used during enumeration)
247
HKEY regKey; // (only used during enumeration)
248
char *winFontDir; // (only used during enumeration)
251
WinFontList::WinFontList(char *winFontDirA) {
252
OSVERSIONINFO version;
255
fonts = new GooList();
257
winFontDir = winFontDirA;
258
version.dwOSVersionInfoSize = sizeof(version);
259
GetVersionEx(&version);
260
if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
261
path = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts\\";
263
path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts\\";
265
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0,
266
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
267
®Key) == ERROR_SUCCESS) {
268
EnumFonts(dc, NULL, &WinFontList::enumFunc1, (LPARAM)this);
274
WinFontList::~WinFontList() {
275
deleteGooList(fonts, WinFontInfo);
278
void WinFontList::add(WinFontInfo *fi) {
281
for (i = 0; i < fonts->getLength(); ++i) {
282
if (((WinFontInfo *)fonts->get(i))->equals(fi)) {
290
WinFontInfo *WinFontList::find(GooString *font) {
299
// remove space, comma, dash chars
301
while (i < name->getLength()) {
302
c = name->getChar(i);
303
if (c == ' ' || c == ',' || c == '-') {
309
n = name->getLength();
311
// remove trailing "MT" (Foo-MT, Foo-BoldMT, etc.)
312
if (!strcmp(name->getCString() + n - 2, "MT")) {
318
if (!strcmp(name->getCString() + n - 6, "Italic")) {
327
if (!strcmp(name->getCString() + n - 4, "Bold")) {
335
// remove trailing "MT" (FooMT-Bold, etc.)
336
if (!strcmp(name->getCString() + n - 2, "MT")) {
341
// remove trailing "PS"
342
if (!strcmp(name->getCString() + n - 2, "PS")) {
347
// search for the font
349
for (i = 0; i < fonts->getLength(); ++i) {
350
fi = (WinFontInfo *)fonts->get(i);
351
if (!fi->name->cmp(name) && fi->bold == bold && fi->italic == italic) {
361
int CALLBACK WinFontList::enumFunc1(CONST LOGFONT *font,
362
CONST TEXTMETRIC *metrics,
363
DWORD type, LPARAM data) {
364
WinFontList *fl = (WinFontList *)data;
366
EnumFonts(fl->dc, font->lfFaceName, &WinFontList::enumFunc2, (LPARAM)fl);
370
int CALLBACK WinFontList::enumFunc2(CONST LOGFONT *font,
371
CONST TEXTMETRIC *metrics,
372
DWORD type, LPARAM data) {
373
WinFontList *fl = (WinFontList *)data;
376
if (type & TRUETYPE_FONTTYPE) {
377
if ((fi = WinFontInfo::make(new GooString(font->lfFaceName),
378
font->lfWeight >= 600,
379
font->lfItalic ? gTrue : gFalse,
380
fl->regKey, fl->winFontDir))) {
388
#endif // PDF_PARSER_ONLY
390
//------------------------------------------------------------------------
392
//------------------------------------------------------------------------
394
PSFontParam::PSFontParam(GooString *pdfFontNameA, int wModeA,
395
GooString *psFontNameA, GooString *encodingA) {
396
pdfFontName = pdfFontNameA;
398
psFontName = psFontNameA;
399
encoding = encodingA;
402
PSFontParam::~PSFontParam() {
410
#ifdef ENABLE_PLUGINS
411
//------------------------------------------------------------------------
413
//------------------------------------------------------------------------
418
static Plugin *load(char *type, char *name);
424
Plugin(HMODULE libA);
432
Plugin *Plugin::load(char *type, char *name) {
435
XpdfPluginVecTable *vt;
436
XpdfBool (*xpdfInitPlugin)(void);
443
path = globalParams->getBaseDir();
444
appendToPath(path, "plugins");
445
appendToPath(path, type);
446
appendToPath(path, name);
449
path->append(".dll");
450
if (!(libA = LoadLibrary(path->getCString()))) {
451
error(-1, "Failed to load plugin '%s'",
455
if (!(vt = (XpdfPluginVecTable *)
456
GetProcAddress(libA, "xpdfPluginVecTable"))) {
457
error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
462
//~ need to deal with other extensions here
464
if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
465
error(-1, "Failed to load plugin '%s': %s",
466
path->getCString(), dlerror());
469
if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
470
error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
476
if (vt->version != xpdfPluginVecTable.version) {
477
error(-1, "Plugin '%s' is wrong version", path->getCString());
480
memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
483
if (!(xpdfInitPlugin = (XpdfBool (*)(void))
484
GetProcAddress(libA, "xpdfInitPlugin"))) {
485
error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
490
if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
491
error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
497
if (!(*xpdfInitPlugin)()) {
498
error(-1, "Initialization of plugin '%s' failed",
504
plugin = new Plugin(libA);
506
plugin = new Plugin(dlA);
524
Plugin::Plugin(HMODULE libA) {
528
Plugin::Plugin(void *dlA) {
534
void (*xpdfFreePlugin)(void);
537
if ((xpdfFreePlugin = (void (*)(void))
538
GetProcAddress(lib, "xpdfFreePlugin"))) {
543
if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
550
#endif // ENABLE_PLUGINS
552
//------------------------------------------------------------------------
554
//------------------------------------------------------------------------
556
GlobalParams::GlobalParams(const char *customPopplerDataDir)
557
: popplerDataDir(customPopplerDataDir)
562
#if !defined(PDF_PARSER_ONLY) && !defined(_MSC_VER)
564
FCcfg = FcConfigGetCurrent();
569
gInitMutex(&unicodeMapCacheMutex);
570
gInitMutex(&cMapCacheMutex);
573
initBuiltinFontTables();
575
// scan the encoding in reverse because we want the lowest-numbered
576
// index for each char name ('space' is encoded twice)
577
macRomanReverseMap = new NameToCharCode();
578
for (i = 255; i >= 0; --i) {
579
if (macRomanEncoding[i]) {
580
macRomanReverseMap->add(macRomanEncoding[i], (CharCode)i);
585
// baseDir will be set by a call to setBaseDir
586
baseDir = new GooString();
588
baseDir = appendToPath(getHomeDir(), ".xpdf");
590
nameToUnicode = new NameToCharCode();
591
cidToUnicodes = new GooHash(gTrue);
592
unicodeToUnicodes = new GooHash(gTrue);
593
residentUnicodeMaps = new GooHash();
594
unicodeMaps = new GooHash(gTrue);
595
cMapDirs = new GooHash(gTrue);
596
toUnicodeDirs = new GooList();
597
displayFonts = new GooHash();
598
psExpandSmaller = gFalse;
599
psShrinkLarger = gTrue;
602
psFonts = new GooHash();
603
psNamedFonts16 = new GooList();
604
psFonts16 = new GooList();
605
psEmbedType1 = gTrue;
606
psEmbedTrueType = gTrue;
607
psEmbedCIDPostScript = gTrue;
608
psEmbedCIDTrueType = gTrue;
609
psSubstFonts = gTrue;
613
textEncoding = new GooString("UTF-8");
621
textPageBreaks = gTrue;
622
textKeepTinyChars = gFalse;
623
fontDirs = new GooList();
624
enableFreeType = gTrue;
626
vectorAntialias = gTrue;
627
strokeAdjust = gTrue;
628
screenType = screenUnset;
630
screenDotRadius = -1;
632
screenBlackThreshold = 0.0;
633
screenWhiteThreshold = 1.0;
634
mapNumericCharNames = gTrue;
635
mapUnknownCharNames = gFalse;
636
printCommands = gFalse;
637
profileCommands = gFalse;
640
cidToUnicodeCache = new CharCodeToUnicodeCache(cidToUnicodeCacheSize);
641
unicodeToUnicodeCache =
642
new CharCodeToUnicodeCache(unicodeToUnicodeCacheSize);
643
unicodeMapCache = new UnicodeMapCache();
644
cMapCache = new CMapCache();
647
baseFontsInitialized = gFalse;
651
#ifdef ENABLE_PLUGINS
652
plugins = new GooList();
653
securityHandlers = new GooList();
656
// set up the initial nameToUnicode table
657
for (i = 0; nameToUnicodeTab[i].name; ++i) {
658
nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
661
// set up the residentUnicodeMaps table
662
map = new UnicodeMap("Latin1", gFalse,
663
latin1UnicodeMapRanges, latin1UnicodeMapLen);
664
residentUnicodeMaps->add(map->getEncodingName(), map);
665
map = new UnicodeMap("ASCII7", gFalse,
666
ascii7UnicodeMapRanges, ascii7UnicodeMapLen);
667
residentUnicodeMaps->add(map->getEncodingName(), map);
668
map = new UnicodeMap("Symbol", gFalse,
669
symbolUnicodeMapRanges, symbolUnicodeMapLen);
670
residentUnicodeMaps->add(map->getEncodingName(), map);
671
map = new UnicodeMap("ZapfDingbats", gFalse, zapfDingbatsUnicodeMapRanges,
672
zapfDingbatsUnicodeMapLen);
673
residentUnicodeMaps->add(map->getEncodingName(), map);
674
map = new UnicodeMap("UTF-8", gTrue, &mapUTF8);
675
residentUnicodeMaps->add(map->getEncodingName(), map);
676
map = new UnicodeMap("UCS-2", gTrue, &mapUCS2);
677
residentUnicodeMaps->add(map->getEncodingName(), map);
682
void GlobalParams::scanEncodingDirs() {
685
const char *dataRoot = popplerDataDir ? popplerDataDir : POPPLER_DATADIR;
687
// allocate buffer large enough to append "/nameToUnicode"
688
size_t bufSize = strlen(dataRoot) + strlen("/nameToUnicode") + 1;
689
char *dataPathBuffer = new char[bufSize];
691
snprintf(dataPathBuffer, bufSize, "%s/nameToUnicode", dataRoot);
692
dir = new GDir(dataPathBuffer, gTrue);
693
while (entry = dir->getNextEntry(), entry != NULL) {
694
if (!entry->isDir()) {
695
parseNameToUnicode(entry->getFullPath());
701
snprintf(dataPathBuffer, bufSize, "%s/cidToUnicode", dataRoot);
702
dir = new GDir(dataPathBuffer, gFalse);
703
while (entry = dir->getNextEntry(), entry != NULL) {
704
addCIDToUnicode(entry->getName(), entry->getFullPath());
709
snprintf(dataPathBuffer, bufSize, "%s/unicodeMap", dataRoot);
710
dir = new GDir(dataPathBuffer, gFalse);
711
while (entry = dir->getNextEntry(), entry != NULL) {
712
addUnicodeMap(entry->getName(), entry->getFullPath());
717
snprintf(dataPathBuffer, bufSize, "%s/cMap", dataRoot);
718
dir = new GDir(dataPathBuffer, gFalse);
719
while (entry = dir->getNextEntry(), entry != NULL) {
720
addCMapDir(entry->getName(), entry->getFullPath());
721
toUnicodeDirs->append(entry->getFullPath()->copy());
726
delete[] dataPathBuffer;
729
void GlobalParams::parseNameToUnicode(GooString *name) {
736
if (!(f = fopen(name->getCString(), "r"))) {
737
error(-1, "Couldn't open 'nameToUnicode' file '%s'",
742
while (getLine(buf, sizeof(buf), f)) {
743
tok1 = strtok(buf, " \t\r\n");
744
tok2 = strtok(NULL, " \t\r\n");
746
sscanf(tok1, "%x", &u);
747
nameToUnicode->add(tok2, u);
749
error(-1, "Bad line in 'nameToUnicode' file (%s:%d)",
750
name->getCString(), line);
757
void GlobalParams::addCIDToUnicode(GooString *collection,
758
GooString *fileName) {
761
if ((old = (GooString *)cidToUnicodes->remove(collection))) {
764
cidToUnicodes->add(collection->copy(), fileName->copy());
767
void GlobalParams::addUnicodeMap(GooString *encodingName, GooString *fileName)
771
if ((old = (GooString *)unicodeMaps->remove(encodingName))) {
774
unicodeMaps->add(encodingName->copy(), fileName->copy());
777
void GlobalParams::addCMapDir(GooString *collection, GooString *dir) {
780
if (!(list = (GooList *)cMapDirs->lookup(collection))) {
781
list = new GooList();
782
cMapDirs->add(collection->copy(), list);
784
list->append(dir->copy());
787
GBool GlobalParams::parseYesNo2(char *token, GBool *flag) {
788
if (!strcmp(token, "yes")) {
790
} else if (!strcmp(token, "no")) {
798
GlobalParams::~GlobalParams() {
799
freeBuiltinFontTables();
801
delete macRomanReverseMap;
804
delete nameToUnicode;
805
deleteGooHash(cidToUnicodes, GooString);
806
deleteGooHash(unicodeToUnicodes, GooString);
807
deleteGooHash(residentUnicodeMaps, UnicodeMap);
808
deleteGooHash(unicodeMaps, GooString);
809
deleteGooList(toUnicodeDirs, GooString);
810
deleteGooHash(displayFonts, DisplayFontParam);
814
deleteGooHash(psFonts, PSFontParam);
815
deleteGooList(psNamedFonts16, PSFontParam);
816
deleteGooList(psFonts16, PSFontParam);
818
deleteGooList(fontDirs, GooString);
822
cMapDirs->startIter(&iter);
824
while (cMapDirs->getNext(&iter, &key, &val)) {
825
GooList* list = (GooList*)val;
826
deleteGooList(list, GooString);
830
delete cidToUnicodeCache;
831
delete unicodeToUnicodeCache;
832
delete unicodeMapCache;
835
#ifdef ENABLE_PLUGINS
836
delete securityHandlers;
837
deleteGooList(plugins, Plugin);
841
gDestroyMutex(&mutex);
842
gDestroyMutex(&unicodeMapCacheMutex);
843
gDestroyMutex(&cMapCacheMutex);
847
//------------------------------------------------------------------------
849
void GlobalParams::setBaseDir(char *dir) {
851
baseDir = new GooString(dir);
854
//------------------------------------------------------------------------
856
//------------------------------------------------------------------------
858
CharCode GlobalParams::getMacRomanCharCode(char *charName) {
859
// no need to lock - macRomanReverseMap is constant
860
return macRomanReverseMap->lookup(charName);
863
GooString *GlobalParams::getBaseDir() {
872
Unicode GlobalParams::mapNameToUnicode(char *charName) {
873
// no need to lock - nameToUnicode is constant
874
return nameToUnicode->lookup(charName);
877
UnicodeMap *GlobalParams::getResidentUnicodeMap(GooString *encodingName) {
881
map = (UnicodeMap *)residentUnicodeMaps->lookup(encodingName);
889
FILE *GlobalParams::getUnicodeMapFile(GooString *encodingName) {
894
if ((fileName = (GooString *)unicodeMaps->lookup(encodingName))) {
895
f = fopen(fileName->getCString(), "r");
903
FILE *GlobalParams::findCMapFile(GooString *collection, GooString *cMapName) {
911
if (!(list = (GooList *)cMapDirs->lookup(collection))) {
915
for (i = 0; i < list->getLength(); ++i) {
916
dir = (GooString *)list->get(i);
917
fileName = appendToPath(dir->copy(), cMapName->getCString());
918
f = fopen(fileName->getCString(), "r");
929
FILE *GlobalParams::findToUnicodeFile(GooString *name) {
930
GooString *dir, *fileName;
935
for (i = 0; i < toUnicodeDirs->getLength(); ++i) {
936
dir = (GooString *)toUnicodeDirs->get(i);
937
fileName = appendToPath(dir->copy(), name->getCString());
938
f = fopen(fileName->getCString(), "r");
949
#if !defined(PDF_PARSER_ONLY) && !defined(_MSC_VER)
950
static GBool findModifier(const char *name, const char *modifier, const char **start)
957
match = strstr(name, modifier);
959
if (*start == NULL || match < *start)
968
static FcPattern *buildFcPattern(GfxFont *font)
974
bool deleteFamily = false;
975
char *family, *name, *lang, *modifiers;
979
// this is all heuristics will be overwritten if font had proper info
980
name = font->getName()->getCString();
982
modifiers = strchr (name, ',');
983
if (modifiers == NULL)
984
modifiers = strchr (name, '-');
986
// remove the - from the names, for some reason, Fontconfig does not
987
// understand "MS-Mincho" but does with "MS Mincho"
988
int len = strlen(name);
989
for (int i = 0; i < len; i++)
990
name[i] = (name[i] == '-' ? ' ' : name[i]);
993
findModifier(modifiers, "Regular", &start);
994
findModifier(modifiers, "Roman", &start);
996
if (findModifier(modifiers, "Oblique", &start))
997
slant = FC_SLANT_OBLIQUE;
998
if (findModifier(modifiers, "Italic", &start))
999
slant = FC_SLANT_ITALIC;
1000
if (findModifier(modifiers, "Bold", &start))
1001
weight = FC_WEIGHT_BOLD;
1002
if (findModifier(modifiers, "Light", &start))
1003
weight = FC_WEIGHT_LIGHT;
1004
if (findModifier(modifiers, "Condensed", &start))
1005
width = FC_WIDTH_CONDENSED;
1008
// There have been "modifiers" in the name, crop them to obtain
1010
family = new char[len+1];
1011
strcpy(family, name);
1012
int pos = (modifiers - name);
1014
deleteFamily = true;
1021
if (font->isFixedWidth())
1024
weight = FC_WEIGHT_BOLD;
1025
if (font->isItalic())
1026
slant = FC_SLANT_ITALIC;
1028
// if the FontDescriptor specified a family name use it
1029
if (font->getFamily()) {
1032
deleteFamily = false;
1034
family = font->getFamily()->getCString();
1037
// if the FontDescriptor specified a weight use it
1038
switch (font -> getWeight())
1040
case GfxFont::W100: weight = FC_WEIGHT_EXTRALIGHT; break;
1041
case GfxFont::W200: weight = FC_WEIGHT_LIGHT; break;
1042
case GfxFont::W300: weight = FC_WEIGHT_BOOK; break;
1043
case GfxFont::W400: weight = FC_WEIGHT_NORMAL; break;
1044
case GfxFont::W500: weight = FC_WEIGHT_MEDIUM; break;
1045
case GfxFont::W600: weight = FC_WEIGHT_DEMIBOLD; break;
1046
case GfxFont::W700: weight = FC_WEIGHT_BOLD; break;
1047
case GfxFont::W800: weight = FC_WEIGHT_EXTRABOLD; break;
1048
case GfxFont::W900: weight = FC_WEIGHT_BLACK; break;
1052
// if the FontDescriptor specified a width use it
1053
switch (font -> getStretch())
1055
case GfxFont::UltraCondensed: width = FC_WIDTH_ULTRACONDENSED; break;
1056
case GfxFont::ExtraCondensed: width = FC_WIDTH_EXTRACONDENSED; break;
1057
case GfxFont::Condensed: width = FC_WIDTH_CONDENSED; break;
1058
case GfxFont::SemiCondensed: width = FC_WIDTH_SEMICONDENSED; break;
1059
case GfxFont::Normal: width = FC_WIDTH_NORMAL; break;
1060
case GfxFont::SemiExpanded: width = FC_WIDTH_SEMIEXPANDED; break;
1061
case GfxFont::Expanded: width = FC_WIDTH_EXPANDED; break;
1062
case GfxFont::ExtraExpanded: width = FC_WIDTH_EXTRAEXPANDED; break;
1063
case GfxFont::UltraExpanded: width = FC_WIDTH_ULTRAEXPANDED; break;
1067
// find the language we want the font to support
1068
if (font->isCIDFont())
1070
GooString *collection = ((GfxCIDFont *)font)->getCollection();
1073
if (strcmp(collection->getCString(), "Adobe-GB1") == 0)
1074
lang = "zh-cn"; // Simplified Chinese
1075
else if (strcmp(collection->getCString(), "Adobe-CNS1") == 0)
1076
lang = "zh-tw"; // Traditional Chinese
1077
else if (strcmp(collection->getCString(), "Adobe-Japan1") == 0)
1078
lang = "ja"; // Japanese
1079
else if (strcmp(collection->getCString(), "Adobe-Japan2") == 0)
1080
lang = "ja"; // Japanese
1081
else if (strcmp(collection->getCString(), "Adobe-Korea1") == 0)
1082
lang = "ko"; // Korean
1083
else if (strcmp(collection->getCString(), "Adobe-UCS") == 0)
1085
else if (strcmp(collection->getCString(), "Adobe-Identity") == 0)
1089
error(-1, "Unknown CID font collection, please report to poppler bugzilla.");
1097
p = FcPatternBuild(NULL,
1098
FC_FAMILY, FcTypeString, family,
1099
FC_LANG, FcTypeString, lang,
1101
if (slant != -1) FcPatternAddInteger(p, FC_SLANT, slant);
1102
if (weight != -1) FcPatternAddInteger(p, FC_WEIGHT, weight);
1103
if (width != -1) FcPatternAddInteger(p, FC_WIDTH, width);
1104
if (spacing != -1) FcPatternAddInteger(p, FC_SPACING, spacing);
1112
/* if you can't or don't want to use Fontconfig, you need to implement
1113
this function for your platform. For Windows, it's in GlobalParamsWin.cc
1115
#ifdef PDF_PARSER_ONLY
1116
DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
1117
return (DisplayFontParam * )NULL;
1121
DisplayFontParam *GlobalParams::getDisplayFont(GfxFont *font) {
1122
DisplayFontParam *dfp;
1125
GooString *fontName = font->getName();
1126
if (!fontName) return NULL;
1137
p = buildFcPattern(font);
1141
FcConfigSubstitute(FCcfg, p, FcMatchPattern);
1142
FcDefaultSubstitute(p);
1143
set = FcFontSort(FCcfg, p, FcFalse, NULL, &res);
1146
for (i = 0; i < set->nfont; ++i)
1148
res = FcPatternGetString(set->fonts[i], FC_FILE, 0, &s);
1149
if (res != FcResultMatch || !s)
1151
ext = strrchr((char*)s,'.');
1154
if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4))
1156
dfp = new DisplayFontParam(fontName->copy(), displayFontTT);
1157
dfp->tt.fileName = new GooString((char*)s);
1158
FcPatternGetInteger(set->fonts[i], FC_INDEX, 0, &(dfp->tt.faceIndex));
1160
else if (!strncasecmp(ext,".pfa",4) || !strncasecmp(ext,".pfb",4))
1162
dfp = new DisplayFontParam(fontName->copy(), displayFontT1);
1163
dfp->t1.fileName = new GooString((char*)s);
1170
FcFontSetDestroy(set);
1174
FcPatternDestroy(p);
1182
GBool GlobalParams::getPSExpandSmaller() {
1186
f = psExpandSmaller;
1191
GBool GlobalParams::getPSShrinkLarger() {
1200
GBool GlobalParams::getPSCenter() {
1209
PSLevel GlobalParams::getPSLevel() {
1218
PSFontParam *GlobalParams::getPSFont(GooString *fontName) {
1222
p = (PSFontParam *)psFonts->lookup(fontName);
1227
PSFontParam *GlobalParams::getPSFont16(GooString *fontName,
1228
GooString *collection, int wMode) {
1235
for (i = 0; i < psNamedFonts16->getLength(); ++i) {
1236
p = (PSFontParam *)psNamedFonts16->get(i);
1237
if (!p->pdfFontName->cmp(fontName) &&
1238
p->wMode == wMode) {
1244
if (!p && collection) {
1245
for (i = 0; i < psFonts16->getLength(); ++i) {
1246
p = (PSFontParam *)psFonts16->get(i);
1247
if (!p->pdfFontName->cmp(collection) &&
1248
p->wMode == wMode) {
1258
GBool GlobalParams::getPSEmbedType1() {
1267
GBool GlobalParams::getPSEmbedTrueType() {
1271
e = psEmbedTrueType;
1276
GBool GlobalParams::getPSEmbedCIDPostScript() {
1280
e = psEmbedCIDPostScript;
1285
GBool GlobalParams::getPSEmbedCIDTrueType() {
1289
e = psEmbedCIDTrueType;
1294
GBool GlobalParams::getPSSubstFonts() {
1303
GBool GlobalParams::getPSPreload() {
1307
preload = psPreload;
1312
GBool GlobalParams::getPSOPI() {
1321
GBool GlobalParams::getPSASCIIHex() {
1330
GooString *GlobalParams::getTextEncodingName() {
1334
s = textEncoding->copy();
1339
EndOfLineKind GlobalParams::getTextEOL() {
1348
GBool GlobalParams::getTextPageBreaks() {
1352
pageBreaks = textPageBreaks;
1357
GBool GlobalParams::getTextKeepTinyChars() {
1361
tiny = textKeepTinyChars;
1366
GooString *GlobalParams::findFontFile(GooString *fontName, char **exts) {
1367
GooString *dir, *fileName;
1373
for (i = 0; i < fontDirs->getLength(); ++i) {
1374
dir = (GooString *)fontDirs->get(i);
1375
for (ext = exts; *ext; ++ext) {
1376
fileName = appendToPath(dir->copy(), fontName->getCString());
1377
fileName->append(*ext);
1378
if ((f = fopen(fileName->getCString(), "rb"))) {
1390
GBool GlobalParams::getEnableFreeType() {
1400
GBool GlobalParams::getAntialias() {
1409
GBool GlobalParams::getVectorAntialias() {
1413
f = vectorAntialias;
1418
GBool GlobalParams::getStrokeAdjust() {
1427
ScreenType GlobalParams::getScreenType() {
1436
int GlobalParams::getScreenSize() {
1445
int GlobalParams::getScreenDotRadius() {
1449
r = screenDotRadius;
1454
double GlobalParams::getScreenGamma() {
1458
gamma = screenGamma;
1463
double GlobalParams::getScreenBlackThreshold() {
1467
thresh = screenBlackThreshold;
1472
double GlobalParams::getScreenWhiteThreshold() {
1476
thresh = screenWhiteThreshold;
1481
GBool GlobalParams::getMapNumericCharNames() {
1485
map = mapNumericCharNames;
1490
GBool GlobalParams::getMapUnknownCharNames() {
1494
map = mapUnknownCharNames;
1499
GBool GlobalParams::getPrintCommands() {
1508
GBool GlobalParams::getProfileCommands() {
1512
p = profileCommands;
1517
GBool GlobalParams::getErrQuiet() {
1518
// no locking -- this function may get called from inside a locked
1523
CharCodeToUnicode *GlobalParams::getCIDToUnicode(GooString *collection) {
1524
GooString *fileName;
1525
CharCodeToUnicode *ctu;
1528
if (!(ctu = cidToUnicodeCache->getCharCodeToUnicode(collection))) {
1529
if ((fileName = (GooString *)cidToUnicodes->lookup(collection)) &&
1530
(ctu = CharCodeToUnicode::parseCIDToUnicode(fileName, collection))) {
1531
cidToUnicodeCache->add(ctu);
1538
CharCodeToUnicode *GlobalParams::getUnicodeToUnicode(GooString *fontName) {
1541
unicodeToUnicodes->startIter(&iter);
1542
GooString *fileName = NULL;
1543
GooString *fontPattern;
1545
while (!fileName && unicodeToUnicodes->getNext(&iter, &fontPattern, &val)) {
1546
if (strstr(fontName->getCString(), fontPattern->getCString())) {
1547
unicodeToUnicodes->killIter(&iter);
1548
fileName = (GooString*)val;
1551
CharCodeToUnicode *ctu = NULL;
1553
ctu = unicodeToUnicodeCache->getCharCodeToUnicode(fileName);
1555
ctu = CharCodeToUnicode::parseUnicodeToUnicode(fileName);
1557
unicodeToUnicodeCache->add(ctu);
1564
UnicodeMap *GlobalParams::getUnicodeMap(GooString *encodingName) {
1565
return getUnicodeMap2(encodingName);
1568
UnicodeMap *GlobalParams::getUnicodeMap2(GooString *encodingName) {
1571
if (!(map = getResidentUnicodeMap(encodingName))) {
1572
lockUnicodeMapCache;
1573
map = unicodeMapCache->getUnicodeMap(encodingName);
1574
unlockUnicodeMapCache;
1579
CMap *GlobalParams::getCMap(GooString *collection, GooString *cMapName, Stream *stream) {
1583
cMap = cMapCache->getCMap(collection, cMapName, stream);
1588
UnicodeMap *GlobalParams::getTextEncoding() {
1589
return getUnicodeMap2(textEncoding);
1592
GooList *GlobalParams::getEncodingNames()
1594
GooList *result = new GooList;
1598
residentUnicodeMaps->startIter(&iter);
1599
while (residentUnicodeMaps->getNext(&iter, &key, &val)) {
1600
result->append(key);
1602
residentUnicodeMaps->killIter(&iter);
1603
unicodeMaps->startIter(&iter);
1604
while (unicodeMaps->getNext(&iter, &key, &val)) {
1605
result->append(key);
1607
unicodeMaps->killIter(&iter);
1611
//------------------------------------------------------------------------
1612
// functions to set parameters
1613
//------------------------------------------------------------------------
1615
void GlobalParams::setPSExpandSmaller(GBool expand) {
1617
psExpandSmaller = expand;
1621
void GlobalParams::setPSShrinkLarger(GBool shrink) {
1623
psShrinkLarger = shrink;
1627
void GlobalParams::setPSCenter(GBool center) {
1633
void GlobalParams::setPSLevel(PSLevel level) {
1639
void GlobalParams::setPSEmbedType1(GBool embed) {
1641
psEmbedType1 = embed;
1645
void GlobalParams::setPSEmbedTrueType(GBool embed) {
1647
psEmbedTrueType = embed;
1651
void GlobalParams::setPSEmbedCIDPostScript(GBool embed) {
1653
psEmbedCIDPostScript = embed;
1657
void GlobalParams::setPSEmbedCIDTrueType(GBool embed) {
1659
psEmbedCIDTrueType = embed;
1663
void GlobalParams::setPSSubstFonts(GBool substFonts) {
1665
psSubstFonts = substFonts;
1669
void GlobalParams::setPSPreload(GBool preload) {
1671
psPreload = preload;
1675
void GlobalParams::setPSOPI(GBool opi) {
1681
void GlobalParams::setPSASCIIHex(GBool hex) {
1687
void GlobalParams::setTextEncoding(char *encodingName) {
1689
delete textEncoding;
1690
textEncoding = new GooString(encodingName);
1694
GBool GlobalParams::setTextEOL(char *s) {
1696
if (!strcmp(s, "unix")) {
1698
} else if (!strcmp(s, "dos")) {
1700
} else if (!strcmp(s, "mac")) {
1710
void GlobalParams::setTextPageBreaks(GBool pageBreaks) {
1712
textPageBreaks = pageBreaks;
1716
void GlobalParams::setTextKeepTinyChars(GBool keep) {
1718
textKeepTinyChars = keep;
1722
GBool GlobalParams::setEnableFreeType(char *s) {
1726
ok = parseYesNo2(s, &enableFreeType);
1732
GBool GlobalParams::setAntialias(char *s) {
1736
ok = parseYesNo2(s, &antialias);
1741
GBool GlobalParams::setVectorAntialias(char *s) {
1745
ok = parseYesNo2(s, &vectorAntialias);
1750
void GlobalParams::setStrokeAdjust(GBool adjust)
1753
strokeAdjust = adjust;
1757
void GlobalParams::setScreenType(ScreenType st)
1764
void GlobalParams::setScreenSize(int size)
1771
void GlobalParams::setScreenDotRadius(int radius)
1774
screenDotRadius = radius;
1778
void GlobalParams::setScreenGamma(double gamma)
1781
screenGamma = gamma;
1785
void GlobalParams::setScreenBlackThreshold(double blackThreshold)
1788
screenBlackThreshold = blackThreshold;
1792
void GlobalParams::setScreenWhiteThreshold(double whiteThreshold)
1795
screenWhiteThreshold = whiteThreshold;
1799
void GlobalParams::setMapNumericCharNames(GBool map) {
1801
mapNumericCharNames = map;
1805
void GlobalParams::setMapUnknownCharNames(GBool map) {
1807
mapUnknownCharNames = map;
1811
void GlobalParams::setPrintCommands(GBool printCommandsA) {
1813
printCommands = printCommandsA;
1817
void GlobalParams::setProfileCommands(GBool profileCommandsA) {
1819
profileCommands = profileCommandsA;
1823
void GlobalParams::setErrQuiet(GBool errQuietA) {
1825
errQuiet = errQuietA;
1829
void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
1830
#ifdef ENABLE_PLUGINS
1832
securityHandlers->append(handler);
1837
XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
1838
#ifdef ENABLE_PLUGINS
1839
XpdfSecurityHandler *hdlr;
1843
for (i = 0; i < securityHandlers->getLength(); ++i) {
1844
hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1845
if (!strcasecmp(hdlr->name, name)) {
1852
if (!loadPlugin("security", name)) {
1855
deleteGooList(keyBindings, KeyBinding);
1858
for (i = 0; i < securityHandlers->getLength(); ++i) {
1859
hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
1860
if (!strcmp(hdlr->name, name)) {
1873
#ifdef ENABLE_PLUGINS
1874
//------------------------------------------------------------------------
1876
//------------------------------------------------------------------------
1878
GBool GlobalParams::loadPlugin(char *type, char *name) {
1881
if (!(plugin = Plugin::load(type, name))) {
1885
plugins->append(plugin);
1890
#endif // ENABLE_PLUGINS