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