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) 15CFPF_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) {} 22CFPF_SkiaFont::~CFPF_SkiaFont() { 23 if (m_Face) { 24 FXFT_Done_Face(m_Face); 25 } 26} 27void CFPF_SkiaFont::Release() { 28 if (--m_dwRefCount == 0) { 29 delete this; 30 } 31} 32IFPF_Font* CFPF_SkiaFont::Retain() { 33 m_dwRefCount++; 34 return (IFPF_Font*)this; 35} 36FPF_HFONT CFPF_SkiaFont::GetHandle() { 37 return NULL; 38} 39CFX_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} 45CFX_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} 51int32_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} 60int32_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} 72int32_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} 79int32_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} 86FX_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} 134FX_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} 148int32_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} 155int32_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} 166FX_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} 178FX_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