~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/plugins/contrib/source_exporter/wxPdfDocument/src/pdffontmanager.cpp

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        pdffontmanager.cpp
 
3
// Purpose:
 
4
// Author:      Ulrich Telle
 
5
// Modified by:
 
6
// Created:     2008-08-10
 
7
// RCS-ID:      $$
 
8
// Copyright:   (c) Ulrich Telle
 
9
// Licence:     wxWindows licence
 
10
///////////////////////////////////////////////////////////////////////////////
 
11
 
 
12
/// \file pdffontmanager.cpp Implementation of the wxPdfFontManager class
 
13
 
 
14
// For compilers that support precompilation, includes <wx.h>.
 
15
#include <wx/wxprec.h>
 
16
 
 
17
#ifdef __BORLANDC__
 
18
#pragma hdrstop
 
19
#endif
 
20
 
 
21
#ifndef WX_PRECOMP
 
22
#include <wx/wx.h>
 
23
#endif
 
24
 
 
25
// includes
 
26
#include <wx/dir.h>
 
27
#include <wx/dynarray.h>
 
28
#include <wx/filefn.h>
 
29
#include <wx/filename.h>
 
30
#include <wx/filesys.h>
 
31
#include <wx/font.h>
 
32
#include <wx/thread.h>
 
33
#include <wx/xml/xml.h>
 
34
 
 
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"
 
45
 
 
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>
 
52
 
 
53
  // Define some FontConfig symbols if they are missing
 
54
  #ifndef FC_WEIGHT_BOOK
 
55
    #define FC_WEIGHT_BOOK 75
 
56
  #endif
 
57
  #ifndef FC_FULLNAME
 
58
    #define FC_FULLNAME "fullname"
 
59
  #endif
 
60
#elif defined(__WXMAC__)
 
61
  #include "wx/pdffontmacosx.h"
 
62
#else
 
63
#endif
 
64
 
 
65
#include "wxmemdbg.h"
 
66
 
 
67
// Include core font data
 
68
#include "pdfcorefontdata.inc"
 
69
 
 
70
// Include CJK font data
 
71
#include "pdfcjkfontdata.inc"
 
72
 
 
73
// wxPdfFontManager is a singleton.
 
74
// Critical sections are used to make access to it thread safe if necessary.
 
75
#if wxUSE_THREADS
 
76
static wxCriticalSection gs_csFontManager;
 
77
static wxCriticalSection gs_csFontData;
 
78
#endif
 
79
 
 
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.
 
83
 
 
84
wxMBConv* wxPdfFontData::ms_winEncoding = NULL;
 
85
 
 
86
wxMBConv*
 
87
wxPdfFontData::GetWinEncodingConv()
 
88
{
 
89
#if wxUSE_THREADS
 
90
  wxCriticalSectionLocker locker(gs_csFontData);
 
91
#endif
 
92
  if (ms_winEncoding == NULL)
 
93
  {
 
94
    static wxCSConv winEncoding(wxFONTENCODING_CP1252);
 
95
    ms_winEncoding = &winEncoding;
 
96
  }
 
97
  return ms_winEncoding;
 
98
}
 
99
 
 
100
int
 
101
wxPdfFontData::IncrementRefCount()
 
102
{
 
103
#if wxUSE_THREADS
 
104
  wxCriticalSectionLocker locker(gs_csFontData);
 
105
#endif
 
106
  return ++m_refCount;
 
107
}
 
108
 
 
109
// --- Font List
 
110
 
 
111
int
 
112
wxPdfFontData::DecrementRefCount()
 
113
{
 
114
#if wxUSE_THREADS
 
115
  wxCriticalSectionLocker locker(gs_csFontData);
 
116
#endif
 
117
  return --m_refCount;
 
118
}
 
119
 
 
120
class wxPdfFontListEntry
 
121
{
 
122
public:
 
123
  wxPdfFontListEntry(wxPdfFontData* fontData) : m_fontData(fontData)
 
124
  {
 
125
    if (m_fontData != NULL)
 
126
    {
 
127
      m_fontData->IncrementRefCount();
 
128
    }
 
129
  }
 
130
 
 
131
  ~wxPdfFontListEntry()
 
132
  {
 
133
    if (m_fontData != NULL && m_fontData->DecrementRefCount() == 0)
 
134
    {
 
135
      delete m_fontData;
 
136
    }
 
137
  }
 
138
 
 
139
  wxPdfFontListEntry(const wxPdfFontListEntry& p) : m_fontData(p.m_fontData)
 
140
  {
 
141
    if (m_fontData != NULL)
 
142
    {
 
143
      m_fontData->IncrementRefCount();
 
144
    }
 
145
  }
 
146
 
 
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)
 
154
    {
 
155
      m_fontData->IncrementRefCount();
 
156
    }
 
157
    if (prevFontData != NULL && prevFontData->DecrementRefCount() == 0)
 
158
    {
 
159
      delete prevFontData;
 
160
    }
 
161
    return *this;
 
162
  }
 
163
 
 
164
  wxPdfFontData* GetFontData() const
 
165
  {
 
166
    return m_fontData;
 
167
  }
 
168
 
 
169
  wxPdfFontData* operator->()
 
170
  {
 
171
    return m_fontData;
 
172
  }
 
173
 
 
174
  wxPdfFontData& operator*()
 
175
  {
 
176
    return *m_fontData;
 
177
  }
 
178
 
 
179
private:
 
180
  wxPdfFontData* m_fontData;
 
181
};
 
182
 
 
183
// --- Encoding checker
 
184
 
 
185
// Include codepage data
 
186
#include "pdfcodepagedata.inc"
 
187
 
 
188
// Class representing a font encoding checker
 
189
class WXDLLIMPEXP_PDFDOC wxPdfCodepageChecker : public wxPdfEncodingChecker
 
190
{
 
191
public:
 
192
  /// Default constructor
 
193
  wxPdfCodepageChecker(const wxString& encoding, int tableSize, const wxUniRangeDesc* cpTable)
 
194
  {
 
195
    m_encoding = encoding;
 
196
    m_tableSize = tableSize;
 
197
    m_cpTable = cpTable;
 
198
  }
 
199
 
 
200
  /// Destructor
 
201
  virtual ~wxPdfCodepageChecker()
 
202
  {
 
203
  }
 
204
 
 
205
  /// Get the name of the encoding
 
206
  /**
 
207
  * \return the name of the encoding
 
208
  */
 
209
  virtual bool IsIncluded(wxUint32 unicode) const
 
210
  {
 
211
    bool isIncluded = false;
 
212
    if (unicode < 0x00010000)
 
213
    {
 
214
      unsigned short code = unicode & 0x0000ffff;
 
215
      int lb = 0;
 
216
      int hb = m_tableSize - 1;
 
217
      int mid = (lb + hb) / 2;
 
218
      while (mid != lb)
 
219
      {
 
220
        if (code >= m_cpTable[mid].uni1)
 
221
        {
 
222
          lb = mid;
 
223
        }
 
224
        else
 
225
        {
 
226
          hb = mid;
 
227
        }
 
228
        mid = (lb + hb) / 2;
 
229
      }
 
230
      isIncluded = (code <= m_cpTable[mid].uni2);
 
231
    }
 
232
    return isIncluded;
 
233
  }
 
234
 
 
235
private:
 
236
  int                   m_tableSize;        ///< Size of the mapping table
 
237
  const wxUniRangeDesc* m_cpTable;          ///< Table for code page
 
238
};
 
239
 
 
240
// Class representing a font encoding checker
 
241
class WXDLLIMPEXP_PDFDOC wxPdfCjkChecker : public wxPdfEncodingChecker
 
242
{
 
243
public:
 
244
  /// Default constructor
 
245
  wxPdfCjkChecker(const wxString& encoding, const unsigned char* cjkTable)
 
246
  {
 
247
    m_encoding = encoding;
 
248
    m_cjkTable = cjkTable;
 
249
  }
 
250
 
 
251
  /// Destructor
 
252
  virtual ~wxPdfCjkChecker()
 
253
  {
 
254
  }
 
255
 
 
256
  /// Check whether a given Unicode character is included in the encoding
 
257
  /**
 
258
  * \return TRUE if the Unicode character is included, FALSE otherwise
 
259
  */
 
260
  virtual bool IsIncluded(wxUint32 unicode) const
 
261
  {
 
262
    bool isIncluded = false;
 
263
    if (unicode < 0x00010000)
 
264
  {
 
265
    int charPos = unicode / 8;
 
266
    unsigned char bitPos = 1 << (7 - (unicode % 8));
 
267
    isIncluded = ((m_cjkTable[charPos] & bitPos) != 0);
 
268
  }
 
269
  return isIncluded;
 
270
  }
 
271
 
 
272
private:
 
273
  const unsigned char* m_cjkTable;         ///< Table for CJK encodings
 
274
};
 
275
 
 
276
// --- Font Manager Base
 
277
 
 
278
WX_DEFINE_ARRAY_PTR(wxPdfFontListEntry*, wxPdfFontList);
 
279
 
 
280
/// Hashmap class for mapping font families
 
281
WX_DECLARE_STRING_HASH_MAP(wxArrayInt, wxPdfFontFamilyMap);
 
282
 
 
283
/// Hashmap class for mapping font names to font list entries
 
284
WX_DECLARE_STRING_HASH_MAP(int, wxPdfFontNameMap);
 
285
 
 
286
/// Hashmap class for mapping alias names to family names
 
287
WX_DECLARE_STRING_HASH_MAP(wxString, wxPdfFontAliasMap);
 
288
 
 
289
/// Hashmap class for mapping encodings
 
290
WX_DECLARE_STRING_HASH_MAP(wxPdfEncoding*, wxPdfEncodingMap);
 
291
 
 
292
/// Hashmap class for mapping encoding checkers
 
293
WX_DECLARE_STRING_HASH_MAP(wxPdfEncodingChecker*, wxPdfEncodingCheckerMap);
 
294
 
 
295
class wxPdfFontManagerBase
 
296
{
 
297
public:
 
298
  /// Default constructor
 
299
  wxPdfFontManagerBase();
 
300
 
 
301
  /// Default destructor
 
302
  ~wxPdfFontManagerBase();
 
303
 
 
304
  void AddSearchPath(const wxString& path);
 
305
 
 
306
  void AddSearchPath(const wxArrayString& pathArray);
 
307
 
 
308
  bool SetDefaultEmbed(bool embed);
 
309
 
 
310
  bool GetDefaultEmbed();
 
311
 
 
312
  bool SetDefaultSubset(bool subset);
 
313
 
 
314
  bool GetDefaultSubset();
 
315
 
 
316
  wxPdfFont RegisterFont(const wxString& fontFileName, const wxString& aliasName = wxEmptyString, int fontIndex = 0);
 
317
 
 
318
#if wxUSE_UNICODE
 
319
  wxPdfFont RegisterFont(const wxFont& font, const wxString& aliasName = wxEmptyString);
 
320
 
 
321
  int RegisterFontCollection(const wxString& fontCollectionFileName);
 
322
#endif
 
323
 
 
324
  bool RegisterFontCJK(const wxString& family);
 
325
 
 
326
#if wxUSE_UNICODE
 
327
  int RegisterSystemFonts();
 
328
 
 
329
  int RegisterFontDirectory(const wxString& directory, bool recursive = false);
 
330
#endif
 
331
 
 
332
  wxPdfFont GetFont(const wxString& fontName, int fontStyle = wxPDF_FONTSTYLE_REGULAR) const;
 
333
 
 
334
  wxPdfFont GetFont(const wxString& fontName, const wxString& fontStyle) const;
 
335
 
 
336
  wxPdfFont GetFont(size_t fontIndex) const;
 
337
 
 
338
  size_t GetFontCount() const;
 
339
 
 
340
  bool InitializeFontData(const wxPdfFont& font);
 
341
 
 
342
  bool RegisterEncoding(const wxPdfEncoding& encoding);
 
343
 
 
344
  const wxPdfEncoding* GetEncoding(const wxString& encodingName);
 
345
 
 
346
  bool FindFile(const wxString& fileName, wxString& fullFileName) const;
 
347
 
 
348
  static wxString ConvertStyleToString(int fontStyle);
 
349
 
 
350
private:
 
351
  void InitializeCoreFonts();
 
352
 
 
353
#if wxUSE_UNICODE
 
354
  void InitializeCjkFonts();
 
355
#endif
 
356
 
 
357
  void InitializeEncodingChecker();
 
358
 
 
359
  bool RegisterEncoding(const wxString& encoding);
 
360
 
 
361
  void SetFontBaseEncoding(wxPdfFontData* fontData);
 
362
 
 
363
  bool RegisterFontCJK(const wxString& fontFileName, const wxString& fontStyle, const wxString& alias);
 
364
 
 
365
  wxPdfFontData* LoadFontFromXML(const wxString& fontFileName);
 
366
 
 
367
  bool IsRegistered(wxPdfFontData* fontData);
 
368
 
 
369
  bool AddFont(wxPdfFontData* fontData);
 
370
 
 
371
  bool AddFont(wxPdfFontData* fontData, wxPdfFont& font);
 
372
 
 
373
  wxPathList         m_searchPaths;
 
374
 
 
375
  wxPdfFontNameMap   m_fontNameMap;
 
376
  wxPdfFontFamilyMap m_fontFamilyMap;
 
377
  wxPdfFontAliasMap  m_fontAliasMap;
 
378
  wxPdfFontList      m_fontList;
 
379
 
 
380
  bool               m_defaultEmbed;
 
381
  bool               m_defaultSubset;
 
382
 
 
383
  wxPdfEncodingMap*        m_encodingMap;
 
384
  wxPdfEncodingCheckerMap* m_encodingCheckerMap;
 
385
};
 
386
 
 
387
#include "wxmemdbg.h"
 
388
 
 
389
wxPdfFontManagerBase::wxPdfFontManagerBase()
 
390
{
 
391
  m_defaultEmbed = true;
 
392
  m_defaultSubset = true;
 
393
  {
 
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.
 
397
#if wxUSE_THREADS
 
398
    wxCriticalSectionLocker locker(gs_csFontManager);
 
399
#endif
 
400
    m_searchPaths.Add(wxT("fonts"));
 
401
    m_searchPaths.AddEnvList(wxT("WXPDF_FONTPATH"));
 
402
  }
 
403
  m_encodingMap = new wxPdfEncodingMap();
 
404
  m_encodingCheckerMap = new wxPdfEncodingCheckerMap();
 
405
  InitializeEncodingChecker();
 
406
  InitializeCoreFonts();
 
407
#if wxUSE_UNICODE
 
408
  InitializeCjkFonts();
 
409
#endif
 
410
}
 
411
 
 
412
wxPdfFontManagerBase::~wxPdfFontManagerBase()
 
413
{
 
414
#if wxUSE_THREADS
 
415
  wxCriticalSectionLocker locker(gs_csFontManager);
 
416
#endif
 
417
  m_fontNameMap.clear();
 
418
  m_fontFamilyMap.clear();
 
419
  m_fontAliasMap.clear();
 
420
  size_t n = m_fontList.GetCount();
 
421
  size_t j;
 
422
  for (j = 0; j < n; ++j)
 
423
  {
 
424
    delete m_fontList[j];
 
425
  }
 
426
  m_fontList.clear();
 
427
 
 
428
  wxPdfEncodingMap::iterator encoding;
 
429
  for (encoding = m_encodingMap->begin();
 
430
       encoding != m_encodingMap->end(); ++encoding)
 
431
  {
 
432
    wxPdfEncoding* foundEncoding = encoding->second;
 
433
    delete foundEncoding;
 
434
  }
 
435
  delete m_encodingMap;
 
436
 
 
437
  wxPdfEncodingCheckerMap::iterator checker;
 
438
  for (checker = m_encodingCheckerMap->begin();
 
439
       checker != m_encodingCheckerMap->end(); ++checker)
 
440
  {
 
441
    delete checker->second;
 
442
  }
 
443
  delete m_encodingCheckerMap;
 
444
}
 
445
 
 
446
void
 
447
wxPdfFontManagerBase::AddSearchPath(const wxString& path)
 
448
{
 
449
#if wxUSE_THREADS
 
450
  wxCriticalSectionLocker locker(gs_csFontManager);
 
451
#endif
 
452
  m_searchPaths.Add(path);
 
453
}
 
454
 
 
455
void
 
456
wxPdfFontManagerBase::AddSearchPath(const wxArrayString& pathArray)
 
457
{
 
458
#if wxUSE_THREADS
 
459
  wxCriticalSectionLocker locker(gs_csFontManager);
 
460
#endif
 
461
  m_searchPaths.Add(pathArray);
 
462
}
 
463
 
 
464
bool
 
465
wxPdfFontManagerBase::FindFile(const wxString& fileName, wxString& fullFileName) const
 
466
{
 
467
  bool ok = false;
 
468
  wxFileName myFileName(fileName);
 
469
  fullFileName = wxEmptyString;
 
470
  if (myFileName.IsOk())
 
471
  {
 
472
    if (myFileName.IsRelative())
 
473
    {
 
474
      // Check whether the file is relative to the current working directory
 
475
      if (!(myFileName.MakeAbsolute() && myFileName.FileExists()))
 
476
      {
 
477
        // File not found, search in given search paths
 
478
#if wxUSE_THREADS
 
479
        wxCriticalSectionLocker locker(gs_csFontManager);
 
480
#endif
 
481
        wxString foundFileName = m_searchPaths.FindAbsoluteValidPath(fileName);
 
482
        if (!foundFileName.IsEmpty())
 
483
        {
 
484
          myFileName.Assign(foundFileName);
 
485
        }
 
486
      }
 
487
    }
 
488
    if (myFileName.FileExists() && myFileName.IsFileReadable())
 
489
    {
 
490
      // File exists and is accessible
 
491
      fullFileName = myFileName.GetFullPath();
 
492
      ok = true;
 
493
    }
 
494
    else
 
495
    {
 
496
      wxLogDebug(wxString(wxT("wxPdfFontManagerBase::FindFile: ")) +
 
497
                 wxString::Format(_("File '%s' does not exist."), fileName.c_str()));
 
498
    }
 
499
  }
 
500
  else
 
501
  {
 
502
    wxLogDebug(wxString(wxT("wxPdfFontManagerBase::FindFile: ")) +
 
503
               wxString::Format(_("File name '%s' is invalid."), fileName.c_str()));
 
504
  }
 
505
  return ok;
 
506
}
 
507
 
 
508
bool
 
509
wxPdfFontManagerBase::SetDefaultEmbed(bool embed)
 
510
{
 
511
#if wxUSE_THREADS
 
512
  wxCriticalSectionLocker locker(gs_csFontManager);
 
513
#endif
 
514
  bool previous = m_defaultEmbed;
 
515
  m_defaultEmbed = embed;
 
516
  return previous;
 
517
}
 
518
 
 
519
bool
 
520
wxPdfFontManagerBase::GetDefaultEmbed()
 
521
{
 
522
#if wxUSE_THREADS
 
523
  wxCriticalSectionLocker locker(gs_csFontManager);
 
524
#endif
 
525
  return m_defaultEmbed;
 
526
}
 
527
 
 
528
bool
 
529
wxPdfFontManagerBase::SetDefaultSubset(bool subset)
 
530
{
 
531
#if wxUSE_THREADS
 
532
  wxCriticalSectionLocker locker(gs_csFontManager);
 
533
#endif
 
534
  bool previous = m_defaultSubset;
 
535
  m_defaultSubset = subset;
 
536
  return previous;
 
537
}
 
538
 
 
539
bool
 
540
wxPdfFontManagerBase::GetDefaultSubset()
 
541
{
 
542
#if wxUSE_THREADS
 
543
  wxCriticalSectionLocker locker(gs_csFontManager);
 
544
#endif
 
545
  return m_defaultSubset;
 
546
}
 
547
 
 
548
wxPdfFont
 
549
wxPdfFontManagerBase::RegisterFont(const wxString& fontFileName, const wxString& aliasName, int fontIndex)
 
550
{
 
551
#if !wxUSE_UNICODE
 
552
  wxUnusedVar(fontIndex);
 
553
#endif
 
554
  wxPdfFont font;
 
555
  wxString fullFontFileName;
 
556
  if (FindFile(fontFileName, fullFontFileName))
 
557
  {
 
558
    wxFileName fileName(fullFontFileName);
 
559
    wxString ext = fileName.GetExt().Lower();
 
560
    if (ext.IsSameAs(wxT("ttf")) || ext.IsSameAs(wxT("otf")) || ext.IsSameAs(wxT("ttc")))
 
561
    {
 
562
#if wxUSE_UNICODE
 
563
      // TrueType font, OpenType font, or TrueType collection
 
564
      wxPdfFontParserTrueType fontParser;
 
565
      wxPdfFontData* fontData = fontParser.IdentifyFont(fileName.GetFullPath(), fontIndex);
 
566
      if (fontData != NULL)
 
567
      {
 
568
        fontData->SetAlias(aliasName);
 
569
        if (!AddFont(fontData, font))
 
570
        {
 
571
          delete fontData;
 
572
          wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
573
                     wxString::Format(_("Font file '%s' already registered."), fontFileName.c_str()));
 
574
        }
 
575
      }
 
576
#else
 
577
      wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
578
                 wxString::Format(_("Format of font file '%s' not supported."), fontFileName.c_str()));
 
579
#endif
 
580
    }
 
581
    else if (/* ext.IsSameAs(wxT("pfa")) || */ ext.IsSameAs(wxT("pfb")) || ext.IsEmpty())
 
582
    {
 
583
      // TODO: allow Type1 fonts in PFA format (this requires encoding the binary section)
 
584
#if wxUSE_UNICODE
 
585
      // Type1 font
 
586
      wxPdfFontParserType1 fontParser;
 
587
      wxPdfFontData* fontData = fontParser.IdentifyFont(fileName.GetFullPath(), fontIndex);
 
588
      if (fontData != NULL)
 
589
      {
 
590
        fontData->SetAlias(aliasName);
 
591
        SetFontBaseEncoding(fontData);
 
592
        if (!AddFont(fontData, font))
 
593
        {
 
594
          delete fontData;
 
595
          wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
596
                     wxString::Format(_("Font file '%s' already registered."), fontFileName.c_str()));
 
597
        }
 
598
      }
 
599
#else
 
600
      wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
601
                 wxString::Format(_("Format of font file '%s' not supported."), fontFileName.c_str()));
 
602
#endif
 
603
    }
 
604
    else if (ext.IsSameAs(wxT("xml")))
 
605
    {
 
606
      // wxPdfDocument font description file
 
607
      wxPdfFontData* fontData = LoadFontFromXML(fullFontFileName);
 
608
      if (fontData != NULL)
 
609
      {
 
610
        fontData->SetAlias(aliasName);
 
611
        SetFontBaseEncoding(fontData);
 
612
        if (!AddFont(fontData, font))
 
613
        {
 
614
          delete fontData;
 
615
          wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
616
                     wxString::Format(_("Font file '%s' already registered."), fontFileName.c_str()));
 
617
        }
 
618
      }
 
619
    }
 
620
    else
 
621
    {
 
622
      wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
623
                 wxString::Format(_("Format of font file '%s' not supported."), fontFileName.c_str()));
 
624
    }
 
625
  }
 
626
  else
 
627
  {
 
628
    wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
629
               wxString::Format(_("Font file '%s' does not exist or is not readable."), fontFileName.c_str()));
 
630
  }
 
631
  return font;
 
632
}
 
633
 
 
634
#if wxUSE_UNICODE
 
635
wxPdfFont
 
636
wxPdfFontManagerBase::RegisterFont(const wxFont& font, const wxString& aliasName)
 
637
{
 
638
  wxPdfFont regFont;
 
639
#if defined(__WXMSW__)
 
640
  wxPdfFontParserTrueType fontParser;
 
641
  wxPdfFontData* fontData = fontParser.IdentifyFont(font);
 
642
  if (fontData != NULL)
 
643
  {
 
644
    fontData->SetAlias(aliasName);
 
645
    if (!AddFont(fontData, regFont))
 
646
    {
 
647
      delete fontData;
 
648
      wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
649
                 wxString::Format(_("wxFont '%s' already registered."), font.GetFaceName().c_str()));
 
650
    }
 
651
  }
 
652
#elif defined(__WXGTK20__)
 
653
// TODO: Would testing for __WXGTK__ be sufficient?
 
654
#if 0
 
655
  // TODO: Do we need to load the fontconfig library?
 
656
  FcConfig* fc = FcInitLoadConfigAndFonts();
 
657
  if (fc == NULL)
 
658
  {
 
659
    wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
660
               wxString(_("FontConfig init failed.")));
 
661
    return 0;
 
662
  }
 
663
#endif
 
664
 
 
665
  wxString fontFileName = wxEmptyString;
 
666
  int fontFileIndex = 0;
 
667
  int slant = -1;
 
668
  int weight = -1;
 
669
  int width = -1;
 
670
  wxString fontDesc = font.GetNativeFontInfoUserDesc();
 
671
  wxString faceName = font.GetFaceName();
 
672
  wxCharBuffer faceNameBuffer = faceName.ToUTF8();
 
673
  const char* fontFamily = faceNameBuffer;
 
674
 
 
675
  // Check font slant
 
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;
 
680
  else
 
681
    slant = FC_SLANT_ROMAN;
 
682
 
 
683
  // Check font weight
 
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;
 
691
#endif
 
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;
 
699
#endif
 
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;
 
704
  else
 
705
    weight = FC_WEIGHT_NORMAL;
 
706
 
 
707
  // Check font width
 
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;
 
724
  else
 
725
    width = FC_WIDTH_NORMAL;
 
726
 
 
727
  FcResult res;
 
728
  FcPattern* matchPattern;
 
729
  matchPattern = FcPatternBuild(NULL,
 
730
                                FC_FAMILY, FcTypeString, (FcChar8*) fontFamily,
 
731
                                NULL);
 
732
  if (slant != -1)
 
733
    FcPatternAddInteger(matchPattern, FC_SLANT, slant);
 
734
  if (weight != -1)
 
735
    FcPatternAddInteger(matchPattern, FC_WEIGHT, weight);
 
736
  if (width != -1)
 
737
    FcPatternAddInteger(matchPattern, FC_WIDTH, width);
 
738
 
 
739
  FcConfigSubstitute (NULL, matchPattern, FcMatchPattern);
 
740
  FcDefaultSubstitute (matchPattern);
 
741
 
 
742
  FcPattern* resultPattern = FcFontMatch (NULL, matchPattern, &res);
 
743
  if (resultPattern)
 
744
  {
 
745
    FcChar8* fileName;
 
746
    int id = 0;
 
747
    if (FcPatternGetString (resultPattern, FC_FILE, 0, &fileName) == FcResultMatch)
 
748
    {
 
749
      fontFileName = wxString::FromUTF8((char*) fileName);
 
750
    }
 
751
    else
 
752
    {
 
753
    }
 
754
    if (FcPatternGetInteger (resultPattern, FC_INDEX, 0, &id) == FcResultMatch)
 
755
    {
 
756
      fontFileIndex = id;
 
757
    }
 
758
    FcPatternDestroy (resultPattern);
 
759
  }
 
760
  FcPatternDestroy (matchPattern);
 
761
 
 
762
  if (!fontFileName.IsEmpty())
 
763
  {
 
764
    regFont = RegisterFont(fontFileName, aliasName, fontFileIndex);
 
765
  }
 
766
  else
 
767
  {
 
768
    wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
769
                 wxString::Format(_("Font file name not found for wxFont '%s'."), fontDesc.c_str()));
 
770
  }
 
771
#elif defined(__WXMAC__)
 
772
#if wxPDFMACOSX_HAS_CORE_TEXT
 
773
  wxPdfFontParserTrueType fontParser;
 
774
  wxPdfFontData* fontData = fontParser.IdentifyFont(font);
 
775
  if (fontData != NULL)
 
776
  {
 
777
    fontData->SetAlias(aliasName);
 
778
    if (!AddFont(fontData, regFont))
 
779
    {
 
780
      delete fontData;
 
781
      wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
782
                 wxString::Format(_("wxFont '%s' already registered."), font.GetFaceName().c_str()));
 
783
    }
 
784
  }
 
785
#elif wxPDFMACOSX_HAS_ATSU_TEXT
 
786
  wxString fontFileName = wxEmptyString;
 
787
 
 
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();
 
792
#endif
 
793
#else // wxWidgets 2.8.x
 
794
#ifdef __WXMAC_CLASSIC__
 
795
  wxUint32 atsuFontID = font.GetMacATSUFontID();
 
796
#else
 
797
  wxUint32 atsuFontID = font.MacGetATSUFontID();
 
798
#endif
 
799
#endif
 
800
 
 
801
  FSSpec fileSpecification;
 
802
  FSRef fileReference;
 
803
  if (::ATSFontGetFileSpecification(::FMGetATSFontRefFromFont(atsuFontID), &fileSpecification) == noErr)
 
804
  {
 
805
    if (::FSpMakeFSRef(&fileSpecification, &fileReference) == noErr)
 
806
    {
 
807
      fontFileName = wxMacFSRefToPath(&fileReference);
 
808
    }
 
809
  }
 
810
 
 
811
  if (!fontFileName.IsEmpty())
 
812
  {
 
813
    regFont = RegisterFont(fontFileName, aliasName, 0);
 
814
  }
 
815
  else
 
816
  {
 
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()));
 
820
  }
 
821
#else
 
822
  wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
823
             wxString(_("Method 'RegisterFont' for wxFont instances is not available for platform WXMAC.")));
 
824
#endif
 
825
#else
 
826
  wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFont: ")) +
 
827
             wxString(_("Method 'RegisterFont' for wxFont instances is not available for your platform.")));
 
828
#endif
 
829
  return regFont;
 
830
}
 
831
 
 
832
int
 
833
wxPdfFontManagerBase::RegisterFontCollection(const wxString& fontCollectionFileName)
 
834
{
 
835
  int count = 0;
 
836
  wxString fullFontCollectionFileName;
 
837
  if (FindFile(fontCollectionFileName, fullFontCollectionFileName))
 
838
  {
 
839
    wxFileName fileName(fullFontCollectionFileName);
 
840
    if (fileName.IsOk() && fileName.GetExt().Lower().IsSameAs(wxT("ttc")))
 
841
    {
 
842
      wxPdfFontParserTrueType fontParser;
 
843
      int fontCount = fontParser.GetCollectionFontCount(fullFontCollectionFileName);
 
844
      int j;
 
845
      for (j = 0; j < fontCount; ++j)
 
846
      {
 
847
        wxPdfFont registeredFont = RegisterFont(fileName.GetFullPath(), wxEmptyString, j);
 
848
        if (registeredFont.IsValid())
 
849
        {
 
850
          ++count;
 
851
        }
 
852
      }
 
853
    }
 
854
    else
 
855
    {
 
856
      wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFontCollection: ")) +
 
857
                   wxString::Format(_("Font collection file '%s' has not the file extension '.ttc'."), fontCollectionFileName.c_str()));
 
858
    }
 
859
  }
 
860
  else
 
861
  {
 
862
    wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterFontCollection: ")) +
 
863
               wxString::Format(_("Font collection file '%s' does not exist or is not readable."), fontCollectionFileName.c_str()));
 
864
  }
 
865
  return count;
 
866
}
 
867
#endif
 
868
 
 
869
bool
 
870
wxPdfFontManagerBase::RegisterFontCJK(const wxString& family)
 
871
{
 
872
  bool ok = false;
 
873
  wxPdfFontFamilyMap::const_iterator familyIter = m_fontFamilyMap.find(family.Lower());
 
874
  if (familyIter == m_fontFamilyMap.end())
 
875
  {
 
876
    wxString fontFileName = family.Lower() + wxString(wxT(".xml"));
 
877
    wxString fullFontFileName;
 
878
    if (FindFile(fontFileName, fullFontFileName))
 
879
    {
 
880
      ok = RegisterFontCJK(fullFontFileName, wxT(""), family);
 
881
      if (ok)
 
882
      {
 
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);
 
888
      }
 
889
    }
 
890
    else
 
891
    {
 
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()));
 
894
    }
 
895
  }
 
896
  else
 
897
  {
 
898
    wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFontCJK: ")) +
 
899
               wxString::Format(_("CJK family '%s' already registered."), family.c_str()));
 
900
    ok = true;
 
901
  }
 
902
  return ok;
 
903
}
 
904
 
 
905
#if wxUSE_UNICODE
 
906
int
 
907
wxPdfFontManagerBase::RegisterSystemFonts()
 
908
{
 
909
  int count = 0;
 
910
#if defined(__WXMSW__)
 
911
  wxString strFont;
 
912
  if (wxGetOsVersion() == wxOS_WINDOWS_NT)
 
913
  {
 
914
    strFont = wxT("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
 
915
  }
 
916
  else
 
917
  {
 
918
    strFont = wxT("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Fonts");
 
919
  }
 
920
 
 
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))
 
929
  {
 
930
    fontDirectory += wxT("\\");
 
931
  }
 
932
  fontDirectory += wxT("Fonts\\");
 
933
  wxString strValueName;
 
934
  wxString strValueData;
 
935
  wxString fontFileName;
 
936
  long nIndex;
 
937
  fontRegKey->GetFirstValue(strValueName, nIndex);
 
938
  size_t i;
 
939
  for (i = 0; i < nValues; ++i)
 
940
  {
 
941
    fontRegKey->QueryValue(strValueName, fontFileName);
 
942
    if (fontFileName.Find(wxT('\\')) == wxNOT_FOUND)
 
943
    {
 
944
      fontFileName.Prepend(fontDirectory);
 
945
    }
 
946
    if (fontFileName.Lower().EndsWith(wxT(".ttc")))
 
947
    {
 
948
      count += RegisterFontCollection(fontFileName);
 
949
    }
 
950
    else
 
951
    {
 
952
      wxPdfFont registeredFont = RegisterFont(fontFileName);
 
953
      if (registeredFont.IsValid())
 
954
      {
 
955
        ++count;
 
956
      }
 
957
    }
 
958
    fontRegKey->GetNextValue(strValueName, nIndex);
 
959
  }
 
960
  fontRegKey->Close();
 
961
  delete fontRegKey;
 
962
#elif defined(__WXGTK20__)
 
963
// TODO: Would testing for __WXGTK__ be sufficient?
 
964
#if 0
 
965
  // TODO: Do we need to load the fontconfig library?
 
966
  FcConfig* fc = FcInitLoadConfigAndFonts();
 
967
  if (fc == NULL)
 
968
  {
 
969
    wxLogError(wxString(wxT("wxPdfFontManagerBase::RegisterSystemFonts: ")) +
 
970
               wxString(_("FontConfig init failed.")));
 
971
    return 0;
 
972
  }
 
973
#endif
 
974
  FcPattern* pat = FcPatternBuild(NULL,
 
975
                                  FC_OUTLINE, FcTypeBool, 1,
 
976
                                  FC_SCALABLE, FcTypeBool, 1,
 
977
                                  NULL);
 
978
  FcObjectSet* os = FcObjectSetBuild (FC_FAMILY,
 
979
                                      FC_STYLE,
 
980
                                      FC_FULLNAME,
 
981
                                      FC_FILE,
 
982
                                      FC_INDEX,
 
983
                                      NULL);
 
984
  // TODO: Add FC_OUTLINE, FC_WEIGHT, FC_SLANT ?
 
985
  FcFontSet* fs = FcFontList(0, pat, os);
 
986
  FcObjectSetDestroy(os);
 
987
  FcPatternDestroy(pat);
 
988
  if (fs != NULL)
 
989
  {
 
990
    int j;
 
991
    for (j = 0; j < fs->nfont; ++j)
 
992
    {
 
993
      FcChar8* file;
 
994
      if (FcPatternGetString(fs->fonts[j], FC_FILE, 0, &file) == FcResultMatch)
 
995
      {
 
996
        int fontFileIndex = 0;
 
997
        int id = 0;
 
998
        if (FcPatternGetInteger (fs->fonts[j], FC_INDEX, 0, &id) == FcResultMatch)
 
999
        {
 
1000
          fontFileIndex = id;
 
1001
        }
 
1002
        wxString fontFileName = wxString::FromUTF8((char*) file);
 
1003
        wxPdfFont registeredFont = RegisterFont(fontFileName, wxEmptyString, fontFileIndex);
 
1004
        if (registeredFont.IsValid())
 
1005
        {
 
1006
          ++count;
 
1007
        }
 
1008
      }
 
1009
    }
 
1010
    FcFontSetDestroy(fs);
 
1011
  }
 
1012
#elif defined(__WXMAC__)
 
1013
  count += RegisterFontDirectory(wxT("/System/Library/Fonts"));
 
1014
  count += RegisterFontDirectory(wxT("/Library/Fonts"));
 
1015
#else
 
1016
  wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterSystemFonts: ")) +
 
1017
               wxString(_("Method is not available for your platform.")));
 
1018
#endif
 
1019
  return count;
 
1020
}
 
1021
 
 
1022
class wxPdfFontDirTraverser : public wxDirTraverser
 
1023
{
 
1024
public:
 
1025
  wxPdfFontDirTraverser(wxPdfFontManagerBase* fontManager)
 
1026
    : m_fontManager(fontManager), m_count(0)
 
1027
  {
 
1028
  }
 
1029
 
 
1030
  virtual wxDirTraverseResult OnFile(const wxString& fileName)
 
1031
  {
 
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")))
 
1036
    {
 
1037
      wxPdfFont registeredFont = m_fontManager->RegisterFont(fontFileName.GetFullPath());
 
1038
      if (registeredFont.IsValid())
 
1039
      {
 
1040
        ++m_count;
 
1041
      }
 
1042
    }
 
1043
    else if (ext.IsSameAs(wxT("ttc")))
 
1044
    {
 
1045
      m_count += m_fontManager->RegisterFontCollection(fontFileName.GetFullPath());
 
1046
    }
 
1047
    return wxDIR_CONTINUE;
 
1048
  }
 
1049
 
 
1050
  virtual wxDirTraverseResult OnDir(const wxString& WXUNUSED(dirname))
 
1051
  {
 
1052
    return wxDIR_CONTINUE;
 
1053
  }
 
1054
 
 
1055
  int GetCount() const
 
1056
  {
 
1057
    return m_count;
 
1058
  }
 
1059
 
 
1060
private:
 
1061
  wxPdfFontManagerBase* m_fontManager;
 
1062
  int                   m_count;
 
1063
};
 
1064
 
 
1065
int
 
1066
wxPdfFontManagerBase::RegisterFontDirectory(const wxString& directory, bool recursive)
 
1067
{
 
1068
  int count = 0;
 
1069
  if (wxDir::Exists(directory))
 
1070
  {
 
1071
    wxDir fontDir(directory);
 
1072
    if (fontDir.IsOpened())
 
1073
    {
 
1074
      wxPdfFontDirTraverser fontDirTraverser(this);
 
1075
      int flags = (recursive) ? wxDIR_FILES | wxDIR_DIRS : wxDIR_FILES;
 
1076
      fontDir.Traverse(fontDirTraverser, wxEmptyString, flags);
 
1077
      count = fontDirTraverser.GetCount();
 
1078
    }
 
1079
    else
 
1080
    {
 
1081
      wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFontDirectory: ")) +
 
1082
                   wxString::Format(_("Directory '%s' could not be opened."),directory.c_str()));
 
1083
    }
 
1084
  }
 
1085
  else
 
1086
  {
 
1087
    wxLogWarning(wxString(wxT("wxPdfFontManagerBase::RegisterFontDirectory: ")) +
 
1088
                 wxString::Format(_("Directory '%s' does not exist."),directory.c_str()));
 
1089
  }
 
1090
  return count;
 
1091
}
 
1092
#endif
 
1093
 
 
1094
wxPdfFont
 
1095
wxPdfFontManagerBase::GetFont(const wxString& fontName, int fontStyle) const
 
1096
{
 
1097
#if wxUSE_THREADS
 
1098
  wxCriticalSectionLocker locker(gs_csFontManager);
 
1099
#endif
 
1100
  wxString lcFontName = fontName.Lower();
 
1101
  int searchStyle = (fontStyle & ~wxPDF_FONTSTYLE_DECORATION_MASK) & wxPDF_FONTSTYLE_MASK;
 
1102
  wxPdfFontData* fontData = NULL;
 
1103
 
 
1104
  // Check whether font name equals font family
 
1105
  wxPdfFontFamilyMap::const_iterator familyIter = m_fontFamilyMap.find(lcFontName);
 
1106
  if (familyIter == m_fontFamilyMap.end())
 
1107
  {
 
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())
 
1111
    {
 
1112
      familyIter = m_fontFamilyMap.find(aliasIter->second);
 
1113
    }
 
1114
  }
 
1115
 
 
1116
  if (familyIter != m_fontFamilyMap.end())
 
1117
  {
 
1118
    // 2. Check whether the family contains a font with the requested style
 
1119
    size_t n = familyIter->second.GetCount();
 
1120
    size_t j;
 
1121
    for (j = 0; j < n && fontData == NULL; ++j)
 
1122
    {
 
1123
      fontData = m_fontList[familyIter->second[j]]->GetFontData();
 
1124
      if (fontData->GetStyle() != searchStyle)
 
1125
      {
 
1126
        fontData = NULL;
 
1127
      }
 
1128
    }
 
1129
  }
 
1130
 
 
1131
  if (fontData == NULL)
 
1132
  {
 
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())
 
1136
    {
 
1137
      fontData = m_fontList[fontIter->second]->GetFontData();
 
1138
    }
 
1139
    else
 
1140
    {
 
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()));
 
1144
    }
 
1145
  }
 
1146
  wxPdfFont font(fontData, fontStyle);
 
1147
  font.SetEmbed(m_defaultEmbed);
 
1148
  font.SetSubset(m_defaultSubset);
 
1149
  return font;
 
1150
}
 
1151
 
 
1152
wxPdfFont
 
1153
wxPdfFontManagerBase::GetFont(const wxString& fontName, const wxString& fontStyle) const
 
1154
{
 
1155
  int style = wxPDF_FONTSTYLE_REGULAR;
 
1156
  wxString localStyle = fontStyle.Lower();
 
1157
  if (localStyle.length() > 2)
 
1158
  {
 
1159
    if (localStyle.Find(wxT("bold")) != wxNOT_FOUND)
 
1160
    {
 
1161
      style |= wxPDF_FONTSTYLE_BOLD;
 
1162
    }
 
1163
    if (localStyle.Find(wxT("italic")) != wxNOT_FOUND || localStyle.Find(wxT("oblique")) != wxNOT_FOUND)
 
1164
    {
 
1165
      style |= wxPDF_FONTSTYLE_ITALIC;
 
1166
    }
 
1167
  }
 
1168
  else
 
1169
  {
 
1170
    if (localStyle.Find(wxT("b")) != wxNOT_FOUND)
 
1171
    {
 
1172
      style |= wxPDF_FONTSTYLE_BOLD;
 
1173
    }
 
1174
    if (localStyle.Find(wxT("i")) != wxNOT_FOUND)
 
1175
    {
 
1176
      style |= wxPDF_FONTSTYLE_ITALIC;
 
1177
    }
 
1178
  }
 
1179
  return GetFont(fontName, style);
 
1180
}
 
1181
 
 
1182
wxPdfFont
 
1183
wxPdfFontManagerBase::GetFont(size_t fontIndex) const
 
1184
{
 
1185
#if wxUSE_THREADS
 
1186
  wxCriticalSectionLocker locker(gs_csFontManager);
 
1187
#endif
 
1188
  wxPdfFont font;
 
1189
  if (fontIndex < m_fontList.GetCount())
 
1190
  {
 
1191
    font = wxPdfFont(m_fontList[fontIndex]->GetFontData());
 
1192
  }
 
1193
  return font;
 
1194
}
 
1195
 
 
1196
size_t
 
1197
wxPdfFontManagerBase::GetFontCount() const
 
1198
{
 
1199
#if wxUSE_THREADS
 
1200
  wxCriticalSectionLocker locker(gs_csFontManager);
 
1201
#endif
 
1202
  return m_fontList.GetCount();
 
1203
}
 
1204
 
 
1205
bool
 
1206
wxPdfFontManagerBase::InitializeFontData(const wxPdfFont& font)
 
1207
{
 
1208
  bool ok = false;
 
1209
  if (font.m_fontData != NULL)
 
1210
  {
 
1211
    ok = font.m_fontData->IsInitialized();
 
1212
    if (!ok)
 
1213
    {
 
1214
#if wxUSE_THREADS
 
1215
      wxCriticalSectionLocker locker(gs_csFontManager);
 
1216
#endif
 
1217
      ok = font.m_fontData->Initialize();
 
1218
    }
 
1219
  }
 
1220
  return ok;
 
1221
}
 
1222
 
 
1223
bool
 
1224
wxPdfFontManagerBase::RegisterEncoding(const wxPdfEncoding& encoding)
 
1225
{
 
1226
  bool ok = true;
 
1227
  wxString encodingName = encoding.GetEncodingName().Lower();
 
1228
  if (m_encodingMap->find(encodingName) == m_encodingMap->end())
 
1229
  {
 
1230
#if wxUSE_THREADS
 
1231
    wxCriticalSectionLocker locker(gs_csFontManager);
 
1232
#endif
 
1233
    wxPdfEncoding* addedEncoding = new wxPdfEncoding(encoding);
 
1234
    if (addedEncoding->IsOk())
 
1235
    {
 
1236
      addedEncoding->InitializeEncodingMap();
 
1237
      (*m_encodingMap)[encodingName] = addedEncoding;
 
1238
    }
 
1239
    else
 
1240
    {
 
1241
      ok = false;
 
1242
    }
 
1243
  }
 
1244
  return ok;
 
1245
}
 
1246
 
 
1247
void
 
1248
wxPdfFontManagerBase::SetFontBaseEncoding(wxPdfFontData* fontData)
 
1249
{
 
1250
  if (fontData != NULL)
 
1251
  {
 
1252
    wxString fontType = fontData->GetType();
 
1253
    wxString encoding = fontData->GetEncoding();
 
1254
    if (encoding.IsEmpty())
 
1255
    {
 
1256
      encoding = wxT("iso-8859-1");
 
1257
    }
 
1258
    if (fontType.IsSameAs(wxT("TrueType")) || fontType.IsSameAs(wxT("Type1")))
 
1259
    {
 
1260
      if (RegisterEncoding(encoding))
 
1261
      {
 
1262
        wxPdfEncodingMap::const_iterator beIter = m_encodingMap->find(encoding);
 
1263
        wxPdfEncoding* baseEncoding = (beIter != m_encodingMap->end()) ? beIter->second : NULL;
 
1264
        fontData->SetEncoding(baseEncoding);
 
1265
      }
 
1266
    }
 
1267
    else if (fontType.IsSameAs(wxT("Type0")))
 
1268
    {
 
1269
      wxPdfEncodingCheckerMap::const_iterator ecIter = m_encodingCheckerMap->find(encoding);
 
1270
      wxPdfEncodingChecker* encodingChecker = (ecIter != m_encodingCheckerMap->end()) ? ecIter->second : NULL;
 
1271
      fontData->SetEncodingChecker(encodingChecker);
 
1272
    }
 
1273
  }
 
1274
}
 
1275
 
 
1276
const wxPdfEncoding*
 
1277
wxPdfFontManagerBase::GetEncoding(const wxString& encodingName)
 
1278
{
 
1279
#if wxUSE_THREADS
 
1280
  wxCriticalSectionLocker locker(gs_csFontManager);
 
1281
#endif
 
1282
  wxPdfEncoding* foundEncoding = NULL;
 
1283
  if (RegisterEncoding(encodingName))
 
1284
  {
 
1285
    wxPdfEncodingMap::const_iterator encoding = m_encodingMap->find(encodingName.Lower());
 
1286
    if (encoding != m_encodingMap->end())
 
1287
    {
 
1288
      foundEncoding = encoding->second;
 
1289
    }
 
1290
  }
 
1291
  return foundEncoding;
 
1292
}
 
1293
 
 
1294
wxString
 
1295
wxPdfFontManagerBase::ConvertStyleToString(int fontStyle)
 
1296
{
 
1297
  wxString style = wxEmptyString;
 
1298
  if ((fontStyle & wxPDF_FONTSTYLE_BOLDITALIC) == wxPDF_FONTSTYLE_BOLDITALIC)
 
1299
  {
 
1300
    style = wxString(_("BoldItalic"));
 
1301
  }
 
1302
  else if (fontStyle & wxPDF_FONTSTYLE_BOLD)
 
1303
  {
 
1304
    style = wxString(_("Bold"));
 
1305
  }
 
1306
  else if (fontStyle & wxPDF_FONTSTYLE_ITALIC)
 
1307
  {
 
1308
    style = wxString(_("Italic"));
 
1309
  }
 
1310
  else
 
1311
  {
 
1312
    style = wxString(_("Regular"));
 
1313
  }
 
1314
  return style;
 
1315
}
 
1316
 
 
1317
// --- wxPdfFontManagerBase (private)
 
1318
 
 
1319
void
 
1320
wxPdfFontManagerBase::InitializeCoreFonts()
 
1321
{
 
1322
  wxPdfFontDataCore* coreFontData;
 
1323
  if (!RegisterEncoding(wxT("winansi")) ||
 
1324
      !RegisterEncoding(wxT("iso-8859-1")))
 
1325
  {
 
1326
    wxLogDebug(wxString(wxT("wxPdfFontManagerBase::InitializeCoreFonts: ")) +
 
1327
               wxString::Format(_("Registering encodings for core fonts failed.")));
 
1328
  }
 
1329
  int j;
 
1330
  for (j = 0; gs_coreFontTable[j].name != wxEmptyString; ++j)
 
1331
  {
 
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");
 
1336
 
 
1337
    wxPdfEncodingMap::const_iterator beIter = m_encodingMap->find(encoding);
 
1338
    wxPdfEncoding* baseEncoding = (beIter != m_encodingMap->end()) ? beIter->second : NULL;
 
1339
 
 
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);
 
1350
  }
 
1351
}
 
1352
 
 
1353
#if wxUSE_UNICODE
 
1354
void
 
1355
wxPdfFontManagerBase::InitializeCjkFonts()
 
1356
{
 
1357
  const wxChar* fontStyles[4] = { wxT(""), wxT(",Bold"), wxT(",Italic"), wxT(",BoldItalic") };
 
1358
  wxString fontName;
 
1359
  wxString fontAlias;
 
1360
  wxPdfFontDataType0* cjkFontData;
 
1361
  bool ok;
 
1362
  int j, k;
 
1363
  for (j = 0; gs_cjkFontTable[j].name != wxEmptyString; ++j)
 
1364
  {
 
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)
 
1369
    {
 
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);
 
1389
      if (!ok)
 
1390
      {
 
1391
        delete cjkFontData;
 
1392
      }
 
1393
    }
 
1394
  }
 
1395
}
 
1396
#endif
 
1397
 
 
1398
void
 
1399
wxPdfFontManagerBase::InitializeEncodingChecker()
 
1400
{
 
1401
  int j;
 
1402
  for (j = 0; gs_encodingTableData[j].m_encodingName != NULL; ++j)
 
1403
  {
 
1404
    wxString encodingName(gs_encodingTableData[j].m_encodingName);
 
1405
    wxPdfEncodingChecker* encodingChecker;
 
1406
    if (gs_encodingTableData[j].m_encodingTable != NULL)
 
1407
    {
 
1408
      encodingChecker = new wxPdfCodepageChecker(gs_encodingTableData[j].m_encodingName,
 
1409
                                                 gs_encodingTableData[j].m_encodingTableSize,
 
1410
                                                 gs_encodingTableData[j].m_encodingTable);
 
1411
    }
 
1412
    else
 
1413
    {
 
1414
      encodingChecker = new wxPdfCjkChecker(gs_encodingTableData[j].m_encodingName,
 
1415
                                            gs_encodingTableData[j].m_encodingBase);
 
1416
    }
 
1417
    (*m_encodingCheckerMap)[encodingName] = encodingChecker;
 
1418
  }
 
1419
}
 
1420
 
 
1421
bool
 
1422
wxPdfFontManagerBase::RegisterEncoding(const wxString& encoding)
 
1423
{
 
1424
  bool ok = true;
 
1425
  wxString encodingName = encoding.Lower();
 
1426
  if (m_encodingMap->find(encodingName) == m_encodingMap->end())
 
1427
  {
 
1428
    wxPdfEncoding* addedEncoding = new wxPdfEncoding();
 
1429
    if (addedEncoding->SetEncoding(encoding))
 
1430
    {
 
1431
      addedEncoding->InitializeEncodingMap();
 
1432
      (*m_encodingMap)[encodingName] = addedEncoding;
 
1433
    }
 
1434
    else
 
1435
    {
 
1436
      wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterEncoding: ")) +
 
1437
                 wxString::Format(_("Encoding '%s' is unknown."), encoding.c_str()));
 
1438
      delete addedEncoding;
 
1439
      ok = false;
 
1440
    }
 
1441
  }
 
1442
  return ok;
 
1443
}
 
1444
 
 
1445
bool
 
1446
wxPdfFontManagerBase::RegisterFontCJK(const wxString& fontFileName, const wxString& fontStyle, const wxString& alias)
 
1447
{
 
1448
  bool ok = false;
 
1449
  wxPdfFontData* fontData;
 
1450
  fontData = LoadFontFromXML(fontFileName);
 
1451
  if (fontData != NULL)
 
1452
  {
 
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);
 
1461
    if (!ok)
 
1462
    {
 
1463
      wxLogDebug(wxString(wxT("wxPdfFontManagerBase::RegisterFontCJK: ")) +
 
1464
                 wxString::Format(_("CJK font '%s' already registered."), fontName.c_str()));
 
1465
    }
 
1466
  }
 
1467
  return ok;
 
1468
}
 
1469
 
 
1470
wxPdfFontData*
 
1471
wxPdfFontManagerBase::LoadFontFromXML(const wxString& fontFileName)
 
1472
{
 
1473
  wxPdfFontData* fontData = NULL;
 
1474
  wxFileName fileName(fontFileName);
 
1475
  wxFileSystem fs;
 
1476
 
 
1477
  // Open font metrics XML file
 
1478
  wxFSFile* xmlFontMetrics = fs.OpenFile(wxFileSystem::FileNameToURL(fileName));
 
1479
  if (xmlFontMetrics != NULL)
 
1480
  {
 
1481
    // Load the XML file
 
1482
    wxXmlDocument fontMetrics;
 
1483
    bool loaded = fontMetrics.Load(*xmlFontMetrics->GetStream());
 
1484
    delete xmlFontMetrics;
 
1485
    if (loaded)
 
1486
    {
 
1487
      if (fontMetrics.IsOk() && fontMetrics.GetRoot()->GetName().IsSameAs(wxT("wxpdfdoc-font-metrics")))
 
1488
      {
 
1489
        wxString fontType;
 
1490
        wxXmlNode* root = fontMetrics.GetRoot();
 
1491
#if wxCHECK_VERSION(2,9,0)
 
1492
        if (root->GetAttribute(wxT("type"), &fontType))
 
1493
#else
 
1494
        if (root->GetPropVal(wxT("type"), &fontType))
 
1495
#endif
 
1496
        {
 
1497
          if (fontType.IsSameAs(wxT("TrueType")))
 
1498
          {
 
1499
            fontData = new wxPdfFontDataTrueType();
 
1500
          }
 
1501
          else if (fontType.IsSameAs(wxT("Type1")))
 
1502
          {
 
1503
            fontData = new wxPdfFontDataType1();
 
1504
          }
 
1505
#if wxUSE_UNICODE
 
1506
          else if (fontType.IsSameAs(wxT("TrueTypeUnicode")))
 
1507
          {
 
1508
            fontData = new wxPdfFontDataTrueTypeUnicode();
 
1509
          }
 
1510
          else if (fontType.IsSameAs(wxT("OpenTypeUnicode")))
 
1511
          {
 
1512
            fontData = new wxPdfFontDataOpenTypeUnicode();
 
1513
          }
 
1514
          else if (fontType.IsSameAs(wxT("Type0")))
 
1515
          {
 
1516
            fontData = new wxPdfFontDataType0();
 
1517
          }
 
1518
#endif
 
1519
          else
 
1520
          {
 
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()));
 
1524
          }
 
1525
          if (fontData != NULL)
 
1526
          {
 
1527
            fontData->SetFilePath(fileName.GetPath());
 
1528
            if (!fontData->LoadFontMetrics(root))
 
1529
            {
 
1530
              wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
 
1531
                         wxString::Format(_("Loading of font metrics failed for font file '%s'."), fontFileName.c_str()));
 
1532
              delete fontData;
 
1533
              fontData = NULL;
 
1534
            }
 
1535
          }
 
1536
        }
 
1537
        else
 
1538
        {
 
1539
          // Font type not specified
 
1540
          wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
 
1541
                     wxString::Format(_("Font type not specified for font '%s'."), fontFileName.c_str()));
 
1542
        }
 
1543
      }
 
1544
      else
 
1545
      {
 
1546
        // Not a font metrics file
 
1547
        wxLogError(wxString(wxT("wxPdfFontManagerBase::LoadFontFromXML: ")) +
 
1548
                   wxString::Format(_("Font metrics file '%s' invalid."), fontFileName.c_str()));
 
1549
      }
 
1550
    }
 
1551
    else
 
1552
    {
 
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()));
 
1556
    }
 
1557
  }
 
1558
  else
 
1559
  {
 
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()));
 
1563
  }
 
1564
  return fontData;
 
1565
}
 
1566
 
 
1567
bool
 
1568
wxPdfFontManagerBase::IsRegistered(wxPdfFontData* fontData)
 
1569
{
 
1570
#if wxUSE_THREADS
 
1571
  wxCriticalSectionLocker locker(gs_csFontManager);
 
1572
#endif
 
1573
  wxString fontName = fontData->GetName();
 
1574
  wxPdfFontNameMap::const_iterator font = m_fontNameMap.find(fontName.Lower());
 
1575
  return (font != m_fontNameMap.end());
 
1576
}
 
1577
 
 
1578
bool
 
1579
wxPdfFontManagerBase::AddFont(wxPdfFontData* fontData)
 
1580
{
 
1581
  wxPdfFont font;
 
1582
  return AddFont(fontData, font);
 
1583
}
 
1584
 
 
1585
bool
 
1586
wxPdfFontManagerBase::AddFont(wxPdfFontData* fontData, wxPdfFont& font)
 
1587
{
 
1588
  bool ok = false;
 
1589
#if wxUSE_THREADS
 
1590
  wxCriticalSectionLocker locker(gs_csFontManager);
 
1591
#endif
 
1592
  wxString fontName = fontData->GetName().Lower();
 
1593
  wxString family = fontData->GetFamily().Lower();
 
1594
  wxString alias = fontData->GetAlias().Lower();
 
1595
 
 
1596
  wxPdfFontNameMap::const_iterator fontIter = m_fontNameMap.find(fontName.Lower());
 
1597
  if (fontIter == m_fontNameMap.end())
 
1598
  {
 
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);
 
1605
    ok = true;
 
1606
 
 
1607
    // Register Postscript font name
 
1608
    m_fontNameMap[fontName] = pos;
 
1609
 
 
1610
    // Register all full font names
 
1611
    size_t j;
 
1612
    for (j = 0; j < fullNames.GetCount(); ++j)
 
1613
    {
 
1614
      m_fontNameMap[fullNames[j].Lower()] = pos;
 
1615
    }
 
1616
 
 
1617
    // Register font in family
 
1618
    if (!family.IsEmpty())
 
1619
    {
 
1620
      m_fontFamilyMap[family].Add(pos);
 
1621
    }
 
1622
    else if (!alias.IsEmpty())
 
1623
    {
 
1624
      m_fontFamilyMap[alias].Add(pos);
 
1625
    }
 
1626
  }
 
1627
  else
 
1628
  {
 
1629
    font = wxPdfFont(m_fontList[fontIter->second]->GetFontData());
 
1630
  }
 
1631
 
 
1632
  // Register family alias
 
1633
  if (!alias.IsEmpty() && !alias.IsSameAs(family))
 
1634
  {
 
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())
 
1638
    {
 
1639
      if (!aliasIter->second.IsSameAs(family))
 
1640
      {
 
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()));
 
1644
      }
 
1645
    }
 
1646
    else
 
1647
    {
 
1648
      // alias not previously assigned, remember assignment
 
1649
      m_fontAliasMap[alias] = family;
 
1650
    }
 
1651
  }
 
1652
  return ok;
 
1653
}
 
1654
 
 
1655
// --- wxPdfFontManager
 
1656
 
 
1657
/* C::B begin */
 
1658
#ifndef wxPDF_USE_WXMODULE
 
1659
  #define wxPDF_USE_WXMODULE 1
 
1660
#endif
 
1661
 
 
1662
#if wxPDF_USE_WXMODULE
 
1663
wxPdfFontManager* wxPdfFontManager::ms_fontManager = NULL;
 
1664
#else
 
1665
wxPdfFontManager* wxPdfFontManager::ms_fontManager = new wxPdfFontManager();
 
1666
#endif // wxPDF_USE_WXMODULE
 
1667
/* C::B end */
 
1668
 
 
1669
wxPdfFontManager::wxPdfFontManager()
 
1670
{
 
1671
  m_fontManagerBase = new wxPdfFontManagerBase();
 
1672
}
 
1673
 
 
1674
wxPdfFontManager::~wxPdfFontManager()
 
1675
{
 
1676
  delete m_fontManagerBase;
 
1677
/* C::B begin */
 
1678
#if !wxPDF_USE_WXMODULE
 
1679
  if ( ms_fontManager )
 
1680
  {
 
1681
    delete ms_fontManager;
 
1682
    ms_fontManager = NULL;
 
1683
  }
 
1684
#endif // !wxPDF_USE_WXMODULE
 
1685
/* C::B end */
 
1686
}
 
1687
 
 
1688
wxPdfFontManager*
 
1689
wxPdfFontManager::GetFontManager()
 
1690
{
 
1691
  return ms_fontManager;
 
1692
}
 
1693
 
 
1694
 
 
1695
void
 
1696
wxPdfFontManager::AddSearchPath(const wxString& path)
 
1697
{
 
1698
  m_fontManagerBase->AddSearchPath(path);
 
1699
}
 
1700
 
 
1701
void
 
1702
wxPdfFontManager::AddSearchPath(const wxArrayString& pathArray)
 
1703
{
 
1704
  m_fontManagerBase->AddSearchPath(pathArray);
 
1705
}
 
1706
 
 
1707
bool
 
1708
wxPdfFontManager::SetDefaultEmbed(bool embed)
 
1709
{
 
1710
  return m_fontManagerBase->SetDefaultEmbed(embed);
 
1711
}
 
1712
 
 
1713
bool
 
1714
wxPdfFontManager::GetDefaultEmbed()
 
1715
{
 
1716
  return m_fontManagerBase->GetDefaultEmbed();
 
1717
}
 
1718
 
 
1719
bool
 
1720
wxPdfFontManager::SetDefaultSubset(bool subset)
 
1721
{
 
1722
  return m_fontManagerBase->SetDefaultSubset(subset);
 
1723
}
 
1724
 
 
1725
bool
 
1726
wxPdfFontManager::GetDefaultSubset()
 
1727
{
 
1728
  return m_fontManagerBase->GetDefaultSubset();
 
1729
}
 
1730
 
 
1731
wxPdfFont
 
1732
wxPdfFontManager::RegisterFont(const wxString& fontFileName, const wxString& aliasName, int fontIndex)
 
1733
{
 
1734
  return m_fontManagerBase->RegisterFont(fontFileName, aliasName, fontIndex);
 
1735
}
 
1736
 
 
1737
wxPdfFont
 
1738
wxPdfFontManager::RegisterFont(const wxFont& font, const wxString& aliasName)
 
1739
{
 
1740
#if wxUSE_UNICODE
 
1741
  return m_fontManagerBase->RegisterFont(font, aliasName);
 
1742
#else
 
1743
  wxUnusedVar(font);
 
1744
  wxUnusedVar(aliasName);
 
1745
  return wxPdfFont();
 
1746
#endif
 
1747
}
 
1748
 
 
1749
int
 
1750
wxPdfFontManager::RegisterFontCollection(const wxString& fontCollectionFileName)
 
1751
{
 
1752
#if wxUSE_UNICODE
 
1753
  return m_fontManagerBase->RegisterFontCollection(fontCollectionFileName);
 
1754
#else
 
1755
  wxUnusedVar(fontCollectionFileName);
 
1756
  return 0;
 
1757
#endif
 
1758
}
 
1759
 
 
1760
bool
 
1761
wxPdfFontManager::RegisterFontCJK(const wxString& family)
 
1762
{
 
1763
  return m_fontManagerBase->RegisterFontCJK(family);
 
1764
}
 
1765
 
 
1766
int
 
1767
wxPdfFontManager::RegisterSystemFonts()
 
1768
{
 
1769
#if wxUSE_UNICODE
 
1770
  return m_fontManagerBase->RegisterSystemFonts();
 
1771
#else
 
1772
  return 0;
 
1773
#endif
 
1774
}
 
1775
 
 
1776
int
 
1777
wxPdfFontManager::RegisterFontDirectory(const wxString& directory, bool recursive)
 
1778
{
 
1779
#if wxUSE_UNICODE
 
1780
  return m_fontManagerBase->RegisterFontDirectory(directory, recursive);
 
1781
#else
 
1782
  wxUnusedVar(directory);
 
1783
  wxUnusedVar(recursive);
 
1784
  return 0;
 
1785
#endif
 
1786
}
 
1787
 
 
1788
wxPdfFont
 
1789
wxPdfFontManager::GetFont(const wxString& fontName, int fontStyle) const
 
1790
{
 
1791
  return m_fontManagerBase->GetFont(fontName, fontStyle);
 
1792
}
 
1793
 
 
1794
wxPdfFont
 
1795
wxPdfFontManager::GetFont(const wxString& fontName, const wxString& fontStyle) const
 
1796
{
 
1797
  return m_fontManagerBase->GetFont(fontName, fontStyle);
 
1798
}
 
1799
 
 
1800
wxPdfFont
 
1801
wxPdfFontManager::GetFont(size_t fontIndex) const
 
1802
{
 
1803
  return m_fontManagerBase->GetFont(fontIndex);
 
1804
}
 
1805
 
 
1806
size_t
 
1807
wxPdfFontManager::GetFontCount() const
 
1808
{
 
1809
  return m_fontManagerBase->GetFontCount();
 
1810
}
 
1811
 
 
1812
bool
 
1813
wxPdfFontManager::InitializeFontData(const wxPdfFont& font)
 
1814
{
 
1815
  bool ok = false;
 
1816
  if (font.IsValid())
 
1817
  {
 
1818
    ok = m_fontManagerBase->InitializeFontData(font);
 
1819
  }
 
1820
  return ok;
 
1821
}
 
1822
 
 
1823
bool
 
1824
wxPdfFontManager::RegisterEncoding(const wxPdfEncoding& encoding)
 
1825
{
 
1826
  return m_fontManagerBase->RegisterEncoding(encoding);
 
1827
}
 
1828
 
 
1829
const wxPdfEncoding*
 
1830
wxPdfFontManager::GetEncoding(const wxString& encodingName)
 
1831
{
 
1832
  return m_fontManagerBase->GetEncoding(encodingName);
 
1833
}
 
1834
 
 
1835
// A module to allow initialization/cleanup of wxPdfDocument
 
1836
// singletons without calling these functions from app.cpp.
 
1837
 
 
1838
/* C::B begin */
 
1839
#if wxPDF_USE_WXMODULE
 
1840
 
 
1841
#include <wx/module.h>
 
1842
/* C::B end */
 
1843
 
 
1844
class WXDLLIMPEXP_PDFDOC wxPdfDocumentModule : public wxModule
 
1845
{
 
1846
DECLARE_DYNAMIC_CLASS(wxPdfDocumentModule)
 
1847
public:
 
1848
  wxPdfDocumentModule() {}
 
1849
  bool OnInit();
 
1850
  void OnExit();
 
1851
};
 
1852
 
 
1853
IMPLEMENT_DYNAMIC_CLASS(wxPdfDocumentModule, wxModule)
 
1854
 
 
1855
/*
 
1856
 * Initialization/cleanup module
 
1857
 */
 
1858
 
 
1859
bool wxPdfDocumentModule::OnInit()
 
1860
{
 
1861
  wxPdfFontManager::ms_fontManager = new wxPdfFontManager();
 
1862
  return true;
 
1863
}
 
1864
 
 
1865
void wxPdfDocumentModule::OnExit()
 
1866
{
 
1867
  delete wxPdfFontManager::ms_fontManager;
 
1868
  wxPdfFontManager::ms_fontManager = NULL;
 
1869
}
 
1870
 
 
1871
/* C::B begin */
 
1872
#endif // wxPDF_USE_WXMODULE
 
1873
/* C::B end */