1 // Copyright 2016 PDFium Authors. All rights reserved.
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 <memory>
10 #include <utility>
11 
12 #include "core/fxge/cfx_face.h"
13 #include "core/fxge/cfx_fontmapper.h"
14 #include "core/fxge/cfx_substfont.h"
15 #include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
16 #include "core/fxge/fx_font.h"
17 #include "core/fxge/systemfontinfo_iface.h"
18 #include "third_party/base/ptr_util.h"
19 
20 namespace {
21 
22 struct BuiltinFont {
23   const uint8_t* m_pFontData;  // Raw, POD struct.
24   uint32_t m_dwSize;
25 };
26 
27 const BuiltinFont g_FoxitFonts[14] = {
28     {g_FoxitFixedFontData, 17597},
29     {g_FoxitFixedBoldFontData, 18055},
30     {g_FoxitFixedBoldItalicFontData, 19151},
31     {g_FoxitFixedItalicFontData, 18746},
32     {g_FoxitSansFontData, 15025},
33     {g_FoxitSansBoldFontData, 16344},
34     {g_FoxitSansBoldItalicFontData, 16418},
35     {g_FoxitSansItalicFontData, 16339},
36     {g_FoxitSerifFontData, 19469},
37     {g_FoxitSerifBoldFontData, 19395},
38     {g_FoxitSerifBoldItalicFontData, 20733},
39     {g_FoxitSerifItalicFontData, 21227},
40     {g_FoxitSymbolFontData, 16729},
41     {g_FoxitDingbatsFontData, 29513},
42 };
43 
44 const BuiltinFont g_MMFonts[2] = {
45     {g_FoxitSerifMMFontData, 113417},
46     {g_FoxitSansMMFontData, 66919},
47 };
48 
KeyNameFromFace(const ByteString & face_name,int weight,bool bItalic)49 ByteString KeyNameFromFace(const ByteString& face_name,
50                            int weight,
51                            bool bItalic) {
52   ByteString key(face_name);
53   key += ',';
54   key += ByteString::FormatInteger(weight);
55   key += bItalic ? 'I' : 'N';
56   return key;
57 }
58 
KeyNameFromSize(int ttc_size,uint32_t checksum)59 ByteString KeyNameFromSize(int ttc_size, uint32_t checksum) {
60   return ByteString::Format("%d:%d", ttc_size, checksum);
61 }
62 
FTLibraryInitHelper()63 FXFT_LibraryRec* FTLibraryInitHelper() {
64   FXFT_LibraryRec* pLibrary = nullptr;
65   FT_Init_FreeType(&pLibrary);
66   return pLibrary;
67 }
68 
69 }  // namespace
70 
FontDesc(std::unique_ptr<uint8_t,FxFreeDeleter> pData,size_t size)71 CFX_FontMgr::FontDesc::FontDesc(std::unique_ptr<uint8_t, FxFreeDeleter> pData,
72                                 size_t size)
73     : m_Size(size), m_pFontData(std::move(pData)) {}
74 
75 CFX_FontMgr::FontDesc::~FontDesc() = default;
76 
SetFace(size_t index,CFX_Face * face)77 void CFX_FontMgr::FontDesc::SetFace(size_t index, CFX_Face* face) {
78   ASSERT(index < FX_ArraySize(m_TTCFaces));
79   m_TTCFaces[index].Reset(face);
80 }
81 
GetFace(size_t index) const82 CFX_Face* CFX_FontMgr::FontDesc::GetFace(size_t index) const {
83   ASSERT(index < FX_ArraySize(m_TTCFaces));
84   return m_TTCFaces[index].Get();
85 }
86 
CFX_FontMgr()87 CFX_FontMgr::CFX_FontMgr()
88     : m_FTLibrary(FTLibraryInitHelper()),
89       m_pBuiltinMapper(pdfium::MakeUnique<CFX_FontMapper>(this)),
90       m_FTLibrarySupportsHinting(SetLcdFilterMode() ||
91                                  FreeTypeVersionSupportsHinting()) {}
92 
93 CFX_FontMgr::~CFX_FontMgr() = default;
94 
SetSystemFontInfo(std::unique_ptr<SystemFontInfoIface> pFontInfo)95 void CFX_FontMgr::SetSystemFontInfo(
96     std::unique_ptr<SystemFontInfoIface> pFontInfo) {
97   m_pBuiltinMapper->SetSystemFontInfo(std::move(pFontInfo));
98 }
99 
FindSubstFont(const ByteString & face_name,bool bTrueType,uint32_t flags,int weight,int italic_angle,int CharsetCP,CFX_SubstFont * pSubstFont)100 RetainPtr<CFX_Face> CFX_FontMgr::FindSubstFont(const ByteString& face_name,
101                                                bool bTrueType,
102                                                uint32_t flags,
103                                                int weight,
104                                                int italic_angle,
105                                                int CharsetCP,
106                                                CFX_SubstFont* pSubstFont) {
107   return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
108                                          italic_angle, CharsetCP, pSubstFont);
109 }
110 
GetCachedFontDesc(const ByteString & face_name,int weight,bool bItalic)111 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedFontDesc(
112     const ByteString& face_name,
113     int weight,
114     bool bItalic) {
115   auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
116   return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
117 }
118 
AddCachedFontDesc(const ByteString & face_name,int weight,bool bItalic,std::unique_ptr<uint8_t,FxFreeDeleter> pData,uint32_t size)119 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedFontDesc(
120     const ByteString& face_name,
121     int weight,
122     bool bItalic,
123     std::unique_ptr<uint8_t, FxFreeDeleter> pData,
124     uint32_t size) {
125   auto pFontDesc = pdfium::MakeRetain<FontDesc>(std::move(pData), size);
126   m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)].Reset(pFontDesc.Get());
127   return pFontDesc;
128 }
129 
GetCachedTTCFontDesc(int ttc_size,uint32_t checksum)130 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::GetCachedTTCFontDesc(
131     int ttc_size,
132     uint32_t checksum) {
133   auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
134   return it != m_FaceMap.end() ? pdfium::WrapRetain(it->second.Get()) : nullptr;
135 }
136 
AddCachedTTCFontDesc(int ttc_size,uint32_t checksum,std::unique_ptr<uint8_t,FxFreeDeleter> pData,uint32_t size)137 RetainPtr<CFX_FontMgr::FontDesc> CFX_FontMgr::AddCachedTTCFontDesc(
138     int ttc_size,
139     uint32_t checksum,
140     std::unique_ptr<uint8_t, FxFreeDeleter> pData,
141     uint32_t size) {
142   auto pNewDesc = pdfium::MakeRetain<FontDesc>(std::move(pData), size);
143   m_FaceMap[KeyNameFromSize(ttc_size, checksum)].Reset(pNewDesc.Get());
144   return pNewDesc;
145 }
146 
NewFixedFace(const RetainPtr<FontDesc> & pDesc,pdfium::span<const uint8_t> span,int face_index)147 RetainPtr<CFX_Face> CFX_FontMgr::NewFixedFace(const RetainPtr<FontDesc>& pDesc,
148                                               pdfium::span<const uint8_t> span,
149                                               int face_index) {
150   RetainPtr<CFX_Face> face =
151       CFX_Face::New(m_FTLibrary.get(), pDesc, span, face_index);
152   if (!face)
153     return nullptr;
154 
155   if (FT_Set_Pixel_Sizes(face->GetRec(), 64, 64) != 0)
156     return nullptr;
157 
158   return face;
159 }
160 
161 // static
GetBuiltinFont(size_t index)162 Optional<pdfium::span<const uint8_t>> CFX_FontMgr::GetBuiltinFont(
163     size_t index) {
164   if (index < FX_ArraySize(g_FoxitFonts)) {
165     return pdfium::make_span(g_FoxitFonts[index].m_pFontData,
166                              g_FoxitFonts[index].m_dwSize);
167   }
168   size_t mm_index = index - FX_ArraySize(g_FoxitFonts);
169   if (mm_index < FX_ArraySize(g_MMFonts)) {
170     return pdfium::make_span(g_MMFonts[mm_index].m_pFontData,
171                              g_MMFonts[mm_index].m_dwSize);
172   }
173   return {};
174 }
175 
FreeTypeVersionSupportsHinting() const176 bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
177   FT_Int major;
178   FT_Int minor;
179   FT_Int patch;
180   FT_Library_Version(m_FTLibrary.get(), &major, &minor, &patch);
181   // Freetype versions >= 2.8.1 support hinting even if subpixel rendering is
182   // disabled. https://sourceforge.net/projects/freetype/files/freetype2/2.8.1/
183   return major > 2 || (major == 2 && minor > 8) ||
184          (major == 2 && minor == 8 && patch >= 1);
185 }
186 
SetLcdFilterMode() const187 bool CFX_FontMgr::SetLcdFilterMode() const {
188   return FT_Library_SetLcdFilter(m_FTLibrary.get(), FT_LCD_FILTER_DEFAULT) !=
189          FT_Err_Unimplemented_Feature;
190 }
191