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