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