1
///////////////////////////////////////////////////////////////////////////////
2
// Name: pdffontmanager.cpp
4
// Author: Ulrich Telle
8
// Copyright: (c) Ulrich Telle
9
// Licence: wxWindows licence
10
///////////////////////////////////////////////////////////////////////////////
12
/// \file pdffontmanager.cpp Implementation of the wxPdfFontManager class
14
// For compilers that support precompilation, includes <wx.h>.
15
#include <wx/wxprec.h>
27
#include <wx/dynarray.h>
28
#include <wx/filefn.h>
29
#include <wx/filename.h>
30
#include <wx/filesys.h>
32
#include <wx/thread.h>
33
#include <wx/xml/xml.h>
35
#include "wx/pdfencoding.h"
36
#include "wx/pdffontmanager.h"
37
#include "wx/pdffontdata.h"
38
#include "wx/pdffontdatacore.h"
39
#include "wx/pdffontdataopentype.h"
40
#include "wx/pdffontdatatruetype.h"
41
#include "wx/pdffontdatatype0.h"
42
#include "wx/pdffontdatatype1.h"
43
#include "wx/pdffontparsertruetype.h"
44
#include "wx/pdffontparsertype1.h"
46
#if defined(__WXMSW__)
47
#include <wx/msw/registry.h>
48
// #include "wx/msw/private.h"
49
#elif defined(__WXGTK20__)
50
// TODO: Would testing for __WXGTK__ be sufficient?
51
#include <fontconfig/fontconfig.h>
53
// Define some FontConfig symbols if they are missing
54
#ifndef FC_WEIGHT_BOOK
55
#define FC_WEIGHT_BOOK 75
58
#define FC_FULLNAME "fullname"
60
#elif defined(__WXMAC__)
61
#include "wx/pdffontmacosx.h"
67
// Include core font data
68
#include "pdfcorefontdata.inc"
70
// Include CJK font data
71
#include "pdfcjkfontdata.inc"
73
// wxPdfFontManager is a singleton.
74
// Critical sections are used to make access to it thread safe if necessary.
76
static wxCriticalSection gs_csFontManager;
77
static wxCriticalSection gs_csFontData;
80
// To make reference counting and encoding conversion thread safe
81
// some methods of the wxFontData class use the critical section
82
// associated with the font manager.
84
wxMBConv* wxPdfFontData::ms_winEncoding = NULL;
87
wxPdfFontData::GetWinEncodingConv()
90
wxCriticalSectionLocker locker(gs_csFontData);
92
if (ms_winEncoding == NULL)
94
static wxCSConv winEncoding(wxFONTENCODING_CP1252);
95
ms_winEncoding = &winEncoding;
97
return ms_winEncoding;
101
wxPdfFontData::IncrementRefCount()
104
wxCriticalSectionLocker locker(gs_csFontData);
112
wxPdfFontData::DecrementRefCount()
115
wxCriticalSectionLocker locker(gs_csFontData);
120
class wxPdfFontListEntry
123
wxPdfFontListEntry(wxPdfFontData* fontData) : m_fontData(fontData)
125
if (m_fontData != NULL)
127
m_fontData->IncrementRefCount();
131
~wxPdfFontListEntry()
133
if (m_fontData != NULL && m_fontData->DecrementRefCount() == 0)
139
wxPdfFontListEntry(const wxPdfFontListEntry& p) : m_fontData(p.m_fontData)
141
if (m_fontData != NULL)
143
m_fontData->IncrementRefCount();
147
wxPdfFontListEntry& operator=(const wxPdfFontListEntry& p)
148
{ // DO NOT CHANGE THE ORDER OF THESE STATEMENTS!
149
// (This order properly handles self-assignment)
150
// (This order also properly handles recursion)
151
wxPdfFontData* const prevFontData = m_fontData;
152
m_fontData = p.m_fontData;
153
if (m_fontData != NULL)
155
m_fontData->IncrementRefCount();
157
if (prevFontData != NULL && prevFontData->DecrementRefCount() == 0)
164
wxPdfFontData* GetFontData() const
169
wxPdfFontData* operator->()
174
wxPdfFontData& operator*()
180
wxPdfFontData* m_fontData;
183
// --- Encoding checker
185
// Include codepage data
186
#include "pdfcodepagedata.inc"
188
// Class representing a font encoding checker
189
class WXDLLIMPEXP_PDFDOC wxPdfCodepageChecker : public wxPdfEncodingChecker
192
/// Default constructor
193
wxPdfCodepageChecker(const wxString& encoding, int tableSize, const wxUniRangeDesc* cpTable)
195
m_encoding = encoding;
196
m_tableSize = tableSize;
201
virtual ~wxPdfCodepageChecker()
205
/// Get the name of the encoding
207
* \return the name of the encoding
209
virtual bool IsIncluded(wxUint32 unicode) const
211
bool isIncluded = false;
212
if (unicode < 0x00010000)
214
unsigned short code = unicode & 0x0000ffff;
216
int hb = m_tableSize - 1;
217
int mid = (lb + hb) / 2;
220
if (code >= m_cpTable[mid].uni1)
230
isIncluded = (code <= m_cpTable[mid].uni2);
236
int m_tableSize; ///< Size of the mapping table
237
const wxUniRangeDesc* m_cpTable; ///< Table for code page
240
// Class representing a font encoding checker
241
class WXDLLIMPEXP_PDFDOC wxPdfCjkChecker : public wxPdfEncodingChecker
244
/// Default constructor
245
wxPdfCjkChecker(const wxString& encoding, const unsigned char* cjkTable)
247
m_encoding = encoding;
248
m_cjkTable = cjkTable;
252
virtual ~wxPdfCjkChecker()
256
/// Check whether a given Unicode character is included in the encoding
258
* \return TRUE if the Unicode character is included, FALSE otherwise
260
virtual bool IsIncluded(wxUint32 unicode) const
262
bool isIncluded = false;
263
if (unicode < 0x00010000)
265
int charPos = unicode / 8;
266
unsigned char bitPos = 1 << (7 - (unicode % 8));
267
isIncluded = ((m_cjkTable[charPos] & bitPos) != 0);
273
const unsigned char* m_cjkTable; ///< Table for CJK encodings
276
// --- Font Manager Base
278
WX_DEFINE_ARRAY_PTR(wxPdfFontListEntry*, wxPdfFontList);
280
/// Hashmap class for mapping font families
281
WX_DECLARE_STRING_HASH_MAP(wxArrayInt, wxPdfFontFamilyMap);
283
/// Hashmap class for mapping font names to font list entries
284
WX_DECLARE_STRING_HASH_MAP(int, wxPdfFontNameMap);
286
/// Hashmap class for mapping alias names to family names
287
WX_DECLARE_STRING_HASH_MAP(wxString, wxPdfFontAliasMap);
289
/// Hashmap class for mapping encodings
290
WX_DECLARE_STRING_HASH_MAP(wxPdfEncoding*, wxPdfEncodingMap);
292
/// Hashmap class for mapping encoding checkers
293
WX_DECLARE_STRING_HASH_MAP(wxPdfEncodingChecker*, wxPdfEncodingCheckerMap);
295
class wxPdfFontManagerBase
298
/// Default constructor
299
wxPdfFontManagerBase();
301
/// Default destructor
302
~wxPdfFontManagerBase();
304
void AddSearchPath(const wxString& path);
306
void AddSearchPath(const wxArrayString& pathArray);
308
bool SetDefaultEmbed(bool embed);
310
bool GetDefaultEmbed();
312
bool SetDefaultSubset(bool subset);
314
bool GetDefaultSubset();
316
wxPdfFont RegisterFont(const wxString& fontFileName, const wxString& aliasName = wxEmptyString, int fontIndex = 0);
319
wxPdfFont RegisterFont(const wxFont& font, const wxString& aliasName = wxEmptyString);
321
int RegisterFontCollection(const wxString& fontCollectionFileName);
324
bool RegisterFontCJK(const wxString& family);
327
int RegisterSystemFonts();
329
int RegisterFontDirectory(const wxString& directory, bool recursive = false);
332
wxPdfFont GetFont(const wxString& fontName, int fontStyle = wxPDF_FONTSTYLE_REGULAR) const;
334
wxPdfFont GetFont(const wxString& fontName, const wxString& fontStyle) const;
336
wxPdfFont GetFont(size_t fontIndex) const;
338
size_t GetFontCount() const;
340
bool InitializeFontData(const wxPdfFont& font);
342
bool RegisterEncoding(const wxPdfEncoding& encoding);
344
const wxPdfEncoding* GetEncoding(const wxString& encodingName);
346
bool FindFile(const wxString& fileName, wxString& fullFileName) const;
348
static wxString ConvertStyleToString(int fontStyle);
351
void InitializeCoreFonts();
354
void InitializeCjkFonts();
357
void InitializeEncodingChecker();
359
bool RegisterEncoding(const wxString& encoding);
361
void SetFontBaseEncoding(wxPdfFontData* fontData);
363
bool RegisterFontCJK(const wxString& fontFileName, const wxString& fontStyle, const wxString& alias);
365
wxPdfFontData* LoadFontFromXML(const wxString& fontFileName);
367
bool IsRegistered(wxPdfFontData* fontData);
369
bool AddFont(wxPdfFontData* fontData);
371
bool AddFont(wxPdfFontData* fontData, wxPdfFont& font);
373
wxPathList m_searchPaths;
375
wxPdfFontNameMap m_fontNameMap;
376
wxPdfFontFamilyMap m_fontFamilyMap;
377
wxPdfFontAliasMap m_fontAliasMap;
378
wxPdfFontList m_fontList;
381
bool m_defaultSubset;
383
wxPdfEncodingMap* m_encodingMap;
384
wxPdfEncodingCheckerMap* m_encodingCheckerMap;
387
#include "wxmemdbg.h"
389
wxPdfFontManagerBase::wxPdfFontManagerBase()
391
m_defaultEmbed = true;
392
m_defaultSubset = true;
394
// Since InitializeCoreFonts uses locking, too, it is necessary
395
// to create a new context, thus locking only the access of the
396
// search path member.
398
wxCriticalSectionLocker locker(gs_csFontManager);
400
m_searchPaths.Add(wxT("fonts"));
401
m_searchPaths.AddEnvList(wxT("WXPDF_FONTPATH"));
403
m_encodingMap = new wxPdfEncodingMap();
404
m_encodingCheckerMap = new wxPdfEncodingCheckerMap();
405
InitializeEncodingChecker();
406
InitializeCoreFonts();
408
InitializeCjkFonts();
412
wxPdfFontManagerBase::~wxPdfFontManagerBase()
415
wxCriticalSectionLocker locker(gs_csFontManager);
417
m_fontNameMap.clear();
418
m_fontFamilyMap.clear();
419
m_fontAliasMap.clear();
420
size_t n = m_fontList.GetCount();
422
for (j = 0; j < n; ++j)
424
delete m_fontList[j];
428
wxPdfEncodingMap::iterator encoding;
429
for (encoding = m_encodingMap->begin();
430
encoding != m_encodingMap->end(); ++encoding)
432
wxPdfEncoding* foundEncoding = encoding->second;
433
delete foundEncoding;
435
delete m_encodingMap;
437
wxPdfEncodingCheckerMap::iterator checker;
438
for (checker = m_encodingCheckerMap->begin();
439
checker != m_encodingCheckerMap->end(); ++checker)
441
delete checker->second;
443
delete m_encodingCheckerMap;
447
wxPdfFontManagerBase::AddSearchPath(const wxString& path)
450
wxCriticalSectionLocker locker(gs_csFontManager);
452
m_searchPaths.Add(path);
456
wxPdfFontManagerBase::AddSearchPath(const wxArrayString& pathArray)
459
wxCriticalSectionLocker locker(gs_csFontManager);
461
m_searchPaths.Add(pathArray);
465
wxPdfFontManagerBase::FindFile(const wxString& fileName, wxString& fullFileName) const
468
wxFileName myFileName(fileName);
469
fullFileName = wxEmptyString;
470
if (myFileName.IsOk())
472
if (myFileName.IsRelative())
474
// Check whether the file is relative to the current working directory
475
if (!(myFileName.MakeAbsolute() && myFileName.FileExists()))
477
// File not found, search in given search paths
479
wxCriticalSectionLocker locker(gs_csFontManager);
481
wxString foundFileName = m_searchPaths.FindAbsoluteValidPath(fileName);
482
if (!foundFileName.IsEmpty())
484
myFileName.Assign(foundFileName);
488
if (myFileName.FileExists() && myFileName.IsFileReadable())
490
// File exists and is accessible
491
fullFileName = myFileName.GetFullPath();
496
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::FindFile: ")) +
497
wxString::Format(_("File '%s' does not exist."), fileName.c_str()));
502
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::FindFile: ")) +
503
wxString::Format(_("File name '%s' is invalid."), fileName.c_str()));
509
wxPdfFontManagerBase::SetDefaultEmbed(bool embed)
512
wxCriticalSectionLocker locker(gs_csFontManager);
514
bool previous = m_defaultEmbed;
515
m_defaultEmbed = embed;
520
wxPdfFontManagerBase::GetDefaultEmbed()
523
wxCriticalSectionLocker locker(gs_csFontManager);
525
return m_defaultEmbed;
529
wxPdfFontManagerBase::SetDefaultSubset(bool subset)
532
wxCriticalSectionLocker locker(gs_csFontManager);
534
bool previous = m_defaultSubset;
535
m_defaultSubset = subset;
540
wxPdfFontManagerBase::GetDefaultSubset()
543
wxCriticalSectionLocker locker(gs_csFontManager);
545
return m_defaultSubset;
549
wxPdfFontManagerBase::RegisterFont(const wxString& fontFileName, const wxString& aliasName, int fontIndex)
552
wxUnusedVar(fontIndex);
555
wxString fullFontFileName;
556
if (FindFile(fontFileName, fullFontFileName))
558
wxFileName fileName(fullFontFileName);
559
wxString ext = fileName.GetExt().Lower();
560
if (ext.IsSameAs(wxT("ttf")) || ext.IsSameAs(wxT("otf")) || ext.IsSameAs(wxT("ttc")))
563
// TrueType font, OpenType font, or TrueType collection
564
wxPdfFontParserTrueType fontParser;
565
wxPdfFontData* fontData = fontParser.IdentifyFont(fileName.GetFullPath(), fontIndex);
566
if (fontData != NULL)
568
fontData->SetAlias(aliasName);
569
if (!AddFont(fontData, font))
572
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
573
wxString::Format(_("Font file '%s' already registered."), fontFileName.c_str()));
577
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
578
wxString::Format(_("Format of font file '%s' not supported."), fontFileName.c_str()));
581
else if (/* ext.IsSameAs(wxT("pfa")) || */ ext.IsSameAs(wxT("pfb")) || ext.IsEmpty())
583
// TODO: allow Type1 fonts in PFA format (this requires encoding the binary section)
586
wxPdfFontParserType1 fontParser;
587
wxPdfFontData* fontData = fontParser.IdentifyFont(fileName.GetFullPath(), fontIndex);
588
if (fontData != NULL)
590
fontData->SetAlias(aliasName);
591
SetFontBaseEncoding(fontData);
592
if (!AddFont(fontData, font))
595
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
596
wxString::Format(_("Font file '%s' already registered."), fontFileName.c_str()));
600
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
601
wxString::Format(_("Format of font file '%s' not supported."), fontFileName.c_str()));
604
else if (ext.IsSameAs(wxT("xml")))
606
// wxPdfDocument font description file
607
wxPdfFontData* fontData = LoadFontFromXML(fullFontFileName);
608
if (fontData != NULL)
610
fontData->SetAlias(aliasName);
611
SetFontBaseEncoding(fontData);
612
if (!AddFont(fontData, font))
615
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
616
wxString::Format(_("Font file '%s' already registered."), fontFileName.c_str()));
622
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
623
wxString::Format(_("Format of font file '%s' not supported."), fontFileName.c_str()));
628
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
629
wxString::Format(_("Font file '%s' does not exist or is not readable."), fontFileName.c_str()));
636
wxPdfFontManagerBase::RegisterFont(const wxFont& font, const wxString& aliasName)
639
#if defined(__WXMSW__)
640
wxPdfFontParserTrueType fontParser;
641
wxPdfFontData* fontData = fontParser.IdentifyFont(font);
642
if (fontData != NULL)
644
fontData->SetAlias(aliasName);
645
if (!AddFont(fontData, regFont))
648
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
649
wxString::Format(_("wxFont '%s' already registered."), font.GetFaceName().c_str()));
652
#elif defined(__WXGTK20__)
653
// TODO: Would testing for __WXGTK__ be sufficient?
655
// TODO: Do we need to load the fontconfig library?
656
FcConfig* fc = FcInitLoadConfigAndFonts();
659
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
660
wxString(_("FontConfig init failed.")));
665
wxString fontFileName = wxEmptyString;
666
int fontFileIndex = 0;
670
wxString fontDesc = font.GetNativeFontInfoUserDesc();
671
wxString faceName = font.GetFaceName();
672
wxCharBuffer faceNameBuffer = faceName.ToUTF8();
673
const char* fontFamily = faceNameBuffer;
676
if (fontDesc.Find(wxT("Oblique")) != wxNOT_FOUND)
677
slant = FC_SLANT_OBLIQUE;
678
else if (fontDesc.Find(wxT("Italic")) != wxNOT_FOUND)
679
slant = FC_SLANT_ITALIC;
681
slant = FC_SLANT_ROMAN;
684
if (fontDesc.Find(wxT("Book")) != wxNOT_FOUND)
685
weight = FC_WEIGHT_BOOK;
686
else if (fontDesc.Find(wxT("Medium")) != wxNOT_FOUND)
687
weight = FC_WEIGHT_MEDIUM;
688
#ifdef FC_WEIGHT_ULTRALIGHT
689
else if (fontDesc.Find(wxT("Ultra-Light")) != wxNOT_FOUND)
690
weight = FC_WEIGHT_ULTRALIGHT;
692
else if (fontDesc.Find(wxT("Light")) != wxNOT_FOUND)
693
weight = FC_WEIGHT_LIGHT;
694
else if (fontDesc.Find(wxT("Semi-Bold")) != wxNOT_FOUND)
695
weight = FC_WEIGHT_DEMIBOLD;
696
#ifdef FC_WEIGHT_ULTRABOLD
697
else if (fontDesc.Find(wxT("Ultra-Bold")) != wxNOT_FOUND)
698
weight = FC_WEIGHT_ULTRABOLD;
700
else if (fontDesc.Find(wxT("Bold")) != wxNOT_FOUND)
701
weight = FC_WEIGHT_BOLD;
702
else if (fontDesc.Find(wxT("Heavy")) != wxNOT_FOUND)
703
weight = FC_WEIGHT_BLACK;
705
weight = FC_WEIGHT_NORMAL;
708
if (fontDesc.Find(wxT("Ultra-Condensed")) != wxNOT_FOUND)
709
width = FC_WIDTH_ULTRACONDENSED;
710
else if (fontDesc.Find(wxT("Extra-Condensed")) != wxNOT_FOUND)
711
width = FC_WIDTH_EXTRACONDENSED;
712
else if (fontDesc.Find(wxT("Semi-Condensed")) != wxNOT_FOUND)
713
width = FC_WIDTH_SEMICONDENSED;
714
else if (fontDesc.Find(wxT("Condensed")) != wxNOT_FOUND)
715
width = FC_WIDTH_CONDENSED;
716
else if (fontDesc.Find(wxT("Ultra-Expanded")) != wxNOT_FOUND)
717
width = FC_WIDTH_ULTRAEXPANDED;
718
else if (fontDesc.Find(wxT("Extra-Expanded")) != wxNOT_FOUND)
719
width = FC_WIDTH_EXTRAEXPANDED;
720
else if (fontDesc.Find(wxT("Semi-Expanded")) != wxNOT_FOUND)
721
width = FC_WIDTH_SEMIEXPANDED;
722
else if (fontDesc.Find(wxT("Expanded")) != wxNOT_FOUND)
723
width = FC_WIDTH_EXPANDED;
725
width = FC_WIDTH_NORMAL;
728
FcPattern* matchPattern;
729
matchPattern = FcPatternBuild(NULL,
730
FC_FAMILY, FcTypeString, (FcChar8*) fontFamily,
733
FcPatternAddInteger(matchPattern, FC_SLANT, slant);
735
FcPatternAddInteger(matchPattern, FC_WEIGHT, weight);
737
FcPatternAddInteger(matchPattern, FC_WIDTH, width);
739
FcConfigSubstitute (NULL, matchPattern, FcMatchPattern);
740
FcDefaultSubstitute (matchPattern);
742
FcPattern* resultPattern = FcFontMatch (NULL, matchPattern, &res);
747
if (FcPatternGetString (resultPattern, FC_FILE, 0, &fileName) == FcResultMatch)
749
fontFileName = wxString::FromUTF8((char*) fileName);
754
if (FcPatternGetInteger (resultPattern, FC_INDEX, 0, &id) == FcResultMatch)
758
FcPatternDestroy (resultPattern);
760
FcPatternDestroy (matchPattern);
762
if (!fontFileName.IsEmpty())
764
regFont = RegisterFont(fontFileName, aliasName, fontFileIndex);
768
wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
769
wxString::Format(_("Font file name not found for wxFont '%s'."), fontDesc.c_str()));
771
#elif defined(__WXMAC__)
772
#if wxPDFMACOSX_HAS_CORE_TEXT
773
wxPdfFontParserTrueType fontParser;
774
wxPdfFontData* fontData = fontParser.IdentifyFont(font);
775
if (fontData != NULL)
777
fontData->SetAlias(aliasName);
778
if (!AddFont(fontData, regFont))
781
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
782
wxString::Format(_("wxFont '%s' already registered."), font.GetFaceName().c_str()));
785
#elif wxPDFMACOSX_HAS_ATSU_TEXT
786
wxString fontFileName = wxEmptyString;
788
#if wxCHECK_VERSION(2,9,0)
789
// wxWidgets 2.9.x or higher
790
#if wxOSX_USE_ATSU_TEXT
791
wxUint32 atsuFontID = font.MacGetATSUFontID();
793
#else // wxWidgets 2.8.x
794
#ifdef __WXMAC_CLASSIC__
795
wxUint32 atsuFontID = font.GetMacATSUFontID();
797
wxUint32 atsuFontID = font.MacGetATSUFontID();
801
FSSpec fileSpecification;
803
if (::ATSFontGetFileSpecification(::FMGetATSFontRefFromFont(atsuFontID), &fileSpecification) == noErr)
805
if (::FSpMakeFSRef(&fileSpecification, &fileReference) == noErr)
807
fontFileName = wxMacFSRefToPath(&fileReference);
811
if (!fontFileName.IsEmpty())
813
regFont = RegisterFont(fontFileName, aliasName, 0);
817
wxString fontDesc = font.GetNativeFontInfoUserDesc();
818
wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
819
wxString::Format(_("Font file name not found for wxFont '%s'."), fontDesc.c_str()));
822
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
823
wxString(_("Method 'RegisterFont' for wxFont instances is not available for platform WXMAC.")));
826
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
827
wxString(_("Method 'RegisterFont' for wxFont instances is not available for your platform.")));
833
wxPdfFontManagerBase::RegisterFontCollection(const wxString& fontCollectionFileName)
836
wxString fullFontCollectionFileName;
837
if (FindFile(fontCollectionFileName, fullFontCollectionFileName))
839
wxFileName fileName(fullFontCollectionFileName);
840
if (fileName.IsOk() && fileName.GetExt().Lower().IsSameAs(wxT("ttc")))
842
wxPdfFontParserTrueType fontParser;
843
int fontCount = fontParser.GetCollectionFontCount(fullFontCollectionFileName);
845
for (j = 0; j < fontCount; ++j)
847
wxPdfFont registeredFont = RegisterFont(fileName.GetFullPath(), wxEmptyString, j);
848
if (registeredFont.IsValid())
856
wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFontCollection: ")) +
857
wxString::Format(_("Font collection file '%s' has not the file extension '.ttc'."), fontCollectionFileName.c_str()));
862
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFontCollection: ")) +
863
wxString::Format(_("Font collection file '%s' does not exist or is not readable."), fontCollectionFileName.c_str()));
870
wxPdfFontManagerBase::RegisterFontCJK(const wxString& family)
873
wxPdfFontFamilyMap::const_iterator familyIter = m_fontFamilyMap.find(family.Lower());
874
if (familyIter == m_fontFamilyMap.end())
876
wxString fontFileName = family.Lower() + wxString(wxT(".xml"));
877
wxString fullFontFileName;
878
if (FindFile(fontFileName, fullFontFileName))
880
ok = RegisterFontCJK(fullFontFileName, wxT(""), family);
883
// Add all available styles (bold, italic and bold-italic)
884
// For all styles the same font metric file is used.
885
RegisterFontCJK(fullFontFileName, wxT(",Bold"), family);
886
RegisterFontCJK(fullFontFileName, wxT(",Italic"), family);
887
RegisterFontCJK(fullFontFileName, wxT(",BoldItalic"), family);
892
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFontCJK: ")) +
893
wxString::Format(_("CJK Font file '%s' for CJK family '%s' does not exist or is not readable."), fontFileName.c_str(), family.c_str()));
898
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFontCJK: ")) +
899
wxString::Format(_("CJK family '%s' already registered."), family.c_str()));
907
wxPdfFontManagerBase::RegisterSystemFonts()
910
#if defined(__WXMSW__)
912
if (wxGetOsVersion() == wxOS_WINDOWS_NT)
914
strFont = wxT("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
918
strFont = wxT("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts");
921
wxRegKey* fontRegKey = new wxRegKey(strFont);
922
fontRegKey->Open(wxRegKey::Read);
923
// Retrieve the number of SubKeys and enumerate them
924
size_t nSubKeys = 0, nMaxKeyLen = 0;
925
size_t nValues = 0, nMaxValueLen = 0;
926
fontRegKey->GetKeyInfo(&nSubKeys, &nMaxKeyLen, &nValues, &nMaxValueLen);
927
wxString fontDirectory = wxGetOSDirectory();
928
if (!wxEndsWithPathSeparator(fontDirectory))
930
fontDirectory += wxT("\\");
932
fontDirectory += wxT("Fonts\\");
933
wxString strValueName;
934
wxString strValueData;
935
wxString fontFileName;
937
fontRegKey->GetFirstValue(strValueName, nIndex);
939
for (i = 0; i < nValues; ++i)
941
fontRegKey->QueryValue(strValueName, fontFileName);
942
if (fontFileName.Find(wxT('\\')) == wxNOT_FOUND)
944
fontFileName.Prepend(fontDirectory);
946
if (fontFileName.Lower().EndsWith(wxT(".ttc")))
948
count += RegisterFontCollection(fontFileName);
952
wxPdfFont registeredFont = RegisterFont(fontFileName);
953
if (registeredFont.IsValid())
958
fontRegKey->GetNextValue(strValueName, nIndex);
962
#elif defined(__WXGTK20__)
963
// TODO: Would testing for __WXGTK__ be sufficient?
965
// TODO: Do we need to load the fontconfig library?
966
FcConfig* fc = FcInitLoadConfigAndFonts();
969
wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterSystemFonts: ")) +
970
wxString(_("FontConfig init failed.")));
974
FcPattern* pat = FcPatternBuild(NULL,
975
FC_OUTLINE, FcTypeBool, 1,
976
FC_SCALABLE, FcTypeBool, 1,
978
FcObjectSet* os = FcObjectSetBuild (FC_FAMILY,
984
// TODO: Add FC_OUTLINE, FC_WEIGHT, FC_SLANT ?
985
FcFontSet* fs = FcFontList(0, pat, os);
986
FcObjectSetDestroy(os);
987
FcPatternDestroy(pat);
991
for (j = 0; j < fs->nfont; ++j)
994
if (FcPatternGetString(fs->fonts[j], FC_FILE, 0, &file) == FcResultMatch)
996
int fontFileIndex = 0;
998
if (FcPatternGetInteger (fs->fonts[j], FC_INDEX, 0, &id) == FcResultMatch)
1002
wxString fontFileName = wxString::FromUTF8((char*) file);
1003
wxPdfFont registeredFont = RegisterFont(fontFileName, wxEmptyString, fontFileIndex);
1004
if (registeredFont.IsValid())
1010
FcFontSetDestroy(fs);
1012
#elif defined(__WXMAC__)
1013
count += RegisterFontDirectory(wxT("/System/Library/Fonts"));
1014
count += RegisterFontDirectory(wxT("/Library/Fonts"));
1016
wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterSystemFonts: ")) +
1017
wxString(_("Method is not available for your platform.")));
1022
class wxPdfFontDirTraverser : public wxDirTraverser
1025
wxPdfFontDirTraverser(wxPdfFontManagerBase* fontManager)
1026
: m_fontManager(fontManager), m_count(0)
1030
virtual wxDirTraverseResult OnFile(const wxString& fileName)
1032
wxFileName fontFileName(fileName);
1033
wxString ext = fontFileName.GetExt().Lower();
1034
if (ext.IsSameAs(wxT("ttf")) || ext.IsSameAs(wxT("otf")) ||
1035
/* ext.IsSameAs(wxT("pfa")) || */ ext.IsSameAs(wxT("pfb")))
1037
wxPdfFont registeredFont = m_fontManager->RegisterFont(fontFileName.GetFullPath());
1038
if (registeredFont.IsValid())
1043
else if (ext.IsSameAs(wxT("ttc")))
1045
m_count += m_fontManager->RegisterFontCollection(fontFileName.GetFullPath());
1047
return wxDIR_CONTINUE;
1050
virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dirname))
1052
return wxDIR_CONTINUE;
1055
int GetCount() const
1061
wxPdfFontManagerBase* m_fontManager;
1066
wxPdfFontManagerBase::RegisterFontDirectory(const wxString& directory, bool recursive)
1069
if (wxDir::Exists(directory))
1071
wxDir fontDir(directory);
1072
if (fontDir.IsOpened())
1074
wxPdfFontDirTraverser fontDirTraverser(this);
1075
int flags = (recursive) ? wxDIR_FILES | wxDIR_DIRS : wxDIR_FILES;
1076
fontDir.Traverse(fontDirTraverser, wxEmptyString, flags);
1077
count = fontDirTraverser.GetCount();
1081
wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFontDirectory: ")) +
1082
wxString::Format(_("Directory '%s' could not be opened."),directory.c_str()));
1087
wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFontDirectory: ")) +
1088
wxString::Format(_("Directory '%s' does not exist."),directory.c_str()));
1095
wxPdfFontManagerBase::GetFont(const wxString& fontName, int fontStyle) const
1098
wxCriticalSectionLocker locker(gs_csFontManager);
1100
wxString lcFontName = fontName.Lower();
1101
int searchStyle = (fontStyle & ~wxPDF_FONTSTYLE_DECORATION_MASK) & wxPDF_FONTSTYLE_MASK;
1102
wxPdfFontData* fontData = NULL;
1104
// Check whether font name equals font family
1105
wxPdfFontFamilyMap::const_iterator familyIter = m_fontFamilyMap.find(lcFontName);
1106
if (familyIter == m_fontFamilyMap.end())
1108
// 1. Check family alias if given name was not a family name
1109
wxPdfFontAliasMap::const_iterator aliasIter = m_fontAliasMap.find(lcFontName);
1110
if (aliasIter != m_fontAliasMap.end())
1112
familyIter = m_fontFamilyMap.find(aliasIter->second);
1116
if (familyIter != m_fontFamilyMap.end())
1118
// 2. Check whether the family contains a font with the requested style
1119
size_t n = familyIter->second.GetCount();
1121
for (j = 0; j < n && fontData == NULL; ++j)
1123
fontData = m_fontList[familyIter->second[j]]->GetFontData();
1124
if (fontData->GetStyle() != searchStyle)
1131
if (fontData == NULL)
1133
// 3. Check whether a font is registered under the given name
1134
wxPdfFontNameMap::const_iterator fontIter = m_fontNameMap.find(lcFontName);
1135
if (fontIter != m_fontNameMap.end())
1137
fontData = m_fontList[fontIter->second]->GetFontData();
1141
wxString style = ConvertStyleToString(searchStyle);
1142
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::GetFont: ")) +
1143
wxString::Format(_("Font '%s' with style '%s' not found."), fontName.c_str(), style.c_str()));
1146
wxPdfFont font(fontData, fontStyle);
1147
font.SetEmbed(m_defaultEmbed);
1148
font.SetSubset(m_defaultSubset);
1153
wxPdfFontManagerBase::GetFont(const wxString& fontName, const wxString& fontStyle) const
1155
int style = wxPDF_FONTSTYLE_REGULAR;
1156
wxString localStyle = fontStyle.Lower();
1157
if (localStyle.length() > 2)
1159
if (localStyle.Find(wxT("bold")) != wxNOT_FOUND)
1161
style |= wxPDF_FONTSTYLE_BOLD;
1163
if (localStyle.Find(wxT("italic")) != wxNOT_FOUND || localStyle.Find(wxT("oblique")) != wxNOT_FOUND)
1165
style |= wxPDF_FONTSTYLE_ITALIC;
1170
if (localStyle.Find(wxT("b")) != wxNOT_FOUND)
1172
style |= wxPDF_FONTSTYLE_BOLD;
1174
if (localStyle.Find(wxT("i")) != wxNOT_FOUND)
1176
style |= wxPDF_FONTSTYLE_ITALIC;
1179
return GetFont(fontName, style);
1183
wxPdfFontManagerBase::GetFont(size_t fontIndex) const
1186
wxCriticalSectionLocker locker(gs_csFontManager);
1189
if (fontIndex < m_fontList.GetCount())
1191
font = wxPdfFont(m_fontList[fontIndex]->GetFontData());
1197
wxPdfFontManagerBase::GetFontCount() const
1200
wxCriticalSectionLocker locker(gs_csFontManager);
1202
return m_fontList.GetCount();
1206
wxPdfFontManagerBase::InitializeFontData(const wxPdfFont& font)
1209
if (font.m_fontData != NULL)
1211
ok = font.m_fontData->IsInitialized();
1215
wxCriticalSectionLocker locker(gs_csFontManager);
1217
ok = font.m_fontData->Initialize();
1224
wxPdfFontManagerBase::RegisterEncoding(const wxPdfEncoding& encoding)
1227
wxString encodingName = encoding.GetEncodingName().Lower();
1228
if (m_encodingMap->find(encodingName) == m_encodingMap->end())
1231
wxCriticalSectionLocker locker(gs_csFontManager);
1233
wxPdfEncoding* addedEncoding = new wxPdfEncoding(encoding);
1234
if (addedEncoding->IsOk())
1236
addedEncoding->InitializeEncodingMap();
1237
(*m_encodingMap)[encodingName] = addedEncoding;
1248
wxPdfFontManagerBase::SetFontBaseEncoding(wxPdfFontData* fontData)
1250
if (fontData != NULL)
1252
wxString fontType = fontData->GetType();
1253
wxString encoding = fontData->GetEncoding();
1254
if (encoding.IsEmpty())
1256
encoding = wxT("iso-8859-1");
1258
if (fontType.IsSameAs(wxT("TrueType")) || fontType.IsSameAs(wxT("Type1")))
1260
if (RegisterEncoding(encoding))
1262
wxPdfEncodingMap::const_iterator beIter = m_encodingMap->find(encoding);
1263
wxPdfEncoding* baseEncoding = (beIter != m_encodingMap->end()) ? beIter->second : NULL;
1264
fontData->SetEncoding(baseEncoding);
1267
else if (fontType.IsSameAs(wxT("Type0")))
1269
wxPdfEncodingCheckerMap::const_iterator ecIter = m_encodingCheckerMap->find(encoding);
1270
wxPdfEncodingChecker* encodingChecker = (ecIter != m_encodingCheckerMap->end()) ? ecIter->second : NULL;
1271
fontData->SetEncodingChecker(encodingChecker);
1276
const wxPdfEncoding*
1277
wxPdfFontManagerBase::GetEncoding(const wxString& encodingName)
1280
wxCriticalSectionLocker locker(gs_csFontManager);
1282
wxPdfEncoding* foundEncoding = NULL;
1283
if (RegisterEncoding(encodingName))
1285
wxPdfEncodingMap::const_iterator encoding = m_encodingMap->find(encodingName.Lower());
1286
if (encoding != m_encodingMap->end())
1288
foundEncoding = encoding->second;
1291
return foundEncoding;
1295
wxPdfFontManagerBase::ConvertStyleToString(int fontStyle)
1297
wxString style = wxEmptyString;
1298
if ((fontStyle & wxPDF_FONTSTYLE_BOLDITALIC) == wxPDF_FONTSTYLE_BOLDITALIC)
1300
style = wxString(_("BoldItalic"));
1302
else if (fontStyle & wxPDF_FONTSTYLE_BOLD)
1304
style = wxString(_("Bold"));
1306
else if (fontStyle & wxPDF_FONTSTYLE_ITALIC)
1308
style = wxString(_("Italic"));
1312
style = wxString(_("Regular"));
1317
// --- wxPdfFontManagerBase (private)
1320
wxPdfFontManagerBase::InitializeCoreFonts()
1322
wxPdfFontDataCore* coreFontData;
1323
if (!RegisterEncoding(wxT("winansi")) ||
1324
!RegisterEncoding(wxT("iso-8859-1")))
1326
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::InitializeCoreFonts: ")) +
1327
wxString::Format(_("Registering encodings for core fonts failed.")));
1330
for (j = 0; gs_coreFontTable[j].name != wxEmptyString; ++j)
1332
const wxPdfCoreFontDesc& coreFontDesc = gs_coreFontTable[j];
1333
wxString family(coreFontDesc.family);
1334
bool isWinAnsi = !(family.IsSameAs(wxT("Symbol")) || family.IsSameAs(wxT("ZapfDingbats")));
1335
wxString encoding = (isWinAnsi) ? wxT("winansi") : wxT("iso-8859-1");
1337
wxPdfEncodingMap::const_iterator beIter = m_encodingMap->find(encoding);
1338
wxPdfEncoding* baseEncoding = (beIter != m_encodingMap->end()) ? beIter->second : NULL;
1340
coreFontData = new wxPdfFontDataCore(coreFontDesc.family, coreFontDesc.alias, coreFontDesc.name,
1341
coreFontDesc.cwArray, coreFontDesc.kpArray,
1342
wxPdfFontDescription(coreFontDesc.ascent, coreFontDesc.descent,
1343
coreFontDesc.capHeight, coreFontDesc.flags,
1344
coreFontDesc.bbox, coreFontDesc.italicAngle,
1345
coreFontDesc.stemV, coreFontDesc.missingWidth,
1346
coreFontDesc.xHeight, coreFontDesc.underlinePosition,
1347
coreFontDesc.underlineThickness));
1348
coreFontData->SetEncoding(baseEncoding);
1349
AddFont(coreFontData);
1355
wxPdfFontManagerBase::InitializeCjkFonts()
1357
const wxChar* fontStyles[4] = { wxT(""), wxT(",Bold"), wxT(",Italic"), wxT(",BoldItalic") };
1360
wxPdfFontDataType0* cjkFontData;
1363
for (j = 0; gs_cjkFontTable[j].name != wxEmptyString; ++j)
1365
const wxPdfCjkFontDesc& cjkFontDesc = gs_cjkFontTable[j];
1366
wxPdfEncodingCheckerMap::const_iterator ecIter = m_encodingCheckerMap->find(cjkFontDesc.encoding);
1367
wxPdfEncodingChecker* encodingChecker = (ecIter != m_encodingCheckerMap->end()) ? ecIter->second : NULL;
1368
for (k = 0; k < 4; ++k)
1370
cjkFontData = new wxPdfFontDataType0(cjkFontDesc.family, cjkFontDesc.name,
1371
cjkFontDesc.encoding, cjkFontDesc.ordering,
1372
cjkFontDesc.supplement, cjkFontDesc.cmap,
1373
cjkFontDesc.cwArray,
1374
wxPdfFontDescription(cjkFontDesc.ascent, cjkFontDesc.descent,
1375
cjkFontDesc.capHeight, cjkFontDesc.flags,
1376
cjkFontDesc.bbox, cjkFontDesc.italicAngle,
1377
cjkFontDesc.stemV, cjkFontDesc.missingWidth,
1378
cjkFontDesc.xHeight, cjkFontDesc.underlinePosition,
1379
cjkFontDesc.underlineThickness));
1380
fontName = cjkFontDesc.name;
1381
fontName += fontStyles[k];
1382
cjkFontData->SetName(fontName);
1383
fontAlias = cjkFontDesc.family;
1384
cjkFontData->SetFamily(fontAlias);
1385
cjkFontData->SetAlias(fontAlias);
1386
cjkFontData->SetStyleFromName();
1387
cjkFontData->SetEncodingChecker(encodingChecker);
1388
ok = AddFont(cjkFontData);
1399
wxPdfFontManagerBase::InitializeEncodingChecker()
1402
for (j = 0; gs_encodingTableData[j].m_encodingName != NULL; ++j)
1404
wxString encodingName(gs_encodingTableData[j].m_encodingName);
1405
wxPdfEncodingChecker* encodingChecker;
1406
if (gs_encodingTableData[j].m_encodingTable != NULL)
1408
encodingChecker = new wxPdfCodepageChecker(gs_encodingTableData[j].m_encodingName,
1409
gs_encodingTableData[j].m_encodingTableSize,
1410
gs_encodingTableData[j].m_encodingTable);
1414
encodingChecker = new wxPdfCjkChecker(gs_encodingTableData[j].m_encodingName,
1415
gs_encodingTableData[j].m_encodingBase);
1417
(*m_encodingCheckerMap)[encodingName] = encodingChecker;
1422
wxPdfFontManagerBase::RegisterEncoding(const wxString& encoding)
1425
wxString encodingName = encoding.Lower();
1426
if (m_encodingMap->find(encodingName) == m_encodingMap->end())
1428
wxPdfEncoding* addedEncoding = new wxPdfEncoding();
1429
if (addedEncoding->SetEncoding(encoding))
1431
addedEncoding->InitializeEncodingMap();
1432
(*m_encodingMap)[encodingName] = addedEncoding;
1436
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterEncoding: ")) +
1437
wxString::Format(_("Encoding '%s' is unknown."), encoding.c_str()));
1438
delete addedEncoding;
1446
wxPdfFontManagerBase::RegisterFontCJK(const wxString& fontFileName, const wxString& fontStyle, const wxString& alias)
1449
wxPdfFontData* fontData;
1450
fontData = LoadFontFromXML(fontFileName);
1451
if (fontData != NULL)
1453
wxString fontName = fontData->GetName();
1454
fontName += fontStyle;
1455
fontData->SetName(fontName);
1456
fontData->SetFamily(alias);
1457
fontData->SetAlias(alias);
1458
fontData->SetStyleFromName();
1459
SetFontBaseEncoding(fontData);
1460
ok = AddFont(fontData);
1463
wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFontCJK: ")) +
1464
wxString::Format(_("CJK font '%s' already registered."), fontName.c_str()));
1471
wxPdfFontManagerBase::LoadFontFromXML(const wxString& fontFileName)
1473
wxPdfFontData* fontData = NULL;
1474
wxFileName fileName(fontFileName);
1477
// Open font metrics XML file
1478
wxFSFile* xmlFontMetrics = fs.OpenFile(wxFileSystem::FileNameToURL(fileName));
1479
if (xmlFontMetrics != NULL)
1481
// Load the XML file
1482
wxXmlDocument fontMetrics;
1483
bool loaded = fontMetrics.Load(*xmlFontMetrics->GetStream());
1484
delete xmlFontMetrics;
1487
if (fontMetrics.IsOk() && fontMetrics.GetRoot()->GetName().IsSameAs(wxT("wxpdfdoc-font-metrics")))
1490
wxXmlNode* root = fontMetrics.GetRoot();
1491
#if wxCHECK_VERSION(2,9,0)
1492
if (root->GetAttribute(wxT("type"), &fontType))
1494
if (root->GetPropVal(wxT("type"), &fontType))
1497
if (fontType.IsSameAs(wxT("TrueType")))
1499
fontData = new wxPdfFontDataTrueType();
1501
else if (fontType.IsSameAs(wxT("Type1")))
1503
fontData = new wxPdfFontDataType1();
1506
else if (fontType.IsSameAs(wxT("TrueTypeUnicode")))
1508
fontData = new wxPdfFontDataTrueTypeUnicode();
1510
else if (fontType.IsSameAs(wxT("OpenTypeUnicode")))
1512
fontData = new wxPdfFontDataOpenTypeUnicode();
1514
else if (fontType.IsSameAs(wxT("Type0")))
1516
fontData = new wxPdfFontDataType0();
1521
// Unknown font type
1522
wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
1523
wxString::Format(_("Unknown font type '%s' in font file '%s'."), fontType.c_str(), fontFileName.c_str()));
1525
if (fontData != NULL)
1527
fontData->SetFilePath(fileName.GetPath());
1528
if (!fontData->LoadFontMetrics(root))
1530
wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
1531
wxString::Format(_("Loading of font metrics failed for font file '%s'."), fontFileName.c_str()));
1539
// Font type not specified
1540
wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
1541
wxString::Format(_("Font type not specified for font '%s'."), fontFileName.c_str()));
1546
// Not a font metrics file
1547
wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
1548
wxString::Format(_("Font metrics file '%s' invalid."), fontFileName.c_str()));
1553
// Font metrics file loading failed
1554
wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
1555
wxString::Format(_("Loading of font metrics file '%s' failed."), fontFileName.c_str()));
1560
// Font metrics XML file not found
1561
wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
1562
wxString::Format(_("Font metrics file '%s' not found."), fontFileName.c_str()));
1568
wxPdfFontManagerBase::IsRegistered(wxPdfFontData* fontData)
1571
wxCriticalSectionLocker locker(gs_csFontManager);
1573
wxString fontName = fontData->GetName();
1574
wxPdfFontNameMap::const_iterator font = m_fontNameMap.find(fontName.Lower());
1575
return (font != m_fontNameMap.end());
1579
wxPdfFontManagerBase::AddFont(wxPdfFontData* fontData)
1582
return AddFont(fontData, font);
1586
wxPdfFontManagerBase::AddFont(wxPdfFontData* fontData, wxPdfFont& font)
1590
wxCriticalSectionLocker locker(gs_csFontManager);
1592
wxString fontName = fontData->GetName().Lower();
1593
wxString family = fontData->GetFamily().Lower();
1594
wxString alias = fontData->GetAlias().Lower();
1596
wxPdfFontNameMap::const_iterator fontIter = m_fontNameMap.find(fontName.Lower());
1597
if (fontIter == m_fontNameMap.end())
1599
// Font not yet registered
1600
wxArrayString fullNames = fontData->GetFullNames();
1601
size_t pos = m_fontList.GetCount();
1602
wxPdfFontListEntry* fontEntry = new wxPdfFontListEntry(fontData);
1603
m_fontList.Add(fontEntry);
1604
font = wxPdfFont(fontData);
1607
// Register Postscript font name
1608
m_fontNameMap[fontName] = pos;
1610
// Register all full font names
1612
for (j = 0; j < fullNames.GetCount(); ++j)
1614
m_fontNameMap[fullNames[j].Lower()] = pos;
1617
// Register font in family
1618
if (!family.IsEmpty())
1620
m_fontFamilyMap[family].Add(pos);
1622
else if (!alias.IsEmpty())
1624
m_fontFamilyMap[alias].Add(pos);
1629
font = wxPdfFont(m_fontList[fontIter->second]->GetFontData());
1632
// Register family alias
1633
if (!alias.IsEmpty() && !alias.IsSameAs(family))
1635
// Check whether the alias is already assigned and - if so - to the same family
1636
wxPdfFontAliasMap::const_iterator aliasIter = m_fontAliasMap.find(alias);
1637
if (aliasIter != m_fontAliasMap.end())
1639
if (!aliasIter->second.IsSameAs(family))
1641
wxLogError(wxString(wxT("wxPdfFontManagerBase::AddFont: ")) +
1642
wxString::Format(_("Family alias '%s' for family '%s' already assigned to family '%s'."),
1643
alias.c_str(), family.c_str(), aliasIter->second.c_str()));
1648
// alias not previously assigned, remember assignment
1649
m_fontAliasMap[alias] = family;
1655
// --- wxPdfFontManager
1658
#ifndef wxPDF_USE_WXMODULE
1659
#define wxPDF_USE_WXMODULE 1
1662
#if wxPDF_USE_WXMODULE
1663
wxPdfFontManager* wxPdfFontManager::ms_fontManager = NULL;
1665
wxPdfFontManager* wxPdfFontManager::ms_fontManager = new wxPdfFontManager();
1666
#endif // wxPDF_USE_WXMODULE
1669
wxPdfFontManager::wxPdfFontManager()
1671
m_fontManagerBase = new wxPdfFontManagerBase();
1674
wxPdfFontManager::~wxPdfFontManager()
1676
delete m_fontManagerBase;
1678
#if !wxPDF_USE_WXMODULE
1679
if ( ms_fontManager )
1681
delete ms_fontManager;
1682
ms_fontManager = NULL;
1684
#endif // !wxPDF_USE_WXMODULE
1689
wxPdfFontManager::GetFontManager()
1691
return ms_fontManager;
1696
wxPdfFontManager::AddSearchPath(const wxString& path)
1698
m_fontManagerBase->AddSearchPath(path);
1702
wxPdfFontManager::AddSearchPath(const wxArrayString& pathArray)
1704
m_fontManagerBase->AddSearchPath(pathArray);
1708
wxPdfFontManager::SetDefaultEmbed(bool embed)
1710
return m_fontManagerBase->SetDefaultEmbed(embed);
1714
wxPdfFontManager::GetDefaultEmbed()
1716
return m_fontManagerBase->GetDefaultEmbed();
1720
wxPdfFontManager::SetDefaultSubset(bool subset)
1722
return m_fontManagerBase->SetDefaultSubset(subset);
1726
wxPdfFontManager::GetDefaultSubset()
1728
return m_fontManagerBase->GetDefaultSubset();
1732
wxPdfFontManager::RegisterFont(const wxString& fontFileName, const wxString& aliasName, int fontIndex)
1734
return m_fontManagerBase->RegisterFont(fontFileName, aliasName, fontIndex);
1738
wxPdfFontManager::RegisterFont(const wxFont& font, const wxString& aliasName)
1741
return m_fontManagerBase->RegisterFont(font, aliasName);
1744
wxUnusedVar(aliasName);
1750
wxPdfFontManager::RegisterFontCollection(const wxString& fontCollectionFileName)
1753
return m_fontManagerBase->RegisterFontCollection(fontCollectionFileName);
1755
wxUnusedVar(fontCollectionFileName);
1761
wxPdfFontManager::RegisterFontCJK(const wxString& family)
1763
return m_fontManagerBase->RegisterFontCJK(family);
1767
wxPdfFontManager::RegisterSystemFonts()
1770
return m_fontManagerBase->RegisterSystemFonts();
1777
wxPdfFontManager::RegisterFontDirectory(const wxString& directory, bool recursive)
1780
return m_fontManagerBase->RegisterFontDirectory(directory, recursive);
1782
wxUnusedVar(directory);
1783
wxUnusedVar(recursive);
1789
wxPdfFontManager::GetFont(const wxString& fontName, int fontStyle) const
1791
return m_fontManagerBase->GetFont(fontName, fontStyle);
1795
wxPdfFontManager::GetFont(const wxString& fontName, const wxString& fontStyle) const
1797
return m_fontManagerBase->GetFont(fontName, fontStyle);
1801
wxPdfFontManager::GetFont(size_t fontIndex) const
1803
return m_fontManagerBase->GetFont(fontIndex);
1807
wxPdfFontManager::GetFontCount() const
1809
return m_fontManagerBase->GetFontCount();
1813
wxPdfFontManager::InitializeFontData(const wxPdfFont& font)
1818
ok = m_fontManagerBase->InitializeFontData(font);
1824
wxPdfFontManager::RegisterEncoding(const wxPdfEncoding& encoding)
1826
return m_fontManagerBase->RegisterEncoding(encoding);
1829
const wxPdfEncoding*
1830
wxPdfFontManager::GetEncoding(const wxString& encodingName)
1832
return m_fontManagerBase->GetEncoding(encodingName);
1835
// A module to allow initialization/cleanup of wxPdfDocument
1836
// singletons without calling these functions from app.cpp.
1839
#if wxPDF_USE_WXMODULE
1841
#include <wx/module.h>
1844
class WXDLLIMPEXP_PDFDOC wxPdfDocumentModule : public wxModule
1846
DECLARE_DYNAMIC_CLASS(wxPdfDocumentModule)
1848
wxPdfDocumentModule() {}
1853
IMPLEMENT_DYNAMIC_CLASS(wxPdfDocumentModule, wxModule)
1856
* Initialization/cleanup module
1859
bool wxPdfDocumentModule::OnInit()
1861
wxPdfFontManager::ms_fontManager = new wxPdfFontManager();
1865
void wxPdfDocumentModule::OnExit()
1867
delete wxPdfFontManager::ms_fontManager;
1868
wxPdfFontManager::ms_fontManager = NULL;
1872
#endif // wxPDF_USE_WXMODULE