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