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