Home | History | Annotate | Download | only in fpdf_font
      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 
    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 
    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 
    190 CFX_ByteString CMap_GetString(const CFX_ByteStringC& word) {
    191   return word.Mid(1, word.GetLength() - 2);
    192 }
    193 
    194 int CompareDWORD(const void* data1, const void* data2) {
    195   return (*(FX_DWORD*)data1) - (*(FX_DWORD*)data2);
    196 }
    197 
    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 
    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 
    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 
    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_
    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 
    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 
    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 
    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 
    528 CPDF_CMapManager::CPDF_CMapManager() {
    529   m_bPrompted = FALSE;
    530   FXSYS_memset(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps);
    531 }
    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 }
    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 }
    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 
    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 }
    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 }
    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 }
    591 CPDF_CMapParser::CPDF_CMapParser() {
    592   m_pCMap = NULL;
    593   m_Status = 0;
    594   m_CodeSeq = 0;
    595 }
    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 
    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.
    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.
    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 
    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 }
    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 }
    771 void CPDF_CMap::Release() {
    772   if (m_PredefinedCMap.IsEmpty()) {
    773     delete this;
    774   }
    775 }
    776 
    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 }
    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 
    844 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 
    877 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 }
    922 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 }
    943 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 
    971 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 }
   1013 CPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap() {
   1014   m_EmbeddedCount = 0;
   1015 }
   1016 CPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap() {}
   1017 FX_BOOL CPDF_CID2UnicodeMap::Initialize() {
   1018   return TRUE;
   1019 }
   1020 FX_BOOL CPDF_CID2UnicodeMap::IsLoaded() {
   1021   return m_EmbeddedCount != 0;
   1022 }
   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 
   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"
   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 }
   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 }
   1060 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 }
   1066 FX_BOOL CPDF_CIDFont::IsVertWriting() const {
   1067   return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
   1068 }
   1069 
   1070 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 }
   1106 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 
   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 
   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 }
   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 }
   1372 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 }
   1384 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 }
   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 }
   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 }
   1604 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 }
   1609 int CPDF_CIDFont::GetCharSize(FX_DWORD charcode) const {
   1610   return m_pCMap->GetCharSize(charcode);
   1611 }
   1612 int CPDF_CIDFont::CountChar(const FX_CHAR* pString, int size) const {
   1613   return m_pCMap->CountChar(pString, size);
   1614 }
   1615 int CPDF_CIDFont::AppendChar(FX_CHAR* str, FX_DWORD charcode) const {
   1616   return m_pCMap->AppendChar(str, charcode);
   1617 }
   1618 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 }
   1625 FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const {
   1626   return TRUE;
   1627 }
   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 }
   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
   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 
   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 
   1717 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