blob: 0b91df87cdd70b06ce13968ee8bbe27e6a330ebe [file] [log] [blame]
John Abd-El-Malek5110c472014-05-17 22:33:34 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek5110c472014-05-17 22:33:34 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_sysfontinfo.h"
8
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05009#include <memory>
10
Dan Sinclairf51a02a2017-04-19 12:46:53 -040011#include "core/fxcrt/fx_codepage.h"
Artem Strygin656eb842018-05-31 14:08:11 +000012#include "core/fxge/cfx_font.h"
dsinclair74a34fc2016-09-29 16:41:42 -070013#include "core/fxge/cfx_fontmapper.h"
Lei Zhang96d6b4d2018-01-11 14:31:41 +000014#include "core/fxge/cfx_fontmgr.h"
dsinclair74a34fc2016-09-29 16:41:42 -070015#include "core/fxge/cfx_gemodule.h"
16#include "core/fxge/fx_font.h"
Dan Sinclairf8af5652018-03-06 18:56:33 +000017#include "core/fxge/systemfontinfo_iface.h"
Dan Sinclair00d47a62018-03-28 18:39:04 +000018#include "fpdfsdk/cpdfsdk_helpers.h"
Dan Sinclairc411eb92017-07-25 09:39:30 -040019#include "fpdfsdk/pwl/cpwl_font_map.h"
Tom Sepezfe91c6c2017-05-16 15:33:20 -070020#include "third_party/base/ptr_util.h"
John Abd-El-Malek5110c472014-05-17 22:33:34 -070021
Dan Sinclairf51a02a2017-04-19 12:46:53 -040022static_assert(FXFONT_ANSI_CHARSET == FX_CHARSET_ANSI, "Charset must match");
23static_assert(FXFONT_DEFAULT_CHARSET == FX_CHARSET_Default,
24 "Charset must match");
25static_assert(FXFONT_SYMBOL_CHARSET == FX_CHARSET_Symbol, "Charset must match");
26static_assert(FXFONT_SHIFTJIS_CHARSET == FX_CHARSET_ShiftJIS,
27 "Charset must match");
28static_assert(FXFONT_HANGEUL_CHARSET == FX_CHARSET_Hangul,
29 "Charset must match");
30static_assert(FXFONT_GB2312_CHARSET == FX_CHARSET_ChineseSimplified,
31 "Charset must match");
32static_assert(FXFONT_CHINESEBIG5_CHARSET == FX_CHARSET_ChineseTraditional,
33 "Charset must match");
Artem Strygin656eb842018-05-31 14:08:11 +000034static_assert(sizeof(CFX_Font::CharsetFontMap) == sizeof(FPDF_CharsetFontMap),
35 "CFX_Font::CharsetFontMap should be same as FPDF_CharsetFontMap");
Dan Sinclairf51a02a2017-04-19 12:46:53 -040036
Dan Sinclairf8af5652018-03-06 18:56:33 +000037class CFX_ExternalFontInfo final : public SystemFontInfoIface {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070038 public:
Lei Zhang2b1a2d52015-08-14 22:16:22 -070039 explicit CFX_ExternalFontInfo(FPDF_SYSFONTINFO* pInfo) : m_pInfo(pInfo) {}
thestig24508df2016-05-27 15:14:20 -070040 ~CFX_ExternalFontInfo() override {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070041 if (m_pInfo->Release)
42 m_pInfo->Release(m_pInfo);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -070044
tsepez4cf55152016-11-02 14:37:54 -070045 bool EnumFontList(CFX_FontMapper* pMapper) override {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 if (m_pInfo->EnumFonts) {
47 m_pInfo->EnumFonts(m_pInfo, pMapper);
tsepez4cf55152016-11-02 14:37:54 -070048 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 }
tsepez4cf55152016-11-02 14:37:54 -070050 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -070052
Lei Zhang2b1a2d52015-08-14 22:16:22 -070053 void* MapFont(int weight,
tsepez4cf55152016-11-02 14:37:54 -070054 bool bItalic,
Lei Zhang2b1a2d52015-08-14 22:16:22 -070055 int charset,
56 int pitch_family,
Nicolas Pena979e9162017-11-07 16:32:20 +000057 const char* family) override {
thestig907a5222016-06-21 14:38:27 -070058 if (!m_pInfo->MapFont)
59 return nullptr;
Nicolas Pena979e9162017-11-07 16:32:20 +000060
61 int iExact;
thestig907a5222016-06-21 14:38:27 -070062 return m_pInfo->MapFont(m_pInfo, weight, bItalic, charset, pitch_family,
63 family, &iExact);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -070065
Dan Sinclair812e96c2017-03-13 16:43:37 -040066 void* GetFont(const char* family) override {
thestig907a5222016-06-21 14:38:27 -070067 if (!m_pInfo->GetFont)
68 return nullptr;
69 return m_pInfo->GetFont(m_pInfo, family);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -070071
tsepezc3255f52016-03-25 14:52:27 -070072 uint32_t GetFontData(void* hFont,
73 uint32_t table,
Lei Zhang2b1a2d52015-08-14 22:16:22 -070074 uint8_t* buffer,
tsepezc3255f52016-03-25 14:52:27 -070075 uint32_t size) override {
thestig907a5222016-06-21 14:38:27 -070076 if (!m_pInfo->GetFontData)
77 return 0;
78 return m_pInfo->GetFontData(m_pInfo, hFont, table, buffer, size);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -070080
Ryan Harrison275e2602017-09-18 14:23:18 -040081 bool GetFaceName(void* hFont, ByteString* name) override {
Lei Zhang412e9082015-12-14 18:34:00 -080082 if (!m_pInfo->GetFaceName)
tsepez4cf55152016-11-02 14:37:54 -070083 return false;
thestig1cd352e2016-06-07 17:53:06 -070084 uint32_t size = m_pInfo->GetFaceName(m_pInfo, hFont, nullptr, 0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 if (size == 0)
tsepez4cf55152016-11-02 14:37:54 -070086 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087 char* buffer = FX_Alloc(char, size);
88 size = m_pInfo->GetFaceName(m_pInfo, hFont, buffer, size);
Ryan Harrison275e2602017-09-18 14:23:18 -040089 *name = ByteString(buffer, size);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 FX_Free(buffer);
tsepez4cf55152016-11-02 14:37:54 -070091 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -070093
Tom Sepezec8ff7d2017-04-07 16:58:00 -070094 bool GetFontCharset(void* hFont, int* charset) override {
thestig907a5222016-06-21 14:38:27 -070095 if (!m_pInfo->GetFontCharset)
tsepez4cf55152016-11-02 14:37:54 -070096 return false;
thestig907a5222016-06-21 14:38:27 -070097
Tom Sepezec8ff7d2017-04-07 16:58:00 -070098 *charset = m_pInfo->GetFontCharset(m_pInfo, hFont);
tsepez4cf55152016-11-02 14:37:54 -070099 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100 }
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700101
Lei Zhang2b1a2d52015-08-14 22:16:22 -0700102 void DeleteFont(void* hFont) override {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103 if (m_pInfo->DeleteFont)
104 m_pInfo->DeleteFont(m_pInfo, hFont);
105 }
Tom Sepeze5b59ca2015-01-09 11:46:17 -0800106
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 private:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108 FPDF_SYSFONTINFO* const m_pInfo;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700109};
110
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400111FPDF_EXPORT void FPDF_CALLCONV FPDF_AddInstalledFont(void* mapper,
112 const char* name,
113 int charset) {
Nicolas Pena46abb662017-05-17 17:23:22 -0400114 CFX_FontMapper* pMapper = static_cast<CFX_FontMapper*>(mapper);
thestig907a5222016-06-21 14:38:27 -0700115 pMapper->AddInstalledFont(name, charset);
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700116}
117
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400118FPDF_EXPORT void FPDF_CALLCONV
119FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* pFontInfoExt) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 if (pFontInfoExt->version != 1)
121 return;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700122
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 CFX_GEModule::Get()->GetFontMgr()->SetSystemFontInfo(
Tom Sepezfe91c6c2017-05-16 15:33:20 -0700124 pdfium::MakeUnique<CFX_ExternalFontInfo>(pFontInfoExt));
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700125}
126
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400127FPDF_EXPORT const FPDF_CharsetFontMap* FPDF_CALLCONV FPDF_GetDefaultTTFMap() {
Artem Strygin656eb842018-05-31 14:08:11 +0000128 return reinterpret_cast<const FPDF_CharsetFontMap*>(CFX_Font::defaultTTFMap);
Tom Sepez2a0bb3b2015-05-12 12:37:14 -0700129}
130
Tom Sepez55865452018-08-27 20:18:04 +0000131struct FPDF_SYSFONTINFO_DEFAULT final : public FPDF_SYSFONTINFO {
Dan Sinclairf8af5652018-03-06 18:56:33 +0000132 UnownedPtr<SystemFontInfoIface> m_pFontInfo;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700133};
134
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135static void DefaultRelease(struct _FPDF_SYSFONTINFO* pThis) {
thestig24508df2016-05-27 15:14:20 -0700136 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
Tom Sepezd0409af2017-05-25 15:53:57 -0700137 delete pDefault->m_pFontInfo.Release();
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700138}
139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140static void DefaultEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper) {
thestig907a5222016-06-21 14:38:27 -0700141 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
Tom Sepezea3a2522018-04-26 18:33:58 +0000142 pDefault->m_pFontInfo->EnumFontList(static_cast<CFX_FontMapper*>(pMapper));
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700143}
144
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145static void* DefaultMapFont(struct _FPDF_SYSFONTINFO* pThis,
146 int weight,
147 int bItalic,
148 int charset,
149 int pitch_family,
150 const char* family,
151 int* bExact) {
thestig907a5222016-06-21 14:38:27 -0700152 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
tsepez95e58342016-10-28 11:34:42 -0700153 return pDefault->m_pFontInfo->MapFont(weight, !!bItalic, charset,
Nicolas Pena979e9162017-11-07 16:32:20 +0000154 pitch_family, family);
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700155}
156
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157void* DefaultGetFont(struct _FPDF_SYSFONTINFO* pThis, const char* family) {
thestig907a5222016-06-21 14:38:27 -0700158 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
159 return pDefault->m_pFontInfo->GetFont(family);
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700160}
161
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162static unsigned long DefaultGetFontData(struct _FPDF_SYSFONTINFO* pThis,
163 void* hFont,
164 unsigned int table,
165 unsigned char* buffer,
166 unsigned long buf_size) {
thestig907a5222016-06-21 14:38:27 -0700167 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
168 return pDefault->m_pFontInfo->GetFontData(hFont, table, buffer, buf_size);
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700169}
170
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171static unsigned long DefaultGetFaceName(struct _FPDF_SYSFONTINFO* pThis,
172 void* hFont,
173 char* buffer,
174 unsigned long buf_size) {
Ryan Harrison275e2602017-09-18 14:23:18 -0400175 ByteString name;
thestig907a5222016-06-21 14:38:27 -0700176 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
Tom Sepezec8ff7d2017-04-07 16:58:00 -0700177 if (!pDefault->m_pFontInfo->GetFaceName(hFont, &name))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 return 0;
Ryan Harrison875e98c2017-09-27 10:53:11 -0400179 if (name.GetLength() >= static_cast<size_t>(buf_size))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 return name.GetLength() + 1;
Dan Sinclair7e7c6492017-04-03 14:50:05 -0400181
182 strncpy(buffer, name.c_str(),
Ryan Harrison275e2602017-09-18 14:23:18 -0400183 (name.GetLength() + 1) * sizeof(ByteString::CharType));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 return name.GetLength() + 1;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700185}
186
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187static int DefaultGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
188 int charset;
thestig907a5222016-06-21 14:38:27 -0700189 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
Tom Sepezec8ff7d2017-04-07 16:58:00 -0700190 if (!pDefault->m_pFontInfo->GetFontCharset(hFont, &charset))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 return 0;
192 return charset;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700193}
194
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195static void DefaultDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont) {
thestig907a5222016-06-21 14:38:27 -0700196 auto* pDefault = static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pThis);
197 pDefault->m_pFontInfo->DeleteFont(hFont);
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700198}
199
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400200FPDF_EXPORT FPDF_SYSFONTINFO* FPDF_CALLCONV FPDF_GetDefaultSystemFontInfo() {
Dan Sinclairf8af5652018-03-06 18:56:33 +0000201 std::unique_ptr<SystemFontInfoIface> pFontInfo =
202 SystemFontInfoIface::CreateDefault(nullptr);
Lei Zhang412e9082015-12-14 18:34:00 -0800203 if (!pFontInfo)
thestig24508df2016-05-27 15:14:20 -0700204 return nullptr;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700205
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 FPDF_SYSFONTINFO_DEFAULT* pFontInfoExt =
207 FX_Alloc(FPDF_SYSFONTINFO_DEFAULT, 1);
208 pFontInfoExt->DeleteFont = DefaultDeleteFont;
209 pFontInfoExt->EnumFonts = DefaultEnumFonts;
210 pFontInfoExt->GetFaceName = DefaultGetFaceName;
211 pFontInfoExt->GetFont = DefaultGetFont;
212 pFontInfoExt->GetFontCharset = DefaultGetFontCharset;
213 pFontInfoExt->GetFontData = DefaultGetFontData;
214 pFontInfoExt->MapFont = DefaultMapFont;
215 pFontInfoExt->Release = DefaultRelease;
216 pFontInfoExt->version = 1;
thestig24508df2016-05-27 15:14:20 -0700217 pFontInfoExt->m_pFontInfo = pFontInfo.release();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 return pFontInfoExt;
John Abd-El-Malek5110c472014-05-17 22:33:34 -0700219}
npm788217d2016-11-08 16:48:36 -0800220
Dan Sinclair00d2ad12017-08-10 14:13:02 -0400221FPDF_EXPORT void FPDF_CALLCONV
Dan Sinclair4bb4e842017-07-18 09:58:58 -0400222FPDF_FreeDefaultSystemFontInfo(FPDF_SYSFONTINFO* pDefaultFontInfo) {
npmbe6b1482016-11-10 10:12:30 -0800223 FX_Free(static_cast<FPDF_SYSFONTINFO_DEFAULT*>(pDefaultFontInfo));
npm788217d2016-11-08 16:48:36 -0800224}