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