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