summaryrefslogtreecommitdiff
path: root/core/fpdfapi/font/cpdf_truetypefont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/font/cpdf_truetypefont.cpp')
-rw-r--r--core/fpdfapi/font/cpdf_truetypefont.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/core/fpdfapi/font/cpdf_truetypefont.cpp b/core/fpdfapi/font/cpdf_truetypefont.cpp
new file mode 100644
index 0000000000..f3b5f2507e
--- /dev/null
+++ b/core/fpdfapi/font/cpdf_truetypefont.cpp
@@ -0,0 +1,223 @@
+// 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/font/cpdf_truetypefont.h"
+
+#include "core/fpdfapi/font/font_int.h"
+#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h"
+#include "core/fxge/fx_font.h"
+
+namespace {
+
+const uint8_t kPrefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
+
+} // namespace
+
+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;
+}
+
+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_CharNames.empty()) ||
+ (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->GetIntegerFor("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;
+ }
+ bool bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
+ bool bMacRoman = false;
+ bool 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_CharNames, 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) {
+ for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) {
+ uint16_t unicode = kPrefix[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) {
+ uint32_t 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)) {
+ bool bFound = false;
+ for (int charcode = 0; charcode < 256; charcode++) {
+ for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) {
+ uint16_t unicode = kPrefix[j] * 256 + charcode;
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
+ if (m_GlyphIndex[charcode]) {
+ bFound = true;
+ break;
+ }
+ }
+ }
+ if (bFound) {
+ if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(baseEncoding, m_CharNames, charcode);
+ if (name)
+ 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)) {
+ bool bFound = 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]) {
+ bFound = true;
+ }
+ }
+ if (m_pFontFile || bFound)
+ return;
+ }
+ if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
+ bool bFound = 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_CharNames, 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])
+ bFound = true;
+ }
+ if (bFound)
+ return;
+ }
+ for (int charcode = 0; charcode < 256; charcode++)
+ m_GlyphIndex[charcode] = charcode;
+}