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 <memory>
10
11#include "core/fxge/cfx_fontmapper.h"
12#include "core/fxge/cfx_gemodule.h"
13#include "core/fxge/fx_font.h"
14#include "core/fxge/ifx_systemfontinfo.h"
15#include "fpdfsdk/fsdk_define.h"
16#include "fpdfsdk/pdfwindow/PWL_FontMap.h"
17
18class CFX_ExternalFontInfo final : public IFX_SystemFontInfo {
19 public:
20  explicit CFX_ExternalFontInfo(FPDF_SYSFONTINFO* pInfo) : m_pInfo(pInfo) {}
21  ~CFX_ExternalFontInfo() override {
22    if (m_pInfo->Release)
23      m_pInfo->Release(m_pInfo);
24  }
25
26  bool EnumFontList(CFX_FontMapper* pMapper) override {
27    if (m_pInfo->EnumFonts) {
28      m_pInfo->EnumFonts(m_pInfo, pMapper);
29      return true;
30    }
31    return false;
32  }
33
34  void* MapFont(int weight,
35                bool bItalic,
36                int charset,
37                int pitch_family,
38                const FX_CHAR* family,
39                int& iExact) override {
40    if (!m_pInfo->MapFont)
41      return nullptr;
42    return m_pInfo->MapFont(m_pInfo, weight, bItalic, charset, pitch_family,
43                            family, &iExact);
44  }
45
46  void* GetFont(const FX_CHAR* family) override {
47    if (!m_pInfo->GetFont)
48      return nullptr;
49    return m_pInfo->GetFont(m_pInfo, family);
50  }
51
52  uint32_t GetFontData(void* hFont,
53                       uint32_t table,
54                       uint8_t* buffer,
55                       uint32_t size) override {
56    if (!m_pInfo->GetFontData)
57      return 0;
58    return m_pInfo->GetFontData(m_pInfo, hFont, table, buffer, size);
59  }
60
61  bool GetFaceName(void* hFont, CFX_ByteString& name) override {
62    if (!m_pInfo->GetFaceName)
63      return false;
64    uint32_t size = m_pInfo->GetFaceName(m_pInfo, hFont, nullptr, 0);
65    if (size == 0)
66      return false;
67    char* buffer = FX_Alloc(char, size);
68    size = m_pInfo->GetFaceName(m_pInfo, hFont, buffer, size);
69    name = CFX_ByteString(buffer, size);
70    FX_Free(buffer);
71    return true;
72  }
73
74  bool GetFontCharset(void* hFont, int& charset) override {
75    if (!m_pInfo->GetFontCharset)
76      return false;
77
78    charset = m_pInfo->GetFontCharset(m_pInfo, hFont);
79    return true;
80  }
81
82  void DeleteFont(void* hFont) override {
83    if (m_pInfo->DeleteFont)
84      m_pInfo->DeleteFont(m_pInfo, hFont);
85  }
86
87 private:
88  FPDF_SYSFONTINFO* const m_pInfo;
89};
90
91DLLEXPORT void STDCALL FPDF_AddInstalledFont(void* mapper,
92                                             const char* name,
93                                             int charset) {
94  CFX_FontMapper* pMapper = reinterpret_cast<CFX_FontMapper*>(mapper);
95  pMapper->AddInstalledFont(name, charset);
96}
97
98DLLEXPORT void STDCALL FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* pFontInfoExt) {
99  if (pFontInfoExt->version != 1)
100    return;
101
102  CFX_GEModule::Get()->GetFontMgr()->SetSystemFontInfo(
103      std::unique_ptr<IFX_SystemFontInfo>(
104          new CFX_ExternalFontInfo(pFontInfoExt)));
105}
106
107DLLEXPORT const FPDF_CharsetFontMap* STDCALL FPDF_GetDefaultTTFMap() {
108  return CPWL_FontMap::defaultTTFMap;
109}
110
111struct FPDF_SYSFONTINFO_DEFAULT : public FPDF_SYSFONTINFO {
112  IFX_SystemFontInfo* m_pFontInfo;
113};
114
115static void DefaultRelease(struct _FPDF_SYSFONTINFO* pThis) {
116  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
117  // TODO(thestig): Should this be set to nullptr too?
118  delete pDefault->m_pFontInfo;
119}
120
121static void DefaultEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper) {
122  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
123  pDefault->m_pFontInfo->EnumFontList((CFX_FontMapper*)pMapper);
124}
125
126static void* DefaultMapFont(struct _FPDF_SYSFONTINFO* pThis,
127                            int weight,
128                            int bItalic,
129                            int charset,
130                            int pitch_family,
131                            const char* family,
132                            int* bExact) {
133  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
134  return pDefault->m_pFontInfo->MapFont(weight, !!bItalic, charset,
135                                        pitch_family, family, *bExact);
136}
137
138void* DefaultGetFont(struct _FPDF_SYSFONTINFO* pThis, const char* family) {
139  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
140  return pDefault->m_pFontInfo->GetFont(family);
141}
142
143static unsigned long DefaultGetFontData(struct _FPDF_SYSFONTINFO* pThis,
144                                        void* hFont,
145                                        unsigned int table,
146                                        unsigned char* buffer,
147                                        unsigned long buf_size) {
148  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
149  return pDefault->m_pFontInfo->GetFontData(hFont, table, buffer, buf_size);
150}
151
152static unsigned long DefaultGetFaceName(struct _FPDF_SYSFONTINFO* pThis,
153                                        void* hFont,
154                                        char* buffer,
155                                        unsigned long buf_size) {
156  CFX_ByteString name;
157  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
158  if (!pDefault->m_pFontInfo->GetFaceName(hFont, name))
159    return 0;
160  if (name.GetLength() >= (long)buf_size)
161    return name.GetLength() + 1;
162  FXSYS_strcpy(buffer, name.c_str());
163  return name.GetLength() + 1;
164}
165
166static int DefaultGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
167  int charset;
168  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
169  if (!pDefault->m_pFontInfo->GetFontCharset(hFont, charset))
170    return 0;
171  return charset;
172}
173
174static void DefaultDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
175  auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
176  pDefault->m_pFontInfo->DeleteFont(hFont);
177}
178
179DLLEXPORT FPDF_SYSFONTINFO* STDCALL FPDF_GetDefaultSystemFontInfo() {
180  std::unique_ptr<IFX_SystemFontInfo> pFontInfo =
181      IFX_SystemFontInfo::CreateDefault(nullptr);
182  if (!pFontInfo)
183    return nullptr;
184
185  FPDF_SYSFONTINFO_DEFAULT* pFontInfoExt =
186      FX_Alloc(FPDF_SYSFONTINFO_DEFAULT, 1);
187  pFontInfoExt->DeleteFont = DefaultDeleteFont;
188  pFontInfoExt->EnumFonts = DefaultEnumFonts;
189  pFontInfoExt->GetFaceName = DefaultGetFaceName;
190  pFontInfoExt->GetFont = DefaultGetFont;
191  pFontInfoExt->GetFontCharset = DefaultGetFontCharset;
192  pFontInfoExt->GetFontData = DefaultGetFontData;
193  pFontInfoExt->MapFont = DefaultMapFont;
194  pFontInfoExt->Release = DefaultRelease;
195  pFontInfoExt->version = 1;
196  pFontInfoExt->m_pFontInfo = pFontInfo.release();
197  return pFontInfoExt;
198}
199
200DLLEXPORT void FPDF_FreeDefaultSystemFontInfo(
201    FPDF_SYSFONTINFO* pDefaultFontInfo) {
202  FX_Free(static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pDefaultFontInfo));
203}
204