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