Home | History | Annotate | Download | only in ge
      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 "../../../include/fxge/fx_ge.h"
      8 #include "../../../include/fxge/fx_freetype.h"
      9 #include "text_int.h"
     10 #define EM_ADJUST(em, a) (em == 0?(a): (a)*1000/em)
     11 extern void _FPDFAPI_GetInternalFontData(int id1, FX_LPCBYTE& data, FX_DWORD& size);
     12 CFX_Font::CFX_Font()
     13 {
     14     m_pSubstFont = NULL;
     15     m_Face = NULL;
     16     m_bEmbedded = FALSE;
     17     m_bVertical = FALSE;
     18     m_pFontData = NULL;
     19     m_pFontDataAllocation = NULL;
     20     m_dwSize = 0;
     21     m_pOwnedStream = NULL;
     22     m_pGsubData = NULL;
     23     m_pPlatformFont = NULL;
     24     m_pPlatformFontCollection = NULL;
     25     m_pDwFont = NULL;
     26     m_hHandle = NULL;
     27     m_bDwLoaded = FALSE;
     28 }
     29 CFX_Font::~CFX_Font()
     30 {
     31     if (m_pSubstFont) {
     32         delete m_pSubstFont;
     33         m_pSubstFont = NULL;
     34     }
     35     if (m_pFontDataAllocation) {
     36         FX_Free(m_pFontDataAllocation);
     37         m_pFontDataAllocation = NULL;
     38     }
     39     if (m_Face) {
     40         if (FXFT_Get_Face_External_Stream(m_Face)) {
     41             FXFT_Clear_Face_External_Stream(m_Face);
     42         }
     43         if(m_bEmbedded) {
     44             DeleteFace();
     45         } else {
     46             CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
     47         }
     48     }
     49     if (m_pOwnedStream) {
     50         FX_Free(m_pOwnedStream);
     51         m_pOwnedStream = NULL;
     52     }
     53     if (m_pGsubData) {
     54         FX_Free(m_pGsubData);
     55         m_pGsubData = NULL;
     56     }
     57 #if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
     58     ReleasePlatformResource();
     59 #endif
     60 }
     61 void CFX_Font::DeleteFace()
     62 {
     63     FXFT_Done_Face(m_Face);
     64     m_Face = NULL;
     65 }
     66 FX_BOOL CFX_Font::LoadSubst(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
     67                             int weight, int italic_angle, int CharsetCP, FX_BOOL bVertical)
     68 {
     69     m_bEmbedded = FALSE;
     70     m_bVertical = bVertical;
     71     m_pSubstFont = new CFX_SubstFont;
     72     m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
     73              CharsetCP, m_pSubstFont);
     74 #if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
     75     if(m_pSubstFont->m_ExtHandle) {
     76         m_pPlatformFont = m_pSubstFont->m_ExtHandle;
     77         m_pSubstFont->m_ExtHandle = NULL;
     78     }
     79 #endif
     80     if (m_Face) {
     81         m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
     82         m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
     83     }
     84     return TRUE;
     85 }
     86 extern "C" {
     87     unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
     88                                 unsigned char* buffer, unsigned long count)
     89     {
     90         if (count == 0) {
     91             return 0;
     92         }
     93         IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
     94         int res = pFile->ReadBlock(buffer, offset, count);
     95         if (res) {
     96             return count;
     97         }
     98         return 0;
     99     }
    100     void _FTStreamClose(FXFT_Stream stream)
    101     {
    102     }
    103 };
    104 FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream)
    105 {
    106     FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(FX_BYTE, sizeof (FXFT_StreamRec));
    107     stream1->base = NULL;
    108     stream1->size = (unsigned long)pFile->GetSize();
    109     stream1->pos = 0;
    110     stream1->descriptor.pointer = pFile;
    111     stream1->close = _FTStreamClose;
    112     stream1->read = _FTStreamRead;
    113     FXFT_Open_Args args;
    114     args.flags = FT_OPEN_STREAM;
    115     args.stream = stream1;
    116     if (FXFT_Open_Face(library, &args, 0, Face)) {
    117         FX_Free(stream1);
    118         return FALSE;
    119     }
    120     if (stream) {
    121         *stream = stream1;
    122     }
    123     return TRUE;
    124 }
    125 FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile)
    126 {
    127     m_bEmbedded = FALSE;
    128     FXFT_Library library;
    129     if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
    130         FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
    131     }
    132     library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
    133     FXFT_Stream stream = NULL;
    134     if (!_LoadFile(library, &m_Face, pFile, &stream)) {
    135         return FALSE;
    136     }
    137     m_pOwnedStream = stream;
    138     FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
    139     return TRUE;
    140 }
    141 int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index)
    142 {
    143     if (!m_Face) {
    144         return 0;
    145     }
    146     if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) {
    147         AdjustMMParams(glyph_index, 0, 0);
    148     }
    149     int err = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
    150     if (err) {
    151         return 0;
    152     }
    153     int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriAdvance(m_Face));
    154     return width;
    155 }
    156 static FXFT_Face FT_LoadFont(FX_LPBYTE pData, int size)
    157 {
    158     FXFT_Library library;
    159     if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
    160         FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
    161     }
    162     library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
    163     FXFT_Face face = NULL;
    164     int error = FXFT_New_Memory_Face(library, pData, size, 0, &face);
    165     if (error) {
    166         return NULL;
    167     }
    168     error = FXFT_Set_Pixel_Sizes(face, 64, 64);
    169     if (error) {
    170         return NULL;
    171     }
    172     return face;
    173 }
    174 FX_BOOL CFX_Font::LoadEmbedded(FX_LPCBYTE data, FX_DWORD size)
    175 {
    176     m_pFontDataAllocation = FX_Alloc(FX_BYTE, size);
    177     FXSYS_memcpy32(m_pFontDataAllocation, data, size);
    178     m_Face = FT_LoadFont((FX_LPBYTE)m_pFontDataAllocation, size);
    179     m_pFontData = (FX_LPBYTE)m_pFontDataAllocation;
    180     m_bEmbedded = TRUE;
    181     m_dwSize = size;
    182     return m_Face != NULL;
    183 }
    184 FX_BOOL CFX_Font::IsTTFont()
    185 {
    186     if (m_Face == NULL) {
    187         return FALSE;
    188     }
    189     return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
    190 }
    191 int CFX_Font::GetAscent() const
    192 {
    193     if (m_Face == NULL) {
    194         return 0;
    195     }
    196     int ascent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Ascender(m_Face));
    197     return ascent;
    198 }
    199 int CFX_Font::GetDescent() const
    200 {
    201     if (m_Face == NULL) {
    202         return 0;
    203     }
    204     int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face));
    205     return descent;
    206 }
    207 FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT &bbox)
    208 {
    209     if (m_Face == NULL) {
    210         return FALSE;
    211     }
    212     if (FXFT_Is_Face_Tricky(m_Face)) {
    213         int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
    214         if (error) {
    215             return FALSE;
    216         }
    217         error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
    218         if (error) {
    219             return FALSE;
    220         }
    221         FXFT_BBox cbox;
    222         FT_Glyph glyph;
    223         error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph);
    224         if (error) {
    225             return FALSE;
    226         }
    227         FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
    228         int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem,
    229             pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem;
    230         if (pixel_size_x == 0 || pixel_size_y == 0) {
    231             bbox.left = cbox.xMin;
    232             bbox.right = cbox.xMax;
    233             bbox.top = cbox.yMax;
    234             bbox.bottom = cbox.yMin;
    235         } else {
    236             bbox.left = cbox.xMin * 1000 / pixel_size_x;
    237             bbox.right = cbox.xMax * 1000 / pixel_size_x;
    238             bbox.top = cbox.yMax * 1000 / pixel_size_y;
    239             bbox.bottom = cbox.yMin * 1000 / pixel_size_y;
    240         }
    241         if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) {
    242             bbox.top = FXFT_Get_Face_Ascender(m_Face);
    243         }
    244         if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) {
    245             bbox.bottom = FXFT_Get_Face_Descender(m_Face);
    246         }
    247         FT_Done_Glyph(glyph);
    248         return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
    249     }
    250     if (FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
    251         return FALSE;
    252     }
    253     int em = FXFT_Get_Face_UnitsPerEM(m_Face);
    254     if (em == 0) {
    255         bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face);
    256         bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
    257         bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face);
    258         bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face);
    259     } else {
    260         bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
    261         bbox.top = (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * 1000 / em;
    262         bbox.right = (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * 1000 / em;
    263         bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
    264     }
    265     return TRUE;
    266 }
    267 FX_BOOL CFX_Font::IsItalic()
    268 {
    269     if (m_Face == NULL) {
    270         return FALSE;
    271     }
    272     FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC;
    273     if (!ret) {
    274         CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face));
    275         str.MakeLower();
    276         if (str.Find("italic") != -1) {
    277             ret = TRUE;
    278         }
    279     }
    280     return ret;
    281 }
    282 FX_BOOL CFX_Font::IsBold()
    283 {
    284     if (m_Face == NULL) {
    285         return FALSE;
    286     }
    287     return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
    288 }
    289 FX_BOOL CFX_Font::IsFixedWidth()
    290 {
    291     if (m_Face == NULL) {
    292         return FALSE;
    293     }
    294     return FXFT_Is_Face_fixedwidth(m_Face);
    295 }
    296 CFX_WideString CFX_Font::GetPsName() const
    297 {
    298     if (m_Face == NULL) {
    299         return CFX_WideString();
    300     }
    301     CFX_WideString psName = CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face));
    302     if (psName.IsEmpty()) {
    303         psName =  CFX_WideString::FromLocal("Untitled");
    304     }
    305     return psName;
    306 }
    307 CFX_ByteString CFX_Font::GetFamilyName() const
    308 {
    309     if (m_Face == NULL && m_pSubstFont == NULL) {
    310         return CFX_ByteString();
    311     }
    312     if (m_Face) {
    313         return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
    314     } else {
    315         return m_pSubstFont->m_Family;
    316     }
    317 }
    318 CFX_ByteString CFX_Font::GetFaceName() const
    319 {
    320     if (m_Face == NULL && m_pSubstFont == NULL) {
    321         return CFX_ByteString();
    322     }
    323     if (m_Face) {
    324         CFX_ByteString facename;
    325         CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face));
    326         facename = GetFamilyName();
    327         if (facename.IsEmpty()) {
    328             facename = "Untitled";
    329         }
    330         if (!style.IsEmpty() && style != "Regular") {
    331             facename += " " + style;
    332         }
    333         return facename;
    334     } else {
    335         return m_pSubstFont->m_Family;
    336     }
    337 }
    338 FX_BOOL CFX_Font::GetBBox(FX_RECT &bbox)
    339 {
    340     if (m_Face == NULL) {
    341         return FALSE;
    342     }
    343     int em = FXFT_Get_Face_UnitsPerEM(m_Face);
    344     if (em == 0) {
    345         bbox.left = FXFT_Get_Face_xMin(m_Face);
    346         bbox.bottom = FXFT_Get_Face_yMax(m_Face);
    347         bbox.top = FXFT_Get_Face_yMin(m_Face);
    348         bbox.right = FXFT_Get_Face_xMax(m_Face);
    349     } else {
    350         bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
    351         bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
    352         bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
    353         bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
    354     }
    355     return TRUE;
    356 }
    357 int CFX_Font::GetHeight()
    358 {
    359     if (m_Face == NULL) {
    360         return 0;
    361     }
    362     int height = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face));
    363     return height;
    364 }
    365 int CFX_Font::GetMaxAdvanceWidth()
    366 {
    367     if (m_Face == NULL) {
    368         return 0;
    369     }
    370     int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_MaxAdvanceWidth(m_Face));
    371     return width;
    372 }
    373 int CFX_Font::GetULPos()
    374 {
    375     if (m_Face == NULL) {
    376         return 0;
    377     }
    378     int pos = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLinePosition(m_Face));
    379     return pos;
    380 }
    381 int CFX_Font::GetULthickness()
    382 {
    383     if (m_Face == NULL) {
    384         return 0;
    385     }
    386     int thickness = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLineThickness(m_Face));
    387     return thickness;
    388 }
    389 CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont)
    390 {
    391     m_pFont = pFont;
    392 }
    393 FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode)
    394 {
    395     FXFT_Face face =  m_pFont->GetFace();
    396     if (!face) {
    397         return charcode;
    398     }
    399     if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) {
    400         return FXFT_Get_Char_Index(face, charcode);
    401     }
    402     if (m_pFont->m_pSubstFont && m_pFont->m_pSubstFont->m_Charset == 2) {
    403         FX_DWORD index = 0;
    404         if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) {
    405             index = FXFT_Get_Char_Index(face, charcode);
    406         }
    407         if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) {
    408             return FXFT_Get_Char_Index(face, charcode);
    409         }
    410     }
    411     return charcode;
    412 }
    413 FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode, int encoding)
    414 {
    415     FXFT_Face face =  m_pFont->GetFace();
    416     if (!face) {
    417         return charcode;
    418     }
    419     if (encoding == ENCODING_UNICODE) {
    420         return	GlyphFromCharCode(charcode);
    421     } else {
    422         int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face);
    423         int i = 0;
    424         while (i < nmaps) {
    425             int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]);
    426             if (encoding != FXFT_ENCODING_UNICODE) {
    427                 FXFT_Select_Charmap(face, encoding);
    428                 break;
    429             }
    430         }
    431     }
    432     return FXFT_Get_Char_Index(face, charcode);
    433 }
    434 IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont)
    435 {
    436     return new CFX_UnicodeEncoding(pFont);
    437 }
    438