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