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