191 lines
6.2 KiB
C++
191 lines
6.2 KiB
C++
// 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/cfx_fontmgr.h"
|
|
|
|
#include <memory>
|
|
#include <utility>
|
|
|
|
#include "core/fxge/cfx_face.h"
|
|
#include "core/fxge/cfx_fontmapper.h"
|
|
#include "core/fxge/cfx_substfont.h"
|
|
#include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
|
|
#include "core/fxge/fx_font.h"
|
|
#include "core/fxge/systemfontinfo_iface.h"
|
|
#include "third_party/base/ptr_util.h"
|
|
|
|
namespace {
|
|
|
|
struct BuiltinFont {
|
|
const uint8_t* m_pFontData; // Raw, POD struct.
|
|
uint32_t m_dwSize;
|
|
};
|
|
|
|
const BuiltinFont g_FoxitFonts[14] = {
|
|
{g_FoxitFixedFontData, 17597},
|
|
{g_FoxitFixedBoldFontData, 18055},
|
|
{g_FoxitFixedBoldItalicFontData, 19151},
|
|
{g_FoxitFixedItalicFontData, 18746},
|
|
{g_FoxitSansFontData, 15025},
|
|
{g_FoxitSansBoldFontData, 16344},
|
|
{g_FoxitSansBoldItalicFontData, 16418},
|
|
{g_FoxitSansItalicFontData, 16339},
|
|
{g_FoxitSerifFontData, 19469},
|
|
{g_FoxitSerifBoldFontData, 19395},
|
|
{g_FoxitSerifBoldItalicFontData, 20733},
|
|
{g_FoxitSerifItalicFontData, 21227},
|
|
{g_FoxitSymbolFontData, 16729},
|
|
{g_FoxitDingbatsFontData, 29513},
|
|
};
|
|
|
|
const BuiltinFont g_MMFonts[2] = {
|
|
{g_FoxitSerifMMFontData, 113417},
|
|
{g_FoxitSansMMFontData, 66919},
|
|
};
|
|
|
|
ByteString KeyNameFromFace(const ByteString& face_name,
|
|
int weight,
|
|
bool bItalic) {
|
|
ByteString key(face_name);
|
|
key += ',';
|
|
key += ByteString::FormatInteger(weight);
|
|
key += bItalic ? 'I' : 'N';
|
|
return key;
|
|
}
|
|
|
|
ByteString KeyNameFromSize(int ttc_size, uint32_t checksum) {
|
|
return ByteString::Format("%d:%d", ttc_size, checksum);
|
|
}
|
|
|
|
FXFT_LibraryRec* FTLibraryInitHelper() {
|
|
FXFT_LibraryRec* pLibrary = nullptr;
|
|
FT_Init_FreeType(&pLibrary);
|
|
return pLibrary;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
CFX_FontMgr::FontDesc::FontDesc(std::unique_ptr<uint8_t, FxFreeDeleter> pData,
|
|
size_t size)
|
|
: m_Size(size), m_pFontData(std::move(pData)) {}
|
|
|
|
CFX_FontMgr::FontDesc::~FontDesc() = default;
|
|
|
|
void CFX_FontMgr::FontDesc::SetFace(size_t index, CFX_Face* face) {
|
|
ASSERT(index < FX_ArraySize(m_TTCFaces));
|
|
m_TTCFaces[index].Reset(face);
|
|
}
|
|
|
|
CFX_Face* CFX_FontMgr::FontDesc::GetFace(size_t index) const {
|
|
ASSERT(index < FX_ArraySize(m_TTCFaces));
|
|
return m_TTCFaces[index].Get();
|
|
}
|
|
|
|
CFX_FontMgr::CFX_FontMgr()
|
|
: m_FTLibrary(FTLibraryInitHelper()),
|
|
m_pBuiltinMapper(pdfium::MakeUnique<CFX_FontMapper>(this)),
|
|
m_FTLibrarySupportsHinting(SetLcdFilterMode() ||
|
|
FreeTypeVersionSupportsHinting()) {}
|
|
|
|
CFX_FontMgr::~CFX_FontMgr() = default;
|
|
|
|
void CFX_FontMgr::SetSystemFontInfo(
|
|
std::unique_ptr<SystemFontInfoIface> pFontInfo) {
|
|
m_pBuiltinMapper->SetSystemFontInfo(std::move(pFontInfo));
|
|
}
|
|
|
|
RetainPtr<CFX_Face> CFX_FontMgr::FindSubstFont(const ByteString& face_name,
|
|
bool bTrueType,
|
|
uint32_t flags,
|
|
int weight,
|
|
int italic_angle,
|
|
int CharsetCP,
|
|
CFX_SubstFont* pSubstFont) {
|
|
return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
|
|
italic_angle, CharsetCP, pSubstFont);
|
|
}
|
|
|
|
RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedFontDesc(
|
|
const ByteString& face_name,
|
|
int weight,
|
|
bool bItalic) {
|
|
auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
|
|
return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
|
|
}
|
|
|
|
RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedFontDesc(
|
|
const ByteString& face_name,
|
|
int weight,
|
|
bool bItalic,
|
|
std::unique_ptr<uint8_t, FxFreeDeleter> pData,
|
|
uint32_t size) {
|
|
auto pFontDesc = pdfium::MakeRetain<FontDesc>(std::move(pData), size);
|
|
m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)].Reset(pFontDesc.Get());
|
|
return pFontDesc;
|
|
}
|
|
|
|
RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedTTCFontDesc(
|
|
int ttc_size,
|
|
uint32_t checksum) {
|
|
auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
|
|
return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
|
|
}
|
|
|
|
RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedTTCFontDesc(
|
|
int ttc_size,
|
|
uint32_t checksum,
|
|
std::unique_ptr<uint8_t, FxFreeDeleter> pData,
|
|
uint32_t size) {
|
|
auto pNewDesc = pdfium::MakeRetain<FontDesc>(std::move(pData), size);
|
|
m_FaceMap[KeyNameFromSize(ttc_size, checksum)].Reset(pNewDesc.Get());
|
|
return pNewDesc;
|
|
}
|
|
|
|
RetainPtr<CFX_Face> CFX_FontMgr::NewFixedFace(const RetainPtr<FontDesc>& pDesc,
|
|
pdfium::span<const uint8_t> span,
|
|
int face_index) {
|
|
RetainPtr<CFX_Face> face =
|
|
CFX_Face::New(m_FTLibrary.get(), pDesc, span, face_index);
|
|
if (!face)
|
|
return nullptr;
|
|
|
|
if (FT_Set_Pixel_Sizes(face->GetRec(), 64, 64) != 0)
|
|
return nullptr;
|
|
|
|
return face;
|
|
}
|
|
|
|
// static
|
|
Optional<pdfium::span<const uint8_t>> CFX_FontMgr::GetBuiltinFont(
|
|
size_t index) {
|
|
if (index < FX_ArraySize(g_FoxitFonts)) {
|
|
return pdfium::make_span(g_FoxitFonts[index].m_pFontData,
|
|
g_FoxitFonts[index].m_dwSize);
|
|
}
|
|
size_t mm_index = index - FX_ArraySize(g_FoxitFonts);
|
|
if (mm_index < FX_ArraySize(g_MMFonts)) {
|
|
return pdfium::make_span(g_MMFonts[mm_index].m_pFontData,
|
|
g_MMFonts[mm_index].m_dwSize);
|
|
}
|
|
return {};
|
|
}
|
|
|
|
bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
|
|
FT_Int major;
|
|
FT_Int minor;
|
|
FT_Int patch;
|
|
FT_Library_Version(m_FTLibrary.get(), &major, &minor, &patch);
|
|
// Freetype versions >= 2.8.1 support hinting even if subpixel rendering is
|
|
// disabled. https://sourceforge.net/projects/freetype/files/freetype2/2.8.1/
|
|
return major > 2 || (major == 2 && minor > 8) ||
|
|
(major == 2 && minor == 8 && patch >= 1);
|
|
}
|
|
|
|
bool CFX_FontMgr::SetLcdFilterMode() const {
|
|
return FT_Library_SetLcdFilter(m_FTLibrary.get(), FT_LCD_FILTER_DEFAULT) !=
|
|
FT_Err_Unimplemented_Feature;
|
|
}
|