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