Index: core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp |
diff --git a/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp b/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..13e031808e4e513bf37392dbe78fd3446683dd62 |
--- /dev/null |
+++ b/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp |
@@ -0,0 +1,225 @@ |
+// Copyright 2016 PDFium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
+ |
+#include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h" |
+ |
+#include "core/fpdfapi/fpdf_font/font_int.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
+#include "core/include/fxge/fx_font.h" |
+ |
+CPDF_TrueTypeFont::CPDF_TrueTypeFont() {} |
+ |
+bool CPDF_TrueTypeFont::IsTrueTypeFont() const { |
+ return true; |
+} |
+ |
+const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const { |
+ return this; |
+} |
+ |
+CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() { |
+ return this; |
+} |
+ |
+FX_BOOL CPDF_TrueTypeFont::Load() { |
+ return LoadCommon(); |
+} |
+ |
+void CPDF_TrueTypeFont::LoadGlyphMap() { |
+ if (!m_Font.GetFace()) |
+ return; |
+ |
+ int baseEncoding = m_BaseEncoding; |
+ if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 && |
+ (baseEncoding == PDFFONT_ENCODING_MACROMAN || |
+ baseEncoding == PDFFONT_ENCODING_WINANSI) && |
+ (m_Flags & PDFFONT_SYMBOLIC)) { |
+ FX_BOOL bSupportWin = FALSE; |
+ FX_BOOL bSupportMac = FALSE; |
+ for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) { |
+ int platform_id = FXFT_Get_Charmap_PlatformID( |
+ FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]); |
+ if (platform_id == 0 || platform_id == 3) { |
+ bSupportWin = TRUE; |
+ } else if (platform_id == 0 || platform_id == 1) { |
+ bSupportMac = TRUE; |
+ } |
+ } |
+ if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { |
+ baseEncoding = |
+ bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; |
+ } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { |
+ baseEncoding = |
+ bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; |
+ } |
+ } |
+ if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || |
+ baseEncoding == PDFFONT_ENCODING_WINANSI) && |
+ !m_pCharNames) || |
+ (m_Flags & PDFFONT_NONSYMBOLIC)) { |
+ if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && |
+ (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { |
+ int nStartChar = m_pFontDict->GetIntegerBy("FirstChar"); |
+ if (nStartChar < 0 || nStartChar > 255) |
+ return; |
+ |
+ int charcode = 0; |
+ for (; charcode < nStartChar; charcode++) { |
+ m_GlyphIndex[charcode] = 0; |
+ } |
+ uint16_t nGlyph = charcode - nStartChar + 3; |
+ for (; charcode < 256; charcode++, nGlyph++) { |
+ m_GlyphIndex[charcode] = nGlyph; |
+ } |
+ return; |
+ } |
+ FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); |
+ FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE; |
+ if (!bMSUnicode) { |
+ if (m_Flags & PDFFONT_NONSYMBOLIC) { |
+ bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); |
+ bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); |
+ } else { |
+ bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0); |
+ bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0); |
+ } |
+ } |
+ FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode"); |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ const FX_CHAR* name = |
+ GetAdobeCharName(baseEncoding, m_pCharNames, charcode); |
+ if (!name) { |
+ m_GlyphIndex[charcode] = |
+ m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1; |
+ continue; |
+ } |
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
+ if (bMSSymbol) { |
+ const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; |
+ for (int j = 0; j < 4; j++) { |
+ uint16_t unicode = prefix[j] * 256 + charcode; |
+ m_GlyphIndex[charcode] = |
+ FXFT_Get_Char_Index(m_Font.GetFace(), unicode); |
+ if (m_GlyphIndex[charcode]) { |
+ break; |
+ } |
+ } |
+ } else if (m_Encoding.m_Unicodes[charcode]) { |
+ if (bMSUnicode) { |
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index( |
+ m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); |
+ } else if (bMacRoman) { |
+ FX_DWORD maccode = FT_CharCodeFromUnicode( |
+ FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); |
+ if (!maccode) { |
+ m_GlyphIndex[charcode] = |
+ FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); |
+ } else { |
+ m_GlyphIndex[charcode] = |
+ FXFT_Get_Char_Index(m_Font.GetFace(), maccode); |
+ } |
+ } |
+ } |
+ if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && |
+ name) { |
+ if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { |
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32); |
+ } else { |
+ m_GlyphIndex[charcode] = |
+ FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); |
+ if (m_GlyphIndex[charcode] == 0) { |
+ if (bToUnicode) { |
+ CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); |
+ if (!wsUnicode.IsEmpty()) { |
+ m_GlyphIndex[charcode] = |
+ FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]); |
+ m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; |
+ } |
+ } |
+ if (m_GlyphIndex[charcode] == 0) { |
+ m_GlyphIndex[charcode] = |
+ FXFT_Get_Char_Index(m_Font.GetFace(), charcode); |
+ } |
+ } |
+ } |
+ } |
+ } |
+ return; |
+ } |
+ if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { |
+ const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; |
+ FX_BOOL bGotOne = FALSE; |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ for (int j = 0; j < 4; j++) { |
+ uint16_t unicode = prefix[j] * 256 + charcode; |
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); |
+ if (m_GlyphIndex[charcode]) { |
+ bGotOne = TRUE; |
+ break; |
+ } |
+ } |
+ } |
+ if (bGotOne) { |
+ if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ const FX_CHAR* name = |
+ GetAdobeCharName(baseEncoding, m_pCharNames, charcode); |
+ if (!name) { |
+ continue; |
+ } |
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
+ } |
+ } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ m_Encoding.m_Unicodes[charcode] = |
+ FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); |
+ } |
+ } |
+ return; |
+ } |
+ } |
+ if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { |
+ FX_BOOL bGotOne = FALSE; |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); |
+ m_Encoding.m_Unicodes[charcode] = |
+ FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); |
+ if (m_GlyphIndex[charcode]) { |
+ bGotOne = TRUE; |
+ } |
+ } |
+ if (m_pFontFile || bGotOne) { |
+ return; |
+ } |
+ } |
+ if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { |
+ FX_BOOL bGotOne = FALSE; |
+ const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ if (m_pFontFile) { |
+ m_Encoding.m_Unicodes[charcode] = charcode; |
+ } else { |
+ const FX_CHAR* name = GetAdobeCharName(0, m_pCharNames, charcode); |
+ if (name) { |
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
+ } else if (pUnicodes) { |
+ m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; |
+ } |
+ } |
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index( |
+ m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); |
+ if (m_GlyphIndex[charcode]) { |
+ bGotOne = TRUE; |
+ } |
+ } |
+ if (bGotOne) { |
+ return; |
+ } |
+ } |
+ for (int charcode = 0; charcode < 256; charcode++) { |
+ m_GlyphIndex[charcode] = charcode; |
+ } |
+} |