1 // Copyright 2014 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 "font_int.h"
8 
9 #include "core/include/fpdfapi/fpdf_module.h"
10 #include "core/include/fpdfapi/fpdf_page.h"
11 #include "core/include/fpdfapi/fpdf_resource.h"
12 #include "core/include/fxcrt/fx_ext.h"
13 #include "core/include/fxge/fx_freetype.h"
14 #include "core/include/fxge/fx_ge.h"
15 #include "core/src/fpdfapi/fpdf_cmaps/cmap_int.h"
16 
17 namespace {
18 
19 const FX_CHAR* const g_CharsetNames[CIDSET_NUM_SETS] =
20     {nullptr, "GB1", "CNS1", "Japan1", "Korea1", "UCS"};
21 
22 const int g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
23 
24 class CPDF_PredefinedCMap {
25  public:
26   const FX_CHAR* m_pName;
27   CIDSet m_Charset;
28   int m_Coding;
29   CPDF_CMap::CodingScheme m_CodingScheme;
30   FX_DWORD m_LeadingSegCount;
31   uint8_t m_LeadingSegs[4];
32 };
33 
34 const CPDF_PredefinedCMap g_PredefinedCMaps[] = {
35     {"GB-EUC",
36      CIDSET_GB1,
37      CIDCODING_GB,
38      CPDF_CMap::MixedTwoBytes,
39      1,
40      {0xa1, 0xfe}},
41     {"GBpc-EUC",
42      CIDSET_GB1,
43      CIDCODING_GB,
44      CPDF_CMap::MixedTwoBytes,
45      1,
46      {0xa1, 0xfc}},
47     {"GBK-EUC",
48      CIDSET_GB1,
49      CIDCODING_GB,
50      CPDF_CMap::MixedTwoBytes,
51      1,
52      {0x81, 0xfe}},
53     {"GBKp-EUC",
54      CIDSET_GB1,
55      CIDCODING_GB,
56      CPDF_CMap::MixedTwoBytes,
57      1,
58      {0x81, 0xfe}},
59     {"GBK2K-EUC",
60      CIDSET_GB1,
61      CIDCODING_GB,
62      CPDF_CMap::MixedTwoBytes,
63      1,
64      {0x81, 0xfe}},
65     {"GBK2K",
66      CIDSET_GB1,
67      CIDCODING_GB,
68      CPDF_CMap::MixedTwoBytes,
69      1,
70      {0x81, 0xfe}},
71     {"UniGB-UCS2", CIDSET_GB1, CIDCODING_UCS2, CPDF_CMap::TwoBytes},
72     {"UniGB-UTF16", CIDSET_GB1, CIDCODING_UTF16, CPDF_CMap::TwoBytes},
73     {"B5pc",
74      CIDSET_CNS1,
75      CIDCODING_BIG5,
76      CPDF_CMap::MixedTwoBytes,
77      1,
78      {0xa1, 0xfc}},
79     {"HKscs-B5",
80      CIDSET_CNS1,
81      CIDCODING_BIG5,
82      CPDF_CMap::MixedTwoBytes,
83      1,
84      {0x88, 0xfe}},
85     {"ETen-B5",
86      CIDSET_CNS1,
87      CIDCODING_BIG5,
88      CPDF_CMap::MixedTwoBytes,
89      1,
90      {0xa1, 0xfe}},
91     {"ETenms-B5",
92      CIDSET_CNS1,
93      CIDCODING_BIG5,
94      CPDF_CMap::MixedTwoBytes,
95      1,
96      {0xa1, 0xfe}},
97     {"UniCNS-UCS2", CIDSET_CNS1, CIDCODING_UCS2, CPDF_CMap::TwoBytes},
98     {"UniCNS-UTF16", CIDSET_CNS1, CIDCODING_UTF16, CPDF_CMap::TwoBytes},
99     {"83pv-RKSJ",
100      CIDSET_JAPAN1,
101      CIDCODING_JIS,
102      CPDF_CMap::MixedTwoBytes,
103      2,
104      {0x81, 0x9f, 0xe0, 0xfc}},
105     {"90ms-RKSJ",
106      CIDSET_JAPAN1,
107      CIDCODING_JIS,
108      CPDF_CMap::MixedTwoBytes,
109      2,
110      {0x81, 0x9f, 0xe0, 0xfc}},
111     {"90msp-RKSJ",
112      CIDSET_JAPAN1,
113      CIDCODING_JIS,
114      CPDF_CMap::MixedTwoBytes,
115      2,
116      {0x81, 0x9f, 0xe0, 0xfc}},
117     {"90pv-RKSJ",
118      CIDSET_JAPAN1,
119      CIDCODING_JIS,
120      CPDF_CMap::MixedTwoBytes,
121      2,
122      {0x81, 0x9f, 0xe0, 0xfc}},
123     {"Add-RKSJ",
124      CIDSET_JAPAN1,
125      CIDCODING_JIS,
126      CPDF_CMap::MixedTwoBytes,
127      2,
128      {0x81, 0x9f, 0xe0, 0xfc}},
129     {"EUC",
130      CIDSET_JAPAN1,
131      CIDCODING_JIS,
132      CPDF_CMap::MixedTwoBytes,
133      2,
134      {0x8e, 0x8e, 0xa1, 0xfe}},
135     {"H", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}},
136     {"V", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e}},
137     {"Ext-RKSJ",
138      CIDSET_JAPAN1,
139      CIDCODING_JIS,
140      CPDF_CMap::MixedTwoBytes,
141      2,
142      {0x81, 0x9f, 0xe0, 0xfc}},
143     {"UniJIS-UCS2", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes},
144     {"UniJIS-UCS2-HW", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes},
145     {"UniJIS-UTF16", CIDSET_JAPAN1, CIDCODING_UTF16, CPDF_CMap::TwoBytes},
146     {"KSC-EUC",
147      CIDSET_KOREA1,
148      CIDCODING_KOREA,
149      CPDF_CMap::MixedTwoBytes,
150      1,
151      {0xa1, 0xfe}},
152     {"KSCms-UHC",
153      CIDSET_KOREA1,
154      CIDCODING_KOREA,
155      CPDF_CMap::MixedTwoBytes,
156      1,
157      {0x81, 0xfe}},
158     {"KSCms-UHC-HW",
159      CIDSET_KOREA1,
160      CIDCODING_KOREA,
161      CPDF_CMap::MixedTwoBytes,
162      1,
163      {0x81, 0xfe}},
164     {"KSCpc-EUC",
165      CIDSET_KOREA1,
166      CIDCODING_KOREA,
167      CPDF_CMap::MixedTwoBytes,
168      1,
169      {0xa1, 0xfd}},
170     {"UniKS-UCS2", CIDSET_KOREA1, CIDCODING_UCS2, CPDF_CMap::TwoBytes},
171     {"UniKS-UTF16", CIDSET_KOREA1, CIDCODING_UTF16, CPDF_CMap::TwoBytes},
172 };
173 
CIDSetFromSizeT(size_t index)174 CIDSet CIDSetFromSizeT(size_t index) {
175   if (index >= CIDSET_NUM_SETS) {
176     NOTREACHED();
177     return CIDSET_UNKNOWN;
178   }
179   return static_cast<CIDSet>(index);
180 }
181 
CharsetFromOrdering(const CFX_ByteString & ordering)182 CIDSet CharsetFromOrdering(const CFX_ByteString& ordering) {
183   for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) {
184     if (ordering == CFX_ByteStringC(g_CharsetNames[charset]))
185       return CIDSetFromSizeT(charset);
186   }
187   return CIDSET_UNKNOWN;
188 }
189 
CMap_GetString(const CFX_ByteStringC & word)190 CFX_ByteString CMap_GetString(const CFX_ByteStringC& word) {
191   return word.Mid(1, word.GetLength() - 2);
192 }
193 
CompareDWORD(const void * data1,const void * data2)194 int CompareDWORD(const void* data1, const void* data2) {
195   return (*(FX_DWORD*)data1) - (*(FX_DWORD*)data2);
196 }
197 
CompareCID(const void * key,const void * element)198 int CompareCID(const void* key, const void* element) {
199   if ((*(FX_DWORD*)key) < (*(FX_DWORD*)element)) {
200     return -1;
201   }
202   if ((*(FX_DWORD*)key) >
203       (*(FX_DWORD*)element) + ((FX_DWORD*)element)[1] / 65536) {
204     return 1;
205   }
206   return 0;
207 }
208 
CheckCodeRange(uint8_t * codes,int size,CMap_CodeRange * pRanges,int nRanges)209 int CheckCodeRange(uint8_t* codes,
210                    int size,
211                    CMap_CodeRange* pRanges,
212                    int nRanges) {
213   int iSeg = nRanges - 1;
214   while (iSeg >= 0) {
215     if (pRanges[iSeg].m_CharSize < size) {
216       --iSeg;
217       continue;
218     }
219     int iChar = 0;
220     while (iChar < size) {
221       if (codes[iChar] < pRanges[iSeg].m_Lower[iChar] ||
222           codes[iChar] > pRanges[iSeg].m_Upper[iChar]) {
223         break;
224       }
225       ++iChar;
226     }
227     if (iChar == pRanges[iSeg].m_CharSize)
228       return 2;
229 
230     if (iChar)
231       return (size == pRanges[iSeg].m_CharSize) ? 2 : 1;
232     iSeg--;
233   }
234   return 0;
235 }
236 
GetCharSizeImpl(FX_DWORD charcode,CMap_CodeRange * pRanges,int iRangesSize)237 int GetCharSizeImpl(FX_DWORD charcode,
238                     CMap_CodeRange* pRanges,
239                     int iRangesSize) {
240   if (!iRangesSize)
241     return 1;
242 
243   uint8_t codes[4];
244   codes[0] = codes[1] = 0x00;
245   codes[2] = (uint8_t)(charcode >> 8 & 0xFF);
246   codes[3] = (uint8_t)charcode;
247   int offset = 0;
248   int size = 4;
249   for (int i = 0; i < 4; ++i) {
250     int iSeg = iRangesSize - 1;
251     while (iSeg >= 0) {
252       if (pRanges[iSeg].m_CharSize < size) {
253         --iSeg;
254         continue;
255       }
256       int iChar = 0;
257       while (iChar < size) {
258         if (codes[offset + iChar] < pRanges[iSeg].m_Lower[iChar] ||
259             codes[offset + iChar] > pRanges[iSeg].m_Upper[iChar]) {
260           break;
261         }
262         ++iChar;
263       }
264       if (iChar == pRanges[iSeg].m_CharSize)
265         return size;
266       --iSeg;
267     }
268     --size;
269     ++offset;
270   }
271   return 1;
272 }
273 
IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset)274 bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
275   switch (charset) {
276     case CIDSET_GB1:
277     case CIDSET_CNS1:
278     case CIDSET_JAPAN1:
279     case CIDSET_KOREA1:
280       return true;
281 
282     default:
283       return false;
284   }
285 }
286 
287 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
EmbeddedCharcodeFromUnicode(const FXCMAP_CMap * pEmbedMap,CIDSet charset,FX_WCHAR unicode)288 FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
289                                      CIDSet charset,
290                                      FX_WCHAR unicode) {
291   if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
292     return 0;
293 
294   CPDF_FontGlobals* pFontGlobals =
295       CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
296   const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
297   if (!pCodes)
298     return 0;
299 
300   int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
301   for (int i = 0; i < nCodes; ++i) {
302     if (pCodes[i] == unicode) {
303       FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
304       if (CharCode != 0) {
305         return CharCode;
306       }
307     }
308   }
309   return 0;
310 }
311 #endif  // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
312 
EmbeddedUnicodeFromCharcode(const FXCMAP_CMap * pEmbedMap,CIDSet charset,FX_DWORD charcode)313 FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
314                                      CIDSet charset,
315                                      FX_DWORD charcode) {
316   if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
317     return 0;
318 
319   FX_WORD cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
320   if (cid == 0)
321     return 0;
322 
323   CPDF_FontGlobals* pFontGlobals =
324       CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
325   const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
326   if (!pCodes)
327     return 0;
328 
329   if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count)
330     return pCodes[cid];
331   return 0;
332 }
333 
FT_UseCIDCharmap(FXFT_Face face,int coding)334 void FT_UseCIDCharmap(FXFT_Face face, int coding) {
335   int encoding;
336   switch (coding) {
337     case CIDCODING_GB:
338       encoding = FXFT_ENCODING_GB2312;
339       break;
340     case CIDCODING_BIG5:
341       encoding = FXFT_ENCODING_BIG5;
342       break;
343     case CIDCODING_JIS:
344       encoding = FXFT_ENCODING_SJIS;
345       break;
346     case CIDCODING_KOREA:
347       encoding = FXFT_ENCODING_JOHAB;
348       break;
349     default:
350       encoding = FXFT_ENCODING_UNICODE;
351   }
352   int err = FXFT_Select_Charmap(face, encoding);
353   if (err) {
354     err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
355   }
356   if (err && FXFT_Get_Face_Charmaps(face)) {
357     FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
358   }
359 }
360 
361 const struct CIDTransform {
362   FX_WORD CID;
363   uint8_t a, b, c, d, e, f;
364 } g_Japan1_VertCIDs[] = {
365     {97, 129, 0, 0, 127, 55, 0},
366     {7887, 127, 0, 0, 127, 76, 89},
367     {7888, 127, 0, 0, 127, 79, 94},
368     {7889, 0, 129, 127, 0, 17, 127},
369     {7890, 0, 129, 127, 0, 17, 127},
370     {7891, 0, 129, 127, 0, 17, 127},
371     {7892, 0, 129, 127, 0, 17, 127},
372     {7893, 0, 129, 127, 0, 17, 127},
373     {7894, 0, 129, 127, 0, 17, 127},
374     {7895, 0, 129, 127, 0, 17, 127},
375     {7896, 0, 129, 127, 0, 17, 127},
376     {7897, 0, 129, 127, 0, 17, 127},
377     {7898, 0, 129, 127, 0, 17, 127},
378     {7899, 0, 129, 127, 0, 17, 104},
379     {7900, 0, 129, 127, 0, 17, 127},
380     {7901, 0, 129, 127, 0, 17, 104},
381     {7902, 0, 129, 127, 0, 17, 127},
382     {7903, 0, 129, 127, 0, 17, 127},
383     {7904, 0, 129, 127, 0, 17, 127},
384     {7905, 0, 129, 127, 0, 17, 114},
385     {7906, 0, 129, 127, 0, 17, 127},
386     {7907, 0, 129, 127, 0, 17, 127},
387     {7908, 0, 129, 127, 0, 17, 127},
388     {7909, 0, 129, 127, 0, 17, 127},
389     {7910, 0, 129, 127, 0, 17, 127},
390     {7911, 0, 129, 127, 0, 17, 127},
391     {7912, 0, 129, 127, 0, 17, 127},
392     {7913, 0, 129, 127, 0, 17, 127},
393     {7914, 0, 129, 127, 0, 17, 127},
394     {7915, 0, 129, 127, 0, 17, 114},
395     {7916, 0, 129, 127, 0, 17, 127},
396     {7917, 0, 129, 127, 0, 17, 127},
397     {7918, 127, 0, 0, 127, 18, 25},
398     {7919, 127, 0, 0, 127, 18, 25},
399     {7920, 127, 0, 0, 127, 18, 25},
400     {7921, 127, 0, 0, 127, 18, 25},
401     {7922, 127, 0, 0, 127, 18, 25},
402     {7923, 127, 0, 0, 127, 18, 25},
403     {7924, 127, 0, 0, 127, 18, 25},
404     {7925, 127, 0, 0, 127, 18, 25},
405     {7926, 127, 0, 0, 127, 18, 25},
406     {7927, 127, 0, 0, 127, 18, 25},
407     {7928, 127, 0, 0, 127, 18, 25},
408     {7929, 127, 0, 0, 127, 18, 25},
409     {7930, 127, 0, 0, 127, 18, 25},
410     {7931, 127, 0, 0, 127, 18, 25},
411     {7932, 127, 0, 0, 127, 18, 25},
412     {7933, 127, 0, 0, 127, 18, 25},
413     {7934, 127, 0, 0, 127, 18, 25},
414     {7935, 127, 0, 0, 127, 18, 25},
415     {7936, 127, 0, 0, 127, 18, 25},
416     {7937, 127, 0, 0, 127, 18, 25},
417     {7938, 127, 0, 0, 127, 18, 25},
418     {7939, 127, 0, 0, 127, 18, 25},
419     {8720, 0, 129, 127, 0, 19, 102},
420     {8721, 0, 129, 127, 0, 13, 127},
421     {8722, 0, 129, 127, 0, 19, 108},
422     {8723, 0, 129, 127, 0, 19, 102},
423     {8724, 0, 129, 127, 0, 19, 102},
424     {8725, 0, 129, 127, 0, 19, 102},
425     {8726, 0, 129, 127, 0, 19, 102},
426     {8727, 0, 129, 127, 0, 19, 102},
427     {8728, 0, 129, 127, 0, 19, 114},
428     {8729, 0, 129, 127, 0, 19, 114},
429     {8730, 0, 129, 127, 0, 38, 108},
430     {8731, 0, 129, 127, 0, 13, 108},
431     {8732, 0, 129, 127, 0, 19, 108},
432     {8733, 0, 129, 127, 0, 19, 108},
433     {8734, 0, 129, 127, 0, 19, 108},
434     {8735, 0, 129, 127, 0, 19, 108},
435     {8736, 0, 129, 127, 0, 19, 102},
436     {8737, 0, 129, 127, 0, 19, 102},
437     {8738, 0, 129, 127, 0, 19, 102},
438     {8739, 0, 129, 127, 0, 19, 102},
439     {8740, 0, 129, 127, 0, 19, 102},
440     {8741, 0, 129, 127, 0, 19, 102},
441     {8742, 0, 129, 127, 0, 19, 102},
442     {8743, 0, 129, 127, 0, 19, 102},
443     {8744, 0, 129, 127, 0, 19, 102},
444     {8745, 0, 129, 127, 0, 19, 102},
445     {8746, 0, 129, 127, 0, 19, 114},
446     {8747, 0, 129, 127, 0, 19, 114},
447     {8748, 0, 129, 127, 0, 19, 102},
448     {8749, 0, 129, 127, 0, 19, 102},
449     {8750, 0, 129, 127, 0, 19, 102},
450     {8751, 0, 129, 127, 0, 19, 102},
451     {8752, 0, 129, 127, 0, 19, 102},
452     {8753, 0, 129, 127, 0, 19, 102},
453     {8754, 0, 129, 127, 0, 19, 102},
454     {8755, 0, 129, 127, 0, 19, 102},
455     {8756, 0, 129, 127, 0, 19, 102},
456     {8757, 0, 129, 127, 0, 19, 102},
457     {8758, 0, 129, 127, 0, 19, 102},
458     {8759, 0, 129, 127, 0, 19, 102},
459     {8760, 0, 129, 127, 0, 19, 102},
460     {8761, 0, 129, 127, 0, 19, 102},
461     {8762, 0, 129, 127, 0, 19, 102},
462     {8763, 0, 129, 127, 0, 19, 102},
463     {8764, 0, 129, 127, 0, 19, 102},
464     {8765, 0, 129, 127, 0, 19, 102},
465     {8766, 0, 129, 127, 0, 19, 102},
466     {8767, 0, 129, 127, 0, 19, 102},
467     {8768, 0, 129, 127, 0, 19, 102},
468     {8769, 0, 129, 127, 0, 19, 102},
469     {8770, 0, 129, 127, 0, 19, 102},
470     {8771, 0, 129, 127, 0, 19, 102},
471     {8772, 0, 129, 127, 0, 19, 102},
472     {8773, 0, 129, 127, 0, 19, 102},
473     {8774, 0, 129, 127, 0, 19, 102},
474     {8775, 0, 129, 127, 0, 19, 102},
475     {8776, 0, 129, 127, 0, 19, 102},
476     {8777, 0, 129, 127, 0, 19, 102},
477     {8778, 0, 129, 127, 0, 19, 102},
478     {8779, 0, 129, 127, 0, 19, 114},
479     {8780, 0, 129, 127, 0, 19, 108},
480     {8781, 0, 129, 127, 0, 19, 114},
481     {8782, 0, 129, 127, 0, 13, 114},
482     {8783, 0, 129, 127, 0, 19, 108},
483     {8784, 0, 129, 127, 0, 13, 114},
484     {8785, 0, 129, 127, 0, 19, 108},
485     {8786, 0, 129, 127, 0, 19, 108},
486     {8787, 0, 129, 127, 0, 19, 108},
487     {8788, 0, 129, 127, 0, 19, 108},
488     {8789, 0, 129, 127, 0, 19, 108},
489     {8790, 0, 129, 127, 0, 19, 108},
490     {8791, 0, 129, 127, 0, 19, 108},
491     {8792, 0, 129, 127, 0, 19, 108},
492     {8793, 0, 129, 127, 0, 19, 108},
493     {8794, 0, 129, 127, 0, 19, 108},
494     {8795, 0, 129, 127, 0, 19, 108},
495     {8796, 0, 129, 127, 0, 19, 108},
496     {8797, 0, 129, 127, 0, 19, 108},
497     {8798, 0, 129, 127, 0, 19, 108},
498     {8799, 0, 129, 127, 0, 19, 108},
499     {8800, 0, 129, 127, 0, 19, 108},
500     {8801, 0, 129, 127, 0, 19, 108},
501     {8802, 0, 129, 127, 0, 19, 108},
502     {8803, 0, 129, 127, 0, 19, 108},
503     {8804, 0, 129, 127, 0, 19, 108},
504     {8805, 0, 129, 127, 0, 19, 108},
505     {8806, 0, 129, 127, 0, 19, 108},
506     {8807, 0, 129, 127, 0, 19, 108},
507     {8808, 0, 129, 127, 0, 19, 108},
508     {8809, 0, 129, 127, 0, 19, 108},
509     {8810, 0, 129, 127, 0, 19, 108},
510     {8811, 0, 129, 127, 0, 19, 114},
511     {8812, 0, 129, 127, 0, 19, 102},
512     {8813, 0, 129, 127, 0, 19, 114},
513     {8814, 0, 129, 127, 0, 76, 102},
514     {8815, 0, 129, 127, 0, 13, 121},
515     {8816, 0, 129, 127, 0, 19, 114},
516     {8817, 0, 129, 127, 0, 19, 127},
517     {8818, 0, 129, 127, 0, 19, 114},
518     {8819, 0, 129, 127, 0, 218, 108},
519 };
520 
CompareCIDTransform(const void * key,const void * element)521 int CompareCIDTransform(const void* key, const void* element) {
522   FX_WORD CID = *static_cast<const FX_WORD*>(key);
523   return CID - static_cast<const struct CIDTransform*>(element)->CID;
524 }
525 
526 }  // namespace
527 
CPDF_CMapManager()528 CPDF_CMapManager::CPDF_CMapManager() {
529   m_bPrompted = FALSE;
530   FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps);
531 }
~CPDF_CMapManager()532 CPDF_CMapManager::~CPDF_CMapManager() {
533   for (const auto& pair : m_CMaps) {
534     delete pair.second;
535   }
536   m_CMaps.clear();
537   for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) {
538     delete m_CID2UnicodeMaps[i];
539   }
540 }
GetPredefinedCMap(const CFX_ByteString & name,FX_BOOL bPromptCJK)541 CPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name,
542                                                FX_BOOL bPromptCJK) {
543   auto it = m_CMaps.find(name);
544   if (it != m_CMaps.end()) {
545     return it->second;
546   }
547   CPDF_CMap* pCMap = LoadPredefinedCMap(name, bPromptCJK);
548   if (!name.IsEmpty()) {
549     m_CMaps[name] = pCMap;
550   }
551   return pCMap;
552 }
LoadPredefinedCMap(const CFX_ByteString & name,FX_BOOL bPromptCJK)553 CPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name,
554                                                 FX_BOOL bPromptCJK) {
555   CPDF_CMap* pCMap = new CPDF_CMap;
556   const FX_CHAR* pname = name;
557   if (*pname == '/') {
558     pname++;
559   }
560   pCMap->LoadPredefined(this, pname, bPromptCJK);
561   return pCMap;
562 }
563 
ReloadAll()564 void CPDF_CMapManager::ReloadAll() {
565   for (const auto& pair : m_CMaps) {
566     CPDF_CMap* pCMap = pair.second;
567     pCMap->LoadPredefined(this, pair.first, FALSE);
568   }
569   for (size_t i = 0; i < FX_ArraySize(m_CID2UnicodeMaps); ++i) {
570     if (CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i]) {
571       pMap->Load(this, CIDSetFromSizeT(i), FALSE);
572     }
573   }
574 }
GetCID2UnicodeMap(CIDSet charset,FX_BOOL bPromptCJK)575 CPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(CIDSet charset,
576                                                          FX_BOOL bPromptCJK) {
577   if (!m_CID2UnicodeMaps[charset])
578     m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK);
579   return m_CID2UnicodeMaps[charset];
580 }
LoadCID2UnicodeMap(CIDSet charset,FX_BOOL bPromptCJK)581 CPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(CIDSet charset,
582                                                           FX_BOOL bPromptCJK) {
583   CPDF_CID2UnicodeMap* pMap = new CPDF_CID2UnicodeMap();
584   if (!pMap->Initialize()) {
585     delete pMap;
586     return NULL;
587   }
588   pMap->Load(this, charset, bPromptCJK);
589   return pMap;
590 }
CPDF_CMapParser()591 CPDF_CMapParser::CPDF_CMapParser() {
592   m_pCMap = NULL;
593   m_Status = 0;
594   m_CodeSeq = 0;
595 }
Initialize(CPDF_CMap * pCMap)596 FX_BOOL CPDF_CMapParser::Initialize(CPDF_CMap* pCMap) {
597   m_pCMap = pCMap;
598   m_Status = 0;
599   m_CodeSeq = 0;
600   m_AddMaps.EstimateSize(0, 10240);
601   return TRUE;
602 }
603 
ParseWord(const CFX_ByteStringC & word)604 void CPDF_CMapParser::ParseWord(const CFX_ByteStringC& word) {
605   if (word.IsEmpty()) {
606     return;
607   }
608   if (word == "begincidchar") {
609     m_Status = 1;
610     m_CodeSeq = 0;
611   } else if (word == "begincidrange") {
612     m_Status = 2;
613     m_CodeSeq = 0;
614   } else if (word == "endcidrange" || word == "endcidchar") {
615     m_Status = 0;
616   } else if (word == "/WMode") {
617     m_Status = 6;
618   } else if (word == "/Registry") {
619     m_Status = 3;
620   } else if (word == "/Ordering") {
621     m_Status = 4;
622   } else if (word == "/Supplement") {
623     m_Status = 5;
624   } else if (word == "begincodespacerange") {
625     m_Status = 7;
626     m_CodeSeq = 0;
627   } else if (word == "usecmap") {
628   } else if (m_Status == 1 || m_Status == 2) {
629     m_CodePoints[m_CodeSeq] = CMap_GetCode(word);
630     m_CodeSeq++;
631     FX_DWORD StartCode, EndCode;
632     FX_WORD StartCID;
633     if (m_Status == 1) {
634       if (m_CodeSeq < 2) {
635         return;
636       }
637       EndCode = StartCode = m_CodePoints[0];
638       StartCID = (FX_WORD)m_CodePoints[1];
639     } else {
640       if (m_CodeSeq < 3) {
641         return;
642       }
643       StartCode = m_CodePoints[0];
644       EndCode = m_CodePoints[1];
645       StartCID = (FX_WORD)m_CodePoints[2];
646     }
647     if (EndCode < 0x10000) {
648       for (FX_DWORD code = StartCode; code <= EndCode; code++) {
649         m_pCMap->m_pMapping[code] = (FX_WORD)(StartCID + code - StartCode);
650       }
651     } else {
652       FX_DWORD buf[2];
653       buf[0] = StartCode;
654       buf[1] = ((EndCode - StartCode) << 16) + StartCID;
655       m_AddMaps.AppendBlock(buf, sizeof buf);
656     }
657     m_CodeSeq = 0;
658   } else if (m_Status == 3) {
659     CMap_GetString(word);
660     m_Status = 0;
661   } else if (m_Status == 4) {
662     m_pCMap->m_Charset = CharsetFromOrdering(CMap_GetString(word));
663     m_Status = 0;
664   } else if (m_Status == 5) {
665     CMap_GetCode(word);
666     m_Status = 0;
667   } else if (m_Status == 6) {
668     m_pCMap->m_bVertical = CMap_GetCode(word);
669     m_Status = 0;
670   } else if (m_Status == 7) {
671     if (word == "endcodespacerange") {
672       int nSegs = m_CodeRanges.GetSize();
673       if (nSegs > 1) {
674         m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes;
675         m_pCMap->m_nCodeRanges = nSegs;
676         m_pCMap->m_pLeadingBytes =
677             FX_Alloc2D(uint8_t, nSegs, sizeof(CMap_CodeRange));
678         FXSYS_memcpy(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(),
679                      nSegs * sizeof(CMap_CodeRange));
680       } else if (nSegs == 1) {
681         m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2)
682                                       ? CPDF_CMap::TwoBytes
683                                       : CPDF_CMap::OneByte;
684       }
685       m_Status = 0;
686     } else {
687       if (word.GetLength() == 0 || word.GetAt(0) != '<') {
688         return;
689       }
690       if (m_CodeSeq % 2) {
691         CMap_CodeRange range;
692         if (CMap_GetCodeRange(range, m_LastWord, word)) {
693           m_CodeRanges.Add(range);
694         }
695       }
696       m_CodeSeq++;
697     }
698   }
699   m_LastWord = word;
700 }
701 
702 // Static.
CMap_GetCode(const CFX_ByteStringC & word)703 FX_DWORD CPDF_CMapParser::CMap_GetCode(const CFX_ByteStringC& word) {
704   int num = 0;
705   if (word.GetAt(0) == '<') {
706     for (int i = 1; i < word.GetLength() && std::isxdigit(word.GetAt(i)); ++i)
707       num = num * 16 + FXSYS_toHexDigit(word.GetAt(i));
708     return num;
709   }
710 
711   for (int i = 0; i < word.GetLength() && std::isdigit(word.GetAt(i)); ++i)
712     num = num * 10 + FXSYS_toDecimalDigit(word.GetAt(i));
713   return num;
714 }
715 
716 // Static.
CMap_GetCodeRange(CMap_CodeRange & range,const CFX_ByteStringC & first,const CFX_ByteStringC & second)717 bool CPDF_CMapParser::CMap_GetCodeRange(CMap_CodeRange& range,
718                                         const CFX_ByteStringC& first,
719                                         const CFX_ByteStringC& second) {
720   if (first.GetLength() == 0 || first.GetAt(0) != '<')
721     return false;
722 
723   int i;
724   for (i = 1; i < first.GetLength(); ++i) {
725     if (first.GetAt(i) == '>') {
726       break;
727     }
728   }
729   range.m_CharSize = (i - 1) / 2;
730   if (range.m_CharSize > 4)
731     return false;
732 
733   for (i = 0; i < range.m_CharSize; ++i) {
734     uint8_t digit1 = first.GetAt(i * 2 + 1);
735     uint8_t digit2 = first.GetAt(i * 2 + 2);
736     range.m_Lower[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2);
737   }
738 
739   FX_DWORD size = second.GetLength();
740   for (i = 0; i < range.m_CharSize; ++i) {
741     uint8_t digit1 = ((FX_DWORD)i * 2 + 1 < size)
742                          ? second.GetAt((FX_STRSIZE)i * 2 + 1)
743                          : '0';
744     uint8_t digit2 = ((FX_DWORD)i * 2 + 2 < size)
745                          ? second.GetAt((FX_STRSIZE)i * 2 + 2)
746                          : '0';
747     range.m_Upper[i] = FXSYS_toHexDigit(digit1) * 16 + FXSYS_toHexDigit(digit2);
748   }
749   return true;
750 }
751 
CPDF_CMap()752 CPDF_CMap::CPDF_CMap() {
753   m_Charset = CIDSET_UNKNOWN;
754   m_Coding = CIDCODING_UNKNOWN;
755   m_CodingScheme = TwoBytes;
756   m_bVertical = 0;
757   m_bLoaded = FALSE;
758   m_pMapping = NULL;
759   m_pLeadingBytes = NULL;
760   m_pAddMapping = NULL;
761   m_pEmbedMap = NULL;
762   m_pUseMap = NULL;
763   m_nCodeRanges = 0;
764 }
~CPDF_CMap()765 CPDF_CMap::~CPDF_CMap() {
766   FX_Free(m_pMapping);
767   FX_Free(m_pAddMapping);
768   FX_Free(m_pLeadingBytes);
769   delete m_pUseMap;
770 }
Release()771 void CPDF_CMap::Release() {
772   if (m_PredefinedCMap.IsEmpty()) {
773     delete this;
774   }
775 }
776 
LoadPredefined(CPDF_CMapManager * pMgr,const FX_CHAR * pName,FX_BOOL bPromptCJK)777 FX_BOOL CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr,
778                                   const FX_CHAR* pName,
779                                   FX_BOOL bPromptCJK) {
780   m_PredefinedCMap = pName;
781   if (m_PredefinedCMap == "Identity-H" || m_PredefinedCMap == "Identity-V") {
782     m_Coding = CIDCODING_CID;
783     m_bVertical = pName[9] == 'V';
784     m_bLoaded = TRUE;
785     return TRUE;
786   }
787   CFX_ByteString cmapid = m_PredefinedCMap;
788   m_bVertical = cmapid.Right(1) == "V";
789   if (cmapid.GetLength() > 2) {
790     cmapid = cmapid.Left(cmapid.GetLength() - 2);
791   }
792   const CPDF_PredefinedCMap* map = nullptr;
793   for (size_t i = 0; i < FX_ArraySize(g_PredefinedCMaps); ++i) {
794     if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[i].m_pName)) {
795       map = &g_PredefinedCMaps[i];
796       break;
797     }
798   }
799   if (!map)
800     return FALSE;
801 
802   m_Charset = map->m_Charset;
803   m_Coding = map->m_Coding;
804   m_CodingScheme = map->m_CodingScheme;
805   if (m_CodingScheme == MixedTwoBytes) {
806     m_pLeadingBytes = FX_Alloc(uint8_t, 256);
807     for (FX_DWORD i = 0; i < map->m_LeadingSegCount; ++i) {
808       const uint8_t* segs = map->m_LeadingSegs;
809       for (int b = segs[i * 2]; b <= segs[i * 2 + 1]; ++b) {
810         m_pLeadingBytes[b] = 1;
811       }
812     }
813   }
814   FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap);
815   if (m_pEmbedMap) {
816     m_bLoaded = TRUE;
817     return TRUE;
818   }
819   return FALSE;
820 }
LoadEmbedded(const uint8_t * pData,FX_DWORD size)821 FX_BOOL CPDF_CMap::LoadEmbedded(const uint8_t* pData, FX_DWORD size) {
822   m_pMapping = FX_Alloc(FX_WORD, 65536);
823   CPDF_CMapParser parser;
824   parser.Initialize(this);
825   CPDF_SimpleParser syntax(pData, size);
826   while (1) {
827     CFX_ByteStringC word = syntax.GetWord();
828     if (word.IsEmpty()) {
829       break;
830     }
831     parser.ParseWord(word);
832   }
833   if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) {
834     m_pAddMapping = FX_Alloc(uint8_t, parser.m_AddMaps.GetSize() + 4);
835     *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8;
836     FXSYS_memcpy(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(),
837                  parser.m_AddMaps.GetSize());
838     FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8,
839                 CompareDWORD);
840   }
841   return TRUE;
842 }
843 
CIDFromCharCode(FX_DWORD charcode) const844 FX_WORD CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const {
845   if (m_Coding == CIDCODING_CID) {
846     return (FX_WORD)charcode;
847   }
848   if (m_pEmbedMap) {
849     return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode);
850   }
851   if (!m_pMapping) {
852     return (FX_WORD)charcode;
853   }
854   if (charcode >> 16) {
855     if (m_pAddMapping) {
856       void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4,
857                                   *(FX_DWORD*)m_pAddMapping, 8, CompareCID);
858       if (!found) {
859         if (m_pUseMap) {
860           return m_pUseMap->CIDFromCharCode(charcode);
861         }
862         return 0;
863       }
864       return (FX_WORD)(((FX_DWORD*)found)[1] % 65536 + charcode -
865                        *(FX_DWORD*)found);
866     }
867     if (m_pUseMap)
868       return m_pUseMap->CIDFromCharCode(charcode);
869     return 0;
870   }
871   FX_DWORD CID = m_pMapping[charcode];
872   if (!CID && m_pUseMap)
873     return m_pUseMap->CIDFromCharCode(charcode);
874   return (FX_WORD)CID;
875 }
876 
GetNextChar(const FX_CHAR * pString,int nStrLen,int & offset) const877 FX_DWORD CPDF_CMap::GetNextChar(const FX_CHAR* pString,
878                                 int nStrLen,
879                                 int& offset) const {
880   switch (m_CodingScheme) {
881     case OneByte:
882       return ((uint8_t*)pString)[offset++];
883     case TwoBytes:
884       offset += 2;
885       return ((uint8_t*)pString)[offset - 2] * 256 +
886              ((uint8_t*)pString)[offset - 1];
887     case MixedTwoBytes: {
888       uint8_t byte1 = ((uint8_t*)pString)[offset++];
889       if (!m_pLeadingBytes[byte1]) {
890         return byte1;
891       }
892       uint8_t byte2 = ((uint8_t*)pString)[offset++];
893       return byte1 * 256 + byte2;
894     }
895     case MixedFourBytes: {
896       uint8_t codes[4];
897       int char_size = 1;
898       codes[0] = ((uint8_t*)pString)[offset++];
899       CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes;
900       while (1) {
901         int ret = CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges);
902         if (ret == 0) {
903           return 0;
904         }
905         if (ret == 2) {
906           FX_DWORD charcode = 0;
907           for (int i = 0; i < char_size; i++) {
908             charcode = (charcode << 8) + codes[i];
909           }
910           return charcode;
911         }
912         if (char_size == 4 || offset == nStrLen) {
913           return 0;
914         }
915         codes[char_size++] = ((uint8_t*)pString)[offset++];
916       }
917       break;
918     }
919   }
920   return 0;
921 }
GetCharSize(FX_DWORD charcode) const922 int CPDF_CMap::GetCharSize(FX_DWORD charcode) const {
923   switch (m_CodingScheme) {
924     case OneByte:
925       return 1;
926     case TwoBytes:
927       return 2;
928     case MixedTwoBytes:
929     case MixedFourBytes:
930       if (charcode < 0x100) {
931         return 1;
932       }
933       if (charcode < 0x10000) {
934         return 2;
935       }
936       if (charcode < 0x1000000) {
937         return 3;
938       }
939       return 4;
940   }
941   return 1;
942 }
CountChar(const FX_CHAR * pString,int size) const943 int CPDF_CMap::CountChar(const FX_CHAR* pString, int size) const {
944   switch (m_CodingScheme) {
945     case OneByte:
946       return size;
947     case TwoBytes:
948       return (size + 1) / 2;
949     case MixedTwoBytes: {
950       int count = 0;
951       for (int i = 0; i < size; i++) {
952         count++;
953         if (m_pLeadingBytes[((uint8_t*)pString)[i]]) {
954           i++;
955         }
956       }
957       return count;
958     }
959     case MixedFourBytes: {
960       int count = 0, offset = 0;
961       while (offset < size) {
962         GetNextChar(pString, size, offset);
963         count++;
964       }
965       return count;
966     }
967   }
968   return size;
969 }
970 
AppendChar(FX_CHAR * str,FX_DWORD charcode) const971 int CPDF_CMap::AppendChar(FX_CHAR* str, FX_DWORD charcode) const {
972   switch (m_CodingScheme) {
973     case OneByte:
974       str[0] = (uint8_t)charcode;
975       return 1;
976     case TwoBytes:
977       str[0] = (uint8_t)(charcode / 256);
978       str[1] = (uint8_t)(charcode % 256);
979       return 2;
980     case MixedTwoBytes:
981     case MixedFourBytes:
982       if (charcode < 0x100) {
983         CMap_CodeRange* pRanges = (CMap_CodeRange*)m_pLeadingBytes;
984         int iSize = GetCharSizeImpl(charcode, pRanges, m_nCodeRanges);
985         if (iSize == 0) {
986           iSize = 1;
987         }
988         if (iSize > 1) {
989           FXSYS_memset(str, 0, sizeof(uint8_t) * iSize);
990         }
991         str[iSize - 1] = (uint8_t)charcode;
992         return iSize;
993       }
994       if (charcode < 0x10000) {
995         str[0] = (uint8_t)(charcode >> 8);
996         str[1] = (uint8_t)charcode;
997         return 2;
998       }
999       if (charcode < 0x1000000) {
1000         str[0] = (uint8_t)(charcode >> 16);
1001         str[1] = (uint8_t)(charcode >> 8);
1002         str[2] = (uint8_t)charcode;
1003         return 3;
1004       }
1005       str[0] = (uint8_t)(charcode >> 24);
1006       str[1] = (uint8_t)(charcode >> 16);
1007       str[2] = (uint8_t)(charcode >> 8);
1008       str[3] = (uint8_t)charcode;
1009       return 4;
1010   }
1011   return 0;
1012 }
CPDF_CID2UnicodeMap()1013 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() {
1014   m_EmbeddedCount = 0;
1015 }
~CPDF_CID2UnicodeMap()1016 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {}
Initialize()1017 FX_BOOL CPDF_CID2UnicodeMap::Initialize() {
1018   return TRUE;
1019 }
IsLoaded()1020 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() {
1021   return m_EmbeddedCount != 0;
1022 }
UnicodeFromCID(FX_WORD CID)1023 FX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(FX_WORD CID) {
1024   if (m_Charset == CIDSET_UNICODE) {
1025     return CID;
1026   }
1027   if (CID < m_EmbeddedCount) {
1028     return m_pEmbeddedMap[CID];
1029   }
1030   return 0;
1031 }
1032 
Load(CPDF_CMapManager * pMgr,CIDSet charset,FX_BOOL bPromptCJK)1033 void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr,
1034                                CIDSet charset,
1035                                FX_BOOL bPromptCJK) {
1036   m_Charset = charset;
1037   FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount);
1038 }
1039 
1040 #include "ttgsubtable.h"
CPDF_CIDFont()1041 CPDF_CIDFont::CPDF_CIDFont() : CPDF_Font(PDFFONT_CIDFONT) {
1042   m_pCMap = NULL;
1043   m_pAllocatedCMap = NULL;
1044   m_pCID2UnicodeMap = NULL;
1045   m_pAnsiWidths = NULL;
1046   m_pCIDToGIDMap = NULL;
1047   m_bCIDIsGID = FALSE;
1048   m_bAdobeCourierStd = FALSE;
1049   m_pTTGSUBTable = NULL;
1050   FXSYS_memset(m_CharBBox, 0xff, 256 * sizeof(FX_SMALL_RECT));
1051 }
~CPDF_CIDFont()1052 CPDF_CIDFont::~CPDF_CIDFont() {
1053   if (m_pAnsiWidths) {
1054     FX_Free(m_pAnsiWidths);
1055   }
1056   delete m_pAllocatedCMap;
1057   delete m_pCIDToGIDMap;
1058   delete m_pTTGSUBTable;
1059 }
CIDFromCharCode(FX_DWORD charcode) const1060 FX_WORD CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const {
1061   if (!m_pCMap) {
1062     return (FX_WORD)charcode;
1063   }
1064   return m_pCMap->CIDFromCharCode(charcode);
1065 }
IsVertWriting() const1066 FX_BOOL CPDF_CIDFont::IsVertWriting() const {
1067   return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
1068 }
1069 
_UnicodeFromCharCode(FX_DWORD charcode) const1070 FX_WCHAR CPDF_CIDFont::_UnicodeFromCharCode(FX_DWORD charcode) const {
1071   switch (m_pCMap->m_Coding) {
1072     case CIDCODING_UCS2:
1073     case CIDCODING_UTF16:
1074       return (FX_WCHAR)charcode;
1075     case CIDCODING_CID:
1076       if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
1077         return 0;
1078       }
1079       return m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)charcode);
1080   }
1081   if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
1082       !m_pCID2UnicodeMap->IsLoaded()) {
1083 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
1084     FX_WCHAR unicode;
1085     int charsize = 1;
1086     if (charcode > 255) {
1087       charcode = (charcode % 256) * 256 + (charcode / 256);
1088       charsize = 2;
1089     }
1090     int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->m_Coding], 0,
1091                                         (const FX_CHAR*)&charcode, charsize,
1092                                         &unicode, 1);
1093     if (ret != 1) {
1094       return 0;
1095     }
1096     return unicode;
1097 #endif
1098     if (m_pCMap->m_pEmbedMap) {
1099       return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap,
1100                                          m_pCMap->m_Charset, charcode);
1101     }
1102     return 0;
1103   }
1104   return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
1105 }
_CharCodeFromUnicode(FX_WCHAR unicode) const1106 FX_DWORD CPDF_CIDFont::_CharCodeFromUnicode(FX_WCHAR unicode) const {
1107   switch (m_pCMap->m_Coding) {
1108     case CIDCODING_UNKNOWN:
1109       return 0;
1110     case CIDCODING_UCS2:
1111     case CIDCODING_UTF16:
1112       return unicode;
1113     case CIDCODING_CID: {
1114       if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
1115         return 0;
1116       }
1117       FX_DWORD CID = 0;
1118       while (CID < 65536) {
1119         FX_WCHAR this_unicode = m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)CID);
1120         if (this_unicode == unicode) {
1121           return CID;
1122         }
1123         CID++;
1124       }
1125       break;
1126     }
1127   }
1128 
1129   if (unicode < 0x80) {
1130     return static_cast<FX_DWORD>(unicode);
1131   }
1132   if (m_pCMap->m_Coding == CIDCODING_CID) {
1133     return 0;
1134   }
1135 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
1136   uint8_t buffer[32];
1137   int ret =
1138       FXSYS_WideCharToMultiByte(g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1,
1139                                 (char*)buffer, 4, NULL, NULL);
1140   if (ret == 1) {
1141     return buffer[0];
1142   }
1143   if (ret == 2) {
1144     return buffer[0] * 256 + buffer[1];
1145   }
1146 #else
1147   if (m_pCMap->m_pEmbedMap) {
1148     return EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset,
1149                                        unicode);
1150   }
1151 #endif
1152   return 0;
1153 }
1154 
_Load()1155 FX_BOOL CPDF_CIDFont::_Load() {
1156   if (m_pFontDict->GetString("Subtype") == "TrueType") {
1157     return LoadGB2312();
1158   }
1159   CPDF_Array* pFonts = m_pFontDict->GetArray("DescendantFonts");
1160   if (!pFonts) {
1161     return FALSE;
1162   }
1163   if (pFonts->GetCount() != 1) {
1164     return FALSE;
1165   }
1166   CPDF_Dictionary* pCIDFontDict = pFonts->GetDict(0);
1167   if (!pCIDFontDict) {
1168     return FALSE;
1169   }
1170   m_BaseFont = pCIDFontDict->GetString("BaseFont");
1171   if ((m_BaseFont.Compare("CourierStd") == 0 ||
1172        m_BaseFont.Compare("CourierStd-Bold") == 0 ||
1173        m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
1174        m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
1175       !IsEmbedded()) {
1176     m_bAdobeCourierStd = TRUE;
1177   }
1178   CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDict("FontDescriptor");
1179   if (pFontDesc) {
1180     LoadFontDescriptor(pFontDesc);
1181   }
1182   CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
1183   if (!pEncoding) {
1184     return FALSE;
1185   }
1186   CFX_ByteString subtype = pCIDFontDict->GetString("Subtype");
1187   m_bType1 = (subtype == "CIDFontType0");
1188 
1189   if (pEncoding->IsName()) {
1190     CFX_ByteString cmap = pEncoding->GetString();
1191     m_pCMap =
1192         CPDF_ModuleMgr::Get()
1193             ->GetPageModule()
1194             ->GetFontGlobals()
1195             ->m_CMapManager.GetPredefinedCMap(cmap, m_pFontFile && m_bType1);
1196   } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
1197     m_pAllocatedCMap = m_pCMap = new CPDF_CMap;
1198     CPDF_StreamAcc acc;
1199     acc.LoadAllData(pStream, FALSE);
1200     m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
1201   } else {
1202     return FALSE;
1203   }
1204   if (!m_pCMap) {
1205     return FALSE;
1206   }
1207   m_Charset = m_pCMap->m_Charset;
1208   if (m_Charset == CIDSET_UNKNOWN) {
1209     CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDict("CIDSystemInfo");
1210     if (pCIDInfo) {
1211       m_Charset = CharsetFromOrdering(pCIDInfo->GetString("Ordering"));
1212     }
1213   }
1214   if (m_Charset != CIDSET_UNKNOWN)
1215     m_pCID2UnicodeMap =
1216         CPDF_ModuleMgr::Get()
1217             ->GetPageModule()
1218             ->GetFontGlobals()
1219             ->m_CMapManager.GetCID2UnicodeMap(
1220                 m_Charset,
1221                 !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID ||
1222                                  pCIDFontDict->KeyExist("W")));
1223   if (m_Font.GetFace()) {
1224     if (m_bType1) {
1225       FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
1226     } else {
1227       FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding);
1228     }
1229   }
1230   m_DefaultWidth = pCIDFontDict->GetInteger("DW", 1000);
1231   CPDF_Array* pWidthArray = pCIDFontDict->GetArray("W");
1232   if (pWidthArray) {
1233     LoadMetricsArray(pWidthArray, m_WidthList, 1);
1234   }
1235   if (!IsEmbedded()) {
1236     LoadSubstFont();
1237   }
1238   if (1) {
1239     if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
1240       CPDF_Object* pmap = pCIDFontDict->GetElementValue("CIDToGIDMap");
1241       if (pmap) {
1242         if (CPDF_Stream* pStream = pmap->AsStream()) {
1243           m_pCIDToGIDMap = new CPDF_StreamAcc;
1244           m_pCIDToGIDMap->LoadAllData(pStream, FALSE);
1245         } else if (pmap->GetString() == "Identity") {
1246 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1247           if (m_pFontFile) {
1248             m_bCIDIsGID = TRUE;
1249           }
1250 #else
1251           m_bCIDIsGID = TRUE;
1252 #endif
1253         }
1254       }
1255     }
1256   }
1257   CheckFontMetrics();
1258   if (IsVertWriting()) {
1259     pWidthArray = pCIDFontDict->GetArray("W2");
1260     if (pWidthArray) {
1261       LoadMetricsArray(pWidthArray, m_VertMetrics, 3);
1262     }
1263     CPDF_Array* pDefaultArray = pCIDFontDict->GetArray("DW2");
1264     if (pDefaultArray) {
1265       m_DefaultVY = pDefaultArray->GetInteger(0);
1266       m_DefaultW1 = pDefaultArray->GetInteger(1);
1267     } else {
1268       m_DefaultVY = 880;
1269       m_DefaultW1 = -1000;
1270     }
1271   }
1272   return TRUE;
1273 }
1274 
GetCharBBox(FX_DWORD charcode,FX_RECT & rect,int level)1275 void CPDF_CIDFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) {
1276   if (charcode < 256 && m_CharBBox[charcode].Right != -1) {
1277     rect.bottom = m_CharBBox[charcode].Bottom;
1278     rect.left = m_CharBBox[charcode].Left;
1279     rect.right = m_CharBBox[charcode].Right;
1280     rect.top = m_CharBBox[charcode].Top;
1281     return;
1282   }
1283   FX_BOOL bVert = FALSE;
1284   int glyph_index = GlyphFromCharCode(charcode, &bVert);
1285   FXFT_Face face = m_Font.GetFace();
1286   if (face) {
1287     rect.left = rect.bottom = rect.right = rect.top = 0;
1288     if (FXFT_Is_Face_Tricky(face)) {
1289       int err = FXFT_Load_Glyph(face, glyph_index,
1290                                 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1291       if (!err) {
1292         FXFT_BBox cbox;
1293         FXFT_Glyph glyph;
1294         err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph);
1295         if (!err) {
1296           FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
1297           int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem;
1298           int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem;
1299           if (pixel_size_x == 0 || pixel_size_y == 0) {
1300             rect.left = cbox.xMin;
1301             rect.right = cbox.xMax;
1302             rect.top = cbox.yMax;
1303             rect.bottom = cbox.yMin;
1304           } else {
1305             rect.left = cbox.xMin * 1000 / pixel_size_x;
1306             rect.right = cbox.xMax * 1000 / pixel_size_x;
1307             rect.top = cbox.yMax * 1000 / pixel_size_y;
1308             rect.bottom = cbox.yMin * 1000 / pixel_size_y;
1309           }
1310           if (rect.top > FXFT_Get_Face_Ascender(face)) {
1311             rect.top = FXFT_Get_Face_Ascender(face);
1312           }
1313           if (rect.bottom < FXFT_Get_Face_Descender(face)) {
1314             rect.bottom = FXFT_Get_Face_Descender(face);
1315           }
1316           FXFT_Done_Glyph(glyph);
1317         }
1318       }
1319     } else {
1320       int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE);
1321       if (err == 0) {
1322         rect.left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face);
1323         rect.right = TT2PDF(
1324             FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face),
1325             face);
1326         rect.top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face);
1327         rect.top += rect.top / 64;
1328         rect.bottom = TT2PDF(
1329             FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face),
1330             face);
1331       }
1332     }
1333   } else {
1334     rect = FX_RECT(0, 0, 0, 0);
1335   }
1336   if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) {
1337     FX_WORD CID = CIDFromCharCode(charcode);
1338     const uint8_t* pTransform = GetCIDTransform(CID);
1339     if (pTransform && !bVert) {
1340       CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]),
1341                         CIDTransformToFloat(pTransform[1]),
1342                         CIDTransformToFloat(pTransform[2]),
1343                         CIDTransformToFloat(pTransform[3]),
1344                         CIDTransformToFloat(pTransform[4]) * 1000,
1345                         CIDTransformToFloat(pTransform[5]) * 1000);
1346       CFX_FloatRect rect_f(rect);
1347       rect_f.Transform(&matrix);
1348       rect = rect_f.GetOutterRect();
1349     }
1350   }
1351   if (charcode < 256) {
1352     m_CharBBox[charcode].Bottom = (short)rect.bottom;
1353     m_CharBBox[charcode].Left = (short)rect.left;
1354     m_CharBBox[charcode].Right = (short)rect.right;
1355     m_CharBBox[charcode].Top = (short)rect.top;
1356   }
1357 }
GetCharWidthF(FX_DWORD charcode,int level)1358 int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) {
1359   if (m_pAnsiWidths && charcode < 0x80) {
1360     return m_pAnsiWidths[charcode];
1361   }
1362   FX_WORD cid = CIDFromCharCode(charcode);
1363   int size = m_WidthList.GetSize();
1364   FX_DWORD* list = m_WidthList.GetData();
1365   for (int i = 0; i < size; i += 3) {
1366     if (cid >= list[i] && cid <= list[i + 1]) {
1367       return (int)list[i + 2];
1368     }
1369   }
1370   return m_DefaultWidth;
1371 }
GetVertWidth(FX_WORD CID) const1372 short CPDF_CIDFont::GetVertWidth(FX_WORD CID) const {
1373   FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
1374   if (vertsize == 0) {
1375     return m_DefaultW1;
1376   }
1377   const FX_DWORD* pTable = m_VertMetrics.GetData();
1378   for (FX_DWORD i = 0; i < vertsize; i++)
1379     if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
1380       return (short)(int)pTable[i * 5 + 2];
1381     }
1382   return m_DefaultW1;
1383 }
GetVertOrigin(FX_WORD CID,short & vx,short & vy) const1384 void CPDF_CIDFont::GetVertOrigin(FX_WORD CID, short& vx, short& vy) const {
1385   FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
1386   if (vertsize) {
1387     const FX_DWORD* pTable = m_VertMetrics.GetData();
1388     for (FX_DWORD i = 0; i < vertsize; i++)
1389       if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
1390         vx = (short)(int)pTable[i * 5 + 3];
1391         vy = (short)(int)pTable[i * 5 + 4];
1392         return;
1393       }
1394   }
1395   FX_DWORD dwWidth = m_DefaultWidth;
1396   int size = m_WidthList.GetSize();
1397   const FX_DWORD* list = m_WidthList.GetData();
1398   for (int i = 0; i < size; i += 3) {
1399     if (CID >= list[i] && CID <= list[i + 1]) {
1400       dwWidth = (FX_WORD)list[i + 2];
1401       break;
1402     }
1403   }
1404   vx = (short)dwWidth / 2;
1405   vy = (short)m_DefaultVY;
1406 }
GetGlyphIndex(FX_DWORD unicode,FX_BOOL * pVertGlyph)1407 int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL* pVertGlyph) {
1408   if (pVertGlyph) {
1409     *pVertGlyph = FALSE;
1410   }
1411   FXFT_Face face = m_Font.GetFace();
1412   int index = FXFT_Get_Char_Index(face, unicode);
1413   if (unicode == 0x2502) {
1414     return index;
1415   }
1416   if (index && IsVertWriting()) {
1417     if (m_pTTGSUBTable) {
1418       uint32_t vindex = 0;
1419       m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
1420       if (vindex) {
1421         index = vindex;
1422         if (pVertGlyph) {
1423           *pVertGlyph = TRUE;
1424         }
1425       }
1426       return index;
1427     }
1428     if (!m_Font.GetSubData()) {
1429       unsigned long length = 0;
1430       int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
1431                                        NULL, &length);
1432       if (!error) {
1433         m_Font.SetSubData(FX_Alloc(uint8_t, length));
1434       }
1435     }
1436     int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
1437                                      m_Font.GetSubData(), NULL);
1438     if (!error && m_Font.GetSubData()) {
1439       m_pTTGSUBTable = new CFX_CTTGSUBTable;
1440       m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
1441       uint32_t vindex = 0;
1442       m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
1443       if (vindex) {
1444         index = vindex;
1445         if (pVertGlyph) {
1446           *pVertGlyph = TRUE;
1447         }
1448       }
1449     }
1450     return index;
1451   }
1452   if (pVertGlyph) {
1453     *pVertGlyph = FALSE;
1454   }
1455   return index;
1456 }
GlyphFromCharCode(FX_DWORD charcode,FX_BOOL * pVertGlyph)1457 int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
1458   if (pVertGlyph) {
1459     *pVertGlyph = FALSE;
1460   }
1461   if (!m_pFontFile && !m_pCIDToGIDMap) {
1462     FX_WORD cid = CIDFromCharCode(charcode);
1463     FX_WCHAR unicode = 0;
1464     if (m_bCIDIsGID) {
1465 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1466       return cid;
1467 #else
1468       if (m_Flags & PDFFONT_SYMBOLIC) {
1469         return cid;
1470       }
1471       CFX_WideString uni_str = UnicodeFromCharCode(charcode);
1472       if (uni_str.IsEmpty()) {
1473         return cid;
1474       }
1475       unicode = uni_str.GetAt(0);
1476 #endif
1477     } else {
1478       if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) {
1479         unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid);
1480       }
1481       if (unicode == 0) {
1482         unicode = _UnicodeFromCharCode(charcode);
1483       }
1484       if (unicode == 0 && !(m_Flags & PDFFONT_SYMBOLIC)) {
1485         unicode = UnicodeFromCharCode(charcode).GetAt(0);
1486       }
1487     }
1488     FXFT_Face face = m_Font.GetFace();
1489     if (unicode == 0) {
1490       if (!m_bAdobeCourierStd) {
1491         return charcode == 0 ? -1 : (int)charcode;
1492       }
1493       charcode += 31;
1494       int index = 0, iBaseEncoding;
1495       FX_BOOL bMSUnicode = FT_UseTTCharmap(face, 3, 1);
1496       FX_BOOL bMacRoman = FALSE;
1497       if (!bMSUnicode) {
1498         bMacRoman = FT_UseTTCharmap(face, 1, 0);
1499       }
1500       iBaseEncoding = PDFFONT_ENCODING_STANDARD;
1501       if (bMSUnicode) {
1502         iBaseEncoding = PDFFONT_ENCODING_WINANSI;
1503       } else if (bMacRoman) {
1504         iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
1505       }
1506       const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode);
1507       if (!name) {
1508         return charcode == 0 ? -1 : (int)charcode;
1509       }
1510       FX_WORD unicode = PDF_UnicodeFromAdobeName(name);
1511       if (unicode) {
1512         if (bMSUnicode) {
1513           index = FXFT_Get_Char_Index(face, unicode);
1514         } else if (bMacRoman) {
1515           FX_DWORD maccode =
1516               FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode);
1517           index = !maccode ? FXFT_Get_Name_Index(face, (char*)name)
1518                            : FXFT_Get_Char_Index(face, maccode);
1519         } else {
1520           return FXFT_Get_Char_Index(face, unicode);
1521         }
1522       } else {
1523         return charcode == 0 ? -1 : (int)charcode;
1524       }
1525       if (index == 0 || index == 0xffff) {
1526         return charcode == 0 ? -1 : (int)charcode;
1527       }
1528       return index;
1529     }
1530     if (m_Charset == CIDSET_JAPAN1) {
1531       if (unicode == '\\') {
1532         unicode = '/';
1533       }
1534 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1535       else if (unicode == 0xa5) {
1536         unicode = 0x5c;
1537       }
1538 #endif
1539     }
1540     if (!face)
1541       return unicode;
1542 
1543     int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
1544     if (err != 0) {
1545       int i;
1546       for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
1547         FX_DWORD ret = FT_CharCodeFromUnicode(
1548             FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
1549             (FX_WCHAR)charcode);
1550         if (ret == 0) {
1551           continue;
1552         }
1553         FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
1554         unicode = (FX_WCHAR)ret;
1555         break;
1556       }
1557       if (i == FXFT_Get_Face_CharmapCount(face) && i) {
1558         FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
1559         unicode = (FX_WCHAR)charcode;
1560       }
1561     }
1562     if (FXFT_Get_Face_Charmap(face)) {
1563       int index = GetGlyphIndex(unicode, pVertGlyph);
1564       if (index == 0)
1565         return -1;
1566       return index;
1567     }
1568     return unicode;
1569   }
1570   if (!m_Font.GetFace())
1571     return -1;
1572 
1573   FX_WORD cid = CIDFromCharCode(charcode);
1574   if (m_bType1) {
1575     if (!m_pCIDToGIDMap) {
1576       return cid;
1577     }
1578   } else {
1579     if (!m_pCIDToGIDMap) {
1580       if (m_pFontFile && !m_pCMap->m_pMapping)
1581         return cid;
1582       if (m_pCMap->m_Coding == CIDCODING_UNKNOWN ||
1583           !FXFT_Get_Face_Charmap(m_Font.GetFace())) {
1584         return cid;
1585       }
1586       if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) ==
1587           FXFT_ENCODING_UNICODE) {
1588         CFX_WideString unicode_str = UnicodeFromCharCode(charcode);
1589         if (unicode_str.IsEmpty()) {
1590           return -1;
1591         }
1592         charcode = unicode_str.GetAt(0);
1593       }
1594       return GetGlyphIndex(charcode, pVertGlyph);
1595     }
1596   }
1597   FX_DWORD byte_pos = cid * 2;
1598   if (byte_pos + 2 > m_pCIDToGIDMap->GetSize())
1599     return -1;
1600 
1601   const uint8_t* pdata = m_pCIDToGIDMap->GetData() + byte_pos;
1602   return pdata[0] * 256 + pdata[1];
1603 }
GetNextChar(const FX_CHAR * pString,int nStrLen,int & offset) const1604 FX_DWORD CPDF_CIDFont::GetNextChar(const FX_CHAR* pString,
1605                                    int nStrLen,
1606                                    int& offset) const {
1607   return m_pCMap->GetNextChar(pString, nStrLen, offset);
1608 }
GetCharSize(FX_DWORD charcode) const1609 int CPDF_CIDFont::GetCharSize(FX_DWORD charcode) const {
1610   return m_pCMap->GetCharSize(charcode);
1611 }
CountChar(const FX_CHAR * pString,int size) const1612 int CPDF_CIDFont::CountChar(const FX_CHAR* pString, int size) const {
1613   return m_pCMap->CountChar(pString, size);
1614 }
AppendChar(FX_CHAR * str,FX_DWORD charcode) const1615 int CPDF_CIDFont::AppendChar(FX_CHAR* str, FX_DWORD charcode) const {
1616   return m_pCMap->AppendChar(str, charcode);
1617 }
IsUnicodeCompatible() const1618 FX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const {
1619   if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
1620       !m_pCID2UnicodeMap->IsLoaded()) {
1621     return m_pCMap->m_Coding != CIDCODING_UNKNOWN;
1622   }
1623   return TRUE;
1624 }
IsFontStyleFromCharCode(FX_DWORD charcode) const1625 FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const {
1626   return TRUE;
1627 }
LoadSubstFont()1628 void CPDF_CIDFont::LoadSubstFont() {
1629   m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle,
1630                    g_CharsetCPs[m_Charset], IsVertWriting());
1631 }
LoadMetricsArray(CPDF_Array * pArray,CFX_DWordArray & result,int nElements)1632 void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
1633                                     CFX_DWordArray& result,
1634                                     int nElements) {
1635   int width_status = 0;
1636   int iCurElement = 0;
1637   int first_code = 0, last_code;
1638   FX_DWORD count = pArray->GetCount();
1639   for (FX_DWORD i = 0; i < count; i++) {
1640     CPDF_Object* pObj = pArray->GetElementValue(i);
1641     if (!pObj)
1642       continue;
1643 
1644     if (CPDF_Array* pArray = pObj->AsArray()) {
1645       if (width_status != 1)
1646         return;
1647 
1648       FX_DWORD count = pArray->GetCount();
1649       for (FX_DWORD j = 0; j < count; j += nElements) {
1650         result.Add(first_code);
1651         result.Add(first_code);
1652         for (int k = 0; k < nElements; k++) {
1653           result.Add(pArray->GetInteger(j + k));
1654         }
1655         first_code++;
1656       }
1657       width_status = 0;
1658     } else {
1659       if (width_status == 0) {
1660         first_code = pObj->GetInteger();
1661         width_status = 1;
1662       } else if (width_status == 1) {
1663         last_code = pObj->GetInteger();
1664         width_status = 2;
1665         iCurElement = 0;
1666       } else {
1667         if (!iCurElement) {
1668           result.Add(first_code);
1669           result.Add(last_code);
1670         }
1671         result.Add(pObj->GetInteger());
1672         iCurElement++;
1673         if (iCurElement == nElements) {
1674           width_status = 0;
1675         }
1676       }
1677     }
1678   }
1679 }
1680 
1681 // static
CIDTransformToFloat(uint8_t ch)1682 FX_FLOAT CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) {
1683   if (ch < 128) {
1684     return ch * 1.0f / 127;
1685   }
1686   return (-255 + ch) * 1.0f / 127;
1687 }
1688 
LoadGB2312()1689 FX_BOOL CPDF_CIDFont::LoadGB2312() {
1690   m_BaseFont = m_pFontDict->GetString("BaseFont");
1691   CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor");
1692   if (pFontDesc) {
1693     LoadFontDescriptor(pFontDesc);
1694   }
1695   m_Charset = CIDSET_GB1;
1696   m_bType1 = FALSE;
1697   m_pCMap = CPDF_ModuleMgr::Get()
1698                 ->GetPageModule()
1699                 ->GetFontGlobals()
1700                 ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE);
1701   m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()
1702                           ->GetPageModule()
1703                           ->GetFontGlobals()
1704                           ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE);
1705   if (!IsEmbedded()) {
1706     LoadSubstFont();
1707   }
1708   CheckFontMetrics();
1709   m_DefaultWidth = 1000;
1710   m_pAnsiWidths = FX_Alloc(FX_WORD, 128);
1711   for (int i = 32; i < 127; i++) {
1712     m_pAnsiWidths[i] = 500;
1713   }
1714   return TRUE;
1715 }
1716 
GetCIDTransform(FX_WORD CID) const1717 const uint8_t* CPDF_CIDFont::GetCIDTransform(FX_WORD CID) const {
1718   if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
1719     return nullptr;
1720 
1721   const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch(
1722       &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs),
1723       sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform);
1724   return found ? &found->a : nullptr;
1725 }
1726