| OLD | NEW |
| (Empty) |
| 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/src/fgas/font/fgas_gefont.h" | |
| 8 | |
| 9 #include "xfa/src/fgas/crt/fgas_codepage.h" | |
| 10 #include "xfa/src/fgas/font/fgas_fontutils.h" | |
| 11 | |
| 12 IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFontFamily, | |
| 13 FX_DWORD dwFontStyles, | |
| 14 FX_WORD wCodePage, | |
| 15 IFX_FontMgr* pFontMgr) { | |
| 16 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 17 if (NULL != pFontMgr) { | |
| 18 return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily); | |
| 19 } | |
| 20 return NULL; | |
| 21 #else | |
| 22 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr); | |
| 23 if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) { | |
| 24 pFont->Release(); | |
| 25 return NULL; | |
| 26 } | |
| 27 return pFont; | |
| 28 #endif | |
| 29 } | |
| 30 IFX_Font* IFX_Font::LoadFont(const uint8_t* pBuffer, | |
| 31 int32_t iLength, | |
| 32 IFX_FontMgr* pFontMgr) { | |
| 33 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 34 if (NULL != pFontMgr) { | |
| 35 return pFontMgr->LoadFont(pBuffer, iLength, 0, NULL); | |
| 36 } | |
| 37 return NULL; | |
| 38 #else | |
| 39 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr); | |
| 40 if (!pFont->LoadFont(pBuffer, iLength)) { | |
| 41 pFont->Release(); | |
| 42 return NULL; | |
| 43 } | |
| 44 return pFont; | |
| 45 #endif | |
| 46 } | |
| 47 IFX_Font* IFX_Font::LoadFont(const FX_WCHAR* pszFileName, | |
| 48 IFX_FontMgr* pFontMgr) { | |
| 49 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 50 if (NULL != pFontMgr) { | |
| 51 return pFontMgr->LoadFont(pszFileName, 0, NULL); | |
| 52 } | |
| 53 return NULL; | |
| 54 #else | |
| 55 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr); | |
| 56 if (!pFont->LoadFont(pszFileName)) { | |
| 57 pFont->Release(); | |
| 58 return NULL; | |
| 59 } | |
| 60 return pFont; | |
| 61 #endif | |
| 62 } | |
| 63 IFX_Font* IFX_Font::LoadFont(IFX_Stream* pFontStream, | |
| 64 IFX_FontMgr* pFontMgr, | |
| 65 FX_BOOL bSaveStream) { | |
| 66 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 67 if (NULL != pFontMgr) { | |
| 68 return pFontMgr->LoadFont(pFontStream, 0, NULL); | |
| 69 } | |
| 70 return NULL; | |
| 71 #else | |
| 72 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr); | |
| 73 if (!pFont->LoadFont(pFontStream, bSaveStream)) { | |
| 74 pFont->Release(); | |
| 75 return NULL; | |
| 76 } | |
| 77 return pFont; | |
| 78 #endif | |
| 79 } | |
| 80 IFX_Font* IFX_Font::LoadFont(CFX_Font* pExtFont, | |
| 81 IFX_FontMgr* pFontMgr, | |
| 82 FX_BOOL bTakeOver) { | |
| 83 CFX_GEFont* pFont = new CFX_GEFont(pFontMgr); | |
| 84 if (!pFont->LoadFont(pExtFont, bTakeOver)) { | |
| 85 pFont->Release(); | |
| 86 return NULL; | |
| 87 } | |
| 88 return pFont; | |
| 89 } | |
| 90 CFX_GEFont::CFX_GEFont(IFX_FontMgr* pFontMgr) | |
| 91 : | |
| 92 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 93 m_bUseLogFontStyle(FALSE), | |
| 94 m_dwLogFontStyle(0), | |
| 95 #endif | |
| 96 m_pFont(NULL), | |
| 97 m_pFontMgr(pFontMgr), | |
| 98 m_iRefCount(1), | |
| 99 m_bExtFont(FALSE), | |
| 100 m_pStream(NULL), | |
| 101 m_pFileRead(NULL), | |
| 102 m_pFontEncoding(NULL), | |
| 103 m_pCharWidthMap(NULL), | |
| 104 m_pRectArray(NULL), | |
| 105 m_pBBoxMap(NULL), | |
| 106 m_pProvider(NULL), | |
| 107 m_wCharSet(0xFFFF), | |
| 108 m_SubstFonts(), | |
| 109 m_FontMapper(16) { | |
| 110 } | |
| 111 | |
| 112 CFX_GEFont::CFX_GEFont(const CFX_GEFont& src, FX_DWORD dwFontStyles) | |
| 113 : | |
| 114 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 115 m_bUseLogFontStyle(FALSE), | |
| 116 m_dwLogFontStyle(0), | |
| 117 #endif | |
| 118 m_pFont(NULL), | |
| 119 m_pFontMgr(src.m_pFontMgr), | |
| 120 m_iRefCount(1), | |
| 121 m_bExtFont(FALSE), | |
| 122 m_pStream(NULL), | |
| 123 m_pFileRead(NULL), | |
| 124 m_pFontEncoding(NULL), | |
| 125 m_pCharWidthMap(NULL), | |
| 126 m_pRectArray(NULL), | |
| 127 m_pBBoxMap(NULL), | |
| 128 m_pProvider(NULL), | |
| 129 m_wCharSet(0xFFFF), | |
| 130 m_SubstFonts(), | |
| 131 m_FontMapper(16) { | |
| 132 m_pFont = new CFX_Font; | |
| 133 FXSYS_assert(m_pFont != NULL); | |
| 134 FXSYS_assert(src.m_pFont != NULL); | |
| 135 m_pFont->LoadClone(src.m_pFont); | |
| 136 CFX_SubstFont* pSubst = m_pFont->GetSubstFont(); | |
| 137 if (!pSubst) { | |
| 138 pSubst = new CFX_SubstFont; | |
| 139 m_pFont->SetSubstFont(pSubst); | |
| 140 } | |
| 141 pSubst->m_Weight = | |
| 142 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; | |
| 143 if (dwFontStyles & FX_FONTSTYLE_Italic) { | |
| 144 pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC; | |
| 145 } | |
| 146 InitFont(); | |
| 147 } | |
| 148 CFX_GEFont::~CFX_GEFont() { | |
| 149 int32_t iCount = m_SubstFonts.GetSize(); | |
| 150 for (int32_t i = 0; i < iCount; i++) { | |
| 151 IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i]; | |
| 152 pFont->Release(); | |
| 153 } | |
| 154 m_SubstFonts.RemoveAll(); | |
| 155 m_FontMapper.RemoveAll(); | |
| 156 if (m_pFileRead != NULL) { | |
| 157 m_pFileRead->Release(); | |
| 158 } | |
| 159 if (m_pStream != NULL) { | |
| 160 m_pStream->Release(); | |
| 161 } | |
| 162 if (m_pFontEncoding != NULL) { | |
| 163 delete m_pFontEncoding; | |
| 164 } | |
| 165 if (m_pCharWidthMap != NULL) { | |
| 166 delete m_pCharWidthMap; | |
| 167 } | |
| 168 if (m_pRectArray != NULL) { | |
| 169 delete m_pRectArray; | |
| 170 } | |
| 171 if (m_pBBoxMap != NULL) { | |
| 172 delete m_pBBoxMap; | |
| 173 } | |
| 174 if (m_pFont != NULL && !m_bExtFont) { | |
| 175 delete m_pFont; | |
| 176 } | |
| 177 } | |
| 178 void CFX_GEFont::Release() { | |
| 179 if (--m_iRefCount < 1) { | |
| 180 if (m_pFontMgr != NULL) { | |
| 181 m_pFontMgr->RemoveFont(this); | |
| 182 } | |
| 183 delete this; | |
| 184 } | |
| 185 } | |
| 186 IFX_Font* CFX_GEFont::Retain() { | |
| 187 ++m_iRefCount; | |
| 188 return this; | |
| 189 } | |
| 190 FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFontFamily, | |
| 191 FX_DWORD dwFontStyles, | |
| 192 FX_WORD wCodePage) { | |
| 193 if (m_pFont) { | |
| 194 return FALSE; | |
| 195 } | |
| 196 CFX_ByteString csFontFamily; | |
| 197 if (pszFontFamily != NULL) { | |
| 198 csFontFamily = CFX_ByteString::FromUnicode(pszFontFamily); | |
| 199 } | |
| 200 FX_DWORD dwFlags = 0; | |
| 201 if (dwFontStyles & FX_FONTSTYLE_FixedPitch) { | |
| 202 dwFlags |= FXFONT_FIXED_PITCH; | |
| 203 } | |
| 204 if (dwFontStyles & FX_FONTSTYLE_Serif) { | |
| 205 dwFlags |= FXFONT_SERIF; | |
| 206 } | |
| 207 if (dwFontStyles & FX_FONTSTYLE_Symbolic) { | |
| 208 dwFlags |= FXFONT_SYMBOLIC; | |
| 209 } | |
| 210 if (dwFontStyles & FX_FONTSTYLE_Script) { | |
| 211 dwFlags |= FXFONT_SCRIPT; | |
| 212 } | |
| 213 if (dwFontStyles & FX_FONTSTYLE_Italic) { | |
| 214 dwFlags |= FXFONT_ITALIC; | |
| 215 } | |
| 216 if (dwFontStyles & FX_FONTSTYLE_Bold) { | |
| 217 dwFlags |= FXFONT_BOLD; | |
| 218 } | |
| 219 if (dwFontStyles & FX_FONTSTYLE_ExactMatch) { | |
| 220 dwFlags |= FXFONT_EXACTMATCH; | |
| 221 } | |
| 222 int32_t iWeight = | |
| 223 (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL; | |
| 224 FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage); | |
| 225 if (wCharSet == 0xFFFF) { | |
| 226 wCharSet = FXSYS_GetACP(); | |
| 227 } | |
| 228 m_wCharSet = wCharSet; | |
| 229 m_pFont = new CFX_Font; | |
| 230 if ((dwFlags & FXFONT_ITALIC) && (dwFlags & FXFONT_BOLD)) { | |
| 231 csFontFamily += ",BoldItalic"; | |
| 232 } else if (dwFlags & FXFONT_BOLD) { | |
| 233 csFontFamily += ",Bold"; | |
| 234 } else if (dwFlags & FXFONT_ITALIC) { | |
| 235 csFontFamily += ",Italic"; | |
| 236 } | |
| 237 m_pFont->LoadSubst(csFontFamily, TRUE, dwFlags, iWeight, 0, wCodePage); | |
| 238 FX_BOOL bRet = m_pFont->GetFace() != nullptr; | |
| 239 if (bRet) { | |
| 240 bRet = InitFont(); | |
| 241 } | |
| 242 return bRet; | |
| 243 } | |
| 244 FX_BOOL CFX_GEFont::LoadFont(const uint8_t* pBuffer, int32_t length) { | |
| 245 if (m_pFont) { | |
| 246 return FALSE; | |
| 247 } | |
| 248 m_pFont = new CFX_Font; | |
| 249 FX_BOOL bRet = m_pFont->LoadEmbedded(pBuffer, length); | |
| 250 if (bRet) { | |
| 251 bRet = InitFont(); | |
| 252 } | |
| 253 m_wCharSet = 0xFFFF; | |
| 254 return bRet; | |
| 255 } | |
| 256 FX_BOOL CFX_GEFont::LoadFont(const FX_WCHAR* pszFileName) { | |
| 257 if (m_pFont || m_pStream || m_pFileRead) { | |
| 258 return FALSE; | |
| 259 } | |
| 260 m_pStream = IFX_Stream::CreateStream( | |
| 261 pszFileName, FX_STREAMACCESS_Binary | FX_STREAMACCESS_Read); | |
| 262 m_pFileRead = FX_CreateFileRead(m_pStream); | |
| 263 FX_BOOL bRet = FALSE; | |
| 264 if (m_pStream && m_pFileRead) { | |
| 265 m_pFont = new CFX_Font; | |
| 266 bRet = m_pFont->LoadFile(m_pFileRead); | |
| 267 if (bRet) { | |
| 268 bRet = InitFont(); | |
| 269 } else { | |
| 270 m_pFileRead->Release(); | |
| 271 m_pFileRead = nullptr; | |
| 272 } | |
| 273 } | |
| 274 m_wCharSet = 0xFFFF; | |
| 275 return bRet; | |
| 276 } | |
| 277 FX_BOOL CFX_GEFont::LoadFont(IFX_Stream* pFontStream, FX_BOOL bSaveStream) { | |
| 278 if (m_pFont || m_pFileRead || !pFontStream || pFontStream->GetLength() < 1) { | |
| 279 return FALSE; | |
| 280 } | |
| 281 if (bSaveStream) { | |
| 282 m_pStream = pFontStream; | |
| 283 } | |
| 284 m_pFileRead = FX_CreateFileRead(pFontStream); | |
| 285 m_pFont = new CFX_Font; | |
| 286 FX_BOOL bRet = m_pFont->LoadFile(m_pFileRead); | |
| 287 if (bRet) { | |
| 288 bRet = InitFont(); | |
| 289 } else { | |
| 290 m_pFileRead->Release(); | |
| 291 m_pFileRead = nullptr; | |
| 292 } | |
| 293 m_wCharSet = 0xFFFF; | |
| 294 return bRet; | |
| 295 } | |
| 296 FX_BOOL CFX_GEFont::LoadFont(CFX_Font* pExtFont, FX_BOOL bTakeOver) { | |
| 297 if (m_pFont || !pExtFont) { | |
| 298 return FALSE; | |
| 299 } | |
| 300 m_pFont = pExtFont; | |
| 301 FX_BOOL bRet = !!m_pFont; | |
| 302 if (bRet) { | |
| 303 m_bExtFont = !bTakeOver; | |
| 304 bRet = InitFont(); | |
| 305 } else { | |
| 306 m_bExtFont = TRUE; | |
| 307 } | |
| 308 m_wCharSet = 0xFFFF; | |
| 309 return bRet; | |
| 310 } | |
| 311 FX_BOOL CFX_GEFont::InitFont() { | |
| 312 if (!m_pFont) { | |
| 313 return FALSE; | |
| 314 } | |
| 315 if (!m_pFontEncoding) { | |
| 316 m_pFontEncoding = FX_CreateFontEncodingEx(m_pFont); | |
| 317 if (!m_pFontEncoding) { | |
| 318 return FALSE; | |
| 319 } | |
| 320 } | |
| 321 if (!m_pCharWidthMap) { | |
| 322 m_pCharWidthMap = new CFX_WordDiscreteArray(1024); | |
| 323 } | |
| 324 if (!m_pRectArray) { | |
| 325 m_pRectArray = new CFX_RectMassArray(16); | |
| 326 } | |
| 327 if (!m_pBBoxMap) { | |
| 328 m_pBBoxMap = new CFX_MapPtrToPtr(16); | |
| 329 } | |
| 330 return TRUE; | |
| 331 } | |
| 332 IFX_Font* CFX_GEFont::Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage) { | |
| 333 if (GetFontStyles() == dwFontStyles) { | |
| 334 return Retain(); | |
| 335 } | |
| 336 return new CFX_GEFont(*this, dwFontStyles); | |
| 337 } | |
| 338 uint8_t CFX_GEFont::GetCharSet() const { | |
| 339 if (m_wCharSet != 0xFFFF) { | |
| 340 return (uint8_t)m_wCharSet; | |
| 341 } | |
| 342 if (!m_pFont->GetSubstFont()) { | |
| 343 return FX_CHARSET_Default; | |
| 344 } | |
| 345 return m_pFont->GetSubstFont()->m_Charset; | |
| 346 } | |
| 347 void CFX_GEFont::GetFamilyName(CFX_WideString& wsFamily) const { | |
| 348 if (!m_pFont->GetSubstFont() || | |
| 349 m_pFont->GetSubstFont()->m_Family.GetLength() == 0) { | |
| 350 wsFamily = CFX_WideString::FromLocal(m_pFont->GetFamilyName()); | |
| 351 } else { | |
| 352 wsFamily = CFX_WideString::FromLocal(m_pFont->GetSubstFont()->m_Family); | |
| 353 } | |
| 354 } | |
| 355 void CFX_GEFont::GetPsName(CFX_WideString& wsName) const { | |
| 356 wsName = m_pFont->GetPsName(); | |
| 357 } | |
| 358 FX_DWORD CFX_GEFont::GetFontStyles() const { | |
| 359 FXSYS_assert(m_pFont != NULL); | |
| 360 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ | |
| 361 if (m_bUseLogFontStyle) { | |
| 362 return m_dwLogFontStyle; | |
| 363 } | |
| 364 #endif | |
| 365 FX_DWORD dwStyles = 0; | |
| 366 if (!m_pFont->GetSubstFont()) { | |
| 367 if (m_pFont->IsBold()) { | |
| 368 dwStyles |= FX_FONTSTYLE_Bold; | |
| 369 } | |
| 370 if (m_pFont->IsItalic()) { | |
| 371 dwStyles |= FX_FONTSTYLE_Italic; | |
| 372 } | |
| 373 } else { | |
| 374 if (m_pFont->GetSubstFont()->m_Weight == FXFONT_FW_BOLD) { | |
| 375 dwStyles |= FX_FONTSTYLE_Bold; | |
| 376 } | |
| 377 if (m_pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_ITALIC) { | |
| 378 dwStyles |= FX_FONTSTYLE_Italic; | |
| 379 } | |
| 380 } | |
| 381 return dwStyles; | |
| 382 } | |
| 383 FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode, | |
| 384 int32_t& iWidth, | |
| 385 FX_BOOL bCharCode) { | |
| 386 return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode); | |
| 387 } | |
| 388 FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode, | |
| 389 int32_t& iWidth, | |
| 390 FX_BOOL bRecursive, | |
| 391 FX_BOOL bCharCode) { | |
| 392 FXSYS_assert(m_pCharWidthMap != NULL); | |
| 393 iWidth = m_pCharWidthMap->GetAt(wUnicode, 0); | |
| 394 if (iWidth < 1) { | |
| 395 if (!m_pProvider || | |
| 396 !m_pProvider->GetCharWidth(this, wUnicode, iWidth, bCharCode)) { | |
| 397 IFX_Font* pFont = NULL; | |
| 398 int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode); | |
| 399 if (iGlyph != 0xFFFF && pFont != NULL) { | |
| 400 if (pFont == (IFX_Font*)this) { | |
| 401 iWidth = m_pFont->GetGlyphWidth(iGlyph); | |
| 402 if (iWidth < 0) { | |
| 403 iWidth = -1; | |
| 404 } | |
| 405 } else if (((CFX_GEFont*)pFont) | |
| 406 ->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) { | |
| 407 return TRUE; | |
| 408 } | |
| 409 } else { | |
| 410 iWidth = -1; | |
| 411 } | |
| 412 } | |
| 413 m_pCharWidthMap->SetAtGrow(wUnicode, (int16_t)iWidth); | |
| 414 } else if (iWidth == 65535) { | |
| 415 iWidth = -1; | |
| 416 } | |
| 417 return iWidth > 0; | |
| 418 } | |
| 419 FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode, | |
| 420 CFX_Rect& bbox, | |
| 421 FX_BOOL bCharCode) { | |
| 422 return GetCharBBox(wUnicode, bbox, TRUE, bCharCode); | |
| 423 } | |
| 424 FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode, | |
| 425 CFX_Rect& bbox, | |
| 426 FX_BOOL bRecursive, | |
| 427 FX_BOOL bCharCode) { | |
| 428 FXSYS_assert(m_pRectArray != NULL); | |
| 429 FXSYS_assert(m_pBBoxMap != NULL); | |
| 430 void* pRect = NULL; | |
| 431 if (!m_pBBoxMap->Lookup((void*)(uintptr_t)wUnicode, pRect)) { | |
| 432 IFX_Font* pFont = NULL; | |
| 433 int32_t iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode); | |
| 434 if (iGlyph != 0xFFFF && pFont != NULL) { | |
| 435 if (pFont == (IFX_Font*)this) { | |
| 436 FX_RECT rtBBox; | |
| 437 if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) { | |
| 438 CFX_Rect rt; | |
| 439 rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height()); | |
| 440 int32_t index = m_pRectArray->Add(rt); | |
| 441 pRect = m_pRectArray->GetPtrAt(index); | |
| 442 m_pBBoxMap->SetAt((void*)(uintptr_t)wUnicode, pRect); | |
| 443 } | |
| 444 } else if (((CFX_GEFont*)pFont) | |
| 445 ->GetCharBBox(wUnicode, bbox, FALSE, bCharCode)) { | |
| 446 return TRUE; | |
| 447 } | |
| 448 } | |
| 449 } | |
| 450 if (!pRect) | |
| 451 return FALSE; | |
| 452 | |
| 453 bbox = *static_cast<const CFX_Rect*>(pRect); | |
| 454 return TRUE; | |
| 455 } | |
| 456 FX_BOOL CFX_GEFont::GetBBox(CFX_Rect& bbox) { | |
| 457 FX_RECT rt(0, 0, 0, 0); | |
| 458 FX_BOOL bRet = m_pFont->GetBBox(rt); | |
| 459 if (bRet) { | |
| 460 bbox.left = rt.left; | |
| 461 bbox.width = rt.Width(); | |
| 462 bbox.top = rt.bottom; | |
| 463 bbox.height = -rt.Height(); | |
| 464 } | |
| 465 return bRet; | |
| 466 } | |
| 467 int32_t CFX_GEFont::GetItalicAngle() const { | |
| 468 if (!m_pFont->GetSubstFont()) { | |
| 469 return 0; | |
| 470 } | |
| 471 return m_pFont->GetSubstFont()->m_ItalicAngle; | |
| 472 } | |
| 473 int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode) { | |
| 474 return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode); | |
| 475 } | |
| 476 int32_t CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, | |
| 477 FX_BOOL bRecursive, | |
| 478 IFX_Font** ppFont, | |
| 479 FX_BOOL bCharCode) { | |
| 480 FXSYS_assert(m_pFontEncoding != NULL); | |
| 481 int32_t iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode); | |
| 482 if (iGlyphIndex > 0) { | |
| 483 if (ppFont != NULL) { | |
| 484 *ppFont = (IFX_Font*)this; | |
| 485 } | |
| 486 return iGlyphIndex; | |
| 487 } | |
| 488 const FGAS_FONTUSB* pFontUSB = FGAS_GetUnicodeBitField(wUnicode); | |
| 489 if (pFontUSB == NULL) { | |
| 490 return 0xFFFF; | |
| 491 } | |
| 492 FX_WORD wBitField = pFontUSB->wBitField; | |
| 493 if (wBitField >= 128) { | |
| 494 return 0xFFFF; | |
| 495 } | |
| 496 IFX_Font* pFont = NULL; | |
| 497 m_FontMapper.Lookup((void*)(uintptr_t)wUnicode, (void*&)pFont); | |
| 498 if (pFont != NULL && pFont != (IFX_Font*)this) { | |
| 499 iGlyphIndex = | |
| 500 ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode); | |
| 501 if (iGlyphIndex != 0xFFFF) { | |
| 502 int32_t i = m_SubstFonts.Find(pFont); | |
| 503 if (i > -1) { | |
| 504 iGlyphIndex |= ((i + 1) << 24); | |
| 505 if (ppFont != NULL) { | |
| 506 *ppFont = pFont; | |
| 507 } | |
| 508 return iGlyphIndex; | |
| 509 } | |
| 510 } | |
| 511 } | |
| 512 if (m_pFontMgr != NULL && bRecursive) { | |
| 513 CFX_WideString wsFamily; | |
| 514 GetFamilyName(wsFamily); | |
| 515 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | |
| 516 IFX_Font* pFont = m_pFontMgr->GetDefFontByUnicode( | |
| 517 wUnicode, GetFontStyles(), (const FX_WCHAR*)wsFamily); | |
| 518 #else | |
| 519 IFX_Font* pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), | |
| 520 (const FX_WCHAR*)wsFamily); | |
| 521 if (NULL == pFont) { | |
| 522 pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), NULL); | |
| 523 } | |
| 524 #endif | |
| 525 if (pFont != NULL) { | |
| 526 if (pFont == (IFX_Font*)this) { | |
| 527 pFont->Release(); | |
| 528 return 0xFFFF; | |
| 529 } | |
| 530 m_FontMapper.SetAt((void*)(uintptr_t)wUnicode, (void*)pFont); | |
| 531 int32_t i = m_SubstFonts.GetSize(); | |
| 532 m_SubstFonts.Add(pFont); | |
| 533 iGlyphIndex = | |
| 534 ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode); | |
| 535 if (iGlyphIndex != 0xFFFF) { | |
| 536 iGlyphIndex |= ((i + 1) << 24); | |
| 537 if (ppFont != NULL) { | |
| 538 *ppFont = pFont; | |
| 539 } | |
| 540 return iGlyphIndex; | |
| 541 } | |
| 542 } | |
| 543 } | |
| 544 return 0xFFFF; | |
| 545 } | |
| 546 int32_t CFX_GEFont::GetAscent() const { | |
| 547 return m_pFont->GetAscent(); | |
| 548 } | |
| 549 int32_t CFX_GEFont::GetDescent() const { | |
| 550 return m_pFont->GetDescent(); | |
| 551 } | |
| 552 void CFX_GEFont::Reset() { | |
| 553 int32_t iCount = m_SubstFonts.GetSize(); | |
| 554 for (int32_t i = 0; i < iCount; i++) { | |
| 555 IFX_Font* pFont = (IFX_Font*)m_SubstFonts[i]; | |
| 556 ((CFX_GEFont*)pFont)->Reset(); | |
| 557 } | |
| 558 if (m_pCharWidthMap != NULL) { | |
| 559 m_pCharWidthMap->RemoveAll(); | |
| 560 } | |
| 561 if (m_pBBoxMap != NULL) { | |
| 562 m_pBBoxMap->RemoveAll(); | |
| 563 } | |
| 564 if (m_pRectArray != NULL) { | |
| 565 m_pRectArray->RemoveAll(); | |
| 566 } | |
| 567 } | |
| 568 IFX_Font* CFX_GEFont::GetSubstFont(int32_t iGlyphIndex) const { | |
| 569 iGlyphIndex = ((FX_DWORD)iGlyphIndex) >> 24; | |
| 570 return iGlyphIndex == 0 ? (IFX_Font*)this | |
| 571 : (IFX_Font*)m_SubstFonts[iGlyphIndex - 1]; | |
| 572 } | |
| OLD | NEW |