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_coordinates.h"
12 #include "core/fxcrt/fx_system.h"
13 #include "core/fxge/android/cfpf_skiafontmgr.h"
14 #include "core/fxge/android/cfpf_skiapathfont.h"
15 #include "core/fxge/fx_freetype.h"
16
17 #define FPF_EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em)
18
CFPF_SkiaFont(CFPF_SkiaFontMgr * pFontMgr,const CFPF_SkiaPathFont * pFont,uint32_t dwStyle,uint8_t uCharset)19 CFPF_SkiaFont::CFPF_SkiaFont(CFPF_SkiaFontMgr* pFontMgr,
20 const CFPF_SkiaPathFont* pFont,
21 uint32_t dwStyle,
22 uint8_t uCharset)
23 : m_pFontMgr(pFontMgr),
24 m_pFont(pFont),
25 m_Face(m_pFontMgr->GetFontFace(m_pFont->path(), m_pFont->face_index())),
26 m_dwStyle(dwStyle),
27 m_uCharset(uCharset) {}
28
29 CFPF_SkiaFont::~CFPF_SkiaFont() = default;
30
GetFamilyName()31 ByteString CFPF_SkiaFont::GetFamilyName() {
32 if (!m_Face)
33 return ByteString();
34 return ByteString(FXFT_Get_Face_Family_Name(GetFaceRec()));
35 }
36
GetPsName()37 ByteString CFPF_SkiaFont::GetPsName() {
38 if (!m_Face)
39 return ByteString();
40 return FT_Get_Postscript_Name(GetFaceRec());
41 }
42
GetGlyphIndex(wchar_t wUnicode)43 int32_t CFPF_SkiaFont::GetGlyphIndex(wchar_t wUnicode) {
44 if (!m_Face)
45 return wUnicode;
46 if (FXFT_Select_Charmap(GetFaceRec(), FT_ENCODING_UNICODE))
47 return 0;
48 return FT_Get_Char_Index(GetFaceRec(), wUnicode);
49 }
50
GetGlyphWidth(int32_t iGlyphIndex)51 int32_t CFPF_SkiaFont::GetGlyphWidth(int32_t iGlyphIndex) {
52 if (!m_Face)
53 return 0;
54 if (FT_Load_Glyph(GetFaceRec(), iGlyphIndex,
55 FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
56 return 0;
57 }
58 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
59 FXFT_Get_Glyph_HoriAdvance(GetFaceRec()));
60 }
61
GetAscent() const62 int32_t CFPF_SkiaFont::GetAscent() const {
63 if (!m_Face)
64 return 0;
65 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
66 FXFT_Get_Face_Ascender(GetFaceRec()));
67 }
68
GetDescent() const69 int32_t CFPF_SkiaFont::GetDescent() const {
70 if (!m_Face)
71 return 0;
72 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
73 FXFT_Get_Face_Descender(GetFaceRec()));
74 }
75
GetGlyphBBox(int32_t iGlyphIndex,FX_RECT & rtBBox)76 bool CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox) {
77 if (!m_Face)
78 return false;
79 if (FXFT_Is_Face_Tricky(GetFaceRec())) {
80 if (FT_Set_Char_Size(GetFaceRec(), 0, 1000 * 64, 72, 72))
81 return false;
82 if (FT_Load_Glyph(GetFaceRec(), iGlyphIndex,
83 FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
84 FT_Set_Pixel_Sizes(GetFaceRec(), 0, 64);
85 return false;
86 }
87 FT_Glyph glyph;
88 if (FT_Get_Glyph(GetFaceRec()->glyph, &glyph)) {
89 FT_Set_Pixel_Sizes(GetFaceRec(), 0, 64);
90 return false;
91 }
92 FT_BBox cbox;
93 FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &cbox);
94 int32_t x_ppem = GetFaceRec()->size->metrics.x_ppem;
95 int32_t y_ppem = GetFaceRec()->size->metrics.y_ppem;
96 rtBBox.left = FPF_EM_ADJUST(x_ppem, cbox.xMin);
97 rtBBox.right = FPF_EM_ADJUST(x_ppem, cbox.xMax);
98 rtBBox.top = FPF_EM_ADJUST(y_ppem, cbox.yMax);
99 rtBBox.bottom = FPF_EM_ADJUST(y_ppem, cbox.yMin);
100 rtBBox.top = std::min(rtBBox.top, GetAscent());
101 rtBBox.bottom = std::max(rtBBox.bottom, GetDescent());
102 FT_Done_Glyph(glyph);
103 return FT_Set_Pixel_Sizes(GetFaceRec(), 0, 64) == 0;
104 }
105 if (FT_Load_Glyph(GetFaceRec(), iGlyphIndex,
106 FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
107 return false;
108 }
109 rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
110 FXFT_Get_Glyph_HoriBearingX(GetFaceRec()));
111 rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
112 FXFT_Get_Glyph_HoriBearingY(GetFaceRec()));
113 rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
114 FXFT_Get_Glyph_HoriBearingX(GetFaceRec()) +
115 FXFT_Get_Glyph_Width(GetFaceRec()));
116 rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
117 FXFT_Get_Glyph_HoriBearingY(GetFaceRec()) -
118 FXFT_Get_Glyph_Height(GetFaceRec()));
119 return true;
120 }
121
GetBBox(FX_RECT & rtBBox)122 bool CFPF_SkiaFont::GetBBox(FX_RECT& rtBBox) {
123 if (!m_Face) {
124 return false;
125 }
126 rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
127 FXFT_Get_Face_xMin(GetFaceRec()));
128 rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
129 FXFT_Get_Face_yMin(GetFaceRec()));
130 rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
131 FXFT_Get_Face_xMax(GetFaceRec()));
132 rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
133 FXFT_Get_Face_yMax(GetFaceRec()));
134 return true;
135 }
136
GetHeight() const137 int32_t CFPF_SkiaFont::GetHeight() const {
138 if (!m_Face)
139 return 0;
140 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(GetFaceRec()),
141 FXFT_Get_Face_Height(GetFaceRec()));
142 }
143
GetItalicAngle() const144 int32_t CFPF_SkiaFont::GetItalicAngle() const {
145 if (!m_Face)
146 return 0;
147
148 auto* info = static_cast<TT_Postscript*>(
149 FT_Get_Sfnt_Table(GetFaceRec(), ft_sfnt_post));
150 return info ? info->italicAngle : 0;
151 }
152
GetFontData(uint32_t dwTable,pdfium::span<uint8_t> pBuffer)153 uint32_t CFPF_SkiaFont::GetFontData(uint32_t dwTable,
154 pdfium::span<uint8_t> pBuffer) {
155 if (!m_Face)
156 return 0;
157
158 FT_ULong ulSize = pdfium::base::checked_cast<FT_ULong>(pBuffer.size());
159 if (FT_Load_Sfnt_Table(GetFaceRec(), dwTable, 0, pBuffer.data(), &ulSize))
160 return 0;
161 return pdfium::base::checked_cast<uint32_t>(ulSize);
162 }
163