• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fpdfapi/font/cpdf_cidfont.h"
8 
9 #include <algorithm>
10 #include <limits>
11 #include <vector>
12 
13 #include "core/fpdfapi/cmaps/cmap_int.h"
14 #include "core/fpdfapi/cpdf_modulemgr.h"
15 #include "core/fpdfapi/font/cfx_cttgsubtable.h"
16 #include "core/fpdfapi/font/cpdf_cid2unicodemap.h"
17 #include "core/fpdfapi/font/cpdf_cmap.h"
18 #include "core/fpdfapi/font/cpdf_cmapparser.h"
19 #include "core/fpdfapi/font/cpdf_fontencoding.h"
20 #include "core/fpdfapi/page/cpdf_pagemodule.h"
21 #include "core/fpdfapi/parser/cpdf_array.h"
22 #include "core/fpdfapi/parser/cpdf_dictionary.h"
23 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
24 #include "third_party/base/numerics/safe_math.h"
25 #include "third_party/base/ptr_util.h"
26 #include "third_party/base/stl_util.h"
27 
28 namespace {
29 
30 const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
31 
32 const struct CIDTransform {
33   uint16_t cid;
34   uint8_t a;
35   uint8_t b;
36   uint8_t c;
37   uint8_t d;
38   uint8_t e;
39   uint8_t f;
40 } g_Japan1_VertCIDs[] = {
41     {97, 129, 0, 0, 127, 55, 0},     {7887, 127, 0, 0, 127, 76, 89},
42     {7888, 127, 0, 0, 127, 79, 94},  {7889, 0, 129, 127, 0, 17, 127},
43     {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127},
44     {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127},
45     {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127},
46     {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127},
47     {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104},
48     {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104},
49     {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127},
50     {7904, 0, 129, 127, 0, 17, 127}, {7905, 0, 129, 127, 0, 17, 114},
51     {7906, 0, 129, 127, 0, 17, 127}, {7907, 0, 129, 127, 0, 17, 127},
52     {7908, 0, 129, 127, 0, 17, 127}, {7909, 0, 129, 127, 0, 17, 127},
53     {7910, 0, 129, 127, 0, 17, 127}, {7911, 0, 129, 127, 0, 17, 127},
54     {7912, 0, 129, 127, 0, 17, 127}, {7913, 0, 129, 127, 0, 17, 127},
55     {7914, 0, 129, 127, 0, 17, 127}, {7915, 0, 129, 127, 0, 17, 114},
56     {7916, 0, 129, 127, 0, 17, 127}, {7917, 0, 129, 127, 0, 17, 127},
57     {7918, 127, 0, 0, 127, 18, 25},  {7919, 127, 0, 0, 127, 18, 25},
58     {7920, 127, 0, 0, 127, 18, 25},  {7921, 127, 0, 0, 127, 18, 25},
59     {7922, 127, 0, 0, 127, 18, 25},  {7923, 127, 0, 0, 127, 18, 25},
60     {7924, 127, 0, 0, 127, 18, 25},  {7925, 127, 0, 0, 127, 18, 25},
61     {7926, 127, 0, 0, 127, 18, 25},  {7927, 127, 0, 0, 127, 18, 25},
62     {7928, 127, 0, 0, 127, 18, 25},  {7929, 127, 0, 0, 127, 18, 25},
63     {7930, 127, 0, 0, 127, 18, 25},  {7931, 127, 0, 0, 127, 18, 25},
64     {7932, 127, 0, 0, 127, 18, 25},  {7933, 127, 0, 0, 127, 18, 25},
65     {7934, 127, 0, 0, 127, 18, 25},  {7935, 127, 0, 0, 127, 18, 25},
66     {7936, 127, 0, 0, 127, 18, 25},  {7937, 127, 0, 0, 127, 18, 25},
67     {7938, 127, 0, 0, 127, 18, 25},  {7939, 127, 0, 0, 127, 18, 25},
68     {8720, 0, 129, 127, 0, 19, 102}, {8721, 0, 129, 127, 0, 13, 127},
69     {8722, 0, 129, 127, 0, 19, 108}, {8723, 0, 129, 127, 0, 19, 102},
70     {8724, 0, 129, 127, 0, 19, 102}, {8725, 0, 129, 127, 0, 19, 102},
71     {8726, 0, 129, 127, 0, 19, 102}, {8727, 0, 129, 127, 0, 19, 102},
72     {8728, 0, 129, 127, 0, 19, 114}, {8729, 0, 129, 127, 0, 19, 114},
73     {8730, 0, 129, 127, 0, 38, 108}, {8731, 0, 129, 127, 0, 13, 108},
74     {8732, 0, 129, 127, 0, 19, 108}, {8733, 0, 129, 127, 0, 19, 108},
75     {8734, 0, 129, 127, 0, 19, 108}, {8735, 0, 129, 127, 0, 19, 108},
76     {8736, 0, 129, 127, 0, 19, 102}, {8737, 0, 129, 127, 0, 19, 102},
77     {8738, 0, 129, 127, 0, 19, 102}, {8739, 0, 129, 127, 0, 19, 102},
78     {8740, 0, 129, 127, 0, 19, 102}, {8741, 0, 129, 127, 0, 19, 102},
79     {8742, 0, 129, 127, 0, 19, 102}, {8743, 0, 129, 127, 0, 19, 102},
80     {8744, 0, 129, 127, 0, 19, 102}, {8745, 0, 129, 127, 0, 19, 102},
81     {8746, 0, 129, 127, 0, 19, 114}, {8747, 0, 129, 127, 0, 19, 114},
82     {8748, 0, 129, 127, 0, 19, 102}, {8749, 0, 129, 127, 0, 19, 102},
83     {8750, 0, 129, 127, 0, 19, 102}, {8751, 0, 129, 127, 0, 19, 102},
84     {8752, 0, 129, 127, 0, 19, 102}, {8753, 0, 129, 127, 0, 19, 102},
85     {8754, 0, 129, 127, 0, 19, 102}, {8755, 0, 129, 127, 0, 19, 102},
86     {8756, 0, 129, 127, 0, 19, 102}, {8757, 0, 129, 127, 0, 19, 102},
87     {8758, 0, 129, 127, 0, 19, 102}, {8759, 0, 129, 127, 0, 19, 102},
88     {8760, 0, 129, 127, 0, 19, 102}, {8761, 0, 129, 127, 0, 19, 102},
89     {8762, 0, 129, 127, 0, 19, 102}, {8763, 0, 129, 127, 0, 19, 102},
90     {8764, 0, 129, 127, 0, 19, 102}, {8765, 0, 129, 127, 0, 19, 102},
91     {8766, 0, 129, 127, 0, 19, 102}, {8767, 0, 129, 127, 0, 19, 102},
92     {8768, 0, 129, 127, 0, 19, 102}, {8769, 0, 129, 127, 0, 19, 102},
93     {8770, 0, 129, 127, 0, 19, 102}, {8771, 0, 129, 127, 0, 19, 102},
94     {8772, 0, 129, 127, 0, 19, 102}, {8773, 0, 129, 127, 0, 19, 102},
95     {8774, 0, 129, 127, 0, 19, 102}, {8775, 0, 129, 127, 0, 19, 102},
96     {8776, 0, 129, 127, 0, 19, 102}, {8777, 0, 129, 127, 0, 19, 102},
97     {8778, 0, 129, 127, 0, 19, 102}, {8779, 0, 129, 127, 0, 19, 114},
98     {8780, 0, 129, 127, 0, 19, 108}, {8781, 0, 129, 127, 0, 19, 114},
99     {8782, 0, 129, 127, 0, 13, 114}, {8783, 0, 129, 127, 0, 19, 108},
100     {8784, 0, 129, 127, 0, 13, 114}, {8785, 0, 129, 127, 0, 19, 108},
101     {8786, 0, 129, 127, 0, 19, 108}, {8787, 0, 129, 127, 0, 19, 108},
102     {8788, 0, 129, 127, 0, 19, 108}, {8789, 0, 129, 127, 0, 19, 108},
103     {8790, 0, 129, 127, 0, 19, 108}, {8791, 0, 129, 127, 0, 19, 108},
104     {8792, 0, 129, 127, 0, 19, 108}, {8793, 0, 129, 127, 0, 19, 108},
105     {8794, 0, 129, 127, 0, 19, 108}, {8795, 0, 129, 127, 0, 19, 108},
106     {8796, 0, 129, 127, 0, 19, 108}, {8797, 0, 129, 127, 0, 19, 108},
107     {8798, 0, 129, 127, 0, 19, 108}, {8799, 0, 129, 127, 0, 19, 108},
108     {8800, 0, 129, 127, 0, 19, 108}, {8801, 0, 129, 127, 0, 19, 108},
109     {8802, 0, 129, 127, 0, 19, 108}, {8803, 0, 129, 127, 0, 19, 108},
110     {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108},
111     {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108},
112     {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108},
113     {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114},
114     {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114},
115     {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121},
116     {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127},
117     {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108},
118 };
119 
120 // Boundary values to avoid integer overflow when multiplied by 1000.
121 const long kMinCBox = -2147483;
122 const long kMaxCBox = 2147483;
123 
GetFontGlobals()124 CPDF_FontGlobals* GetFontGlobals() {
125   return CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
126 }
127 
128 #if _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
129 
IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset)130 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
131   switch (charset) {
132     case CIDSET_GB1:
133     case CIDSET_CNS1:
134     case CIDSET_JAPAN1:
135     case CIDSET_KOREA1:
136       return true;
137 
138     default:
139       return false;
140   }
141 }
142 
EmbeddedUnicodeFromCharcode(const FXCMAP_CMap * pEmbedMap,CIDSet charset,uint32_t charcode)143 wchar_t EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
144                                     CIDSet charset,
145                                     uint32_t charcode) {
146   if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
147     return 0;
148 
149   uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
150   if (!cid)
151     return 0;
152 
153   const uint16_t* map;
154   uint32_t count;
155   std::tie(count, map) = GetFontGlobals()->GetEmbeddedToUnicode(charset);
156   if (map && cid < count)
157     return map[cid];
158   return 0;
159 }
160 
EmbeddedCharcodeFromUnicode(const FXCMAP_CMap * pEmbedMap,CIDSet charset,wchar_t unicode)161 uint32_t EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
162                                      CIDSet charset,
163                                      wchar_t unicode) {
164   if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
165     return 0;
166 
167   const uint16_t* map;
168   uint32_t count;
169   std::tie(count, map) = GetFontGlobals()->GetEmbeddedToUnicode(charset);
170   if (!map)
171     return 0;
172 
173   for (uint32_t i = 0; i < count; ++i) {
174     if (map[i] == unicode) {
175       uint32_t charCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
176       if (charCode)
177         return charCode;
178     }
179   }
180   return 0;
181 }
182 
183 #endif  // _FX_PLATFORM_ != _FX_PLATFORM_WINDOWS_
184 
FT_UseCIDCharmap(FXFT_Face face,int coding)185 void FT_UseCIDCharmap(FXFT_Face face, int coding) {
186   int encoding;
187   switch (coding) {
188     case CIDCODING_GB:
189       encoding = FXFT_ENCODING_GB2312;
190       break;
191     case CIDCODING_BIG5:
192       encoding = FXFT_ENCODING_BIG5;
193       break;
194     case CIDCODING_JIS:
195       encoding = FXFT_ENCODING_SJIS;
196       break;
197     case CIDCODING_KOREA:
198       encoding = FXFT_ENCODING_JOHAB;
199       break;
200     default:
201       encoding = FXFT_ENCODING_UNICODE;
202   }
203   int err = FXFT_Select_Charmap(face, encoding);
204   if (err)
205     err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
206   if (err && FXFT_Get_Face_Charmaps(face))
207     FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
208 }
209 
IsMetricForCID(const uint32_t * pEntry,uint16_t CID)210 bool IsMetricForCID(const uint32_t* pEntry, uint16_t CID) {
211   return pEntry[0] <= CID && pEntry[1] >= CID;
212 }
213 
214 }  // namespace
215 
CPDF_CIDFont()216 CPDF_CIDFont::CPDF_CIDFont()
217     : m_pCID2UnicodeMap(nullptr),
218       m_bCIDIsGID(false),
219       m_bAnsiWidthsFixed(false),
220       m_bAdobeCourierStd(false) {
221   for (size_t i = 0; i < FX_ArraySize(m_CharBBox); ++i)
222     m_CharBBox[i] = FX_RECT(-1, -1, -1, -1);
223 }
224 
~CPDF_CIDFont()225 CPDF_CIDFont::~CPDF_CIDFont() {}
226 
IsCIDFont() const227 bool CPDF_CIDFont::IsCIDFont() const {
228   return true;
229 }
230 
AsCIDFont() const231 const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const {
232   return this;
233 }
234 
AsCIDFont()235 CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() {
236   return this;
237 }
238 
CIDFromCharCode(uint32_t charcode) const239 uint16_t CPDF_CIDFont::CIDFromCharCode(uint32_t charcode) const {
240   return m_pCMap ? m_pCMap->CIDFromCharCode(charcode)
241                  : static_cast<uint16_t>(charcode);
242 }
243 
IsVertWriting() const244 bool CPDF_CIDFont::IsVertWriting() const {
245   return m_pCMap && m_pCMap->IsVertWriting();
246 }
247 
UnicodeFromCharCode(uint32_t charcode) const248 WideString CPDF_CIDFont::UnicodeFromCharCode(uint32_t charcode) const {
249   WideString str = CPDF_Font::UnicodeFromCharCode(charcode);
250   if (!str.IsEmpty())
251     return str;
252   wchar_t ret = GetUnicodeFromCharCode(charcode);
253   return ret ? ret : WideString();
254 }
255 
GetUnicodeFromCharCode(uint32_t charcode) const256 wchar_t CPDF_CIDFont::GetUnicodeFromCharCode(uint32_t charcode) const {
257   switch (m_pCMap->GetCoding()) {
258     case CIDCODING_UCS2:
259     case CIDCODING_UTF16:
260       return static_cast<wchar_t>(charcode);
261     case CIDCODING_CID:
262       if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded())
263         return 0;
264       return m_pCID2UnicodeMap->UnicodeFromCID(static_cast<uint16_t>(charcode));
265   }
266   if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded())
267     return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
268 
269 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
270   wchar_t unicode;
271   int charsize = 1;
272   if (charcode > 255) {
273     charcode = (charcode % 256) * 256 + (charcode / 256);
274     charsize = 2;
275   }
276   int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->GetCoding()], 0,
277                                       reinterpret_cast<const char*>(&charcode),
278                                       charsize, &unicode, 1);
279   return ret == 1 ? unicode : 0;
280 #else
281   if (!m_pCMap->GetEmbedMap())
282     return 0;
283   return EmbeddedUnicodeFromCharcode(m_pCMap->GetEmbedMap(),
284                                      m_pCMap->GetCharset(), charcode);
285 #endif
286 }
287 
CharCodeFromUnicode(wchar_t unicode) const288 uint32_t CPDF_CIDFont::CharCodeFromUnicode(wchar_t unicode) const {
289   uint32_t charcode = CPDF_Font::CharCodeFromUnicode(unicode);
290   if (charcode)
291     return charcode;
292   switch (m_pCMap->GetCoding()) {
293     case CIDCODING_UNKNOWN:
294       return 0;
295     case CIDCODING_UCS2:
296     case CIDCODING_UTF16:
297       return unicode;
298     case CIDCODING_CID: {
299       if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded())
300         return 0;
301       uint32_t CID = 0;
302       while (CID < 65536) {
303         wchar_t this_unicode =
304             m_pCID2UnicodeMap->UnicodeFromCID(static_cast<uint16_t>(CID));
305         if (this_unicode == unicode)
306           return CID;
307         CID++;
308       }
309       break;
310     }
311   }
312 
313   if (unicode < 0x80)
314     return static_cast<uint32_t>(unicode);
315   if (m_pCMap->GetCoding() == CIDCODING_CID)
316     return 0;
317 #if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
318   uint8_t buffer[32];
319   int ret = FXSYS_WideCharToMultiByte(
320       g_CharsetCPs[m_pCMap->GetCoding()], 0, &unicode, 1,
321       reinterpret_cast<char*>(buffer), 4, nullptr, nullptr);
322   if (ret == 1)
323     return buffer[0];
324   if (ret == 2)
325     return buffer[0] * 256 + buffer[1];
326 #else
327   if (m_pCMap->GetEmbedMap()) {
328     return EmbeddedCharcodeFromUnicode(m_pCMap->GetEmbedMap(),
329                                        m_pCMap->GetCharset(), unicode);
330   }
331 #endif
332   return 0;
333 }
334 
Load()335 bool CPDF_CIDFont::Load() {
336   if (m_pFontDict->GetStringFor("Subtype") == "TrueType") {
337     LoadGB2312();
338     return true;
339   }
340 
341   CPDF_Array* pFonts = m_pFontDict->GetArrayFor("DescendantFonts");
342   if (!pFonts || pFonts->GetCount() != 1)
343     return false;
344 
345   CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
346   if (!pCIDFontDict)
347     return false;
348 
349   m_BaseFont = pCIDFontDict->GetStringFor("BaseFont");
350   if ((m_BaseFont.Compare("CourierStd") == 0 ||
351        m_BaseFont.Compare("CourierStd-Bold") == 0 ||
352        m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
353        m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
354       !IsEmbedded()) {
355     m_bAdobeCourierStd = true;
356   }
357   CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictFor("FontDescriptor");
358   if (pFontDesc)
359     LoadFontDescriptor(pFontDesc);
360 
361   CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding");
362   if (!pEncoding)
363     return false;
364 
365   ByteString subtype = pCIDFontDict->GetStringFor("Subtype");
366   m_bType1 = (subtype == "CIDFontType0");
367 
368   CPDF_CMapManager* manager = GetFontGlobals()->GetCMapManager();
369   if (pEncoding->IsName()) {
370     ByteString cmap = pEncoding->GetString();
371     bool bPromptCJK = m_pFontFile && m_bType1;
372     m_pCMap = manager->GetPredefinedCMap(cmap, bPromptCJK);
373     if (!m_pCMap)
374       return false;
375   } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
376     auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
377     pAcc->LoadAllDataFiltered();
378     m_pCMap = pdfium::MakeRetain<CPDF_CMap>();
379     m_pCMap->LoadEmbedded(pAcc->GetData(), pAcc->GetSize());
380   } else {
381     return false;
382   }
383 
384   m_Charset = m_pCMap->GetCharset();
385   if (m_Charset == CIDSET_UNKNOWN) {
386     CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictFor("CIDSystemInfo");
387     if (pCIDInfo) {
388       m_Charset = CPDF_CMapParser::CharsetFromOrdering(
389           pCIDInfo->GetStringFor("Ordering").AsStringView());
390     }
391   }
392   if (m_Charset != CIDSET_UNKNOWN) {
393     bool bPromptCJK = !m_pFontFile && (m_pCMap->GetCoding() == CIDCODING_CID ||
394                                        pCIDFontDict->KeyExist("W"));
395     m_pCID2UnicodeMap = manager->GetCID2UnicodeMap(m_Charset, bPromptCJK);
396   }
397   if (m_Font.GetFace()) {
398     if (m_bType1)
399       FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
400     else
401       FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->GetCoding());
402   }
403   m_DefaultWidth = pCIDFontDict->GetIntegerFor("DW", 1000);
404   CPDF_Array* pWidthArray = pCIDFontDict->GetArrayFor("W");
405   if (pWidthArray)
406     LoadMetricsArray(pWidthArray, &m_WidthList, 1);
407   if (!IsEmbedded())
408     LoadSubstFont();
409 
410   if (m_pFontFile) {
411     CPDF_Object* pmap = pCIDFontDict->GetDirectObjectFor("CIDToGIDMap");
412     if (pmap) {
413       if (CPDF_Stream* pStream = pmap->AsStream()) {
414         m_pStreamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
415         m_pStreamAcc->LoadAllDataFiltered();
416       } else if (pmap->GetString() == "Identity") {
417 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
418         if (m_pFontFile)
419           m_bCIDIsGID = true;
420 #else
421         m_bCIDIsGID = true;
422 #endif
423       }
424     }
425   }
426 
427   CheckFontMetrics();
428   if (IsVertWriting()) {
429     pWidthArray = pCIDFontDict->GetArrayFor("W2");
430     if (pWidthArray)
431       LoadMetricsArray(pWidthArray, &m_VertMetrics, 3);
432     CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayFor("DW2");
433     if (pDefaultArray) {
434       m_DefaultVY = pDefaultArray->GetIntegerAt(0);
435       m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
436     } else {
437       m_DefaultVY = 880;
438       m_DefaultW1 = -1000;
439     }
440   }
441   return true;
442 }
443 
GetCharBBox(uint32_t charcode)444 FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) {
445   if (charcode < 256 && m_CharBBox[charcode].right != -1)
446     return m_CharBBox[charcode];
447 
448   FX_RECT rect;
449   bool bVert = false;
450   int glyph_index = GlyphFromCharCode(charcode, &bVert);
451   FXFT_Face face = m_Font.GetFace();
452   if (face) {
453     if (FXFT_Is_Face_Tricky(face)) {
454       int err = FXFT_Load_Glyph(face, glyph_index,
455                                 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
456       if (!err) {
457         FXFT_Glyph glyph;
458         err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph);
459         if (!err) {
460           FXFT_BBox cbox;
461           FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
462           cbox.xMin = pdfium::clamp(cbox.xMin, kMinCBox, kMaxCBox);
463           cbox.xMax = pdfium::clamp(cbox.xMax, kMinCBox, kMaxCBox);
464           cbox.yMin = pdfium::clamp(cbox.yMin, kMinCBox, kMaxCBox);
465           cbox.yMax = pdfium::clamp(cbox.yMax, kMinCBox, kMaxCBox);
466           int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem;
467           int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem;
468           if (pixel_size_x == 0 || pixel_size_y == 0) {
469             rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin);
470           } else {
471             rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x,
472                            cbox.yMax * 1000 / pixel_size_y,
473                            cbox.xMax * 1000 / pixel_size_x,
474                            cbox.yMin * 1000 / pixel_size_y);
475           }
476           rect.top = std::min(rect.top,
477                               static_cast<int>(FXFT_Get_Face_Ascender(face)));
478           rect.bottom = std::max(
479               rect.bottom, static_cast<int>(FXFT_Get_Face_Descender(face)));
480           FXFT_Done_Glyph(glyph);
481         }
482       }
483     } else {
484       int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE);
485       if (err == 0) {
486         rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
487                        TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
488                        TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) +
489                                   FXFT_Get_Glyph_Width(face),
490                               face),
491                        TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) -
492                                   FXFT_Get_Glyph_Height(face),
493                               face));
494         rect.top += rect.top / 64;
495       }
496     }
497   }
498   if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) {
499     uint16_t CID = CIDFromCharCode(charcode);
500     const uint8_t* pTransform = GetCIDTransform(CID);
501     if (pTransform && !bVert) {
502       CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]),
503                         CIDTransformToFloat(pTransform[1]),
504                         CIDTransformToFloat(pTransform[2]),
505                         CIDTransformToFloat(pTransform[3]),
506                         CIDTransformToFloat(pTransform[4]) * 1000,
507                         CIDTransformToFloat(pTransform[5]) * 1000);
508       rect = matrix.TransformRect(CFX_FloatRect(rect)).GetOuterRect();
509     }
510   }
511   if (charcode < 256)
512     m_CharBBox[charcode] = rect;
513 
514   return rect;
515 }
516 
GetCharWidthF(uint32_t charcode)517 int CPDF_CIDFont::GetCharWidthF(uint32_t charcode) {
518   if (charcode < 0x80 && m_bAnsiWidthsFixed)
519     return (charcode >= 32 && charcode < 127) ? 500 : 0;
520 
521   uint16_t cid = CIDFromCharCode(charcode);
522   size_t size = m_WidthList.size();
523   const uint32_t* pList = m_WidthList.data();
524   for (size_t i = 0; i < size; i += 3) {
525     const uint32_t* pEntry = pList + i;
526     if (IsMetricForCID(pEntry, cid))
527       return static_cast<int>(pEntry[2]);
528   }
529   return m_DefaultWidth;
530 }
531 
GetVertWidth(uint16_t CID) const532 short CPDF_CIDFont::GetVertWidth(uint16_t CID) const {
533   size_t vertsize = m_VertMetrics.size() / 5;
534   if (vertsize) {
535     const uint32_t* pTable = m_VertMetrics.data();
536     for (size_t i = 0; i < vertsize; i++) {
537       const uint32_t* pEntry = pTable + (i * 5);
538       if (IsMetricForCID(pEntry, CID))
539         return static_cast<short>(pEntry[2]);
540     }
541   }
542   return m_DefaultW1;
543 }
544 
GetVertOrigin(uint16_t CID,short & vx,short & vy) const545 void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const {
546   size_t vertsize = m_VertMetrics.size() / 5;
547   if (vertsize) {
548     const uint32_t* pTable = m_VertMetrics.data();
549     for (size_t i = 0; i < vertsize; i++) {
550       const uint32_t* pEntry = pTable + (i * 5);
551       if (IsMetricForCID(pEntry, CID)) {
552         vx = static_cast<short>(pEntry[3]);
553         vy = static_cast<short>(pEntry[4]);
554         return;
555       }
556     }
557   }
558   uint32_t dwWidth = m_DefaultWidth;
559   size_t size = m_WidthList.size();
560   const uint32_t* pList = m_WidthList.data();
561   for (size_t i = 0; i < size; i += 3) {
562     const uint32_t* pEntry = pList + i;
563     if (IsMetricForCID(pEntry, CID)) {
564       dwWidth = pEntry[2];
565       break;
566     }
567   }
568   vx = static_cast<short>(dwWidth) / 2;
569   vy = m_DefaultVY;
570 }
571 
GetGlyphIndex(uint32_t unicode,bool * pVertGlyph)572 int CPDF_CIDFont::GetGlyphIndex(uint32_t unicode, bool* pVertGlyph) {
573   if (pVertGlyph)
574     *pVertGlyph = false;
575 
576   FXFT_Face face = m_Font.GetFace();
577   int index = FXFT_Get_Char_Index(face, unicode);
578   if (unicode == 0x2502)
579     return index;
580 
581   if (!index || !IsVertWriting())
582     return index;
583 
584   if (m_pTTGSUBTable)
585     return GetVerticalGlyph(index, pVertGlyph);
586 
587   if (!m_Font.GetSubData()) {
588     unsigned long length = 0;
589     int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
590                                      nullptr, &length);
591     if (!error)
592       m_Font.SetSubData(FX_Alloc(uint8_t, length));
593   }
594   int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
595                                    m_Font.GetSubData(), nullptr);
596   if (error || !m_Font.GetSubData())
597     return index;
598 
599   m_pTTGSUBTable = pdfium::MakeUnique<CFX_CTTGSUBTable>();
600   m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
601   return GetVerticalGlyph(index, pVertGlyph);
602 }
603 
GetVerticalGlyph(int index,bool * pVertGlyph)604 int CPDF_CIDFont::GetVerticalGlyph(int index, bool* pVertGlyph) {
605   uint32_t vindex = 0;
606   m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
607   if (!vindex)
608     return index;
609 
610   index = vindex;
611   if (pVertGlyph)
612     *pVertGlyph = true;
613   return index;
614 }
615 
GlyphFromCharCode(uint32_t charcode,bool * pVertGlyph)616 int CPDF_CIDFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) {
617   if (pVertGlyph)
618     *pVertGlyph = false;
619 
620   if (!m_pFontFile && !m_pStreamAcc) {
621     uint16_t cid = CIDFromCharCode(charcode);
622     wchar_t unicode = 0;
623     if (m_bCIDIsGID) {
624 #if _FX_PLATFORM_ != _FX_PLATFORM_APPLE_
625       return cid;
626 #else
627       if (FontStyleIsSymbolic(m_Flags))
628         return cid;
629 
630       WideString uni_str = UnicodeFromCharCode(charcode);
631       if (uni_str.IsEmpty())
632         return cid;
633 
634       unicode = uni_str[0];
635 #endif
636     } else {
637       if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded())
638         unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid);
639       if (unicode == 0)
640         unicode = GetUnicodeFromCharCode(charcode);
641       if (unicode == 0) {
642         WideString unicode_str = UnicodeFromCharCode(charcode);
643         if (!unicode_str.IsEmpty())
644           unicode = unicode_str[0];
645       }
646     }
647     FXFT_Face face = m_Font.GetFace();
648     if (unicode == 0) {
649       if (!m_bAdobeCourierStd)
650         return charcode ? static_cast<int>(charcode) : -1;
651 
652       charcode += 31;
653       bool bMSUnicode = FT_UseTTCharmap(face, 3, 1);
654       bool bMacRoman = !bMSUnicode && FT_UseTTCharmap(face, 1, 0);
655       int iBaseEncoding = PDFFONT_ENCODING_STANDARD;
656       if (bMSUnicode)
657         iBaseEncoding = PDFFONT_ENCODING_WINANSI;
658       else if (bMacRoman)
659         iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
660       const char* name =
661           GetAdobeCharName(iBaseEncoding, std::vector<ByteString>(), charcode);
662       if (!name)
663         return charcode ? static_cast<int>(charcode) : -1;
664 
665       int index = 0;
666       uint16_t name_unicode = PDF_UnicodeFromAdobeName(name);
667       if (!name_unicode)
668         return charcode ? static_cast<int>(charcode) : -1;
669 
670       if (iBaseEncoding == PDFFONT_ENCODING_STANDARD)
671         return FXFT_Get_Char_Index(face, name_unicode);
672 
673       if (iBaseEncoding == PDFFONT_ENCODING_WINANSI) {
674         index = FXFT_Get_Char_Index(face, name_unicode);
675       } else {
676         ASSERT(iBaseEncoding == PDFFONT_ENCODING_MACROMAN);
677         uint32_t maccode =
678             FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, name_unicode);
679         index = maccode ? FXFT_Get_Char_Index(face, maccode)
680                         : FXFT_Get_Name_Index(face, const_cast<char*>(name));
681       }
682       if (index == 0 || index == 0xffff)
683         return charcode ? static_cast<int>(charcode) : -1;
684       return index;
685     }
686     if (m_Charset == CIDSET_JAPAN1) {
687       if (unicode == '\\') {
688         unicode = '/';
689 #if _FX_PLATFORM_ != _FX_PLATFORM_APPLE_
690       } else if (unicode == 0xa5) {
691         unicode = 0x5c;
692 #endif
693       }
694     }
695     if (!face)
696       return unicode;
697 
698     int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
699     if (err) {
700       int i;
701       for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
702         uint32_t ret = FT_CharCodeFromUnicode(
703             FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
704             static_cast<wchar_t>(charcode));
705         if (ret == 0)
706           continue;
707         FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
708         unicode = static_cast<wchar_t>(ret);
709         break;
710       }
711       if (i == FXFT_Get_Face_CharmapCount(face) && i) {
712         FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
713         unicode = static_cast<wchar_t>(charcode);
714       }
715     }
716     if (FXFT_Get_Face_Charmap(face)) {
717       int index = GetGlyphIndex(unicode, pVertGlyph);
718       return index != 0 ? index : -1;
719     }
720     return unicode;
721   }
722 
723   if (!m_Font.GetFace())
724     return -1;
725 
726   uint16_t cid = CIDFromCharCode(charcode);
727   if (!m_pStreamAcc) {
728     if (m_bType1)
729       return cid;
730     if (m_pFontFile && m_pCMap->IsDirectCharcodeToCIDTableIsEmpty())
731       return cid;
732     if (m_pCMap->GetCoding() == CIDCODING_UNKNOWN ||
733         !FXFT_Get_Face_Charmap(m_Font.GetFace())) {
734       return cid;
735     }
736     if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) ==
737         FXFT_ENCODING_UNICODE) {
738       WideString unicode_str = UnicodeFromCharCode(charcode);
739       if (unicode_str.IsEmpty())
740         return -1;
741 
742       charcode = unicode_str[0];
743     }
744     return GetGlyphIndex(charcode, pVertGlyph);
745   }
746   uint32_t byte_pos = cid * 2;
747   if (byte_pos + 2 > m_pStreamAcc->GetSize())
748     return -1;
749 
750   const uint8_t* pdata = m_pStreamAcc->GetData() + byte_pos;
751   return pdata[0] * 256 + pdata[1];
752 }
753 
GetNextChar(const char * pString,int nStrLen,int & offset) const754 uint32_t CPDF_CIDFont::GetNextChar(const char* pString,
755                                    int nStrLen,
756                                    int& offset) const {
757   return m_pCMap->GetNextChar(pString, nStrLen, offset);
758 }
759 
GetCharSize(uint32_t charcode) const760 int CPDF_CIDFont::GetCharSize(uint32_t charcode) const {
761   return m_pCMap->GetCharSize(charcode);
762 }
763 
CountChar(const char * pString,int size) const764 int CPDF_CIDFont::CountChar(const char* pString, int size) const {
765   return m_pCMap->CountChar(pString, size);
766 }
767 
AppendChar(char * str,uint32_t charcode) const768 int CPDF_CIDFont::AppendChar(char* str, uint32_t charcode) const {
769   return m_pCMap->AppendChar(str, charcode);
770 }
771 
IsUnicodeCompatible() const772 bool CPDF_CIDFont::IsUnicodeCompatible() const {
773   if (m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded() && m_pCMap->IsLoaded())
774     return true;
775   return m_pCMap->GetCoding() != CIDCODING_UNKNOWN;
776 }
777 
LoadSubstFont()778 void CPDF_CIDFont::LoadSubstFont() {
779   pdfium::base::CheckedNumeric<int> safeStemV(m_StemV);
780   safeStemV *= 5;
781   m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags,
782                    safeStemV.ValueOrDefault(FXFONT_FW_NORMAL), m_ItalicAngle,
783                    g_CharsetCPs[m_Charset], IsVertWriting());
784 }
785 
LoadMetricsArray(CPDF_Array * pArray,std::vector<uint32_t> * result,int nElements)786 void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
787                                     std::vector<uint32_t>* result,
788                                     int nElements) {
789   int width_status = 0;
790   int iCurElement = 0;
791   uint32_t first_code = 0;
792   uint32_t last_code = 0;
793   for (size_t i = 0; i < pArray->GetCount(); i++) {
794     CPDF_Object* pObj = pArray->GetDirectObjectAt(i);
795     if (!pObj)
796       continue;
797 
798     if (CPDF_Array* pObjArray = pObj->AsArray()) {
799       if (width_status != 1)
800         return;
801       if (first_code >
802           std::numeric_limits<uint32_t>::max() - pObjArray->GetCount()) {
803         width_status = 0;
804         continue;
805       }
806 
807       for (size_t j = 0; j < pObjArray->GetCount(); j += nElements) {
808         result->push_back(first_code);
809         result->push_back(first_code);
810         for (int k = 0; k < nElements; k++)
811           result->push_back(pObjArray->GetIntegerAt(j + k));
812         first_code++;
813       }
814       width_status = 0;
815     } else {
816       if (width_status == 0) {
817         first_code = pObj->GetInteger();
818         width_status = 1;
819       } else if (width_status == 1) {
820         last_code = pObj->GetInteger();
821         width_status = 2;
822         iCurElement = 0;
823       } else {
824         if (!iCurElement) {
825           result->push_back(first_code);
826           result->push_back(last_code);
827         }
828         result->push_back(pObj->GetInteger());
829         iCurElement++;
830         if (iCurElement == nElements)
831           width_status = 0;
832       }
833     }
834   }
835 }
836 
837 // static
CIDTransformToFloat(uint8_t ch)838 float CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) {
839   return (ch < 128 ? ch : ch - 255) * (1.0f / 127);
840 }
841 
LoadGB2312()842 void CPDF_CIDFont::LoadGB2312() {
843   m_BaseFont = m_pFontDict->GetStringFor("BaseFont");
844   CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor");
845   if (pFontDesc)
846     LoadFontDescriptor(pFontDesc);
847 
848   m_Charset = CIDSET_GB1;
849   m_bType1 = false;
850 
851   CPDF_CMapManager* manager = GetFontGlobals()->GetCMapManager();
852   m_pCMap = manager->GetPredefinedCMap("GBK-EUC-H", false);
853   m_pCID2UnicodeMap = manager->GetCID2UnicodeMap(m_Charset, false);
854   if (!IsEmbedded())
855     LoadSubstFont();
856 
857   CheckFontMetrics();
858   m_DefaultWidth = 1000;
859   m_bAnsiWidthsFixed = true;
860 }
861 
GetCIDTransform(uint16_t CID) const862 const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
863   if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
864     return nullptr;
865 
866   const auto* pEnd = g_Japan1_VertCIDs + FX_ArraySize(g_Japan1_VertCIDs);
867   const auto* pTransform = std::lower_bound(
868       g_Japan1_VertCIDs, pEnd, CID,
869       [](const CIDTransform& entry, uint16_t cid) { return entry.cid < cid; });
870   return (pTransform < pEnd && CID == pTransform->cid) ? &pTransform->a
871                                                        : nullptr;
872 }
873