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