• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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 "core/fpdfapi/font/cpdf_font.h"
8 
9 #include <memory>
10 #include <utility>
11 #include <vector>
12 
13 #include "core/fpdfapi/cpdf_modulemgr.h"
14 #include "core/fpdfapi/font/cpdf_fontencoding.h"
15 #include "core/fpdfapi/font/cpdf_truetypefont.h"
16 #include "core/fpdfapi/font/cpdf_type1font.h"
17 #include "core/fpdfapi/font/cpdf_type3font.h"
18 #include "core/fpdfapi/font/font_int.h"
19 #include "core/fpdfapi/page/cpdf_docpagedata.h"
20 #include "core/fpdfapi/page/cpdf_pagemodule.h"
21 #include "core/fpdfapi/parser/cpdf_array.h"
22 #include "core/fpdfapi/parser/cpdf_dictionary.h"
23 #include "core/fpdfapi/parser/cpdf_document.h"
24 #include "core/fpdfapi/parser/cpdf_name.h"
25 #include "core/fpdfapi/parser/cpdf_stream_acc.h"
26 #include "core/fxcrt/fx_memory.h"
27 #include "core/fxge/fx_freetype.h"
28 #include "third_party/base/ptr_util.h"
29 #include "third_party/base/stl_util.h"
30 
31 namespace {
32 
33 const uint8_t kChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
34                                         {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
35                                         {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
36                                         {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
37                                         {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
38 
GetPredefinedEncoding(const CFX_ByteString & value,int * basemap)39 void GetPredefinedEncoding(const CFX_ByteString& value, int* basemap) {
40   if (value == "WinAnsiEncoding")
41     *basemap = PDFFONT_ENCODING_WINANSI;
42   else if (value == "MacRomanEncoding")
43     *basemap = PDFFONT_ENCODING_MACROMAN;
44   else if (value == "MacExpertEncoding")
45     *basemap = PDFFONT_ENCODING_MACEXPERT;
46   else if (value == "PDFDocEncoding")
47     *basemap = PDFFONT_ENCODING_PDFDOC;
48 }
49 
50 }  // namespace
51 
CPDF_Font()52 CPDF_Font::CPDF_Font()
53     : m_pFontFile(nullptr),
54       m_pFontDict(nullptr),
55       m_bToUnicodeLoaded(false),
56       m_Flags(0),
57       m_StemV(0),
58       m_Ascent(0),
59       m_Descent(0),
60       m_ItalicAngle(0) {}
61 
~CPDF_Font()62 CPDF_Font::~CPDF_Font() {
63   if (m_pFontFile) {
64     m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
65         m_pFontFile->GetStream()->AsStream());
66   }
67 }
68 
IsType1Font() const69 bool CPDF_Font::IsType1Font() const {
70   return false;
71 }
72 
IsTrueTypeFont() const73 bool CPDF_Font::IsTrueTypeFont() const {
74   return false;
75 }
76 
IsType3Font() const77 bool CPDF_Font::IsType3Font() const {
78   return false;
79 }
80 
IsCIDFont() const81 bool CPDF_Font::IsCIDFont() const {
82   return false;
83 }
84 
AsType1Font() const85 const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
86   return nullptr;
87 }
88 
AsType1Font()89 CPDF_Type1Font* CPDF_Font::AsType1Font() {
90   return nullptr;
91 }
92 
AsTrueTypeFont() const93 const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
94   return nullptr;
95 }
96 
AsTrueTypeFont()97 CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
98   return nullptr;
99 }
100 
AsType3Font() const101 const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
102   return nullptr;
103 }
104 
AsType3Font()105 CPDF_Type3Font* CPDF_Font::AsType3Font() {
106   return nullptr;
107 }
108 
AsCIDFont() const109 const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
110   return nullptr;
111 }
112 
AsCIDFont()113 CPDF_CIDFont* CPDF_Font::AsCIDFont() {
114   return nullptr;
115 }
116 
IsUnicodeCompatible() const117 bool CPDF_Font::IsUnicodeCompatible() const {
118   return false;
119 }
120 
CountChar(const FX_CHAR * pString,int size) const121 int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
122   return size;
123 }
124 
GlyphFromCharCodeExt(uint32_t charcode)125 int CPDF_Font::GlyphFromCharCodeExt(uint32_t charcode) {
126   return GlyphFromCharCode(charcode, nullptr);
127 }
128 
IsVertWriting() const129 bool CPDF_Font::IsVertWriting() const {
130   const CPDF_CIDFont* pCIDFont = AsCIDFont();
131   return pCIDFont ? pCIDFont->IsVertWriting() : m_Font.IsVertical();
132 }
133 
AppendChar(FX_CHAR * buf,uint32_t charcode) const134 int CPDF_Font::AppendChar(FX_CHAR* buf, uint32_t charcode) const {
135   *buf = static_cast<FX_CHAR>(charcode);
136   return 1;
137 }
138 
AppendChar(CFX_ByteString & str,uint32_t charcode) const139 void CPDF_Font::AppendChar(CFX_ByteString& str, uint32_t charcode) const {
140   char buf[4];
141   int len = AppendChar(buf, charcode);
142   if (len == 1) {
143     str += buf[0];
144   } else {
145     str += CFX_ByteString(buf, len);
146   }
147 }
148 
UnicodeFromCharCode(uint32_t charcode) const149 CFX_WideString CPDF_Font::UnicodeFromCharCode(uint32_t charcode) const {
150   if (!m_bToUnicodeLoaded)
151     LoadUnicodeMap();
152 
153   return m_pToUnicodeMap ? m_pToUnicodeMap->Lookup(charcode) : CFX_WideString();
154 }
155 
CharCodeFromUnicode(FX_WCHAR unicode) const156 uint32_t CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
157   if (!m_bToUnicodeLoaded)
158     LoadUnicodeMap();
159 
160   return m_pToUnicodeMap ? m_pToUnicodeMap->ReverseLookup(unicode) : 0;
161 }
162 
LoadFontDescriptor(CPDF_Dictionary * pFontDesc)163 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
164   m_Flags = pFontDesc->GetIntegerFor("Flags", FXFONT_NONSYMBOLIC);
165   int ItalicAngle = 0;
166   bool bExistItalicAngle = false;
167   if (pFontDesc->KeyExist("ItalicAngle")) {
168     ItalicAngle = pFontDesc->GetIntegerFor("ItalicAngle");
169     bExistItalicAngle = true;
170   }
171   if (ItalicAngle < 0) {
172     m_Flags |= FXFONT_ITALIC;
173     m_ItalicAngle = ItalicAngle;
174   }
175   bool bExistStemV = false;
176   if (pFontDesc->KeyExist("StemV")) {
177     m_StemV = pFontDesc->GetIntegerFor("StemV");
178     bExistStemV = true;
179   }
180   bool bExistAscent = false;
181   if (pFontDesc->KeyExist("Ascent")) {
182     m_Ascent = pFontDesc->GetIntegerFor("Ascent");
183     bExistAscent = true;
184   }
185   bool bExistDescent = false;
186   if (pFontDesc->KeyExist("Descent")) {
187     m_Descent = pFontDesc->GetIntegerFor("Descent");
188     bExistDescent = true;
189   }
190   bool bExistCapHeight = false;
191   if (pFontDesc->KeyExist("CapHeight"))
192     bExistCapHeight = true;
193   if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
194       bExistStemV) {
195     m_Flags |= FXFONT_USEEXTERNATTR;
196   }
197   if (m_Descent > 10)
198     m_Descent = -m_Descent;
199   CPDF_Array* pBBox = pFontDesc->GetArrayFor("FontBBox");
200   if (pBBox) {
201     m_FontBBox.left = pBBox->GetIntegerAt(0);
202     m_FontBBox.bottom = pBBox->GetIntegerAt(1);
203     m_FontBBox.right = pBBox->GetIntegerAt(2);
204     m_FontBBox.top = pBBox->GetIntegerAt(3);
205   }
206 
207   CPDF_Stream* pFontFile = pFontDesc->GetStreamFor("FontFile");
208   if (!pFontFile)
209     pFontFile = pFontDesc->GetStreamFor("FontFile2");
210   if (!pFontFile)
211     pFontFile = pFontDesc->GetStreamFor("FontFile3");
212   if (!pFontFile)
213     return;
214 
215   m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
216   if (!m_pFontFile)
217     return;
218 
219   const uint8_t* pFontData = m_pFontFile->GetData();
220   uint32_t dwFontSize = m_pFontFile->GetSize();
221   if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
222     m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
223         m_pFontFile->GetStream()->AsStream());
224     m_pFontFile = nullptr;
225   }
226 }
227 
CheckFontMetrics()228 void CPDF_Font::CheckFontMetrics() {
229   if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
230       m_FontBBox.right == 0) {
231     FXFT_Face face = m_Font.GetFace();
232     if (face) {
233       m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
234       m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
235       m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
236       m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
237       m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
238       m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
239     } else {
240       bool bFirst = true;
241       for (int i = 0; i < 256; i++) {
242         FX_RECT rect = GetCharBBox(i);
243         if (rect.left == rect.right) {
244           continue;
245         }
246         if (bFirst) {
247           m_FontBBox = rect;
248           bFirst = false;
249         } else {
250           if (m_FontBBox.top < rect.top) {
251             m_FontBBox.top = rect.top;
252           }
253           if (m_FontBBox.right < rect.right) {
254             m_FontBBox.right = rect.right;
255           }
256           if (m_FontBBox.left > rect.left) {
257             m_FontBBox.left = rect.left;
258           }
259           if (m_FontBBox.bottom > rect.bottom) {
260             m_FontBBox.bottom = rect.bottom;
261           }
262         }
263       }
264     }
265   }
266   if (m_Ascent == 0 && m_Descent == 0) {
267     FX_RECT rect = GetCharBBox('A');
268     m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
269     rect = GetCharBBox('g');
270     m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
271   }
272 }
273 
LoadUnicodeMap() const274 void CPDF_Font::LoadUnicodeMap() const {
275   m_bToUnicodeLoaded = true;
276   CPDF_Stream* pStream = m_pFontDict->GetStreamFor("ToUnicode");
277   if (!pStream) {
278     return;
279   }
280   m_pToUnicodeMap = pdfium::MakeUnique<CPDF_ToUnicodeMap>();
281   m_pToUnicodeMap->Load(pStream);
282 }
283 
GetStringWidth(const FX_CHAR * pString,int size)284 int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
285   int offset = 0;
286   int width = 0;
287   while (offset < size) {
288     uint32_t charcode = GetNextChar(pString, size, offset);
289     width += GetCharWidthF(charcode);
290   }
291   return width;
292 }
293 
GetStockFont(CPDF_Document * pDoc,const CFX_ByteStringC & name)294 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
295                                    const CFX_ByteStringC& name) {
296   CFX_ByteString fontname(name);
297   int font_id = PDF_GetStandardFontName(&fontname);
298   if (font_id < 0)
299     return nullptr;
300 
301   CPDF_FontGlobals* pFontGlobals =
302       CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
303   CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
304   if (pFont)
305     return pFont;
306 
307   CPDF_Dictionary* pDict = new CPDF_Dictionary(pDoc->GetByteStringPool());
308   pDict->SetNewFor<CPDF_Name>("Type", "Font");
309   pDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
310   pDict->SetNewFor<CPDF_Name>("BaseFont", fontname);
311   pDict->SetNewFor<CPDF_Name>("Encoding", "WinAnsiEncoding");
312   return pFontGlobals->Set(pDoc, font_id, CPDF_Font::Create(nullptr, pDict));
313 }
314 
Create(CPDF_Document * pDoc,CPDF_Dictionary * pFontDict)315 std::unique_ptr<CPDF_Font> CPDF_Font::Create(CPDF_Document* pDoc,
316                                              CPDF_Dictionary* pFontDict) {
317   CFX_ByteString type = pFontDict->GetStringFor("Subtype");
318   std::unique_ptr<CPDF_Font> pFont;
319   if (type == "TrueType") {
320     CFX_ByteString tag = pFontDict->GetStringFor("BaseFont").Left(4);
321     for (size_t i = 0; i < FX_ArraySize(kChineseFontNames); ++i) {
322       if (tag == CFX_ByteString(kChineseFontNames[i], 4)) {
323         CPDF_Dictionary* pFontDesc = pFontDict->GetDictFor("FontDescriptor");
324         if (!pFontDesc || !pFontDesc->KeyExist("FontFile2"))
325           pFont = pdfium::MakeUnique<CPDF_CIDFont>();
326         break;
327       }
328     }
329     if (!pFont)
330       pFont = pdfium::MakeUnique<CPDF_TrueTypeFont>();
331   } else if (type == "Type3") {
332     pFont = pdfium::MakeUnique<CPDF_Type3Font>();
333   } else if (type == "Type0") {
334     pFont = pdfium::MakeUnique<CPDF_CIDFont>();
335   } else {
336     pFont = pdfium::MakeUnique<CPDF_Type1Font>();
337   }
338   pFont->m_pFontDict = pFontDict;
339   pFont->m_pDocument = pDoc;
340   pFont->m_BaseFont = pFontDict->GetStringFor("BaseFont");
341   return pFont->Load() ? std::move(pFont) : nullptr;
342 }
343 
GetNextChar(const FX_CHAR * pString,int nStrLen,int & offset) const344 uint32_t CPDF_Font::GetNextChar(const FX_CHAR* pString,
345                                 int nStrLen,
346                                 int& offset) const {
347   if (offset < 0 || nStrLen < 1) {
348     return 0;
349   }
350   uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
351   return static_cast<uint32_t>(ch);
352 }
353 
LoadPDFEncoding(CPDF_Object * pEncoding,int & iBaseEncoding,std::vector<CFX_ByteString> * pCharNames,bool bEmbedded,bool bTrueType)354 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
355                                 int& iBaseEncoding,
356                                 std::vector<CFX_ByteString>* pCharNames,
357                                 bool bEmbedded,
358                                 bool bTrueType) {
359   if (!pEncoding) {
360     if (m_BaseFont == "Symbol") {
361       iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
362                                 : PDFFONT_ENCODING_ADOBE_SYMBOL;
363     } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
364       iBaseEncoding = PDFFONT_ENCODING_WINANSI;
365     }
366     return;
367   }
368   if (pEncoding->IsName()) {
369     if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
370         iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
371       return;
372     }
373     if ((m_Flags & FXFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
374       if (!bTrueType)
375         iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
376       return;
377     }
378     CFX_ByteString bsEncoding = pEncoding->GetString();
379     if (bsEncoding.Compare("MacExpertEncoding") == 0) {
380       bsEncoding = "WinAnsiEncoding";
381     }
382     GetPredefinedEncoding(bsEncoding, &iBaseEncoding);
383     return;
384   }
385 
386   CPDF_Dictionary* pDict = pEncoding->AsDictionary();
387   if (!pDict)
388     return;
389 
390   if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
391       iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
392     CFX_ByteString bsEncoding = pDict->GetStringFor("BaseEncoding");
393     if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
394       bsEncoding = "WinAnsiEncoding";
395     }
396     GetPredefinedEncoding(bsEncoding, &iBaseEncoding);
397   }
398   if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN)
399     iBaseEncoding = PDFFONT_ENCODING_STANDARD;
400 
401   CPDF_Array* pDiffs = pDict->GetArrayFor("Differences");
402   if (!pDiffs)
403     return;
404 
405   pCharNames->resize(256);
406   uint32_t cur_code = 0;
407   for (uint32_t i = 0; i < pDiffs->GetCount(); i++) {
408     CPDF_Object* pElement = pDiffs->GetDirectObjectAt(i);
409     if (!pElement)
410       continue;
411 
412     if (CPDF_Name* pName = pElement->AsName()) {
413       if (cur_code < 256)
414         (*pCharNames)[cur_code] = pName->GetString();
415       cur_code++;
416     } else {
417       cur_code = pElement->GetInteger();
418     }
419   }
420 }
421 
IsStandardFont() const422 bool CPDF_Font::IsStandardFont() const {
423   if (!IsType1Font())
424     return false;
425   if (m_pFontFile)
426     return false;
427   if (AsType1Font()->GetBase14Font() < 0)
428     return false;
429   return true;
430 }
431 
GetAdobeCharName(int iBaseEncoding,const std::vector<CFX_ByteString> & charnames,int charcode)432 const FX_CHAR* CPDF_Font::GetAdobeCharName(
433     int iBaseEncoding,
434     const std::vector<CFX_ByteString>& charnames,
435     int charcode) {
436   if (charcode < 0 || charcode >= 256) {
437     ASSERT(false);
438     return nullptr;
439   }
440 
441   if (!charnames.empty() && !charnames[charcode].IsEmpty())
442     return charnames[charcode].c_str();
443 
444   const FX_CHAR* name = nullptr;
445   if (iBaseEncoding)
446     name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
447   return name && name[0] ? name : nullptr;
448 }
449 
FallbackFontFromCharcode(uint32_t charcode)450 uint32_t CPDF_Font::FallbackFontFromCharcode(uint32_t charcode) {
451   if (m_FontFallbacks.empty()) {
452     m_FontFallbacks.push_back(pdfium::MakeUnique<CFX_Font>());
453     m_FontFallbacks[0]->LoadSubst("Arial", IsTrueTypeFont(), m_Flags,
454                                   m_StemV * 5, m_ItalicAngle, 0,
455                                   IsVertWriting());
456   }
457   return 0;
458 }
459 
FallbackGlyphFromCharcode(int fallbackFont,uint32_t charcode)460 int CPDF_Font::FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode) {
461   if (fallbackFont < 0 ||
462       fallbackFont >= pdfium::CollectionSize<int>(m_FontFallbacks)) {
463     return -1;
464   }
465   int glyph =
466       FXFT_Get_Char_Index(m_FontFallbacks[fallbackFont]->GetFace(), charcode);
467   if (glyph == 0 || glyph == 0xffff)
468     return -1;
469   return glyph;
470 }
471