Home | History | Annotate | Download | only in ge
      1 // Copyright 2016 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 "core/fxge/cfx_fontmgr.h"
      8 
      9 #include <memory>
     10 #include <utility>
     11 
     12 #include "core/fxge/cfx_fontmapper.h"
     13 #include "core/fxge/cfx_substfont.h"
     14 #include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
     15 #include "core/fxge/fx_font.h"
     16 #include "core/fxge/ge/cttfontdesc.h"
     17 #include "core/fxge/ifx_systemfontinfo.h"
     18 #include "third_party/base/ptr_util.h"
     19 
     20 namespace {
     21 
     22 struct BuiltinFont {
     23   const uint8_t* m_pFontData;
     24   uint32_t m_dwSize;
     25 };
     26 
     27 const BuiltinFont g_FoxitFonts[14] = {
     28     {g_FoxitFixedFontData, 17597},
     29     {g_FoxitFixedBoldFontData, 18055},
     30     {g_FoxitFixedBoldItalicFontData, 19151},
     31     {g_FoxitFixedItalicFontData, 18746},
     32     {g_FoxitSansFontData, 15025},
     33     {g_FoxitSansBoldFontData, 16344},
     34     {g_FoxitSansBoldItalicFontData, 16418},
     35     {g_FoxitSansItalicFontData, 16339},
     36     {g_FoxitSerifFontData, 19469},
     37     {g_FoxitSerifBoldFontData, 19395},
     38     {g_FoxitSerifBoldItalicFontData, 20733},
     39     {g_FoxitSerifItalicFontData, 21227},
     40     {g_FoxitSymbolFontData, 16729},
     41     {g_FoxitDingbatsFontData, 29513},
     42 };
     43 
     44 const BuiltinFont g_MMFonts[2] = {
     45     {g_FoxitSerifMMFontData, 113417},
     46     {g_FoxitSansMMFontData, 66919},
     47 };
     48 
     49 CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name,
     50                                int weight,
     51                                bool bItalic) {
     52   CFX_ByteString key(face_name);
     53   key += ',';
     54   key += CFX_ByteString::FormatInteger(weight);
     55   key += bItalic ? 'I' : 'N';
     56   return key;
     57 }
     58 
     59 CFX_ByteString KeyNameFromSize(int ttc_size, uint32_t checksum) {
     60   CFX_ByteString key;
     61   key.Format("%d:%d", ttc_size, checksum);
     62   return key;
     63 }
     64 
     65 int GetTTCIndex(const uint8_t* pFontData,
     66                 uint32_t ttc_size,
     67                 uint32_t font_offset) {
     68   int face_index = 0;
     69   const uint8_t* p = pFontData + 8;
     70   uint32_t nfont = GET_TT_LONG(p);
     71   uint32_t index;
     72   for (index = 0; index < nfont; index++) {
     73     p = pFontData + 12 + index * 4;
     74     if (GET_TT_LONG(p) == font_offset)
     75       break;
     76   }
     77   if (index >= nfont)
     78     face_index = 0;
     79   else
     80     face_index = index;
     81   return face_index;
     82 }
     83 
     84 }  // namespace
     85 
     86 CFX_FontMgr::CFX_FontMgr()
     87     : m_FTLibrary(nullptr), m_FTLibrarySupportsHinting(false) {
     88   m_pBuiltinMapper = pdfium::MakeUnique<CFX_FontMapper>(this);
     89 }
     90 
     91 CFX_FontMgr::~CFX_FontMgr() {
     92   for (const auto& pair : m_FaceMap)
     93     delete pair.second;
     94 
     95   // |m_pBuiltinMapper| references |m_FTLibrary|, so it has to be destroyed
     96   // first.
     97   m_pBuiltinMapper.reset();
     98   FXFT_Done_FreeType(m_FTLibrary);
     99 }
    100 
    101 void CFX_FontMgr::InitFTLibrary() {
    102   if (m_FTLibrary)
    103     return;
    104   FXFT_Init_FreeType(&m_FTLibrary);
    105   m_FTLibrarySupportsHinting =
    106       FXFT_Library_SetLcdFilter(m_FTLibrary, FT_LCD_FILTER_DEFAULT) !=
    107       FT_Err_Unimplemented_Feature;
    108 }
    109 
    110 void CFX_FontMgr::SetSystemFontInfo(
    111     std::unique_ptr<IFX_SystemFontInfo> pFontInfo) {
    112   m_pBuiltinMapper->SetSystemFontInfo(std::move(pFontInfo));
    113 }
    114 
    115 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name,
    116                                      bool bTrueType,
    117                                      uint32_t flags,
    118                                      int weight,
    119                                      int italic_angle,
    120                                      int CharsetCP,
    121                                      CFX_SubstFont* pSubstFont) {
    122   InitFTLibrary();
    123   return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
    124                                          italic_angle, CharsetCP, pSubstFont);
    125 }
    126 
    127 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name,
    128                                      int weight,
    129                                      bool bItalic,
    130                                      uint8_t*& pFontData) {
    131   auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
    132   if (it == m_FaceMap.end())
    133     return nullptr;
    134 
    135   CTTFontDesc* pFontDesc = it->second;
    136   pFontData = pFontDesc->m_pFontData;
    137   pFontDesc->m_RefCount++;
    138   return pFontDesc->m_SingleFace;
    139 }
    140 
    141 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
    142                                      int weight,
    143                                      bool bItalic,
    144                                      uint8_t* pData,
    145                                      uint32_t size,
    146                                      int face_index) {
    147   CTTFontDesc* pFontDesc = new CTTFontDesc;
    148   pFontDesc->m_Type = 1;
    149   pFontDesc->m_SingleFace = nullptr;
    150   pFontDesc->m_pFontData = pData;
    151   pFontDesc->m_RefCount = 1;
    152 
    153   InitFTLibrary();
    154   FXFT_Library library = m_FTLibrary;
    155   int ret = FXFT_New_Memory_Face(library, pData, size, face_index,
    156                                  &pFontDesc->m_SingleFace);
    157   if (ret) {
    158     delete pFontDesc;
    159     return nullptr;
    160   }
    161   ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace, 64, 64);
    162   if (ret) {
    163     delete pFontDesc;
    164     return nullptr;
    165   }
    166   m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc;
    167   return pFontDesc->m_SingleFace;
    168 }
    169 
    170 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size,
    171                                         uint32_t checksum,
    172                                         int font_offset,
    173                                         uint8_t*& pFontData) {
    174   auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
    175   if (it == m_FaceMap.end())
    176     return nullptr;
    177 
    178   CTTFontDesc* pFontDesc = it->second;
    179   pFontData = pFontDesc->m_pFontData;
    180   pFontDesc->m_RefCount++;
    181   int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
    182   if (!pFontDesc->m_TTCFaces[face_index]) {
    183     pFontDesc->m_TTCFaces[face_index] =
    184         GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
    185   }
    186   return pFontDesc->m_TTCFaces[face_index];
    187 }
    188 
    189 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
    190                                         uint32_t checksum,
    191                                         uint8_t* pData,
    192                                         uint32_t size,
    193                                         int font_offset) {
    194   CTTFontDesc* pFontDesc = new CTTFontDesc;
    195   pFontDesc->m_Type = 2;
    196   pFontDesc->m_pFontData = pData;
    197   for (int i = 0; i < 16; i++)
    198     pFontDesc->m_TTCFaces[i] = nullptr;
    199   pFontDesc->m_RefCount++;
    200   m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = pFontDesc;
    201   int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
    202   pFontDesc->m_TTCFaces[face_index] =
    203       GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
    204   return pFontDesc->m_TTCFaces[face_index];
    205 }
    206 
    207 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData,
    208                                     uint32_t size,
    209                                     int face_index) {
    210   InitFTLibrary();
    211   FXFT_Library library = m_FTLibrary;
    212   FXFT_Face face = nullptr;
    213   if (FXFT_New_Memory_Face(library, pData, size, face_index, &face))
    214     return nullptr;
    215   return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
    216 }
    217 
    218 FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) {
    219   InitFTLibrary();
    220   FXFT_Library library = m_FTLibrary;
    221   FXFT_Face face = nullptr;
    222   if (FXFT_New_Face(library, filename, face_index, &face))
    223     return nullptr;
    224   return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
    225 }
    226 
    227 void CFX_FontMgr::ReleaseFace(FXFT_Face face) {
    228   if (!face)
    229     return;
    230   bool bNeedFaceDone = true;
    231   auto it = m_FaceMap.begin();
    232   while (it != m_FaceMap.end()) {
    233     auto temp = it++;
    234     int nRet = temp->second->ReleaseFace(face);
    235     if (nRet == -1)
    236       continue;
    237     bNeedFaceDone = false;
    238     if (nRet == 0)
    239       m_FaceMap.erase(temp);
    240     break;
    241   }
    242   if (bNeedFaceDone && !m_pBuiltinMapper->IsBuiltinFace(face))
    243     FXFT_Done_Face(face);
    244 }
    245 
    246 bool CFX_FontMgr::GetBuiltinFont(size_t index,
    247                                  const uint8_t** pFontData,
    248                                  uint32_t* size) {
    249   if (index < FX_ArraySize(g_FoxitFonts)) {
    250     *pFontData = g_FoxitFonts[index].m_pFontData;
    251     *size = g_FoxitFonts[index].m_dwSize;
    252     return true;
    253   }
    254   index -= FX_ArraySize(g_FoxitFonts);
    255   if (index < FX_ArraySize(g_MMFonts)) {
    256     *pFontData = g_MMFonts[index].m_pFontData;
    257     *size = g_MMFonts[index].m_dwSize;
    258     return true;
    259   }
    260   return false;
    261 }
    262