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