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