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 "xfa/fgas/font/cfgas_gefont.h" 8 9 #include <memory> 10 #include <utility> 11 12 #include "core/fxge/cfx_substfont.h" 13 #include "core/fxge/cfx_unicodeencoding.h" 14 #include "core/fxge/cfx_unicodeencodingex.h" 15 #include "third_party/base/ptr_util.h" 16 #include "xfa/fgas/crt/fgas_codepage.h" 17 #include "xfa/fgas/font/fgas_fontutils.h" 18 #include "xfa/fxfa/xfa_fontmgr.h" 19 20 // static 21 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( 22 const FX_WCHAR* pszFontFamily, 23 uint32_t dwFontStyles, 24 uint16_t wCodePage, 25 CFGAS_FontMgr* pFontMgr) { 26 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 27 if (!pFontMgr) 28 return nullptr; 29 30 return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); 31 #else 32 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); 33 if (!pFont->LoadFontInternal(pszFontFamily, dwFontStyles, wCodePage)) 34 return nullptr; 35 return pFont; 36 #endif 37 } 38 39 // static 40 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(CFX_Font* pExternalFont, 41 CFGAS_FontMgr* pFontMgr) { 42 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); 43 if (!pFont->LoadFontInternal(pExternalFont)) 44 return nullptr; 45 return pFont; 46 } 47 48 // static 49 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( 50 std::unique_ptr<CFX_Font> pInternalFont, 51 CFGAS_FontMgr* pFontMgr) { 52 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); 53 if (!pFont->LoadFontInternal(std::move(pInternalFont))) 54 return nullptr; 55 return pFont; 56 } 57 58 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 59 // static 60 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont(const uint8_t* pBuffer, 61 int32_t iLength, 62 CFGAS_FontMgr* pFontMgr) { 63 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); 64 if (pFont->LoadFontInternal(pBuffer, iLength)) 65 return nullptr; 66 return pFont; 67 } 68 69 // static 70 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::LoadFont( 71 const CFX_RetainPtr<IFGAS_Stream>& pFontStream, 72 CFGAS_FontMgr* pFontMgr, 73 bool bSaveStream) { 74 auto pFont = pdfium::MakeRetain<CFGAS_GEFont>(pFontMgr); 75 if (!pFont->LoadFontInternal(pFontStream, bSaveStream)) 76 return nullptr; 77 return pFont; 78 } 79 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 80 81 CFGAS_GEFont::CFGAS_GEFont(CFGAS_FontMgr* pFontMgr) 82 : 83 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 84 m_bUseLogFontStyle(false), 85 m_dwLogFontStyle(0), 86 #endif 87 m_pFont(nullptr), 88 m_pFontMgr(pFontMgr), 89 m_bExternalFont(false), 90 m_pProvider(nullptr) { 91 } 92 93 CFGAS_GEFont::CFGAS_GEFont(const CFX_RetainPtr<CFGAS_GEFont>& src, 94 uint32_t dwFontStyles) 95 : 96 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 97 m_bUseLogFontStyle(false), 98 m_dwLogFontStyle(0), 99 #endif 100 m_pFont(nullptr), 101 m_pSrcFont(src), 102 m_pFontMgr(src->m_pFontMgr), 103 m_bExternalFont(false), 104 m_pProvider(nullptr) { 105 ASSERT(m_pSrcFont->m_pFont); 106 m_pFont = new CFX_Font; 107 m_pFont->LoadClone(m_pSrcFont->m_pFont); 108 CFX_SubstFont* pSubst = m_pFont->GetSubstFont(); 109 if (!pSubst) { 110 pSubst = new CFX_SubstFont; 111 m_pFont->SetSubstFont(std::unique_ptr<CFX_SubstFont>(pSubst)); 112 } 113 pSubst->m_Weight = 114 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; 115 if (dwFontStyles & FX_FONTSTYLE_Italic) 116 pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC; 117 InitFont(); 118 } 119 120 CFGAS_GEFont::~CFGAS_GEFont() { 121 if (!m_bExternalFont) 122 delete m_pFont; 123 } 124 125 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 126 bool CFGAS_GEFont::LoadFontInternal(const FX_WCHAR* pszFontFamily, 127 uint32_t dwFontStyles, 128 uint16_t wCodePage) { 129 if (m_pFont) 130 return false; 131 CFX_ByteString csFontFamily; 132 if (pszFontFamily) 133 csFontFamily = CFX_ByteString::FromUnicode(pszFontFamily); 134 uint32_t dwFlags = 0; 135 if (dwFontStyles & FX_FONTSTYLE_FixedPitch) 136 dwFlags |= FXFONT_FIXED_PITCH; 137 if (dwFontStyles & FX_FONTSTYLE_Serif) 138 dwFlags |= FXFONT_SERIF; 139 if (dwFontStyles & FX_FONTSTYLE_Symbolic) 140 dwFlags |= FXFONT_SYMBOLIC; 141 if (dwFontStyles & FX_FONTSTYLE_Script) 142 dwFlags |= FXFONT_SCRIPT; 143 if (dwFontStyles & FX_FONTSTYLE_Italic) 144 dwFlags |= FXFONT_ITALIC; 145 if (dwFontStyles & FX_FONTSTYLE_Bold) 146 dwFlags |= FXFONT_BOLD; 147 if (dwFontStyles & FX_FONTSTYLE_ExactMatch) 148 dwFlags |= FXFONT_EXACTMATCH; 149 int32_t iWeight = 150 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; 151 m_pFont = new CFX_Font; 152 if ((dwFlags & FXFONT_ITALIC) && (dwFlags & FXFONT_BOLD)) 153 csFontFamily += ",BoldItalic"; 154 else if (dwFlags & FXFONT_BOLD) 155 csFontFamily += ",Bold"; 156 else if (dwFlags & FXFONT_ITALIC) 157 csFontFamily += ",Italic"; 158 m_pFont->LoadSubst(csFontFamily, true, dwFlags, iWeight, 0, wCodePage, false); 159 if (!m_pFont->GetFace()) 160 return false; 161 return InitFont(); 162 } 163 164 bool CFGAS_GEFont::LoadFontInternal(const uint8_t* pBuffer, int32_t length) { 165 if (m_pFont) 166 return false; 167 168 m_pFont = new CFX_Font; 169 if (!m_pFont->LoadEmbedded(pBuffer, length)) 170 return false; 171 return InitFont(); 172 } 173 174 bool CFGAS_GEFont::LoadFontInternal( 175 const CFX_RetainPtr<IFGAS_Stream>& pFontStream, 176 bool bSaveStream) { 177 if (m_pFont || m_pFileRead || !pFontStream || pFontStream->GetLength() < 1) 178 return false; 179 if (bSaveStream) 180 m_pStream = pFontStream; 181 182 m_pFileRead = pFontStream->MakeSeekableReadStream(); 183 m_pFont = new CFX_Font; 184 if (!m_pFont->LoadFile(m_pFileRead)) { 185 m_pFileRead.Reset(); 186 return false; 187 } 188 return InitFont(); 189 } 190 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 191 192 bool CFGAS_GEFont::LoadFontInternal(CFX_Font* pExternalFont) { 193 if (m_pFont || !pExternalFont) 194 return false; 195 196 m_pFont = pExternalFont; 197 m_bExternalFont = true; 198 return InitFont(); 199 } 200 201 bool CFGAS_GEFont::LoadFontInternal(std::unique_ptr<CFX_Font> pInternalFont) { 202 if (m_pFont || !pInternalFont) 203 return false; 204 205 m_pFont = pInternalFont.release(); 206 m_bExternalFont = false; 207 return InitFont(); 208 } 209 210 bool CFGAS_GEFont::InitFont() { 211 if (!m_pFont) 212 return false; 213 214 if (!m_pFontEncoding) { 215 m_pFontEncoding.reset(FX_CreateFontEncodingEx(m_pFont)); 216 if (!m_pFontEncoding) 217 return false; 218 } 219 if (!m_pCharWidthMap) { 220 m_pCharWidthMap = 221 pdfium::MakeUnique<CFX_DiscreteArrayTemplate<uint16_t>>(1024); 222 } 223 return true; 224 } 225 226 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::Derive(uint32_t dwFontStyles, 227 uint16_t wCodePage) { 228 CFX_RetainPtr<CFGAS_GEFont> pFont(this); 229 if (GetFontStyles() == dwFontStyles) 230 return pFont; 231 return pdfium::MakeRetain<CFGAS_GEFont>(pFont, dwFontStyles); 232 } 233 234 CFX_WideString CFGAS_GEFont::GetFamilyName() const { 235 if (!m_pFont->GetSubstFont() || 236 m_pFont->GetSubstFont()->m_Family.GetLength() == 0) { 237 return CFX_WideString::FromLocal(m_pFont->GetFamilyName().AsStringC()); 238 } 239 return CFX_WideString::FromLocal( 240 m_pFont->GetSubstFont()->m_Family.AsStringC()); 241 } 242 243 uint32_t CFGAS_GEFont::GetFontStyles() const { 244 ASSERT(m_pFont); 245 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 246 if (m_bUseLogFontStyle) 247 return m_dwLogFontStyle; 248 #endif 249 250 uint32_t dwStyles = 0; 251 auto* pSubstFont = m_pFont->GetSubstFont(); 252 if (pSubstFont) { 253 if (pSubstFont->m_Weight == FXFONT_FW_BOLD) 254 dwStyles |= FX_FONTSTYLE_Bold; 255 if (pSubstFont->m_SubstFlags & FXFONT_SUBST_ITALIC) 256 dwStyles |= FX_FONTSTYLE_Italic; 257 } else { 258 if (m_pFont->IsBold()) 259 dwStyles |= FX_FONTSTYLE_Bold; 260 if (m_pFont->IsItalic()) 261 dwStyles |= FX_FONTSTYLE_Italic; 262 } 263 return dwStyles; 264 } 265 266 bool CFGAS_GEFont::GetCharWidth(FX_WCHAR wUnicode, 267 int32_t& iWidth, 268 bool bCharCode) { 269 return GetCharWidthInternal(wUnicode, iWidth, true, bCharCode); 270 } 271 272 bool CFGAS_GEFont::GetCharWidthInternal(FX_WCHAR wUnicode, 273 int32_t& iWidth, 274 bool bRecursive, 275 bool bCharCode) { 276 ASSERT(m_pCharWidthMap); 277 iWidth = m_pCharWidthMap->GetAt(wUnicode, 0); 278 if (iWidth == 65535) 279 return false; 280 281 if (iWidth > 0) 282 return true; 283 284 if (!m_pProvider || 285 !m_pProvider->GetCharWidth(CFX_RetainPtr<CFGAS_GEFont>(this), wUnicode, 286 bCharCode, &iWidth)) { 287 CFX_RetainPtr<CFGAS_GEFont> pFont; 288 int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); 289 if (iGlyph != 0xFFFF && pFont) { 290 if (pFont.Get() == this) { 291 iWidth = m_pFont->GetGlyphWidth(iGlyph); 292 if (iWidth < 0) 293 iWidth = -1; 294 } else if (pFont->GetCharWidthInternal(wUnicode, iWidth, false, 295 bCharCode)) { 296 return true; 297 } 298 } else { 299 iWidth = -1; 300 } 301 } 302 m_pCharWidthMap->SetAtGrow(wUnicode, iWidth); 303 return iWidth > 0; 304 } 305 306 bool CFGAS_GEFont::GetCharBBox(FX_WCHAR wUnicode, 307 CFX_Rect* bbox, 308 bool bCharCode) { 309 return GetCharBBoxInternal(wUnicode, bbox, true, bCharCode); 310 } 311 312 bool CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode, 313 CFX_Rect* bbox, 314 bool bRecursive, 315 bool bCharCode) { 316 auto it = m_BBoxMap.find(wUnicode); 317 if (it != m_BBoxMap.end()) { 318 *bbox = it->second; 319 return true; 320 } 321 322 CFX_RetainPtr<CFGAS_GEFont> pFont; 323 int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); 324 if (!pFont || iGlyph == 0xFFFF) 325 return false; 326 327 if (pFont.Get() != this) 328 return pFont->GetCharBBoxInternal(wUnicode, bbox, false, bCharCode); 329 330 FX_RECT rtBBox; 331 if (!m_pFont->GetGlyphBBox(iGlyph, rtBBox)) 332 return false; 333 334 CFX_Rect rt(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height()); 335 m_BBoxMap[wUnicode] = rt; 336 *bbox = rt; 337 return true; 338 } 339 340 bool CFGAS_GEFont::GetBBox(CFX_Rect* bbox) { 341 FX_RECT rt(0, 0, 0, 0); 342 if (!m_pFont->GetBBox(rt)) 343 return false; 344 345 bbox->left = rt.left; 346 bbox->width = rt.Width(); 347 bbox->top = rt.bottom; 348 bbox->height = -rt.Height(); 349 return true; 350 } 351 352 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, bool bCharCode) { 353 return GetGlyphIndex(wUnicode, true, nullptr, bCharCode); 354 } 355 356 int32_t CFGAS_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, 357 bool bRecursive, 358 CFX_RetainPtr<CFGAS_GEFont>* ppFont, 359 bool bCharCode) { 360 int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode); 361 if (iGlyphIndex > 0) { 362 if (ppFont) 363 ppFont->Reset(this); 364 return iGlyphIndex; 365 } 366 const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode); 367 if (!pFontUSB) 368 return 0xFFFF; 369 370 uint16_t wBitField = pFontUSB->wBitField; 371 if (wBitField >= 128) 372 return 0xFFFF; 373 374 auto it = m_FontMapper.find(wUnicode); 375 if (it != m_FontMapper.end() && it->second && it->second.Get() != this) { 376 iGlyphIndex = 377 it->second->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); 378 if (iGlyphIndex != 0xFFFF) { 379 for (size_t i = 0; i < m_SubstFonts.size(); ++i) { 380 if (m_SubstFonts[i] == it->second) { 381 if (ppFont) 382 *ppFont = it->second; 383 return (iGlyphIndex | ((i + 1) << 24)); 384 } 385 } 386 } 387 } 388 if (!m_pFontMgr || !bRecursive) 389 return 0xFFFF; 390 391 CFX_WideString wsFamily = GetFamilyName(); 392 CFX_RetainPtr<CFGAS_GEFont> pFont = 393 m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), wsFamily.c_str()); 394 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 395 if (!pFont) 396 pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), nullptr); 397 #endif 398 if (!pFont || pFont.Get() == this) // Avoids direct cycles below. 399 return 0xFFFF; 400 401 m_FontMapper[wUnicode] = pFont; 402 m_SubstFonts.push_back(pFont); 403 iGlyphIndex = pFont->GetGlyphIndex(wUnicode, false, nullptr, bCharCode); 404 if (iGlyphIndex == 0xFFFF) 405 return 0xFFFF; 406 407 if (ppFont) 408 *ppFont = pFont; 409 return (iGlyphIndex | (m_SubstFonts.size() << 24)); 410 } 411 412 int32_t CFGAS_GEFont::GetAscent() const { 413 return m_pFont->GetAscent(); 414 } 415 416 int32_t CFGAS_GEFont::GetDescent() const { 417 return m_pFont->GetDescent(); 418 } 419 420 CFX_RetainPtr<CFGAS_GEFont> CFGAS_GEFont::GetSubstFont(int32_t iGlyphIndex) { 421 iGlyphIndex = static_cast<uint32_t>(iGlyphIndex) >> 24; 422 if (iGlyphIndex == 0) 423 return CFX_RetainPtr<CFGAS_GEFont>(this); 424 return m_SubstFonts[iGlyphIndex - 1]; 425 } 426