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