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.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../../include/fpdfapi/fpdf_page.h"
8 #include "../../../include/fpdfapi/fpdf_module.h"
9 #include "../../../include/fpdfapi/fpdf_pageobj.h"
11 #include "../fpdf_page/pageint.h"
12 #include "../../../include/fxge/fx_freetype.h"
13 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id)
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]);
24 extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int);
25 CPDF_FontGlobals::CPDF_FontGlobals()
27 FXSYS_memset32(m_EmbeddedCharsets, 0, sizeof m_EmbeddedCharsets);
28 FXSYS_memset32(m_EmbeddedToUnicodes, 0, sizeof m_EmbeddedToUnicodes);
29 m_pContrastRamps = NULL;
31 CPDF_FontGlobals::~CPDF_FontGlobals()
34 if (m_pContrastRamps) {
35 FX_Free(m_pContrastRamps);
38 class CFX_StockFontArray
43 FXSYS_memset32(m_pStockFonts, 0, sizeof(CPDF_Font*) * 14);
45 CPDF_Font* m_pStockFonts[14];
47 CPDF_Font* CPDF_FontGlobals::Find(void* key, int index)
50 if (!m_pStockMap.Lookup(key, value)) {
56 return ((CFX_StockFontArray*)value)->m_pStockFonts[index];
58 void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont)
61 if (m_pStockMap.Lookup(key, value)) {
62 ((CFX_StockFontArray*)value)->m_pStockFonts[index] = pFont;
65 CFX_StockFontArray* pFonts = FX_NEW CFX_StockFontArray();
67 pFonts->m_pStockFonts[index] = pFont;
69 m_pStockMap.SetAt(key, pFonts);
71 void CPDF_FontGlobals::Clear(void* key)
74 if (!m_pStockMap.Lookup(key, value)) {
78 CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value;
79 for (int i = 0; i < 14; i ++) {
80 if (pStockFonts->m_pStockFonts[i]) {
81 CPDF_Dictionary* pFontDict = pStockFonts->m_pStockFonts[i]->GetFontDict();
84 delete pStockFonts->m_pStockFonts[i];
89 m_pStockMap.RemoveKey(key);
91 void CPDF_FontGlobals::ClearAll()
93 FX_POSITION pos = m_pStockMap.GetStartPosition();
97 m_pStockMap.GetNextAssoc(pos, key, value);
99 CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value;
100 for (int i = 0; i < 14; i ++) {
101 if (pStockFonts->m_pStockFonts[i]) {
102 CPDF_Dictionary* pFontDict = pStockFonts->m_pStockFonts[i]->GetFontDict();
104 pFontDict->Release();
105 delete pStockFonts->m_pStockFonts[i];
110 m_pStockMap.RemoveKey(key);
113 CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype)
115 m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0;
116 m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0;
119 m_pToUnicodeMap = NULL;
120 m_bToUnicodeLoaded = FALSE;
121 m_pCharMap = new CPDF_FontCharMap(this);
123 CPDF_Font::~CPDF_Font()
128 delete m_pToUnicodeMap;
129 m_pToUnicodeMap = NULL;
132 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc((CPDF_Stream*)m_pFontFile->GetStream());
135 FX_BOOL CPDF_Font::IsVertWriting() const
137 FX_BOOL bVertWriting = FALSE;
138 CPDF_CIDFont* pCIDFont = GetCIDFont();
140 bVertWriting = pCIDFont->IsVertWriting();
142 bVertWriting = m_Font.IsVertical();
146 CFX_ByteString CPDF_Font::GetFontTypeName() const
148 switch (m_FontType) {
150 return FX_BSTRC("Type1");
151 case PDFFONT_TRUETYPE:
152 return FX_BSTRC("TrueType");
154 return FX_BSTRC("Type3");
155 case PDFFONT_CIDFONT:
156 return FX_BSTRC("Type0");
158 return CFX_ByteString();
160 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const
163 int len = AppendChar(buf, charcode);
167 str += CFX_ByteString(buf, len);
170 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const
172 if (!m_bToUnicodeLoaded) {
173 ((CPDF_Font*)this)->LoadUnicodeMap();
175 if (m_pToUnicodeMap) {
176 CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode);
177 if (!wsRet.IsEmpty()) {
181 FX_WCHAR unicode = _UnicodeFromCharCode(charcode);
183 return CFX_WideString();
187 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const
189 if (!m_bToUnicodeLoaded) {
190 ((CPDF_Font*)this)->LoadUnicodeMap();
192 if (m_pToUnicodeMap) {
193 FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode);
198 return _CharCodeFromUnicode(unicode);
200 CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const
202 CFX_WideString result;
203 int src_len = str.GetLength();
204 result.Reserve(src_len);
205 FX_LPCSTR src_buf = str;
207 while (src_pos < src_len) {
208 FX_DWORD charcode = GetNextChar(src_buf, src_len, src_pos);
209 CFX_WideString unicode = UnicodeFromCharCode(charcode);
210 if (!unicode.IsEmpty()) {
213 result += (FX_WCHAR)charcode;
218 CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const
220 CFX_ByteString result;
221 int src_len = str.GetLength();
222 FX_LPSTR dest_buf = result.GetBuffer(src_len * 2);
223 FX_LPCWSTR src_buf = str.c_str();
225 for (int src_pos = 0; src_pos < src_len; src_pos ++) {
226 FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]);
227 dest_pos += AppendChar(dest_buf + dest_pos, charcode);
229 result.ReleaseBuffer(dest_pos);
232 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc)
234 m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC);
236 FX_BOOL bExistItalicAngle = FALSE;
237 if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) {
238 ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle"));
239 bExistItalicAngle = TRUE;
241 if (ItalicAngle < 0) {
242 m_Flags |= PDFFONT_ITALIC;
243 m_ItalicAngle = ItalicAngle;
245 FX_BOOL bExistStemV = FALSE;
246 if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) {
247 m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV"));
250 FX_BOOL bExistAscent = FALSE;
251 if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) {
252 m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent"));
255 FX_BOOL bExistDescent = FALSE;
256 if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) {
257 m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent"));
258 bExistDescent = TRUE;
260 FX_BOOL bExistCapHeight = FALSE;
261 if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) {
262 bExistCapHeight = TRUE;
264 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && bExistStemV) {
265 m_Flags |= PDFFONT_USEEXTERNATTR;
267 if (m_Descent > 10) {
268 m_Descent = -m_Descent;
270 CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox"));
272 m_FontBBox.left = pBBox->GetInteger(0);
273 m_FontBBox.bottom = pBBox->GetInteger(1);
274 m_FontBBox.right = pBBox->GetInteger(2);
275 m_FontBBox.top = pBBox->GetInteger(3);
277 CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile"));
278 if (pFontFile == NULL) {
279 pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2"));
281 if (pFontFile == NULL) {
282 pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3"));
285 m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
286 if (m_pFontFile == NULL) {
289 FX_LPCBYTE pFontData = m_pFontFile->GetData();
290 FX_DWORD dwFontSize = m_pFontFile->GetSize();
291 m_Font.LoadEmbedded(pFontData, dwFontSize);
292 if (m_Font.m_Face == NULL) {
297 short TT2PDF(int m, FXFT_Face face)
299 int upm = FXFT_Get_Face_UnitsPerEM(face);
303 return (m * 1000 + upm / 2) / upm;
305 void CPDF_Font::CheckFontMetrics()
307 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && m_FontBBox.right == 0) {
309 m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m_Face);
310 m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font.m_Face);
311 m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.m_Face);
312 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_Face);
313 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Face);
314 m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_Face);
316 FX_BOOL bFirst = TRUE;
317 for (int i = 0; i < 256; i ++) {
319 GetCharBBox(i, rect);
320 if (rect.left == rect.right) {
327 if (m_FontBBox.top < rect.top) {
328 m_FontBBox.top = rect.top;
330 if (m_FontBBox.right < rect.right) {
331 m_FontBBox.right = rect.right;
333 if (m_FontBBox.left > rect.left) {
334 m_FontBBox.left = rect.left;
336 if (m_FontBBox.bottom > rect.bottom) {
337 m_FontBBox.bottom = rect.bottom;
343 if (m_Ascent == 0 && m_Descent == 0) {
345 GetCharBBox('A', rect);
346 if (rect.bottom == rect.top) {
347 m_Ascent = m_FontBBox.top;
351 GetCharBBox('g', rect);
352 if (rect.bottom == rect.top) {
353 m_Descent = m_FontBBox.bottom;
355 m_Descent = rect.bottom;
359 void CPDF_Font::LoadUnicodeMap()
361 m_bToUnicodeLoaded = TRUE;
362 CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode"));
363 if (pStream == NULL) {
366 m_pToUnicodeMap = FX_NEW CPDF_ToUnicodeMap;
367 m_pToUnicodeMap->Load(pStream);
369 int CPDF_Font::GetStringWidth(FX_LPCSTR pString, int size)
373 while (offset < size) {
374 FX_DWORD charcode = GetNextChar(pString, size, offset);
375 width += GetCharWidthF(charcode);
379 int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode)
381 if (m_Font.m_Face == NULL) {
384 int glyph_index = GlyphFromCharCode(charcode);
385 if (glyph_index == 0xffff) {
388 return m_Font.GetGlyphWidth(glyph_index);
390 int _PDF_GetStandardFontName(CFX_ByteString& name);
391 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, FX_BSTR name)
393 CFX_ByteString fontname(name);
394 int font_id = _PDF_GetStandardFontName(fontname);
398 CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
399 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
403 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
404 pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font"));
405 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1"));
406 pDict->SetAtName(FX_BSTRC("BaseFont"), fontname);
407 pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding"));
408 pFont = CPDF_Font::CreateFontF(NULL, pDict);
409 pFontGlobals->Set(pDoc, font_id, pFont);
412 const FX_BYTE ChineseFontNames[][5] = {
413 {0xCB, 0xCE, 0xCC, 0xE5, 0x00},
414 {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
415 {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
416 {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
417 {0xD0, 0xC2, 0xCB, 0xCE, 0x00}
419 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict)
421 CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype"));
423 if (type == FX_BSTRC("TrueType")) {
425 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
426 CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont"));
427 CFX_ByteString tag = basefont.Left(4);
429 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
430 for (i = 0; i < count; ++i) {
431 if (tag == CFX_ByteString((FX_LPCSTR)ChineseFontNames[i])) {
436 CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
437 if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) {
438 pFont = FX_NEW CPDF_CIDFont;
439 pFont->m_pFontDict = pFontDict;
440 pFont->m_pDocument = pDoc;
441 if (!pFont->Load()) {
450 pFont = FX_NEW CPDF_TrueTypeFont;
451 } else if (type == FX_BSTRC("Type3")) {
452 pFont = FX_NEW CPDF_Type3Font;
453 } else if (type == FX_BSTRC("Type0")) {
454 pFont = FX_NEW CPDF_CIDFont;
456 pFont = FX_NEW CPDF_Type1Font;
458 pFont->m_pFontDict = pFontDict;
459 pFont->m_pDocument = pDoc;
460 if (!pFont->Load()) {
466 FX_BOOL CPDF_Font::Load()
468 if (m_pFontDict == NULL) {
471 CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype"));
472 m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont"));
473 if (type == FX_BSTRC("MMType1")) {
474 type = FX_BSTRC("Type1");
478 static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, const CFX_ByteString& bytestr)
480 return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr);
482 static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, const CFX_WideString& widestr)
484 return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr);
486 CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont)
488 m_GetByteString = _FontMap_GetByteString;
489 m_GetWideString = _FontMap_GetWideString;
492 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode)
495 if (m_Map.Lookup(charcode, value)) {
496 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);
497 if (unicode != 0xffff) {
500 FX_LPCWSTR buf = m_MultiCharBuf.GetBuffer();
501 FX_DWORD buf_len = m_MultiCharBuf.GetLength();
502 if (buf == NULL || buf_len == 0) {
503 return CFX_WideString();
505 FX_DWORD index = value >> 16;
506 if (index >= buf_len) {
507 return CFX_WideString();
509 FX_DWORD len = buf[index];
510 if (index + len < index || index + len >= buf_len) {
511 return CFX_WideString();
513 return CFX_WideString(buf + index + 1, len);
516 return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);
518 return CFX_WideString();
520 FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode)
522 FX_POSITION pos = m_Map.GetStartPosition();
525 m_Map.GetNextAssoc(pos, key, value);
526 if ((FX_WCHAR)value == unicode) {
532 static FX_DWORD _StringToCode(FX_BSTR str)
534 FX_LPCSTR buf = str.GetCStr();
535 int len = str.GetLength();
541 for (int i = 1; i < len; i ++) {
543 if (buf[i] >= '0' && buf[i] <= '9') {
544 digit = buf[i] - '0';
545 } else if (buf[i] >= 'a' && buf[i] <= 'f') {
546 digit = buf[i] - 'a' + 10;
547 } else if (buf[i] >= 'A' && buf[i] <= 'F') {
548 digit = buf[i] - 'A' + 10;
552 result = result * 16 + digit;
556 for (int i = 0; i < len; i ++) {
557 if (buf[i] < '0' || buf[i] > '9') {
560 result = result * 10 + buf[i] - '0';
565 static CFX_WideString _StringDataAdd(CFX_WideString str)
568 int len = str.GetLength();
570 for (int i = len - 1; i >= 0 ; --i) {
571 FX_WCHAR ch = str[i] + value;
580 ret.Insert(0, value);
584 static CFX_WideString _StringToWideString(FX_BSTR str)
586 FX_LPCSTR buf = str.GetCStr();
587 int len = str.GetLength();
589 return CFX_WideString();
591 CFX_WideString result;
595 for (int i = 1; i < len; i ++) {
597 if (buf[i] >= '0' && buf[i] <= '9') {
598 digit = buf[i] - '0';
599 } else if (buf[i] >= 'a' && buf[i] <= 'f') {
600 digit = buf[i] - 'a' + 10;
601 } else if (buf[i] >= 'A' && buf[i] <= 'F') {
602 digit = buf[i] - 'A' + 10;
606 ch = ch * 16 + digit;
620 void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream)
623 CPDF_StreamAcc stream;
624 stream.LoadAllData(pStream, FALSE);
625 CPDF_SimpleParser parser(stream.GetData(), stream.GetSize());
626 m_Map.EstimateSize(stream.GetSize() / 8, 1024);
628 CFX_ByteStringC word = parser.GetWord();
629 if (word.IsEmpty()) {
632 if (word == FX_BSTRC("beginbfchar")) {
634 word = parser.GetWord();
635 if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) {
638 FX_DWORD srccode = _StringToCode(word);
639 word = parser.GetWord();
640 CFX_WideString destcode = _StringToWideString(word);
641 int len = destcode.GetLength();
646 m_Map.SetAt(srccode, destcode.GetAt(0));
648 m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
649 m_MultiCharBuf.AppendChar(destcode.GetLength());
650 m_MultiCharBuf << destcode;
653 } else if (word == FX_BSTRC("beginbfrange")) {
655 CFX_ByteString low, high;
656 low = parser.GetWord();
657 if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) {
660 high = parser.GetWord();
661 FX_DWORD lowcode = _StringToCode(low);
662 FX_DWORD highcode = (lowcode & 0xffffff00) | (_StringToCode(high) & 0xff);
663 if (highcode == (FX_DWORD) - 1) {
666 CFX_ByteString start = parser.GetWord();
667 if (start == FX_BSTRC("[")) {
668 for (FX_DWORD code = lowcode; code <= highcode; code ++) {
669 CFX_ByteString dest = parser.GetWord();
670 CFX_WideString destcode = _StringToWideString(dest);
671 int len = destcode.GetLength();
676 m_Map.SetAt(code, destcode.GetAt(0));
678 m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
679 m_MultiCharBuf.AppendChar(destcode.GetLength());
680 m_MultiCharBuf << destcode;
685 CFX_WideString destcode = _StringToWideString(start);
686 int len = destcode.GetLength();
689 value = _StringToCode(start);
690 for (FX_DWORD code = lowcode; code <= highcode; code ++) {
691 m_Map.SetAt(code, value++);
694 for (FX_DWORD code = lowcode; code <= highcode; code ++) {
695 CFX_WideString retcode;
696 if (code == lowcode) {
699 retcode = _StringDataAdd(destcode);
701 m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
702 m_MultiCharBuf.AppendChar(retcode.GetLength());
703 m_MultiCharBuf << retcode;
709 } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) {
710 CIDSet = CIDSET_KOREA1;
711 } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) {
712 CIDSet = CIDSET_JAPAN1;
713 } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) {
714 CIDSet = CIDSET_CNS1;
715 } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) {
720 m_pBaseMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE);
725 static FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value)
727 if (value == FX_BSTRC("WinAnsiEncoding")) {
728 basemap = PDFFONT_ENCODING_WINANSI;
729 } else if (value == FX_BSTRC("MacRomanEncoding")) {
730 basemap = PDFFONT_ENCODING_MACROMAN;
731 } else if (value == FX_BSTRC("MacExpertEncoding")) {
732 basemap = PDFFONT_ENCODING_MACEXPERT;
733 } else if (value == FX_BSTRC("PDFDocEncoding")) {
734 basemap = PDFFONT_ENCODING_PDFDOC;
740 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, int& iBaseEncoding, CFX_ByteString*& pCharNames,
741 FX_BOOL bEmbedded, FX_BOOL bTrueType)
743 if (pEncoding == NULL) {
744 if (m_BaseFont == FX_BSTRC("Symbol")) {
745 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL : PDFFONT_ENCODING_ADOBE_SYMBOL;
746 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
747 iBaseEncoding = PDFFONT_ENCODING_WINANSI;
751 if (pEncoding->GetType() == PDFOBJ_NAME) {
752 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
755 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) {
757 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
761 CFX_ByteString bsEncoding = pEncoding->GetString();
762 if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) {
763 bsEncoding = FX_BSTRC("WinAnsiEncoding");
765 GetPredefinedEncoding(iBaseEncoding, bsEncoding);
768 if (pEncoding->GetType() != PDFOBJ_DICTIONARY) {
771 CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding;
772 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
773 CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding"));
774 if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType) {
775 bsEncoding = FX_BSTRC("WinAnsiEncoding");
777 GetPredefinedEncoding(iBaseEncoding, bsEncoding);
779 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
780 iBaseEncoding = PDFFONT_ENCODING_STANDARD;
782 CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences"));
783 if (pDiffs == NULL) {
786 FX_NEW_VECTOR(pCharNames, CFX_ByteString, 256);
787 FX_DWORD cur_code = 0;
788 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i ++) {
789 CPDF_Object* pElement = pDiffs->GetElementValue(i);
790 if (pElement == NULL) {
793 if (pElement->GetType() == PDFOBJ_NAME) {
794 if (cur_code < 256) {
795 pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString();
799 cur_code = pElement->GetInteger();
803 FX_BOOL CPDF_Font::IsStandardFont() const
805 if (m_FontType != PDFFONT_TYPE1) {
808 if (m_pFontFile != NULL) {
811 if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) {
816 extern FX_LPCSTR PDF_CharNameFromPredefinedCharSet(int encoding, FX_BYTE charcode);
817 CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype)
819 FXSYS_memset8(m_CharBBox, 0xff, sizeof m_CharBBox);
820 FXSYS_memset8(m_CharWidth, 0xff, sizeof m_CharWidth);
821 FXSYS_memset8(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
822 FXSYS_memset8(m_ExtGID, 0xff, sizeof m_ExtGID);
824 m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
826 CPDF_SimpleFont::~CPDF_SimpleFont()
829 FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256);
832 int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph)
837 if (charcode > 0xff) {
840 int index = m_GlyphIndex[(FX_BYTE)charcode];
841 if (index == 0xffff) {
846 void CPDF_SimpleFont::LoadCharMetrics(int charcode)
848 if (m_Font.m_Face == NULL) {
851 if (charcode < 0 || charcode > 0xff) {
854 int glyph_index = m_GlyphIndex[charcode];
855 if (glyph_index == 0xffff) {
856 if (m_pFontFile == NULL && charcode != 32) {
858 m_CharBBox[charcode] = m_CharBBox[32];
859 if (m_bUseFontWidth) {
860 m_CharWidth[charcode] = m_CharWidth[32];
865 int err = FXFT_Load_Glyph(m_Font.m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
869 m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face), m_Font.m_Face);
870 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);
871 m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face), m_Font.m_Face);
872 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);
873 if (m_bUseFontWidth) {
874 int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.m_Face);
875 if (m_CharWidth[charcode] == 0xffff) {
876 m_CharWidth[charcode] = TT_Width;
877 } else if (TT_Width && !IsEmbedded()) {
878 m_CharBBox[charcode].Right = m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width;
879 m_CharBBox[charcode].Left = m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width;
883 int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level)
885 if (charcode > 0xff) {
888 if (m_CharWidth[charcode] == 0xffff) {
889 LoadCharMetrics(charcode);
890 if (m_CharWidth[charcode] == 0xffff) {
891 m_CharWidth[charcode] = 0;
894 return (FX_INT16)m_CharWidth[charcode];
896 void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
898 if (charcode > 0xff) {
901 if (m_CharBBox[charcode].Left == (FX_SHORT)0xffff) {
902 LoadCharMetrics(charcode);
904 rect.left = m_CharBBox[charcode].Left;
905 rect.right = m_CharBBox[charcode].Right;
906 rect.bottom = m_CharBBox[charcode].Bottom;
907 rect.top = m_CharBBox[charcode].Top;
909 FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode)
911 ASSERT(charcode >= 0 && charcode < 256);
912 if (charcode < 0 || charcode >= 256) {
915 FX_LPCSTR name = NULL;
917 name = pCharNames[charcode];
919 if ((name == NULL || name[0] == 0) && iBaseEncoding) {
920 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
922 if (name == NULL || name[0] == 0) {
927 FX_BOOL CPDF_SimpleFont::LoadCommon()
929 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
931 LoadFontDescriptor(pFontDesc);
933 CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));
934 int width_start = 0, width_end = -1;
935 m_bUseFontWidth = TRUE;
937 m_bUseFontWidth = FALSE;
938 if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) {
939 int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth"));
940 for (int i = 0; i < 256; i ++) {
941 m_CharWidth[i] = MissingWidth;
944 width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0);
945 width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0);
946 if (width_start >= 0 && width_start <= 255) {
947 if (width_end <= 0 || width_end >= width_start + (int)pWidthArray->GetCount()) {
948 width_end = width_start + pWidthArray->GetCount() - 1;
950 if (width_end > 255) {
953 for (int i = width_start; i <= width_end; i ++) {
954 m_CharWidth[i] = pWidthArray->GetInteger(i - width_start);
958 if (m_pFontFile == NULL) {
961 if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
962 m_BaseFont = m_BaseFont.Mid(8);
965 if (!(m_Flags & PDFFONT_SYMBOLIC)) {
966 m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
968 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
969 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, m_Font.IsTTFont());
972 FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256);
975 if (m_Font.m_Face == NULL) {
978 if (m_Flags & PDFFONT_ALLCAP) {
979 unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
980 for (size_t range = 0; range < sizeof lowercases / 2; range ++) {
981 for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i ++) {
982 if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) {
985 m_GlyphIndex[i] = m_GlyphIndex[i - 32];
986 if (m_CharWidth[i - 32]) {
987 m_CharWidth[i] = m_CharWidth[i - 32];
988 m_CharBBox[i] = m_CharBBox[i - 32];
996 void CPDF_SimpleFont::LoadSubstFont()
998 if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
1000 for (i = 0; i < 256; i ++) {
1001 if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
1005 width = m_CharWidth[i];
1006 } else if (width != m_CharWidth[i]) {
1010 if (i == 256 && width) {
1011 m_Flags |= PDFFONT_FIXEDPITCH;
1014 int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
1015 m_Font.LoadSubst(m_BaseFont, IsFontType(PDFFONT_TRUETYPE), m_Flags, weight, m_ItalicAngle, 0);
1016 if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
1019 FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const
1021 return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
1022 m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
1024 CPDF_Type1Font::CPDF_Type1Font() : CPDF_SimpleFont(PDFFONT_TYPE1)
1028 FX_BOOL CPDF_Type1Font::_Load()
1030 m_Base14Font = _PDF_GetStandardFontName(m_BaseFont);
1031 if (m_Base14Font >= 0) {
1032 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
1033 if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) {
1034 m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"));
1036 m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
1038 if (m_Base14Font < 4)
1039 for (int i = 0; i < 256; i ++) {
1040 m_CharWidth[i] = 600;
1042 if (m_Base14Font == 12) {
1043 m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
1044 } else if (m_Base14Font == 13) {
1045 m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
1046 } else if (m_Flags & PDFFONT_NONSYMBOLIC) {
1047 m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
1050 return LoadCommon();
1052 static FX_BOOL FT_UseType1Charmap(FXFT_Face face)
1054 if (FXFT_Get_Face_CharmapCount(face) == 0) {
1057 if (FXFT_Get_Face_CharmapCount(face) == 1 &&
1058 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {
1061 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {
1062 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
1064 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
1068 extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode);
1069 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1070 #include "../../fxge/apple/apple_int.h"
1072 int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode)
1074 if (charcode > 0xff) {
1077 int index = m_ExtGID[(FX_BYTE)charcode];
1078 if (index == 0xffff) {
1083 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1084 struct _GlyphNameMap {
1085 FX_LPCSTR m_pStrAdobe;
1086 FX_LPCSTR m_pStrUnicode;
1088 static const _GlyphNameMap g_GlyphNameSubsts[] = {
1096 static int compareString(const void* key, const void* element)
1098 return FXSYS_stricmp((FX_LPCSTR)key, ((_GlyphNameMap*)element)->m_pStrAdobe);
1101 static FX_LPCSTR _GlyphNameRemap(FX_LPCSTR pStrAdobe)
1103 _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(pStrAdobe, g_GlyphNameSubsts,
1104 sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap),
1107 return found->m_pStrUnicode;
1112 void CPDF_Type1Font::LoadGlyphMap()
1114 if (m_Font.m_Face == NULL) {
1117 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1118 FX_BOOL bCoreText = TRUE;
1119 CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
1120 if (!m_Font.m_pPlatformFont) {
1121 if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
1124 m_Font.m_pPlatformFont = quartz2d.CreateFont(m_Font.m_pFontData, m_Font.m_dwSize);
1125 if (NULL == m_Font.m_pPlatformFont) {
1130 if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
1131 if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
1132 FX_BOOL bGotOne = FALSE;
1133 for (int charcode = 0; charcode < 256; charcode ++) {
1134 const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1135 for (int j = 0; j < 4; j ++) {
1136 FX_WORD unicode = prefix[j] * 256 + charcode;
1137 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
1138 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1139 FX_CHAR name_glyph[256];
1140 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1141 name_glyph[255] = 0;
1142 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
1143 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1148 if (m_GlyphIndex[charcode]) {
1155 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1157 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
1163 FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE);
1164 if (m_BaseEncoding == 0) {
1165 m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
1167 for (int charcode = 0; charcode < 256; charcode ++) {
1168 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1172 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1173 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
1174 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1175 FX_CHAR name_glyph[256];
1176 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1177 name_glyph[255] = 0;
1178 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
1179 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1184 if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
1185 m_Encoding.m_Unicodes[charcode] = 0x20;
1186 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20);
1187 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1188 FX_CHAR name_glyph[256];
1189 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1190 name_glyph[255] = 0;
1191 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
1192 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1199 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1201 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
1206 FT_UseType1Charmap(m_Font.m_Face);
1207 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1209 if (m_Flags & PDFFONT_SYMBOLIC) {
1210 for (int charcode = 0; charcode < 256; charcode ++) {
1211 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1213 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1214 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
1215 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
1216 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1221 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
1222 FX_WCHAR unicode = 0;
1223 if (m_GlyphIndex[charcode]) {
1224 unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
1226 FX_CHAR name_glyph[256];
1227 FXSYS_memset32(name_glyph, 0, sizeof(name_glyph));
1228 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1229 name_glyph[255] = 0;
1230 if (unicode == 0 && name_glyph[0] != 0) {
1231 unicode = PDF_UnicodeFromAdobeName(name_glyph);
1233 m_Encoding.m_Unicodes[charcode] = unicode;
1234 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
1235 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1243 FX_BOOL bUnicode = FALSE;
1244 if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {
1247 for (int charcode = 0; charcode < 256; charcode ++) {
1248 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1252 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1253 FX_LPCSTR pStrUnicode = _GlyphNameRemap(name);
1254 if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)) {
1257 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
1258 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
1259 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1263 if (m_GlyphIndex[charcode] == 0) {
1264 if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {
1265 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
1266 FX_CHAR name_glyph[256];
1267 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1268 name_glyph[255] = 0;
1269 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
1270 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1275 m_Encoding.m_Unicodes[charcode] = 0x20;
1276 m_GlyphIndex[charcode] = bUnicode ? FXFT_Get_Char_Index(m_Font.m_Face, 0x20) : 0xffff;
1277 FX_CHAR name_glyph[256];
1278 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1279 name_glyph[255] = 0;
1280 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
1281 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
1291 if (m_Flags & PDFFONT_SYMBOLIC) {
1292 for (int charcode = 0; charcode < 256; charcode ++) {
1293 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1295 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1296 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
1298 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
1299 if (m_GlyphIndex[charcode]) {
1300 FX_WCHAR unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
1302 FX_CHAR name_glyph[256];
1303 FXSYS_memset32(name_glyph, 0, sizeof(name_glyph));
1304 FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
1305 name_glyph[255] = 0;
1306 if (name_glyph[0] != 0) {
1307 unicode = PDF_UnicodeFromAdobeName(name_glyph);
1310 m_Encoding.m_Unicodes[charcode] = unicode;
1314 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1316 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
1321 FX_BOOL bUnicode = FALSE;
1322 if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {
1325 for (int charcode = 0; charcode < 256; charcode ++) {
1326 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1330 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1331 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
1332 if (m_GlyphIndex[charcode] == 0) {
1333 if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {
1334 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
1336 m_Encoding.m_Unicodes[charcode] = 0x20;
1337 m_GlyphIndex[charcode] = 0xffff;
1341 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1343 FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);
1347 CPDF_FontEncoding::CPDF_FontEncoding()
1349 FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes));
1351 int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const
1353 for (int i = 0; i < 256; i ++)
1354 if (m_Unicodes[i] == unicode) {
1359 CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding)
1361 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
1363 FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes));
1365 for (int i = 0; i < 256; i++) {
1366 m_Unicodes[i] = pSrc[i];
1369 FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const
1371 return FXSYS_memcmp32(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == 0;
1373 CPDF_Object* CPDF_FontEncoding::Realize()
1376 for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs ++) {
1377 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
1378 FX_BOOL match = TRUE;
1379 for (int i = 0; i < 256; ++i) {
1380 if (m_Unicodes[i] != pSrc[i]) {
1391 if (predefined == PDFFONT_ENCODING_WINANSI) {
1392 return CPDF_Name::Create("WinAnsiEncoding");
1394 if (predefined == PDFFONT_ENCODING_MACROMAN) {
1395 return CPDF_Name::Create("MacRomanEncoding");
1397 if (predefined == PDFFONT_ENCODING_MACEXPERT) {
1398 return CPDF_Name::Create("MacExpertEncoding");
1402 CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
1403 pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding"));
1404 const FX_WORD* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
1405 CPDF_Array* pDiff = CPDF_Array::Create();
1406 for (int i = 0; i < 256; i ++) {
1407 if (pStandard[i] == m_Unicodes[i]) {
1410 pDiff->Add(CPDF_Number::Create(i));
1411 pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
1413 pDict->SetAt(FX_BSTRC("Differences"), pDiff);
1416 CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE)
1419 FX_BOOL CPDF_TrueTypeFont::_Load()
1421 return LoadCommon();
1423 extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
1424 void CPDF_TrueTypeFont::LoadGlyphMap()
1426 if (m_Font.m_Face == NULL) {
1429 int baseEncoding = m_BaseEncoding;
1430 if (m_pFontFile && m_Font.m_Face->num_charmaps > 0
1431 && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)
1432 && (m_Flags & PDFFONT_SYMBOLIC)) {
1433 FX_BOOL bSupportWin = FALSE;
1434 FX_BOOL bSupportMac = FALSE;
1435 for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) {
1436 int platform_id = FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]);
1437 if (platform_id == 0 || platform_id == 3) {
1439 } else if (platform_id == 0 || platform_id == 1) {
1443 if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
1444 baseEncoding = bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
1445 } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
1446 baseEncoding = bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
1449 if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)
1450 && m_pCharNames == NULL) || (m_Flags & PDFFONT_NONSYMBOLIC)) {
1451 if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && (!m_Font.m_Face->num_charmaps || !m_Font.m_Face->charmaps)) {
1452 int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));
1453 if(nStartChar < 0 || nStartChar > 255)
1457 for (; charcode < nStartChar; charcode ++) {
1458 m_GlyphIndex[charcode] = 0;
1460 FX_WORD nGlyph = charcode - nStartChar + 3;
1461 for (; charcode < 256; charcode ++, nGlyph ++) {
1462 m_GlyphIndex[charcode] = nGlyph;
1466 FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1);
1467 FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;
1469 if (m_Flags & PDFFONT_NONSYMBOLIC) {
1470 bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0);
1471 bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0);
1473 bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0);
1474 bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0);
1477 FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode"));
1478 for (int charcode = 0; charcode < 256; charcode ++) {
1479 FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
1481 m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Font.m_Face, charcode) : -1;
1484 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1486 const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1487 for (int j = 0; j < 4; j ++) {
1488 FX_WORD unicode = prefix[j] * 256 + charcode;
1489 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
1490 if (m_GlyphIndex[charcode]) {
1494 } else if (m_Encoding.m_Unicodes[charcode]) {
1496 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
1497 } else if (bMacRoman) {
1498 FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
1500 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char *)name);
1502 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, maccode);
1506 if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && name != NULL) {
1507 if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
1508 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 32);
1510 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
1511 if (m_GlyphIndex[charcode] == 0) {
1513 CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
1514 if (!wsUnicode.IsEmpty()) {
1515 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, wsUnicode[0]);
1516 m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
1519 if (m_GlyphIndex[charcode] == 0) {
1520 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
1528 if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
1529 const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1530 FX_BOOL bGotOne = FALSE;
1531 for (int charcode = 0; charcode < 256; charcode ++) {
1532 for (int j = 0; j < 4; j ++) {
1533 FX_WORD unicode = prefix[j] * 256 + charcode;
1534 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
1535 if (m_GlyphIndex[charcode]) {
1542 if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
1543 for (int charcode = 0; charcode < 256; charcode ++) {
1544 FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
1548 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1550 } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {
1551 for (int charcode = 0; charcode < 256; charcode ++) {
1552 m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
1558 if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {
1559 FX_BOOL bGotOne = FALSE;
1560 for (int charcode = 0; charcode < 256; charcode ++) {
1561 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
1562 m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
1563 if (m_GlyphIndex[charcode]) {
1567 if (m_pFontFile || bGotOne) {
1571 if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) {
1572 FX_BOOL bGotOne = FALSE;
1573 const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
1574 for (int charcode = 0; charcode < 256; charcode ++) {
1575 if (m_pFontFile == NULL) {
1576 FX_LPCSTR name = GetAdobeCharName(0, m_pCharNames, charcode);
1578 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1579 } else if (pUnicodes) {
1580 m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
1583 m_Encoding.m_Unicodes[charcode] = charcode;
1585 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
1586 if (m_GlyphIndex[charcode]) {
1594 for (int charcode = 0; charcode < 256; charcode ++) {
1595 m_GlyphIndex[charcode] = charcode;
1598 CPDF_Type3Font::CPDF_Type3Font() : CPDF_SimpleFont(PDFFONT_TYPE3)
1600 m_pPageResources = NULL;
1601 FXSYS_memset32(m_CharWidthL, 0, sizeof m_CharWidthL);
1603 CPDF_Type3Font::~CPDF_Type3Font()
1605 FX_POSITION pos = m_CacheMap.GetStartPosition();
1607 FX_LPVOID key, value;
1608 m_CacheMap.GetNextAssoc(pos, key, value);
1609 delete (CPDF_Type3Char*)value;
1611 m_CacheMap.RemoveAll();
1612 pos = m_DeletedMap.GetStartPosition();
1614 FX_LPVOID key, value;
1615 m_DeletedMap.GetNextAssoc(pos, key, value);
1616 delete (CPDF_Type3Char*)key;
1619 FX_BOOL CPDF_Type3Font::_Load()
1621 m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources"));
1622 CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix"));
1623 FX_FLOAT xscale = 1.0f, yscale = 1.0f;
1625 m_FontMatrix = pMatrix->GetMatrix();
1626 xscale = m_FontMatrix.a;
1627 yscale = m_FontMatrix.d;
1629 CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox"));
1631 m_FontBBox.left = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
1632 m_FontBBox.bottom = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
1633 m_FontBBox.right = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
1634 m_FontBBox.top = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000);
1636 int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));
1637 CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));
1638 if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
1639 FX_DWORD count = pWidthArray->GetCount();
1643 if (StartChar + count > 256) {
1644 count = 256 - StartChar;
1646 for (FX_DWORD i = 0; i < count; i ++) {
1647 m_CharWidthL[StartChar + i] = FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000);
1650 m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs"));
1651 CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
1653 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
1655 for (int i = 0; i < 256; i ++) {
1656 m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
1657 if (m_Encoding.m_Unicodes[i] == 0) {
1658 m_Encoding.m_Unicodes[i] = i;
1665 void CPDF_Type3Font::CheckType3FontMetrics()
1669 CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level)
1671 if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) {
1674 CPDF_Type3Char* pChar = NULL;
1675 if (m_CacheMap.Lookup((FX_LPVOID)(FX_UINTPTR)charcode, (FX_LPVOID&)pChar)) {
1676 if (pChar->m_bPageRequired && m_pPageResources) {
1678 m_CacheMap.RemoveKey((FX_LPVOID)(FX_UINTPTR)charcode);
1679 return LoadChar(charcode, level + 1);
1683 FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1687 CPDF_Stream* pStream = (CPDF_Stream*)(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : NULL);
1688 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
1691 pChar = FX_NEW CPDF_Type3Char;
1692 pChar->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, pStream, NULL);
1693 pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1);
1694 FX_FLOAT scale = m_FontMatrix.GetXUnit();
1695 pChar->m_Width = (FX_INT32)(pChar->m_Width * scale + 0.5f);
1696 FX_RECT &rcBBox = pChar->m_BBox;
1697 CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
1698 (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
1699 if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) {
1700 char_rect = pChar->m_pForm->CalcBoundingBox();
1702 char_rect.Transform(&m_FontMatrix);
1703 rcBBox.left = FXSYS_round(char_rect.left * 1000);
1704 rcBBox.right = FXSYS_round(char_rect.right * 1000);
1705 rcBBox.top = FXSYS_round(char_rect.top * 1000);
1706 rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
1707 m_CacheMap.SetAt((FX_LPVOID)(FX_UINTPTR)charcode, pChar);
1708 if (pChar->m_pForm->CountObjects() == 0) {
1709 delete pChar->m_pForm;
1710 pChar->m_pForm = NULL;
1714 int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level)
1716 if (charcode > 0xff) {
1719 if (m_CharWidthL[charcode]) {
1720 return m_CharWidthL[charcode];
1722 CPDF_Type3Char* pChar = LoadChar(charcode, level);
1723 if (pChar == NULL) {
1726 return pChar->m_Width;
1728 void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
1730 CPDF_Type3Char* pChar = LoadChar(charcode, level);
1731 if (pChar == NULL) {
1732 rect.left = rect.right = rect.top = rect.bottom = 0;
1735 rect = pChar->m_BBox;
1737 CPDF_Type3Char::CPDF_Type3Char()
1741 m_bPageRequired = FALSE;
1744 CPDF_Type3Char::~CPDF_Type3Char()