зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1810815 - Properly account for cases where CSS units ch or ic are based on a different font than the first, due to character coverage. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D167070
This commit is contained in:
Родитель
482a193c66
Коммит
f956fb8c4d
|
@ -2284,7 +2284,7 @@ already_AddRefed<gfxFont> gfxFontGroup::GetDefaultFont() {
|
|||
}
|
||||
|
||||
already_AddRefed<gfxFont> gfxFontGroup::GetFirstValidFont(
|
||||
uint32_t aCh, StyleGenericFontFamily* aGeneric) {
|
||||
uint32_t aCh, StyleGenericFontFamily* aGeneric, bool* aIsFirst) {
|
||||
// Ensure cached font instances are valid.
|
||||
CheckForUpdatedPlatformList();
|
||||
|
||||
|
@ -2319,6 +2319,9 @@ already_AddRefed<gfxFont> gfxFontGroup::GetFirstValidFont(
|
|||
if (aGeneric) {
|
||||
*aGeneric = ff.Generic();
|
||||
}
|
||||
if (aIsFirst) {
|
||||
*aIsFirst = (i == 0);
|
||||
}
|
||||
return font.forget();
|
||||
}
|
||||
|
||||
|
@ -2349,12 +2352,18 @@ already_AddRefed<gfxFont> gfxFontGroup::GetFirstValidFont(
|
|||
if (aGeneric) {
|
||||
*aGeneric = ff.Generic();
|
||||
}
|
||||
if (aIsFirst) {
|
||||
*aIsFirst = (i == 0);
|
||||
}
|
||||
return font.forget();
|
||||
}
|
||||
}
|
||||
if (aGeneric) {
|
||||
*aGeneric = StyleGenericFontFamily::None;
|
||||
}
|
||||
if (aIsFirst) {
|
||||
*aIsFirst = false;
|
||||
}
|
||||
return GetDefaultFont();
|
||||
}
|
||||
|
||||
|
@ -3831,6 +3840,35 @@ already_AddRefed<gfxFont> gfxFontGroup::WhichSystemFontSupportsChar(
|
|||
&visibility);
|
||||
}
|
||||
|
||||
gfxFont::Metrics gfxFontGroup::GetMetricsForCSSUnits(
|
||||
gfxFont::Orientation aOrientation) {
|
||||
bool isFirst;
|
||||
RefPtr<gfxFont> font = GetFirstValidFont(0x20, nullptr, &isFirst);
|
||||
auto metrics = font->GetMetrics(aOrientation);
|
||||
|
||||
// If the font we used to get metrics was not the first in the list,
|
||||
// or if it doesn't support the ZERO character, check for the font that
|
||||
// does support ZERO and use its metrics for the 'ch' unit.
|
||||
if (!isFirst || !font->HasCharacter('0')) {
|
||||
RefPtr<gfxFont> zeroFont = GetFirstValidFont('0');
|
||||
if (zeroFont != font) {
|
||||
const auto& zeroMetrics = zeroFont->GetMetrics(aOrientation);
|
||||
metrics.zeroWidth = zeroMetrics.zeroWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Likewise for the WATER ideograph character used as the basis for 'ic'.
|
||||
if (!isFirst || !font->HasCharacter(0x6C34)) {
|
||||
RefPtr<gfxFont> icFont = GetFirstValidFont(0x6C34);
|
||||
if (icFont != font) {
|
||||
const auto& icMetrics = icFont->GetMetrics(aOrientation);
|
||||
metrics.ideographicWidth = icMetrics.ideographicWidth;
|
||||
}
|
||||
}
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
void gfxMissingFontRecorder::Flush() {
|
||||
static bool mNotifiedFontsInitialized = false;
|
||||
static uint32_t mNotifiedFonts[gfxMissingFontRecorder::kNumScriptBitsWords];
|
||||
|
|
|
@ -947,8 +947,10 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
|||
// Initiates userfont loads if userfont not loaded.
|
||||
// aGeneric: if non-null, returns the CSS generic type that was mapped to
|
||||
// this font
|
||||
// aIsFirst: if non-null, returns whether the font was first in the list
|
||||
already_AddRefed<gfxFont> GetFirstValidFont(
|
||||
uint32_t aCh = 0x20, mozilla::StyleGenericFontFamily* aGeneric = nullptr);
|
||||
uint32_t aCh = 0x20, mozilla::StyleGenericFontFamily* aGeneric = nullptr,
|
||||
bool* aIsFirst = nullptr);
|
||||
|
||||
// Returns the first font in the font-group that has an OpenType MATH table,
|
||||
// or null if no such font is available. The GetMathConstant methods may be
|
||||
|
@ -1104,6 +1106,14 @@ class gfxFontGroup final : public gfxTextRunFactory {
|
|||
|
||||
nsAtom* Language() const { return mLanguage.get(); }
|
||||
|
||||
// Get font metrics to be used as the basis for CSS font-relative units.
|
||||
// Note that these may be a "composite" of metrics from multiple fonts,
|
||||
// because the 'ch' and 'ic' units depend on the font that would be used
|
||||
// to render specific characters, not simply the "first available" font.
|
||||
// https://drafts.csswg.org/css-values-4/#ch
|
||||
// https://drafts.csswg.org/css-values-4/#ic
|
||||
gfxFont::Metrics GetMetricsForCSSUnits(gfxFont::Orientation aOrientation);
|
||||
|
||||
protected:
|
||||
friend class mozilla::PostTraversalTask;
|
||||
|
||||
|
|
|
@ -1431,17 +1431,20 @@ GeckoFontMetrics Gecko_GetFontMetrics(const nsPresContext* aPresContext,
|
|||
nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
|
||||
RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetMetricsFor(
|
||||
presContext, aIsVertical, aFont, aFontSize, aUseUserFontSet);
|
||||
RefPtr<gfxFont> font = fm->GetThebesFontGroup()->GetFirstValidFont();
|
||||
const auto& metrics = font->GetMetrics(fm->Orientation());
|
||||
auto* fontGroup = fm->GetThebesFontGroup();
|
||||
auto metrics = fontGroup->GetMetricsForCSSUnits(fm->Orientation());
|
||||
|
||||
float scriptPercentScaleDown = 0;
|
||||
float scriptScriptPercentScaleDown = 0;
|
||||
if (aRetrieveMathScales && font->TryGetMathTable()) {
|
||||
scriptPercentScaleDown = static_cast<float>(
|
||||
font->MathTable()->Constant(gfxMathTable::ScriptPercentScaleDown));
|
||||
scriptScriptPercentScaleDown =
|
||||
static_cast<float>(font->MathTable()->Constant(
|
||||
gfxMathTable::ScriptScriptPercentScaleDown));
|
||||
if (aRetrieveMathScales) {
|
||||
RefPtr<gfxFont> font = fontGroup->GetFirstValidFont();
|
||||
if (font->TryGetMathTable()) {
|
||||
scriptPercentScaleDown = static_cast<float>(
|
||||
font->MathTable()->Constant(gfxMathTable::ScriptPercentScaleDown));
|
||||
scriptScriptPercentScaleDown =
|
||||
static_cast<float>(font->MathTable()->Constant(
|
||||
gfxMathTable::ScriptScriptPercentScaleDown));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t d2a = aPresContext->AppUnitsPerDevPixel();
|
||||
|
|
Загрузка…
Ссылка в новой задаче