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

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

Issue 1824033002: Split core/include/fpdfapi/fpdf_resource.h (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 9 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_cidfont.cpp ('k') | core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp » ('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/include/cpdf_font.h"
8
9 #include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h"
10 #include "core/fpdfapi/fpdf_font/cpdf_type1font.h"
11 #include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
12 #include "core/fpdfapi/fpdf_font/font_int.h"
13 #include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
14 #include "core/fpdfapi/fpdf_page/pageint.h"
15 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
17 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
18 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
19 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
20 #include "core/fpdfapi/include/cpdf_modulemgr.h"
21 #include "core/include/fxge/fx_freetype.h"
22
23 namespace {
24
25 const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
26 {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
27 {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
28 {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
29 {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
30
31 FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
32 if (value == "WinAnsiEncoding")
33 basemap = PDFFONT_ENCODING_WINANSI;
34 else if (value == "MacRomanEncoding")
35 basemap = PDFFONT_ENCODING_MACROMAN;
36 else if (value == "MacExpertEncoding")
37 basemap = PDFFONT_ENCODING_MACEXPERT;
38 else if (value == "PDFDocEncoding")
39 basemap = PDFFONT_ENCODING_PDFDOC;
40 else
41 return FALSE;
42 return TRUE;
43 }
44
45 } // namespace
46
47 CPDF_Font::CPDF_Font()
48 : m_pFontFile(nullptr),
49 m_pFontDict(nullptr),
50 m_pToUnicodeMap(nullptr),
51 m_bToUnicodeLoaded(FALSE),
52 m_Flags(0),
53 m_StemV(0),
54 m_Ascent(0),
55 m_Descent(0),
56 m_ItalicAngle(0) {}
57
58 CPDF_Font::~CPDF_Font() {
59 delete m_pToUnicodeMap;
60 m_pToUnicodeMap = NULL;
61
62 if (m_pFontFile) {
63 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
64 const_cast<CPDF_Stream*>(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 FX_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(FX_DWORD charcode) const {
125 return 1;
126 }
127
128 int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
129 ASSERT(false);
130 return 0;
131 }
132
133 int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
134 return GlyphFromCharCode(charcode);
135 }
136
137 FX_BOOL CPDF_Font::IsVertWriting() const {
138 FX_BOOL bVertWriting = FALSE;
139 const CPDF_CIDFont* pCIDFont = AsCIDFont();
140 if (pCIDFont) {
141 bVertWriting = pCIDFont->IsVertWriting();
142 } else {
143 bVertWriting = m_Font.IsVertical();
144 }
145 return bVertWriting;
146 }
147
148 int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
149 *buf = (FX_CHAR)charcode;
150 return 1;
151 }
152
153 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const {
154 char buf[4];
155 int len = AppendChar(buf, charcode);
156 if (len == 1) {
157 str += buf[0];
158 } else {
159 str += CFX_ByteString(buf, len);
160 }
161 }
162
163 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const {
164 if (!m_bToUnicodeLoaded)
165 ((CPDF_Font*)this)->LoadUnicodeMap();
166
167 if (m_pToUnicodeMap)
168 return m_pToUnicodeMap->Lookup(charcode);
169 return CFX_WideString();
170 }
171
172 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
173 if (!m_bToUnicodeLoaded)
174 ((CPDF_Font*)this)->LoadUnicodeMap();
175
176 if (m_pToUnicodeMap)
177 return m_pToUnicodeMap->ReverseLookup(unicode);
178 return 0;
179 }
180
181 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
182 m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
183 int ItalicAngle = 0;
184 FX_BOOL bExistItalicAngle = FALSE;
185 if (pFontDesc->KeyExist("ItalicAngle")) {
186 ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
187 bExistItalicAngle = TRUE;
188 }
189 if (ItalicAngle < 0) {
190 m_Flags |= PDFFONT_ITALIC;
191 m_ItalicAngle = ItalicAngle;
192 }
193 FX_BOOL bExistStemV = FALSE;
194 if (pFontDesc->KeyExist("StemV")) {
195 m_StemV = pFontDesc->GetIntegerBy("StemV");
196 bExistStemV = TRUE;
197 }
198 FX_BOOL bExistAscent = FALSE;
199 if (pFontDesc->KeyExist("Ascent")) {
200 m_Ascent = pFontDesc->GetIntegerBy("Ascent");
201 bExistAscent = TRUE;
202 }
203 FX_BOOL bExistDescent = FALSE;
204 if (pFontDesc->KeyExist("Descent")) {
205 m_Descent = pFontDesc->GetIntegerBy("Descent");
206 bExistDescent = TRUE;
207 }
208 FX_BOOL bExistCapHeight = FALSE;
209 if (pFontDesc->KeyExist("CapHeight")) {
210 bExistCapHeight = TRUE;
211 }
212 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
213 bExistStemV) {
214 m_Flags |= PDFFONT_USEEXTERNATTR;
215 }
216 if (m_Descent > 10) {
217 m_Descent = -m_Descent;
218 }
219 CPDF_Array* pBBox = pFontDesc->GetArrayBy("FontBBox");
220 if (pBBox) {
221 m_FontBBox.left = pBBox->GetIntegerAt(0);
222 m_FontBBox.bottom = pBBox->GetIntegerAt(1);
223 m_FontBBox.right = pBBox->GetIntegerAt(2);
224 m_FontBBox.top = pBBox->GetIntegerAt(3);
225 }
226
227 CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile");
228 if (!pFontFile)
229 pFontFile = pFontDesc->GetStreamBy("FontFile2");
230 if (!pFontFile)
231 pFontFile = pFontDesc->GetStreamBy("FontFile3");
232 if (!pFontFile)
233 return;
234
235 m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
236 if (!m_pFontFile)
237 return;
238
239 const uint8_t* pFontData = m_pFontFile->GetData();
240 FX_DWORD dwFontSize = m_pFontFile->GetSize();
241 if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
242 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
243 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
244 m_pFontFile = nullptr;
245 }
246 }
247
248 void CPDF_Font::CheckFontMetrics() {
249 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
250 m_FontBBox.right == 0) {
251 FXFT_Face face = m_Font.GetFace();
252 if (face) {
253 m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
254 m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
255 m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
256 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
257 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
258 m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
259 } else {
260 FX_BOOL bFirst = TRUE;
261 for (int i = 0; i < 256; i++) {
262 FX_RECT rect = GetCharBBox(i);
263 if (rect.left == rect.right) {
264 continue;
265 }
266 if (bFirst) {
267 m_FontBBox = rect;
268 bFirst = FALSE;
269 } else {
270 if (m_FontBBox.top < rect.top) {
271 m_FontBBox.top = rect.top;
272 }
273 if (m_FontBBox.right < rect.right) {
274 m_FontBBox.right = rect.right;
275 }
276 if (m_FontBBox.left > rect.left) {
277 m_FontBBox.left = rect.left;
278 }
279 if (m_FontBBox.bottom > rect.bottom) {
280 m_FontBBox.bottom = rect.bottom;
281 }
282 }
283 }
284 }
285 }
286 if (m_Ascent == 0 && m_Descent == 0) {
287 FX_RECT rect = GetCharBBox('A');
288 m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
289 rect = GetCharBBox('g');
290 m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
291 }
292 }
293
294 void CPDF_Font::LoadUnicodeMap() {
295 m_bToUnicodeLoaded = TRUE;
296 CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
297 if (!pStream) {
298 return;
299 }
300 m_pToUnicodeMap = new CPDF_ToUnicodeMap;
301 m_pToUnicodeMap->Load(pStream);
302 }
303
304 int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
305 int offset = 0;
306 int width = 0;
307 while (offset < size) {
308 FX_DWORD charcode = GetNextChar(pString, size, offset);
309 width += GetCharWidthF(charcode);
310 }
311 return width;
312 }
313
314 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
315 const CFX_ByteStringC& name) {
316 CFX_ByteString fontname(name);
317 int font_id = PDF_GetStandardFontName(&fontname);
318 if (font_id < 0) {
319 return nullptr;
320 }
321 CPDF_FontGlobals* pFontGlobals =
322 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
323 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
324 if (pFont) {
325 return pFont;
326 }
327 CPDF_Dictionary* pDict = new CPDF_Dictionary;
328 pDict->SetAtName("Type", "Font");
329 pDict->SetAtName("Subtype", "Type1");
330 pDict->SetAtName("BaseFont", fontname);
331 pDict->SetAtName("Encoding", "WinAnsiEncoding");
332 pFont = CPDF_Font::CreateFontF(NULL, pDict);
333 pFontGlobals->Set(pDoc, font_id, pFont);
334 return pFont;
335 }
336
337 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
338 CPDF_Dictionary* pFontDict) {
339 CFX_ByteString type = pFontDict->GetStringBy("Subtype");
340 CPDF_Font* pFont;
341 if (type == "TrueType") {
342 {
343 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
344 _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
345 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
346 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
347 CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont");
348 CFX_ByteString tag = basefont.Left(4);
349 int i;
350 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
351 for (i = 0; i < count; ++i) {
352 if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
353 break;
354 }
355 }
356 if (i < count) {
357 CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
358 if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
359 pFont = new CPDF_CIDFont;
360 pFont->m_pFontDict = pFontDict;
361 pFont->m_pDocument = pDoc;
362 pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
363 if (!pFont->Load()) {
364 delete pFont;
365 return NULL;
366 }
367 return pFont;
368 }
369 }
370 #endif
371 }
372 pFont = new CPDF_TrueTypeFont;
373 } else if (type == "Type3") {
374 pFont = new CPDF_Type3Font;
375 } else if (type == "Type0") {
376 pFont = new CPDF_CIDFont;
377 } else {
378 pFont = new CPDF_Type1Font;
379 }
380 pFont->m_pFontDict = pFontDict;
381 pFont->m_pDocument = pDoc;
382 pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
383 if (!pFont->Load()) {
384 delete pFont;
385 return NULL;
386 }
387 return pFont;
388 }
389
390 FX_DWORD CPDF_Font::GetNextChar(const FX_CHAR* pString,
391 int nStrLen,
392 int& offset) const {
393 if (offset < 0 || nStrLen < 1) {
394 return 0;
395 }
396 uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
397 return static_cast<FX_DWORD>(ch);
398 }
399
400 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
401 int& iBaseEncoding,
402 CFX_ByteString*& pCharNames,
403 FX_BOOL bEmbedded,
404 FX_BOOL bTrueType) {
405 if (!pEncoding) {
406 if (m_BaseFont == "Symbol") {
407 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
408 : PDFFONT_ENCODING_ADOBE_SYMBOL;
409 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
410 iBaseEncoding = PDFFONT_ENCODING_WINANSI;
411 }
412 return;
413 }
414 if (pEncoding->IsName()) {
415 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
416 iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
417 return;
418 }
419 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
420 if (!bTrueType) {
421 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
422 }
423 return;
424 }
425 CFX_ByteString bsEncoding = pEncoding->GetString();
426 if (bsEncoding.Compare("MacExpertEncoding") == 0) {
427 bsEncoding = "WinAnsiEncoding";
428 }
429 GetPredefinedEncoding(iBaseEncoding, bsEncoding);
430 return;
431 }
432
433 CPDF_Dictionary* pDict = pEncoding->AsDictionary();
434 if (!pDict)
435 return;
436
437 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
438 iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
439 CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
440 if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
441 bsEncoding = "WinAnsiEncoding";
442 }
443 GetPredefinedEncoding(iBaseEncoding, bsEncoding);
444 }
445 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
446 iBaseEncoding = PDFFONT_ENCODING_STANDARD;
447 }
448 CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
449 if (!pDiffs) {
450 return;
451 }
452 pCharNames = new CFX_ByteString[256];
453 FX_DWORD cur_code = 0;
454 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
455 CPDF_Object* pElement = pDiffs->GetElementValue(i);
456 if (!pElement)
457 continue;
458
459 if (CPDF_Name* pName = pElement->AsName()) {
460 if (cur_code < 256)
461 pCharNames[cur_code] = pName->GetString();
462 cur_code++;
463 } else {
464 cur_code = pElement->GetInteger();
465 }
466 }
467 }
468
469 FX_BOOL CPDF_Font::IsStandardFont() const {
470 if (!IsType1Font())
471 return FALSE;
472 if (m_pFontFile)
473 return FALSE;
474 if (AsType1Font()->GetBase14Font() < 0)
475 return FALSE;
476 return TRUE;
477 }
478
479 const FX_CHAR* CPDF_Font::GetAdobeCharName(int iBaseEncoding,
480 const CFX_ByteString* pCharNames,
481 int charcode) {
482 ASSERT(charcode >= 0 && charcode < 256);
483 if (charcode < 0 || charcode >= 256)
484 return nullptr;
485
486 const FX_CHAR* name = nullptr;
487 if (pCharNames)
488 name = pCharNames[charcode];
489 if ((!name || name[0] == 0) && iBaseEncoding)
490 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
491 return name && name[0] ? name : nullptr;
492 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_font/cpdf_cidfont.cpp ('k') | core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698