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