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