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
This commit is contained in:
Jonathan Kew 2023-02-10 09:11:01 +00:00
parent 6c2cb4ec55
commit 07fba46d11
6 changed files with 44 additions and 18 deletions

View file

@ -870,11 +870,15 @@ void gfxShapedText::AdjustAdvancesForSyntheticBold(float aSynBoldOffset,
} }
float gfxFont::AngleForSyntheticOblique() const { float gfxFont::AngleForSyntheticOblique() const {
// If the style doesn't call for italic/oblique, or if the face already // First check conditions that mean no synthetic slant should be used:
// provides it, no synthetic style should be added. if (mStyle.style == FontSlantStyle::NORMAL) {
if (mStyle.style == FontSlantStyle::NORMAL || !mStyle.allowSyntheticStyle || return 0.0f; // Requested style is 'normal'.
!mFontEntry->IsUpright() || mFontEntry->HasSlantVariation()) { }
return 0.0f; 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 // 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; : 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(); return mStyle.style.ObliqueAngle();
} }

View file

@ -1349,18 +1349,14 @@ void gfxFontEntry::GetVariationsForStyle(nsTArray<gfxFontVariation>& aResult,
// The 'ital' axis is normally a binary toggle; intermediate values // The 'ital' axis is normally a binary toggle; intermediate values
// can only be set using font-variation-settings. // can only be set using font-variation-settings.
aResult.AppendElement(gfxFontVariation{HB_TAG('i', 't', 'a', 'l'), 1.0f}); 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 // Figure out what slant angle we should try to match from the
// requested style. // requested style.
float angle = aStyle.style.IsNormal() ? 0.0f float angle = aStyle.style.SlantAngle();
: aStyle.style.IsItalic()
? FontSlantStyle::DEFAULT_OBLIQUE_DEGREES
: aStyle.style.ObliqueAngle();
// Clamp to the available range, unless the face is a user font // Clamp to the available range, unless the face is a user font
// with no explicit descriptor. // with no explicit descriptor.
if (!(IsUserFont() && (mRangeFlags & RangeFlags::eAutoSlantStyle))) { if (!(IsUserFont() && (mRangeFlags & RangeFlags::eAutoSlantStyle))) {
angle = angle = SlantStyle().Clamp(FontSlantStyle::FromFloat(angle)).SlantAngle();
SlantStyle().Clamp(FontSlantStyle::FromFloat(angle)).ObliqueAngle();
} }
// OpenType and CSS measure angles in opposite directions, so we have to // OpenType and CSS measure angles in opposite directions, so we have to
// invert the sign of the CSS oblique value when setting OpenType 'slnt'. // invert the sign of the CSS oblique value when setting OpenType 'slnt'.

View file

@ -181,8 +181,9 @@ class gfxFontEntry {
bool IsItalic() const { return SlantStyle().Min().IsItalic(); } bool IsItalic() const { return SlantStyle().Min().IsItalic(); }
bool IsOblique() const { return SlantStyle().Min().IsOblique(); } bool IsOblique() const { return SlantStyle().Min().IsOblique(); }
bool IsUpright() const { return SlantStyle().Min().IsNormal(); } bool IsUpright() const { return SlantStyle().Min().IsNormal(); }
inline bool SupportsItalic(); inline bool SupportsItalic(); // defined below, because of RangeFlags use
inline bool SupportsBold(); // defined below, because of RangeFlags use inline bool SupportsBold();
inline bool MayUseSyntheticSlant();
bool IgnoreGDEF() const { return mIgnoreGDEF; } bool IgnoreGDEF() const { return mIgnoreGDEF; }
bool IgnoreGSUB() const { return mIgnoreGSUB; } bool IgnoreGSUB() const { return mIgnoreGSUB; }
@ -834,6 +835,22 @@ inline bool gfxFontEntry::SupportsBold() {
HasBoldVariableWeight()); 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 // used when iterating over all fonts looking for a match for a given character
struct GlobalFontMatch { struct GlobalFontMatch {
GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh, GlobalFontMatch(uint32_t aCharacter, uint32_t aNextCh,

View file

@ -1262,7 +1262,7 @@ static inline double StyleDistance(const mozilla::SlantStyleRange& aRange,
return kReverse; return kReverse;
} }
const double kDefaultAngle = mozilla::FontSlantStyle::OBLIQUE.ObliqueAngle(); const double kDefaultAngle = mozilla::FontSlantStyle::DEFAULT_OBLIQUE_DEGREES;
if (aTargetStyle.IsItalic()) { if (aTargetStyle.IsItalic()) {
if (minStyle.IsOblique()) { if (minStyle.IsOblique()) {

View file

@ -1078,7 +1078,14 @@ inline bool StyleFontStyle::IsOblique() const {
return !IsItalic() && !IsNormal(); 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 FontStretch = StyleFontStretch;
using FontSlantStyle = StyleFontStyle; using FontSlantStyle = StyleFontStyle;

View file

@ -906,7 +906,9 @@ renaming_overrides_prefixing = true
inline bool IsItalic() const; inline bool IsItalic() const;
inline bool IsOblique() 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" = """ "FontStretch" = """