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_system.h" 12 #include "core/fxge/android/cfpf_skiabufferfont.h" 13 #include "core/fxge/android/cfpf_skiafilefont.h" 14 #include "core/fxge/android/cfpf_skiafontdescriptor.h" 15 #include "core/fxge/android/cfpf_skiafontmgr.h" 16 #include "core/fxge/android/cfpf_skiapathfont.h" 17 #include "core/fxge/fx_freetype.h" 18 19 #define FPF_EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) 20 21 CFPF_SkiaFont::CFPF_SkiaFont() 22 : m_pFontMgr(nullptr), 23 m_pFontDes(nullptr), 24 m_Face(nullptr), 25 m_dwStyle(0), 26 m_uCharset(0), 27 m_dwRefCount(0) {} 28 29 CFPF_SkiaFont::~CFPF_SkiaFont() { 30 if (m_Face) 31 FXFT_Done_Face(m_Face); 32 } 33 34 void CFPF_SkiaFont::Release() { 35 if (--m_dwRefCount == 0) 36 delete this; 37 } 38 39 CFPF_SkiaFont* CFPF_SkiaFont::Retain() { 40 m_dwRefCount++; 41 return this; 42 } 43 44 ByteString CFPF_SkiaFont::GetFamilyName() { 45 if (!m_Face) 46 return ByteString(); 47 return ByteString(FXFT_Get_Face_Family_Name(m_Face)); 48 } 49 50 ByteString CFPF_SkiaFont::GetPsName() { 51 if (!m_Face) 52 return ByteString(); 53 return FXFT_Get_Postscript_Name(m_Face); 54 } 55 56 int32_t CFPF_SkiaFont::GetGlyphIndex(wchar_t wUnicode) { 57 if (!m_Face) 58 return wUnicode; 59 if (FXFT_Select_Charmap(m_Face, FXFT_ENCODING_UNICODE)) 60 return 0; 61 return FXFT_Get_Char_Index(m_Face, wUnicode); 62 } 63 64 int32_t CFPF_SkiaFont::GetGlyphWidth(int32_t iGlyphIndex) { 65 if (!m_Face) 66 return 0; 67 if (FXFT_Load_Glyph( 68 m_Face, iGlyphIndex, 69 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { 70 return 0; 71 } 72 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 73 FXFT_Get_Glyph_HoriAdvance(m_Face)); 74 } 75 76 int32_t CFPF_SkiaFont::GetAscent() const { 77 if (!m_Face) 78 return 0; 79 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 80 FXFT_Get_Face_Ascender(m_Face)); 81 } 82 83 int32_t CFPF_SkiaFont::GetDescent() const { 84 if (!m_Face) 85 return 0; 86 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 87 FXFT_Get_Face_Descender(m_Face)); 88 } 89 90 bool CFPF_SkiaFont::GetGlyphBBox(int32_t iGlyphIndex, FX_RECT& rtBBox) { 91 if (!m_Face) 92 return false; 93 if (FXFT_Is_Face_Tricky(m_Face)) { 94 if (FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72)) 95 return false; 96 if (FXFT_Load_Glyph(m_Face, iGlyphIndex, 97 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { 98 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); 99 return false; 100 } 101 FXFT_Glyph glyph; 102 if (FXFT_Get_Glyph(m_Face->glyph, &glyph)) { 103 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); 104 return false; 105 } 106 FXFT_BBox cbox; 107 FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); 108 int32_t x_ppem = m_Face->size->metrics.x_ppem; 109 int32_t y_ppem = m_Face->size->metrics.y_ppem; 110 rtBBox.left = FPF_EM_ADJUST(x_ppem, cbox.xMin); 111 rtBBox.right = FPF_EM_ADJUST(x_ppem, cbox.xMax); 112 rtBBox.top = FPF_EM_ADJUST(y_ppem, cbox.yMax); 113 rtBBox.bottom = FPF_EM_ADJUST(y_ppem, cbox.yMin); 114 rtBBox.top = std::min(rtBBox.top, GetAscent()); 115 rtBBox.bottom = std::max(rtBBox.bottom, GetDescent()); 116 FXFT_Done_Glyph(glyph); 117 return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; 118 } 119 if (FXFT_Load_Glyph( 120 m_Face, iGlyphIndex, 121 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), 125 FXFT_Get_Glyph_HoriBearingX(m_Face)); 126 rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 127 FXFT_Get_Glyph_HoriBearingY(m_Face)); 128 rtBBox.right = FPF_EM_ADJUST( 129 FXFT_Get_Face_UnitsPerEM(m_Face), 130 FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)); 131 rtBBox.top = FPF_EM_ADJUST( 132 FXFT_Get_Face_UnitsPerEM(m_Face), 133 FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)); 134 return true; 135 } 136 137 bool CFPF_SkiaFont::GetBBox(FX_RECT& rtBBox) { 138 if (!m_Face) { 139 return false; 140 } 141 rtBBox.left = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 142 FXFT_Get_Face_xMin(m_Face)); 143 rtBBox.top = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 144 FXFT_Get_Face_yMin(m_Face)); 145 rtBBox.right = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 146 FXFT_Get_Face_xMax(m_Face)); 147 rtBBox.bottom = FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 148 FXFT_Get_Face_yMax(m_Face)); 149 return true; 150 } 151 152 int32_t CFPF_SkiaFont::GetHeight() const { 153 if (!m_Face) 154 return 0; 155 return FPF_EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 156 FXFT_Get_Face_Height(m_Face)); 157 } 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 return 0; 168 } 169 170 uint32_t CFPF_SkiaFont::GetFontData(uint32_t dwTable, 171 uint8_t* pBuffer, 172 uint32_t 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 return pdfium::base::checked_cast<uint32_t>(ulSize); 180 } 181 182 bool CFPF_SkiaFont::InitFont(CFPF_SkiaFontMgr* pFontMgr, 183 CFPF_SkiaFontDescriptor* pFontDes, 184 const ByteStringView& bsFamily, 185 uint32_t 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 } 196 case FPF_SKIAFONTTYPE_File: { 197 CFPF_SkiaFileFont* pFont = (CFPF_SkiaFileFont*)pFontDes; 198 m_Face = pFontMgr->GetFontFace(pFont->m_pFile, pFont->m_iFaceIndex); 199 break; 200 } 201 case FPF_SKIAFONTTYPE_Buffer: { 202 CFPF_SkiaBufferFont* pFont = (CFPF_SkiaBufferFont*)pFontDes; 203 m_Face = pFontMgr->GetFontFace((const uint8_t*)pFont->m_pBuffer, 204 pFont->m_szBuffer, pFont->m_iFaceIndex); 205 break; 206 } 207 default: 208 return false; 209 } 210 if (!m_Face) 211 return false; 212 213 m_dwStyle = dwStyle; 214 m_uCharset = uCharset; 215 m_pFontMgr = pFontMgr; 216 m_pFontDes = pFontDes; 217 m_dwRefCount = 1; 218 return true; 219 } 220