OLD | NEW |
| (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 } | |
OLD | NEW |