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