xref: /aosp_15_r20/external/pdfium/fpdfsdk/fpdf_sysfontinfo.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2014 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 "public/fpdf_sysfontinfo.h"
8 
9 #include <stddef.h>
10 
11 #include <memory>
12 
13 #include "core/fxcrt/fx_codepage.h"
14 #include "core/fxcrt/stl_util.h"
15 #include "core/fxcrt/unowned_ptr.h"
16 #include "core/fxge/cfx_font.h"
17 #include "core/fxge/cfx_fontmapper.h"
18 #include "core/fxge/cfx_fontmgr.h"
19 #include "core/fxge/cfx_gemodule.h"
20 #include "core/fxge/fx_font.h"
21 #include "core/fxge/systemfontinfo_iface.h"
22 #include "third_party/base/numerics/safe_conversions.h"
23 
24 #ifdef PDF_ENABLE_XFA
25 #include "xfa/fgas/font/cfgas_fontmgr.h"
26 #include "xfa/fgas/font/cfgas_gemodule.h"
27 #endif
28 
29 static_assert(FXFONT_ANSI_CHARSET == static_cast<int>(FX_Charset::kANSI),
30               "Charset must match");
31 static_assert(FXFONT_DEFAULT_CHARSET == static_cast<int>(FX_Charset::kDefault),
32               "Charset must match");
33 static_assert(FXFONT_SYMBOL_CHARSET == static_cast<int>(FX_Charset::kSymbol),
34               "Charset must match");
35 static_assert(FXFONT_SHIFTJIS_CHARSET ==
36                   static_cast<int>(FX_Charset::kShiftJIS),
37               "Charset must match");
38 static_assert(FXFONT_HANGEUL_CHARSET == static_cast<int>(FX_Charset::kHangul),
39               "Charset must match");
40 static_assert(FXFONT_GB2312_CHARSET ==
41                   static_cast<int>(FX_Charset::kChineseSimplified),
42               "Charset must match");
43 static_assert(FXFONT_CHINESEBIG5_CHARSET ==
44                   static_cast<int>(FX_Charset::kChineseTraditional),
45               "Charset must match");
46 static_assert(FXFONT_GREEK_CHARSET ==
47                   static_cast<int>(FX_Charset::kMSWin_Greek),
48               "Charset must match");
49 static_assert(FXFONT_VIETNAMESE_CHARSET ==
50                   static_cast<int>(FX_Charset::kMSWin_Vietnamese),
51               "Charset must match");
52 static_assert(FXFONT_HEBREW_CHARSET ==
53                   static_cast<int>(FX_Charset::kMSWin_Hebrew),
54               "Charset must match");
55 static_assert(FXFONT_ARABIC_CHARSET ==
56                   static_cast<int>(FX_Charset::kMSWin_Arabic),
57               "Charset must match");
58 static_assert(FXFONT_CYRILLIC_CHARSET ==
59                   static_cast<int>(FX_Charset::kMSWin_Cyrillic),
60               "Charset must match");
61 static_assert(FXFONT_THAI_CHARSET == static_cast<int>(FX_Charset::kThai),
62               "Charset must match");
63 static_assert(FXFONT_EASTERNEUROPEAN_CHARSET ==
64                   static_cast<int>(FX_Charset::kMSWin_EasternEuropean),
65               "Charset must match");
66 static_assert(offsetof(CFX_Font::CharsetFontMap, charset) ==
67                   offsetof(FPDF_CharsetFontMap, charset),
68               "CFX_Font::CharsetFontMap must be same as FPDF_CharsetFontMap");
69 static_assert(offsetof(CFX_Font::CharsetFontMap, fontname) ==
70                   offsetof(FPDF_CharsetFontMap, fontname),
71               "CFX_Font::CharsetFontMap must be same as FPDF_CharsetFontMap");
72 static_assert(sizeof(CFX_Font::CharsetFontMap) == sizeof(FPDF_CharsetFontMap),
73               "CFX_Font::CharsetFontMap must be same as FPDF_CharsetFontMap");
74 
75 class CFX_ExternalFontInfo final : public SystemFontInfoIface {
76  public:
CFX_ExternalFontInfo(FPDF_SYSFONTINFO * pInfo)77   explicit CFX_ExternalFontInfo(FPDF_SYSFONTINFO* pInfo) : m_pInfo(pInfo) {}
~CFX_ExternalFontInfo()78   ~CFX_ExternalFontInfo() override {
79     if (m_pInfo->Release)
80       m_pInfo->Release(m_pInfo);
81   }
82 
EnumFontList(CFX_FontMapper * pMapper)83   bool EnumFontList(CFX_FontMapper* pMapper) override {
84     if (m_pInfo->EnumFonts) {
85       m_pInfo->EnumFonts(m_pInfo, pMapper);
86       return true;
87     }
88     return false;
89   }
90 
MapFont(int weight,bool bItalic,FX_Charset charset,int pitch_family,const ByteString & face)91   void* MapFont(int weight,
92                 bool bItalic,
93                 FX_Charset charset,
94                 int pitch_family,
95                 const ByteString& face) override {
96     if (!m_pInfo->MapFont)
97       return nullptr;
98 
99     int iExact;
100     return m_pInfo->MapFont(m_pInfo, weight, bItalic, static_cast<int>(charset),
101                             pitch_family, face.c_str(), &iExact);
102   }
103 
GetFont(const ByteString & family)104   void* GetFont(const ByteString& family) override {
105     if (!m_pInfo->GetFont)
106       return nullptr;
107     return m_pInfo->GetFont(m_pInfo, family.c_str());
108   }
109 
GetFontData(void * hFont,uint32_t table,pdfium::span<uint8_t> buffer)110   size_t GetFontData(void* hFont,
111                      uint32_t table,
112                      pdfium::span<uint8_t> buffer) override {
113     if (!m_pInfo->GetFontData)
114       return 0;
115     return m_pInfo->GetFontData(m_pInfo, hFont, table, buffer.data(),
116                                 fxcrt::CollectionSize<unsigned long>(buffer));
117   }
118 
GetFaceName(void * hFont,ByteString * name)119   bool GetFaceName(void* hFont, ByteString* name) override {
120     if (!m_pInfo->GetFaceName)
121       return false;
122     unsigned long size = m_pInfo->GetFaceName(m_pInfo, hFont, nullptr, 0);
123     if (size == 0)
124       return false;
125     char* buffer = FX_Alloc(char, size);
126     size = m_pInfo->GetFaceName(m_pInfo, hFont, buffer, size);
127     *name = ByteString(buffer, size);
128     FX_Free(buffer);
129     return true;
130   }
131 
GetFontCharset(void * hFont,FX_Charset * charset)132   bool GetFontCharset(void* hFont, FX_Charset* charset) override {
133     if (!m_pInfo->GetFontCharset)
134       return false;
135 
136     *charset = FX_GetCharsetFromInt(m_pInfo->GetFontCharset(m_pInfo, hFont));
137     return true;
138   }
139 
DeleteFont(void * hFont)140   void DeleteFont(void* hFont) override {
141     if (m_pInfo->DeleteFont)
142       m_pInfo->DeleteFont(m_pInfo, hFont);
143   }
144 
145  private:
146   UnownedPtr<FPDF_SYSFONTINFO> const m_pInfo;
147 };
148 
FPDF_AddInstalledFont(void * mapper,const char * face,int charset)149 FPDF_EXPORT void FPDF_CALLCONV FPDF_AddInstalledFont(void* mapper,
150                                                      const char* face,
151                                                      int charset) {
152   CFX_FontMapper* pMapper = static_cast<CFX_FontMapper*>(mapper);
153   pMapper->AddInstalledFont(face, FX_GetCharsetFromInt(charset));
154 }
155 
156 FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO * pFontInfoExt)157 FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* pFontInfoExt) {
158   if (pFontInfoExt->version != 1)
159     return;
160 
161   CFX_GEModule::Get()->GetFontMgr()->GetBuiltinMapper()->SetSystemFontInfo(
162       std::make_unique<CFX_ExternalFontInfo>(pFontInfoExt));
163 
164 #ifdef PDF_ENABLE_XFA
165   CFGAS_GEModule::Get()->GetFontMgr()->EnumFonts();
166 #endif
167 }
168 
FPDF_GetDefaultTTFMap()169 FPDF_EXPORT const FPDF_CharsetFontMap* FPDF_CALLCONV FPDF_GetDefaultTTFMap() {
170   return reinterpret_cast<const FPDF_CharsetFontMap*>(CFX_Font::kDefaultTTFMap);
171 }
172 
173 struct FPDF_SYSFONTINFO_DEFAULT final : public FPDF_SYSFONTINFO {
174   UnownedPtr<SystemFontInfoIface> m_pFontInfo;
175 };
176 
DefaultRelease(struct _FPDF_SYSFONTINFO * pThis)177 static void DefaultRelease(struct _FPDF_SYSFONTINFO* pThis) {
178   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
179   delete pDefault->m_pFontInfo.ExtractAsDangling();
180 }
181 
DefaultEnumFonts(struct _FPDF_SYSFONTINFO * pThis,void * pMapper)182 static void DefaultEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper) {
183   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
184   pDefault->m_pFontInfo->EnumFontList(static_cast<CFX_FontMapper*>(pMapper));
185 }
186 
DefaultMapFont(struct _FPDF_SYSFONTINFO * pThis,int weight,int bItalic,int charset,int pitch_family,const char * family,int * bExact)187 static void* DefaultMapFont(struct _FPDF_SYSFONTINFO* pThis,
188                             int weight,
189                             int bItalic,
190                             int charset,
191                             int pitch_family,
192                             const char* family,
193                             int* bExact) {
194   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
195   return pDefault->m_pFontInfo->MapFont(
196       weight, !!bItalic, FX_GetCharsetFromInt(charset), pitch_family, family);
197 }
198 
DefaultGetFont(struct _FPDF_SYSFONTINFO * pThis,const char * family)199 void* DefaultGetFont(struct _FPDF_SYSFONTINFO* pThis, const char* family) {
200   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
201   return pDefault->m_pFontInfo->GetFont(family);
202 }
203 
DefaultGetFontData(struct _FPDF_SYSFONTINFO * pThis,void * hFont,unsigned int table,unsigned char * buffer,unsigned long buf_size)204 static unsigned long DefaultGetFontData(struct _FPDF_SYSFONTINFO* pThis,
205                                         void* hFont,
206                                         unsigned int table,
207                                         unsigned char* buffer,
208                                         unsigned long buf_size) {
209   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
210   return pdfium::base::checked_cast<unsigned long>(
211       pDefault->m_pFontInfo->GetFontData(hFont, table, {buffer, buf_size}));
212 }
213 
DefaultGetFaceName(struct _FPDF_SYSFONTINFO * pThis,void * hFont,char * buffer,unsigned long buf_size)214 static unsigned long DefaultGetFaceName(struct _FPDF_SYSFONTINFO* pThis,
215                                         void* hFont,
216                                         char* buffer,
217                                         unsigned long buf_size) {
218   ByteString name;
219   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
220   if (!pDefault->m_pFontInfo->GetFaceName(hFont, &name))
221     return 0;
222 
223   const unsigned long copy_length =
224       pdfium::base::checked_cast<unsigned long>(name.GetLength() + 1);
225   if (copy_length <= buf_size)
226     strncpy(buffer, name.c_str(), copy_length * sizeof(ByteString::CharType));
227 
228   return copy_length;
229 }
230 
DefaultGetFontCharset(struct _FPDF_SYSFONTINFO * pThis,void * hFont)231 static int DefaultGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
232   FX_Charset charset;
233   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
234   if (!pDefault->m_pFontInfo->GetFontCharset(hFont, &charset))
235     return 0;
236   return static_cast<int>(charset);
237 }
238 
DefaultDeleteFont(struct _FPDF_SYSFONTINFO * pThis,void * hFont)239 static void DefaultDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
240   auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
241   pDefault->m_pFontInfo->DeleteFont(hFont);
242 }
243 
FPDF_GetDefaultSystemFontInfo()244 FPDF_EXPORT FPDF_SYSFONTINFO* FPDF_CALLCONV FPDF_GetDefaultSystemFontInfo() {
245   std::unique_ptr<SystemFontInfoIface> pFontInfo =
246       CFX_GEModule::Get()->GetPlatform()->CreateDefaultSystemFontInfo();
247   if (!pFontInfo)
248     return nullptr;
249 
250   FPDF_SYSFONTINFO_DEFAULT* pFontInfoExt =
251       FX_Alloc(FPDF_SYSFONTINFO_DEFAULT, 1);
252   pFontInfoExt->DeleteFont = DefaultDeleteFont;
253   pFontInfoExt->EnumFonts = DefaultEnumFonts;
254   pFontInfoExt->GetFaceName = DefaultGetFaceName;
255   pFontInfoExt->GetFont = DefaultGetFont;
256   pFontInfoExt->GetFontCharset = DefaultGetFontCharset;
257   pFontInfoExt->GetFontData = DefaultGetFontData;
258   pFontInfoExt->MapFont = DefaultMapFont;
259   pFontInfoExt->Release = DefaultRelease;
260   pFontInfoExt->version = 1;
261   pFontInfoExt->m_pFontInfo = pFontInfo.release();
262   return pFontInfoExt;
263 }
264 
265 FPDF_EXPORT void FPDF_CALLCONV
FPDF_FreeDefaultSystemFontInfo(FPDF_SYSFONTINFO * pFontInfo)266 FPDF_FreeDefaultSystemFontInfo(FPDF_SYSFONTINFO* pFontInfo) {
267   FX_Free(static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pFontInfo));
268 }
269