1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        pdffontdata.cpp
3 // Purpose:
4 // Author:      Ulrich Telle
5 // Created:     2008-08-07
6 // Copyright:   (c) Ulrich Telle
7 // Licence:     wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 /// \file pdffontdata.cpp Implementation of wxPdfFontData class
11 
12 // For compilers that support precompilation, includes <wx.h>.
13 #include <wx/wxprec.h>
14 
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18 
19 #ifndef WX_PRECOMP
20 #include <wx/wx.h>
21 #endif
22 
23 // includes
24 #include <wx/tokenzr.h>
25 
26 #include "wx/pdfencoding.h"
27 #include "wx/pdffontdata.h"
28 #include "wx/pdffont.h"
29 
30 wxString
GetNodeContent(const wxXmlNode * node)31 wxPdfFontData::GetNodeContent(const wxXmlNode *node)
32 {
33   const wxXmlNode *n = node;
34   if (n == NULL) return wxEmptyString;
35    n = n->GetChildren();
36 
37   while (n)
38   {
39     if (n->GetType() == wxXML_TEXT_NODE ||
40         n->GetType() == wxXML_CDATA_SECTION_NODE)
41       return n->GetContent();
42     n = n->GetNext();
43   }
44 
45   return wxEmptyString;
46 }
47 
48 bool
GetFontDescription(const wxXmlNode * node,wxPdfFontDescription & fontDescription)49 wxPdfFontData::GetFontDescription(const wxXmlNode *node, wxPdfFontDescription& fontDescription)
50 {
51   bool bAscent             = false,
52        bDescent            = false,
53        bCapheight          = false,
54        bFlags              = false,
55        bFontbbox           = false,
56        bItalicangle        = false,
57        bStemv              = false,
58        bMissingwidth       = false,
59        bXHeight            = false,
60        bUnderlinePosition  = false,
61        bUnderlineThickness = false;
62   wxString value;
63   long number;
64   wxXmlNode* child = node->GetChildren();
65   while (child)
66   {
67     // parse the children
68     if (child->GetName() == wxS("ascent"))
69     {
70       value = GetNodeContent(child);
71       if (value.ToLong(&number))
72       {
73         bAscent = true;
74         fontDescription.SetAscent(number);
75       }
76     }
77     else if (child->GetName() == wxS("descent"))
78     {
79       value = GetNodeContent(child);
80       if (value.ToLong(&number))
81       {
82         bDescent = true;
83         fontDescription.SetDescent(number);
84       }
85     }
86     else if (child->GetName() == wxS("cap-height"))
87     {
88       value = GetNodeContent(child);
89       if (value.ToLong(&number))
90       {
91         bCapheight = true;
92         fontDescription.SetCapHeight(number);
93       }
94     }
95     else if (child->GetName() == wxS("flags"))
96     {
97       value = GetNodeContent(child);
98       if (value.ToLong(&number))
99       {
100         bFlags = true;
101         fontDescription.SetFlags(number);
102       }
103     }
104     else if (child->GetName() == wxS("font-bbox"))
105     {
106       value = GetNodeContent(child);
107       if (value.Length() > 0 && value[0] == wxS('[') && value.Last() == wxS(']'))
108       {
109         bFontbbox = true;
110         fontDescription.SetFontBBox(value);
111       }
112     }
113     else if (child->GetName() == wxS("italic-angle"))
114     {
115       value = GetNodeContent(child);
116       if (value.ToLong(&number))
117       {
118         bItalicangle = true;
119         fontDescription.SetItalicAngle(number);
120       }
121     }
122     else if (child->GetName() == wxS("stem-v"))
123     {
124       value = GetNodeContent(child);
125       if (value.ToLong(&number))
126       {
127         bStemv = true;
128         fontDescription.SetStemV(number);
129       }
130     }
131     else if (child->GetName() == wxS("missing-width"))
132     {
133       value = GetNodeContent(child);
134       if (value.ToLong(&number))
135       {
136         bMissingwidth = true;
137         fontDescription.SetMissingWidth(number);
138       }
139     }
140     else if (child->GetName() == wxS("x-height"))
141     {
142       value = GetNodeContent(child);
143       if (value.ToLong(&number))
144       {
145         bXHeight = true;
146         fontDescription.SetXHeight(number);
147       }
148     }
149     else if (child->GetName() == wxS("underline-position"))
150     {
151       value = GetNodeContent(child);
152       if (value.ToLong(&number))
153       {
154         bUnderlinePosition = true;
155         fontDescription.SetUnderlinePosition(number);
156       }
157     }
158     else if (child->GetName() == wxS("underline-thickness"))
159     {
160       value = GetNodeContent(child);
161       if (value.ToLong(&number))
162       {
163         bUnderlineThickness = true;
164         fontDescription.SetUnderlineThickness(number);
165       }
166     }
167     child = child->GetNext();
168   }
169   return (bAscent && bDescent && bCapheight && bFlags && bFontbbox &&
170           bItalicangle && bStemv && bMissingwidth && bXHeight &&
171           bUnderlinePosition && bUnderlineThickness);
172 }
173 
wxPdfFontData()174 wxPdfFontData::wxPdfFontData()
175 {
176   m_refCount = 0;
177 
178   m_type   = wxS("unknown");
179   m_family = wxEmptyString;
180   m_alias  = wxEmptyString;
181   m_name   = wxEmptyString;
182 
183   m_fontFileName = wxEmptyString;
184   m_fontIndex = 0;
185 
186   m_cff = false;
187   m_cffOffset = 0;
188   m_cffLength = 0;
189 
190   m_cw = NULL;
191   m_gn = NULL;
192   m_kp = NULL;
193 
194   m_enc   = wxEmptyString;
195   m_diffs = wxEmptyString;
196   m_file  = wxEmptyString;
197   m_ctg   = wxEmptyString;
198   m_size1 = 0;
199   m_size2 = 0;
200 
201   m_initialized = false;
202   m_embedRequired = false;
203   m_embedSupported = false;
204   m_subsetSupported = false;
205 
206   m_encoding = NULL;
207   m_encodingChecker = NULL;
208 }
209 
~wxPdfFontData()210 wxPdfFontData::~wxPdfFontData()
211 {
212   if (m_kp != NULL)
213   {
214     wxPdfKernPairMap::iterator kp;
215     for (kp = m_kp->begin(); kp != m_kp->end(); kp++)
216     {
217       if (kp->second != NULL)
218       {
219         delete kp->second;
220       }
221     }
222     delete m_kp;
223   }
224   if (m_gn != NULL)
225   {
226     delete m_gn;
227   }
228   delete m_cw;
229 }
230 
231 void
SetEncoding(wxPdfEncoding * encoding)232 wxPdfFontData::SetEncoding(wxPdfEncoding* encoding)
233 {
234   m_encoding = encoding;
235 }
236 
237 const wxPdfChar2GlyphMap*
FindEncodingMap(const wxPdfEncoding * encoding) const238 wxPdfFontData::FindEncodingMap(const wxPdfEncoding* encoding) const
239 {
240   const wxPdfChar2GlyphMap* convMap = NULL;
241   if (encoding != NULL)
242   {
243     convMap = encoding->GetEncodingMap();
244   }
245   if (convMap == NULL && m_encoding != NULL)
246   {
247     convMap = m_encoding->GetEncodingMap();
248   }
249   return convMap;
250 }
251 
252 void
SetEncodingChecker(wxPdfEncodingChecker * encodingChecker)253 wxPdfFontData::SetEncodingChecker(wxPdfEncodingChecker* encodingChecker)
254 {
255   m_encodingChecker = encodingChecker;
256 }
257 
258 wxPdfEncodingChecker*
GetEncodingChecker() const259 wxPdfFontData::GetEncodingChecker() const
260 {
261   return m_encodingChecker;
262 }
263 
264 void
SetType(const wxString & type)265 wxPdfFontData::SetType(const wxString& type)
266 {
267   m_type = type;
268 }
269 
270 wxString
GetType() const271 wxPdfFontData::GetType() const
272 {
273   return m_type;
274 }
275 
276 void
SetFamily(const wxString & family)277 wxPdfFontData::SetFamily(const wxString& family)
278 {
279   m_family = family;
280 }
281 
282 wxString
GetFamily() const283 wxPdfFontData::GetFamily() const
284 {
285   wxString family = m_family;
286   if (family.IsEmpty())
287   {
288     family = (!m_alias.IsEmpty()) ? m_alias : m_name;
289   }
290   return family;
291 }
292 
293 void
SetAlias(const wxString & alias)294 wxPdfFontData::SetAlias(const wxString& alias)
295 {
296   m_alias = alias;
297 }
298 
299 wxString
GetAlias() const300 wxPdfFontData::GetAlias() const
301 {
302   return m_alias;
303 }
304 
305 void
SetName(const wxString & name)306 wxPdfFontData::SetName(const wxString& name)
307 {
308   m_name = name;
309 }
310 
311 wxString
GetName() const312 wxPdfFontData::GetName() const
313 {
314   return m_name;
315 }
316 
317 void
SetFullNames(const wxArrayString & fullNames)318 wxPdfFontData::SetFullNames(const wxArrayString& fullNames)
319 {
320   m_fullNames = fullNames;
321 }
322 
323 wxArrayString
GetFullNames() const324 wxPdfFontData::GetFullNames() const
325 {
326   return m_fullNames;
327 }
328 
329 void
SetStyle(const wxString & style)330 wxPdfFontData::SetStyle(const wxString& style)
331 {
332   wxString lcStyle = style.Lower();
333   bool italic = (lcStyle.Find(wxS("italic"))  != wxNOT_FOUND) ||
334                 (lcStyle.Find(wxS("oblique")) != wxNOT_FOUND) ||
335                 lcStyle.IsSameAs(wxS("i")) || lcStyle.IsSameAs(wxS("bi")) || lcStyle.IsSameAs(wxS("ib"));
336   bool bold = (lcStyle.Find(wxS("bold"))  != wxNOT_FOUND) ||
337               (lcStyle.Find(wxS("black")) != wxNOT_FOUND) ||
338               lcStyle.IsSameAs(wxS("b")) || lcStyle.IsSameAs(wxS("bi")) || lcStyle.IsSameAs(wxS("ib"));
339   m_style = wxPDF_FONTSTYLE_REGULAR;
340   if (bold)
341   {
342     m_style |= wxPDF_FONTSTYLE_BOLD;
343   }
344   if (italic)
345   {
346     m_style |= wxPDF_FONTSTYLE_ITALIC;
347   }
348 }
349 
350 void
SetStyle(int style)351 wxPdfFontData::SetStyle(int style)
352 {
353   m_style = (style & ~wxPDF_FONTSTYLE_DECORATION_MASK) & wxPDF_FONTSTYLE_MASK;
354 }
355 
356 void
SetStyleFromName()357 wxPdfFontData::SetStyleFromName()
358 {
359   SetStyle(m_name);
360 }
361 
362 int
GetStyle() const363 wxPdfFontData::GetStyle() const
364 {
365   return m_style;
366 }
367 
368 void
SetUnderlinePosition(int up)369 wxPdfFontData::SetUnderlinePosition(int up)
370 {
371   m_desc.SetUnderlinePosition(up);
372 }
373 
374 int
GetUnderlinePosition() const375 wxPdfFontData::GetUnderlinePosition() const
376 {
377   return m_desc.GetUnderlinePosition();
378 }
379 
380 void
SetUnderlineThickness(int ut)381 wxPdfFontData::SetUnderlineThickness(int ut)
382 {
383   m_desc.SetUnderlineThickness(ut);
384 }
385 
386 int
GetUnderlineThickness() const387 wxPdfFontData::GetUnderlineThickness() const
388 {
389   return m_desc.GetUnderlineThickness();
390 }
391 
392 int
GetBBoxTopPosition() const393 wxPdfFontData::GetBBoxTopPosition() const
394 {
395   long top = 1000;
396   wxString bBox = m_desc.GetFontBBox();
397   wxStringTokenizer tkz(bBox, wxS(" []"), wxTOKEN_STRTOK);
398   if (tkz.CountTokens() >= 4)
399   {
400     tkz.GetNextToken();
401     tkz.GetNextToken();
402     tkz.GetNextToken();
403     wxString topToken = tkz.GetNextToken();
404     topToken.ToLong(&top);
405   }
406   return top;
407 }
408 
409 void
SetEncoding(const wxString & enc)410 wxPdfFontData::SetEncoding(const wxString& enc)
411 {
412   m_enc = enc;
413 }
414 
415 wxString
GetEncoding() const416 wxPdfFontData::GetEncoding() const
417 {
418   return m_enc;
419 }
420 
421 const wxPdfEncoding*
GetBaseEncoding() const422 wxPdfFontData::GetBaseEncoding() const
423 {
424   return m_encoding;
425 }
426 
427 bool
HasDiffs() const428 wxPdfFontData::HasDiffs() const
429 {
430   return m_diffs.Length() > 0;
431 }
432 
433 void
SetDiffs(const wxString & diffs)434 wxPdfFontData::SetDiffs(const wxString& diffs)
435 {
436   m_diffs = diffs;
437 }
438 
439 wxString
GetDiffs() const440 wxPdfFontData::GetDiffs() const
441 {
442   return m_diffs;
443 }
444 
445 void
SetFilePath(const wxString & path)446 wxPdfFontData::SetFilePath(const wxString& path)
447 {
448   m_path = path;
449 }
450 
451 wxString
GetFilePath() const452 wxPdfFontData::GetFilePath() const
453 {
454   return m_path;
455 }
456 
457 bool
HasFile() const458 wxPdfFontData::HasFile() const
459 {
460   return m_file.Length() > 0;
461 }
462 
463 void
SetFontFile(const wxString & file)464 wxPdfFontData::SetFontFile(const wxString& file)
465 {
466   m_file = file;
467 }
468 
469 wxString
GetFontFile() const470 wxPdfFontData::GetFontFile() const
471 {
472   return m_file;
473 }
474 
475 void
SetCtgFile(const wxString & ctg)476 wxPdfFontData::SetCtgFile(const wxString& ctg)
477 {
478   m_ctg = ctg;
479 }
480 
481 wxString
GetCtgFile() const482 wxPdfFontData::GetCtgFile() const
483 {
484   return m_ctg;
485 }
486 
487 void
SetSize1(size_t size1)488 wxPdfFontData::SetSize1(size_t size1)
489 {
490   m_size1 = size1;
491 }
492 
493 size_t
GetSize1() const494 wxPdfFontData::GetSize1() const
495 {
496   return m_size1;
497 }
498 
499 bool
HasSize2() const500 wxPdfFontData::HasSize2() const
501 {
502   return m_size2 > 0;
503 }
504 
505 void
SetSize2(size_t size2)506 wxPdfFontData::SetSize2(size_t size2)
507 {
508   m_size2 = size2;
509 }
510 
511 size_t
GetSize2() const512 wxPdfFontData::GetSize2() const
513 {
514   return m_size2;
515 }
516 
517 wxString
GetCMap() const518 wxPdfFontData::GetCMap() const
519 {
520   return m_cmap;
521 }
522 
523 void
SetCMap(const wxString & cmap)524 wxPdfFontData::SetCMap(const wxString& cmap)
525 {
526   m_cmap = cmap;
527 }
528 
529 wxString
GetOrdering() const530 wxPdfFontData::GetOrdering() const
531 {
532   return m_ordering;
533 }
534 
535 void
SetOrdering(const wxString & ordering)536 wxPdfFontData::SetOrdering(const wxString& ordering)
537 {
538   m_ordering = ordering;
539 }
540 
541 wxString
GetSupplement() const542 wxPdfFontData::GetSupplement() const
543 {
544   return m_supplement;
545 }
546 
547 void
SetSupplement(const wxString & supplement)548 wxPdfFontData::SetSupplement(const wxString& supplement)
549 {
550   m_supplement = supplement;
551 }
552 
553 void
SetGlyphWidthMap(wxPdfGlyphWidthMap * cw)554 wxPdfFontData::SetGlyphWidthMap(wxPdfGlyphWidthMap* cw)
555 {
556   m_cw = cw;
557 }
558 
559 const wxPdfGlyphWidthMap*
GetGlyphWidthMap() const560 wxPdfFontData::GetGlyphWidthMap() const
561 {
562   return m_cw;
563 }
564 
565 void
SetChar2GlyphMap(wxPdfChar2GlyphMap * gn)566 wxPdfFontData::SetChar2GlyphMap(wxPdfChar2GlyphMap* gn)
567 {
568   m_gn = gn;
569 }
570 
571 const wxPdfChar2GlyphMap*
GetChar2GlyphMap() const572 wxPdfFontData::GetChar2GlyphMap() const
573 {
574   return m_gn;
575 }
576 
577 void
SetKernPairMap(wxPdfKernPairMap * kp)578 wxPdfFontData::SetKernPairMap(wxPdfKernPairMap* kp)
579 {
580   m_kp = kp;
581 }
582 
583 const wxPdfKernPairMap*
GetKernPairMap() const584 wxPdfFontData::GetKernPairMap() const
585 {
586   return m_kp;
587 }
588 
589 int
GetKerningWidth(const wxString & s) const590 wxPdfFontData::GetKerningWidth(const wxString& s) const
591 {
592   bool translateChar2Glyph = m_type.IsSameAs(wxS("TrueTypeUnicode")) ||
593                              m_type.IsSameAs(wxS("OpenTypeUnicode"));
594   int width = 0;
595   if (m_kp != NULL && s.length())
596   {
597     wxPdfKernPairMap::const_iterator kpIter;
598     wxPdfKernWidthMap::const_iterator kwIter;
599     wxUint32 ch1, ch2;
600     wxString::const_iterator ch = s.begin();
601     ch1 = (wxUint32) (*ch);
602     if (translateChar2Glyph && m_gn != NULL)
603     {
604       wxPdfChar2GlyphMap::const_iterator glyphIter;
605       glyphIter = m_gn->find(ch1);
606       if (glyphIter != m_gn->end())
607       {
608         ch1 = glyphIter->second;
609       }
610     }
611     for (++ch; ch != s.end(); ++ch)
612     {
613       ch2 = (wxUint32) (*ch);
614       if (translateChar2Glyph && m_gn != NULL)
615       {
616         wxPdfChar2GlyphMap::const_iterator glyphIter;
617         glyphIter = m_gn->find(ch2);
618         if (glyphIter != m_gn->end())
619         {
620           ch2 = glyphIter->second;
621         }
622       }
623       kpIter = (*m_kp).find(ch1);
624       if (kpIter != (*m_kp).end())
625       {
626         kwIter = kpIter->second->find(ch2);
627         if (kwIter != kpIter->second->end())
628         {
629           width += kwIter->second;
630         }
631       }
632       ch1 = ch2;
633     }
634   }
635   return width;
636 }
637 
638 wxArrayInt
GetKerningWidthArray(const wxString & s) const639 wxPdfFontData::GetKerningWidthArray(const wxString& s) const
640 {
641   bool translateChar2Glyph = m_type.IsSameAs(wxS("TrueTypeUnicode")) ||
642                              m_type.IsSameAs(wxS("OpenTypeUnicode"));
643   wxArrayInt widths;
644   int pos = 0;
645   if (m_kp != NULL && s.length())
646   {
647     wxPdfKernPairMap::const_iterator kpIter;
648     wxPdfKernWidthMap::const_iterator kwIter;
649     wxUint32 ch1, ch2;
650     wxString::const_iterator ch = s.begin();
651     ch1 = (wxUint32) (*ch);
652     if (translateChar2Glyph && m_gn != NULL)
653     {
654       wxPdfChar2GlyphMap::const_iterator glyphIter;
655       glyphIter = m_gn->find(ch1);
656       if (glyphIter != m_gn->end())
657       {
658         ch1 = glyphIter->second;
659       }
660     }
661     for (++ch; ch != s.end(); ++ch)
662     {
663       ch2 = (wxUint32) (*ch);
664       if (translateChar2Glyph && m_gn != NULL)
665       {
666         wxPdfChar2GlyphMap::const_iterator glyphIter;
667         glyphIter = m_gn->find(ch2);
668         if (glyphIter != m_gn->end())
669         {
670           ch2 = glyphIter->second;
671         }
672       }
673       kpIter = (*m_kp).find(ch1);
674       if (kpIter != (*m_kp).end())
675       {
676         kwIter = kpIter->second->find(ch2);
677         if (kwIter != kpIter->second->end())
678         {
679           widths.Add(pos);
680           widths.Add(-kwIter->second);
681         }
682       }
683       ch1 = ch2;
684       ++pos;
685     }
686   }
687   return widths;
688 }
689 
690 bool
Initialize()691 wxPdfFontData::Initialize()
692 {
693   return IsInitialized();
694 }
695 
696 void
SetInitialized(bool initialized)697 wxPdfFontData::SetInitialized(bool initialized)
698 {
699   m_initialized = initialized;
700 }
701 
702 wxString
GetWidthsAsString(bool subset,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs) const703 wxPdfFontData::GetWidthsAsString(bool subset, wxPdfSortedArrayInt* usedGlyphs, wxPdfChar2GlyphMap* subsetGlyphs) const
704 {
705   wxUnusedVar(subset);
706   wxUnusedVar(usedGlyphs);
707   wxUnusedVar(subsetGlyphs);
708   return wxEmptyString;
709 }
710 
711 double
GetStringWidth(const wxString & s,const wxPdfEncoding * encoding,bool withKerning) const712 wxPdfFontData::GetStringWidth(const wxString& s, const wxPdfEncoding* encoding, bool withKerning) const
713 {
714   wxUnusedVar(s);
715   wxUnusedVar(encoding);
716   wxUnusedVar(withKerning);
717   return 0;
718 }
719 
720 bool
GetGlyphNames(wxArrayString & glyphNames) const721 wxPdfFontData::GetGlyphNames(wxArrayString& glyphNames) const
722 {
723   wxUnusedVar(glyphNames);
724   return false;
725 }
726 
727 size_t
WriteFontData(wxOutputStream * fontData,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs)728 wxPdfFontData::WriteFontData(wxOutputStream* fontData, wxPdfSortedArrayInt* usedGlyphs, wxPdfChar2GlyphMap* subsetGlyphs)
729 {
730   wxUnusedVar(fontData);
731   wxUnusedVar(usedGlyphs);
732   wxUnusedVar(subsetGlyphs);
733   return 0;
734 }
735 
736 size_t
WriteUnicodeMap(wxOutputStream * mapData,const wxPdfEncoding * encoding,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs)737 wxPdfFontData::WriteUnicodeMap(wxOutputStream* mapData,
738                                const wxPdfEncoding* encoding, wxPdfSortedArrayInt* usedGlyphs, wxPdfChar2GlyphMap* subsetGlyphs)
739 {
740   wxUnusedVar(mapData);
741   wxUnusedVar(encoding);
742   wxUnusedVar(usedGlyphs);
743   wxUnusedVar(subsetGlyphs);
744   return 0;
745 }
746 
747 void
SetDescription(const wxPdfFontDescription & desc)748 wxPdfFontData::SetDescription(const wxPdfFontDescription& desc)
749 {
750   m_desc = desc;
751 }
752 
753 const wxPdfFontDescription&
GetDescription() const754 wxPdfFontData::GetDescription() const
755 {
756   return m_desc;
757 }
758 
759 bool
LoadFontMetrics(wxXmlNode * root)760 wxPdfFontData::LoadFontMetrics(wxXmlNode* root)
761 {
762   wxUnusedVar(root);
763   return false;
764 };
765 
766 bool
CanShow(const wxString & s,const wxPdfEncoding * encoding) const767 wxPdfFontData::CanShow(const wxString& s, const wxPdfEncoding* encoding) const
768 {
769   wxUnusedVar(encoding);
770   bool canShow = true;
771 #if wxUSE_UNICODE
772   wxMBConv* conv = GetEncodingConv();
773   size_t len = conv->FromWChar(NULL, 0, s.wc_str(), s.length());
774   canShow = (len != wxCONV_FAILED);
775 #endif
776   return canShow;
777 }
778 
779 wxString
ConvertToValid(const wxString & s,wxChar replace) const780 wxPdfFontData::ConvertToValid(const wxString& s, wxChar replace) const
781 {
782   wxString t;
783   if (m_encodingChecker != NULL)
784   {
785     if (m_encodingChecker->IsIncluded((wxUint32) replace))
786     {
787       replace = wxS('?');
788     }
789     wxString::const_iterator ch = s.begin();
790     for (ch = s.begin(); ch != s.end(); ++ch)
791     {
792       if (m_encodingChecker->IsIncluded((wxUint32) *ch))
793       {
794         t.Append(*ch);
795       }
796       else
797       {
798         t.Append(replace);
799       }
800     }
801   }
802   else
803   {
804     t = s;
805   }
806   return  t;
807 }
808 
809 wxString
ConvertCID2GID(const wxString & s,const wxPdfEncoding * encoding,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs) const810 wxPdfFontData::ConvertCID2GID(const wxString& s,
811                               const wxPdfEncoding* encoding,
812                               wxPdfSortedArrayInt* usedGlyphs,
813                               wxPdfChar2GlyphMap* subsetGlyphs) const
814 {
815   // No conversion from cid to gid
816   wxUnusedVar(encoding);
817   wxUnusedVar(usedGlyphs);
818   wxUnusedVar(subsetGlyphs);
819   return s;
820 }
821 
822 wxString
ConvertGlyph(wxUint32 glyph,const wxPdfEncoding * encoding,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs) const823 wxPdfFontData::ConvertGlyph(wxUint32 glyph,
824                             const wxPdfEncoding* encoding,
825                             wxPdfSortedArrayInt* usedGlyphs,
826                             wxPdfChar2GlyphMap* subsetGlyphs) const
827 {
828   wxUnusedVar(glyph);
829   wxUnusedVar(encoding);
830   wxUnusedVar(usedGlyphs);
831   wxUnusedVar(subsetGlyphs);
832   return wxEmptyString;
833 }
834 
835 #if wxUSE_UNICODE
836 wxMBConv*
GetEncodingConv() const837 wxPdfFontData::GetEncodingConv() const
838 {
839   return &wxConvISO8859_1;
840 }
841 
842 void
CreateDefaultEncodingConv()843 wxPdfFontData::CreateDefaultEncodingConv()
844 {
845 }
846 #endif
847 
848 void
SetGlyphWidths(const wxPdfArrayUint16 & glyphWidths)849 wxPdfFontData::SetGlyphWidths(const wxPdfArrayUint16& glyphWidths)
850 {
851   wxUnusedVar(glyphWidths);
852 }
853 
854 int
FindStyleFromName(const wxString & name)855 wxPdfFontData::FindStyleFromName(const wxString& name)
856 {
857   int style = wxPDF_FONTSTYLE_REGULAR;
858   wxString lcName = name.Lower();
859   if (lcName.Find(wxS("bold")) != wxNOT_FOUND)
860   {
861     style |= wxPDF_FONTSTYLE_BOLD;
862   }
863   if (lcName.Find(wxS("italic")) != wxNOT_FOUND || lcName.Find(wxS("oblique")) != wxNOT_FOUND)
864   {
865     style |= wxPDF_FONTSTYLE_ITALIC;
866   }
867   return style;
868 }
869 
870 int
CompareGlyphListEntries(wxPdfGlyphListEntry * item1,wxPdfGlyphListEntry * item2)871 wxPdfFontData::CompareGlyphListEntries(wxPdfGlyphListEntry* item1, wxPdfGlyphListEntry* item2)
872 {
873   return item1->m_gid - item2->m_gid;
874 }
875 
876 void
WriteStreamBuffer(wxOutputStream & stream,const char * buffer)877 wxPdfFontData::WriteStreamBuffer(wxOutputStream& stream, const char* buffer)
878 {
879   size_t buflen = strlen(buffer);
880   stream.Write(buffer, buflen);
881 }
882 
883 void
WriteToUnicode(wxPdfGlyphList & glyphs,wxMemoryOutputStream & toUnicode,bool simple)884 wxPdfFontData::WriteToUnicode(wxPdfGlyphList& glyphs, wxMemoryOutputStream& toUnicode, bool simple)
885 {
886   wxString gidFormat = (simple) ? wxString(wxS("<%02x>")) : wxString(wxS("<%04x>"));
887   WriteStreamBuffer(toUnicode, "/CIDInit /ProcSet findresource begin\n");
888   WriteStreamBuffer(toUnicode, "12 dict begin\n");
889   WriteStreamBuffer(toUnicode, "begincmap\n");
890   WriteStreamBuffer(toUnicode, "/CIDSystemInfo\n");
891   WriteStreamBuffer(toUnicode, "<< /Registry (Adobe)\n");
892   WriteStreamBuffer(toUnicode, "/Ordering (UCS)\n");
893   WriteStreamBuffer(toUnicode, "/Supplement 0\n");
894   WriteStreamBuffer(toUnicode, ">> def\n");
895   WriteStreamBuffer(toUnicode, "/CMapName /Adobe-Identity-UCS def\n");
896   WriteStreamBuffer(toUnicode, "/CMapType 2 def\n");
897   WriteStreamBuffer(toUnicode, "1 begincodespacerange\n");
898   if (simple)
899   {
900     WriteStreamBuffer(toUnicode, "<00><FF>\n");
901   }
902   else
903   {
904     WriteStreamBuffer(toUnicode, "<0000><FFFF>\n");
905   }
906   WriteStreamBuffer(toUnicode, "endcodespacerange\n");
907   unsigned int size = 0;
908   unsigned int k;
909   unsigned int numGlyphs = (unsigned int) glyphs.GetCount();
910   for (k = 0; k < numGlyphs; ++k)
911   {
912     if (size == 0)
913     {
914       if (k != 0)
915       {
916         WriteStreamBuffer(toUnicode, "endbfrange\n");
917       }
918       size = (numGlyphs-k > 100) ? 100 : numGlyphs - k;
919       wxString sizeStr = wxString::Format(wxS("%u"), size);
920       WriteStreamBuffer(toUnicode, sizeStr.ToAscii());
921       WriteStreamBuffer(toUnicode, " beginbfrange\n");
922     }
923     size--;
924     wxPdfGlyphListEntry* entry = glyphs[k];
925     wxString fromTo = wxString::Format(gidFormat, entry->m_gid);
926     wxString uniChr = wxString::Format(wxS("<%04x>"), entry->m_uid);
927     WriteStreamBuffer(toUnicode, fromTo.ToAscii());
928     WriteStreamBuffer(toUnicode, fromTo.ToAscii());
929     WriteStreamBuffer(toUnicode, uniChr.ToAscii());
930     WriteStreamBuffer(toUnicode, "\n");
931   }
932   WriteStreamBuffer(toUnicode, "endbfrange\n");
933   WriteStreamBuffer(toUnicode, "endcmap\n");
934   WriteStreamBuffer(toUnicode, "CMapName currentdict /CMap defineresource pop\n");
935   WriteStreamBuffer(toUnicode, "end end\n");
936 }
937