summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_font
diff options
context:
space:
mode:
authordan sinclair <dsinclair@chromium.org>2016-03-23 19:21:44 -0400
committerdan sinclair <dsinclair@chromium.org>2016-03-23 19:21:44 -0400
commit61b2fc718910a5ab2a75ec5026b239ff33bccfdc (patch)
tree4031f4cea10dac3d77969035e66fc17235cb1d3d /core/fpdfapi/fpdf_font
parent46a8a2041868c5df6883647226dab1482e2bf4c2 (diff)
downloadpdfium-61b2fc718910a5ab2a75ec5026b239ff33bccfdc.tar.xz
Split core/include/fpdfapi/fpdf_resource.h
This CL splits apart the core/include/fpdfapi/fpdf_resource.h file and places the classes into individual files. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1824033002 .
Diffstat (limited to 'core/fpdfapi/fpdf_font')
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_cidfont.cpp908
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_cidfont.h89
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_font.cpp492
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp (renamed from core/fpdfapi/fpdf_font/fpdf_font_charset.cpp)354
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_simplefont.cpp222
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_simplefont.h48
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp225
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_truetypefont.h30
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type1font.cpp403
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type1font.h35
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3char.cpp43
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3char.h33
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3font.cpp162
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type3font.h56
-rw-r--r--core/fpdfapi/fpdf_font/font_int.h3
-rw-r--r--core/fpdfapi/fpdf_font/fpdf_font.cpp1515
-rw-r--r--core/fpdfapi/fpdf_font/fpdf_font_cid.cpp893
-rw-r--r--core/fpdfapi/fpdf_font/include/cpdf_font.h128
-rw-r--r--core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h59
19 files changed, 3136 insertions, 2562 deletions
diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp
new file mode 100644
index 0000000000..d528017779
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_cidfont.cpp
@@ -0,0 +1,908 @@
+// 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_cidfont.h"
+
+#include "core/fpdfapi/fpdf_cmaps/cmap_int.h"
+#include "core/fpdfapi/fpdf_font/font_int.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+#include "core/fpdfapi/fpdf_font/ttgsubtable.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "core/fpdfapi/include/cpdf_modulemgr.h"
+
+namespace {
+
+const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
+
+const struct CIDTransform {
+ uint16_t CID;
+ uint8_t a;
+ uint8_t b;
+ uint8_t c;
+ uint8_t d;
+ uint8_t e;
+ uint8_t f;
+} g_Japan1_VertCIDs[] = {
+ {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89},
+ {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127},
+ {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127},
+ {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127},
+ {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127},
+ {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127},
+ {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104},
+ {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104},
+ {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127},
+ {7904, 0, 129, 127, 0, 17, 127}, {7905, 0, 129, 127, 0, 17, 114},
+ {7906, 0, 129, 127, 0, 17, 127}, {7907, 0, 129, 127, 0, 17, 127},
+ {7908, 0, 129, 127, 0, 17, 127}, {7909, 0, 129, 127, 0, 17, 127},
+ {7910, 0, 129, 127, 0, 17, 127}, {7911, 0, 129, 127, 0, 17, 127},
+ {7912, 0, 129, 127, 0, 17, 127}, {7913, 0, 129, 127, 0, 17, 127},
+ {7914, 0, 129, 127, 0, 17, 127}, {7915, 0, 129, 127, 0, 17, 114},
+ {7916, 0, 129, 127, 0, 17, 127}, {7917, 0, 129, 127, 0, 17, 127},
+ {7918, 127, 0, 0, 127, 18, 25}, {7919, 127, 0, 0, 127, 18, 25},
+ {7920, 127, 0, 0, 127, 18, 25}, {7921, 127, 0, 0, 127, 18, 25},
+ {7922, 127, 0, 0, 127, 18, 25}, {7923, 127, 0, 0, 127, 18, 25},
+ {7924, 127, 0, 0, 127, 18, 25}, {7925, 127, 0, 0, 127, 18, 25},
+ {7926, 127, 0, 0, 127, 18, 25}, {7927, 127, 0, 0, 127, 18, 25},
+ {7928, 127, 0, 0, 127, 18, 25}, {7929, 127, 0, 0, 127, 18, 25},
+ {7930, 127, 0, 0, 127, 18, 25}, {7931, 127, 0, 0, 127, 18, 25},
+ {7932, 127, 0, 0, 127, 18, 25}, {7933, 127, 0, 0, 127, 18, 25},
+ {7934, 127, 0, 0, 127, 18, 25}, {7935, 127, 0, 0, 127, 18, 25},
+ {7936, 127, 0, 0, 127, 18, 25}, {7937, 127, 0, 0, 127, 18, 25},
+ {7938, 127, 0, 0, 127, 18, 25}, {7939, 127, 0, 0, 127, 18, 25},
+ {8720, 0, 129, 127, 0, 19, 102}, {8721, 0, 129, 127, 0, 13, 127},
+ {8722, 0, 129, 127, 0, 19, 108}, {8723, 0, 129, 127, 0, 19, 102},
+ {8724, 0, 129, 127, 0, 19, 102}, {8725, 0, 129, 127, 0, 19, 102},
+ {8726, 0, 129, 127, 0, 19, 102}, {8727, 0, 129, 127, 0, 19, 102},
+ {8728, 0, 129, 127, 0, 19, 114}, {8729, 0, 129, 127, 0, 19, 114},
+ {8730, 0, 129, 127, 0, 38, 108}, {8731, 0, 129, 127, 0, 13, 108},
+ {8732, 0, 129, 127, 0, 19, 108}, {8733, 0, 129, 127, 0, 19, 108},
+ {8734, 0, 129, 127, 0, 19, 108}, {8735, 0, 129, 127, 0, 19, 108},
+ {8736, 0, 129, 127, 0, 19, 102}, {8737, 0, 129, 127, 0, 19, 102},
+ {8738, 0, 129, 127, 0, 19, 102}, {8739, 0, 129, 127, 0, 19, 102},
+ {8740, 0, 129, 127, 0, 19, 102}, {8741, 0, 129, 127, 0, 19, 102},
+ {8742, 0, 129, 127, 0, 19, 102}, {8743, 0, 129, 127, 0, 19, 102},
+ {8744, 0, 129, 127, 0, 19, 102}, {8745, 0, 129, 127, 0, 19, 102},
+ {8746, 0, 129, 127, 0, 19, 114}, {8747, 0, 129, 127, 0, 19, 114},
+ {8748, 0, 129, 127, 0, 19, 102}, {8749, 0, 129, 127, 0, 19, 102},
+ {8750, 0, 129, 127, 0, 19, 102}, {8751, 0, 129, 127, 0, 19, 102},
+ {8752, 0, 129, 127, 0, 19, 102}, {8753, 0, 129, 127, 0, 19, 102},
+ {8754, 0, 129, 127, 0, 19, 102}, {8755, 0, 129, 127, 0, 19, 102},
+ {8756, 0, 129, 127, 0, 19, 102}, {8757, 0, 129, 127, 0, 19, 102},
+ {8758, 0, 129, 127, 0, 19, 102}, {8759, 0, 129, 127, 0, 19, 102},
+ {8760, 0, 129, 127, 0, 19, 102}, {8761, 0, 129, 127, 0, 19, 102},
+ {8762, 0, 129, 127, 0, 19, 102}, {8763, 0, 129, 127, 0, 19, 102},
+ {8764, 0, 129, 127, 0, 19, 102}, {8765, 0, 129, 127, 0, 19, 102},
+ {8766, 0, 129, 127, 0, 19, 102}, {8767, 0, 129, 127, 0, 19, 102},
+ {8768, 0, 129, 127, 0, 19, 102}, {8769, 0, 129, 127, 0, 19, 102},
+ {8770, 0, 129, 127, 0, 19, 102}, {8771, 0, 129, 127, 0, 19, 102},
+ {8772, 0, 129, 127, 0, 19, 102}, {8773, 0, 129, 127, 0, 19, 102},
+ {8774, 0, 129, 127, 0, 19, 102}, {8775, 0, 129, 127, 0, 19, 102},
+ {8776, 0, 129, 127, 0, 19, 102}, {8777, 0, 129, 127, 0, 19, 102},
+ {8778, 0, 129, 127, 0, 19, 102}, {8779, 0, 129, 127, 0, 19, 114},
+ {8780, 0, 129, 127, 0, 19, 108}, {8781, 0, 129, 127, 0, 19, 114},
+ {8782, 0, 129, 127, 0, 13, 114}, {8783, 0, 129, 127, 0, 19, 108},
+ {8784, 0, 129, 127, 0, 13, 114}, {8785, 0, 129, 127, 0, 19, 108},
+ {8786, 0, 129, 127, 0, 19, 108}, {8787, 0, 129, 127, 0, 19, 108},
+ {8788, 0, 129, 127, 0, 19, 108}, {8789, 0, 129, 127, 0, 19, 108},
+ {8790, 0, 129, 127, 0, 19, 108}, {8791, 0, 129, 127, 0, 19, 108},
+ {8792, 0, 129, 127, 0, 19, 108}, {8793, 0, 129, 127, 0, 19, 108},
+ {8794, 0, 129, 127, 0, 19, 108}, {8795, 0, 129, 127, 0, 19, 108},
+ {8796, 0, 129, 127, 0, 19, 108}, {8797, 0, 129, 127, 0, 19, 108},
+ {8798, 0, 129, 127, 0, 19, 108}, {8799, 0, 129, 127, 0, 19, 108},
+ {8800, 0, 129, 127, 0, 19, 108}, {8801, 0, 129, 127, 0, 19, 108},
+ {8802, 0, 129, 127, 0, 19, 108}, {8803, 0, 129, 127, 0, 19, 108},
+ {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108},
+ {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108},
+ {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108},
+ {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114},
+ {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114},
+ {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121},
+ {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127},
+ {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108},
+};
+
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+
+bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
+ switch (charset) {
+ case CIDSET_GB1:
+ case CIDSET_CNS1:
+ case CIDSET_JAPAN1:
+ case CIDSET_KOREA1:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
+ CIDSet charset,
+ FX_DWORD charcode) {
+ if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
+ return 0;
+
+ uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
+ if (cid == 0)
+ return 0;
+
+ CPDF_FontGlobals* pFontGlobals =
+ CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
+ const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
+ if (!pCodes)
+ return 0;
+
+ if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count)
+ return pCodes[cid];
+ return 0;
+}
+
+FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
+ CIDSet charset,
+ FX_WCHAR unicode) {
+ if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
+ return 0;
+
+ CPDF_FontGlobals* pFontGlobals =
+ CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
+ const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
+ if (!pCodes)
+ return 0;
+
+ int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
+ for (int i = 0; i < nCodes; ++i) {
+ if (pCodes[i] == unicode) {
+ FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
+ if (CharCode != 0) {
+ return CharCode;
+ }
+ }
+ }
+ return 0;
+}
+
+#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+
+void FT_UseCIDCharmap(FXFT_Face face, int coding) {
+ int encoding;
+ switch (coding) {
+ case CIDCODING_GB:
+ encoding = FXFT_ENCODING_GB2312;
+ break;
+ case CIDCODING_BIG5:
+ encoding = FXFT_ENCODING_BIG5;
+ break;
+ case CIDCODING_JIS:
+ encoding = FXFT_ENCODING_SJIS;
+ break;
+ case CIDCODING_KOREA:
+ encoding = FXFT_ENCODING_JOHAB;
+ break;
+ default:
+ encoding = FXFT_ENCODING_UNICODE;
+ }
+ int err = FXFT_Select_Charmap(face, encoding);
+ if (err) {
+ err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
+ }
+ if (err && FXFT_Get_Face_Charmaps(face)) {
+ FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
+ }
+}
+
+int CompareCIDTransform(const void* key, const void* element) {
+ uint16_t CID = *static_cast<const uint16_t*>(key);
+ return CID - static_cast<const struct CIDTransform*>(element)->CID;
+}
+
+} // namespace
+
+CPDF_CIDFont::CPDF_CIDFont()
+ : m_pCMap(nullptr),
+ m_pAllocatedCMap(nullptr),
+ m_pCID2UnicodeMap(nullptr),
+ m_pCIDToGIDMap(nullptr),
+ m_bCIDIsGID(FALSE),
+ m_pAnsiWidths(nullptr),
+ m_bAdobeCourierStd(FALSE),
+ m_pTTGSUBTable(nullptr) {}
+
+CPDF_CIDFont::~CPDF_CIDFont() {
+ if (m_pAnsiWidths) {
+ FX_Free(m_pAnsiWidths);
+ }
+ delete m_pAllocatedCMap;
+ delete m_pCIDToGIDMap;
+ delete m_pTTGSUBTable;
+}
+
+bool CPDF_CIDFont::IsCIDFont() const {
+ return true;
+}
+
+const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const {
+ return this;
+}
+
+CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() {
+ return this;
+}
+
+uint16_t CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const {
+ if (!m_pCMap) {
+ return (uint16_t)charcode;
+ }
+ return m_pCMap->CIDFromCharCode(charcode);
+}
+
+FX_BOOL CPDF_CIDFont::IsVertWriting() const {
+ return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
+}
+
+CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(FX_DWORD charcode) const {
+ CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode);
+ if (!str.IsEmpty())
+ return str;
+ FX_WCHAR ret = GetUnicodeFromCharCode(charcode);
+ if (ret == 0)
+ return CFX_WideString();
+ return ret;
+}
+
+FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(FX_DWORD charcode) const {
+ switch (m_pCMap->m_Coding) {
+ case CIDCODING_UCS2:
+ case CIDCODING_UTF16:
+ return (FX_WCHAR)charcode;
+ case CIDCODING_CID:
+ if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
+ return 0;
+ }
+ return m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)charcode);
+ }
+ if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
+ !m_pCID2UnicodeMap->IsLoaded()) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ FX_WCHAR unicode;
+ int charsize = 1;
+ if (charcode > 255) {
+ charcode = (charcode % 256) * 256 + (charcode / 256);
+ charsize = 2;
+ }
+ int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->m_Coding], 0,
+ (const FX_CHAR*)&charcode, charsize,
+ &unicode, 1);
+ if (ret != 1) {
+ return 0;
+ }
+ return unicode;
+#else
+ if (m_pCMap->m_pEmbedMap) {
+ return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap,
+ m_pCMap->m_Charset, charcode);
+ }
+ return 0;
+#endif
+ }
+ return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
+}
+
+FX_DWORD CPDF_CIDFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ FX_DWORD charcode = CPDF_Font::CharCodeFromUnicode(unicode);
+ if (charcode)
+ return charcode;
+ switch (m_pCMap->m_Coding) {
+ case CIDCODING_UNKNOWN:
+ return 0;
+ case CIDCODING_UCS2:
+ case CIDCODING_UTF16:
+ return unicode;
+ case CIDCODING_CID: {
+ if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
+ return 0;
+ }
+ FX_DWORD CID = 0;
+ while (CID < 65536) {
+ FX_WCHAR this_unicode =
+ m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID);
+ if (this_unicode == unicode) {
+ return CID;
+ }
+ CID++;
+ }
+ break;
+ }
+ }
+
+ if (unicode < 0x80) {
+ return static_cast<FX_DWORD>(unicode);
+ }
+ if (m_pCMap->m_Coding == CIDCODING_CID) {
+ return 0;
+ }
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ uint8_t buffer[32];
+ int ret =
+ FXSYS_WideCharToMultiByte(g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1,
+ (char*)buffer, 4, NULL, NULL);
+ if (ret == 1) {
+ return buffer[0];
+ }
+ if (ret == 2) {
+ return buffer[0] * 256 + buffer[1];
+ }
+#else
+ if (m_pCMap->m_pEmbedMap) {
+ return EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset,
+ unicode);
+ }
+#endif
+ return 0;
+}
+
+FX_BOOL CPDF_CIDFont::Load() {
+ if (m_pFontDict->GetStringBy("Subtype") == "TrueType") {
+ return LoadGB2312();
+ }
+ CPDF_Array* pFonts = m_pFontDict->GetArrayBy("DescendantFonts");
+ if (!pFonts) {
+ return FALSE;
+ }
+ if (pFonts->GetCount() != 1) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
+ if (!pCIDFontDict) {
+ return FALSE;
+ }
+ m_BaseFont = pCIDFontDict->GetStringBy("BaseFont");
+ if ((m_BaseFont.Compare("CourierStd") == 0 ||
+ m_BaseFont.Compare("CourierStd-Bold") == 0 ||
+ m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
+ m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
+ !IsEmbedded()) {
+ m_bAdobeCourierStd = TRUE;
+ }
+ CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc) {
+ LoadFontDescriptor(pFontDesc);
+ }
+ CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
+ if (!pEncoding) {
+ return FALSE;
+ }
+ CFX_ByteString subtype = pCIDFontDict->GetStringBy("Subtype");
+ m_bType1 = (subtype == "CIDFontType0");
+
+ if (pEncoding->IsName()) {
+ CFX_ByteString cmap = pEncoding->GetString();
+ m_pCMap =
+ CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetPredefinedCMap(cmap, m_pFontFile && m_bType1);
+ } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
+ m_pAllocatedCMap = m_pCMap = new CPDF_CMap;
+ CPDF_StreamAcc acc;
+ acc.LoadAllData(pStream, FALSE);
+ m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
+ } else {
+ return FALSE;
+ }
+ if (!m_pCMap) {
+ return FALSE;
+ }
+ m_Charset = m_pCMap->m_Charset;
+ if (m_Charset == CIDSET_UNKNOWN) {
+ CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictBy("CIDSystemInfo");
+ if (pCIDInfo) {
+ m_Charset = CharsetFromOrdering(pCIDInfo->GetStringBy("Ordering"));
+ }
+ }
+ if (m_Charset != CIDSET_UNKNOWN)
+ m_pCID2UnicodeMap =
+ CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetCID2UnicodeMap(
+ m_Charset,
+ !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID ||
+ pCIDFontDict->KeyExist("W")));
+ if (m_Font.GetFace()) {
+ if (m_bType1) {
+ FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
+ } else {
+ FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding);
+ }
+ }
+ m_DefaultWidth = pCIDFontDict->GetIntegerBy("DW", 1000);
+ CPDF_Array* pWidthArray = pCIDFontDict->GetArrayBy("W");
+ if (pWidthArray) {
+ LoadMetricsArray(pWidthArray, m_WidthList, 1);
+ }
+ if (!IsEmbedded()) {
+ LoadSubstFont();
+ }
+ if (1) {
+ if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
+ CPDF_Object* pmap = pCIDFontDict->GetElementValue("CIDToGIDMap");
+ if (pmap) {
+ if (CPDF_Stream* pStream = pmap->AsStream()) {
+ m_pCIDToGIDMap = new CPDF_StreamAcc;
+ m_pCIDToGIDMap->LoadAllData(pStream, FALSE);
+ } else if (pmap->GetString() == "Identity") {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (m_pFontFile) {
+ m_bCIDIsGID = TRUE;
+ }
+#else
+ m_bCIDIsGID = TRUE;
+#endif
+ }
+ }
+ }
+ }
+ CheckFontMetrics();
+ if (IsVertWriting()) {
+ pWidthArray = pCIDFontDict->GetArrayBy("W2");
+ if (pWidthArray) {
+ LoadMetricsArray(pWidthArray, m_VertMetrics, 3);
+ }
+ CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayBy("DW2");
+ if (pDefaultArray) {
+ m_DefaultVY = pDefaultArray->GetIntegerAt(0);
+ m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
+ } else {
+ m_DefaultVY = 880;
+ m_DefaultW1 = -1000;
+ }
+ }
+ return TRUE;
+}
+
+FX_RECT CPDF_CIDFont::GetCharBBox(FX_DWORD charcode, int level) {
+ if (charcode < 256 && m_CharBBox[charcode].right != FX_SMALL_RECT::kInvalid)
+ return FX_RECT(m_CharBBox[charcode]);
+
+ FX_RECT rect;
+ FX_BOOL bVert = FALSE;
+ int glyph_index = GlyphFromCharCode(charcode, &bVert);
+ FXFT_Face face = m_Font.GetFace();
+ if (face) {
+ if (FXFT_Is_Face_Tricky(face)) {
+ int err = FXFT_Load_Glyph(face, glyph_index,
+ FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ if (!err) {
+ FXFT_BBox cbox;
+ FXFT_Glyph glyph;
+ err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph);
+ if (!err) {
+ FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
+ int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem;
+ int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem;
+ if (pixel_size_x == 0 || pixel_size_y == 0) {
+ rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin);
+ } else {
+ rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x,
+ cbox.yMax * 1000 / pixel_size_y,
+ cbox.xMax * 1000 / pixel_size_x,
+ cbox.yMin * 1000 / pixel_size_y);
+ }
+ if (rect.top > FXFT_Get_Face_Ascender(face)) {
+ rect.top = FXFT_Get_Face_Ascender(face);
+ }
+ if (rect.bottom < FXFT_Get_Face_Descender(face)) {
+ rect.bottom = FXFT_Get_Face_Descender(face);
+ }
+ FXFT_Done_Glyph(glyph);
+ }
+ }
+ } else {
+ int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE);
+ if (err == 0) {
+ rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
+ TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
+ TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) +
+ FXFT_Get_Glyph_Width(face),
+ face),
+ TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) -
+ FXFT_Get_Glyph_Height(face),
+ face));
+ rect.top += rect.top / 64;
+ }
+ }
+ }
+ if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) {
+ uint16_t CID = CIDFromCharCode(charcode);
+ const uint8_t* pTransform = GetCIDTransform(CID);
+ if (pTransform && !bVert) {
+ CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]),
+ CIDTransformToFloat(pTransform[1]),
+ CIDTransformToFloat(pTransform[2]),
+ CIDTransformToFloat(pTransform[3]),
+ CIDTransformToFloat(pTransform[4]) * 1000,
+ CIDTransformToFloat(pTransform[5]) * 1000);
+ CFX_FloatRect rect_f(rect);
+ rect_f.Transform(&matrix);
+ rect = rect_f.GetOutterRect();
+ }
+ }
+ if (charcode < 256)
+ m_CharBBox[charcode] = rect.ToSmallRect();
+
+ return rect;
+}
+int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) {
+ if (m_pAnsiWidths && charcode < 0x80) {
+ return m_pAnsiWidths[charcode];
+ }
+ uint16_t cid = CIDFromCharCode(charcode);
+ int size = m_WidthList.GetSize();
+ FX_DWORD* list = m_WidthList.GetData();
+ for (int i = 0; i < size; i += 3) {
+ if (cid >= list[i] && cid <= list[i + 1]) {
+ return (int)list[i + 2];
+ }
+ }
+ return m_DefaultWidth;
+}
+short CPDF_CIDFont::GetVertWidth(uint16_t CID) const {
+ FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
+ if (vertsize == 0) {
+ return m_DefaultW1;
+ }
+ const FX_DWORD* pTable = m_VertMetrics.GetData();
+ for (FX_DWORD i = 0; i < vertsize; i++)
+ if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
+ return (short)(int)pTable[i * 5 + 2];
+ }
+ return m_DefaultW1;
+}
+void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const {
+ FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
+ if (vertsize) {
+ const FX_DWORD* pTable = m_VertMetrics.GetData();
+ for (FX_DWORD i = 0; i < vertsize; i++)
+ if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
+ vx = (short)(int)pTable[i * 5 + 3];
+ vy = (short)(int)pTable[i * 5 + 4];
+ return;
+ }
+ }
+ FX_DWORD dwWidth = m_DefaultWidth;
+ int size = m_WidthList.GetSize();
+ const FX_DWORD* list = m_WidthList.GetData();
+ for (int i = 0; i < size; i += 3) {
+ if (CID >= list[i] && CID <= list[i + 1]) {
+ dwWidth = (uint16_t)list[i + 2];
+ break;
+ }
+ }
+ vx = (short)dwWidth / 2;
+ vy = (short)m_DefaultVY;
+}
+int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL* pVertGlyph) {
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ FXFT_Face face = m_Font.GetFace();
+ int index = FXFT_Get_Char_Index(face, unicode);
+ if (unicode == 0x2502) {
+ return index;
+ }
+ if (index && IsVertWriting()) {
+ if (m_pTTGSUBTable) {
+ uint32_t vindex = 0;
+ m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
+ if (vindex) {
+ index = vindex;
+ if (pVertGlyph) {
+ *pVertGlyph = TRUE;
+ }
+ }
+ return index;
+ }
+ if (!m_Font.GetSubData()) {
+ unsigned long length = 0;
+ int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
+ NULL, &length);
+ if (!error) {
+ m_Font.SetSubData(FX_Alloc(uint8_t, length));
+ }
+ }
+ int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
+ m_Font.GetSubData(), NULL);
+ if (!error && m_Font.GetSubData()) {
+ m_pTTGSUBTable = new CFX_CTTGSUBTable;
+ m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
+ uint32_t vindex = 0;
+ m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
+ if (vindex) {
+ index = vindex;
+ if (pVertGlyph) {
+ *pVertGlyph = TRUE;
+ }
+ }
+ }
+ return index;
+ }
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ return index;
+}
+int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ if (!m_pFontFile && !m_pCIDToGIDMap) {
+ uint16_t cid = CIDFromCharCode(charcode);
+ FX_WCHAR unicode = 0;
+ if (m_bCIDIsGID) {
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
+ return cid;
+#else
+ if (m_Flags & PDFFONT_SYMBOLIC) {
+ return cid;
+ }
+ CFX_WideString uni_str = UnicodeFromCharCode(charcode);
+ if (uni_str.IsEmpty()) {
+ return cid;
+ }
+ unicode = uni_str.GetAt(0);
+#endif
+ } else {
+ if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) {
+ unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid);
+ }
+ if (unicode == 0) {
+ unicode = GetUnicodeFromCharCode(charcode);
+ }
+ if (unicode == 0 && !(m_Flags & PDFFONT_SYMBOLIC)) {
+ unicode = UnicodeFromCharCode(charcode).GetAt(0);
+ }
+ }
+ FXFT_Face face = m_Font.GetFace();
+ if (unicode == 0) {
+ if (!m_bAdobeCourierStd) {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ charcode += 31;
+ int index = 0, iBaseEncoding;
+ FX_BOOL bMSUnicode = FT_UseTTCharmap(face, 3, 1);
+ FX_BOOL bMacRoman = FALSE;
+ if (!bMSUnicode) {
+ bMacRoman = FT_UseTTCharmap(face, 1, 0);
+ }
+ iBaseEncoding = PDFFONT_ENCODING_STANDARD;
+ if (bMSUnicode) {
+ iBaseEncoding = PDFFONT_ENCODING_WINANSI;
+ } else if (bMacRoman) {
+ iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
+ }
+ const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode);
+ if (!name) {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ uint16_t unicode = PDF_UnicodeFromAdobeName(name);
+ if (unicode) {
+ if (bMSUnicode) {
+ index = FXFT_Get_Char_Index(face, unicode);
+ } else if (bMacRoman) {
+ FX_DWORD maccode =
+ FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode);
+ index = !maccode ? FXFT_Get_Name_Index(face, (char*)name)
+ : FXFT_Get_Char_Index(face, maccode);
+ } else {
+ return FXFT_Get_Char_Index(face, unicode);
+ }
+ } else {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ if (index == 0 || index == 0xffff) {
+ return charcode == 0 ? -1 : (int)charcode;
+ }
+ return index;
+ }
+ if (m_Charset == CIDSET_JAPAN1) {
+ if (unicode == '\\') {
+ unicode = '/';
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
+ } else if (unicode == 0xa5) {
+ unicode = 0x5c;
+#endif
+ }
+ }
+ if (!face)
+ return unicode;
+
+ int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
+ if (err != 0) {
+ int i;
+ for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
+ FX_DWORD ret = FT_CharCodeFromUnicode(
+ FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
+ (FX_WCHAR)charcode);
+ if (ret == 0) {
+ continue;
+ }
+ FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
+ unicode = (FX_WCHAR)ret;
+ break;
+ }
+ if (i == FXFT_Get_Face_CharmapCount(face) && i) {
+ FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
+ unicode = (FX_WCHAR)charcode;
+ }
+ }
+ if (FXFT_Get_Face_Charmap(face)) {
+ int index = GetGlyphIndex(unicode, pVertGlyph);
+ if (index == 0)
+ return -1;
+ return index;
+ }
+ return unicode;
+ }
+ if (!m_Font.GetFace())
+ return -1;
+
+ uint16_t cid = CIDFromCharCode(charcode);
+ if (m_bType1) {
+ if (!m_pCIDToGIDMap) {
+ return cid;
+ }
+ } else {
+ if (!m_pCIDToGIDMap) {
+ if (m_pFontFile && !m_pCMap->m_pMapping)
+ return cid;
+ if (m_pCMap->m_Coding == CIDCODING_UNKNOWN ||
+ !FXFT_Get_Face_Charmap(m_Font.GetFace())) {
+ return cid;
+ }
+ if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) ==
+ FXFT_ENCODING_UNICODE) {
+ CFX_WideString unicode_str = UnicodeFromCharCode(charcode);
+ if (unicode_str.IsEmpty()) {
+ return -1;
+ }
+ charcode = unicode_str.GetAt(0);
+ }
+ return GetGlyphIndex(charcode, pVertGlyph);
+ }
+ }
+ FX_DWORD byte_pos = cid * 2;
+ if (byte_pos + 2 > m_pCIDToGIDMap->GetSize())
+ return -1;
+
+ const uint8_t* pdata = m_pCIDToGIDMap->GetData() + byte_pos;
+ return pdata[0] * 256 + pdata[1];
+}
+FX_DWORD CPDF_CIDFont::GetNextChar(const FX_CHAR* pString,
+ int nStrLen,
+ int& offset) const {
+ return m_pCMap->GetNextChar(pString, nStrLen, offset);
+}
+int CPDF_CIDFont::GetCharSize(FX_DWORD charcode) const {
+ return m_pCMap->GetCharSize(charcode);
+}
+int CPDF_CIDFont::CountChar(const FX_CHAR* pString, int size) const {
+ return m_pCMap->CountChar(pString, size);
+}
+int CPDF_CIDFont::AppendChar(FX_CHAR* str, FX_DWORD charcode) const {
+ return m_pCMap->AppendChar(str, charcode);
+}
+FX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const {
+ if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
+ !m_pCID2UnicodeMap->IsLoaded()) {
+ return m_pCMap->m_Coding != CIDCODING_UNKNOWN;
+ }
+ return TRUE;
+}
+FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const {
+ return TRUE;
+}
+void CPDF_CIDFont::LoadSubstFont() {
+ m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle,
+ g_CharsetCPs[m_Charset], IsVertWriting());
+}
+void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
+ CFX_DWordArray& result,
+ int nElements) {
+ int width_status = 0;
+ int iCurElement = 0;
+ int first_code = 0;
+ int last_code = 0;
+ FX_DWORD count = pArray->GetCount();
+ for (FX_DWORD i = 0; i < count; i++) {
+ CPDF_Object* pObj = pArray->GetElementValue(i);
+ if (!pObj)
+ continue;
+
+ if (CPDF_Array* pArray = pObj->AsArray()) {
+ if (width_status != 1)
+ return;
+
+ FX_DWORD count = pArray->GetCount();
+ for (FX_DWORD j = 0; j < count; j += nElements) {
+ result.Add(first_code);
+ result.Add(first_code);
+ for (int k = 0; k < nElements; k++) {
+ result.Add(pArray->GetIntegerAt(j + k));
+ }
+ first_code++;
+ }
+ width_status = 0;
+ } else {
+ if (width_status == 0) {
+ first_code = pObj->GetInteger();
+ width_status = 1;
+ } else if (width_status == 1) {
+ last_code = pObj->GetInteger();
+ width_status = 2;
+ iCurElement = 0;
+ } else {
+ if (!iCurElement) {
+ result.Add(first_code);
+ result.Add(last_code);
+ }
+ result.Add(pObj->GetInteger());
+ iCurElement++;
+ if (iCurElement == nElements) {
+ width_status = 0;
+ }
+ }
+ }
+ }
+}
+
+// static
+FX_FLOAT CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) {
+ if (ch < 128) {
+ return ch * 1.0f / 127;
+ }
+ return (-255 + ch) * 1.0f / 127;
+}
+
+FX_BOOL CPDF_CIDFont::LoadGB2312() {
+ m_BaseFont = m_pFontDict->GetStringBy("BaseFont");
+ CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc) {
+ LoadFontDescriptor(pFontDesc);
+ }
+ m_Charset = CIDSET_GB1;
+ m_bType1 = FALSE;
+ m_pCMap = CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE);
+ m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()
+ ->GetPageModule()
+ ->GetFontGlobals()
+ ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE);
+ if (!IsEmbedded()) {
+ LoadSubstFont();
+ }
+ CheckFontMetrics();
+ m_DefaultWidth = 1000;
+ m_pAnsiWidths = FX_Alloc(uint16_t, 128);
+ for (int i = 32; i < 127; i++) {
+ m_pAnsiWidths[i] = 500;
+ }
+ return TRUE;
+}
+
+const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
+ if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
+ return nullptr;
+
+ const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch(
+ &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs),
+ sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform);
+ return found ? &found->a : nullptr;
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_cidfont.h b/core/fpdfapi/fpdf_font/cpdf_cidfont.h
new file mode 100644
index 0000000000..6ff7c825d2
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_cidfont.h
@@ -0,0 +1,89 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_CIDFONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_CIDFONT_H_
+
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+
+enum CIDSet {
+ CIDSET_UNKNOWN,
+ CIDSET_GB1,
+ CIDSET_CNS1,
+ CIDSET_JAPAN1,
+ CIDSET_KOREA1,
+ CIDSET_UNICODE,
+ CIDSET_NUM_SETS
+};
+
+class CFX_CTTGSUBTable;
+class CPDF_Array;
+class CPDF_CID2UnicodeMap;
+class CPDF_CMap;
+class CPDF_StreamAcc;
+
+class CPDF_CIDFont : public CPDF_Font {
+ public:
+ CPDF_CIDFont();
+ ~CPDF_CIDFont() override;
+
+ static FX_FLOAT CIDTransformToFloat(uint8_t ch);
+
+ // CPDF_Font:
+ bool IsCIDFont() const override;
+ const CPDF_CIDFont* AsCIDFont() const override;
+ CPDF_CIDFont* AsCIDFont() override;
+ int GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph = NULL) override;
+ int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
+ FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) override;
+ FX_DWORD GetNextChar(const FX_CHAR* pString,
+ int nStrLen,
+ int& offset) const override;
+ int CountChar(const FX_CHAR* pString, int size) const override;
+ int AppendChar(FX_CHAR* str, FX_DWORD charcode) const override;
+ int GetCharSize(FX_DWORD charcode) const override;
+ FX_BOOL IsVertWriting() const override;
+ FX_BOOL IsUnicodeCompatible() const override;
+ FX_BOOL Load() override;
+ CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const override;
+ FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const override;
+
+ FX_BOOL LoadGB2312();
+ uint16_t CIDFromCharCode(FX_DWORD charcode) const;
+ const uint8_t* GetCIDTransform(uint16_t CID) const;
+ short GetVertWidth(uint16_t CID) const;
+ void GetVertOrigin(uint16_t CID, short& vx, short& vy) const;
+ virtual FX_BOOL IsFontStyleFromCharCode(FX_DWORD charcode) const;
+
+ protected:
+ int GetGlyphIndex(FX_DWORD unicodeb, FX_BOOL* pVertGlyph);
+ void LoadMetricsArray(CPDF_Array* pArray,
+ CFX_DWordArray& result,
+ int nElements);
+ void LoadSubstFont();
+ FX_WCHAR GetUnicodeFromCharCode(FX_DWORD charcode) const;
+
+ CPDF_CMap* m_pCMap;
+ CPDF_CMap* m_pAllocatedCMap;
+ CPDF_CID2UnicodeMap* m_pCID2UnicodeMap;
+ CIDSet m_Charset;
+ FX_BOOL m_bType1;
+ CPDF_StreamAcc* m_pCIDToGIDMap;
+ FX_BOOL m_bCIDIsGID;
+ uint16_t m_DefaultWidth;
+ uint16_t* m_pAnsiWidths;
+ FX_SMALL_RECT m_CharBBox[256];
+ CFX_DWordArray m_WidthList;
+ short m_DefaultVY;
+ short m_DefaultW1;
+ CFX_DWordArray m_VertMetrics;
+ FX_BOOL m_bAdobeCourierStd;
+ CFX_CTTGSUBTable* m_pTTGSUBTable;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_CIDFONT_H_
diff --git a/core/fpdfapi/fpdf_font/cpdf_font.cpp b/core/fpdfapi/fpdf_font/cpdf_font.cpp
new file mode 100644
index 0000000000..bb63966161
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_font.cpp
@@ -0,0 +1,492 @@
+// 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/include/cpdf_font.h"
+
+#include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type1font.h"
+#include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
+#include "core/fpdfapi/fpdf_font/font_int.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
+#include "core/fpdfapi/include/cpdf_modulemgr.h"
+#include "core/include/fxge/fx_freetype.h"
+
+namespace {
+
+const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
+ {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
+ {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
+ {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
+ {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
+
+FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
+ if (value == "WinAnsiEncoding")
+ basemap = PDFFONT_ENCODING_WINANSI;
+ else if (value == "MacRomanEncoding")
+ basemap = PDFFONT_ENCODING_MACROMAN;
+ else if (value == "MacExpertEncoding")
+ basemap = PDFFONT_ENCODING_MACEXPERT;
+ else if (value == "PDFDocEncoding")
+ basemap = PDFFONT_ENCODING_PDFDOC;
+ else
+ return FALSE;
+ return TRUE;
+}
+
+} // namespace
+
+CPDF_Font::CPDF_Font()
+ : m_pFontFile(nullptr),
+ m_pFontDict(nullptr),
+ m_pToUnicodeMap(nullptr),
+ m_bToUnicodeLoaded(FALSE),
+ m_Flags(0),
+ m_StemV(0),
+ m_Ascent(0),
+ m_Descent(0),
+ m_ItalicAngle(0) {}
+
+CPDF_Font::~CPDF_Font() {
+ delete m_pToUnicodeMap;
+ m_pToUnicodeMap = NULL;
+
+ if (m_pFontFile) {
+ m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
+ const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
+ }
+}
+
+bool CPDF_Font::IsType1Font() const {
+ return false;
+}
+
+bool CPDF_Font::IsTrueTypeFont() const {
+ return false;
+}
+
+bool CPDF_Font::IsType3Font() const {
+ return false;
+}
+
+bool CPDF_Font::IsCIDFont() const {
+ return false;
+}
+
+const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
+ return nullptr;
+}
+
+CPDF_Type1Font* CPDF_Font::AsType1Font() {
+ return nullptr;
+}
+
+const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
+ return nullptr;
+}
+
+CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
+ return nullptr;
+}
+
+const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
+ return nullptr;
+}
+
+CPDF_Type3Font* CPDF_Font::AsType3Font() {
+ return nullptr;
+}
+
+const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
+ return nullptr;
+}
+
+CPDF_CIDFont* CPDF_Font::AsCIDFont() {
+ return nullptr;
+}
+
+FX_BOOL CPDF_Font::IsUnicodeCompatible() const {
+ return FALSE;
+}
+
+int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
+ return size;
+}
+
+int CPDF_Font::GetCharSize(FX_DWORD charcode) const {
+ return 1;
+}
+
+int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
+ ASSERT(false);
+ return 0;
+}
+
+int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
+ return GlyphFromCharCode(charcode);
+}
+
+FX_BOOL CPDF_Font::IsVertWriting() const {
+ FX_BOOL bVertWriting = FALSE;
+ const CPDF_CIDFont* pCIDFont = AsCIDFont();
+ if (pCIDFont) {
+ bVertWriting = pCIDFont->IsVertWriting();
+ } else {
+ bVertWriting = m_Font.IsVertical();
+ }
+ return bVertWriting;
+}
+
+int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
+ *buf = (FX_CHAR)charcode;
+ return 1;
+}
+
+void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const {
+ char buf[4];
+ int len = AppendChar(buf, charcode);
+ if (len == 1) {
+ str += buf[0];
+ } else {
+ str += CFX_ByteString(buf, len);
+ }
+}
+
+CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const {
+ if (!m_bToUnicodeLoaded)
+ ((CPDF_Font*)this)->LoadUnicodeMap();
+
+ if (m_pToUnicodeMap)
+ return m_pToUnicodeMap->Lookup(charcode);
+ return CFX_WideString();
+}
+
+FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ if (!m_bToUnicodeLoaded)
+ ((CPDF_Font*)this)->LoadUnicodeMap();
+
+ if (m_pToUnicodeMap)
+ return m_pToUnicodeMap->ReverseLookup(unicode);
+ return 0;
+}
+
+void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
+ m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
+ int ItalicAngle = 0;
+ FX_BOOL bExistItalicAngle = FALSE;
+ if (pFontDesc->KeyExist("ItalicAngle")) {
+ ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
+ bExistItalicAngle = TRUE;
+ }
+ if (ItalicAngle < 0) {
+ m_Flags |= PDFFONT_ITALIC;
+ m_ItalicAngle = ItalicAngle;
+ }
+ FX_BOOL bExistStemV = FALSE;
+ if (pFontDesc->KeyExist("StemV")) {
+ m_StemV = pFontDesc->GetIntegerBy("StemV");
+ bExistStemV = TRUE;
+ }
+ FX_BOOL bExistAscent = FALSE;
+ if (pFontDesc->KeyExist("Ascent")) {
+ m_Ascent = pFontDesc->GetIntegerBy("Ascent");
+ bExistAscent = TRUE;
+ }
+ FX_BOOL bExistDescent = FALSE;
+ if (pFontDesc->KeyExist("Descent")) {
+ m_Descent = pFontDesc->GetIntegerBy("Descent");
+ bExistDescent = TRUE;
+ }
+ FX_BOOL bExistCapHeight = FALSE;
+ if (pFontDesc->KeyExist("CapHeight")) {
+ bExistCapHeight = TRUE;
+ }
+ if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
+ bExistStemV) {
+ m_Flags |= PDFFONT_USEEXTERNATTR;
+ }
+ if (m_Descent > 10) {
+ m_Descent = -m_Descent;
+ }
+ CPDF_Array* pBBox = pFontDesc->GetArrayBy("FontBBox");
+ if (pBBox) {
+ m_FontBBox.left = pBBox->GetIntegerAt(0);
+ m_FontBBox.bottom = pBBox->GetIntegerAt(1);
+ m_FontBBox.right = pBBox->GetIntegerAt(2);
+ m_FontBBox.top = pBBox->GetIntegerAt(3);
+ }
+
+ CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile");
+ if (!pFontFile)
+ pFontFile = pFontDesc->GetStreamBy("FontFile2");
+ if (!pFontFile)
+ pFontFile = pFontDesc->GetStreamBy("FontFile3");
+ if (!pFontFile)
+ return;
+
+ m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
+ if (!m_pFontFile)
+ return;
+
+ const uint8_t* pFontData = m_pFontFile->GetData();
+ FX_DWORD dwFontSize = m_pFontFile->GetSize();
+ if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
+ m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
+ const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
+ m_pFontFile = nullptr;
+ }
+}
+
+void CPDF_Font::CheckFontMetrics() {
+ if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
+ m_FontBBox.right == 0) {
+ FXFT_Face face = m_Font.GetFace();
+ if (face) {
+ m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
+ m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
+ m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
+ m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
+ m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
+ m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
+ } else {
+ FX_BOOL bFirst = TRUE;
+ for (int i = 0; i < 256; i++) {
+ FX_RECT rect = GetCharBBox(i);
+ if (rect.left == rect.right) {
+ continue;
+ }
+ if (bFirst) {
+ m_FontBBox = rect;
+ bFirst = FALSE;
+ } else {
+ if (m_FontBBox.top < rect.top) {
+ m_FontBBox.top = rect.top;
+ }
+ if (m_FontBBox.right < rect.right) {
+ m_FontBBox.right = rect.right;
+ }
+ if (m_FontBBox.left > rect.left) {
+ m_FontBBox.left = rect.left;
+ }
+ if (m_FontBBox.bottom > rect.bottom) {
+ m_FontBBox.bottom = rect.bottom;
+ }
+ }
+ }
+ }
+ }
+ if (m_Ascent == 0 && m_Descent == 0) {
+ FX_RECT rect = GetCharBBox('A');
+ m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
+ rect = GetCharBBox('g');
+ m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
+ }
+}
+
+void CPDF_Font::LoadUnicodeMap() {
+ m_bToUnicodeLoaded = TRUE;
+ CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
+ if (!pStream) {
+ return;
+ }
+ m_pToUnicodeMap = new CPDF_ToUnicodeMap;
+ m_pToUnicodeMap->Load(pStream);
+}
+
+int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
+ int offset = 0;
+ int width = 0;
+ while (offset < size) {
+ FX_DWORD charcode = GetNextChar(pString, size, offset);
+ width += GetCharWidthF(charcode);
+ }
+ return width;
+}
+
+CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
+ const CFX_ByteStringC& name) {
+ CFX_ByteString fontname(name);
+ int font_id = PDF_GetStandardFontName(&fontname);
+ if (font_id < 0) {
+ return nullptr;
+ }
+ CPDF_FontGlobals* pFontGlobals =
+ CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
+ CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
+ if (pFont) {
+ return pFont;
+ }
+ CPDF_Dictionary* pDict = new CPDF_Dictionary;
+ pDict->SetAtName("Type", "Font");
+ pDict->SetAtName("Subtype", "Type1");
+ pDict->SetAtName("BaseFont", fontname);
+ pDict->SetAtName("Encoding", "WinAnsiEncoding");
+ pFont = CPDF_Font::CreateFontF(NULL, pDict);
+ pFontGlobals->Set(pDoc, font_id, pFont);
+ return pFont;
+}
+
+CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
+ CPDF_Dictionary* pFontDict) {
+ CFX_ByteString type = pFontDict->GetStringBy("Subtype");
+ CPDF_Font* pFont;
+ if (type == "TrueType") {
+ {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
+ _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
+ _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
+ _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont");
+ CFX_ByteString tag = basefont.Left(4);
+ int i;
+ int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
+ for (i = 0; i < count; ++i) {
+ if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
+ break;
+ }
+ }
+ if (i < count) {
+ CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
+ if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
+ pFont = new CPDF_CIDFont;
+ pFont->m_pFontDict = pFontDict;
+ pFont->m_pDocument = pDoc;
+ pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
+ if (!pFont->Load()) {
+ delete pFont;
+ return NULL;
+ }
+ return pFont;
+ }
+ }
+#endif
+ }
+ pFont = new CPDF_TrueTypeFont;
+ } else if (type == "Type3") {
+ pFont = new CPDF_Type3Font;
+ } else if (type == "Type0") {
+ pFont = new CPDF_CIDFont;
+ } else {
+ pFont = new CPDF_Type1Font;
+ }
+ pFont->m_pFontDict = pFontDict;
+ pFont->m_pDocument = pDoc;
+ pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
+ if (!pFont->Load()) {
+ delete pFont;
+ return NULL;
+ }
+ return pFont;
+}
+
+FX_DWORD CPDF_Font::GetNextChar(const FX_CHAR* pString,
+ int nStrLen,
+ int& offset) const {
+ if (offset < 0 || nStrLen < 1) {
+ return 0;
+ }
+ uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
+ return static_cast<FX_DWORD>(ch);
+}
+
+void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
+ int& iBaseEncoding,
+ CFX_ByteString*& pCharNames,
+ FX_BOOL bEmbedded,
+ FX_BOOL bTrueType) {
+ if (!pEncoding) {
+ if (m_BaseFont == "Symbol") {
+ iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
+ : PDFFONT_ENCODING_ADOBE_SYMBOL;
+ } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
+ iBaseEncoding = PDFFONT_ENCODING_WINANSI;
+ }
+ return;
+ }
+ if (pEncoding->IsName()) {
+ if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
+ iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
+ return;
+ }
+ if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
+ if (!bTrueType) {
+ iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
+ }
+ return;
+ }
+ CFX_ByteString bsEncoding = pEncoding->GetString();
+ if (bsEncoding.Compare("MacExpertEncoding") == 0) {
+ bsEncoding = "WinAnsiEncoding";
+ }
+ GetPredefinedEncoding(iBaseEncoding, bsEncoding);
+ return;
+ }
+
+ CPDF_Dictionary* pDict = pEncoding->AsDictionary();
+ if (!pDict)
+ return;
+
+ if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
+ iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
+ CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
+ if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
+ bsEncoding = "WinAnsiEncoding";
+ }
+ GetPredefinedEncoding(iBaseEncoding, bsEncoding);
+ }
+ if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
+ iBaseEncoding = PDFFONT_ENCODING_STANDARD;
+ }
+ CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
+ if (!pDiffs) {
+ return;
+ }
+ pCharNames = new CFX_ByteString[256];
+ FX_DWORD cur_code = 0;
+ for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
+ CPDF_Object* pElement = pDiffs->GetElementValue(i);
+ if (!pElement)
+ continue;
+
+ if (CPDF_Name* pName = pElement->AsName()) {
+ if (cur_code < 256)
+ pCharNames[cur_code] = pName->GetString();
+ cur_code++;
+ } else {
+ cur_code = pElement->GetInteger();
+ }
+ }
+}
+
+FX_BOOL CPDF_Font::IsStandardFont() const {
+ if (!IsType1Font())
+ return FALSE;
+ if (m_pFontFile)
+ return FALSE;
+ if (AsType1Font()->GetBase14Font() < 0)
+ return FALSE;
+ return TRUE;
+}
+
+const FX_CHAR* CPDF_Font::GetAdobeCharName(int iBaseEncoding,
+ const CFX_ByteString* pCharNames,
+ int charcode) {
+ ASSERT(charcode >= 0 && charcode < 256);
+ if (charcode < 0 || charcode >= 256)
+ return nullptr;
+
+ const FX_CHAR* name = nullptr;
+ if (pCharNames)
+ name = pCharNames[charcode];
+ if ((!name || name[0] == 0) && iBaseEncoding)
+ name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
+ return name && name[0] ? name : nullptr;
+}
diff --git a/core/fpdfapi/fpdf_font/fpdf_font_charset.cpp b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp
index 1b503c69a6..64e11e09de 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font_charset.cpp
+++ b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp
@@ -1,77 +1,52 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
+// 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_parser/include/fpdf_parser_decode.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+
+#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/include/fxge/fx_freetype.h"
+#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
-static const struct _UnicodeAlt {
- uint16_t m_Unicode;
- const FX_CHAR* m_Alter;
-} UnicodeAlts[] = {
- {0x00a0, " "}, {0x00a1, "!"}, {0x00a2, "c"}, {0x00a3, "P"},
- {0x00a4, "o"}, {0x00a5, "Y"}, {0x00a6, "|"}, {0x00a7, "S"},
- {0x00a9, "(C)"}, {0x00aa, "a"}, {0x00ab, "<<"}, {0x00ac, "-|"},
- {0x00ae, "(R)"}, {0x00af, "-"}, {0x00b0, "o"}, {0x00b1, "+/-"},
- {0x00b2, "^2"}, {0x00b3, "^3"}, {0x00b4, "'"}, {0x00b5, "u"},
- {0x00b6, "P"}, {0x00b7, "."}, {0x00b9, "^1"}, {0x00ba, "o"},
- {0x00bb, ">>"}, {0x00bc, "1/4"}, {0x00bd, "1/2"}, {0x00be, "3/4"},
- {0x00bf, "?"}, {0x00c0, "A"}, {0x00c1, "A"}, {0x00c2, "A"},
- {0x00c3, "A"}, {0x00c4, "A"}, {0x00c5, "A"}, {0x00c6, "AE"},
- {0x00c7, "C"}, {0x00c8, "E"}, {0x00c9, "E"}, {0x00ca, "E"},
- {0x00cb, "E"}, {0x00cc, "I"}, {0x00cd, "I"}, {0x00ce, "I"},
- {0x00cf, "I"}, {0x00d1, "N"}, {0x00d2, "O"}, {0x00d3, "O"},
- {0x00d4, "O"}, {0x00d5, "O"}, {0x00d6, "O"}, {0x00d7, "x"},
- {0x00d8, "O"}, {0x00d9, "U"}, {0x00da, "U"}, {0x00db, "U"},
- {0x00dc, "U"}, {0x00dd, "Y"}, {0x00df, "S"}, {0x00e0, "a"},
- {0x00e1, "a"}, {0x00e2, "a"}, {0x00e3, "a"}, {0x00e4, "a"},
- {0x00e5, "a"}, {0x00e6, "ae"}, {0x00e7, "c"}, {0x00e8, "e"},
- {0x00e9, "e"}, {0x00ea, "e"}, {0x00eb, "e"}, {0x00ec, "i"},
- {0x00ed, "i"}, {0x00ee, "i"}, {0x00ef, "i"}, {0x00f1, "n"},
- {0x00f2, "o"}, {0x00f3, "o"}, {0x00f4, "o"}, {0x00f5, "o"},
- {0x00f6, "o"}, {0x00f7, "/"}, {0x00f8, "o"}, {0x00f9, "u"},
- {0x00fa, "u"}, {0x00fb, "u"}, {0x00fc, "u"}, {0x00fd, "y"},
- {0x00ff, "y"}, {0x02b0, "h"}, {0x02b2, "j"}, {0x02b3, "r"},
- {0x02b7, "w"}, {0x02b8, "y"}, {0x02b9, "'"}, {0x02ba, "\""},
- {0x02bb, "'"}, {0x02bc, "'"}, {0x02bd, "'"}, {0x02be, "'"},
- {0x02bf, "'"}, {0x02c2, "<"}, {0x02c3, ">"}, {0x02c4, "^"},
- {0x02c5, "v"}, {0x02c6, "^"}, {0x02c7, "v"}, {0x02c8, "'"},
- {0x02c9, "-"}, {0x02ca, "'"}, {0x02cb, "'"}, {0x02cc, "."},
- {0x02cd, "_"}, {0x2010, "-"}, {0x2012, "-"}, {0x2013, "-"},
- {0x2014, "--"}, {0x2015, "--"}, {0x2016, "|"}, {0x2017, "_"},
- {0x2018, "'"}, {0x2019, "'"}, {0x201a, ","}, {0x201b, "'"},
- {0x201c, "\""}, {0x201d, "\""}, {0x201e, ","}, {0x201f, "'"},
- {0x2020, "+"}, {0x2021, "+"}, {0x2022, "*"}, {0x2023, ">"},
- {0x2024, "."}, {0x2025, ".."}, {0x2027, "."}, {0x2032, "'"},
- {0x2033, "\""}, {0x2035, "'"}, {0x2036, "\""}, {0x2038, "^"},
- {0x2039, "<"}, {0x203a, ">"}, {0x203b, "*"}, {0x203c, "!!"},
- {0x203d, "?!"}, {0x203e, "-"}, {0x2044, "/"}, {0x2047, "??"},
- {0x2048, "?!"}, {0x2049, "!?"}, {0x204e, "*"}, {0x2052, "%"},
- {0x2122, "(TM)"}, {0x2212, "-"}, {0x2215, "/"}, {0x2216, "\\"},
- {0x2217, "*"}, {0x2218, "*"}, {0x2219, "*"}, {0x2223, "|"},
- {0x22c5, "."}, {0x266f, "#"}, {0XF6D9, "(C)"}, {0XF6DA, "(C)"},
- {0XF6DB, "(TM)"}, {0XF8E8, "(C)"}, {0xf8e9, "(C)"}, {0XF8EA, "(TM)"},
- {0xfb01, "fi"}, {0xfb02, "fl"}};
-const FX_CHAR* FCS_GetAltStr(FX_WCHAR unicode) {
- int begin = 0;
- int end = sizeof UnicodeAlts / sizeof(struct _UnicodeAlt) - 1;
- while (begin <= end) {
- int middle = (begin + end) / 2;
- uint16_t middlecode = UnicodeAlts[middle].m_Unicode;
- if (middlecode > unicode) {
- end = middle - 1;
- } else if (middlecode < unicode) {
- begin = middle + 1;
- } else {
- return UnicodeAlts[middle].m_Alter;
- }
- }
- return NULL;
-}
-static const uint16_t StandardEncoding[256] = {
+namespace {
+
+const uint16_t MSSymbolEncoding[256] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 32, 33, 8704, 35,
+ 8707, 37, 38, 8715, 40, 41, 8727, 43, 44,
+ 8722, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 8773, 913, 914, 935, 916, 917, 934, 915,
+ 919, 921, 977, 922, 923, 924, 925, 927, 928,
+ 920, 929, 931, 932, 933, 962, 937, 926, 936,
+ 918, 91, 8756, 93, 8869, 95, 8254, 945, 946,
+ 967, 948, 949, 966, 947, 951, 953, 981, 954,
+ 955, 956, 957, 959, 960, 952, 961, 963, 964,
+ 965, 982, 969, 958, 968, 950, 123, 124, 125,
+ 8764, 0, 0, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 978,
+ 8242, 8804, 8725, 8734, 402, 9827, 9830, 9828, 9824,
+ 8596, 8592, 8593, 8594, 8595, 176, 177, 8243, 8805,
+ 215, 8733, 8706, 8729, 247, 8800, 8801, 8776, 8943,
+ 0, 0, 8629, 0, 8465, 8476, 8472, 8855, 8853,
+ 8709, 8745, 8746, 8835, 8839, 8836, 8834, 8838, 8712,
+ 8713, 8736, 8711, 174, 169, 8482, 8719, 8730, 8901,
+ 172, 8743, 8744, 8660, 8656, 8657, 8658, 8659, 9674,
+ 9001, 0, 0, 0, 8721, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0x0000, 9002, 8747,
+ 8992, 0, 8993, 0, 0, 0, 0, 0, 0,
+ 0x0000, 0x0000, 0x0000, 0x0000};
+
+const uint16_t StandardEncoding[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -101,7 +76,8 @@ static const uint16_t StandardEncoding[256] = {
0x0152, 0x00ba, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00e6, 0x0000,
0x0000, 0x0000, 0x0131, 0x0000, 0x0000, 0x0142, 0x00f8, 0x0153, 0x00df,
0x0000, 0x0000, 0x0000, 0x0000};
-static const uint16_t MacRomanEncoding[256] = {
+
+const uint16_t MacRomanEncoding[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -131,7 +107,8 @@ static const uint16_t MacRomanEncoding[256] = {
0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, 0x0000, 0x00d2, 0x00da,
0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, 0x02da,
0x00b8, 0x02dd, 0x02db, 0x02c7};
-static const uint16_t AdobeWinAnsiEncoding[256] = {
+
+const uint16_t AdobeWinAnsiEncoding[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -161,7 +138,8 @@ static const uint16_t AdobeWinAnsiEncoding[256] = {
0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
0x00fc, 0x00fd, 0x00fe, 0x00ff};
-static const uint16_t MacExpertEncoding[256] = {
+
+const uint16_t MacExpertEncoding[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -191,7 +169,8 @@ static const uint16_t MacExpertEncoding[256] = {
0xf6f2, 0xf6eb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf6ee, 0xf6fb,
0xf6f4, 0xf7af, 0xf6ea, 0x207f, 0xf6ef, 0xf6e2, 0xf6e8, 0xf6f7, 0xf6fc,
0x0000, 0x0000, 0x0000, 0x0000};
-static const uint16_t AdobeSymbolEncoding[256] = {
+
+const uint16_t AdobeSymbolEncoding[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -222,7 +201,8 @@ static const uint16_t AdobeSymbolEncoding[256] = {
0x2320, 0xF8F5, 0x2321, 0xF8F6, 0xF8F7, 0xF8F8, 0xF8F9, 0xF8FA, 0xF8FB,
0xF8FC, 0xF8FD, 0xF8FE, 0x0000,
};
-static const uint16_t ZapfEncoding[256] = {
+
+const uint16_t ZapfEncoding[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -253,7 +233,8 @@ static const uint16_t ZapfEncoding[256] = {
0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, 0x27B8, 0x27B9, 0x27BA, 0x27BB,
0x27BC, 0x27BD, 0x27BE, 0x0000,
};
-static const FX_CHAR* const StandardEncodingNames[224] = {
+
+const FX_CHAR* const StandardEncodingNames[224] = {
"space",
"exclam",
"quotedbl",
@@ -479,7 +460,8 @@ static const FX_CHAR* const StandardEncodingNames[224] = {
NULL,
NULL,
};
-static const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = {
+
+const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = {
"space",
"exclam",
"quotedbl",
@@ -705,7 +687,8 @@ static const FX_CHAR* const AdobeWinAnsiEncodingNames[224] = {
"thorn",
"ydieresis",
};
-static const FX_CHAR* const MacRomanEncodingNames[224] = {
+
+const FX_CHAR* const MacRomanEncodingNames[224] = {
"space",
"exclam",
"quotedbl",
@@ -931,7 +914,8 @@ static const FX_CHAR* const MacRomanEncodingNames[224] = {
"ogonek",
"caron",
};
-static const FX_CHAR* const MacExpertEncodingNames[224] = {
+
+const FX_CHAR* const MacExpertEncodingNames[224] = {
"space",
"exclamsmall",
"Hungarumlautsmall",
@@ -1157,7 +1141,8 @@ static const FX_CHAR* const MacExpertEncodingNames[224] = {
NULL,
NULL,
};
-static const FX_CHAR* const PDFDocEncodingNames[232] = {
+
+const FX_CHAR* const PDFDocEncodingNames[232] = {
"breve",
"caron",
"circumflex",
@@ -1391,7 +1376,8 @@ static const FX_CHAR* const PDFDocEncodingNames[232] = {
"thorn",
"ydieresis",
};
-static const FX_CHAR* const AdobeSymbolEncodingNames[224] = {
+
+const FX_CHAR* const AdobeSymbolEncodingNames[224] = {
"space",
"exclam",
"universal",
@@ -1617,7 +1603,8 @@ static const FX_CHAR* const AdobeSymbolEncodingNames[224] = {
"bracerightbt",
NULL,
};
-static const FX_CHAR* const ZapfEncodingNames[224] = {
+
+const FX_CHAR* const ZapfEncodingNames[224] = {
"space", "a1", "a2", "a202", "a3", "a4", "a5", "a119", "a118",
"a117", "a11", "a12", "a13", "a14", "a15", "a16", "a105", "a17",
"a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26",
@@ -1643,91 +1630,89 @@ static const FX_CHAR* const ZapfEncodingNames[224] = {
"a176", "a177", "a178", "a179", "a193", "a180", "a199", "a181", "a200",
"a182", NULL, "a201", "a183", "a184", "a197", "a185", "a194", "a198",
"a186", "a195", "a187", "a188", "a189", "a190", "a191", NULL};
-const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding,
- uint8_t charcode) {
- if (encoding == PDFFONT_ENCODING_PDFDOC) {
- if (charcode < 24) {
- return NULL;
+
+FX_DWORD PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) {
+ for (FX_DWORD i = 0; i < 256; i++)
+ if (pCodes[i] == unicode)
+ return i;
+ return 0;
+}
+
+} // namespace
+
+CPDF_FontEncoding::CPDF_FontEncoding() {
+ FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
+}
+
+int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ for (int i = 0; i < 256; i++)
+ if (m_Unicodes[i] == unicode) {
+ return i;
}
- charcode -= 24;
+ return -1;
+}
+
+CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) {
+ const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
+ if (!pSrc) {
+ FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
} else {
- if (charcode < 32) {
- return NULL;
- }
- charcode -= 32;
+ for (int i = 0; i < 256; i++)
+ m_Unicodes[i] = pSrc[i];
}
- switch (encoding) {
- case PDFFONT_ENCODING_WINANSI:
- return AdobeWinAnsiEncodingNames[charcode];
- case PDFFONT_ENCODING_MACROMAN:
- return MacRomanEncodingNames[charcode];
- case PDFFONT_ENCODING_MACEXPERT:
- return MacExpertEncodingNames[charcode];
- case PDFFONT_ENCODING_STANDARD:
- return StandardEncodingNames[charcode];
- case PDFFONT_ENCODING_ADOBE_SYMBOL:
- return AdobeSymbolEncodingNames[charcode];
- case PDFFONT_ENCODING_ZAPFDINGBATS:
- return ZapfEncodingNames[charcode];
- case PDFFONT_ENCODING_PDFDOC:
- return PDFDocEncodingNames[charcode];
- }
- return NULL;
}
-FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode) {
- switch (encoding) {
- case FXFT_ENCODING_UNICODE:
- return (uint16_t)charcode;
- case FXFT_ENCODING_ADOBE_STANDARD:
- return StandardEncoding[(uint8_t)charcode];
- case FXFT_ENCODING_ADOBE_EXPERT:
- return MacExpertEncoding[(uint8_t)charcode];
- case FXFT_ENCODING_ADOBE_LATIN_1:
- return AdobeWinAnsiEncoding[(uint8_t)charcode];
- case FXFT_ENCODING_APPLE_ROMAN:
- return MacRomanEncoding[(uint8_t)charcode];
- case PDFFONT_ENCODING_PDFDOC:
- return PDFDocEncoding[(uint8_t)charcode];
- }
- return 0;
+
+FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const {
+ return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) ==
+ 0;
}
-static FX_DWORD PDF_FindCode(const uint16_t* pCodes, uint16_t unicode) {
- for (FX_DWORD i = 0; i < 256; i++)
- if (pCodes[i] == unicode) {
- return i;
+
+CPDF_Object* CPDF_FontEncoding::Realize() {
+ int predefined = 0;
+ for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS;
+ cs++) {
+ const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
+ FX_BOOL match = TRUE;
+ for (int i = 0; i < 256; ++i) {
+ if (m_Unicodes[i] != pSrc[i]) {
+ match = FALSE;
+ break;
+ }
}
- return 0;
+ if (match) {
+ predefined = cs;
+ break;
+ }
+ }
+ if (predefined) {
+ if (predefined == PDFFONT_ENCODING_WINANSI) {
+ return new CPDF_Name("WinAnsiEncoding");
+ }
+ if (predefined == PDFFONT_ENCODING_MACROMAN) {
+ return new CPDF_Name("MacRomanEncoding");
+ }
+ if (predefined == PDFFONT_ENCODING_MACEXPERT) {
+ return new CPDF_Name("MacExpertEncoding");
+ }
+ return NULL;
+ }
+ const uint16_t* pStandard =
+ PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
+ CPDF_Array* pDiff = new CPDF_Array;
+ for (int i = 0; i < 256; i++) {
+ if (pStandard[i] == m_Unicodes[i]) {
+ continue;
+ }
+ pDiff->Add(new CPDF_Number(i));
+ pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
+ }
+
+ CPDF_Dictionary* pDict = new CPDF_Dictionary;
+ pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
+ pDict->SetAt("Differences", pDiff);
+ return pDict;
}
-static const uint16_t MSSymbolEncoding[256] = {
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 32, 33, 8704, 35,
- 8707, 37, 38, 8715, 40, 41, 8727, 43, 44,
- 8722, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 62,
- 63, 8773, 913, 914, 935, 916, 917, 934, 915,
- 919, 921, 977, 922, 923, 924, 925, 927, 928,
- 920, 929, 931, 932, 933, 962, 937, 926, 936,
- 918, 91, 8756, 93, 8869, 95, 8254, 945, 946,
- 967, 948, 949, 966, 947, 951, 953, 981, 954,
- 955, 956, 957, 959, 960, 952, 961, 963, 964,
- 965, 982, 969, 958, 968, 950, 123, 124, 125,
- 8764, 0, 0, 0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 978,
- 8242, 8804, 8725, 8734, 402, 9827, 9830, 9828, 9824,
- 8596, 8592, 8593, 8594, 8595, 176, 177, 8243, 8805,
- 215, 8733, 8706, 8729, 247, 8800, 8801, 8776, 8943,
- 0, 0, 8629, 0, 8465, 8476, 8472, 8855, 8853,
- 8709, 8745, 8746, 8835, 8839, 8836, 8834, 8838, 8712,
- 8713, 8736, 8711, 174, 169, 8482, 8719, 8730, 8901,
- 172, 8743, 8744, 8660, 8656, 8657, 8658, 8659, 9674,
- 9001, 0, 0, 0, 8721, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0x0000, 9002, 8747,
- 8992, 0, 8993, 0, 0, 0, 0, 0, 0,
- 0x0000, 0x0000, 0x0000, 0x0000};
+
FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode) {
switch (encoding) {
case FXFT_ENCODING_UNICODE:
@@ -1768,14 +1753,63 @@ const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding) {
}
return NULL;
}
-FX_DWORD PDF_PredefinedCharCodeFromUnicode(int encoding, FX_WCHAR unicode) {
- return PDF_FindCode(PDF_UnicodesForPredefinedCharSet(encoding), unicode);
-}
+
FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name) {
return (FX_WCHAR)(FXFT_unicode_from_adobe_name(name) & 0x7FFFFFFF);
}
+
CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode) {
char glyph_name[64];
FXFT_adobe_name_from_unicode(glyph_name, unicode);
return CFX_ByteString(glyph_name);
}
+
+const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding,
+ uint8_t charcode) {
+ if (encoding == PDFFONT_ENCODING_PDFDOC) {
+ if (charcode < 24)
+ return NULL;
+
+ charcode -= 24;
+ } else {
+ if (charcode < 32)
+ return NULL;
+
+ charcode -= 32;
+ }
+ switch (encoding) {
+ case PDFFONT_ENCODING_WINANSI:
+ return AdobeWinAnsiEncodingNames[charcode];
+ case PDFFONT_ENCODING_MACROMAN:
+ return MacRomanEncodingNames[charcode];
+ case PDFFONT_ENCODING_MACEXPERT:
+ return MacExpertEncodingNames[charcode];
+ case PDFFONT_ENCODING_STANDARD:
+ return StandardEncodingNames[charcode];
+ case PDFFONT_ENCODING_ADOBE_SYMBOL:
+ return AdobeSymbolEncodingNames[charcode];
+ case PDFFONT_ENCODING_ZAPFDINGBATS:
+ return ZapfEncodingNames[charcode];
+ case PDFFONT_ENCODING_PDFDOC:
+ return PDFDocEncodingNames[charcode];
+ }
+ return nullptr;
+}
+
+FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode) {
+ switch (encoding) {
+ case FXFT_ENCODING_UNICODE:
+ return (uint16_t)charcode;
+ case FXFT_ENCODING_ADOBE_STANDARD:
+ return StandardEncoding[(uint8_t)charcode];
+ case FXFT_ENCODING_ADOBE_EXPERT:
+ return MacExpertEncoding[(uint8_t)charcode];
+ case FXFT_ENCODING_ADOBE_LATIN_1:
+ return AdobeWinAnsiEncoding[(uint8_t)charcode];
+ case FXFT_ENCODING_APPLE_ROMAN:
+ return MacRomanEncoding[(uint8_t)charcode];
+ case PDFFONT_ENCODING_PDFDOC:
+ return PDFDocEncoding[(uint8_t)charcode];
+ }
+ return 0;
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp
new file mode 100644
index 0000000000..d7057e1894
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_simplefont.cpp
@@ -0,0 +1,222 @@
+// 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_simplefont.h"
+
+#include "core/fpdfapi/fpdf_font/font_int.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/include/fxge/fx_freetype.h"
+
+CPDF_SimpleFont::CPDF_SimpleFont()
+ : m_pCharNames(nullptr), m_BaseEncoding(PDFFONT_ENCODING_BUILTIN) {
+ FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
+ FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
+ FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
+}
+
+CPDF_SimpleFont::~CPDF_SimpleFont() {
+ delete[] m_pCharNames;
+}
+
+int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
+ if (pVertGlyph) {
+ *pVertGlyph = FALSE;
+ }
+ if (charcode > 0xff) {
+ return -1;
+ }
+ int index = m_GlyphIndex[(uint8_t)charcode];
+ if (index == 0xffff) {
+ return -1;
+ }
+ return index;
+}
+
+void CPDF_SimpleFont::LoadCharMetrics(int charcode) {
+ if (!m_Font.GetFace())
+ return;
+
+ if (charcode < 0 || charcode > 0xff) {
+ return;
+ }
+ int glyph_index = m_GlyphIndex[charcode];
+ if (glyph_index == 0xffff) {
+ if (!m_pFontFile && charcode != 32) {
+ LoadCharMetrics(32);
+ m_CharBBox[charcode] = m_CharBBox[32];
+ if (m_bUseFontWidth) {
+ m_CharWidth[charcode] = m_CharWidth[32];
+ }
+ }
+ return;
+ }
+ FXFT_Face face = m_Font.GetFace();
+ int err = FXFT_Load_Glyph(
+ face, glyph_index,
+ FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ if (err) {
+ return;
+ }
+ m_CharBBox[charcode] = FX_SMALL_RECT(
+ TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
+ TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
+ TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face),
+ face),
+ TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face),
+ face));
+
+ if (m_bUseFontWidth) {
+ int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face);
+ if (m_CharWidth[charcode] == 0xffff) {
+ m_CharWidth[charcode] = TT_Width;
+ } else if (TT_Width && !IsEmbedded()) {
+ m_CharBBox[charcode].right =
+ m_CharBBox[charcode].right * m_CharWidth[charcode] / TT_Width;
+ m_CharBBox[charcode].left =
+ m_CharBBox[charcode].left * m_CharWidth[charcode] / TT_Width;
+ }
+ }
+}
+
+int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) {
+ if (charcode > 0xff) {
+ charcode = 0;
+ }
+ if (m_CharWidth[charcode] == 0xffff) {
+ LoadCharMetrics(charcode);
+ if (m_CharWidth[charcode] == 0xffff) {
+ m_CharWidth[charcode] = 0;
+ }
+ }
+ return (int16_t)m_CharWidth[charcode];
+}
+
+FX_RECT CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, int level) {
+ if (charcode > 0xff)
+ charcode = 0;
+
+ if (m_CharBBox[charcode].left == FX_SMALL_RECT::kInvalid)
+ LoadCharMetrics(charcode);
+
+ return FX_RECT(m_CharBBox[charcode]);
+}
+
+FX_BOOL CPDF_SimpleFont::LoadCommon() {
+ CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc) {
+ LoadFontDescriptor(pFontDesc);
+ }
+ CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
+ int width_start = 0, width_end = -1;
+ m_bUseFontWidth = TRUE;
+ if (pWidthArray) {
+ m_bUseFontWidth = FALSE;
+ if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
+ int MissingWidth = pFontDesc->GetIntegerBy("MissingWidth");
+ for (int i = 0; i < 256; i++) {
+ m_CharWidth[i] = MissingWidth;
+ }
+ }
+ width_start = m_pFontDict->GetIntegerBy("FirstChar", 0);
+ width_end = m_pFontDict->GetIntegerBy("LastChar", 0);
+ if (width_start >= 0 && width_start <= 255) {
+ if (width_end <= 0 ||
+ width_end >= width_start + (int)pWidthArray->GetCount()) {
+ width_end = width_start + pWidthArray->GetCount() - 1;
+ }
+ if (width_end > 255) {
+ width_end = 255;
+ }
+ for (int i = width_start; i <= width_end; i++) {
+ m_CharWidth[i] = pWidthArray->GetIntegerAt(i - width_start);
+ }
+ }
+ }
+ if (m_pFontFile) {
+ if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
+ m_BaseFont = m_BaseFont.Mid(8);
+ }
+ } else {
+ LoadSubstFont();
+ }
+ if (!(m_Flags & PDFFONT_SYMBOLIC)) {
+ m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
+ }
+ CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
+ LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
+ m_Font.IsTTFont());
+ LoadGlyphMap();
+ delete[] m_pCharNames;
+ m_pCharNames = NULL;
+ if (!m_Font.GetFace())
+ return TRUE;
+
+ if (m_Flags & PDFFONT_ALLCAP) {
+ unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
+ for (size_t range = 0; range < sizeof lowercases / 2; range++) {
+ for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
+ if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
+ continue;
+ }
+ m_GlyphIndex[i] = m_GlyphIndex[i - 32];
+ if (m_CharWidth[i - 32]) {
+ m_CharWidth[i] = m_CharWidth[i - 32];
+ m_CharBBox[i] = m_CharBBox[i - 32];
+ }
+ }
+ }
+ }
+ CheckFontMetrics();
+ return TRUE;
+}
+
+void CPDF_SimpleFont::LoadSubstFont() {
+ if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
+ int width = 0, i;
+ for (i = 0; i < 256; i++) {
+ if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
+ continue;
+ }
+ if (width == 0) {
+ width = m_CharWidth[i];
+ } else if (width != m_CharWidth[i]) {
+ break;
+ }
+ }
+ if (i == 256 && width) {
+ m_Flags |= PDFFONT_FIXEDPITCH;
+ }
+ }
+ int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
+ m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, weight, m_ItalicAngle,
+ 0);
+ if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
+ }
+}
+
+FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const {
+ return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN &&
+ m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
+ m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
+}
+
+CFX_WideString CPDF_SimpleFont::UnicodeFromCharCode(FX_DWORD charcode) const {
+ CFX_WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode);
+ if (!unicode.IsEmpty())
+ return unicode;
+ FX_WCHAR ret = m_Encoding.UnicodeFromCharCode((uint8_t)charcode);
+ if (ret == 0)
+ return CFX_WideString();
+ return ret;
+}
+
+FX_DWORD CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
+ FX_DWORD ret = CPDF_Font::CharCodeFromUnicode(unicode);
+ if (ret)
+ return ret;
+ return m_Encoding.CharCodeFromUnicode(unicode);
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_simplefont.h b/core/fpdfapi/fpdf_font/cpdf_simplefont.h
new file mode 100644
index 0000000000..19d6816c9f
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_simplefont.h
@@ -0,0 +1,48 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_SIMPLEFONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_SIMPLEFONT_H_
+
+#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
+#include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h"
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_SimpleFont : public CPDF_Font {
+ public:
+ CPDF_SimpleFont();
+ virtual ~CPDF_SimpleFont();
+
+ // CPDF_Font:
+ int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
+ FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) override;
+ int GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph = NULL) override;
+ FX_BOOL IsUnicodeCompatible() const override;
+ CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const override;
+ FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const override;
+
+ CPDF_FontEncoding* GetEncoding() { return &m_Encoding; }
+
+ protected:
+ virtual void LoadGlyphMap() = 0;
+
+ FX_BOOL LoadCommon();
+ void LoadSubstFont();
+ void LoadFaceMetrics();
+ void LoadCharMetrics(int charcode);
+
+ CPDF_FontEncoding m_Encoding;
+ uint16_t m_GlyphIndex[256];
+ uint16_t m_ExtGID[256];
+ CFX_ByteString* m_pCharNames;
+ int m_BaseEncoding;
+ uint16_t m_CharWidth[256];
+ FX_SMALL_RECT m_CharBBox[256];
+ FX_BOOL m_bUseFontWidth;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_SIMPLEFONT_H_
diff --git a/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp b/core/fpdfapi/fpdf_font/cpdf_truetypefont.cpp
new file mode 100644
index 0000000000..13e031808e
--- /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;
+ }
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_truetypefont.h b/core/fpdfapi/fpdf_font/cpdf_truetypefont.h
new file mode 100644
index 0000000000..46b19e513d
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_truetypefont.h
@@ -0,0 +1,30 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_
+
+#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_TrueTypeFont : public CPDF_SimpleFont {
+ public:
+ CPDF_TrueTypeFont();
+
+ // CPDF_Font:
+ bool IsTrueTypeFont() const override;
+ const CPDF_TrueTypeFont* AsTrueTypeFont() const override;
+ CPDF_TrueTypeFont* AsTrueTypeFont() override;
+
+ protected:
+ // CPDF_Font:
+ FX_BOOL Load() override;
+
+ // CPDF_SimpleFont:
+ void LoadGlyphMap() override;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TRUETYPEFONT_H_
diff --git a/core/fpdfapi/fpdf_font/cpdf_type1font.cpp b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp
new file mode 100644
index 0000000000..5a6ee34362
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp
@@ -0,0 +1,403 @@
+// 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_type1font.h"
+
+#include "core/fpdfapi/fpdf_font/font_int.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/include/fxge/fx_freetype.h"
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+#include "core/fxge/apple/apple_int.h"
+#endif
+
+namespace {
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+struct GlyphNameMap {
+ const FX_CHAR* m_pStrAdobe;
+ const FX_CHAR* m_pStrUnicode;
+};
+
+const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"},
+ {"fi", "uniFB01"},
+ {"fl", "uniFB02"},
+ {"ffi", "uniFB03"},
+ {"ffl", "uniFB04"}};
+
+int compareString(const void* key, const void* element) {
+ return FXSYS_stricmp((const FX_CHAR*)key,
+ ((GlyphNameMap*)element)->m_pStrAdobe);
+}
+
+const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) {
+ GlyphNameMap* found = (GlyphNameMap*)FXSYS_bsearch(
+ pStrAdobe, g_GlyphNameSubsts,
+ sizeof(g_GlyphNameSubsts) / sizeof(GlyphNameMap), sizeof(GlyphNameMap),
+ compareString);
+ if (found)
+ return found->m_pStrUnicode;
+ return NULL;
+}
+
+#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+
+FX_BOOL FT_UseType1Charmap(FXFT_Face face) {
+ if (FXFT_Get_Face_CharmapCount(face) == 0) {
+ return FALSE;
+ }
+ if (FXFT_Get_Face_CharmapCount(face) == 1 &&
+ FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
+ FXFT_ENCODING_UNICODE) {
+ return FALSE;
+ }
+ if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
+ FXFT_ENCODING_UNICODE) {
+ FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
+ } else {
+ FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
+ }
+ return TRUE;
+}
+
+} // namespace
+
+CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {}
+
+bool CPDF_Type1Font::IsType1Font() const {
+ return true;
+}
+
+const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
+ return this;
+}
+
+CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
+ return this;
+}
+
+FX_BOOL CPDF_Type1Font::Load() {
+ m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
+ if (m_Base14Font >= 0) {
+ CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
+ if (pFontDesc && pFontDesc->KeyExist("Flags"))
+ m_Flags = pFontDesc->GetIntegerBy("Flags");
+ else
+ m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
+
+ if (m_Base14Font < 4) {
+ for (int i = 0; i < 256; i++)
+ m_CharWidth[i] = 600;
+ }
+ if (m_Base14Font == 12)
+ m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
+ else if (m_Base14Font == 13)
+ m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
+ else if (m_Flags & PDFFONT_NONSYMBOLIC)
+ m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
+ }
+ return LoadCommon();
+}
+
+int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
+ if (charcode > 0xff) {
+ return -1;
+ }
+ int index = m_ExtGID[(uint8_t)charcode];
+ if (index == 0xffff) {
+ return -1;
+ }
+ return index;
+}
+
+void CPDF_Type1Font::LoadGlyphMap() {
+ if (!m_Font.GetFace())
+ return;
+
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ FX_BOOL bCoreText = TRUE;
+ CQuartz2D& quartz2d =
+ ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ if (!m_Font.GetPlatformFont()) {
+ if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
+ bCoreText = FALSE;
+ }
+ m_Font.SetPlatformFont(
+ quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
+ if (!m_Font.GetPlatformFont()) {
+ bCoreText = FALSE;
+ }
+ }
+#endif
+ if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
+ if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
+ FX_BOOL bGotOne = FALSE;
+ for (int charcode = 0; charcode < 256; charcode++) {
+ 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 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ FX_CHAR name_glyph[256];
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
+ name_glyph, 256);
+ name_glyph[255] = 0;
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+#endif
+ if (m_GlyphIndex[charcode]) {
+ bGotOne = TRUE;
+ break;
+ }
+ }
+ }
+ if (bGotOne) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!bCoreText) {
+ FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+ }
+#endif
+ return;
+ }
+ }
+ FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
+ if (m_BaseEncoding == 0) {
+ m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
+ }
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (!name) {
+ continue;
+ }
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
+ m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ FX_CHAR name_glyph[256];
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph,
+ 256);
+ name_glyph[255] = 0;
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+#endif
+ if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
+ m_Encoding.m_Unicodes[charcode] = 0x20;
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ FX_CHAR name_glyph[256];
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
+ name_glyph, 256);
+ name_glyph[255] = 0;
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+#endif
+ }
+ }
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!bCoreText) {
+ FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+ }
+#endif
+ return;
+ }
+ FT_UseType1Charmap(m_Font.GetFace());
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (bCoreText) {
+ if (m_Flags & PDFFONT_SYMBOLIC) {
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (name) {
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+ m_GlyphIndex[charcode] =
+ FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+ } else {
+ m_GlyphIndex[charcode] =
+ FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
+ FX_WCHAR unicode = 0;
+ if (m_GlyphIndex[charcode]) {
+ unicode =
+ FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
+ }
+ FX_CHAR name_glyph[256];
+ FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
+ name_glyph, 256);
+ name_glyph[255] = 0;
+ if (unicode == 0 && name_glyph[0] != 0) {
+ unicode = PDF_UnicodeFromAdobeName(name_glyph);
+ }
+ m_Encoding.m_Unicodes[charcode] = unicode;
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+ }
+ }
+ return;
+ }
+ FX_BOOL bUnicode = FALSE;
+ if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
+ bUnicode = TRUE;
+ }
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (!name) {
+ continue;
+ }
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+ const FX_CHAR* pStrUnicode = GlyphNameRemap(name);
+ if (pStrUnicode &&
+ 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) {
+ name = pStrUnicode;
+ }
+ m_GlyphIndex[charcode] =
+ FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+ if (m_GlyphIndex[charcode] == 0) {
+ if (FXSYS_strcmp(name, ".notdef") != 0 &&
+ FXSYS_strcmp(name, "space") != 0) {
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
+ m_Font.GetFace(),
+ bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
+ FX_CHAR name_glyph[256];
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
+ name_glyph, 256);
+ name_glyph[255] = 0;
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+ } else {
+ m_Encoding.m_Unicodes[charcode] = 0x20;
+ m_GlyphIndex[charcode] =
+ bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff;
+ FX_CHAR name_glyph[256];
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
+ name_glyph, 256);
+ name_glyph[255] = 0;
+ CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
+ kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
+ kCFAllocatorNull);
+ m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
+ (CGFontRef)m_Font.GetPlatformFont(), name_ct);
+ if (name_ct) {
+ CFRelease(name_ct);
+ }
+ }
+ }
+ }
+ return;
+ }
+#endif
+ if (m_Flags & PDFFONT_SYMBOLIC) {
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (name) {
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+ m_GlyphIndex[charcode] =
+ FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
+ } else {
+ m_GlyphIndex[charcode] =
+ FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
+ if (m_GlyphIndex[charcode]) {
+ FX_WCHAR unicode =
+ FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
+ if (unicode == 0) {
+ FX_CHAR name_glyph[256];
+ FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
+ FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
+ name_glyph, 256);
+ name_glyph[255] = 0;
+ if (name_glyph[0] != 0) {
+ unicode = PDF_UnicodeFromAdobeName(name_glyph);
+ }
+ }
+ m_Encoding.m_Unicodes[charcode] = unicode;
+ }
+ }
+ }
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!bCoreText) {
+ FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+ }
+#endif
+ return;
+ }
+ FX_BOOL bUnicode = FALSE;
+ if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
+ bUnicode = TRUE;
+ }
+ for (int charcode = 0; charcode < 256; charcode++) {
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (!name) {
+ continue;
+ }
+ m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+ m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
+ if (m_GlyphIndex[charcode] == 0) {
+ if (FXSYS_strcmp(name, ".notdef") != 0 &&
+ FXSYS_strcmp(name, "space") != 0) {
+ m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
+ m_Font.GetFace(),
+ bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
+ } else {
+ m_Encoding.m_Unicodes[charcode] = 0x20;
+ m_GlyphIndex[charcode] = 0xffff;
+ }
+ }
+ }
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!bCoreText) {
+ FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+ }
+#endif
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_type1font.h b/core/fpdfapi/fpdf_font/cpdf_type1font.h
new file mode 100644
index 0000000000..da82cd4417
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type1font.h
@@ -0,0 +1,35 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_
+
+#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_Type1Font : public CPDF_SimpleFont {
+ public:
+ CPDF_Type1Font();
+
+ // CPDF_Font:
+ bool IsType1Font() const override;
+ const CPDF_Type1Font* AsType1Font() const override;
+ CPDF_Type1Font* AsType1Font() override;
+ int GlyphFromCharCodeExt(FX_DWORD charcode) override;
+
+ int GetBase14Font() const { return m_Base14Font; }
+
+ protected:
+ // CPDF_Font:
+ FX_BOOL Load() override;
+
+ // CPDF_SimpleFont:
+ void LoadGlyphMap() override;
+
+ int m_Base14Font;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE1FONT_H_
diff --git a/core/fpdfapi/fpdf_font/cpdf_type3char.cpp b/core/fpdfapi/fpdf_font/cpdf_type3char.cpp
new file mode 100644
index 0000000000..c9d44435a3
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3char.cpp
@@ -0,0 +1,43 @@
+// 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_type3char.h"
+
+#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_image.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
+#include "core/include/fxge/fx_dib.h"
+
+CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
+ : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
+
+CPDF_Type3Char::~CPDF_Type3Char() {
+ delete m_pForm;
+ delete m_pBitmap;
+}
+
+FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) {
+ if (m_pBitmap || !m_pForm) {
+ return TRUE;
+ }
+ if (m_pForm->GetPageObjectList()->size() == 1 && !m_bColored) {
+ auto& pPageObj = m_pForm->GetPageObjectList()->front();
+ if (pPageObj->IsImage()) {
+ m_ImageMatrix = pPageObj->AsImage()->m_Matrix;
+ const CFX_DIBSource* pSource =
+ pPageObj->AsImage()->m_pImage->LoadDIBSource();
+ if (pSource) {
+ m_pBitmap = pSource->Clone();
+ delete pSource;
+ }
+ delete m_pForm;
+ m_pForm = NULL;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_type3char.h b/core/fpdfapi/fpdf_font/cpdf_type3char.h
new file mode 100644
index 0000000000..c67620b5f6
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3char.h
@@ -0,0 +1,33 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3CHAR_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3CHAR_H_
+
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CFX_DIBitmap;
+class CPDF_Form;
+class CPDF_RenderContext;
+
+class CPDF_Type3Char {
+ public:
+ // Takes ownership of |pForm|.
+ explicit CPDF_Type3Char(CPDF_Form* pForm);
+ ~CPDF_Type3Char();
+
+ FX_BOOL LoadBitmap(CPDF_RenderContext* pContext);
+
+ CPDF_Form* m_pForm;
+ CFX_DIBitmap* m_pBitmap;
+ FX_BOOL m_bColored;
+ int m_Width;
+ CFX_Matrix m_ImageMatrix;
+ FX_RECT m_BBox;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3CHAR_H_
diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.cpp b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp
new file mode 100644
index 0000000000..91a03a9830
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3font.cpp
@@ -0,0 +1,162 @@
+// 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_type3font.h"
+
+#include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
+#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
+#include "core/fpdfapi/fpdf_page/pageint.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
+#include "core/fxcrt/include/fx_system.h"
+#include "third_party/base/stl_util.h"
+
+CPDF_Type3Font::CPDF_Type3Font()
+ : m_pCharProcs(nullptr),
+ m_pPageResources(nullptr),
+ m_pFontResources(nullptr) {
+ FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
+}
+
+CPDF_Type3Font::~CPDF_Type3Font() {
+ for (auto it : m_CacheMap)
+ delete it.second;
+}
+
+bool CPDF_Type3Font::IsType3Font() const {
+ return true;
+}
+
+const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
+ return this;
+}
+
+CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
+ return this;
+}
+
+FX_BOOL CPDF_Type3Font::Load() {
+ m_pFontResources = m_pFontDict->GetDictBy("Resources");
+ CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("FontMatrix");
+ FX_FLOAT xscale = 1.0f, yscale = 1.0f;
+ if (pMatrix) {
+ m_FontMatrix = pMatrix->GetMatrix();
+ xscale = m_FontMatrix.a;
+ yscale = m_FontMatrix.d;
+ }
+ CPDF_Array* pBBox = m_pFontDict->GetArrayBy("FontBBox");
+ if (pBBox) {
+ m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000);
+ m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000);
+ m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000);
+ m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000);
+ }
+ int StartChar = m_pFontDict->GetIntegerBy("FirstChar");
+ CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
+ if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
+ FX_DWORD count = pWidthArray->GetCount();
+ if (count > 256) {
+ count = 256;
+ }
+ if (StartChar + count > 256) {
+ count = 256 - StartChar;
+ }
+ for (FX_DWORD i = 0; i < count; i++) {
+ m_CharWidthL[StartChar + i] =
+ FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
+ }
+ }
+ m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
+ CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
+ if (pEncoding) {
+ LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
+ if (m_pCharNames) {
+ for (int i = 0; i < 256; i++) {
+ m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
+ if (m_Encoding.m_Unicodes[i] == 0) {
+ m_Encoding.m_Unicodes[i] = i;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+void CPDF_Type3Font::CheckType3FontMetrics() {
+ CheckFontMetrics();
+}
+
+CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) {
+ if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
+ return nullptr;
+
+ auto it = m_CacheMap.find(charcode);
+ if (it != m_CacheMap.end())
+ return it->second;
+
+ const FX_CHAR* name =
+ GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+ if (!name)
+ return nullptr;
+
+ CPDF_Stream* pStream =
+ ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
+ if (!pStream)
+ return nullptr;
+
+ std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
+ m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
+ pStream, nullptr)));
+
+ // This can trigger recursion into this method. The content of |m_CacheMap|
+ // can change as a result. Thus after it returns, check the cache again for
+ // a cache hit.
+ pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
+ level + 1);
+ it = m_CacheMap.find(charcode);
+ if (it != m_CacheMap.end())
+ return it->second;
+
+ FX_FLOAT scale = m_FontMatrix.GetXUnit();
+ pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
+ FX_RECT& rcBBox = pNewChar->m_BBox;
+ CFX_FloatRect char_rect(
+ (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
+ (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
+ if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
+ char_rect = pNewChar->m_pForm->CalcBoundingBox();
+
+ char_rect.Transform(&m_FontMatrix);
+ rcBBox.left = FXSYS_round(char_rect.left * 1000);
+ rcBBox.right = FXSYS_round(char_rect.right * 1000);
+ rcBBox.top = FXSYS_round(char_rect.top * 1000);
+ rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
+
+ ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
+ CPDF_Type3Char* pCachedChar = pNewChar.release();
+ m_CacheMap[charcode] = pCachedChar;
+ if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
+ delete pCachedChar->m_pForm;
+ pCachedChar->m_pForm = nullptr;
+ }
+ return pCachedChar;
+}
+
+int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
+ if (charcode >= FX_ArraySize(m_CharWidthL))
+ charcode = 0;
+
+ if (m_CharWidthL[charcode])
+ return m_CharWidthL[charcode];
+
+ const CPDF_Type3Char* pChar = LoadChar(charcode, level);
+ return pChar ? pChar->m_Width : 0;
+}
+
+FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) {
+ const CPDF_Type3Char* pChar = LoadChar(charcode, level);
+ return pChar ? pChar->m_BBox : FX_RECT();
+}
diff --git a/core/fpdfapi/fpdf_font/cpdf_type3font.h b/core/fpdfapi/fpdf_font/cpdf_type3font.h
new file mode 100644
index 0000000000..554556934e
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/cpdf_type3font.h
@@ -0,0 +1,56 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_
+
+#include <map>
+
+#include "core/fpdfapi/fpdf_font/cpdf_simplefont.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_Dictionary;
+class CPDF_Type3Char;
+
+class CPDF_Type3Font : public CPDF_SimpleFont {
+ public:
+ CPDF_Type3Font();
+ ~CPDF_Type3Font() override;
+
+ // CPDF_Font:
+ bool IsType3Font() const override;
+ const CPDF_Type3Font* AsType3Font() const override;
+ CPDF_Type3Font* AsType3Font() override;
+ int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
+ FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) override;
+
+ void SetPageResources(CPDF_Dictionary* pResources) {
+ m_pPageResources = pResources;
+ }
+ CPDF_Type3Char* LoadChar(FX_DWORD charcode, int level = 0);
+ void CheckType3FontMetrics();
+
+ CFX_Matrix& GetFontMatrix() { return m_FontMatrix; }
+
+ protected:
+ CFX_Matrix m_FontMatrix;
+
+ private:
+ // CPDF_Font:
+ FX_BOOL Load() override;
+
+ // CPDF_SimpleFont:
+ void LoadGlyphMap() override {}
+
+ int m_CharWidthL[256];
+ CPDF_Dictionary* m_pCharProcs;
+ CPDF_Dictionary* m_pPageResources;
+ CPDF_Dictionary* m_pFontResources;
+ std::map<FX_DWORD, CPDF_Type3Char*> m_CacheMap;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_CPDF_TYPE3FONT_H_
diff --git a/core/fpdfapi/fpdf_font/font_int.h b/core/fpdfapi/fpdf_font/font_int.h
index 74380f1147..b9b5b5327d 100644
--- a/core/fpdfapi/fpdf_font/font_int.h
+++ b/core/fpdfapi/fpdf_font/font_int.h
@@ -10,8 +10,8 @@
#include <map>
#include <memory>
+#include "core/fpdfapi/fpdf_font/cpdf_cidfont.h"
#include "core/fxcrt/include/fx_basic.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
class CPDF_CID2UnicodeMap;
class CPDF_CMap;
@@ -22,6 +22,7 @@ typedef void* FXFT_Library;
short TT2PDF(int m, FXFT_Face face);
FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id);
+CIDSet CharsetFromOrdering(const CFX_ByteString& ordering);
class CPDF_CMapManager {
public:
diff --git a/core/fpdfapi/fpdf_font/fpdf_font.cpp b/core/fpdfapi/fpdf_font/fpdf_font.cpp
index 8dc91616f9..c0c6f520f4 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font.cpp
+++ b/core/fpdfapi/fpdf_font/fpdf_font.cpp
@@ -14,87 +14,12 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fxcrt/include/fx_ext.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_freetype.h"
#include "third_party/base/stl_util.h"
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-#include "core/fxge/apple/apple_int.h"
-#endif
-
-namespace {
-
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-struct GlyphNameMap {
- const FX_CHAR* m_pStrAdobe;
- const FX_CHAR* m_pStrUnicode;
-};
-
-const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"},
- {"fi", "uniFB01"},
- {"fl", "uniFB02"},
- {"ffi", "uniFB03"},
- {"ffl", "uniFB04"}};
-
-int compareString(const void* key, const void* element) {
- return FXSYS_stricmp((const FX_CHAR*)key,
- ((GlyphNameMap*)element)->m_pStrAdobe);
-}
-
-const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) {
- GlyphNameMap* found = (GlyphNameMap*)FXSYS_bsearch(
- pStrAdobe, g_GlyphNameSubsts,
- sizeof(g_GlyphNameSubsts) / sizeof(GlyphNameMap), sizeof(GlyphNameMap),
- compareString);
- if (found)
- return found->m_pStrUnicode;
- return NULL;
-}
-#endif
-
-const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
- {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
- {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
- {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
- {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
-
-FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
- if (value == "WinAnsiEncoding") {
- basemap = PDFFONT_ENCODING_WINANSI;
- } else if (value == "MacRomanEncoding") {
- basemap = PDFFONT_ENCODING_MACROMAN;
- } else if (value == "MacExpertEncoding") {
- basemap = PDFFONT_ENCODING_MACEXPERT;
- } else if (value == "PDFDocEncoding") {
- basemap = PDFFONT_ENCODING_PDFDOC;
- } else {
- return FALSE;
- }
- return TRUE;
-}
-
-FX_BOOL FT_UseType1Charmap(FXFT_Face face) {
- if (FXFT_Get_Face_CharmapCount(face) == 0) {
- return FALSE;
- }
- if (FXFT_Get_Face_CharmapCount(face) == 1 &&
- FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
- FXFT_ENCODING_UNICODE) {
- return FALSE;
- }
- if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
- FXFT_ENCODING_UNICODE) {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
- } else {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
- }
- return TRUE;
-}
-
-} // namespace
-
FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) {
for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) ==
@@ -156,356 +81,15 @@ void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) {
m_StockMap.erase(pDoc);
}
-CPDF_Font::CPDF_Font()
- : m_pFontFile(nullptr),
- m_pFontDict(nullptr),
- m_pToUnicodeMap(nullptr),
- m_bToUnicodeLoaded(FALSE),
- m_Flags(0),
- m_StemV(0),
- m_Ascent(0),
- m_Descent(0),
- m_ItalicAngle(0) {}
-
-CPDF_Font::~CPDF_Font() {
- delete m_pToUnicodeMap;
- m_pToUnicodeMap = NULL;
-
- if (m_pFontFile) {
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
- const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
- }
-}
-
-bool CPDF_Font::IsType1Font() const {
- return false;
-}
-
-bool CPDF_Font::IsTrueTypeFont() const {
- return false;
-}
-
-bool CPDF_Font::IsType3Font() const {
- return false;
-}
-
-bool CPDF_Font::IsCIDFont() const {
- return false;
-}
-
-const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
- return nullptr;
-}
-
-CPDF_Type1Font* CPDF_Font::AsType1Font() {
- return nullptr;
-}
-
-const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
- return nullptr;
-}
-
-CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
- return nullptr;
-}
-
-const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
- return nullptr;
-}
-
-CPDF_Type3Font* CPDF_Font::AsType3Font() {
- return nullptr;
-}
-
-const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
- return nullptr;
-}
-
-CPDF_CIDFont* CPDF_Font::AsCIDFont() {
- return nullptr;
-}
-
-FX_BOOL CPDF_Font::IsUnicodeCompatible() const {
- return FALSE;
-}
-
-int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
- return size;
-}
-
-int CPDF_Font::GetCharSize(FX_DWORD charcode) const {
- return 1;
-}
-
-int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
- ASSERT(false);
- return 0;
-}
-
-int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
- return GlyphFromCharCode(charcode);
-}
-
-FX_BOOL CPDF_Font::IsVertWriting() const {
- FX_BOOL bVertWriting = FALSE;
- const CPDF_CIDFont* pCIDFont = AsCIDFont();
- if (pCIDFont) {
- bVertWriting = pCIDFont->IsVertWriting();
- } else {
- bVertWriting = m_Font.IsVertical();
- }
- return bVertWriting;
-}
-
-int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
- *buf = (FX_CHAR)charcode;
- return 1;
-}
-
-void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const {
- char buf[4];
- int len = AppendChar(buf, charcode);
- if (len == 1) {
- str += buf[0];
- } else {
- str += CFX_ByteString(buf, len);
- }
-}
-
-CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const {
- if (!m_bToUnicodeLoaded)
- ((CPDF_Font*)this)->LoadUnicodeMap();
-
- if (m_pToUnicodeMap)
- return m_pToUnicodeMap->Lookup(charcode);
- return CFX_WideString();
-}
-
-FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
- if (!m_bToUnicodeLoaded)
- ((CPDF_Font*)this)->LoadUnicodeMap();
-
- if (m_pToUnicodeMap)
- return m_pToUnicodeMap->ReverseLookup(unicode);
- return 0;
-}
-
-void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
- m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
- int ItalicAngle = 0;
- FX_BOOL bExistItalicAngle = FALSE;
- if (pFontDesc->KeyExist("ItalicAngle")) {
- ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
- bExistItalicAngle = TRUE;
- }
- if (ItalicAngle < 0) {
- m_Flags |= PDFFONT_ITALIC;
- m_ItalicAngle = ItalicAngle;
- }
- FX_BOOL bExistStemV = FALSE;
- if (pFontDesc->KeyExist("StemV")) {
- m_StemV = pFontDesc->GetIntegerBy("StemV");
- bExistStemV = TRUE;
- }
- FX_BOOL bExistAscent = FALSE;
- if (pFontDesc->KeyExist("Ascent")) {
- m_Ascent = pFontDesc->GetIntegerBy("Ascent");
- bExistAscent = TRUE;
- }
- FX_BOOL bExistDescent = FALSE;
- if (pFontDesc->KeyExist("Descent")) {
- m_Descent = pFontDesc->GetIntegerBy("Descent");
- bExistDescent = TRUE;
- }
- FX_BOOL bExistCapHeight = FALSE;
- if (pFontDesc->KeyExist("CapHeight")) {
- bExistCapHeight = TRUE;
- }
- if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
- bExistStemV) {
- m_Flags |= PDFFONT_USEEXTERNATTR;
- }
- if (m_Descent > 10) {
- m_Descent = -m_Descent;
- }
- CPDF_Array* pBBox = pFontDesc->GetArrayBy("FontBBox");
- if (pBBox) {
- m_FontBBox.left = pBBox->GetIntegerAt(0);
- m_FontBBox.bottom = pBBox->GetIntegerAt(1);
- m_FontBBox.right = pBBox->GetIntegerAt(2);
- m_FontBBox.top = pBBox->GetIntegerAt(3);
- }
-
- CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile");
- if (!pFontFile)
- pFontFile = pFontDesc->GetStreamBy("FontFile2");
- if (!pFontFile)
- pFontFile = pFontDesc->GetStreamBy("FontFile3");
- if (!pFontFile)
- return;
-
- m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
- if (!m_pFontFile)
- return;
- const uint8_t* pFontData = m_pFontFile->GetData();
- FX_DWORD dwFontSize = m_pFontFile->GetSize();
- if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
- const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
- m_pFontFile = nullptr;
- }
-}
short TT2PDF(int m, FXFT_Face face) {
int upm = FXFT_Get_Face_UnitsPerEM(face);
- if (upm == 0) {
+ if (upm == 0)
return (short)m;
- }
return (m * 1000 + upm / 2) / upm;
}
-void CPDF_Font::CheckFontMetrics() {
- if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
- m_FontBBox.right == 0) {
- FXFT_Face face = m_Font.GetFace();
- if (face) {
- m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
- m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
- m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
- m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
- m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
- m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
- } else {
- FX_BOOL bFirst = TRUE;
- for (int i = 0; i < 256; i++) {
- FX_RECT rect = GetCharBBox(i);
- if (rect.left == rect.right) {
- continue;
- }
- if (bFirst) {
- m_FontBBox = rect;
- bFirst = FALSE;
- } else {
- if (m_FontBBox.top < rect.top) {
- m_FontBBox.top = rect.top;
- }
- if (m_FontBBox.right < rect.right) {
- m_FontBBox.right = rect.right;
- }
- if (m_FontBBox.left > rect.left) {
- m_FontBBox.left = rect.left;
- }
- if (m_FontBBox.bottom > rect.bottom) {
- m_FontBBox.bottom = rect.bottom;
- }
- }
- }
- }
- }
- if (m_Ascent == 0 && m_Descent == 0) {
- FX_RECT rect = GetCharBBox('A');
- m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
- rect = GetCharBBox('g');
- m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
- }
-}
-
-void CPDF_Font::LoadUnicodeMap() {
- m_bToUnicodeLoaded = TRUE;
- CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
- if (!pStream) {
- return;
- }
- m_pToUnicodeMap = new CPDF_ToUnicodeMap;
- m_pToUnicodeMap->Load(pStream);
-}
-
-int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
- int offset = 0;
- int width = 0;
- while (offset < size) {
- FX_DWORD charcode = GetNextChar(pString, size, offset);
- width += GetCharWidthF(charcode);
- }
- return width;
-}
-
-CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
- const CFX_ByteStringC& name) {
- CFX_ByteString fontname(name);
- int font_id = PDF_GetStandardFontName(&fontname);
- if (font_id < 0) {
- return nullptr;
- }
- CPDF_FontGlobals* pFontGlobals =
- CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
- CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
- if (pFont) {
- return pFont;
- }
- CPDF_Dictionary* pDict = new CPDF_Dictionary;
- pDict->SetAtName("Type", "Font");
- pDict->SetAtName("Subtype", "Type1");
- pDict->SetAtName("BaseFont", fontname);
- pDict->SetAtName("Encoding", "WinAnsiEncoding");
- pFont = CPDF_Font::CreateFontF(NULL, pDict);
- pFontGlobals->Set(pDoc, font_id, pFont);
- return pFont;
-}
-
-CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
- CPDF_Dictionary* pFontDict) {
- CFX_ByteString type = pFontDict->GetStringBy("Subtype");
- CPDF_Font* pFont;
- if (type == "TrueType") {
- {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
- _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
- _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
- _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont");
- CFX_ByteString tag = basefont.Left(4);
- int i;
- int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
- for (i = 0; i < count; ++i) {
- if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
- break;
- }
- }
- if (i < count) {
- CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
- if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
- pFont = new CPDF_CIDFont;
- pFont->m_pFontDict = pFontDict;
- pFont->m_pDocument = pDoc;
- pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
- if (!pFont->Load()) {
- delete pFont;
- return NULL;
- }
- return pFont;
- }
- }
-#endif
- }
- pFont = new CPDF_TrueTypeFont;
- } else if (type == "Type3") {
- pFont = new CPDF_Type3Font;
- } else if (type == "Type0") {
- pFont = new CPDF_CIDFont;
- } else {
- pFont = new CPDF_Type1Font;
- }
- pFont->m_pFontDict = pFontDict;
- pFont->m_pDocument = pDoc;
- pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
- if (!pFont->Load()) {
- delete pFont;
- return NULL;
- }
- return pFont;
-}
CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) {
auto it = m_Map.find(charcode);
@@ -716,1098 +300,3 @@ void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) {
m_pBaseMap = NULL;
}
}
-
-FX_DWORD CPDF_Font::GetNextChar(const FX_CHAR* pString,
- int nStrLen,
- int& offset) const {
- if (offset < 0 || nStrLen < 1) {
- return 0;
- }
- uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
- return static_cast<FX_DWORD>(ch);
-}
-
-void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
- int& iBaseEncoding,
- CFX_ByteString*& pCharNames,
- FX_BOOL bEmbedded,
- FX_BOOL bTrueType) {
- if (!pEncoding) {
- if (m_BaseFont == "Symbol") {
- iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
- : PDFFONT_ENCODING_ADOBE_SYMBOL;
- } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
- iBaseEncoding = PDFFONT_ENCODING_WINANSI;
- }
- return;
- }
- if (pEncoding->IsName()) {
- if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
- iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
- return;
- }
- if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
- if (!bTrueType) {
- iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
- }
- return;
- }
- CFX_ByteString bsEncoding = pEncoding->GetString();
- if (bsEncoding.Compare("MacExpertEncoding") == 0) {
- bsEncoding = "WinAnsiEncoding";
- }
- GetPredefinedEncoding(iBaseEncoding, bsEncoding);
- return;
- }
-
- CPDF_Dictionary* pDict = pEncoding->AsDictionary();
- if (!pDict)
- return;
-
- if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
- iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
- CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
- if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
- bsEncoding = "WinAnsiEncoding";
- }
- GetPredefinedEncoding(iBaseEncoding, bsEncoding);
- }
- if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
- iBaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
- if (!pDiffs) {
- return;
- }
- pCharNames = new CFX_ByteString[256];
- FX_DWORD cur_code = 0;
- for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
- CPDF_Object* pElement = pDiffs->GetElementValue(i);
- if (!pElement)
- continue;
-
- if (CPDF_Name* pName = pElement->AsName()) {
- if (cur_code < 256)
- pCharNames[cur_code] = pName->GetString();
- cur_code++;
- } else {
- cur_code = pElement->GetInteger();
- }
- }
-}
-
-FX_BOOL CPDF_Font::IsStandardFont() const {
- if (!IsType1Font())
- return FALSE;
- if (m_pFontFile)
- return FALSE;
- if (AsType1Font()->GetBase14Font() < 0)
- return FALSE;
- return TRUE;
-}
-
-CPDF_SimpleFont::CPDF_SimpleFont()
- : m_pCharNames(nullptr), m_BaseEncoding(PDFFONT_ENCODING_BUILTIN) {
- FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
- FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
- FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
-}
-
-CPDF_SimpleFont::~CPDF_SimpleFont() {
- delete[] m_pCharNames;
-}
-
-int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- if (charcode > 0xff) {
- return -1;
- }
- int index = m_GlyphIndex[(uint8_t)charcode];
- if (index == 0xffff) {
- return -1;
- }
- return index;
-}
-
-void CPDF_SimpleFont::LoadCharMetrics(int charcode) {
- if (!m_Font.GetFace())
- return;
-
- if (charcode < 0 || charcode > 0xff) {
- return;
- }
- int glyph_index = m_GlyphIndex[charcode];
- if (glyph_index == 0xffff) {
- if (!m_pFontFile && charcode != 32) {
- LoadCharMetrics(32);
- m_CharBBox[charcode] = m_CharBBox[32];
- if (m_bUseFontWidth) {
- m_CharWidth[charcode] = m_CharWidth[32];
- }
- }
- return;
- }
- FXFT_Face face = m_Font.GetFace();
- int err = FXFT_Load_Glyph(
- face, glyph_index,
- FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- if (err) {
- return;
- }
- m_CharBBox[charcode] = FX_SMALL_RECT(
- TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
- TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
- TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face),
- face),
- TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face),
- face));
-
- if (m_bUseFontWidth) {
- int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face);
- if (m_CharWidth[charcode] == 0xffff) {
- m_CharWidth[charcode] = TT_Width;
- } else if (TT_Width && !IsEmbedded()) {
- m_CharBBox[charcode].right =
- m_CharBBox[charcode].right * m_CharWidth[charcode] / TT_Width;
- m_CharBBox[charcode].left =
- m_CharBBox[charcode].left * m_CharWidth[charcode] / TT_Width;
- }
- }
-}
-
-int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) {
- if (charcode > 0xff) {
- charcode = 0;
- }
- if (m_CharWidth[charcode] == 0xffff) {
- LoadCharMetrics(charcode);
- if (m_CharWidth[charcode] == 0xffff) {
- m_CharWidth[charcode] = 0;
- }
- }
- return (int16_t)m_CharWidth[charcode];
-}
-
-FX_RECT CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, int level) {
- if (charcode > 0xff)
- charcode = 0;
-
- if (m_CharBBox[charcode].left == FX_SMALL_RECT::kInvalid)
- LoadCharMetrics(charcode);
-
- return FX_RECT(m_CharBBox[charcode]);
-}
-
-const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
- const CFX_ByteString* pCharNames,
- int charcode) {
- ASSERT(charcode >= 0 && charcode < 256);
- if (charcode < 0 || charcode >= 256) {
- return NULL;
- }
- const FX_CHAR* name = NULL;
- if (pCharNames) {
- name = pCharNames[charcode];
- }
- if ((!name || name[0] == 0) && iBaseEncoding) {
- name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
- }
- return name && name[0] ? name : nullptr;
-}
-
-FX_BOOL CPDF_SimpleFont::LoadCommon() {
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
- int width_start = 0, width_end = -1;
- m_bUseFontWidth = TRUE;
- if (pWidthArray) {
- m_bUseFontWidth = FALSE;
- if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
- int MissingWidth = pFontDesc->GetIntegerBy("MissingWidth");
- for (int i = 0; i < 256; i++) {
- m_CharWidth[i] = MissingWidth;
- }
- }
- width_start = m_pFontDict->GetIntegerBy("FirstChar", 0);
- width_end = m_pFontDict->GetIntegerBy("LastChar", 0);
- if (width_start >= 0 && width_start <= 255) {
- if (width_end <= 0 ||
- width_end >= width_start + (int)pWidthArray->GetCount()) {
- width_end = width_start + pWidthArray->GetCount() - 1;
- }
- if (width_end > 255) {
- width_end = 255;
- }
- for (int i = width_start; i <= width_end; i++) {
- m_CharWidth[i] = pWidthArray->GetIntegerAt(i - width_start);
- }
- }
- }
- if (m_pFontFile) {
- if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
- m_BaseFont = m_BaseFont.Mid(8);
- }
- } else {
- LoadSubstFont();
- }
- if (!(m_Flags & PDFFONT_SYMBOLIC)) {
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
- m_Font.IsTTFont());
- LoadGlyphMap();
- delete[] m_pCharNames;
- m_pCharNames = NULL;
- if (!m_Font.GetFace())
- return TRUE;
-
- if (m_Flags & PDFFONT_ALLCAP) {
- unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
- for (size_t range = 0; range < sizeof lowercases / 2; range++) {
- for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
- if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
- continue;
- }
- m_GlyphIndex[i] = m_GlyphIndex[i - 32];
- if (m_CharWidth[i - 32]) {
- m_CharWidth[i] = m_CharWidth[i - 32];
- m_CharBBox[i] = m_CharBBox[i - 32];
- }
- }
- }
- }
- CheckFontMetrics();
- return TRUE;
-}
-
-void CPDF_SimpleFont::LoadSubstFont() {
- if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
- int width = 0, i;
- for (i = 0; i < 256; i++) {
- if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
- continue;
- }
- if (width == 0) {
- width = m_CharWidth[i];
- } else if (width != m_CharWidth[i]) {
- break;
- }
- }
- if (i == 256 && width) {
- m_Flags |= PDFFONT_FIXEDPITCH;
- }
- }
- int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
- m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, weight, m_ItalicAngle,
- 0);
- if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
- }
-}
-
-FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const {
- return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN &&
- m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
- m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
-}
-
-CFX_WideString CPDF_SimpleFont::UnicodeFromCharCode(FX_DWORD charcode) const {
- CFX_WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode);
- if (!unicode.IsEmpty())
- return unicode;
- FX_WCHAR ret = m_Encoding.UnicodeFromCharCode((uint8_t)charcode);
- if (ret == 0)
- return CFX_WideString();
- return ret;
-}
-
-FX_DWORD CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
- FX_DWORD ret = CPDF_Font::CharCodeFromUnicode(unicode);
- if (ret)
- return ret;
- return m_Encoding.CharCodeFromUnicode(unicode);
-}
-
-CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {}
-
-bool CPDF_Type1Font::IsType1Font() const {
- return true;
-}
-
-const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
- return this;
-}
-
-CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
- return this;
-}
-
-FX_BOOL CPDF_Type1Font::Load() {
- m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
- if (m_Base14Font >= 0) {
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc && pFontDesc->KeyExist("Flags"))
- m_Flags = pFontDesc->GetIntegerBy("Flags");
- else
- m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
-
- if (m_Base14Font < 4) {
- for (int i = 0; i < 256; i++)
- m_CharWidth[i] = 600;
- }
- if (m_Base14Font == 12)
- m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
- else if (m_Base14Font == 13)
- m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
- else if (m_Flags & PDFFONT_NONSYMBOLIC)
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- return LoadCommon();
-}
-
-int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
- if (charcode > 0xff) {
- return -1;
- }
- int index = m_ExtGID[(uint8_t)charcode];
- if (index == 0xffff) {
- return -1;
- }
- return index;
-}
-
-void CPDF_Type1Font::LoadGlyphMap() {
- if (!m_Font.GetFace())
- return;
-
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_BOOL bCoreText = TRUE;
- CQuartz2D& quartz2d =
- ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- if (!m_Font.GetPlatformFont()) {
- if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
- bCoreText = FALSE;
- }
- m_Font.SetPlatformFont(
- quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
- if (!m_Font.GetPlatformFont()) {
- bCoreText = FALSE;
- }
- }
-#endif
- if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
- if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
- FX_BOOL bGotOne = FALSE;
- for (int charcode = 0; charcode < 256; charcode++) {
- 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 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
- name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
-#endif
- if (m_GlyphIndex[charcode]) {
- bGotOne = TRUE;
- break;
- }
- }
- }
- if (bGotOne) {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
- return;
- }
- }
- FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
- if (m_BaseEncoding == 0) {
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
- }
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (!name) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
- m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph,
- 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
-#endif
- if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
- m_Encoding.m_Unicodes[charcode] = 0x20;
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
- name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
-#endif
- }
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
- return;
- }
- FT_UseType1Charmap(m_Font.GetFace());
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (bCoreText) {
- if (m_Flags & PDFFONT_SYMBOLIC) {
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name) {
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] =
- FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- } else {
- m_GlyphIndex[charcode] =
- FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
- FX_WCHAR unicode = 0;
- if (m_GlyphIndex[charcode]) {
- unicode =
- FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
- }
- FX_CHAR name_glyph[256];
- FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
- name_glyph, 256);
- name_glyph[255] = 0;
- if (unicode == 0 && name_glyph[0] != 0) {
- unicode = PDF_UnicodeFromAdobeName(name_glyph);
- }
- m_Encoding.m_Unicodes[charcode] = unicode;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- }
- }
- return;
- }
- FX_BOOL bUnicode = FALSE;
- if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
- bUnicode = TRUE;
- }
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (!name) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- const FX_CHAR* pStrUnicode = GlyphNameRemap(name);
- if (pStrUnicode &&
- 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) {
- name = pStrUnicode;
- }
- m_GlyphIndex[charcode] =
- FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- if (m_GlyphIndex[charcode] == 0) {
- if (FXSYS_strcmp(name, ".notdef") != 0 &&
- FXSYS_strcmp(name, "space") != 0) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
- m_Font.GetFace(),
- bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
- name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- } else {
- m_Encoding.m_Unicodes[charcode] = 0x20;
- m_GlyphIndex[charcode] =
- bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff;
- FX_CHAR name_glyph[256];
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
- name_glyph, 256);
- name_glyph[255] = 0;
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
- kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
- kCFAllocatorNull);
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
- (CGFontRef)m_Font.GetPlatformFont(), name_ct);
- if (name_ct) {
- CFRelease(name_ct);
- }
- }
- }
- }
- return;
- }
-#endif
- if (m_Flags & PDFFONT_SYMBOLIC) {
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (name) {
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] =
- FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
- } else {
- m_GlyphIndex[charcode] =
- FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
- if (m_GlyphIndex[charcode]) {
- FX_WCHAR unicode =
- FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
- if (unicode == 0) {
- FX_CHAR name_glyph[256];
- FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
- FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
- name_glyph, 256);
- name_glyph[255] = 0;
- if (name_glyph[0] != 0) {
- unicode = PDF_UnicodeFromAdobeName(name_glyph);
- }
- }
- m_Encoding.m_Unicodes[charcode] = unicode;
- }
- }
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
- return;
- }
- FX_BOOL bUnicode = FALSE;
- if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
- bUnicode = TRUE;
- }
- for (int charcode = 0; charcode < 256; charcode++) {
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (!name) {
- continue;
- }
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
- if (m_GlyphIndex[charcode] == 0) {
- if (FXSYS_strcmp(name, ".notdef") != 0 &&
- FXSYS_strcmp(name, "space") != 0) {
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
- m_Font.GetFace(),
- bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
- } else {
- m_Encoding.m_Unicodes[charcode] = 0x20;
- m_GlyphIndex[charcode] = 0xffff;
- }
- }
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!bCoreText) {
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
- }
-#endif
-}
-
-CPDF_FontEncoding::CPDF_FontEncoding() {
- FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
-}
-
-int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const {
- for (int i = 0; i < 256; i++)
- if (m_Unicodes[i] == unicode) {
- return i;
- }
- return -1;
-}
-
-CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) {
- const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
- if (!pSrc) {
- FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
- } else {
- for (int i = 0; i < 256; i++)
- m_Unicodes[i] = pSrc[i];
- }
-}
-
-FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const {
- return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) ==
- 0;
-}
-
-CPDF_Object* CPDF_FontEncoding::Realize() {
- int predefined = 0;
- for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS;
- cs++) {
- const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
- FX_BOOL match = TRUE;
- for (int i = 0; i < 256; ++i) {
- if (m_Unicodes[i] != pSrc[i]) {
- match = FALSE;
- break;
- }
- }
- if (match) {
- predefined = cs;
- break;
- }
- }
- if (predefined) {
- if (predefined == PDFFONT_ENCODING_WINANSI) {
- return new CPDF_Name("WinAnsiEncoding");
- }
- if (predefined == PDFFONT_ENCODING_MACROMAN) {
- return new CPDF_Name("MacRomanEncoding");
- }
- if (predefined == PDFFONT_ENCODING_MACEXPERT) {
- return new CPDF_Name("MacExpertEncoding");
- }
- return NULL;
- }
- const uint16_t* pStandard =
- PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
- CPDF_Array* pDiff = new CPDF_Array;
- for (int i = 0; i < 256; i++) {
- if (pStandard[i] == m_Unicodes[i]) {
- continue;
- }
- pDiff->Add(new CPDF_Number(i));
- pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
- }
-
- CPDF_Dictionary* pDict = new CPDF_Dictionary;
- pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
- pDict->SetAt("Differences", pDiff);
- return pDict;
-}
-
-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;
- }
-}
-
-CPDF_Type3Font::CPDF_Type3Font()
- : m_pCharProcs(nullptr),
- m_pPageResources(nullptr),
- m_pFontResources(nullptr) {
- FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
-}
-
-CPDF_Type3Font::~CPDF_Type3Font() {
- for (auto it : m_CacheMap)
- delete it.second;
-}
-
-bool CPDF_Type3Font::IsType3Font() const {
- return true;
-}
-
-const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
- return this;
-}
-
-CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
- return this;
-}
-
-FX_BOOL CPDF_Type3Font::Load() {
- m_pFontResources = m_pFontDict->GetDictBy("Resources");
- CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("FontMatrix");
- FX_FLOAT xscale = 1.0f, yscale = 1.0f;
- if (pMatrix) {
- m_FontMatrix = pMatrix->GetMatrix();
- xscale = m_FontMatrix.a;
- yscale = m_FontMatrix.d;
- }
- CPDF_Array* pBBox = m_pFontDict->GetArrayBy("FontBBox");
- if (pBBox) {
- m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000);
- m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000);
- m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000);
- m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000);
- }
- int StartChar = m_pFontDict->GetIntegerBy("FirstChar");
- CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
- if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
- FX_DWORD count = pWidthArray->GetCount();
- if (count > 256) {
- count = 256;
- }
- if (StartChar + count > 256) {
- count = 256 - StartChar;
- }
- for (FX_DWORD i = 0; i < count; i++) {
- m_CharWidthL[StartChar + i] =
- FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
- }
- }
- m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
- if (pEncoding) {
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
- if (m_pCharNames) {
- for (int i = 0; i < 256; i++) {
- m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
- if (m_Encoding.m_Unicodes[i] == 0) {
- m_Encoding.m_Unicodes[i] = i;
- }
- }
- }
- }
- return TRUE;
-}
-
-void CPDF_Type3Font::CheckType3FontMetrics() {
- CheckFontMetrics();
-}
-
-CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) {
- if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
- return nullptr;
-
- auto it = m_CacheMap.find(charcode);
- if (it != m_CacheMap.end())
- return it->second;
-
- const FX_CHAR* name =
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
- if (!name)
- return nullptr;
-
- CPDF_Stream* pStream =
- ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
- if (!pStream)
- return nullptr;
-
- std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
- m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
- pStream, nullptr)));
-
- // This can trigger recursion into this method. The content of |m_CacheMap|
- // can change as a result. Thus after it returns, check the cache again for
- // a cache hit.
- pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
- level + 1);
- it = m_CacheMap.find(charcode);
- if (it != m_CacheMap.end())
- return it->second;
-
- FX_FLOAT scale = m_FontMatrix.GetXUnit();
- pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
- FX_RECT& rcBBox = pNewChar->m_BBox;
- CFX_FloatRect char_rect(
- (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
- (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
- if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
- char_rect = pNewChar->m_pForm->CalcBoundingBox();
-
- char_rect.Transform(&m_FontMatrix);
- rcBBox.left = FXSYS_round(char_rect.left * 1000);
- rcBBox.right = FXSYS_round(char_rect.right * 1000);
- rcBBox.top = FXSYS_round(char_rect.top * 1000);
- rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
-
- ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
- CPDF_Type3Char* pCachedChar = pNewChar.release();
- m_CacheMap[charcode] = pCachedChar;
- if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
- delete pCachedChar->m_pForm;
- pCachedChar->m_pForm = nullptr;
- }
- return pCachedChar;
-}
-
-int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
- if (charcode >= FX_ArraySize(m_CharWidthL))
- charcode = 0;
-
- if (m_CharWidthL[charcode])
- return m_CharWidthL[charcode];
-
- const CPDF_Type3Char* pChar = LoadChar(charcode, level);
- return pChar ? pChar->m_Width : 0;
-}
-
-FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) {
- const CPDF_Type3Char* pChar = LoadChar(charcode, level);
- return pChar ? pChar->m_BBox : FX_RECT();
-}
-
-CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
- : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
-
-CPDF_Type3Char::~CPDF_Type3Char() {
- delete m_pForm;
- delete m_pBitmap;
-}
diff --git a/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp b/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp
index c73043abfa..95452a7227 100644
--- a/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp
+++ b/core/fpdfapi/fpdf_font/fpdf_font_cid.cpp
@@ -13,7 +13,6 @@
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
#include "core/fpdfapi/include/cpdf_modulemgr.h"
#include "core/fxcrt/include/fx_ext.h"
-#include "core/include/fpdfapi/fpdf_resource.h"
#include "core/include/fxge/fx_freetype.h"
#include "core/include/fxge/fx_ge.h"
@@ -22,7 +21,6 @@ namespace {
const FX_CHAR* const g_CharsetNames[CIDSET_NUM_SETS] = {
nullptr, "GB1", "CNS1", "Japan1", "Korea1", "UCS"};
-const uint16_t g_CharsetCPs[CIDSET_NUM_SETS] = {0, 936, 950, 932, 949, 1200};
class CPDF_PredefinedCMap {
public:
@@ -192,14 +190,6 @@ CIDSet CIDSetFromSizeT(size_t index) {
return static_cast<CIDSet>(index);
}
-CIDSet CharsetFromOrdering(const CFX_ByteString& ordering) {
- for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) {
- if (ordering == CFX_ByteStringC(g_CharsetNames[charset]))
- return CIDSetFromSizeT(charset);
- }
- return CIDSET_UNKNOWN;
-}
-
CFX_ByteString CMap_GetString(const CFX_ByteStringC& word) {
return word.Mid(1, word.GetLength() - 2);
}
@@ -284,183 +274,6 @@ int GetCharSizeImpl(FX_DWORD charcode,
return 1;
}
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
-
-bool IsValidEmbeddedCharcodeFromUnicodeCharset(CIDSet charset) {
- switch (charset) {
- case CIDSET_GB1:
- case CIDSET_CNS1:
- case CIDSET_JAPAN1:
- case CIDSET_KOREA1:
- return true;
-
- default:
- return false;
- }
-}
-
-FX_DWORD EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap,
- CIDSet charset,
- FX_WCHAR unicode) {
- if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
- return 0;
-
- CPDF_FontGlobals* pFontGlobals =
- CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
- const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
- if (!pCodes)
- return 0;
-
- int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
- for (int i = 0; i < nCodes; ++i) {
- if (pCodes[i] == unicode) {
- FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
- if (CharCode != 0) {
- return CharCode;
- }
- }
- }
- return 0;
-}
-
-FX_WCHAR EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap,
- CIDSet charset,
- FX_DWORD charcode) {
- if (!IsValidEmbeddedCharcodeFromUnicodeCharset(charset))
- return 0;
-
- uint16_t cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
- if (cid == 0)
- return 0;
-
- CPDF_FontGlobals* pFontGlobals =
- CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
- const uint16_t* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
- if (!pCodes)
- return 0;
-
- if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count)
- return pCodes[cid];
- return 0;
-}
-
-#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
-
-void FT_UseCIDCharmap(FXFT_Face face, int coding) {
- int encoding;
- switch (coding) {
- case CIDCODING_GB:
- encoding = FXFT_ENCODING_GB2312;
- break;
- case CIDCODING_BIG5:
- encoding = FXFT_ENCODING_BIG5;
- break;
- case CIDCODING_JIS:
- encoding = FXFT_ENCODING_SJIS;
- break;
- case CIDCODING_KOREA:
- encoding = FXFT_ENCODING_JOHAB;
- break;
- default:
- encoding = FXFT_ENCODING_UNICODE;
- }
- int err = FXFT_Select_Charmap(face, encoding);
- if (err) {
- err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
- }
- if (err && FXFT_Get_Face_Charmaps(face)) {
- FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
- }
-}
-
-const struct CIDTransform {
- uint16_t CID;
- uint8_t a, b, c, d, e, f;
-} g_Japan1_VertCIDs[] = {
- {97, 129, 0, 0, 127, 55, 0}, {7887, 127, 0, 0, 127, 76, 89},
- {7888, 127, 0, 0, 127, 79, 94}, {7889, 0, 129, 127, 0, 17, 127},
- {7890, 0, 129, 127, 0, 17, 127}, {7891, 0, 129, 127, 0, 17, 127},
- {7892, 0, 129, 127, 0, 17, 127}, {7893, 0, 129, 127, 0, 17, 127},
- {7894, 0, 129, 127, 0, 17, 127}, {7895, 0, 129, 127, 0, 17, 127},
- {7896, 0, 129, 127, 0, 17, 127}, {7897, 0, 129, 127, 0, 17, 127},
- {7898, 0, 129, 127, 0, 17, 127}, {7899, 0, 129, 127, 0, 17, 104},
- {7900, 0, 129, 127, 0, 17, 127}, {7901, 0, 129, 127, 0, 17, 104},
- {7902, 0, 129, 127, 0, 17, 127}, {7903, 0, 129, 127, 0, 17, 127},
- {7904, 0, 129, 127, 0, 17, 127}, {7905, 0, 129, 127, 0, 17, 114},
- {7906, 0, 129, 127, 0, 17, 127}, {7907, 0, 129, 127, 0, 17, 127},
- {7908, 0, 129, 127, 0, 17, 127}, {7909, 0, 129, 127, 0, 17, 127},
- {7910, 0, 129, 127, 0, 17, 127}, {7911, 0, 129, 127, 0, 17, 127},
- {7912, 0, 129, 127, 0, 17, 127}, {7913, 0, 129, 127, 0, 17, 127},
- {7914, 0, 129, 127, 0, 17, 127}, {7915, 0, 129, 127, 0, 17, 114},
- {7916, 0, 129, 127, 0, 17, 127}, {7917, 0, 129, 127, 0, 17, 127},
- {7918, 127, 0, 0, 127, 18, 25}, {7919, 127, 0, 0, 127, 18, 25},
- {7920, 127, 0, 0, 127, 18, 25}, {7921, 127, 0, 0, 127, 18, 25},
- {7922, 127, 0, 0, 127, 18, 25}, {7923, 127, 0, 0, 127, 18, 25},
- {7924, 127, 0, 0, 127, 18, 25}, {7925, 127, 0, 0, 127, 18, 25},
- {7926, 127, 0, 0, 127, 18, 25}, {7927, 127, 0, 0, 127, 18, 25},
- {7928, 127, 0, 0, 127, 18, 25}, {7929, 127, 0, 0, 127, 18, 25},
- {7930, 127, 0, 0, 127, 18, 25}, {7931, 127, 0, 0, 127, 18, 25},
- {7932, 127, 0, 0, 127, 18, 25}, {7933, 127, 0, 0, 127, 18, 25},
- {7934, 127, 0, 0, 127, 18, 25}, {7935, 127, 0, 0, 127, 18, 25},
- {7936, 127, 0, 0, 127, 18, 25}, {7937, 127, 0, 0, 127, 18, 25},
- {7938, 127, 0, 0, 127, 18, 25}, {7939, 127, 0, 0, 127, 18, 25},
- {8720, 0, 129, 127, 0, 19, 102}, {8721, 0, 129, 127, 0, 13, 127},
- {8722, 0, 129, 127, 0, 19, 108}, {8723, 0, 129, 127, 0, 19, 102},
- {8724, 0, 129, 127, 0, 19, 102}, {8725, 0, 129, 127, 0, 19, 102},
- {8726, 0, 129, 127, 0, 19, 102}, {8727, 0, 129, 127, 0, 19, 102},
- {8728, 0, 129, 127, 0, 19, 114}, {8729, 0, 129, 127, 0, 19, 114},
- {8730, 0, 129, 127, 0, 38, 108}, {8731, 0, 129, 127, 0, 13, 108},
- {8732, 0, 129, 127, 0, 19, 108}, {8733, 0, 129, 127, 0, 19, 108},
- {8734, 0, 129, 127, 0, 19, 108}, {8735, 0, 129, 127, 0, 19, 108},
- {8736, 0, 129, 127, 0, 19, 102}, {8737, 0, 129, 127, 0, 19, 102},
- {8738, 0, 129, 127, 0, 19, 102}, {8739, 0, 129, 127, 0, 19, 102},
- {8740, 0, 129, 127, 0, 19, 102}, {8741, 0, 129, 127, 0, 19, 102},
- {8742, 0, 129, 127, 0, 19, 102}, {8743, 0, 129, 127, 0, 19, 102},
- {8744, 0, 129, 127, 0, 19, 102}, {8745, 0, 129, 127, 0, 19, 102},
- {8746, 0, 129, 127, 0, 19, 114}, {8747, 0, 129, 127, 0, 19, 114},
- {8748, 0, 129, 127, 0, 19, 102}, {8749, 0, 129, 127, 0, 19, 102},
- {8750, 0, 129, 127, 0, 19, 102}, {8751, 0, 129, 127, 0, 19, 102},
- {8752, 0, 129, 127, 0, 19, 102}, {8753, 0, 129, 127, 0, 19, 102},
- {8754, 0, 129, 127, 0, 19, 102}, {8755, 0, 129, 127, 0, 19, 102},
- {8756, 0, 129, 127, 0, 19, 102}, {8757, 0, 129, 127, 0, 19, 102},
- {8758, 0, 129, 127, 0, 19, 102}, {8759, 0, 129, 127, 0, 19, 102},
- {8760, 0, 129, 127, 0, 19, 102}, {8761, 0, 129, 127, 0, 19, 102},
- {8762, 0, 129, 127, 0, 19, 102}, {8763, 0, 129, 127, 0, 19, 102},
- {8764, 0, 129, 127, 0, 19, 102}, {8765, 0, 129, 127, 0, 19, 102},
- {8766, 0, 129, 127, 0, 19, 102}, {8767, 0, 129, 127, 0, 19, 102},
- {8768, 0, 129, 127, 0, 19, 102}, {8769, 0, 129, 127, 0, 19, 102},
- {8770, 0, 129, 127, 0, 19, 102}, {8771, 0, 129, 127, 0, 19, 102},
- {8772, 0, 129, 127, 0, 19, 102}, {8773, 0, 129, 127, 0, 19, 102},
- {8774, 0, 129, 127, 0, 19, 102}, {8775, 0, 129, 127, 0, 19, 102},
- {8776, 0, 129, 127, 0, 19, 102}, {8777, 0, 129, 127, 0, 19, 102},
- {8778, 0, 129, 127, 0, 19, 102}, {8779, 0, 129, 127, 0, 19, 114},
- {8780, 0, 129, 127, 0, 19, 108}, {8781, 0, 129, 127, 0, 19, 114},
- {8782, 0, 129, 127, 0, 13, 114}, {8783, 0, 129, 127, 0, 19, 108},
- {8784, 0, 129, 127, 0, 13, 114}, {8785, 0, 129, 127, 0, 19, 108},
- {8786, 0, 129, 127, 0, 19, 108}, {8787, 0, 129, 127, 0, 19, 108},
- {8788, 0, 129, 127, 0, 19, 108}, {8789, 0, 129, 127, 0, 19, 108},
- {8790, 0, 129, 127, 0, 19, 108}, {8791, 0, 129, 127, 0, 19, 108},
- {8792, 0, 129, 127, 0, 19, 108}, {8793, 0, 129, 127, 0, 19, 108},
- {8794, 0, 129, 127, 0, 19, 108}, {8795, 0, 129, 127, 0, 19, 108},
- {8796, 0, 129, 127, 0, 19, 108}, {8797, 0, 129, 127, 0, 19, 108},
- {8798, 0, 129, 127, 0, 19, 108}, {8799, 0, 129, 127, 0, 19, 108},
- {8800, 0, 129, 127, 0, 19, 108}, {8801, 0, 129, 127, 0, 19, 108},
- {8802, 0, 129, 127, 0, 19, 108}, {8803, 0, 129, 127, 0, 19, 108},
- {8804, 0, 129, 127, 0, 19, 108}, {8805, 0, 129, 127, 0, 19, 108},
- {8806, 0, 129, 127, 0, 19, 108}, {8807, 0, 129, 127, 0, 19, 108},
- {8808, 0, 129, 127, 0, 19, 108}, {8809, 0, 129, 127, 0, 19, 108},
- {8810, 0, 129, 127, 0, 19, 108}, {8811, 0, 129, 127, 0, 19, 114},
- {8812, 0, 129, 127, 0, 19, 102}, {8813, 0, 129, 127, 0, 19, 114},
- {8814, 0, 129, 127, 0, 76, 102}, {8815, 0, 129, 127, 0, 13, 121},
- {8816, 0, 129, 127, 0, 19, 114}, {8817, 0, 129, 127, 0, 19, 127},
- {8818, 0, 129, 127, 0, 19, 114}, {8819, 0, 129, 127, 0, 218, 108},
-};
-
-int CompareCIDTransform(const void* key, const void* element) {
- uint16_t CID = *static_cast<const uint16_t*>(key);
- return CID - static_cast<const struct CIDTransform*>(element)->CID;
-}
-
} // namespace
CPDF_CMapManager::CPDF_CMapManager() {
@@ -975,706 +788,10 @@ void CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr,
FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount);
}
-CPDF_CIDFont::CPDF_CIDFont()
- : m_pCMap(nullptr),
- m_pAllocatedCMap(nullptr),
- m_pCID2UnicodeMap(nullptr),
- m_pCIDToGIDMap(nullptr),
- m_bCIDIsGID(FALSE),
- m_pAnsiWidths(nullptr),
- m_bAdobeCourierStd(FALSE),
- m_pTTGSUBTable(nullptr) {}
-
-CPDF_CIDFont::~CPDF_CIDFont() {
- if (m_pAnsiWidths) {
- FX_Free(m_pAnsiWidths);
- }
- delete m_pAllocatedCMap;
- delete m_pCIDToGIDMap;
- delete m_pTTGSUBTable;
-}
-
-bool CPDF_CIDFont::IsCIDFont() const {
- return true;
-}
-
-const CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() const {
- return this;
-}
-
-CPDF_CIDFont* CPDF_CIDFont::AsCIDFont() {
- return this;
-}
-
-uint16_t CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const {
- if (!m_pCMap) {
- return (uint16_t)charcode;
- }
- return m_pCMap->CIDFromCharCode(charcode);
-}
-
-FX_BOOL CPDF_CIDFont::IsVertWriting() const {
- return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
-}
-
-CFX_WideString CPDF_CIDFont::UnicodeFromCharCode(FX_DWORD charcode) const {
- CFX_WideString str = CPDF_Font::UnicodeFromCharCode(charcode);
- if (!str.IsEmpty())
- return str;
- FX_WCHAR ret = GetUnicodeFromCharCode(charcode);
- if (ret == 0)
- return CFX_WideString();
- return ret;
-}
-
-FX_WCHAR CPDF_CIDFont::GetUnicodeFromCharCode(FX_DWORD charcode) const {
- switch (m_pCMap->m_Coding) {
- case CIDCODING_UCS2:
- case CIDCODING_UTF16:
- return (FX_WCHAR)charcode;
- case CIDCODING_CID:
- if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
- return 0;
- }
- return m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)charcode);
- }
- if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
- !m_pCID2UnicodeMap->IsLoaded()) {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
- FX_WCHAR unicode;
- int charsize = 1;
- if (charcode > 255) {
- charcode = (charcode % 256) * 256 + (charcode / 256);
- charsize = 2;
- }
- int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->m_Coding], 0,
- (const FX_CHAR*)&charcode, charsize,
- &unicode, 1);
- if (ret != 1) {
- return 0;
- }
- return unicode;
-#else
- if (m_pCMap->m_pEmbedMap) {
- return EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap,
- m_pCMap->m_Charset, charcode);
- }
- return 0;
-#endif
- }
- return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
-}
-
-FX_DWORD CPDF_CIDFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
- FX_DWORD charcode = CPDF_Font::CharCodeFromUnicode(unicode);
- if (charcode)
- return charcode;
- switch (m_pCMap->m_Coding) {
- case CIDCODING_UNKNOWN:
- return 0;
- case CIDCODING_UCS2:
- case CIDCODING_UTF16:
- return unicode;
- case CIDCODING_CID: {
- if (!m_pCID2UnicodeMap || !m_pCID2UnicodeMap->IsLoaded()) {
- return 0;
- }
- FX_DWORD CID = 0;
- while (CID < 65536) {
- FX_WCHAR this_unicode =
- m_pCID2UnicodeMap->UnicodeFromCID((uint16_t)CID);
- if (this_unicode == unicode) {
- return CID;
- }
- CID++;
- }
- break;
- }
- }
-
- if (unicode < 0x80) {
- return static_cast<FX_DWORD>(unicode);
- }
- if (m_pCMap->m_Coding == CIDCODING_CID) {
- return 0;
- }
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
- uint8_t buffer[32];
- int ret =
- FXSYS_WideCharToMultiByte(g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1,
- (char*)buffer, 4, NULL, NULL);
- if (ret == 1) {
- return buffer[0];
- }
- if (ret == 2) {
- return buffer[0] * 256 + buffer[1];
- }
-#else
- if (m_pCMap->m_pEmbedMap) {
- return EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset,
- unicode);
- }
-#endif
- return 0;
-}
-
-FX_BOOL CPDF_CIDFont::Load() {
- if (m_pFontDict->GetStringBy("Subtype") == "TrueType") {
- return LoadGB2312();
- }
- CPDF_Array* pFonts = m_pFontDict->GetArrayBy("DescendantFonts");
- if (!pFonts) {
- return FALSE;
- }
- if (pFonts->GetCount() != 1) {
- return FALSE;
- }
- CPDF_Dictionary* pCIDFontDict = pFonts->GetDictAt(0);
- if (!pCIDFontDict) {
- return FALSE;
- }
- m_BaseFont = pCIDFontDict->GetStringBy("BaseFont");
- if ((m_BaseFont.Compare("CourierStd") == 0 ||
- m_BaseFont.Compare("CourierStd-Bold") == 0 ||
- m_BaseFont.Compare("CourierStd-BoldOblique") == 0 ||
- m_BaseFont.Compare("CourierStd-Oblique") == 0) &&
- !IsEmbedded()) {
- m_bAdobeCourierStd = TRUE;
- }
- CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
- if (!pEncoding) {
- return FALSE;
- }
- CFX_ByteString subtype = pCIDFontDict->GetStringBy("Subtype");
- m_bType1 = (subtype == "CIDFontType0");
-
- if (pEncoding->IsName()) {
- CFX_ByteString cmap = pEncoding->GetString();
- m_pCMap =
- CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetPredefinedCMap(cmap, m_pFontFile && m_bType1);
- } else if (CPDF_Stream* pStream = pEncoding->AsStream()) {
- m_pAllocatedCMap = m_pCMap = new CPDF_CMap;
- CPDF_StreamAcc acc;
- acc.LoadAllData(pStream, FALSE);
- m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
- } else {
- return FALSE;
- }
- if (!m_pCMap) {
- return FALSE;
- }
- m_Charset = m_pCMap->m_Charset;
- if (m_Charset == CIDSET_UNKNOWN) {
- CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDictBy("CIDSystemInfo");
- if (pCIDInfo) {
- m_Charset = CharsetFromOrdering(pCIDInfo->GetStringBy("Ordering"));
- }
- }
- if (m_Charset != CIDSET_UNKNOWN)
- m_pCID2UnicodeMap =
- CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetCID2UnicodeMap(
- m_Charset,
- !m_pFontFile && (m_pCMap->m_Coding == CIDCODING_CID ||
- pCIDFontDict->KeyExist("W")));
- if (m_Font.GetFace()) {
- if (m_bType1) {
- FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
- } else {
- FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding);
- }
- }
- m_DefaultWidth = pCIDFontDict->GetIntegerBy("DW", 1000);
- CPDF_Array* pWidthArray = pCIDFontDict->GetArrayBy("W");
- if (pWidthArray) {
- LoadMetricsArray(pWidthArray, m_WidthList, 1);
- }
- if (!IsEmbedded()) {
- LoadSubstFont();
- }
- if (1) {
- if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
- CPDF_Object* pmap = pCIDFontDict->GetElementValue("CIDToGIDMap");
- if (pmap) {
- if (CPDF_Stream* pStream = pmap->AsStream()) {
- m_pCIDToGIDMap = new CPDF_StreamAcc;
- m_pCIDToGIDMap->LoadAllData(pStream, FALSE);
- } else if (pmap->GetString() == "Identity") {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (m_pFontFile) {
- m_bCIDIsGID = TRUE;
- }
-#else
- m_bCIDIsGID = TRUE;
-#endif
- }
- }
- }
- }
- CheckFontMetrics();
- if (IsVertWriting()) {
- pWidthArray = pCIDFontDict->GetArrayBy("W2");
- if (pWidthArray) {
- LoadMetricsArray(pWidthArray, m_VertMetrics, 3);
- }
- CPDF_Array* pDefaultArray = pCIDFontDict->GetArrayBy("DW2");
- if (pDefaultArray) {
- m_DefaultVY = pDefaultArray->GetIntegerAt(0);
- m_DefaultW1 = pDefaultArray->GetIntegerAt(1);
- } else {
- m_DefaultVY = 880;
- m_DefaultW1 = -1000;
- }
- }
- return TRUE;
-}
-
-FX_RECT CPDF_CIDFont::GetCharBBox(FX_DWORD charcode, int level) {
- if (charcode < 256 && m_CharBBox[charcode].right != FX_SMALL_RECT::kInvalid)
- return FX_RECT(m_CharBBox[charcode]);
-
- FX_RECT rect;
- FX_BOOL bVert = FALSE;
- int glyph_index = GlyphFromCharCode(charcode, &bVert);
- FXFT_Face face = m_Font.GetFace();
- if (face) {
- if (FXFT_Is_Face_Tricky(face)) {
- int err = FXFT_Load_Glyph(face, glyph_index,
- FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- if (!err) {
- FXFT_BBox cbox;
- FXFT_Glyph glyph;
- err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph);
- if (!err) {
- FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
- int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem;
- int pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem;
- if (pixel_size_x == 0 || pixel_size_y == 0) {
- rect = FX_RECT(cbox.xMin, cbox.yMax, cbox.xMax, cbox.yMin);
- } else {
- rect = FX_RECT(cbox.xMin * 1000 / pixel_size_x,
- cbox.yMax * 1000 / pixel_size_y,
- cbox.xMax * 1000 / pixel_size_x,
- cbox.yMin * 1000 / pixel_size_y);
- }
- if (rect.top > FXFT_Get_Face_Ascender(face)) {
- rect.top = FXFT_Get_Face_Ascender(face);
- }
- if (rect.bottom < FXFT_Get_Face_Descender(face)) {
- rect.bottom = FXFT_Get_Face_Descender(face);
- }
- FXFT_Done_Glyph(glyph);
- }
- }
- } else {
- int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE);
- if (err == 0) {
- rect = FX_RECT(TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
- TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
- TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) +
- FXFT_Get_Glyph_Width(face),
- face),
- TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) -
- FXFT_Get_Glyph_Height(face),
- face));
- rect.top += rect.top / 64;
- }
- }
- }
- if (!m_pFontFile && m_Charset == CIDSET_JAPAN1) {
- uint16_t CID = CIDFromCharCode(charcode);
- const uint8_t* pTransform = GetCIDTransform(CID);
- if (pTransform && !bVert) {
- CFX_Matrix matrix(CIDTransformToFloat(pTransform[0]),
- CIDTransformToFloat(pTransform[1]),
- CIDTransformToFloat(pTransform[2]),
- CIDTransformToFloat(pTransform[3]),
- CIDTransformToFloat(pTransform[4]) * 1000,
- CIDTransformToFloat(pTransform[5]) * 1000);
- CFX_FloatRect rect_f(rect);
- rect_f.Transform(&matrix);
- rect = rect_f.GetOutterRect();
- }
- }
- if (charcode < 256)
- m_CharBBox[charcode] = rect.ToSmallRect();
-
- return rect;
-}
-int CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level) {
- if (m_pAnsiWidths && charcode < 0x80) {
- return m_pAnsiWidths[charcode];
- }
- uint16_t cid = CIDFromCharCode(charcode);
- int size = m_WidthList.GetSize();
- FX_DWORD* list = m_WidthList.GetData();
- for (int i = 0; i < size; i += 3) {
- if (cid >= list[i] && cid <= list[i + 1]) {
- return (int)list[i + 2];
- }
- }
- return m_DefaultWidth;
-}
-short CPDF_CIDFont::GetVertWidth(uint16_t CID) const {
- FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
- if (vertsize == 0) {
- return m_DefaultW1;
- }
- const FX_DWORD* pTable = m_VertMetrics.GetData();
- for (FX_DWORD i = 0; i < vertsize; i++)
- if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
- return (short)(int)pTable[i * 5 + 2];
- }
- return m_DefaultW1;
-}
-void CPDF_CIDFont::GetVertOrigin(uint16_t CID, short& vx, short& vy) const {
- FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
- if (vertsize) {
- const FX_DWORD* pTable = m_VertMetrics.GetData();
- for (FX_DWORD i = 0; i < vertsize; i++)
- if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
- vx = (short)(int)pTable[i * 5 + 3];
- vy = (short)(int)pTable[i * 5 + 4];
- return;
- }
- }
- FX_DWORD dwWidth = m_DefaultWidth;
- int size = m_WidthList.GetSize();
- const FX_DWORD* list = m_WidthList.GetData();
- for (int i = 0; i < size; i += 3) {
- if (CID >= list[i] && CID <= list[i + 1]) {
- dwWidth = (uint16_t)list[i + 2];
- break;
- }
- }
- vx = (short)dwWidth / 2;
- vy = (short)m_DefaultVY;
-}
-int CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL* pVertGlyph) {
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- FXFT_Face face = m_Font.GetFace();
- int index = FXFT_Get_Char_Index(face, unicode);
- if (unicode == 0x2502) {
- return index;
- }
- if (index && IsVertWriting()) {
- if (m_pTTGSUBTable) {
- uint32_t vindex = 0;
- m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
- if (vindex) {
- index = vindex;
- if (pVertGlyph) {
- *pVertGlyph = TRUE;
- }
- }
- return index;
- }
- if (!m_Font.GetSubData()) {
- unsigned long length = 0;
- int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
- NULL, &length);
- if (!error) {
- m_Font.SetSubData(FX_Alloc(uint8_t, length));
- }
- }
- int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0,
- m_Font.GetSubData(), NULL);
- if (!error && m_Font.GetSubData()) {
- m_pTTGSUBTable = new CFX_CTTGSUBTable;
- m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData());
- uint32_t vindex = 0;
- m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
- if (vindex) {
- index = vindex;
- if (pVertGlyph) {
- *pVertGlyph = TRUE;
- }
- }
- }
- return index;
- }
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- return index;
-}
-int CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
- if (pVertGlyph) {
- *pVertGlyph = FALSE;
- }
- if (!m_pFontFile && !m_pCIDToGIDMap) {
- uint16_t cid = CIDFromCharCode(charcode);
- FX_WCHAR unicode = 0;
- if (m_bCIDIsGID) {
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
- return cid;
-#else
- if (m_Flags & PDFFONT_SYMBOLIC) {
- return cid;
- }
- CFX_WideString uni_str = UnicodeFromCharCode(charcode);
- if (uni_str.IsEmpty()) {
- return cid;
- }
- unicode = uni_str.GetAt(0);
-#endif
- } else {
- if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) {
- unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid);
- }
- if (unicode == 0) {
- unicode = GetUnicodeFromCharCode(charcode);
- }
- if (unicode == 0 && !(m_Flags & PDFFONT_SYMBOLIC)) {
- unicode = UnicodeFromCharCode(charcode).GetAt(0);
- }
- }
- FXFT_Face face = m_Font.GetFace();
- if (unicode == 0) {
- if (!m_bAdobeCourierStd) {
- return charcode == 0 ? -1 : (int)charcode;
- }
- charcode += 31;
- int index = 0, iBaseEncoding;
- FX_BOOL bMSUnicode = FT_UseTTCharmap(face, 3, 1);
- FX_BOOL bMacRoman = FALSE;
- if (!bMSUnicode) {
- bMacRoman = FT_UseTTCharmap(face, 1, 0);
- }
- iBaseEncoding = PDFFONT_ENCODING_STANDARD;
- if (bMSUnicode) {
- iBaseEncoding = PDFFONT_ENCODING_WINANSI;
- } else if (bMacRoman) {
- iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
- }
- const FX_CHAR* name = GetAdobeCharName(iBaseEncoding, NULL, charcode);
- if (!name) {
- return charcode == 0 ? -1 : (int)charcode;
- }
- uint16_t unicode = PDF_UnicodeFromAdobeName(name);
- if (unicode) {
- if (bMSUnicode) {
- index = FXFT_Get_Char_Index(face, unicode);
- } else if (bMacRoman) {
- FX_DWORD maccode =
- FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode);
- index = !maccode ? FXFT_Get_Name_Index(face, (char*)name)
- : FXFT_Get_Char_Index(face, maccode);
- } else {
- return FXFT_Get_Char_Index(face, unicode);
- }
- } else {
- return charcode == 0 ? -1 : (int)charcode;
- }
- if (index == 0 || index == 0xffff) {
- return charcode == 0 ? -1 : (int)charcode;
- }
- return index;
- }
- if (m_Charset == CIDSET_JAPAN1) {
- if (unicode == '\\') {
- unicode = '/';
-#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
- } else if (unicode == 0xa5) {
- unicode = 0x5c;
-#endif
- }
- }
- if (!face)
- return unicode;
-
- int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
- if (err != 0) {
- int i;
- for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
- FX_DWORD ret = FT_CharCodeFromUnicode(
- FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]),
- (FX_WCHAR)charcode);
- if (ret == 0) {
- continue;
- }
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
- unicode = (FX_WCHAR)ret;
- break;
- }
- if (i == FXFT_Get_Face_CharmapCount(face) && i) {
- FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
- unicode = (FX_WCHAR)charcode;
- }
- }
- if (FXFT_Get_Face_Charmap(face)) {
- int index = GetGlyphIndex(unicode, pVertGlyph);
- if (index == 0)
- return -1;
- return index;
- }
- return unicode;
- }
- if (!m_Font.GetFace())
- return -1;
-
- uint16_t cid = CIDFromCharCode(charcode);
- if (m_bType1) {
- if (!m_pCIDToGIDMap) {
- return cid;
- }
- } else {
- if (!m_pCIDToGIDMap) {
- if (m_pFontFile && !m_pCMap->m_pMapping)
- return cid;
- if (m_pCMap->m_Coding == CIDCODING_UNKNOWN ||
- !FXFT_Get_Face_Charmap(m_Font.GetFace())) {
- return cid;
- }
- if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) ==
- FXFT_ENCODING_UNICODE) {
- CFX_WideString unicode_str = UnicodeFromCharCode(charcode);
- if (unicode_str.IsEmpty()) {
- return -1;
- }
- charcode = unicode_str.GetAt(0);
- }
- return GetGlyphIndex(charcode, pVertGlyph);
- }
- }
- FX_DWORD byte_pos = cid * 2;
- if (byte_pos + 2 > m_pCIDToGIDMap->GetSize())
- return -1;
-
- const uint8_t* pdata = m_pCIDToGIDMap->GetData() + byte_pos;
- return pdata[0] * 256 + pdata[1];
-}
-FX_DWORD CPDF_CIDFont::GetNextChar(const FX_CHAR* pString,
- int nStrLen,
- int& offset) const {
- return m_pCMap->GetNextChar(pString, nStrLen, offset);
-}
-int CPDF_CIDFont::GetCharSize(FX_DWORD charcode) const {
- return m_pCMap->GetCharSize(charcode);
-}
-int CPDF_CIDFont::CountChar(const FX_CHAR* pString, int size) const {
- return m_pCMap->CountChar(pString, size);
-}
-int CPDF_CIDFont::AppendChar(FX_CHAR* str, FX_DWORD charcode) const {
- return m_pCMap->AppendChar(str, charcode);
-}
-FX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const {
- if (!m_pCMap->IsLoaded() || !m_pCID2UnicodeMap ||
- !m_pCID2UnicodeMap->IsLoaded()) {
- return m_pCMap->m_Coding != CIDCODING_UNKNOWN;
- }
- return TRUE;
-}
-FX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const {
- return TRUE;
-}
-void CPDF_CIDFont::LoadSubstFont() {
- m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle,
- g_CharsetCPs[m_Charset], IsVertWriting());
-}
-void CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray,
- CFX_DWordArray& result,
- int nElements) {
- int width_status = 0;
- int iCurElement = 0;
- int first_code = 0;
- int last_code = 0;
- FX_DWORD count = pArray->GetCount();
- for (FX_DWORD i = 0; i < count; i++) {
- CPDF_Object* pObj = pArray->GetElementValue(i);
- if (!pObj)
- continue;
-
- if (CPDF_Array* pArray = pObj->AsArray()) {
- if (width_status != 1)
- return;
-
- FX_DWORD count = pArray->GetCount();
- for (FX_DWORD j = 0; j < count; j += nElements) {
- result.Add(first_code);
- result.Add(first_code);
- for (int k = 0; k < nElements; k++) {
- result.Add(pArray->GetIntegerAt(j + k));
- }
- first_code++;
- }
- width_status = 0;
- } else {
- if (width_status == 0) {
- first_code = pObj->GetInteger();
- width_status = 1;
- } else if (width_status == 1) {
- last_code = pObj->GetInteger();
- width_status = 2;
- iCurElement = 0;
- } else {
- if (!iCurElement) {
- result.Add(first_code);
- result.Add(last_code);
- }
- result.Add(pObj->GetInteger());
- iCurElement++;
- if (iCurElement == nElements) {
- width_status = 0;
- }
- }
- }
- }
-}
-
-// static
-FX_FLOAT CPDF_CIDFont::CIDTransformToFloat(uint8_t ch) {
- if (ch < 128) {
- return ch * 1.0f / 127;
- }
- return (-255 + ch) * 1.0f / 127;
-}
-
-FX_BOOL CPDF_CIDFont::LoadGB2312() {
- m_BaseFont = m_pFontDict->GetStringBy("BaseFont");
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
- if (pFontDesc) {
- LoadFontDescriptor(pFontDesc);
- }
- m_Charset = CIDSET_GB1;
- m_bType1 = FALSE;
- m_pCMap = CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetPredefinedCMap("GBK-EUC-H", FALSE);
- m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()
- ->GetPageModule()
- ->GetFontGlobals()
- ->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE);
- if (!IsEmbedded()) {
- LoadSubstFont();
- }
- CheckFontMetrics();
- m_DefaultWidth = 1000;
- m_pAnsiWidths = FX_Alloc(uint16_t, 128);
- for (int i = 32; i < 127; i++) {
- m_pAnsiWidths[i] = 500;
+CIDSet CharsetFromOrdering(const CFX_ByteString& ordering) {
+ for (size_t charset = 1; charset < FX_ArraySize(g_CharsetNames); ++charset) {
+ if (ordering == CFX_ByteStringC(g_CharsetNames[charset]))
+ return CIDSetFromSizeT(charset);
}
- return TRUE;
-}
-
-const uint8_t* CPDF_CIDFont::GetCIDTransform(uint16_t CID) const {
- if (m_Charset != CIDSET_JAPAN1 || m_pFontFile)
- return nullptr;
-
- const struct CIDTransform* found = (const struct CIDTransform*)FXSYS_bsearch(
- &CID, g_Japan1_VertCIDs, FX_ArraySize(g_Japan1_VertCIDs),
- sizeof(g_Japan1_VertCIDs[0]), CompareCIDTransform);
- return found ? &found->a : nullptr;
+ return CIDSET_UNKNOWN;
}
diff --git a/core/fpdfapi/fpdf_font/include/cpdf_font.h b/core/fpdfapi/fpdf_font/include/cpdf_font.h
new file mode 100644
index 0000000000..1931c245de
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/include/cpdf_font.h
@@ -0,0 +1,128 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONT_H_
+#define CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONT_H_
+
+#include "core/fxcrt/include/fx_string.h"
+#include "core/fxcrt/include/fx_system.h"
+#include "core/include/fxge/fx_font.h"
+
+#define PDFFONT_FIXEDPITCH 1
+#define PDFFONT_SERIF 2
+#define PDFFONT_SYMBOLIC 4
+#define PDFFONT_SCRIPT 8
+#define PDFFONT_NONSYMBOLIC 32
+#define PDFFONT_ITALIC 64
+#define PDFFONT_ALLCAP 0x10000
+#define PDFFONT_SMALLCAP 0x20000
+#define PDFFONT_FORCEBOLD 0x40000
+#define PDFFONT_USEEXTERNATTR 0x80000
+
+class CFX_SubstFont;
+class CPDF_CIDFont;
+class CPDF_Dictionary;
+class CPDF_Document;
+class CPDF_Object;
+class CPDF_StreamAcc;
+class CPDF_TrueTypeFont;
+class CPDF_Type1Font;
+class CPDF_Type3Font;
+class CPDF_ToUnicodeMap;
+
+class CPDF_Font {
+ public:
+ static CPDF_Font* CreateFontF(CPDF_Document* pDoc,
+ CPDF_Dictionary* pFontDict);
+ static CPDF_Font* GetStockFont(CPDF_Document* pDoc,
+ const CFX_ByteStringC& fontname);
+ static const FX_DWORD kInvalidCharCode = static_cast<FX_DWORD>(-1);
+
+ virtual ~CPDF_Font();
+
+ virtual bool IsType1Font() const;
+ virtual bool IsTrueTypeFont() const;
+ virtual bool IsType3Font() const;
+ virtual bool IsCIDFont() const;
+ virtual const CPDF_Type1Font* AsType1Font() const;
+ virtual CPDF_Type1Font* AsType1Font();
+ virtual const CPDF_TrueTypeFont* AsTrueTypeFont() const;
+ virtual CPDF_TrueTypeFont* AsTrueTypeFont();
+ virtual const CPDF_Type3Font* AsType3Font() const;
+ virtual CPDF_Type3Font* AsType3Font();
+ virtual const CPDF_CIDFont* AsCIDFont() const;
+ virtual CPDF_CIDFont* AsCIDFont();
+
+ virtual FX_BOOL IsVertWriting() const;
+ virtual FX_BOOL IsUnicodeCompatible() const;
+ virtual FX_DWORD GetNextChar(const FX_CHAR* pString,
+ int nStrLen,
+ int& offset) const;
+ virtual int CountChar(const FX_CHAR* pString, int size) const;
+ virtual int AppendChar(FX_CHAR* buf, FX_DWORD charcode) const;
+ virtual int GetCharSize(FX_DWORD charcode) const;
+ virtual int GlyphFromCharCode(FX_DWORD charcode,
+ FX_BOOL* pVertGlyph = nullptr);
+ virtual int GlyphFromCharCodeExt(FX_DWORD charcode);
+ virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const;
+ virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const;
+
+ const CFX_ByteString& GetBaseFont() const { return m_BaseFont; }
+ const CFX_SubstFont* GetSubstFont() const { return m_Font.GetSubstFont(); }
+ FX_DWORD GetFlags() const { return m_Flags; }
+ FX_BOOL IsEmbedded() const { return IsType3Font() || m_pFontFile != nullptr; }
+ CPDF_StreamAcc* GetFontFile() const { return m_pFontFile; }
+ CPDF_Dictionary* GetFontDict() const { return m_pFontDict; }
+ FX_BOOL IsStandardFont() const;
+ FXFT_Face GetFace() const { return m_Font.GetFace(); }
+ void AppendChar(CFX_ByteString& str, FX_DWORD charcode) const;
+
+ void GetFontBBox(FX_RECT& rect) const { rect = m_FontBBox; }
+ int GetTypeAscent() const { return m_Ascent; }
+ int GetTypeDescent() const { return m_Descent; }
+ int GetItalicAngle() const { return m_ItalicAngle; }
+ int GetStemV() const { return m_StemV; }
+ int GetStringWidth(const FX_CHAR* pString, int size);
+
+ virtual int GetCharWidthF(FX_DWORD charcode, int level = 0) = 0;
+ virtual FX_RECT GetCharBBox(FX_DWORD charcode, int level = 0) = 0;
+
+ CPDF_Document* m_pDocument;
+ CFX_Font m_Font;
+
+ protected:
+ CPDF_Font();
+
+ virtual FX_BOOL Load() = 0;
+
+ FX_BOOL Initialize();
+ void LoadUnicodeMap();
+ void LoadPDFEncoding(CPDF_Object* pEncoding,
+ int& iBaseEncoding,
+ CFX_ByteString*& pCharNames,
+ FX_BOOL bEmbedded,
+ FX_BOOL bTrueType);
+ void LoadFontDescriptor(CPDF_Dictionary* pDict);
+ void CheckFontMetrics();
+
+ const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
+ const CFX_ByteString* pCharNames,
+ int charcode);
+
+ CFX_ByteString m_BaseFont;
+ CPDF_StreamAcc* m_pFontFile;
+ CPDF_Dictionary* m_pFontDict;
+ CPDF_ToUnicodeMap* m_pToUnicodeMap;
+ FX_BOOL m_bToUnicodeLoaded;
+ int m_Flags;
+ FX_RECT m_FontBBox;
+ int m_StemV;
+ int m_Ascent;
+ int m_Descent;
+ int m_ItalicAngle;
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONT_H_
diff --git a/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h b/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h
new file mode 100644
index 0000000000..a64687cd0e
--- /dev/null
+++ b/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h
@@ -0,0 +1,59 @@
+// 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
+
+#ifndef CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_
+#define CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_
+
+#include "core/fxcrt/include/fx_string.h"
+
+#define PDFFONT_ENCODING_BUILTIN 0
+#define PDFFONT_ENCODING_WINANSI 1
+#define PDFFONT_ENCODING_MACROMAN 2
+#define PDFFONT_ENCODING_MACEXPERT 3
+#define PDFFONT_ENCODING_STANDARD 4
+#define PDFFONT_ENCODING_ADOBE_SYMBOL 5
+#define PDFFONT_ENCODING_ZAPFDINGBATS 6
+#define PDFFONT_ENCODING_PDFDOC 7
+#define PDFFONT_ENCODING_MS_SYMBOL 8
+#define PDFFONT_ENCODING_UNICODE 9
+
+FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
+FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode);
+
+FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name);
+CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode);
+
+const uint16_t* PDF_UnicodesForPredefinedCharSet(int encoding);
+const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding,
+ uint8_t charcode);
+
+class CPDF_Object;
+
+class CPDF_FontEncoding {
+ public:
+ CPDF_FontEncoding();
+ explicit CPDF_FontEncoding(int PredefinedEncoding);
+
+ void LoadEncoding(CPDF_Object* pEncoding);
+
+ FX_BOOL IsIdentical(CPDF_FontEncoding* pAnother) const;
+
+ FX_WCHAR UnicodeFromCharCode(uint8_t charcode) const {
+ return m_Unicodes[charcode];
+ }
+ int CharCodeFromUnicode(FX_WCHAR unicode) const;
+
+ void SetUnicode(uint8_t charcode, FX_WCHAR unicode) {
+ m_Unicodes[charcode] = unicode;
+ }
+
+ CPDF_Object* Realize();
+
+ public:
+ FX_WCHAR m_Unicodes[256];
+};
+
+#endif // CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_