ULONG GetBestFontAttributes(IDWriteFontCollection* fontCollection, const WCHAR* fontFamilyName, const FontFaceInfo& desiredAttributes) { DWRITE_FONT_WEIGHT fontWeight = desiredAttributes.fontWeight; DWRITE_FONT_STYLE fontStyle = desiredAttributes.fontStyle; DWRITE_FONT_STRETCH fontStretch = desiredAttributes.fontStretch; IDWriteFontFamily* fontFamily = NULL; IDWriteFont* font = NULL; if (SUCCEEDED(GetFontFamily(fontCollection, fontFamilyName, &fontFamily))) { if (SUCCEEDED(fontFamily->GetFirstMatchingFont(fontWeight, fontStretch, fontStyle, &font))) { fontWeight = font->GetWeight(); fontStyle = font->GetStyle(); fontStretch = font->GetStretch(); } } SafeRelease(&font); SafeRelease(&fontFamily); FontFaceInfo fontFaceInfo(L"", fontWeight, fontStyle, fontStretch); return fontFaceInfo.PackedFontAttributes(); }
/* * Extract a TEStyle object from the buffer. */ void RStyleBlock::TEStyle::Create(const uint8_t* buf) { fFontID = Reformat::Get32LE(buf); fForeColor = Reformat::Get16LE(buf + 4); fBackColor = Reformat::Get16LE(buf + 6); fUserData = Reformat::Get32LE(buf + 8); LOGI(" TEStyle: font fam=0x%04x size=%-2d style=0x%02x fore=0x%04x", GetFontFamily(), GetFontSize(), GetTextStyle(), fForeColor); }
// Create font from font attributes. wxFont wxTextAttr::GetFont() const { if ( !HasFont() ) return wxNullFont; int fontSize = 10; if (HasFontSize()) fontSize = GetFontSize(); wxFontStyle fontStyle = wxFONTSTYLE_NORMAL; if (HasFontItalic()) fontStyle = GetFontStyle(); wxFontWeight fontWeight = wxFONTWEIGHT_NORMAL; if (HasFontWeight()) fontWeight = GetFontWeight(); bool underlined = false; if (HasFontUnderlined()) underlined = GetFontUnderlined(); bool strikethrough = false; if (HasFontStrikethrough()) strikethrough = GetFontStrikethrough(); wxString fontFaceName; if (HasFontFaceName()) fontFaceName = GetFontFaceName(); wxFontEncoding encoding = wxFONTENCODING_DEFAULT; if (HasFontEncoding()) encoding = GetFontEncoding(); wxFontFamily fontFamily = wxFONTFAMILY_DEFAULT; if (HasFontFamily()) fontFamily = GetFontFamily(); if (HasFontPixelSize()) { wxFont font(wxSize(0, fontSize), fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding); if (strikethrough) font.SetStrikethrough(true); return font; } else { wxFont font(fontSize, fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding); if (strikethrough) font.SetStrikethrough(true); return font; } }
// Equality test bool wxTextAttr::operator== (const wxTextAttr& attr) const { return GetFlags() == attr.GetFlags() && (!HasTextColour() || (GetTextColour() == attr.GetTextColour())) && (!HasBackgroundColour() || (GetBackgroundColour() == attr.GetBackgroundColour())) && (!HasAlignment() || (GetAlignment() == attr.GetAlignment())) && (!HasLeftIndent() || (GetLeftIndent() == attr.GetLeftIndent() && GetLeftSubIndent() == attr.GetLeftSubIndent())) && (!HasRightIndent() || (GetRightIndent() == attr.GetRightIndent())) && (!HasTabs() || (TabsEq(GetTabs(), attr.GetTabs()))) && (!HasParagraphSpacingAfter() || (GetParagraphSpacingAfter() == attr.GetParagraphSpacingAfter())) && (!HasParagraphSpacingBefore() || (GetParagraphSpacingBefore() == attr.GetParagraphSpacingBefore())) && (!HasLineSpacing() || (GetLineSpacing() == attr.GetLineSpacing())) && (!HasCharacterStyleName() || (GetCharacterStyleName() == attr.GetCharacterStyleName())) && (!HasParagraphStyleName() || (GetParagraphStyleName() == attr.GetParagraphStyleName())) && (!HasListStyleName() || (GetListStyleName() == attr.GetListStyleName())) && (!HasBulletStyle() || (GetBulletStyle() == attr.GetBulletStyle())) && (!HasBulletText() || (GetBulletText() == attr.GetBulletText())) && (!HasBulletNumber() || (GetBulletNumber() == attr.GetBulletNumber())) && (GetBulletFont() == attr.GetBulletFont()) && (!HasBulletName() || (GetBulletName() == attr.GetBulletName())) && (!HasTextEffects() || (GetTextEffects() == attr.GetTextEffects() && GetTextEffectFlags() == attr.GetTextEffectFlags())) && (!HasOutlineLevel() || (GetOutlineLevel() == attr.GetOutlineLevel())) && (!HasFontSize() || (GetFontSize() == attr.GetFontSize())) && (!HasFontItalic() || (GetFontStyle() == attr.GetFontStyle())) && (!HasFontWeight() || (GetFontWeight() == attr.GetFontWeight())) && (!HasFontUnderlined() || (GetFontUnderlined() == attr.GetFontUnderlined())) && (!HasFontStrikethrough() || (GetFontStrikethrough() == attr.GetFontStrikethrough())) && (!HasFontFaceName() || (GetFontFaceName() == attr.GetFontFaceName())) && (!HasFontEncoding() || (GetFontEncoding() == attr.GetFontEncoding())) && (!HasFontFamily() || (GetFontFamily() == attr.GetFontFamily())) && (!HasURL() || (GetURL() == attr.GetURL())); }
HRESULT GetFonts(IDWriteFontCollection* fontCollection, const WCHAR* fontFamilyName, IN OUT std::vector<IDWriteFont*>& fonts) { HRESULT hr = S_OK; IDWriteFontFamily* fontFamily = NULL; IDWriteFont* font = NULL; hr = GetFontFamily(fontCollection, fontFamilyName, &fontFamily); if (SUCCEEDED(hr)) { UINT32 fontCount = fontFamily->GetFontCount(); // Read font variant in the family. try { for (UINT32 i = 0; i != fontCount; ++i) { hr = fontFamily->GetFont(i, &font); if (FAILED(hr)) break; fonts.push_back(font); SafeDetach(&font); } } catch (...) { hr = ExceptionToHResult(); } } SafeRelease(&font); SafeRelease(&fontFamily); return hr; }
// Create font from font attributes. wxFont wxTextAttr::GetFont() const { if ( !HasFont() ) return wxNullFont; int fontSize = 10; if (HasFontSize()) fontSize = GetFontSize(); int fontStyle = wxNORMAL; if (HasFontItalic()) fontStyle = GetFontStyle(); int fontWeight = wxNORMAL; if (HasFontWeight()) fontWeight = GetFontWeight(); bool underlined = false; if (HasFontUnderlined()) underlined = GetFontUnderlined(); wxString fontFaceName; if (HasFontFaceName()) fontFaceName = GetFontFaceName(); wxFontEncoding encoding = wxFONTENCODING_DEFAULT; if (HasFontEncoding()) encoding = GetFontEncoding(); int fontFamily = wxFONTFAMILY_DEFAULT; if (HasFontFamily()) fontFamily = GetFontFamily(); wxFont font(fontSize, fontFamily, fontStyle, fontWeight, underlined, fontFaceName, encoding); return font; }
// Partial equality test taking flags into account bool wxTextAttr::EqPartial(const wxTextAttr& attr, int flags) const { if ((flags & wxTEXT_ATTR_TEXT_COLOUR) && GetTextColour() != attr.GetTextColour()) return false; if ((flags & wxTEXT_ATTR_BACKGROUND_COLOUR) && GetBackgroundColour() != attr.GetBackgroundColour()) return false; if ((flags & wxTEXT_ATTR_FONT_FACE) && GetFontFaceName() != attr.GetFontFaceName()) return false; if ((flags & wxTEXT_ATTR_FONT_SIZE) && GetFontSize() != attr.GetFontSize()) return false; if ((flags & wxTEXT_ATTR_FONT_WEIGHT) && GetFontWeight() != attr.GetFontWeight()) return false; if ((flags & wxTEXT_ATTR_FONT_ITALIC) && GetFontStyle() != attr.GetFontStyle()) return false; if ((flags & wxTEXT_ATTR_FONT_UNDERLINE) && GetFontUnderlined() != attr.GetFontUnderlined()) return false; if ((flags & wxTEXT_ATTR_FONT_ENCODING) && GetFontEncoding() != attr.GetFontEncoding()) return false; if ((flags & wxTEXT_ATTR_FONT_FAMILY) && GetFontFamily() != attr.GetFontFamily()) return false; if ((flags & wxTEXT_ATTR_URL) && GetURL() != attr.GetURL()) return false; if ((flags & wxTEXT_ATTR_ALIGNMENT) && GetAlignment() != attr.GetAlignment()) return false; if ((flags & wxTEXT_ATTR_LEFT_INDENT) && ((GetLeftIndent() != attr.GetLeftIndent()) || (GetLeftSubIndent() != attr.GetLeftSubIndent()))) return false; if ((flags & wxTEXT_ATTR_RIGHT_INDENT) && (GetRightIndent() != attr.GetRightIndent())) return false; if ((flags & wxTEXT_ATTR_PARA_SPACING_AFTER) && (GetParagraphSpacingAfter() != attr.GetParagraphSpacingAfter())) return false; if ((flags & wxTEXT_ATTR_PARA_SPACING_BEFORE) && (GetParagraphSpacingBefore() != attr.GetParagraphSpacingBefore())) return false; if ((flags & wxTEXT_ATTR_LINE_SPACING) && (GetLineSpacing() != attr.GetLineSpacing())) return false; if ((flags & wxTEXT_ATTR_CHARACTER_STYLE_NAME) && (GetCharacterStyleName() != attr.GetCharacterStyleName())) return false; if ((flags & wxTEXT_ATTR_PARAGRAPH_STYLE_NAME) && (GetParagraphStyleName() != attr.GetParagraphStyleName())) return false; if ((flags & wxTEXT_ATTR_LIST_STYLE_NAME) && (GetListStyleName() != attr.GetListStyleName())) return false; if ((flags & wxTEXT_ATTR_BULLET_STYLE) && (GetBulletStyle() != attr.GetBulletStyle())) return false; if ((flags & wxTEXT_ATTR_BULLET_NUMBER) && (GetBulletNumber() != attr.GetBulletNumber())) return false; if ((flags & wxTEXT_ATTR_BULLET_TEXT) && (GetBulletText() != attr.GetBulletText()) && (GetBulletFont() != attr.GetBulletFont())) return false; if ((flags & wxTEXT_ATTR_BULLET_NAME) && (GetBulletName() != attr.GetBulletName())) return false; if ((flags & wxTEXT_ATTR_TABS) && !TabsEq(GetTabs(), attr.GetTabs())) return false; if ((flags & wxTEXT_ATTR_PAGE_BREAK) && (HasPageBreak() != attr.HasPageBreak())) return false; if (flags & wxTEXT_ATTR_EFFECTS) { if (HasTextEffects() != attr.HasTextEffects()) return false; if (!BitlistsEqPartial(GetTextEffects(), attr.GetTextEffects(), attr.GetTextEffectFlags())) return false; } if ((flags & wxTEXT_ATTR_OUTLINE_LEVEL) && (GetOutlineLevel() != attr.GetOutlineLevel())) return false; return true; }
// Partial equality test. Only returns false if an attribute doesn't match. bool wxTextAttr::EqPartial(const wxTextAttr& attr, bool weakTest) const { int flags = attr.GetFlags(); if (!weakTest && ((!HasTextColour() && attr.HasTextColour()) || (!HasBackgroundColour() && attr.HasBackgroundColour()) || (!HasFontFaceName() && attr.HasFontFaceName()) || (!HasFontSize() && attr.HasFontSize()) || (!HasFontWeight() && attr.HasFontWeight()) || (!HasFontItalic() && attr.HasFontItalic()) || (!HasFontUnderlined() && attr.HasFontUnderlined()) || (!HasFontStrikethrough() && attr.HasFontStrikethrough()) || (!HasFontEncoding() && attr.HasFontEncoding()) || (!HasFontFamily() && attr.HasFontFamily()) || (!HasURL() && attr.HasURL()) || (!HasAlignment() && attr.HasAlignment()) || (!HasLeftIndent() && attr.HasLeftIndent()) || (!HasParagraphSpacingAfter() && attr.HasParagraphSpacingAfter()) || (!HasParagraphSpacingBefore() && attr.HasParagraphSpacingBefore()) || (!HasLineSpacing() && attr.HasLineSpacing()) || (!HasCharacterStyleName() && attr.HasCharacterStyleName()) || (!HasParagraphStyleName() && attr.HasParagraphStyleName()) || (!HasListStyleName() && attr.HasListStyleName()) || (!HasBulletStyle() && attr.HasBulletStyle()) || (!HasBulletNumber() && attr.HasBulletNumber()) || (!HasBulletText() && attr.HasBulletText()) || (!HasBulletName() && attr.HasBulletName()) || (!HasTabs() && attr.HasTabs()) || (!HasTextEffects() && attr.HasTextEffects()) || (!HasOutlineLevel() && attr.HasOutlineLevel()))) { return false; } if (HasTextColour() && attr.HasTextColour() && GetTextColour() != attr.GetTextColour()) return false; if (HasBackgroundColour() && attr.HasBackgroundColour() && GetBackgroundColour() != attr.GetBackgroundColour()) return false; if (HasFontFaceName() && attr.HasFontFaceName() && GetFontFaceName() != attr.GetFontFaceName()) return false; // This checks whether the two objects have the same font size dimension (px versus pt) if (HasFontSize() && attr.HasFontSize() && (flags & wxTEXT_ATTR_FONT) != (GetFlags() & wxTEXT_ATTR_FONT)) return false; if (HasFontPointSize() && attr.HasFontPointSize() && GetFontSize() != attr.GetFontSize()) return false; if (HasFontPixelSize() && attr.HasFontPixelSize() && GetFontSize() != attr.GetFontSize()) return false; if (HasFontWeight() && attr.HasFontWeight() && GetFontWeight() != attr.GetFontWeight()) return false; if (HasFontItalic() && attr.HasFontItalic() && GetFontStyle() != attr.GetFontStyle()) return false; if (HasFontUnderlined() && attr.HasFontUnderlined() && GetFontUnderlined() != attr.GetFontUnderlined()) return false; if (HasFontStrikethrough() && attr.HasFontStrikethrough() && GetFontStrikethrough() != attr.GetFontStrikethrough()) return false; if (HasFontEncoding() && attr.HasFontEncoding() && GetFontEncoding() != attr.GetFontEncoding()) return false; if (HasFontFamily() && attr.HasFontFamily() && GetFontFamily() != attr.GetFontFamily()) return false; if (HasURL() && attr.HasURL() && GetURL() != attr.GetURL()) return false; if (HasAlignment() && attr.HasAlignment() && GetAlignment() != attr.GetAlignment()) return false; if (HasLeftIndent() && attr.HasLeftIndent() && ((GetLeftIndent() != attr.GetLeftIndent()) || (GetLeftSubIndent() != attr.GetLeftSubIndent()))) return false; if (HasRightIndent() && attr.HasRightIndent() && (GetRightIndent() != attr.GetRightIndent())) return false; if (HasParagraphSpacingAfter() && attr.HasParagraphSpacingAfter() && (GetParagraphSpacingAfter() != attr.GetParagraphSpacingAfter())) return false; if (HasParagraphSpacingBefore() && attr.HasParagraphSpacingBefore() && (GetParagraphSpacingBefore() != attr.GetParagraphSpacingBefore())) return false; if (HasLineSpacing() && attr.HasLineSpacing() && (GetLineSpacing() != attr.GetLineSpacing())) return false; if (HasCharacterStyleName() && attr.HasCharacterStyleName() && (GetCharacterStyleName() != attr.GetCharacterStyleName())) return false; if (HasParagraphStyleName() && attr.HasParagraphStyleName() && (GetParagraphStyleName() != attr.GetParagraphStyleName())) return false; if (HasListStyleName() && attr.HasListStyleName() && (GetListStyleName() != attr.GetListStyleName())) return false; if (HasBulletStyle() && attr.HasBulletStyle() && (GetBulletStyle() != attr.GetBulletStyle())) return false; if (HasBulletNumber() && attr.HasBulletNumber() && (GetBulletNumber() != attr.GetBulletNumber())) return false; if (HasBulletText() && attr.HasBulletText() && (GetBulletText() != attr.GetBulletText()) && (GetBulletFont() != attr.GetBulletFont())) return false; if (HasBulletName() && attr.HasBulletName() && (GetBulletName() != attr.GetBulletName())) return false; if (HasTabs() && attr.HasTabs() && !TabsEq(GetTabs(), attr.GetTabs())) return false; if ((HasPageBreak() != attr.HasPageBreak())) return false; if (HasTextEffects() && attr.HasTextEffects()) { if (!BitlistsEqPartial(GetTextEffects(), attr.GetTextEffects(), attr.GetTextEffectFlags())) return false; } if (HasOutlineLevel() && attr.HasOutlineLevel() && (GetOutlineLevel() != attr.GetOutlineLevel())) return false; return true; }
FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTrueType, uint32_t flags, int weight, int italic_angle, int WindowCP, CFX_SubstFont* pSubstFont) { if (!(flags & FXFONT_USEEXTERNATTR)) { weight = FXFONT_FW_NORMAL; italic_angle = 0; } CFX_ByteString SubstName = name; SubstName.Remove(' '); if (bTrueType && name[0] == '@') SubstName = name.Mid(1); PDF_GetStandardFontName(&SubstName); if (SubstName == "Symbol" && !bTrueType) { pSubstFont->m_Family = "Chrome Symbol"; pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; if (m_FoxitFaces[12]) return m_FoxitFaces[12]; const uint8_t* pFontData = nullptr; uint32_t size = 0; m_pFontMgr->GetBuiltinFont(12, &pFontData, &size); m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); return m_FoxitFaces[12]; } if (SubstName == "ZapfDingbats") { pSubstFont->m_Family = "Chrome Dingbats"; pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; if (m_FoxitFaces[13]) return m_FoxitFaces[13]; const uint8_t* pFontData = nullptr; uint32_t size = 0; m_pFontMgr->GetBuiltinFont(13, &pFontData, &size); m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0); return m_FoxitFaces[13]; } int iBaseFont = 0; CFX_ByteString family; CFX_ByteString style; bool bHasComma = false; bool bHasHyphen = false; int find = SubstName.Find(",", 0); if (find >= 0) { family = SubstName.Left(find); PDF_GetStandardFontName(&family); style = SubstName.Mid(find + 1); bHasComma = true; } else { family = SubstName; } for (; iBaseFont < kExternalFontIndex; iBaseFont++) { if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) break; } int PitchFamily = 0; bool bItalic = false; uint32_t nStyle = 0; bool bStyleAvail = false; if (iBaseFont < kExternalFontIndex) { if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) nStyle |= FX_FONT_STYLE_Bold; if ((iBaseFont % 4) / 2) nStyle |= FX_FONT_STYLE_Italic; if (iBaseFont < 4) PitchFamily |= FXFONT_FF_FIXEDPITCH; if (iBaseFont >= 8) PitchFamily |= FXFONT_FF_ROMAN; } else { if (!bHasComma) { find = family.ReverseFind('-'); if (find >= 0) { style = family.Mid(find + 1); family = family.Left(find); bHasHyphen = true; } } if (!bHasHyphen) { int nLen = family.GetLength(); int32_t nRet = GetStyleType(family, true); if (nRet > -1) { family = family.Left(nLen - g_FontStyles[nRet].len); if (nRet == 0) nStyle |= FX_FONT_STYLE_Bold; else if (nRet == 1) nStyle |= FX_FONT_STYLE_Italic; else if (nRet == 2) nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic); } } UpdatePitchFamily(flags, PitchFamily); } if (!style.IsEmpty()) { int nLen = style.GetLength(); const FX_CHAR* pStyle = style.c_str(); int i = 0; bool bFirstItem = true; CFX_ByteString buf; while (i < nLen) { buf = ParseStyle(pStyle, nLen, i); int32_t nRet = GetStyleType(buf, false); if ((i && !bStyleAvail) || (!i && nRet < 0)) { family = SubstName; iBaseFont = kExternalFontIndex; break; } if (nRet >= 0) { bStyleAvail = true; } if (nRet == 1) { if (bFirstItem) { nStyle |= FX_FONT_STYLE_Italic; } else { family = SubstName; iBaseFont = kExternalFontIndex; } break; } if (nRet == 0) { if (nStyle & FX_FONT_STYLE_Bold) nStyle |= FX_FONT_STYLE_BoldBold; else nStyle |= FX_FONT_STYLE_Bold; bFirstItem = false; } else if (nRet == 2) { nStyle |= FX_FONT_STYLE_Italic; if (nStyle & FX_FONT_STYLE_Bold) nStyle |= FX_FONT_STYLE_BoldBold; else nStyle |= FX_FONT_STYLE_Bold; bFirstItem = false; } i += buf.GetLength() + 1; } } weight = weight ? weight : FXFONT_FW_NORMAL; int old_weight = weight; if (nStyle) { weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); } if (nStyle & FX_FONT_STYLE_Italic) bItalic = true; int iExact = 0; int Charset = FXFONT_ANSI_CHARSET; if (WindowCP) Charset = GetCharsetFromCodePage(WindowCP); else if (iBaseFont == kExternalFontIndex && (flags & FXFONT_SYMBOLIC)) Charset = FXFONT_SYMBOL_CHARSET; bool bCJK = (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || Charset == FXFONT_HANGUL_CHARSET || Charset == FXFONT_CHINESEBIG5_CHARSET); if (!m_pFontInfo) { pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); } family = GetFontFamily(family, nStyle); CFX_ByteString match = MatchInstalledFonts(TT_NormalizeName(family.c_str())); if (match.IsEmpty() && family != SubstName && (!bHasComma && (!bHasHyphen || (bHasHyphen && !bStyleAvail)))) { match = MatchInstalledFonts(TT_NormalizeName(SubstName.c_str())); } if (match.IsEmpty() && iBaseFont >= kExternalFontIndex) { if (!bCJK) { if (!CheckSupportThirdPartFont(family, PitchFamily)) { bItalic = italic_angle != 0; weight = old_weight; } } else { pSubstFont->m_bSubstCJK = true; if (nStyle) pSubstFont->m_WeightCJK = nStyle ? weight : FXFONT_FW_NORMAL; if (nStyle & FX_FONT_STYLE_Italic) pSubstFont->m_bItalicCJK = true; } } else { italic_angle = 0; weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); } if (!match.IsEmpty() || iBaseFont < kExternalFontIndex) { if (!match.IsEmpty()) family = match; if (iBaseFont < kExternalFontIndex) { if (nStyle && !(iBaseFont % 4)) { if ((nStyle & 0x3) == 1) iBaseFont += 1; if ((nStyle & 0x3) == 2) iBaseFont += 3; if ((nStyle & 0x3) == 3) iBaseFont += 2; } family = g_Base14FontNames[iBaseFont]; pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; } } else { if (flags & FXFONT_ITALIC) bItalic = true; } iExact = !match.IsEmpty(); void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, family.c_str(), iExact); if (iExact) pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; if (!hFont) { #ifdef PDF_ENABLE_XFA if (flags & FXFONT_EXACTMATCH) return nullptr; #endif // PDF_ENABLE_XFA if (bCJK) { bItalic = italic_angle != 0; weight = old_weight; } if (!match.IsEmpty()) { hFont = m_pFontInfo->GetFont(match.c_str()); if (!hFont) { return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); } } else { if (Charset == FXFONT_SYMBOL_CHARSET) { #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ if (SubstName == "Symbol") { pSubstFont->m_Family = "Chrome Symbol"; pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; if (m_FoxitFaces[12]) return m_FoxitFaces[12]; const uint8_t* pFontData = nullptr; uint32_t size = 0; m_pFontMgr->GetBuiltinFont(12, &pFontData, &size); m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0); return m_FoxitFaces[12]; } #endif pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL; return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, weight, italic_angle, 0, pSubstFont); } if (Charset == FXFONT_ANSI_CHARSET) { pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD; return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); } auto it = std::find_if(m_FaceArray.begin(), m_FaceArray.end(), [Charset](const FaceData& face) { return face.charset == static_cast<uint32_t>(Charset); }); if (it == m_FaceArray.end()) { return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily); } hFont = m_pFontInfo->GetFont(it->name.c_str()); } } if (!hFont) return nullptr; m_pFontInfo->GetFaceName(hFont, SubstName); if (Charset == FXFONT_DEFAULT_CHARSET) m_pFontInfo->GetFontCharset(hFont, Charset); uint32_t ttc_size = m_pFontInfo->GetFontData(hFont, kTableTTCF, nullptr, 0); uint32_t font_size = m_pFontInfo->GetFontData(hFont, 0, nullptr, 0); if (font_size == 0 && ttc_size == 0) { m_pFontInfo->DeleteFont(hFont); return nullptr; } FXFT_Face face = nullptr; if (ttc_size) face = GetCachedTTCFace(hFont, kTableTTCF, ttc_size, font_size); else face = GetCachedFace(hFont, SubstName, weight, bItalic, font_size); if (!face) { m_pFontInfo->DeleteFont(hFont); return nullptr; } pSubstFont->m_Family = SubstName; pSubstFont->m_Charset = Charset; bool bNeedUpdateWeight = false; if (FXFT_Is_Face_Bold(face)) bNeedUpdateWeight = weight != FXFONT_FW_BOLD; else bNeedUpdateWeight = weight != FXFONT_FW_NORMAL; if (bNeedUpdateWeight) pSubstFont->m_Weight = weight; if (bItalic && !FXFT_Is_Face_Italic(face)) { if (italic_angle == 0) italic_angle = -12; else if (FXSYS_abs(italic_angle) < 5) italic_angle = 0; pSubstFont->m_ItalicAngle = italic_angle; } m_pFontInfo->DeleteFont(hFont); return face; }