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