• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/cttfontdesc.h"
15 #include "core/fxge/fontdata/chromefontdata/chromefontdata.h"
16 #include "core/fxge/fx_font.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 
KeyNameFromFace(const ByteString & face_name,int weight,bool bItalic)49 ByteString KeyNameFromFace(const ByteString& face_name,
50                            int weight,
51                            bool bItalic) {
52   ByteString key(face_name);
53   key += ',';
54   key += ByteString::FormatInteger(weight);
55   key += bItalic ? 'I' : 'N';
56   return key;
57 }
58 
KeyNameFromSize(int ttc_size,uint32_t checksum)59 ByteString KeyNameFromSize(int ttc_size, uint32_t checksum) {
60   return ByteString::Format("%d:%d", ttc_size, checksum);
61 }
62 
GetTTCIndex(const uint8_t * pFontData,uint32_t ttc_size,uint32_t font_offset)63 int GetTTCIndex(const uint8_t* pFontData,
64                 uint32_t ttc_size,
65                 uint32_t font_offset) {
66   const uint8_t* p = pFontData + 8;
67   uint32_t nfont = GET_TT_LONG(p);
68   uint32_t index;
69   for (index = 0; index < nfont; index++) {
70     p = pFontData + 12 + index * 4;
71     if (GET_TT_LONG(p) == font_offset)
72       break;
73   }
74   return index < nfont ? index : 0;
75 }
76 
77 }  // namespace
78 
CFX_FontMgr()79 CFX_FontMgr::CFX_FontMgr()
80     : m_FTLibrary(nullptr), m_FTLibrarySupportsHinting(false) {
81   m_pBuiltinMapper = pdfium::MakeUnique<CFX_FontMapper>(this);
82 }
83 
~CFX_FontMgr()84 CFX_FontMgr::~CFX_FontMgr() {
85   // |m_FaceMap| and |m_pBuiltinMapper| reference |m_FTLibrary|, so they must
86   // be destroyed first.
87   m_FaceMap.clear();
88   m_pBuiltinMapper.reset();
89   FXFT_Done_FreeType(m_FTLibrary);
90 }
91 
InitFTLibrary()92 void CFX_FontMgr::InitFTLibrary() {
93   if (m_FTLibrary)
94     return;
95 
96   FXFT_Init_FreeType(&m_FTLibrary);
97   m_FTLibrarySupportsHinting =
98       SetLcdFilterMode() || FreeTypeVersionSupportsHinting();
99 }
100 
SetSystemFontInfo(std::unique_ptr<IFX_SystemFontInfo> pFontInfo)101 void CFX_FontMgr::SetSystemFontInfo(
102     std::unique_ptr<IFX_SystemFontInfo> pFontInfo) {
103   m_pBuiltinMapper->SetSystemFontInfo(std::move(pFontInfo));
104 }
105 
FindSubstFont(const ByteString & face_name,bool bTrueType,uint32_t flags,int weight,int italic_angle,int CharsetCP,CFX_SubstFont * pSubstFont)106 FXFT_Face CFX_FontMgr::FindSubstFont(const ByteString& face_name,
107                                      bool bTrueType,
108                                      uint32_t flags,
109                                      int weight,
110                                      int italic_angle,
111                                      int CharsetCP,
112                                      CFX_SubstFont* pSubstFont) {
113   InitFTLibrary();
114   return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
115                                          italic_angle, CharsetCP, pSubstFont);
116 }
117 
GetCachedFace(const ByteString & face_name,int weight,bool bItalic,uint8_t ** pFontData)118 FXFT_Face CFX_FontMgr::GetCachedFace(const ByteString& face_name,
119                                      int weight,
120                                      bool bItalic,
121                                      uint8_t** pFontData) {
122   auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
123   if (it == m_FaceMap.end())
124     return nullptr;
125 
126   CTTFontDesc* pFontDesc = it->second.get();
127   *pFontData = pFontDesc->FontData();
128   pFontDesc->AddRef();
129   return pFontDesc->SingleFace();
130 }
131 
AddCachedFace(const ByteString & face_name,int weight,bool bItalic,uint8_t * pData,uint32_t size,int face_index)132 FXFT_Face CFX_FontMgr::AddCachedFace(const ByteString& face_name,
133                                      int weight,
134                                      bool bItalic,
135                                      uint8_t* pData,
136                                      uint32_t size,
137                                      int face_index) {
138   InitFTLibrary();
139 
140   FXFT_Face face = nullptr;
141   int ret = FXFT_New_Memory_Face(m_FTLibrary, pData, size, face_index, &face);
142   if (ret)
143     return nullptr;
144 
145   ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
146   if (ret)
147     return nullptr;
148 
149   auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(pData, face);
150   CTTFontDesc* pResult = pFontDesc.get();
151   m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = std::move(pFontDesc);
152   return pResult->SingleFace();
153 }
154 
GetCachedTTCFace(int ttc_size,uint32_t checksum,int font_offset,uint8_t ** pFontData)155 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size,
156                                         uint32_t checksum,
157                                         int font_offset,
158                                         uint8_t** pFontData) {
159   auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
160   if (it == m_FaceMap.end())
161     return nullptr;
162 
163   CTTFontDesc* pFontDesc = it->second.get();
164   *pFontData = pFontDesc->FontData();
165   int face_index = GetTTCIndex(pFontDesc->FontData(), ttc_size, font_offset);
166   if (!pFontDesc->TTCFace(face_index)) {
167     pFontDesc->SetTTCFace(
168         face_index, GetFixedFace(pFontDesc->FontData(), ttc_size, face_index));
169   }
170   pFontDesc->AddRef();
171   return pFontDesc->TTCFace(face_index);
172 }
173 
AddCachedTTCFace(int ttc_size,uint32_t checksum,uint8_t * pData,uint32_t size,int font_offset)174 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
175                                         uint32_t checksum,
176                                         uint8_t* pData,
177                                         uint32_t size,
178                                         int font_offset) {
179   int face_index = GetTTCIndex(pData, ttc_size, font_offset);
180   FXFT_Face face = GetFixedFace(pData, ttc_size, face_index);
181   auto pFontDesc = pdfium::MakeUnique<CTTFontDesc>(pData, face_index, face);
182   m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = std::move(pFontDesc);
183   return face;
184 }
185 
GetFixedFace(const uint8_t * pData,uint32_t size,int face_index)186 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData,
187                                     uint32_t size,
188                                     int face_index) {
189   InitFTLibrary();
190   FXFT_Face face = nullptr;
191   if (FXFT_New_Memory_Face(m_FTLibrary, pData, size, face_index, &face))
192     return nullptr;
193   return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
194 }
195 
GetFileFace(const char * filename,int face_index)196 FXFT_Face CFX_FontMgr::GetFileFace(const char* filename, int face_index) {
197   InitFTLibrary();
198   FXFT_Face face = nullptr;
199   if (FXFT_New_Face(m_FTLibrary, filename, face_index, &face))
200     return nullptr;
201   return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
202 }
203 
ReleaseFace(FXFT_Face face)204 void CFX_FontMgr::ReleaseFace(FXFT_Face face) {
205   if (!face)
206     return;
207   bool bNeedFaceDone = true;
208   for (auto it = m_FaceMap.begin(); it != m_FaceMap.end(); ++it) {
209     CTTFontDesc::ReleaseStatus nRet = it->second->ReleaseFace(face);
210     if (nRet == CTTFontDesc::kNotAppropriate)
211       continue;
212     bNeedFaceDone = false;
213     if (nRet == CTTFontDesc::kReleased)
214       m_FaceMap.erase(it);
215     break;
216   }
217   if (bNeedFaceDone && !m_pBuiltinMapper->IsBuiltinFace(face))
218     FXFT_Done_Face(face);
219 }
220 
GetBuiltinFont(size_t index,const uint8_t ** pFontData,uint32_t * size)221 bool CFX_FontMgr::GetBuiltinFont(size_t index,
222                                  const uint8_t** pFontData,
223                                  uint32_t* size) {
224   if (index < FX_ArraySize(g_FoxitFonts)) {
225     *pFontData = g_FoxitFonts[index].m_pFontData;
226     *size = g_FoxitFonts[index].m_dwSize;
227     return true;
228   }
229   size_t mm_index = index - FX_ArraySize(g_FoxitFonts);
230   if (mm_index < FX_ArraySize(g_MMFonts)) {
231     *pFontData = g_MMFonts[mm_index].m_pFontData;
232     *size = g_MMFonts[mm_index].m_dwSize;
233     return true;
234   }
235   return false;
236 }
237 
FreeTypeVersionSupportsHinting() const238 bool CFX_FontMgr::FreeTypeVersionSupportsHinting() const {
239   FT_Int major;
240   FT_Int minor;
241   FT_Int patch;
242   FXFT_Library_Version(m_FTLibrary, &major, &minor, &patch);
243   // Freetype versions >= 2.8.1 support hinting even if subpixel rendering is
244   // disabled. https://sourceforge.net/projects/freetype/files/freetype2/2.8.1/
245   return major > 2 || (major == 2 && minor > 8) ||
246          (major == 2 && minor == 8 && patch >= 1);
247 }
248 
SetLcdFilterMode() const249 bool CFX_FontMgr::SetLcdFilterMode() const {
250   return FXFT_Library_SetLcdFilter(m_FTLibrary, FT_LCD_FILTER_DEFAULT) !=
251          FT_Err_Unimplemented_Feature;
252 }
253