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