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