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/src/fpdfapi/fpdf_page/pageint.h"
10#include "core/include/fpdfapi/fpdf_module.h"
11#include "core/include/fpdfapi/fpdf_page.h"
12#include "core/include/fpdfapi/fpdf_pageobj.h"
13#include "core/include/fpdfapi/fpdf_resource.h"
14#include "core/include/fxcrt/fx_ext.h"
15#include "core/include/fxge/fx_freetype.h"
16#include "third_party/base/stl_util.h"
17
18#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
19#include "core/src/fxge/apple/apple_int.h"
20#endif
21
22FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) {
23  for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
24    if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) ==
25            platform_id &&
26        FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) ==
27            encoding_id) {
28      FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
29      return TRUE;
30    }
31  }
32  return FALSE;
33}
34
35CFX_StockFontArray::CFX_StockFontArray() {}
36
37CFX_StockFontArray::~CFX_StockFontArray() {
38  for (size_t i = 0; i < FX_ArraySize(m_StockFonts); ++i) {
39    if (!m_StockFonts[i])
40      continue;
41    CPDF_Dictionary* pFontDict = m_StockFonts[i]->GetFontDict();
42    if (pFontDict)
43      pFontDict->Release();
44  }
45}
46
47CPDF_Font* CFX_StockFontArray::GetFont(int index) const {
48  if (index < 0 || index >= FX_ArraySize(m_StockFonts))
49    return nullptr;
50  return m_StockFonts[index].get();
51}
52
53void CFX_StockFontArray::SetFont(int index, CPDF_Font* font) {
54  if (index < 0 || index >= FX_ArraySize(m_StockFonts))
55    return;
56  m_StockFonts[index].reset(font);
57}
58
59CPDF_FontGlobals::CPDF_FontGlobals() {
60  FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets));
61  FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes));
62}
63
64CPDF_FontGlobals::~CPDF_FontGlobals() {
65}
66
67CPDF_Font* CPDF_FontGlobals::Find(CPDF_Document* pDoc, int index) {
68  auto it = m_StockMap.find(pDoc);
69  if (it == m_StockMap.end())
70    return nullptr;
71  return it->second ? it->second->GetFont(index) : nullptr;
72}
73
74void CPDF_FontGlobals::Set(CPDF_Document* pDoc, int index, CPDF_Font* pFont) {
75  if (!pdfium::ContainsKey(m_StockMap, pDoc))
76    m_StockMap[pDoc].reset(new CFX_StockFontArray);
77  m_StockMap[pDoc]->SetFont(index, pFont);
78}
79
80void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) {
81  m_StockMap.erase(pDoc);
82}
83
84CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype) {
85  m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0;
86  m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0;
87  m_pFontFile = NULL;
88  m_Flags = 0;
89  m_pToUnicodeMap = NULL;
90  m_bToUnicodeLoaded = FALSE;
91  m_pCharMap = new CPDF_FontCharMap(this);
92}
93CPDF_Font::~CPDF_Font() {
94  delete m_pCharMap;
95  m_pCharMap = NULL;
96
97  delete m_pToUnicodeMap;
98  m_pToUnicodeMap = NULL;
99
100  if (m_pFontFile) {
101    m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
102        const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
103  }
104}
105FX_BOOL CPDF_Font::IsVertWriting() const {
106  FX_BOOL bVertWriting = FALSE;
107  CPDF_CIDFont* pCIDFont = GetCIDFont();
108  if (pCIDFont) {
109    bVertWriting = pCIDFont->IsVertWriting();
110  } else {
111    bVertWriting = m_Font.IsVertical();
112  }
113  return bVertWriting;
114}
115CFX_ByteString CPDF_Font::GetFontTypeName() const {
116  switch (m_FontType) {
117    case PDFFONT_TYPE1:
118      return "Type1";
119    case PDFFONT_TRUETYPE:
120      return "TrueType";
121    case PDFFONT_TYPE3:
122      return "Type3";
123    case PDFFONT_CIDFONT:
124      return "Type0";
125  }
126  return CFX_ByteString();
127}
128void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const {
129  char buf[4];
130  int len = AppendChar(buf, charcode);
131  if (len == 1) {
132    str += buf[0];
133  } else {
134    str += CFX_ByteString(buf, len);
135  }
136}
137CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const {
138  if (!m_bToUnicodeLoaded) {
139    ((CPDF_Font*)this)->LoadUnicodeMap();
140  }
141  if (m_pToUnicodeMap) {
142    CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode);
143    if (!wsRet.IsEmpty()) {
144      return wsRet;
145    }
146  }
147  FX_WCHAR unicode = _UnicodeFromCharCode(charcode);
148  if (unicode == 0) {
149    return CFX_WideString();
150  }
151  return unicode;
152}
153FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
154  if (!m_bToUnicodeLoaded) {
155    ((CPDF_Font*)this)->LoadUnicodeMap();
156  }
157  if (m_pToUnicodeMap) {
158    FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode);
159    if (charcode) {
160      return charcode;
161    }
162  }
163  return _CharCodeFromUnicode(unicode);
164}
165CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const {
166  CFX_WideString result;
167  int src_len = str.GetLength();
168  result.Reserve(src_len);
169  const FX_CHAR* src_buf = str;
170  int src_pos = 0;
171  while (src_pos < src_len) {
172    FX_DWORD charcode = GetNextChar(src_buf, src_len, src_pos);
173    CFX_WideString unicode = UnicodeFromCharCode(charcode);
174    if (!unicode.IsEmpty()) {
175      result += unicode;
176    } else {
177      result += (FX_WCHAR)charcode;
178    }
179  }
180  return result;
181}
182CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const {
183  CFX_ByteString result;
184  int src_len = str.GetLength();
185  FX_CHAR* dest_buf = result.GetBuffer(src_len * 2);
186  const FX_WCHAR* src_buf = str.c_str();
187  int dest_pos = 0;
188  for (int src_pos = 0; src_pos < src_len; src_pos++) {
189    FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]);
190    dest_pos += AppendChar(dest_buf + dest_pos, charcode);
191  }
192  result.ReleaseBuffer(dest_pos);
193  return result;
194}
195
196void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
197  m_Flags = pFontDesc->GetInteger("Flags", PDFFONT_NONSYMBOLIC);
198  int ItalicAngle = 0;
199  FX_BOOL bExistItalicAngle = FALSE;
200  if (pFontDesc->KeyExist("ItalicAngle")) {
201    ItalicAngle = pFontDesc->GetInteger("ItalicAngle");
202    bExistItalicAngle = TRUE;
203  }
204  if (ItalicAngle < 0) {
205    m_Flags |= PDFFONT_ITALIC;
206    m_ItalicAngle = ItalicAngle;
207  }
208  FX_BOOL bExistStemV = FALSE;
209  if (pFontDesc->KeyExist("StemV")) {
210    m_StemV = pFontDesc->GetInteger("StemV");
211    bExistStemV = TRUE;
212  }
213  FX_BOOL bExistAscent = FALSE;
214  if (pFontDesc->KeyExist("Ascent")) {
215    m_Ascent = pFontDesc->GetInteger("Ascent");
216    bExistAscent = TRUE;
217  }
218  FX_BOOL bExistDescent = FALSE;
219  if (pFontDesc->KeyExist("Descent")) {
220    m_Descent = pFontDesc->GetInteger("Descent");
221    bExistDescent = TRUE;
222  }
223  FX_BOOL bExistCapHeight = FALSE;
224  if (pFontDesc->KeyExist("CapHeight")) {
225    bExistCapHeight = TRUE;
226  }
227  if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
228      bExistStemV) {
229    m_Flags |= PDFFONT_USEEXTERNATTR;
230  }
231  if (m_Descent > 10) {
232    m_Descent = -m_Descent;
233  }
234  CPDF_Array* pBBox = pFontDesc->GetArray("FontBBox");
235  if (pBBox) {
236    m_FontBBox.left = pBBox->GetInteger(0);
237    m_FontBBox.bottom = pBBox->GetInteger(1);
238    m_FontBBox.right = pBBox->GetInteger(2);
239    m_FontBBox.top = pBBox->GetInteger(3);
240  }
241
242  CPDF_Stream* pFontFile = pFontDesc->GetStream("FontFile");
243  if (!pFontFile)
244    pFontFile = pFontDesc->GetStream("FontFile2");
245  if (!pFontFile)
246    pFontFile = pFontDesc->GetStream("FontFile3");
247  if (!pFontFile)
248    return;
249
250  m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
251  if (!m_pFontFile)
252    return;
253
254  const uint8_t* pFontData = m_pFontFile->GetData();
255  FX_DWORD dwFontSize = m_pFontFile->GetSize();
256  if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
257    m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
258        const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
259    m_pFontFile = nullptr;
260  }
261}
262
263short TT2PDF(int m, FXFT_Face face) {
264  int upm = FXFT_Get_Face_UnitsPerEM(face);
265  if (upm == 0) {
266    return (short)m;
267  }
268  return (m * 1000 + upm / 2) / upm;
269}
270void CPDF_Font::CheckFontMetrics() {
271  if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
272      m_FontBBox.right == 0) {
273    FXFT_Face face = m_Font.GetFace();
274    if (face) {
275      m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
276      m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
277      m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
278      m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
279      m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
280      m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
281    } else {
282      FX_BOOL bFirst = TRUE;
283      for (int i = 0; i < 256; i++) {
284        FX_RECT rect;
285        GetCharBBox(i, rect);
286        if (rect.left == rect.right) {
287          continue;
288        }
289        if (bFirst) {
290          m_FontBBox = rect;
291          bFirst = FALSE;
292        } else {
293          if (m_FontBBox.top < rect.top) {
294            m_FontBBox.top = rect.top;
295          }
296          if (m_FontBBox.right < rect.right) {
297            m_FontBBox.right = rect.right;
298          }
299          if (m_FontBBox.left > rect.left) {
300            m_FontBBox.left = rect.left;
301          }
302          if (m_FontBBox.bottom > rect.bottom) {
303            m_FontBBox.bottom = rect.bottom;
304          }
305        }
306      }
307    }
308  }
309  if (m_Ascent == 0 && m_Descent == 0) {
310    FX_RECT rect;
311    GetCharBBox('A', rect);
312    if (rect.bottom == rect.top) {
313      m_Ascent = m_FontBBox.top;
314    } else {
315      m_Ascent = rect.top;
316    }
317    GetCharBBox('g', rect);
318    if (rect.bottom == rect.top) {
319      m_Descent = m_FontBBox.bottom;
320    } else {
321      m_Descent = rect.bottom;
322    }
323  }
324}
325void CPDF_Font::LoadUnicodeMap() {
326  m_bToUnicodeLoaded = TRUE;
327  CPDF_Stream* pStream = m_pFontDict->GetStream("ToUnicode");
328  if (!pStream) {
329    return;
330  }
331  m_pToUnicodeMap = new CPDF_ToUnicodeMap;
332  m_pToUnicodeMap->Load(pStream);
333}
334int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
335  int offset = 0;
336  int width = 0;
337  while (offset < size) {
338    FX_DWORD charcode = GetNextChar(pString, size, offset);
339    width += GetCharWidthF(charcode);
340  }
341  return width;
342}
343int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode) {
344  if (!m_Font.GetFace())
345    return 0;
346
347  int glyph_index = GlyphFromCharCode(charcode);
348  if (glyph_index == 0xffff) {
349    return 0;
350  }
351  return m_Font.GetGlyphWidth(glyph_index);
352}
353
354CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
355                                   const CFX_ByteStringC& name) {
356  CFX_ByteString fontname(name);
357  int font_id = PDF_GetStandardFontName(&fontname);
358  if (font_id < 0) {
359    return nullptr;
360  }
361  CPDF_FontGlobals* pFontGlobals =
362      CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
363  CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
364  if (pFont) {
365    return pFont;
366  }
367  CPDF_Dictionary* pDict = new CPDF_Dictionary;
368  pDict->SetAtName("Type", "Font");
369  pDict->SetAtName("Subtype", "Type1");
370  pDict->SetAtName("BaseFont", fontname);
371  pDict->SetAtName("Encoding", "WinAnsiEncoding");
372  pFont = CPDF_Font::CreateFontF(NULL, pDict);
373  pFontGlobals->Set(pDoc, font_id, pFont);
374  return pFont;
375}
376const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
377                                       {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
378                                       {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
379                                       {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
380                                       {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
381CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
382                                  CPDF_Dictionary* pFontDict) {
383  CFX_ByteString type = pFontDict->GetString("Subtype");
384  CPDF_Font* pFont;
385  if (type == "TrueType") {
386    {
387#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
388    _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ ||   \
389    _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
390    _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
391      CFX_ByteString basefont = pFontDict->GetString("BaseFont");
392      CFX_ByteString tag = basefont.Left(4);
393      int i;
394      int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
395      for (i = 0; i < count; ++i) {
396        if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
397          break;
398        }
399      }
400      if (i < count) {
401        CPDF_Dictionary* pFontDesc = pFontDict->GetDict("FontDescriptor");
402        if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
403          pFont = new CPDF_CIDFont;
404          pFont->m_pFontDict = pFontDict;
405          pFont->m_pDocument = pDoc;
406          if (!pFont->Load()) {
407            delete pFont;
408            return NULL;
409          }
410          return pFont;
411        }
412      }
413#endif
414    }
415    pFont = new CPDF_TrueTypeFont;
416  } else if (type == "Type3") {
417    pFont = new CPDF_Type3Font;
418  } else if (type == "Type0") {
419    pFont = new CPDF_CIDFont;
420  } else {
421    pFont = new CPDF_Type1Font;
422  }
423  pFont->m_pFontDict = pFontDict;
424  pFont->m_pDocument = pDoc;
425  if (!pFont->Load()) {
426    delete pFont;
427    return NULL;
428  }
429  return pFont;
430}
431FX_BOOL CPDF_Font::Load() {
432  if (!m_pFontDict) {
433    return FALSE;
434  }
435  CFX_ByteString type = m_pFontDict->GetString("Subtype");
436  m_BaseFont = m_pFontDict->GetString("BaseFont");
437  if (type == "MMType1") {
438    type = "Type1";
439  }
440  return _Load();
441}
442static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap,
443                                             const CFX_ByteString& bytestr) {
444  return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr);
445}
446static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap,
447                                             const CFX_WideString& widestr) {
448  return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr);
449}
450CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont) {
451  m_GetByteString = _FontMap_GetByteString;
452  m_GetWideString = _FontMap_GetWideString;
453  m_pFont = pFont;
454}
455CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) {
456  auto it = m_Map.find(charcode);
457  if (it != m_Map.end()) {
458    FX_DWORD value = it->second;
459    FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);
460    if (unicode != 0xffff) {
461      return unicode;
462    }
463    const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer();
464    FX_DWORD buf_len = m_MultiCharBuf.GetLength();
465    if (!buf || buf_len == 0) {
466      return CFX_WideString();
467    }
468    FX_DWORD index = value >> 16;
469    if (index >= buf_len) {
470      return CFX_WideString();
471    }
472    FX_DWORD len = buf[index];
473    if (index + len < index || index + len >= buf_len) {
474      return CFX_WideString();
475    }
476    return CFX_WideString(buf + index + 1, len);
477  }
478  if (m_pBaseMap) {
479    return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);
480  }
481  return CFX_WideString();
482}
483FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) {
484  for (const auto& pair : m_Map) {
485    if (pair.second == unicode)
486      return pair.first;
487  }
488  return 0;
489}
490
491// Static.
492FX_DWORD CPDF_ToUnicodeMap::StringToCode(const CFX_ByteStringC& str) {
493  const FX_CHAR* buf = str.GetCStr();
494  int len = str.GetLength();
495  if (len == 0)
496    return 0;
497
498  int result = 0;
499  if (buf[0] == '<') {
500    for (int i = 1; i < len && std::isxdigit(buf[i]); ++i)
501      result = result * 16 + FXSYS_toHexDigit(buf[i]);
502    return result;
503  }
504
505  for (int i = 0; i < len && std::isdigit(buf[i]); ++i)
506    result = result * 10 + FXSYS_toDecimalDigit(buf[i]);
507
508  return result;
509}
510static CFX_WideString StringDataAdd(CFX_WideString str) {
511  CFX_WideString ret;
512  int len = str.GetLength();
513  FX_WCHAR value = 1;
514  for (int i = len - 1; i >= 0; --i) {
515    FX_WCHAR ch = str[i] + value;
516    if (ch < str[i]) {
517      ret.Insert(0, 0);
518    } else {
519      ret.Insert(0, ch);
520      value = 0;
521    }
522  }
523  if (value) {
524    ret.Insert(0, value);
525  }
526  return ret;
527}
528
529// Static.
530CFX_WideString CPDF_ToUnicodeMap::StringToWideString(
531    const CFX_ByteStringC& str) {
532  const FX_CHAR* buf = str.GetCStr();
533  int len = str.GetLength();
534  if (len == 0)
535    return CFX_WideString();
536
537  CFX_WideString result;
538  if (buf[0] == '<') {
539    int byte_pos = 0;
540    FX_WCHAR ch = 0;
541    for (int i = 1; i < len && std::isxdigit(buf[i]); ++i) {
542      ch = ch * 16 + FXSYS_toHexDigit(buf[i]);
543      byte_pos++;
544      if (byte_pos == 4) {
545        result += ch;
546        byte_pos = 0;
547        ch = 0;
548      }
549    }
550    return result;
551  }
552  return result;
553}
554void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) {
555  CIDSet cid_set = CIDSET_UNKNOWN;
556  CPDF_StreamAcc stream;
557  stream.LoadAllData(pStream, FALSE);
558  CPDF_SimpleParser parser(stream.GetData(), stream.GetSize());
559  while (1) {
560    CFX_ByteStringC word = parser.GetWord();
561    if (word.IsEmpty()) {
562      break;
563    }
564    if (word == "beginbfchar") {
565      while (1) {
566        word = parser.GetWord();
567        if (word.IsEmpty() || word == "endbfchar") {
568          break;
569        }
570        FX_DWORD srccode = StringToCode(word);
571        word = parser.GetWord();
572        CFX_WideString destcode = StringToWideString(word);
573        int len = destcode.GetLength();
574        if (len == 0) {
575          continue;
576        }
577        if (len == 1) {
578          m_Map[srccode] = destcode.GetAt(0);
579        } else {
580          m_Map[srccode] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff;
581          m_MultiCharBuf.AppendChar(destcode.GetLength());
582          m_MultiCharBuf << destcode;
583        }
584      }
585    } else if (word == "beginbfrange") {
586      while (1) {
587        CFX_ByteString low, high;
588        low = parser.GetWord();
589        if (low.IsEmpty() || low == "endbfrange") {
590          break;
591        }
592        high = parser.GetWord();
593        FX_DWORD lowcode = StringToCode(low);
594        FX_DWORD highcode =
595            (lowcode & 0xffffff00) | (StringToCode(high) & 0xff);
596        if (highcode == (FX_DWORD)-1) {
597          break;
598        }
599        CFX_ByteString start = parser.GetWord();
600        if (start == "[") {
601          for (FX_DWORD code = lowcode; code <= highcode; code++) {
602            CFX_ByteString dest = parser.GetWord();
603            CFX_WideString destcode = StringToWideString(dest);
604            int len = destcode.GetLength();
605            if (len == 0) {
606              continue;
607            }
608            if (len == 1) {
609              m_Map[code] = destcode.GetAt(0);
610            } else {
611              m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff;
612              m_MultiCharBuf.AppendChar(destcode.GetLength());
613              m_MultiCharBuf << destcode;
614            }
615          }
616          parser.GetWord();
617        } else {
618          CFX_WideString destcode = StringToWideString(start);
619          int len = destcode.GetLength();
620          FX_DWORD value = 0;
621          if (len == 1) {
622            value = StringToCode(start);
623            for (FX_DWORD code = lowcode; code <= highcode; code++) {
624              m_Map[code] = value++;
625            }
626          } else {
627            for (FX_DWORD code = lowcode; code <= highcode; code++) {
628              CFX_WideString retcode;
629              if (code == lowcode) {
630                retcode = destcode;
631              } else {
632                retcode = StringDataAdd(destcode);
633              }
634              m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff;
635              m_MultiCharBuf.AppendChar(retcode.GetLength());
636              m_MultiCharBuf << retcode;
637              destcode = retcode;
638            }
639          }
640        }
641      }
642    } else if (word == "/Adobe-Korea1-UCS2") {
643      cid_set = CIDSET_KOREA1;
644    } else if (word == "/Adobe-Japan1-UCS2") {
645      cid_set = CIDSET_JAPAN1;
646    } else if (word == "/Adobe-CNS1-UCS2") {
647      cid_set = CIDSET_CNS1;
648    } else if (word == "/Adobe-GB1-UCS2") {
649      cid_set = CIDSET_GB1;
650    }
651  }
652  if (cid_set) {
653    m_pBaseMap = CPDF_ModuleMgr::Get()
654                     ->GetPageModule()
655                     ->GetFontGlobals()
656                     ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE);
657  } else {
658    m_pBaseMap = NULL;
659  }
660}
661static FX_BOOL GetPredefinedEncoding(int& basemap,
662                                     const CFX_ByteString& value) {
663  if (value == "WinAnsiEncoding") {
664    basemap = PDFFONT_ENCODING_WINANSI;
665  } else if (value == "MacRomanEncoding") {
666    basemap = PDFFONT_ENCODING_MACROMAN;
667  } else if (value == "MacExpertEncoding") {
668    basemap = PDFFONT_ENCODING_MACEXPERT;
669  } else if (value == "PDFDocEncoding") {
670    basemap = PDFFONT_ENCODING_PDFDOC;
671  } else {
672    return FALSE;
673  }
674  return TRUE;
675}
676void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
677                                int& iBaseEncoding,
678                                CFX_ByteString*& pCharNames,
679                                FX_BOOL bEmbedded,
680                                FX_BOOL bTrueType) {
681  if (!pEncoding) {
682    if (m_BaseFont == "Symbol") {
683      iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
684                                : PDFFONT_ENCODING_ADOBE_SYMBOL;
685    } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
686      iBaseEncoding = PDFFONT_ENCODING_WINANSI;
687    }
688    return;
689  }
690  if (pEncoding->IsName()) {
691    if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
692        iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
693      return;
694    }
695    if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
696      if (!bTrueType) {
697        iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
698      }
699      return;
700    }
701    CFX_ByteString bsEncoding = pEncoding->GetString();
702    if (bsEncoding.Compare("MacExpertEncoding") == 0) {
703      bsEncoding = "WinAnsiEncoding";
704    }
705    GetPredefinedEncoding(iBaseEncoding, bsEncoding);
706    return;
707  }
708
709  CPDF_Dictionary* pDict = pEncoding->AsDictionary();
710  if (!pDict)
711    return;
712
713  if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
714      iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
715    CFX_ByteString bsEncoding = pDict->GetString("BaseEncoding");
716    if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
717      bsEncoding = "WinAnsiEncoding";
718    }
719    GetPredefinedEncoding(iBaseEncoding, bsEncoding);
720  }
721  if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
722    iBaseEncoding = PDFFONT_ENCODING_STANDARD;
723  }
724  CPDF_Array* pDiffs = pDict->GetArray("Differences");
725  if (!pDiffs) {
726    return;
727  }
728  pCharNames = new CFX_ByteString[256];
729  FX_DWORD cur_code = 0;
730  for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
731    CPDF_Object* pElement = pDiffs->GetElementValue(i);
732    if (!pElement)
733      continue;
734
735    if (CPDF_Name* pName = pElement->AsName()) {
736      if (cur_code < 256)
737        pCharNames[cur_code] = pName->GetString();
738      cur_code++;
739    } else {
740      cur_code = pElement->GetInteger();
741    }
742  }
743}
744
745FX_BOOL CPDF_Font::IsStandardFont() const {
746  if (m_FontType != PDFFONT_TYPE1)
747    return FALSE;
748  if (m_pFontFile)
749    return FALSE;
750  if (((CPDF_Type1Font*)this)->GetBase14Font() < 0)
751    return FALSE;
752  return TRUE;
753}
754CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype) {
755  FXSYS_memset(m_CharBBox, 0xff, sizeof m_CharBBox);
756  FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
757  FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
758  FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
759  m_pCharNames = NULL;
760  m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
761}
762CPDF_SimpleFont::~CPDF_SimpleFont() {
763  delete[] m_pCharNames;
764}
765int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
766  if (pVertGlyph) {
767    *pVertGlyph = FALSE;
768  }
769  if (charcode > 0xff) {
770    return -1;
771  }
772  int index = m_GlyphIndex[(uint8_t)charcode];
773  if (index == 0xffff) {
774    return -1;
775  }
776  return index;
777}
778void CPDF_SimpleFont::LoadCharMetrics(int charcode) {
779  if (!m_Font.GetFace())
780    return;
781
782  if (charcode < 0 || charcode > 0xff) {
783    return;
784  }
785  int glyph_index = m_GlyphIndex[charcode];
786  if (glyph_index == 0xffff) {
787    if (!m_pFontFile && charcode != 32) {
788      LoadCharMetrics(32);
789      m_CharBBox[charcode] = m_CharBBox[32];
790      if (m_bUseFontWidth) {
791        m_CharWidth[charcode] = m_CharWidth[32];
792      }
793    }
794    return;
795  }
796  FXFT_Face face = m_Font.GetFace();
797  int err = FXFT_Load_Glyph(
798      face, glyph_index,
799      FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
800  if (err) {
801    return;
802  }
803  m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face);
804  m_CharBBox[charcode].Right = TT2PDF(
805      FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), face);
806  m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face);
807  m_CharBBox[charcode].Bottom = TT2PDF(
808      FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), face);
809  if (m_bUseFontWidth) {
810    int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face);
811    if (m_CharWidth[charcode] == 0xffff) {
812      m_CharWidth[charcode] = TT_Width;
813    } else if (TT_Width && !IsEmbedded()) {
814      m_CharBBox[charcode].Right =
815          m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width;
816      m_CharBBox[charcode].Left =
817          m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width;
818    }
819  }
820}
821int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) {
822  if (charcode > 0xff) {
823    charcode = 0;
824  }
825  if (m_CharWidth[charcode] == 0xffff) {
826    LoadCharMetrics(charcode);
827    if (m_CharWidth[charcode] == 0xffff) {
828      m_CharWidth[charcode] = 0;
829    }
830  }
831  return (int16_t)m_CharWidth[charcode];
832}
833void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) {
834  if (charcode > 0xff) {
835    charcode = 0;
836  }
837  if (m_CharBBox[charcode].Left == (int16_t)0xffff) {
838    LoadCharMetrics(charcode);
839  }
840  rect.left = m_CharBBox[charcode].Left;
841  rect.right = m_CharBBox[charcode].Right;
842  rect.bottom = m_CharBBox[charcode].Bottom;
843  rect.top = m_CharBBox[charcode].Top;
844}
845const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
846                                const CFX_ByteString* pCharNames,
847                                int charcode) {
848  ASSERT(charcode >= 0 && charcode < 256);
849  if (charcode < 0 || charcode >= 256) {
850    return NULL;
851  }
852  const FX_CHAR* name = NULL;
853  if (pCharNames) {
854    name = pCharNames[charcode];
855  }
856  if ((!name || name[0] == 0) && iBaseEncoding) {
857    name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
858  }
859  return name && name[0] ? name : nullptr;
860}
861FX_BOOL CPDF_SimpleFont::LoadCommon() {
862  CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor");
863  if (pFontDesc) {
864    LoadFontDescriptor(pFontDesc);
865  }
866  CPDF_Array* pWidthArray = m_pFontDict->GetArray("Widths");
867  int width_start = 0, width_end = -1;
868  m_bUseFontWidth = TRUE;
869  if (pWidthArray) {
870    m_bUseFontWidth = FALSE;
871    if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
872      int MissingWidth = pFontDesc->GetInteger("MissingWidth");
873      for (int i = 0; i < 256; i++) {
874        m_CharWidth[i] = MissingWidth;
875      }
876    }
877    width_start = m_pFontDict->GetInteger("FirstChar", 0);
878    width_end = m_pFontDict->GetInteger("LastChar", 0);
879    if (width_start >= 0 && width_start <= 255) {
880      if (width_end <= 0 ||
881          width_end >= width_start + (int)pWidthArray->GetCount()) {
882        width_end = width_start + pWidthArray->GetCount() - 1;
883      }
884      if (width_end > 255) {
885        width_end = 255;
886      }
887      for (int i = width_start; i <= width_end; i++) {
888        m_CharWidth[i] = pWidthArray->GetInteger(i - width_start);
889      }
890    }
891  }
892  if (m_pFontFile) {
893    if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
894      m_BaseFont = m_BaseFont.Mid(8);
895    }
896  } else {
897    LoadSubstFont();
898  }
899  if (!(m_Flags & PDFFONT_SYMBOLIC)) {
900    m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
901  }
902  CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
903  LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
904                  m_Font.IsTTFont());
905  LoadGlyphMap();
906  delete[] m_pCharNames;
907  m_pCharNames = NULL;
908  if (!m_Font.GetFace())
909    return TRUE;
910
911  if (m_Flags & PDFFONT_ALLCAP) {
912    unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
913    for (size_t range = 0; range < sizeof lowercases / 2; range++) {
914      for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
915        if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
916          continue;
917        }
918        m_GlyphIndex[i] = m_GlyphIndex[i - 32];
919        if (m_CharWidth[i - 32]) {
920          m_CharWidth[i] = m_CharWidth[i - 32];
921          m_CharBBox[i] = m_CharBBox[i - 32];
922        }
923      }
924    }
925  }
926  CheckFontMetrics();
927  return TRUE;
928}
929void CPDF_SimpleFont::LoadSubstFont() {
930  if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
931    int width = 0, i;
932    for (i = 0; i < 256; i++) {
933      if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
934        continue;
935      }
936      if (width == 0) {
937        width = m_CharWidth[i];
938      } else if (width != m_CharWidth[i]) {
939        break;
940      }
941    }
942    if (i == 256 && width) {
943      m_Flags |= PDFFONT_FIXEDPITCH;
944    }
945  }
946  int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
947  m_Font.LoadSubst(m_BaseFont, IsFontType(PDFFONT_TRUETYPE), m_Flags, weight,
948                   m_ItalicAngle, 0);
949  if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
950  }
951}
952FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const {
953  return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN &&
954         m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
955         m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
956}
957CPDF_Type1Font::CPDF_Type1Font() : CPDF_SimpleFont(PDFFONT_TYPE1) {
958  m_Base14Font = -1;
959}
960FX_BOOL CPDF_Type1Font::_Load() {
961  m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
962  if (m_Base14Font >= 0) {
963    CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor");
964    if (pFontDesc && pFontDesc->KeyExist("Flags")) {
965      m_Flags = pFontDesc->GetInteger("Flags");
966    } else {
967      m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
968    }
969    if (m_Base14Font < 4)
970      for (int i = 0; i < 256; i++) {
971        m_CharWidth[i] = 600;
972      }
973    if (m_Base14Font == 12) {
974      m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
975    } else if (m_Base14Font == 13) {
976      m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
977    } else if (m_Flags & PDFFONT_NONSYMBOLIC) {
978      m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
979    }
980  }
981  return LoadCommon();
982}
983static FX_BOOL FT_UseType1Charmap(FXFT_Face face) {
984  if (FXFT_Get_Face_CharmapCount(face) == 0) {
985    return FALSE;
986  }
987  if (FXFT_Get_Face_CharmapCount(face) == 1 &&
988      FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
989          FXFT_ENCODING_UNICODE) {
990    return FALSE;
991  }
992  if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
993      FXFT_ENCODING_UNICODE) {
994    FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
995  } else {
996    FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
997  }
998  return TRUE;
999}
1000int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
1001  if (charcode > 0xff) {
1002    return -1;
1003  }
1004  int index = m_ExtGID[(uint8_t)charcode];
1005  if (index == 0xffff) {
1006    return -1;
1007  }
1008  return index;
1009}
1010#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1011struct _GlyphNameMap {
1012  const FX_CHAR* m_pStrAdobe;
1013  const FX_CHAR* m_pStrUnicode;
1014};
1015static const _GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"},
1016                                                  {"fi", "uniFB01"},
1017                                                  {"fl", "uniFB02"},
1018                                                  {"ffi", "uniFB03"},
1019                                                  {"ffl", "uniFB04"}};
1020extern "C" {
1021static int compareString(const void* key, const void* element) {
1022  return FXSYS_stricmp((const FX_CHAR*)key,
1023                       ((_GlyphNameMap*)element)->m_pStrAdobe);
1024}
1025}
1026static const FX_CHAR* _GlyphNameRemap(const FX_CHAR* pStrAdobe) {
1027  _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(
1028      pStrAdobe, g_GlyphNameSubsts,
1029      sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap),
1030      compareString);
1031  if (found) {
1032    return found->m_pStrUnicode;
1033  }
1034  return NULL;
1035}
1036#endif
1037void CPDF_Type1Font::LoadGlyphMap() {
1038  if (!m_Font.GetFace())
1039    return;
1040
1041#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1042  FX_BOOL bCoreText = TRUE;
1043  CQuartz2D& quartz2d =
1044      ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
1045  if (!m_Font.GetPlatformFont()) {
1046    if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
1047      bCoreText = FALSE;
1048    }
1049    m_Font.SetPlatformFont(
1050        quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
1051    if (!m_Font.GetPlatformFont()) {
1052      bCoreText = FALSE;
1053    }
1054  }
1055#endif
1056  if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
1057    if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
1058      FX_BOOL bGotOne = FALSE;
1059      for (int charcode = 0; charcode < 256; charcode++) {
1060        const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1061        for (int j = 0; j < 4; j++) {
1062          FX_WORD unicode = prefix[j] * 256 + charcode;
1063          m_GlyphIndex[charcode] =
1064              FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
1065#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1066          FX_CHAR name_glyph[256];
1067          FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1068                              name_glyph, 256);
1069          name_glyph[255] = 0;
1070          CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1071              kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1072              kCFAllocatorNull);
1073          m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1074              (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1075          if (name_ct) {
1076            CFRelease(name_ct);
1077          }
1078#endif
1079          if (m_GlyphIndex[charcode]) {
1080            bGotOne = TRUE;
1081            break;
1082          }
1083        }
1084      }
1085      if (bGotOne) {
1086#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1087        if (!bCoreText) {
1088          FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1089        }
1090#endif
1091        return;
1092      }
1093    }
1094    FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
1095    if (m_BaseEncoding == 0) {
1096      m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
1097    }
1098    for (int charcode = 0; charcode < 256; charcode++) {
1099      const FX_CHAR* name =
1100          GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1101      if (!name) {
1102        continue;
1103      }
1104      m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1105      m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1106          m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
1107#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1108      FX_CHAR name_glyph[256];
1109      FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph,
1110                          256);
1111      name_glyph[255] = 0;
1112      CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1113          kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1114          kCFAllocatorNull);
1115      m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1116          (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1117      if (name_ct) {
1118        CFRelease(name_ct);
1119      }
1120#endif
1121      if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
1122        m_Encoding.m_Unicodes[charcode] = 0x20;
1123        m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20);
1124#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1125        FX_CHAR name_glyph[256];
1126        FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1127                            name_glyph, 256);
1128        name_glyph[255] = 0;
1129        CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1130            kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1131            kCFAllocatorNull);
1132        m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1133            (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1134        if (name_ct) {
1135          CFRelease(name_ct);
1136        }
1137#endif
1138      }
1139    }
1140#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1141    if (!bCoreText) {
1142      FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1143    }
1144#endif
1145    return;
1146  }
1147  FT_UseType1Charmap(m_Font.GetFace());
1148#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1149  if (bCoreText) {
1150    if (m_Flags & PDFFONT_SYMBOLIC) {
1151      for (int charcode = 0; charcode < 256; charcode++) {
1152        const FX_CHAR* name =
1153            GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1154        if (name) {
1155          m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1156          m_GlyphIndex[charcode] =
1157              FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1158          CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1159              kCFAllocatorDefault, name, kCFStringEncodingASCII,
1160              kCFAllocatorNull);
1161          m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1162              (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1163          if (name_ct) {
1164            CFRelease(name_ct);
1165          }
1166        } else {
1167          m_GlyphIndex[charcode] =
1168              FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1169          FX_WCHAR unicode = 0;
1170          if (m_GlyphIndex[charcode]) {
1171            unicode =
1172                FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
1173          }
1174          FX_CHAR name_glyph[256];
1175          FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
1176          FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1177                              name_glyph, 256);
1178          name_glyph[255] = 0;
1179          if (unicode == 0 && name_glyph[0] != 0) {
1180            unicode = PDF_UnicodeFromAdobeName(name_glyph);
1181          }
1182          m_Encoding.m_Unicodes[charcode] = unicode;
1183          CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1184              kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1185              kCFAllocatorNull);
1186          m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1187              (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1188          if (name_ct) {
1189            CFRelease(name_ct);
1190          }
1191        }
1192      }
1193      return;
1194    }
1195    FX_BOOL bUnicode = FALSE;
1196    if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
1197      bUnicode = TRUE;
1198    }
1199    for (int charcode = 0; charcode < 256; charcode++) {
1200      const FX_CHAR* name =
1201          GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1202      if (!name) {
1203        continue;
1204      }
1205      m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1206      const FX_CHAR* pStrUnicode = _GlyphNameRemap(name);
1207      if (pStrUnicode &&
1208          0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) {
1209        name = pStrUnicode;
1210      }
1211      m_GlyphIndex[charcode] =
1212          FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1213      CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1214          kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
1215      m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1216          (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1217      if (name_ct) {
1218        CFRelease(name_ct);
1219      }
1220      if (m_GlyphIndex[charcode] == 0) {
1221        if (FXSYS_strcmp(name, ".notdef") != 0 &&
1222            FXSYS_strcmp(name, "space") != 0) {
1223          m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1224              m_Font.GetFace(),
1225              bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
1226          FX_CHAR name_glyph[256];
1227          FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1228                              name_glyph, 256);
1229          name_glyph[255] = 0;
1230          CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1231              kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1232              kCFAllocatorNull);
1233          m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1234              (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1235          if (name_ct) {
1236            CFRelease(name_ct);
1237          }
1238        } else {
1239          m_Encoding.m_Unicodes[charcode] = 0x20;
1240          m_GlyphIndex[charcode] =
1241              bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff;
1242          FX_CHAR name_glyph[256];
1243          FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1244                              name_glyph, 256);
1245          name_glyph[255] = 0;
1246          CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1247              kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1248              kCFAllocatorNull);
1249          m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1250              (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1251          if (name_ct) {
1252            CFRelease(name_ct);
1253          }
1254        }
1255      }
1256    }
1257    return;
1258  }
1259#endif
1260  if (m_Flags & PDFFONT_SYMBOLIC) {
1261    for (int charcode = 0; charcode < 256; charcode++) {
1262      const FX_CHAR* name =
1263          GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1264      if (name) {
1265        m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1266        m_GlyphIndex[charcode] =
1267            FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1268      } else {
1269        m_GlyphIndex[charcode] =
1270            FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1271        if (m_GlyphIndex[charcode]) {
1272          FX_WCHAR unicode =
1273              FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
1274          if (unicode == 0) {
1275            FX_CHAR name_glyph[256];
1276            FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
1277            FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1278                                name_glyph, 256);
1279            name_glyph[255] = 0;
1280            if (name_glyph[0] != 0) {
1281              unicode = PDF_UnicodeFromAdobeName(name_glyph);
1282            }
1283          }
1284          m_Encoding.m_Unicodes[charcode] = unicode;
1285        }
1286      }
1287    }
1288#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1289    if (!bCoreText) {
1290      FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1291    }
1292#endif
1293    return;
1294  }
1295  FX_BOOL bUnicode = FALSE;
1296  if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
1297    bUnicode = TRUE;
1298  }
1299  for (int charcode = 0; charcode < 256; charcode++) {
1300    const FX_CHAR* name =
1301        GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1302    if (!name) {
1303      continue;
1304    }
1305    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1306    m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1307    if (m_GlyphIndex[charcode] == 0) {
1308      if (FXSYS_strcmp(name, ".notdef") != 0 &&
1309          FXSYS_strcmp(name, "space") != 0) {
1310        m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1311            m_Font.GetFace(),
1312            bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
1313      } else {
1314        m_Encoding.m_Unicodes[charcode] = 0x20;
1315        m_GlyphIndex[charcode] = 0xffff;
1316      }
1317    }
1318  }
1319#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1320  if (!bCoreText) {
1321    FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1322  }
1323#endif
1324}
1325
1326CPDF_FontEncoding::CPDF_FontEncoding() {
1327  FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
1328}
1329int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const {
1330  for (int i = 0; i < 256; i++)
1331    if (m_Unicodes[i] == unicode) {
1332      return i;
1333    }
1334  return -1;
1335}
1336CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) {
1337  const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
1338  if (!pSrc) {
1339    FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
1340  } else
1341    for (int i = 0; i < 256; i++) {
1342      m_Unicodes[i] = pSrc[i];
1343    }
1344}
1345FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const {
1346  return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) ==
1347         0;
1348}
1349CPDF_Object* CPDF_FontEncoding::Realize() {
1350  int predefined = 0;
1351  for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS;
1352       cs++) {
1353    const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
1354    FX_BOOL match = TRUE;
1355    for (int i = 0; i < 256; ++i) {
1356      if (m_Unicodes[i] != pSrc[i]) {
1357        match = FALSE;
1358        break;
1359      }
1360    }
1361    if (match) {
1362      predefined = cs;
1363      break;
1364    }
1365  }
1366  if (predefined) {
1367    if (predefined == PDFFONT_ENCODING_WINANSI) {
1368      return new CPDF_Name("WinAnsiEncoding");
1369    }
1370    if (predefined == PDFFONT_ENCODING_MACROMAN) {
1371      return new CPDF_Name("MacRomanEncoding");
1372    }
1373    if (predefined == PDFFONT_ENCODING_MACEXPERT) {
1374      return new CPDF_Name("MacExpertEncoding");
1375    }
1376    return NULL;
1377  }
1378  const FX_WORD* pStandard =
1379      PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
1380  CPDF_Array* pDiff = new CPDF_Array;
1381  for (int i = 0; i < 256; i++) {
1382    if (pStandard[i] == m_Unicodes[i]) {
1383      continue;
1384    }
1385    pDiff->Add(new CPDF_Number(i));
1386    pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
1387  }
1388
1389  CPDF_Dictionary* pDict = new CPDF_Dictionary;
1390  pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
1391  pDict->SetAt("Differences", pDiff);
1392  return pDict;
1393}
1394CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE) {}
1395FX_BOOL CPDF_TrueTypeFont::_Load() {
1396  return LoadCommon();
1397}
1398void CPDF_TrueTypeFont::LoadGlyphMap() {
1399  if (!m_Font.GetFace())
1400    return;
1401
1402  int baseEncoding = m_BaseEncoding;
1403  if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 &&
1404      (baseEncoding == PDFFONT_ENCODING_MACROMAN ||
1405       baseEncoding == PDFFONT_ENCODING_WINANSI) &&
1406      (m_Flags & PDFFONT_SYMBOLIC)) {
1407    FX_BOOL bSupportWin = FALSE;
1408    FX_BOOL bSupportMac = FALSE;
1409    for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) {
1410      int platform_id = FXFT_Get_Charmap_PlatformID(
1411          FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]);
1412      if (platform_id == 0 || platform_id == 3) {
1413        bSupportWin = TRUE;
1414      } else if (platform_id == 0 || platform_id == 1) {
1415        bSupportMac = TRUE;
1416      }
1417    }
1418    if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
1419      baseEncoding =
1420          bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
1421    } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
1422      baseEncoding =
1423          bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
1424    }
1425  }
1426  if (((baseEncoding == PDFFONT_ENCODING_MACROMAN ||
1427        baseEncoding == PDFFONT_ENCODING_WINANSI) &&
1428       !m_pCharNames) ||
1429      (m_Flags & PDFFONT_NONSYMBOLIC)) {
1430    if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) &&
1431        (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) {
1432      int nStartChar = m_pFontDict->GetInteger("FirstChar");
1433      if (nStartChar < 0 || nStartChar > 255)
1434        return;
1435
1436      int charcode = 0;
1437      for (; charcode < nStartChar; charcode++) {
1438        m_GlyphIndex[charcode] = 0;
1439      }
1440      FX_WORD nGlyph = charcode - nStartChar + 3;
1441      for (; charcode < 256; charcode++, nGlyph++) {
1442        m_GlyphIndex[charcode] = nGlyph;
1443      }
1444      return;
1445    }
1446    FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
1447    FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;
1448    if (!bMSUnicode) {
1449      if (m_Flags & PDFFONT_NONSYMBOLIC) {
1450        bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
1451        bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
1452      } else {
1453        bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
1454        bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
1455      }
1456    }
1457    FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode");
1458    for (int charcode = 0; charcode < 256; charcode++) {
1459      const FX_CHAR* name =
1460          GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
1461      if (!name) {
1462        m_GlyphIndex[charcode] =
1463            m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1;
1464        continue;
1465      }
1466      m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1467      if (bMSSymbol) {
1468        const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1469        for (int j = 0; j < 4; j++) {
1470          FX_WORD unicode = prefix[j] * 256 + charcode;
1471          m_GlyphIndex[charcode] =
1472              FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
1473          if (m_GlyphIndex[charcode]) {
1474            break;
1475          }
1476        }
1477      } else if (m_Encoding.m_Unicodes[charcode]) {
1478        if (bMSUnicode) {
1479          m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1480              m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
1481        } else if (bMacRoman) {
1482          FX_DWORD maccode = FT_CharCodeFromUnicode(
1483              FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
1484          if (!maccode) {
1485            m_GlyphIndex[charcode] =
1486                FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1487          } else {
1488            m_GlyphIndex[charcode] =
1489                FXFT_Get_Char_Index(m_Font.GetFace(), maccode);
1490          }
1491        }
1492      }
1493      if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) &&
1494          name) {
1495        if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
1496          m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32);
1497        } else {
1498          m_GlyphIndex[charcode] =
1499              FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1500          if (m_GlyphIndex[charcode] == 0) {
1501            if (bToUnicode) {
1502              CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
1503              if (!wsUnicode.IsEmpty()) {
1504                m_GlyphIndex[charcode] =
1505                    FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]);
1506                m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
1507              }
1508            }
1509            if (m_GlyphIndex[charcode] == 0) {
1510              m_GlyphIndex[charcode] =
1511                  FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1512            }
1513          }
1514        }
1515      }
1516    }
1517    return;
1518  }
1519  if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
1520    const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1521    FX_BOOL bGotOne = FALSE;
1522    for (int charcode = 0; charcode < 256; charcode++) {
1523      for (int j = 0; j < 4; j++) {
1524        FX_WORD unicode = prefix[j] * 256 + charcode;
1525        m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
1526        if (m_GlyphIndex[charcode]) {
1527          bGotOne = TRUE;
1528          break;
1529        }
1530      }
1531    }
1532    if (bGotOne) {
1533      if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
1534        for (int charcode = 0; charcode < 256; charcode++) {
1535          const FX_CHAR* name =
1536              GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
1537          if (!name) {
1538            continue;
1539          }
1540          m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1541        }
1542      } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
1543        for (int charcode = 0; charcode < 256; charcode++) {
1544          m_Encoding.m_Unicodes[charcode] =
1545              FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
1546        }
1547      }
1548      return;
1549    }
1550  }
1551  if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
1552    FX_BOOL bGotOne = FALSE;
1553    for (int charcode = 0; charcode < 256; charcode++) {
1554      m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1555      m_Encoding.m_Unicodes[charcode] =
1556          FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
1557      if (m_GlyphIndex[charcode]) {
1558        bGotOne = TRUE;
1559      }
1560    }
1561    if (m_pFontFile || bGotOne) {
1562      return;
1563    }
1564  }
1565  if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
1566    FX_BOOL bGotOne = FALSE;
1567    const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
1568    for (int charcode = 0; charcode < 256; charcode++) {
1569      if (m_pFontFile) {
1570        m_Encoding.m_Unicodes[charcode] = charcode;
1571      } else {
1572        const FX_CHAR* name = GetAdobeCharName(0, m_pCharNames, charcode);
1573        if (name) {
1574          m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1575        } else if (pUnicodes) {
1576          m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
1577        }
1578      }
1579      m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1580          m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
1581      if (m_GlyphIndex[charcode]) {
1582        bGotOne = TRUE;
1583      }
1584    }
1585    if (bGotOne) {
1586      return;
1587    }
1588  }
1589  for (int charcode = 0; charcode < 256; charcode++) {
1590    m_GlyphIndex[charcode] = charcode;
1591  }
1592}
1593
1594CPDF_Type3Font::CPDF_Type3Font()
1595    : CPDF_SimpleFont(PDFFONT_TYPE3),
1596      m_pCharProcs(nullptr),
1597      m_pPageResources(nullptr),
1598      m_pFontResources(nullptr) {
1599  FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
1600}
1601
1602CPDF_Type3Font::~CPDF_Type3Font() {
1603  for (auto it : m_CacheMap)
1604    delete it.second;
1605}
1606
1607FX_BOOL CPDF_Type3Font::_Load() {
1608  m_pFontResources = m_pFontDict->GetDict("Resources");
1609  CPDF_Array* pMatrix = m_pFontDict->GetArray("FontMatrix");
1610  FX_FLOAT xscale = 1.0f, yscale = 1.0f;
1611  if (pMatrix) {
1612    m_FontMatrix = pMatrix->GetMatrix();
1613    xscale = m_FontMatrix.a;
1614    yscale = m_FontMatrix.d;
1615  }
1616  CPDF_Array* pBBox = m_pFontDict->GetArray("FontBBox");
1617  if (pBBox) {
1618    m_FontBBox.left = (int32_t)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
1619    m_FontBBox.bottom =
1620        (int32_t)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
1621    m_FontBBox.right = (int32_t)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
1622    m_FontBBox.top = (int32_t)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000);
1623  }
1624  int StartChar = m_pFontDict->GetInteger("FirstChar");
1625  CPDF_Array* pWidthArray = m_pFontDict->GetArray("Widths");
1626  if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
1627    FX_DWORD count = pWidthArray->GetCount();
1628    if (count > 256) {
1629      count = 256;
1630    }
1631    if (StartChar + count > 256) {
1632      count = 256 - StartChar;
1633    }
1634    for (FX_DWORD i = 0; i < count; i++) {
1635      m_CharWidthL[StartChar + i] =
1636          FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000);
1637    }
1638  }
1639  m_pCharProcs = m_pFontDict->GetDict("CharProcs");
1640  CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
1641  if (pEncoding) {
1642    LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
1643    if (m_pCharNames) {
1644      for (int i = 0; i < 256; i++) {
1645        m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
1646        if (m_Encoding.m_Unicodes[i] == 0) {
1647          m_Encoding.m_Unicodes[i] = i;
1648        }
1649      }
1650    }
1651  }
1652  return TRUE;
1653}
1654void CPDF_Type3Font::CheckType3FontMetrics() {
1655  CheckFontMetrics();
1656}
1657
1658CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) {
1659  if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
1660    return nullptr;
1661
1662  auto it = m_CacheMap.find(charcode);
1663  if (it != m_CacheMap.end())
1664    return it->second;
1665
1666  const FX_CHAR* name =
1667      GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1668  if (!name)
1669    return nullptr;
1670
1671  CPDF_Stream* pStream =
1672      ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
1673  if (!pStream)
1674    return nullptr;
1675
1676  std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
1677      m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
1678      pStream, nullptr)));
1679
1680  // This can trigger recursion into this method. The content of |m_CacheMap|
1681  // can change as a result. Thus after it returns, check the cache again for
1682  // a cache hit.
1683  pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
1684                                  level + 1);
1685  it = m_CacheMap.find(charcode);
1686  if (it != m_CacheMap.end())
1687    return it->second;
1688
1689  FX_FLOAT scale = m_FontMatrix.GetXUnit();
1690  pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
1691  FX_RECT& rcBBox = pNewChar->m_BBox;
1692  CFX_FloatRect char_rect(
1693      (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
1694      (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
1695  if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
1696    char_rect = pNewChar->m_pForm->CalcBoundingBox();
1697
1698  char_rect.Transform(&m_FontMatrix);
1699  rcBBox.left = FXSYS_round(char_rect.left * 1000);
1700  rcBBox.right = FXSYS_round(char_rect.right * 1000);
1701  rcBBox.top = FXSYS_round(char_rect.top * 1000);
1702  rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
1703
1704  ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
1705  CPDF_Type3Char* pCachedChar = pNewChar.release();
1706  m_CacheMap[charcode] = pCachedChar;
1707  if (pCachedChar->m_pForm->CountObjects() == 0) {
1708    delete pCachedChar->m_pForm;
1709    pCachedChar->m_pForm = nullptr;
1710  }
1711  return pCachedChar;
1712}
1713
1714int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
1715  if (charcode >= FX_ArraySize(m_CharWidthL))
1716    charcode = 0;
1717
1718  if (m_CharWidthL[charcode])
1719    return m_CharWidthL[charcode];
1720
1721  const CPDF_Type3Char* pChar = LoadChar(charcode, level);
1722  return pChar ? pChar->m_Width : 0;
1723}
1724
1725void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) {
1726  const CPDF_Type3Char* pChar = LoadChar(charcode, level);
1727  if (!pChar) {
1728    rect.left = 0;
1729    rect.right = 0;
1730    rect.top = 0;
1731    rect.bottom = 0;
1732    return;
1733  }
1734  rect = pChar->m_BBox;
1735}
1736
1737CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
1738    : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
1739
1740CPDF_Type3Char::~CPDF_Type3Char() {
1741  delete m_pForm;
1742  delete m_pBitmap;
1743}
1744