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

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

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

Powered by Google App Engine
This is Rietveld 408576698