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