• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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