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 "core/include/fxge/fx_freetype.h" 8 #include "core/include/fxge/fx_ge.h" 9 #include "text_int.h" 10 11 #define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) 12 13 #ifdef PDF_ENABLE_XFA 14 extern void _FPDFAPI_GetInternalFontData(int id1, 15 const uint8_t*& data, 16 FX_DWORD& size); 17 #endif // PDF_ENABLE_XFA 18 19 namespace { 20 21 #ifdef PDF_ENABLE_XFA 22 const FX_DWORD g_EncodingID[] = { 23 FXFM_ENCODING_MS_SYMBOL, 24 FXFM_ENCODING_UNICODE, 25 FXFM_ENCODING_MS_SJIS, 26 FXFM_ENCODING_MS_GB2312, 27 FXFM_ENCODING_MS_BIG5, 28 FXFM_ENCODING_MS_WANSUNG, 29 FXFM_ENCODING_MS_JOHAB, 30 FXFM_ENCODING_ADOBE_STANDARD, 31 FXFM_ENCODING_ADOBE_EXPERT, 32 FXFM_ENCODING_ADOBE_CUSTOM, 33 FXFM_ENCODING_ADOBE_LATIN_1, 34 FXFM_ENCODING_OLD_LATIN_2, 35 FXFM_ENCODING_APPLE_ROMAN, 36 }; 37 38 CFX_UnicodeEncodingEx* _FXFM_CreateFontEncoding(CFX_Font* pFont, 39 FX_DWORD nEncodingID) { 40 if (FXFT_Select_Charmap(pFont->GetFace(), nEncodingID)) 41 return nullptr; 42 return new CFX_UnicodeEncodingEx(pFont, nEncodingID); 43 } 44 #endif // PDF_ENABLE_XFA 45 46 FXFT_Face FT_LoadFont(const uint8_t* pData, int size) { 47 return CFX_GEModule::Get()->GetFontMgr()->GetFixedFace(pData, size, 0); 48 } 49 50 } // namespace 51 52 CFX_Font::CFX_Font() { 53 m_pSubstFont = NULL; 54 m_Face = NULL; 55 m_bEmbedded = FALSE; 56 m_bVertical = FALSE; 57 m_pFontData = NULL; 58 m_pFontDataAllocation = NULL; 59 m_dwSize = 0; 60 m_pGsubData = NULL; 61 m_pPlatformFont = NULL; 62 m_pPlatformFontCollection = NULL; 63 m_pDwFont = NULL; 64 m_hHandle = NULL; 65 m_bDwLoaded = FALSE; 66 #ifdef PDF_ENABLE_XFA 67 m_bLogic = FALSE; 68 m_pOwnedStream = NULL; 69 #endif // PDF_ENABLE_XFA 70 } 71 72 #ifdef PDF_ENABLE_XFA 73 FX_BOOL CFX_Font::LoadClone(const CFX_Font* pFont) { 74 if (pFont == NULL) { 75 return FALSE; 76 } 77 m_bLogic = TRUE; 78 if (pFont->m_pSubstFont) { 79 m_pSubstFont = new CFX_SubstFont; 80 m_pSubstFont->m_Charset = pFont->m_pSubstFont->m_Charset; 81 m_pSubstFont->m_ExtHandle = pFont->m_pSubstFont->m_ExtHandle; 82 m_pSubstFont->m_SubstFlags = pFont->m_pSubstFont->m_SubstFlags; 83 m_pSubstFont->m_Weight = pFont->m_pSubstFont->m_Weight; 84 m_pSubstFont->m_Family = pFont->m_pSubstFont->m_Family; 85 m_pSubstFont->m_ItalicAngle = pFont->m_pSubstFont->m_ItalicAngle; 86 } 87 if (pFont->m_OtfFontData.GetSize()) { 88 m_OtfFontData.AttachData(pFont->m_OtfFontData.GetBuffer(), 89 pFont->m_OtfFontData.GetSize()); 90 } 91 m_Face = pFont->m_Face; 92 m_bEmbedded = pFont->m_bEmbedded; 93 m_bVertical = pFont->m_bVertical; 94 m_dwSize = pFont->m_dwSize; 95 m_pFontData = pFont->m_pFontData; 96 m_pGsubData = pFont->m_pGsubData; 97 m_pPlatformFont = pFont->m_pPlatformFont; 98 m_pPlatformFontCollection = pFont->m_pPlatformFontCollection; 99 m_pDwFont = pFont->m_pDwFont; 100 m_hHandle = pFont->m_hHandle; 101 m_bDwLoaded = pFont->m_bDwLoaded; 102 m_pOwnedStream = pFont->m_pOwnedStream; 103 return TRUE; 104 } 105 #endif // PDF_ENABLE_XFA 106 107 CFX_Font::~CFX_Font() { 108 delete m_pSubstFont; 109 FX_Free(m_pFontDataAllocation); 110 #ifdef PDF_ENABLE_XFA 111 if (m_bLogic) { 112 m_OtfFontData.DetachBuffer(); 113 return; 114 } 115 #endif // PDF_ENABLE_XFA 116 if (m_Face) { 117 #ifndef PDF_ENABLE_XFA 118 if (FXFT_Get_Face_External_Stream(m_Face)) { 119 FXFT_Clear_Face_External_Stream(m_Face); 120 } 121 #endif // PDF_ENABLE_XFA 122 if (m_bEmbedded) { 123 DeleteFace(); 124 } else { 125 CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face); 126 } 127 } 128 #ifdef PDF_ENABLE_XFA 129 FX_Free(m_pOwnedStream); 130 #endif // PDF_ENABLE_XFA 131 FX_Free(m_pGsubData); 132 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 133 ReleasePlatformResource(); 134 #endif 135 } 136 void CFX_Font::DeleteFace() { 137 FXFT_Done_Face(m_Face); 138 m_Face = NULL; 139 } 140 void CFX_Font::LoadSubst(const CFX_ByteString& face_name, 141 FX_BOOL bTrueType, 142 FX_DWORD flags, 143 int weight, 144 int italic_angle, 145 int CharsetCP, 146 FX_BOOL bVertical) { 147 m_bEmbedded = FALSE; 148 m_bVertical = bVertical; 149 m_pSubstFont = new CFX_SubstFont; 150 m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont( 151 face_name, bTrueType, flags, weight, italic_angle, CharsetCP, 152 m_pSubstFont); 153 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 154 if (m_pSubstFont->m_ExtHandle) { 155 m_pPlatformFont = m_pSubstFont->m_ExtHandle; 156 m_pSubstFont->m_ExtHandle = NULL; 157 } 158 #endif 159 if (m_Face) { 160 m_pFontData = FXFT_Get_Face_Stream_Base(m_Face); 161 m_dwSize = FXFT_Get_Face_Stream_Size(m_Face); 162 } 163 } 164 #ifdef PDF_ENABLE_XFA 165 extern "C" { 166 unsigned long _FTStreamRead(FXFT_Stream stream, 167 unsigned long offset, 168 unsigned char* buffer, 169 unsigned long count) { 170 if (count == 0) { 171 return 0; 172 } 173 IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer; 174 int res = pFile->ReadBlock(buffer, offset, count); 175 if (res) { 176 return count; 177 } 178 return 0; 179 } 180 void _FTStreamClose(FXFT_Stream stream) {} 181 }; 182 FX_BOOL _LoadFile(FXFT_Library library, 183 FXFT_Face* Face, 184 IFX_FileRead* pFile, 185 FXFT_Stream* stream, 186 int32_t faceIndex = 0) { 187 FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(uint8_t, sizeof(FXFT_StreamRec)); 188 stream1->base = NULL; 189 stream1->size = (unsigned long)pFile->GetSize(); 190 stream1->pos = 0; 191 stream1->descriptor.pointer = pFile; 192 stream1->close = _FTStreamClose; 193 stream1->read = _FTStreamRead; 194 FXFT_Open_Args args; 195 args.flags = FT_OPEN_STREAM; 196 args.stream = stream1; 197 if (FXFT_Open_Face(library, &args, faceIndex, Face)) { 198 FX_Free(stream1); 199 return FALSE; 200 } 201 if (stream) { 202 *stream = stream1; 203 } 204 return TRUE; 205 } 206 207 FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile, 208 int nFaceIndex, 209 int* pFaceCount) { 210 m_bEmbedded = FALSE; 211 212 CFX_FontMgr* pFontMgr = CFX_GEModule::Get()->GetFontMgr(); 213 pFontMgr->InitFTLibrary(); 214 FXFT_Library library = pFontMgr->GetFTLibrary(); 215 216 FXFT_Stream stream = nullptr; 217 if (!_LoadFile(library, &m_Face, pFile, &stream, nFaceIndex)) 218 return FALSE; 219 220 if (pFaceCount) 221 *pFaceCount = (int)m_Face->num_faces; 222 m_pOwnedStream = stream; 223 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); 224 return TRUE; 225 } 226 #endif // PDF_ENABLE_XFA 227 228 int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index) { 229 if (!m_Face) { 230 return 0; 231 } 232 if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) { 233 AdjustMMParams(glyph_index, 0, 0); 234 } 235 int err = FXFT_Load_Glyph( 236 m_Face, glyph_index, 237 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); 238 if (err) { 239 return 0; 240 } 241 int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 242 FXFT_Get_Glyph_HoriAdvance(m_Face)); 243 return width; 244 } 245 246 FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, FX_DWORD size) { 247 m_pFontDataAllocation = FX_Alloc(uint8_t, size); 248 FXSYS_memcpy(m_pFontDataAllocation, data, size); 249 m_Face = FT_LoadFont(m_pFontDataAllocation, size); 250 m_pFontData = m_pFontDataAllocation; 251 m_bEmbedded = TRUE; 252 m_dwSize = size; 253 return m_Face != NULL; 254 } 255 256 FX_BOOL CFX_Font::IsTTFont() const { 257 if (!m_Face) 258 return FALSE; 259 return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT; 260 } 261 262 int CFX_Font::GetAscent() const { 263 if (!m_Face) 264 return 0; 265 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 266 FXFT_Get_Face_Ascender(m_Face)); 267 } 268 269 int CFX_Font::GetDescent() const { 270 if (!m_Face) 271 return 0; 272 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 273 FXFT_Get_Face_Descender(m_Face)); 274 } 275 276 FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT& bbox) { 277 if (!m_Face) 278 return FALSE; 279 280 if (FXFT_Is_Face_Tricky(m_Face)) { 281 int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72); 282 if (error) { 283 return FALSE; 284 } 285 error = FXFT_Load_Glyph(m_Face, glyph_index, 286 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); 287 if (error) { 288 return FALSE; 289 } 290 FXFT_BBox cbox; 291 FT_Glyph glyph; 292 error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph); 293 if (error) { 294 return FALSE; 295 } 296 FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); 297 int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem, 298 pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem; 299 if (pixel_size_x == 0 || pixel_size_y == 0) { 300 bbox.left = cbox.xMin; 301 bbox.right = cbox.xMax; 302 bbox.top = cbox.yMax; 303 bbox.bottom = cbox.yMin; 304 } else { 305 bbox.left = cbox.xMin * 1000 / pixel_size_x; 306 bbox.right = cbox.xMax * 1000 / pixel_size_x; 307 bbox.top = cbox.yMax * 1000 / pixel_size_y; 308 bbox.bottom = cbox.yMin * 1000 / pixel_size_y; 309 } 310 if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) { 311 bbox.top = FXFT_Get_Face_Ascender(m_Face); 312 } 313 if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) { 314 bbox.bottom = FXFT_Get_Face_Descender(m_Face); 315 } 316 FT_Done_Glyph(glyph); 317 return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; 318 } 319 if (FXFT_Load_Glyph( 320 m_Face, glyph_index, 321 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { 322 return FALSE; 323 } 324 int em = FXFT_Get_Face_UnitsPerEM(m_Face); 325 if (em == 0) { 326 bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face); 327 bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face); 328 bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face); 329 bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face); 330 } else { 331 bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em; 332 bbox.top = 333 (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * 334 1000 / em; 335 bbox.right = 336 (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * 337 1000 / em; 338 bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em; 339 } 340 return TRUE; 341 } 342 343 FX_BOOL CFX_Font::IsItalic() const { 344 if (!m_Face) 345 return FALSE; 346 347 FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC; 348 if (!ret) { 349 CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face)); 350 str.MakeLower(); 351 if (str.Find("italic") != -1) { 352 ret = TRUE; 353 } 354 } 355 return ret; 356 } 357 358 FX_BOOL CFX_Font::IsBold() const { 359 if (!m_Face) 360 return FALSE; 361 return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD; 362 } 363 364 FX_BOOL CFX_Font::IsFixedWidth() const { 365 if (!m_Face) 366 return FALSE; 367 return FXFT_Is_Face_fixedwidth(m_Face); 368 } 369 370 CFX_WideString CFX_Font::GetPsName() const { 371 if (!m_Face) { 372 return CFX_WideString(); 373 } 374 CFX_WideString psName = 375 CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face)); 376 if (psName.IsEmpty()) { 377 psName = CFX_WideString::FromLocal("Untitled"); 378 } 379 return psName; 380 } 381 CFX_ByteString CFX_Font::GetFamilyName() const { 382 if (!m_Face && !m_pSubstFont) { 383 return CFX_ByteString(); 384 } 385 if (m_Face) { 386 return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); 387 } 388 return m_pSubstFont->m_Family; 389 } 390 CFX_ByteString CFX_Font::GetFaceName() const { 391 if (!m_Face && !m_pSubstFont) { 392 return CFX_ByteString(); 393 } 394 if (m_Face) { 395 CFX_ByteString facename; 396 CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face)); 397 facename = GetFamilyName(); 398 if (facename.IsEmpty()) { 399 facename = "Untitled"; 400 } 401 if (!style.IsEmpty() && style != "Regular") { 402 facename += " " + style; 403 } 404 return facename; 405 } 406 return m_pSubstFont->m_Family; 407 } 408 FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) { 409 if (!m_Face) { 410 return FALSE; 411 } 412 int em = FXFT_Get_Face_UnitsPerEM(m_Face); 413 if (em == 0) { 414 bbox.left = FXFT_Get_Face_xMin(m_Face); 415 bbox.bottom = FXFT_Get_Face_yMax(m_Face); 416 bbox.top = FXFT_Get_Face_yMin(m_Face); 417 bbox.right = FXFT_Get_Face_xMax(m_Face); 418 } else { 419 bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em; 420 bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em; 421 bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em; 422 bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em; 423 } 424 return TRUE; 425 } 426 427 int CFX_Font::GetHeight() const { 428 if (!m_Face) 429 return 0; 430 431 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 432 FXFT_Get_Face_Height(m_Face)); 433 } 434 435 int CFX_Font::GetMaxAdvanceWidth() const { 436 if (!m_Face) 437 return 0; 438 439 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 440 FXFT_Get_Face_MaxAdvanceWidth(m_Face)); 441 } 442 443 int CFX_Font::GetULPos() const { 444 if (!m_Face) 445 return 0; 446 447 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 448 FXFT_Get_Face_UnderLinePosition(m_Face)); 449 } 450 451 int CFX_Font::GetULthickness() const { 452 if (!m_Face) 453 return 0; 454 455 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), 456 FXFT_Get_Face_UnderLineThickness(m_Face)); 457 } 458 459 CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont) : m_pFont(pFont) { 460 } 461 462 CFX_UnicodeEncoding::~CFX_UnicodeEncoding() { 463 } 464 465 FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) { 466 FXFT_Face face = m_pFont->GetFace(); 467 if (!face) 468 return charcode; 469 470 if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) 471 return FXFT_Get_Char_Index(face, charcode); 472 473 if (m_pFont->GetSubstFont() && m_pFont->GetSubstFont()->m_Charset == 2) { 474 FX_DWORD index = 0; 475 if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) 476 index = FXFT_Get_Char_Index(face, charcode); 477 if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) 478 return FXFT_Get_Char_Index(face, charcode); 479 } 480 return charcode; 481 } 482 483 #ifdef PDF_ENABLE_XFA 484 CFX_UnicodeEncodingEx::CFX_UnicodeEncodingEx(CFX_Font* pFont, 485 FX_DWORD EncodingID) 486 : CFX_UnicodeEncoding(pFont), m_nEncodingID(EncodingID) { 487 } 488 489 CFX_UnicodeEncodingEx::~CFX_UnicodeEncodingEx() { 490 } 491 492 FX_DWORD CFX_UnicodeEncodingEx::GlyphFromCharCode(FX_DWORD charcode) { 493 FXFT_Face face = m_pFont->GetFace(); 494 FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode); 495 if (nIndex > 0) { 496 return nIndex; 497 } 498 int nmaps = FXFT_Get_Face_CharmapCount(face); 499 int m = 0; 500 while (m < nmaps) { 501 int nEncodingID = 502 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]); 503 if (m_nEncodingID == nEncodingID) { 504 continue; 505 } 506 int error = FXFT_Select_Charmap(face, nEncodingID); 507 if (error) { 508 continue; 509 } 510 nIndex = FXFT_Get_Char_Index(face, charcode); 511 if (nIndex > 0) { 512 m_nEncodingID = nEncodingID; 513 return nIndex; 514 } 515 } 516 FXFT_Select_Charmap(face, m_nEncodingID); 517 return 0; 518 } 519 520 FX_DWORD CFX_UnicodeEncodingEx::CharCodeFromUnicode(FX_WCHAR Unicode) const { 521 if (m_nEncodingID == FXFM_ENCODING_UNICODE || 522 m_nEncodingID == FXFM_ENCODING_MS_SYMBOL) { 523 return Unicode; 524 } 525 FXFT_Face face = m_pFont->GetFace(); 526 int nmaps = FXFT_Get_Face_CharmapCount(face); 527 for (int i = 0; i < nmaps; i++) { 528 int nEncodingID = 529 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]); 530 if (nEncodingID == FXFM_ENCODING_UNICODE || 531 nEncodingID == FXFM_ENCODING_MS_SYMBOL) { 532 return Unicode; 533 } 534 } 535 return -1; 536 } 537 538 CFX_UnicodeEncodingEx* FX_CreateFontEncodingEx(CFX_Font* pFont, 539 FX_DWORD nEncodingID) { 540 if (!pFont || !pFont->GetFace()) 541 return nullptr; 542 543 if (nEncodingID != FXFM_ENCODING_NONE) 544 return _FXFM_CreateFontEncoding(pFont, nEncodingID); 545 546 for (size_t i = 0; i < FX_ArraySize(g_EncodingID); ++i) { 547 CFX_UnicodeEncodingEx* pFontEncoding = 548 _FXFM_CreateFontEncoding(pFont, g_EncodingID[i]); 549 if (pFontEncoding) { 550 return pFontEncoding; 551 } 552 } 553 return NULL; 554 } 555 #endif // PDF_ENABLE_XFA 556