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