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