summaryrefslogtreecommitdiff
path: root/core/fxge/ge/cfx_folderfontinfo.cpp
diff options
context:
space:
mode:
authornpm <npm@chromium.org>2016-07-27 13:54:25 -0700
committerCommit bot <commit-bot@chromium.org>2016-07-27 13:54:25 -0700
commitf73893a6110f2d4960b372fb4fe38e4fd629ce8f (patch)
treee90128b1eb13a8d5c623fb91b30b07a5cf58eb86 /core/fxge/ge/cfx_folderfontinfo.cpp
parent461eeafe191068ac8c32f2717907fc6a22a667d2 (diff)
downloadpdfium-f73893a6110f2d4960b372fb4fe38e4fd629ce8f.tar.xz
Splitting fx_ge_fontmap.cpp
Move CFX_FolderFontInfo, CFX_FontMgr, and CFX_FontMapper into their own classes. There are namespaces in each of the new files, having methods from the original namespace in fx_ge_fontmap, according to what each class needs. Review-Url: https://codereview.chromium.org/2185533006
Diffstat (limited to 'core/fxge/ge/cfx_folderfontinfo.cpp')
-rw-r--r--core/fxge/ge/cfx_folderfontinfo.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/core/fxge/ge/cfx_folderfontinfo.cpp b/core/fxge/ge/cfx_folderfontinfo.cpp
new file mode 100644
index 0000000000..5bd5b29c79
--- /dev/null
+++ b/core/fxge/ge/cfx_folderfontinfo.cpp
@@ -0,0 +1,377 @@
+// 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/fxge/ge/cfx_folderfontinfo.h"
+
+#include "core/fxge/include/cfx_fontmapper.h"
+#include "core/fxge/include/fx_font.h"
+
+#include "third_party/base/stl_util.h"
+
+namespace {
+
+const struct {
+ const FX_CHAR* m_pName;
+ const FX_CHAR* m_pSubstName;
+} Base14Substs[] = {
+ {"Courier", "Courier New"},
+ {"Courier-Bold", "Courier New Bold"},
+ {"Courier-BoldOblique", "Courier New Bold Italic"},
+ {"Courier-Oblique", "Courier New Italic"},
+ {"Helvetica", "Arial"},
+ {"Helvetica-Bold", "Arial Bold"},
+ {"Helvetica-BoldOblique", "Arial Bold Italic"},
+ {"Helvetica-Oblique", "Arial Italic"},
+ {"Times-Roman", "Times New Roman"},
+ {"Times-Bold", "Times New Roman Bold"},
+ {"Times-BoldItalic", "Times New Roman Bold Italic"},
+ {"Times-Italic", "Times New Roman Italic"},
+};
+
+CFX_ByteString FPDF_ReadStringFromFile(FXSYS_FILE* pFile, uint32_t size) {
+ CFX_ByteString buffer;
+ if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile))
+ return CFX_ByteString();
+ buffer.ReleaseBuffer(size);
+ return buffer;
+}
+
+CFX_ByteString FPDF_LoadTableFromTT(FXSYS_FILE* pFile,
+ const uint8_t* pTables,
+ uint32_t nTables,
+ uint32_t tag) {
+ for (uint32_t i = 0; i < nTables; i++) {
+ const uint8_t* p = pTables + i * 16;
+ if (GET_TT_LONG(p) == tag) {
+ uint32_t offset = GET_TT_LONG(p + 8);
+ uint32_t size = GET_TT_LONG(p + 12);
+ FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
+ return FPDF_ReadStringFromFile(pFile, size);
+ }
+ }
+ return CFX_ByteString();
+}
+
+uint32_t GetCharset(int charset) {
+ switch (charset) {
+ case FXFONT_SHIFTJIS_CHARSET:
+ return CHARSET_FLAG_SHIFTJIS;
+ case FXFONT_GB2312_CHARSET:
+ return CHARSET_FLAG_GB;
+ case FXFONT_CHINESEBIG5_CHARSET:
+ return CHARSET_FLAG_BIG5;
+ case FXFONT_HANGEUL_CHARSET:
+ return CHARSET_FLAG_KOREAN;
+ case FXFONT_SYMBOL_CHARSET:
+ return CHARSET_FLAG_SYMBOL;
+ case FXFONT_ANSI_CHARSET:
+ return CHARSET_FLAG_ANSI;
+ default:
+ break;
+ }
+ return 0;
+}
+
+int32_t GetSimilarValue(int weight,
+ FX_BOOL bItalic,
+ int pitch_family,
+ uint32_t style) {
+ int32_t iSimilarValue = 0;
+ if (!!(style & FXFONT_BOLD) == (weight > 400))
+ iSimilarValue += 16;
+ if (!!(style & FXFONT_ITALIC) == bItalic)
+ iSimilarValue += 16;
+ if (!!(style & FXFONT_SERIF) == !!(pitch_family & FXFONT_FF_ROMAN))
+ iSimilarValue += 16;
+ if (!!(style & FXFONT_SCRIPT) == !!(pitch_family & FXFONT_FF_SCRIPT))
+ iSimilarValue += 8;
+ if (!!(style & FXFONT_FIXED_PITCH) ==
+ !!(pitch_family & FXFONT_FF_FIXEDPITCH)) {
+ iSimilarValue += 8;
+ }
+ return iSimilarValue;
+}
+
+} // namespace
+
+CFX_FolderFontInfo::CFX_FolderFontInfo() {}
+
+CFX_FolderFontInfo::~CFX_FolderFontInfo() {
+ for (const auto& pair : m_FontList)
+ delete pair.second;
+}
+
+void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) {
+ m_PathList.push_back(CFX_ByteString(path));
+}
+
+FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) {
+ m_pMapper = pMapper;
+ for (const auto& path : m_PathList)
+ ScanPath(path);
+ return TRUE;
+}
+
+void CFX_FolderFontInfo::ScanPath(const CFX_ByteString& path) {
+ void* handle = FX_OpenFolder(path.c_str());
+ if (!handle)
+ return;
+
+ CFX_ByteString filename;
+ FX_BOOL bFolder;
+ while (FX_GetNextFile(handle, filename, bFolder)) {
+ if (bFolder) {
+ if (filename == "." || filename == "..")
+ continue;
+ } else {
+ CFX_ByteString ext = filename.Right(4);
+ ext.MakeUpper();
+ if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC")
+ continue;
+ }
+
+ CFX_ByteString fullpath = path;
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ fullpath += "\\";
+#else
+ fullpath += "/";
+#endif
+
+ fullpath += filename;
+ bFolder ? ScanPath(fullpath) : ScanFile(fullpath);
+ }
+ FX_CloseFolder(handle);
+}
+
+void CFX_FolderFontInfo::ScanFile(const CFX_ByteString& path) {
+ FXSYS_FILE* pFile = FXSYS_fopen(path.c_str(), "rb");
+ if (!pFile)
+ return;
+
+ FXSYS_fseek(pFile, 0, FXSYS_SEEK_END);
+
+ uint32_t filesize = FXSYS_ftell(pFile);
+ uint8_t buffer[16];
+ FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET);
+
+ size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile);
+ if (readCnt != 1) {
+ FXSYS_fclose(pFile);
+ return;
+ }
+
+ if (GET_TT_LONG(buffer) == kTableTTCF) {
+ uint32_t nFaces = GET_TT_LONG(buffer + 8);
+ if (nFaces > std::numeric_limits<uint32_t>::max() / 4) {
+ FXSYS_fclose(pFile);
+ return;
+ }
+ uint32_t face_bytes = nFaces * 4;
+ uint8_t* offsets = FX_Alloc(uint8_t, face_bytes);
+ readCnt = FXSYS_fread(offsets, 1, face_bytes, pFile);
+ if (readCnt != face_bytes) {
+ FX_Free(offsets);
+ FXSYS_fclose(pFile);
+ return;
+ }
+ for (uint32_t i = 0; i < nFaces; i++) {
+ uint8_t* p = offsets + i * 4;
+ ReportFace(path, pFile, filesize, GET_TT_LONG(p));
+ }
+ FX_Free(offsets);
+ } else {
+ ReportFace(path, pFile, filesize, 0);
+ }
+ FXSYS_fclose(pFile);
+}
+
+void CFX_FolderFontInfo::ReportFace(const CFX_ByteString& path,
+ FXSYS_FILE* pFile,
+ uint32_t filesize,
+ uint32_t offset) {
+ FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
+ char buffer[16];
+ if (!FXSYS_fread(buffer, 12, 1, pFile))
+ return;
+
+ uint32_t nTables = GET_TT_SHORT(buffer + 4);
+ CFX_ByteString tables = FPDF_ReadStringFromFile(pFile, nTables * 16);
+ if (tables.IsEmpty())
+ return;
+
+ CFX_ByteString names =
+ FPDF_LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x6e616d65);
+ if (names.IsEmpty())
+ return;
+
+ CFX_ByteString facename =
+ GetNameFromTT(names.raw_str(), names.GetLength(), 1);
+ if (facename.IsEmpty())
+ return;
+
+ CFX_ByteString style = GetNameFromTT(names.raw_str(), names.GetLength(), 2);
+ if (style != "Regular")
+ facename += " " + style;
+
+ if (pdfium::ContainsKey(m_FontList, facename))
+ return;
+
+ CFX_FontFaceInfo* pInfo =
+ new CFX_FontFaceInfo(path, facename, tables, offset, filesize);
+ CFX_ByteString os2 =
+ FPDF_LoadTableFromTT(pFile, tables.raw_str(), nTables, 0x4f532f32);
+ if (os2.GetLength() >= 86) {
+ const uint8_t* p = os2.raw_str() + 78;
+ uint32_t codepages = GET_TT_LONG(p);
+ if (codepages & (1 << 17)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
+ }
+ if (codepages & (1 << 18)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_GB;
+ }
+ if (codepages & (1 << 20)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_BIG5;
+ }
+ if ((codepages & (1 << 19)) || (codepages & (1 << 21))) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_KOREAN;
+ }
+ if (codepages & (1 << 31)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL;
+ }
+ }
+ m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_ANSI;
+ pInfo->m_Styles = 0;
+ if (style.Find("Bold") > -1)
+ pInfo->m_Styles |= FXFONT_BOLD;
+ if (style.Find("Italic") > -1 || style.Find("Oblique") > -1)
+ pInfo->m_Styles |= FXFONT_ITALIC;
+ if (facename.Find("Serif") > -1)
+ pInfo->m_Styles |= FXFONT_SERIF;
+
+ m_FontList[facename] = pInfo;
+}
+
+void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) {
+ for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs);
+ iBaseFont++) {
+ if (face == Base14Substs[iBaseFont].m_pName)
+ return GetFont(Base14Substs[iBaseFont].m_pSubstName);
+ }
+ return nullptr;
+}
+
+void* CFX_FolderFontInfo::FindFont(int weight,
+ FX_BOOL bItalic,
+ int charset,
+ int pitch_family,
+ const FX_CHAR* family,
+ FX_BOOL bMatchName) {
+ CFX_FontFaceInfo* pFind = nullptr;
+ if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH))
+ return GetFont("Courier New");
+ uint32_t charset_flag = GetCharset(charset);
+ int32_t iBestSimilar = 0;
+ for (const auto& it : m_FontList) {
+ const CFX_ByteString& bsName = it.first;
+ CFX_FontFaceInfo* pFont = it.second;
+ if (!(pFont->m_Charsets & charset_flag) &&
+ charset != FXFONT_DEFAULT_CHARSET) {
+ continue;
+ }
+ int32_t index = bsName.Find(family);
+ if (bMatchName && index < 0)
+ continue;
+ int32_t iSimilarValue =
+ GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles);
+ if (iSimilarValue > iBestSimilar) {
+ iBestSimilar = iSimilarValue;
+ pFind = pFont;
+ }
+ }
+ return pFind;
+}
+
+void* CFX_FolderFontInfo::MapFont(int weight,
+ FX_BOOL bItalic,
+ int charset,
+ int pitch_family,
+ const FX_CHAR* family,
+ int& iExact) {
+ return nullptr;
+}
+
+#ifdef PDF_ENABLE_XFA
+void* CFX_FolderFontInfo::MapFontByUnicode(uint32_t dwUnicode,
+ int weight,
+ FX_BOOL bItalic,
+ int pitch_family) {
+ return nullptr;
+}
+#endif // PDF_ENABLE_XFA
+
+void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) {
+ auto it = m_FontList.find(face);
+ return it != m_FontList.end() ? it->second : nullptr;
+}
+
+uint32_t CFX_FolderFontInfo::GetFontData(void* hFont,
+ uint32_t table,
+ uint8_t* buffer,
+ uint32_t size) {
+ if (!hFont)
+ return 0;
+
+ const CFX_FontFaceInfo* pFont = static_cast<CFX_FontFaceInfo*>(hFont);
+ uint32_t datasize = 0;
+ uint32_t offset = 0;
+ if (table == 0) {
+ datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize;
+ } else if (table == kTableTTCF) {
+ datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0;
+ } else {
+ uint32_t nTables = pFont->m_FontTables.GetLength() / 16;
+ for (uint32_t i = 0; i < nTables; i++) {
+ const uint8_t* p = pFont->m_FontTables.raw_str() + i * 16;
+ if (GET_TT_LONG(p) == table) {
+ offset = GET_TT_LONG(p + 8);
+ datasize = GET_TT_LONG(p + 12);
+ }
+ }
+ }
+
+ if (!datasize || size < datasize)
+ return datasize;
+
+ FXSYS_FILE* pFile = FXSYS_fopen(pFont->m_FilePath.c_str(), "rb");
+ if (!pFile)
+ return 0;
+
+ if (FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET) < 0 ||
+ FXSYS_fread(buffer, datasize, 1, pFile) != 1) {
+ datasize = 0;
+ }
+ FXSYS_fclose(pFile);
+ return datasize;
+}
+
+void CFX_FolderFontInfo::DeleteFont(void* hFont) {}
+FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) {
+ if (!hFont)
+ return FALSE;
+ CFX_FontFaceInfo* pFont = (CFX_FontFaceInfo*)hFont;
+ name = pFont->m_FaceName;
+ return TRUE;
+}
+
+FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) {
+ return FALSE;
+}