1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        pdffontdatacore.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 pdffontdatacore.cpp Implementation of PDF core fonts
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 
25 #include "wx/pdfcorefontdata.h"
26 #include "wx/pdffontdatacore.h"
27 #include "wx/pdffontdescription.h"
28 #include "wx/pdfencoding.h"
29 
wxPdfFontDataCore(const wxString & family,const wxString & alias,const wxString & name,short * cwArray,const wxPdfKernPairDesc * kpArray,const wxPdfFontDescription & desc)30 wxPdfFontDataCore::wxPdfFontDataCore(const wxString& family, const wxString& alias, const wxString& name,
31                                      short* cwArray, const wxPdfKernPairDesc* kpArray,
32                                      const wxPdfFontDescription& desc)
33   : wxPdfFontData()
34 {
35   m_type   = wxS("core");
36   m_family = family;
37   m_alias  = alias;
38   m_name   = name;
39   m_fullNames.Add(name);
40   m_desc  = desc;
41   m_style = FindStyleFromName(name);
42 
43   if (cwArray != NULL)
44   {
45     m_cw = new wxPdfGlyphWidthMap();
46     int j;
47     for (j = 0; j <256; j++)
48     {
49       (*m_cw)[j] = cwArray[j];
50     }
51   }
52 
53   if (kpArray != NULL)
54   {
55     m_kp = new wxPdfKernPairMap();
56     wxPdfKernWidthMap* kwMap = NULL;
57     wxPdfKernWidthMap::iterator kw;
58     wxUint32 u1, u2;
59     wxUint32 u1prev = 0;
60     size_t k = 0;
61     while ((u1 = kpArray[k].unicode1) != 0 && (u2 = kpArray[k].unicode2) != 0)
62     {
63       if (u1 != u1prev)
64       {
65         u1prev = u1;
66         wxPdfKernPairMap::iterator kp = (*m_kp).find(u1);
67         if (kp == (*m_kp).end())
68         {
69           kwMap = new wxPdfKernWidthMap();
70           (*m_kp)[u1] = kwMap;
71         }
72         else
73         {
74           kwMap = kp->second;
75         }
76       }
77       (*kwMap)[u2] = kpArray[k].kerning;
78       ++k;
79     }
80   }
81 
82   m_initialized = true;
83 }
84 
~wxPdfFontDataCore()85 wxPdfFontDataCore::~wxPdfFontDataCore()
86 {
87 }
88 
89 wxString
GetWidthsAsString(bool subset,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs) const90 wxPdfFontDataCore::GetWidthsAsString(bool subset, wxPdfSortedArrayInt* usedGlyphs, wxPdfChar2GlyphMap* subsetGlyphs) const
91 {
92   wxUnusedVar(subset);
93   wxUnusedVar(usedGlyphs);
94   wxUnusedVar(subsetGlyphs);
95   wxString s = wxString(wxS("["));
96   int i;
97   for (i = 32; i <= 255; i++)
98   {
99     s += wxString::Format(wxS("%u "), (*m_cw)[i]);
100   }
101   s += wxString(wxS("]"));
102   return s;
103 }
104 
105 #if wxUSE_UNICODE
106 wxMBConv*
GetEncodingConv() const107 wxPdfFontDataCore::GetEncodingConv() const
108 {
109   wxMBConv* conv = &wxConvISO8859_1;
110   return conv;
111 }
112 #endif
113 
114 double
GetStringWidth(const wxString & s,const wxPdfEncoding * encoding,bool withKerning) const115 wxPdfFontDataCore::GetStringWidth(const wxString& s, const wxPdfEncoding* encoding, bool withKerning) const
116 {
117   wxUnusedVar(encoding);
118   double w = 0;
119   // Get width of a string in the current font
120   wxString t = ConvertCID2GID(s);
121 
122   wxString::const_iterator ch;
123   for (ch = t.begin(); ch != t.end(); ++ch)
124   {
125     w += (*m_cw)[*ch];
126   }
127   if (withKerning)
128   {
129     int kerningWidth = GetKerningWidth(t);
130     if (kerningWidth != 0)
131     {
132       w += (double) kerningWidth;
133     }
134   }
135   return w / 1000;
136 }
137 
138 bool
CanShow(const wxString & s,const wxPdfEncoding * encoding) const139 wxPdfFontDataCore::CanShow(const wxString& s, const wxPdfEncoding* encoding) const
140 {
141   bool canShow = true;
142   const wxPdfChar2GlyphMap* usedMap = NULL;
143   if (encoding != NULL)
144   {
145     usedMap = encoding->GetEncodingMap();
146   }
147   if (usedMap == NULL)
148   {
149     usedMap = m_encoding->GetEncodingMap();
150   }
151   if (usedMap != NULL)
152   {
153     wxPdfChar2GlyphMap::const_iterator charIter;
154     wxString::const_iterator ch;
155     for (ch = s.begin(); canShow && ch != s.end(); ++ch)
156     {
157       canShow = (usedMap->find(*ch) != usedMap->end());
158     }
159   }
160   return canShow;
161 }
162 
163 wxString
ConvertCID2GID(const wxString & s,const wxPdfEncoding * encoding,wxPdfSortedArrayInt * usedGlyphs,wxPdfChar2GlyphMap * subsetGlyphs) const164 wxPdfFontDataCore::ConvertCID2GID(const wxString& s,
165                                   const wxPdfEncoding* encoding,
166                                   wxPdfSortedArrayInt* usedGlyphs,
167                                   wxPdfChar2GlyphMap* subsetGlyphs) const
168 {
169   // No conversion from cid to gid
170   wxUnusedVar(usedGlyphs);
171   wxUnusedVar(subsetGlyphs);
172 #if wxUSE_UNICODE
173   const wxPdfChar2GlyphMap* convMap = FindEncodingMap(encoding);
174   wxString t;
175   if (convMap != NULL)
176   {
177     wxPdfChar2GlyphMap::const_iterator charIter;
178     wxString::const_iterator ch;
179     for (ch = s.begin(); ch != s.end(); ++ch)
180     {
181       charIter = (*convMap).find(*ch);
182       if (charIter != (*convMap).end())
183       {
184 #if wxCHECK_VERSION(2,9,0)
185         t.Append(wxUniChar(charIter->second));
186 #else
187         t.Append(wxChar(charIter->second));
188 #endif
189       }
190       else
191       {
192         t += wxS("?");
193       }
194     }
195   }
196   else
197   {
198     t = s;
199   }
200   return t;
201 #else
202   // Return unchanged string in ANSI build
203   wxUnusedVar(encoding);
204   return s;
205 #endif
206 }
207