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