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) 11extern void _FPDFAPI_GetInternalFontData(int id1, FX_LPCBYTE& data, FX_DWORD& size); 12CFX_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} 29CFX_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} 61void CFX_Font::DeleteFace() 62{ 63 FXFT_Done_Face(m_Face); 64 m_Face = NULL; 65} 66FX_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} 86extern "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}; 104FX_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} 125FX_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} 141int 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} 156static 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} 174FX_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} 184FX_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} 191int 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} 199int 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} 207FX_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} 267FX_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} 282FX_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} 289FX_BOOL CFX_Font::IsFixedWidth() 290{ 291 if (m_Face == NULL) { 292 return FALSE; 293 } 294 return FXFT_Is_Face_fixedwidth(m_Face); 295} 296CFX_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} 307CFX_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} 318CFX_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} 338FX_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} 357int 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} 365int 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} 373int 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} 381int 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} 389CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) 390{ 391 m_pFont = pFont; 392} 393FX_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} 413FX_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} 434IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont) 435{ 436 return new CFX_UnicodeEncoding(pFont); 437} 438