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