1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxge/cfx_fontmgr.h"
8
9 #include <array>
10 #include <iterator>
11 #include <memory>
12 #include <utility>
13
14 #include "core/fxcrt/check_op.h"
15 #include "core/fxcrt/fixed_size_data_vector.h"
16 #include "core/fxge/cfx_fontmapper.h"
17 #include "core/fxge/cfx_substfont.h"
18 #include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
19 #include "core/fxge/fx_font.h"
20 #include "core/fxge/systemfontinfo_iface.h"
21
22 namespace {
23
24 constexpr std::array<pdfium::span<const uint8_t>,
25 CFX_FontMapper::kNumStandardFonts>
26 kFoxitFonts = {{
27 kFoxitFixedFontData,
28 kFoxitFixedBoldFontData,
29 kFoxitFixedBoldItalicFontData,
30 kFoxitFixedItalicFontData,
31 kFoxitSansFontData,
32 kFoxitSansBoldFontData,
33 kFoxitSansBoldItalicFontData,
34 kFoxitSansItalicFontData,
35 kFoxitSerifFontData,
36 kFoxitSerifBoldFontData,
37 kFoxitSerifBoldItalicFontData,
38 kFoxitSerifItalicFontData,
39 kFoxitSymbolFontData,
40 kFoxitDingbatsFontData,
41 }};
42
43 constexpr pdfium::span<const uint8_t> kGenericSansFont = kFoxitSansMMFontData;
44 constexpr pdfium::span<const uint8_t> kGenericSerifFont = kFoxitSerifMMFontData;
45
FTLibraryInitHelper()46 FXFT_LibraryRec* FTLibraryInitHelper() {
47 FXFT_LibraryRec* pLibrary = nullptr;
48 FT_Init_FreeType(&pLibrary);
49 return pLibrary;
50 }
51
52 } // namespace
53
FontDesc(FixedSizeDataVector<uint8_t> data)54 CFX_FontMgr::FontDesc::FontDesc(FixedSizeDataVector<uint8_t> data)
55 : m_pFontData(std::move(data)) {}
56
57 CFX_FontMgr::FontDesc::~FontDesc() = default;
58
SetFace(size_t index,CFX_Face * face)59 void CFX_FontMgr::FontDesc::SetFace(size_t index, CFX_Face* face) {
60 CHECK_LT(index, std::size(m_TTCFaces));
61 m_TTCFaces[index].Reset(face);
62 }
63
GetFace(size_t index) const64 CFX_Face* CFX_FontMgr::FontDesc::GetFace(size_t index) const {
65 CHECK_LT(index, std::size(m_TTCFaces));
66 return m_TTCFaces[index].Get();
67 }
68
CFX_FontMgr()69 CFX_FontMgr::CFX_FontMgr()
70 : m_FTLibrary(FTLibraryInitHelper()),
71 m_pBuiltinMapper(std::make_unique<CFX_FontMapper>(this)),
72 m_FTLibrarySupportsHinting(SetLcdFilterMode() ||
73 FreeTypeVersionSupportsHinting()) {}
74
75 CFX_FontMgr::~CFX_FontMgr() = default;
76
GetCachedFontDesc(const ByteString & face_name,int weight,bool bItalic)77 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedFontDesc(
78 const ByteString& face_name,
79 int weight,
80 bool bItalic) {
81 auto it = m_FaceMap.find({face_name, weight, bItalic});
82 return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
83 }
84
AddCachedFontDesc(const ByteString & face_name,int weight,bool bItalic,FixedSizeDataVector<uint8_t> data)85 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedFontDesc(
86 const ByteString& face_name,
87 int weight,
88 bool bItalic,
89 FixedSizeDataVector<uint8_t> data) {
90 auto pFontDesc = pdfium::MakeRetain<FontDesc>(std::move(data));
91 m_FaceMap[{face_name, weight, bItalic}].Reset(pFontDesc.Get());
92 return pFontDesc;
93 }
94
GetCachedTTCFontDesc(size_t ttc_size,uint32_t checksum)95 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedTTCFontDesc(
96 size_t ttc_size,
97 uint32_t checksum) {
98 auto it = m_TTCFaceMap.find({ttc_size, checksum});
99 return it != m_TTCFaceMap.end() ? pdfium::WrapRetain(it->second.Get())
100 : nullptr;
101 }
102
AddCachedTTCFontDesc(size_t ttc_size,uint32_t checksum,FixedSizeDataVector<uint8_t> data)103 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedTTCFontDesc(
104 size_t ttc_size,
105 uint32_t checksum,
106 FixedSizeDataVector<uint8_t> data) {
107 auto pNewDesc = pdfium::MakeRetain<FontDesc>(std::move(data));
108 m_TTCFaceMap[{ttc_size, checksum}].Reset(pNewDesc.Get());
109 return pNewDesc;
110 }
111
NewFixedFace(RetainPtr<FontDesc> pDesc,pdfium::span<const uint8_t> span,size_t face_index)112 RetainPtr<CFX_Face> CFX_FontMgr::NewFixedFace(RetainPtr<FontDesc> pDesc,
113 pdfium::span<const uint8_t> span,
114 size_t face_index) {
115 RetainPtr<CFX_Face> face =
116 CFX_Face::New(m_FTLibrary.get(), std::move(pDesc), span,
117 static_cast<FT_Long>(face_index));
118 if (!face || !face->SetPixelSize(64, 64)) {
119 return nullptr;
120 }
121
122 return face;
123 }
124
125 // static
GetStandardFont(size_t index)126 pdfium::span<const uint8_t> CFX_FontMgr::GetStandardFont(size_t index) {
127 return kFoxitFonts[index];
128 }
129
130 // static
GetGenericSansFont()131 pdfium::span<const uint8_t> CFX_FontMgr::GetGenericSansFont() {
132 return kGenericSansFont;
133 }
134
135 // static
GetGenericSerifFont()136 pdfium::span<const uint8_t> CFX_FontMgr::GetGenericSerifFont() {
137 return kGenericSerifFont;
138 }
139
FreeTypeVersionSupportsHinting() const140 bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
141 FT_Int major;
142 FT_Int minor;
143 FT_Int patch;
144 FT_Library_Version(m_FTLibrary.get(), &major, &minor, &patch);
145 // Freetype versions >= 2.8.1 support hinting even if subpixel rendering is
146 // disabled. https://sourceforge.net/projects/freetype/files/freetype2/2.8.1/
147 return major > 2 || (major == 2 && minor > 8) ||
148 (major == 2 && minor == 8 && patch >= 1);
149 }
150
SetLcdFilterMode() const151 bool CFX_FontMgr::SetLcdFilterMode() const {
152 return FT_Library_SetLcdFilter(m_FTLibrary.get(), FT_LCD_FILTER_DEFAULT) !=
153 FT_Err_Unimplemented_Feature;
154 }
155