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 <iterator>
10 #include <memory>
11 #include <utility>
12
13 #include "core/fxcrt/fixed_uninit_data_vector.h"
14 #include "core/fxge/cfx_fontmapper.h"
15 #include "core/fxge/cfx_substfont.h"
16 #include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
17 #include "core/fxge/fx_font.h"
18 #include "core/fxge/systemfontinfo_iface.h"
19 #include "third_party/base/check_op.h"
20
21 namespace {
22
23 struct BuiltinFont {
24 const uint8_t* m_pFontData; // Raw, POD struct.
25 uint32_t m_dwSize;
26 };
27
28 constexpr BuiltinFont kFoxitFonts[] = {
29 {kFoxitFixedFontData, 17597},
30 {kFoxitFixedBoldFontData, 18055},
31 {kFoxitFixedBoldItalicFontData, 19151},
32 {kFoxitFixedItalicFontData, 18746},
33 {kFoxitSansFontData, 15025},
34 {kFoxitSansBoldFontData, 16344},
35 {kFoxitSansBoldItalicFontData, 16418},
36 {kFoxitSansItalicFontData, 16339},
37 {kFoxitSerifFontData, 19469},
38 {kFoxitSerifBoldFontData, 19395},
39 {kFoxitSerifBoldItalicFontData, 20733},
40 {kFoxitSerifItalicFontData, 21227},
41 {kFoxitSymbolFontData, 16729},
42 {kFoxitDingbatsFontData, 29513},
43 };
44 static_assert(std::size(kFoxitFonts) == CFX_FontMapper::kNumStandardFonts,
45 "Wrong font count");
46
47 constexpr BuiltinFont kGenericSansFont = {kFoxitSansMMFontData, 66919};
48 constexpr BuiltinFont kGenericSerifFont = {kFoxitSerifMMFontData, 113417};
49
FTLibraryInitHelper()50 FXFT_LibraryRec* FTLibraryInitHelper() {
51 FXFT_LibraryRec* pLibrary = nullptr;
52 FT_Init_FreeType(&pLibrary);
53 return pLibrary;
54 }
55
56 } // namespace
57
FontDesc(FixedUninitDataVector<uint8_t> data)58 CFX_FontMgr::FontDesc::FontDesc(FixedUninitDataVector<uint8_t> data)
59 : m_pFontData(std::move(data)) {}
60
61 CFX_FontMgr::FontDesc::~FontDesc() = default;
62
SetFace(size_t index,CFX_Face * face)63 void CFX_FontMgr::FontDesc::SetFace(size_t index, CFX_Face* face) {
64 CHECK_LT(index, std::size(m_TTCFaces));
65 m_TTCFaces[index].Reset(face);
66 }
67
GetFace(size_t index) const68 CFX_Face* CFX_FontMgr::FontDesc::GetFace(size_t index) const {
69 CHECK_LT(index, std::size(m_TTCFaces));
70 return m_TTCFaces[index].Get();
71 }
72
CFX_FontMgr()73 CFX_FontMgr::CFX_FontMgr()
74 : m_FTLibrary(FTLibraryInitHelper()),
75 m_pBuiltinMapper(std::make_unique<CFX_FontMapper>(this)),
76 m_FTLibrarySupportsHinting(SetLcdFilterMode() ||
77 FreeTypeVersionSupportsHinting()) {}
78
79 CFX_FontMgr::~CFX_FontMgr() = default;
80
GetCachedFontDesc(const ByteString & face_name,int weight,bool bItalic)81 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedFontDesc(
82 const ByteString& face_name,
83 int weight,
84 bool bItalic) {
85 auto it = m_FaceMap.find({face_name, weight, bItalic});
86 return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
87 }
88
AddCachedFontDesc(const ByteString & face_name,int weight,bool bItalic,FixedUninitDataVector<uint8_t> data)89 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedFontDesc(
90 const ByteString& face_name,
91 int weight,
92 bool bItalic,
93 FixedUninitDataVector<uint8_t> data) {
94 auto pFontDesc = pdfium::MakeRetain<FontDesc>(std::move(data));
95 m_FaceMap[{face_name, weight, bItalic}].Reset(pFontDesc.Get());
96 return pFontDesc;
97 }
98
GetCachedTTCFontDesc(size_t ttc_size,uint32_t checksum)99 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedTTCFontDesc(
100 size_t ttc_size,
101 uint32_t checksum) {
102 auto it = m_TTCFaceMap.find({ttc_size, checksum});
103 return it != m_TTCFaceMap.end() ? pdfium::WrapRetain(it->second.Get())
104 : nullptr;
105 }
106
AddCachedTTCFontDesc(size_t ttc_size,uint32_t checksum,FixedUninitDataVector<uint8_t> data)107 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedTTCFontDesc(
108 size_t ttc_size,
109 uint32_t checksum,
110 FixedUninitDataVector<uint8_t> data) {
111 auto pNewDesc = pdfium::MakeRetain<FontDesc>(std::move(data));
112 m_TTCFaceMap[{ttc_size, checksum}].Reset(pNewDesc.Get());
113 return pNewDesc;
114 }
115
NewFixedFace(RetainPtr<FontDesc> pDesc,pdfium::span<const uint8_t> span,size_t face_index)116 RetainPtr<CFX_Face> CFX_FontMgr::NewFixedFace(RetainPtr<FontDesc> pDesc,
117 pdfium::span<const uint8_t> span,
118 size_t face_index) {
119 RetainPtr<CFX_Face> face =
120 CFX_Face::New(m_FTLibrary.get(), std::move(pDesc), span,
121 static_cast<FT_Long>(face_index));
122 if (!face)
123 return nullptr;
124
125 if (FT_Set_Pixel_Sizes(face->GetRec(), 64, 64) != 0)
126 return nullptr;
127
128 return face;
129 }
130
131 // static
GetStandardFont(size_t index)132 pdfium::span<const uint8_t> CFX_FontMgr::GetStandardFont(size_t index) {
133 CHECK_LT(index, std::size(kFoxitFonts));
134 return pdfium::make_span(kFoxitFonts[index].m_pFontData,
135 kFoxitFonts[index].m_dwSize);
136 }
137
138 // static
GetGenericSansFont()139 pdfium::span<const uint8_t> CFX_FontMgr::GetGenericSansFont() {
140 return pdfium::make_span(kGenericSansFont.m_pFontData,
141 kGenericSansFont.m_dwSize);
142 }
143
144 // static
GetGenericSerifFont()145 pdfium::span<const uint8_t> CFX_FontMgr::GetGenericSerifFont() {
146 return pdfium::make_span(kGenericSerifFont.m_pFontData,
147 kGenericSerifFont.m_dwSize);
148 }
149
FreeTypeVersionSupportsHinting() const150 bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
151 FT_Int major;
152 FT_Int minor;
153 FT_Int patch;
154 FT_Library_Version(m_FTLibrary.get(), &major, &minor, &patch);
155 // Freetype versions >= 2.8.1 support hinting even if subpixel rendering is
156 // disabled. https://sourceforge.net/projects/freetype/files/freetype2/2.8.1/
157 return major > 2 || (major == 2 && minor > 8) ||
158 (major == 2 && minor == 8 && patch >= 1);
159 }
160
SetLcdFilterMode() const161 bool CFX_FontMgr::SetLcdFilterMode() const {
162 return FT_Library_SetLcdFilter(m_FTLibrary.get(), FT_LCD_FILTER_DEFAULT) !=
163 FT_Err_Unimplemented_Feature;
164 }
165