OLD | NEW |
| (Empty) |
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 "core/include/fxcrt/fx_system.h" | |
8 | |
9 #if _FX_OS_ == _FX_ANDROID_ | |
10 | |
11 #include <algorithm> | |
12 | |
13 #include "core/include/fxge/fx_freetype.h" | |
14 #include "core/src/fxge/android/fpf_skiafont.h" | |
15 #include "core/src/fxge/android/fpf_skiafontmgr.h" | |
16 | |
17 #define FPF_EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) | |
18 | |
19 CFPF_SkiaFont::CFPF_SkiaFont() | |
20 : m_pFontMgr(NULL), | |
21 m_pFontDes(NULL), | |
22 m_Face(NULL), | |
23 m_dwStyle(0), | |
24 m_uCharset(0), | |
25 m_dwRefCount(0) {} | |
26 CFPF_SkiaFont::~CFPF_SkiaFont() { | |
27 if (m_Face) { | |
28 FXFT_Done_Face(m_Face); | |
29 } | |
30 } | |
31 void CFPF_SkiaFont::Release() { | |
32 if (--m_dwRefCount == 0) { | |
33 delete this; | |
34 } | |
35 } | |
36 IFPF_Font* CFPF_SkiaFont::Retain() { | |
37 m_dwRefCount++; | |
38 return (IFPF_Font*)this; | |
39 } | |
40 FPF_HFONT CFPF_SkiaFont::GetHandle() { | |
41 return NULL; | |
42 } | |
43 CFX_ByteString CFPF_SkiaFont::GetFamilyName() { | |
44 if (!m_Face) { | |
45 return CFX_ByteString(); | |
46 } | |
47 return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); | |
48 } | |
49 CFX_WideString CFPF_SkiaFont::GetPsName() { | |
50 if (!m_Face) { | |
51 return CFX_WideString(); | |
52 } | |
53 return CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face)); | |
54 } | |
55 int32_t CFPF_SkiaFont::GetGlyphIndex(FX_WCHAR wUnicode) { | |
56 if (!m_Face) { | |
57 return wUnicode; | |
58 } | |
59 if (FXFT_Select_Charmap(m_Face, FXFT_ENCODING_UNICODE)) { | |
60 return 0; | |
61 } | |
62 return FXFT_Get_Char_Index(m_Face, wUnicode); | |
63 } | |
64 int32_t CFPF_SkiaFont::GetGlyphWidth(int32_t iGlyphIndex) { | |
65 if (!m_Face) { | |
66 return 0; | |
67 } | |
68 if (FXFT_Load_Glyph( | |
69 m_Face, iGlyphIndex, | |
70 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { | |
71 return 0; | |
72 } | |
73 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
74 FXFT_Get_Glyph_HoriAdvance(m_Face)); | |
75 } | |
76 int32_t CFPF_SkiaFont::GetAscent() const { | |
77 if (!m_Face) { | |
78 return 0; | |
79 } | |
80 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
81 FXFT_Get_Face_Ascender(m_Face)); | |
82 } | |
83 int32_t CFPF_SkiaFont::GetDescent() const { | |
84 if (!m_Face) { | |
85 return 0; | |
86 } | |
87 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
88 FXFT_Get_Face_Descender(m_Face)); | |
89 } | |
90 FX_BOOL CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox) { | |
91 if (!m_Face) { | |
92 return FALSE; | |
93 } | |
94 if (FXFT_Is_Face_Tricky(m_Face)) { | |
95 if (FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72)) { | |
96 return FALSE; | |
97 } | |
98 if (FXFT_Load_Glyph(m_Face, iGlyphIndex, | |
99 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 int32_t x_ppem = m_Face->size->metrics.x_ppem; | |
111 int32_t 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 = std::min(rtBBox.top, GetAscent()); | |
117 rtBBox.bottom = std::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( | |
122 m_Face, iGlyphIndex, | |
123 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { | |
124 return FALSE; | |
125 } | |
126 rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
127 FXFT_Get_Glyph_HoriBearingX(m_Face)); | |
128 rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
129 FXFT_Get_Glyph_HoriBearingY(m_Face)); | |
130 rtBBox.right = FPF_EM_ADJUST( | |
131 FXFT_Get_Face_UnitsPerEM(m_Face), | |
132 FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)); | |
133 rtBBox.top = FPF_EM_ADJUST( | |
134 FXFT_Get_Face_UnitsPerEM(m_Face), | |
135 FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)); | |
136 return TRUE; | |
137 } | |
138 FX_BOOL CFPF_SkiaFont::GetBBox(FX_RECT& rtBBox) { | |
139 if (!m_Face) { | |
140 return FALSE; | |
141 } | |
142 rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
143 FXFT_Get_Face_xMin(m_Face)); | |
144 rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
145 FXFT_Get_Face_yMin(m_Face)); | |
146 rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
147 FXFT_Get_Face_xMax(m_Face)); | |
148 rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
149 FXFT_Get_Face_yMax(m_Face)); | |
150 return TRUE; | |
151 } | |
152 int32_t CFPF_SkiaFont::GetHeight() const { | |
153 if (!m_Face) { | |
154 return 0; | |
155 } | |
156 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | |
157 FXFT_Get_Face_Height(m_Face)); | |
158 } | |
159 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 } | |
168 return 0; | |
169 } | |
170 FX_DWORD CFPF_SkiaFont::GetFontData(FX_DWORD dwTable, | |
171 uint8_t* pBuffer, | |
172 FX_DWORD 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 } | |
180 return pdfium::base::checked_cast<FX_DWORD>(ulSize); | |
181 } | |
182 FX_BOOL CFPF_SkiaFont::InitFont(CFPF_SkiaFontMgr* pFontMgr, | |
183 CFPF_SkiaFontDescriptor* pFontDes, | |
184 const CFX_ByteStringC& bsFamily, | |
185 FX_DWORD 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 case FPF_SKIAFONTTYPE_File: { | |
196 CFPF_SkiaFileFont* pFont = (CFPF_SkiaFileFont*)pFontDes; | |
197 m_Face = pFontMgr->GetFontFace(pFont->m_pFile, pFont->m_iFaceIndex); | |
198 } break; | |
199 case FPF_SKIAFONTTYPE_Buffer: { | |
200 CFPF_SkiaBufferFont* pFont = (CFPF_SkiaBufferFont*)pFontDes; | |
201 m_Face = pFontMgr->GetFontFace((const uint8_t*)pFont->m_pBuffer, | |
202 pFont->m_szBuffer, pFont->m_iFaceIndex); | |
203 } break; | |
204 default: | |
205 return FALSE; | |
206 } | |
207 if (!m_Face) { | |
208 return FALSE; | |
209 } | |
210 m_dwStyle = dwStyle; | |
211 m_uCharset = uCharset; | |
212 m_pFontMgr = pFontMgr; | |
213 m_pFontDes = pFontDes; | |
214 m_dwRefCount = 1; | |
215 return TRUE; | |
216 } | |
217 #endif | |
OLD | NEW |