From 07fba46d11dca067b21aba2b950f879faa3ce2ce Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Fri, 10 Feb 2023 09:11:01 +0000 Subject: [PATCH] Bug 1815679 - Fix errors in mapping font-style:oblique values to the 'slnt' axis in variable fonts. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D169335 --- gfx/thebes/gfxFont.cpp | 16 ++++++++++------ gfx/thebes/gfxFontEntry.cpp | 10 +++------- gfx/thebes/gfxFontEntry.h | 21 +++++++++++++++++++-- gfx/thebes/gfxFontUtils.h | 2 +- layout/style/ServoStyleConstsInlines.h | 9 ++++++++- servo/ports/geckolib/cbindgen.toml | 4 +++- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 3827f28da964..b9467cbdadb9 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -870,11 +870,15 @@ void gfxShapedText::AdjustAdvancesForSyntheticBold(float aSynBoldOffset, } float gfxFont::AngleForSyntheticOblique() const { - // If the style doesn't call for italic/oblique, or if the face already - // provides it, no synthetic style should be added. - if (mStyle.style == FontSlantStyle::NORMAL || !mStyle.allowSyntheticStyle || - !mFontEntry->IsUpright() || mFontEntry->HasSlantVariation()) { - return 0.0f; + // First check conditions that mean no synthetic slant should be used: + if (mStyle.style == FontSlantStyle::NORMAL) { + return 0.0f; // Requested style is 'normal'. + } + if (!mStyle.allowSyntheticStyle) { + return 0.0f; // Synthetic obliquing is disabled. + } + if (!mFontEntry->MayUseSyntheticSlant()) { + return 0.0f; // The resource supports "real" slant, so don't synthesize. } // If style calls for italic, and face doesn't support it, use default @@ -885,7 +889,7 @@ float gfxFont::AngleForSyntheticOblique() const { : FontSlantStyle::DEFAULT_OBLIQUE_DEGREES; } - // Default or custom oblique angle + // OK, we're going to use synthetic oblique: return the requested angle. return mStyle.style.ObliqueAngle(); } diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index c3b136d2a1b2..2323f31e393e 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -1349,18 +1349,14 @@ void gfxFontEntry::GetVariationsForStyle(nsTArray& aResult, // The 'ital' axis is normally a binary toggle; intermediate values // can only be set using font-variation-settings. aResult.AppendElement(gfxFontVariation{HB_TAG('i', 't', 'a', 'l'), 1.0f}); - } else if (HasSlantVariation()) { + } else if (aStyle.style != StyleFontStyle::NORMAL && HasSlantVariation()) { // Figure out what slant angle we should try to match from the // requested style. - float angle = aStyle.style.IsNormal() ? 0.0f - : aStyle.style.IsItalic() - ? FontSlantStyle::DEFAULT_OBLIQUE_DEGREES - : aStyle.style.ObliqueAngle(); + float angle = aStyle.style.SlantAngle(); // Clamp to the available range, unless the face is a user font // with no explicit descriptor. if (!(IsUserFont() && (mRangeFlags & RangeFlags::eAutoSlantStyle))) { - angle = - SlantStyle().Clamp(FontSlantStyle::FromFloat(angle)).ObliqueAngle(); + angle = SlantStyle().Clamp(FontSlantStyle::FromFloat(angle)).SlantAngle(); } // OpenType and CSS measure angles in opposite directions, so we have to // invert the sign of the CSS oblique value when setting OpenType 'slnt'. diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index a518c457b8d5..2663d571d9d2 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -181,8 +181,9 @@ class gfxFontEntry { bool IsItalic() const { return SlantStyle().Min().IsItalic(); } bool IsOblique() const { return SlantStyle().Min().IsOblique(); } bool IsUpright() const { return SlantStyle().Min().IsNormal(); } - inline bool SupportsItalic(); - inline bool SupportsBold(); // defined below, because of RangeFlags use + inline bool SupportsItalic(); // defined below, because of RangeFlags use + inline bool SupportsBold(); + inline bool MayUseSyntheticSlant(); bool IgnoreGDEF() const { return mIgnoreGDEF; } bool IgnoreGSUB() const { return mIgnoreGSUB; } @@ -834,6 +835,22 @@ inline bool gfxFontEntry::SupportsBold() { HasBoldVariableWeight()); } +inline bool gfxFontEntry::MayUseSyntheticSlant() { + if (!IsUpright()) { + return false; // The resource is already non-upright. + } + if (HasSlantVariation()) { + if (mRangeFlags & RangeFlags::eAutoSlantStyle) { + return false; + } + if (!SlantStyle().IsSingle()) { + return false; // The resource has a 'slnt' axis, and has not been + // clamped to just its upright setting. + } + } + return true; +} + // used when iterating over all fonts looking for a match for a given character struct GlobalFontMatch { GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh, diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h index f441749fc12d..ce11c6943d33 100644 --- a/gfx/thebes/gfxFontUtils.h +++ b/gfx/thebes/gfxFontUtils.h @@ -1262,7 +1262,7 @@ static inline double StyleDistance(const mozilla::SlantStyleRange& aRange, return kReverse; } - const double kDefaultAngle = mozilla::FontSlantStyle::OBLIQUE.ObliqueAngle(); + const double kDefaultAngle = mozilla::FontSlantStyle::DEFAULT_OBLIQUE_DEGREES; if (aTargetStyle.IsItalic()) { if (minStyle.IsOblique()) { diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index 441fc6764811..c8fb68d9aa3f 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -1078,7 +1078,14 @@ inline bool StyleFontStyle::IsOblique() const { return !IsItalic() && !IsNormal(); } -inline float StyleFontStyle::ObliqueAngle() const { return ToFloat(); } +inline float StyleFontStyle::ObliqueAngle() const { + MOZ_ASSERT(IsOblique()); + return ToFloat(); +} + +inline float StyleFontStyle::SlantAngle() const { + return IsNormal() ? 0 : IsItalic() ? DEFAULT_OBLIQUE_DEGREES : ObliqueAngle(); +} using FontStretch = StyleFontStretch; using FontSlantStyle = StyleFontStyle; diff --git a/servo/ports/geckolib/cbindgen.toml b/servo/ports/geckolib/cbindgen.toml index 90e2ed94f2e8..2ed4df3cf638 100644 --- a/servo/ports/geckolib/cbindgen.toml +++ b/servo/ports/geckolib/cbindgen.toml @@ -906,7 +906,9 @@ renaming_overrides_prefixing = true inline bool IsItalic() const; inline bool IsOblique() const; - inline float ObliqueAngle() const; + inline float ObliqueAngle() const; // Only for use when IsOblique() is true + inline float SlantAngle() const; // Returns angle for any font-style, including + // normal/italic as well as explicit oblique """ "FontStretch" = """