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