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