Home | History | Annotate | Download | only in android
      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