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