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