Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(627)

Side by Side Diff: core/fpdfapi/fpdf_font/cpdf_font.cpp

Issue 2392773003: Move core/fpdfapi/fpdf_font to core/fpdfapi/font (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/fpdf_font/cpdf_font.h ('k') | core/fpdfapi/fpdf_font/cpdf_fontencoding.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_font/cpdf_font.h ('k') | core/fpdfapi/fpdf_font/cpdf_fontencoding.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698