• 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/android/cfpf_skiafont.h"
8 
9 #include <algorithm>
10 
11 #include "core/fxcrt/fx_system.h"
12 #include "core/fxge/android/cfpf_skiabufferfont.h"
13 #include "core/fxge/android/cfpf_skiafilefont.h"
14 #include "core/fxge/android/cfpf_skiafontdescriptor.h"
15 #include "core/fxge/android/cfpf_skiafontmgr.h"
16 #include "core/fxge/android/cfpf_skiapathfont.h"
17 #include "core/fxge/fx_freetype.h"
18 
19 #define FPF_EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)
20 
CFPF_SkiaFont()21 CFPF_SkiaFont::CFPF_SkiaFont()
22     : m_pFontMgr(nullptr),
23       m_pFontDes(nullptr),
24       m_Face(nullptr),
25       m_dwStyle(0),
26       m_uCharset(0),
27       m_dwRefCount(0) {}
28 
~CFPF_SkiaFont()29 CFPF_SkiaFont::~CFPF_SkiaFont() {
30   if (m_Face)
31     FXFT_Done_Face(m_Face);
32 }
33 
Release()34 void CFPF_SkiaFont::Release() {
35   if (--m_dwRefCount == 0)
36     delete this;
37 }
38 
Retain()39 CFPF_SkiaFont* CFPF_SkiaFont::Retain() {
40   m_dwRefCount++;
41   return this;
42 }
43 
GetFamilyName()44 CFX_ByteString CFPF_SkiaFont::GetFamilyName() {
45   if (!m_Face)
46     return CFX_ByteString();
47   return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
48 }
49 
GetPsName()50 CFX_ByteString CFPF_SkiaFont::GetPsName() {
51   if (!m_Face)
52     return CFX_ByteString();
53   return FXFT_Get_Postscript_Name(m_Face);
54 }
55 
GetGlyphIndex(FX_WCHAR wUnicode)56 int32_t CFPF_SkiaFont::GetGlyphIndex(FX_WCHAR wUnicode) {
57   if (!m_Face)
58     return wUnicode;
59   if (FXFT_Select_Charmap(m_Face, FXFT_ENCODING_UNICODE))
60     return 0;
61   return FXFT_Get_Char_Index(m_Face, wUnicode);
62 }
63 
GetGlyphWidth(int32_t iGlyphIndex)64 int32_t CFPF_SkiaFont::GetGlyphWidth(int32_t iGlyphIndex) {
65   if (!m_Face)
66     return 0;
67   if (FXFT_Load_Glyph(
68           m_Face, iGlyphIndex,
69           FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
70     return 0;
71   }
72   return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
73                        FXFT_Get_Glyph_HoriAdvance(m_Face));
74 }
75 
GetAscent() const76 int32_t CFPF_SkiaFont::GetAscent() const {
77   if (!m_Face)
78     return 0;
79   return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
80                        FXFT_Get_Face_Ascender(m_Face));
81 }
82 
GetDescent() const83 int32_t CFPF_SkiaFont::GetDescent() const {
84   if (!m_Face)
85     return 0;
86   return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
87                        FXFT_Get_Face_Descender(m_Face));
88 }
89 
GetGlyphBBox(int32_t iGlyphIndex,FX_RECT & rtBBox)90 bool CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox) {
91   if (!m_Face)
92     return false;
93   if (FXFT_Is_Face_Tricky(m_Face)) {
94     if (FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72))
95       return false;
96     if (FXFT_Load_Glyph(m_Face, iGlyphIndex,
97                         FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
98       FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
99       return false;
100     }
101     FXFT_Glyph glyph;
102     if (FXFT_Get_Glyph(m_Face->glyph, &glyph)) {
103       FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
104       return false;
105     }
106     FXFT_BBox cbox;
107     FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
108     int32_t x_ppem = m_Face->size->metrics.x_ppem;
109     int32_t y_ppem = m_Face->size->metrics.y_ppem;
110     rtBBox.left = FPF_EM_ADJUST(x_ppem, cbox.xMin);
111     rtBBox.right = FPF_EM_ADJUST(x_ppem, cbox.xMax);
112     rtBBox.top = FPF_EM_ADJUST(y_ppem, cbox.yMax);
113     rtBBox.bottom = FPF_EM_ADJUST(y_ppem, cbox.yMin);
114     rtBBox.top = std::min(rtBBox.top, GetAscent());
115     rtBBox.bottom = std::max(rtBBox.bottom, GetDescent());
116     FXFT_Done_Glyph(glyph);
117     return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
118   }
119   if (FXFT_Load_Glyph(
120           m_Face, iGlyphIndex,
121           FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
122     return false;
123   }
124   rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
125                               FXFT_Get_Glyph_HoriBearingX(m_Face));
126   rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
127                                 FXFT_Get_Glyph_HoriBearingY(m_Face));
128   rtBBox.right = FPF_EM_ADJUST(
129       FXFT_Get_Face_UnitsPerEM(m_Face),
130       FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face));
131   rtBBox.top = FPF_EM_ADJUST(
132       FXFT_Get_Face_UnitsPerEM(m_Face),
133       FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face));
134   return true;
135 }
136 
GetBBox(FX_RECT & rtBBox)137 bool CFPF_SkiaFont::GetBBox(FX_RECT& rtBBox) {
138   if (!m_Face) {
139     return false;
140   }
141   rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
142                               FXFT_Get_Face_xMin(m_Face));
143   rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
144                              FXFT_Get_Face_yMin(m_Face));
145   rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
146                                FXFT_Get_Face_xMax(m_Face));
147   rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
148                                 FXFT_Get_Face_yMax(m_Face));
149   return true;
150 }
151 
GetHeight() const152 int32_t CFPF_SkiaFont::GetHeight() const {
153   if (!m_Face)
154     return 0;
155   return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face),
156                        FXFT_Get_Face_Height(m_Face));
157 }
158 
GetItalicAngle() const159 int32_t CFPF_SkiaFont::GetItalicAngle() const {
160   if (!m_Face)
161     return 0;
162 
163   TT_Postscript* ttInfo =
164       (TT_Postscript*)FT_Get_Sfnt_Table(m_Face, ft_sfnt_post);
165   if (ttInfo)
166     return ttInfo->italicAngle;
167   return 0;
168 }
169 
GetFontData(uint32_t dwTable,uint8_t * pBuffer,uint32_t dwSize)170 uint32_t CFPF_SkiaFont::GetFontData(uint32_t dwTable,
171                                     uint8_t* pBuffer,
172                                     uint32_t dwSize) {
173   if (!m_Face)
174     return 0;
175 
176   FT_ULong ulSize = pdfium::base::checked_cast<FT_ULong>(dwSize);
177   if (FXFT_Load_Sfnt_Table(m_Face, dwTable, 0, pBuffer, &ulSize))
178     return 0;
179   return pdfium::base::checked_cast<uint32_t>(ulSize);
180 }
181 
InitFont(CFPF_SkiaFontMgr * pFontMgr,CFPF_SkiaFontDescriptor * pFontDes,const CFX_ByteStringC & bsFamily,uint32_t dwStyle,uint8_t uCharset)182 bool CFPF_SkiaFont::InitFont(CFPF_SkiaFontMgr* pFontMgr,
183                              CFPF_SkiaFontDescriptor* pFontDes,
184                              const CFX_ByteStringC& bsFamily,
185                              uint32_t dwStyle,
186                              uint8_t uCharset) {
187   if (!pFontMgr || !pFontDes)
188     return false;
189 
190   switch (pFontDes->GetType()) {
191     case FPF_SKIAFONTTYPE_Path: {
192       CFPF_SkiaPathFont* pFont = (CFPF_SkiaPathFont*)pFontDes;
193       m_Face = pFontMgr->GetFontFace(pFont->m_pPath, pFont->m_iFaceIndex);
194       break;
195     }
196     case FPF_SKIAFONTTYPE_File: {
197       CFPF_SkiaFileFont* pFont = (CFPF_SkiaFileFont*)pFontDes;
198       m_Face = pFontMgr->GetFontFace(pFont->m_pFile, pFont->m_iFaceIndex);
199       break;
200     }
201     case FPF_SKIAFONTTYPE_Buffer: {
202       CFPF_SkiaBufferFont* pFont = (CFPF_SkiaBufferFont*)pFontDes;
203       m_Face = pFontMgr->GetFontFace((const uint8_t*)pFont->m_pBuffer,
204                                      pFont->m_szBuffer, pFont->m_iFaceIndex);
205       break;
206     }
207     default:
208       return false;
209   }
210   if (!m_Face)
211     return false;
212 
213   m_dwStyle = dwStyle;
214   m_uCharset = uCharset;
215   m_pFontMgr = pFontMgr;
216   m_pFontDes = pFontDes;
217   m_dwRefCount = 1;
218   return true;
219 }
220