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