author | Jonathan Kew <jkew@mozilla.com> |
Wed, 25 Apr 2018 07:18:23 +0100 | |
changeset 415632 | ee068c7ae8f44f55c0d0cd004cba77b2c402a2db |
parent 415631 | 3c05b11ca2b837819a60c4a05ac85822f56c608e |
child 415633 | 2e9eda40f4770cc1fd2a2aa2263c1020445ef636 |
push id | 33901 |
push user | apavel@mozilla.com |
push date | Thu, 26 Apr 2018 06:05:37 +0000 |
treeherder | mozilla-central@b62ad926cf2a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwatt |
bugs | 1454598 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -112,20 +112,19 @@ namespace mozilla { namespace dom { // Used on Android/B2G to pass the list of fonts on the device // to the child process struct FontListEntry { nsString familyName; nsString faceName; nsCString filepath; - float minWeight; - float maxWeight; - int16_t stretch; - uint8_t italic; + uint32_t weightRange; + uint32_t stretchRange; + uint32_t styleRange; uint8_t index; }; // Used on Mac OS X to pass the list of font families (not faces) // from chrome to content processes. // The entryType field distinguishes several types of font family // record; see gfxMacPlatformFontList.h for values and meaning. struct FontFamilyListEntry {
--- a/gfx/src/FontPropertyTypes.h +++ b/gfx/src/FontPropertyTypes.h @@ -8,16 +8,20 @@ #ifndef GFX_FONT_PROPERTY_TYPES_H #define GFX_FONT_PROPERTY_TYPES_H #include <algorithm> #include <cstdint> #include <cmath> #include <utility> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + #include "mozilla/Assertions.h" #include "nsString.h" /* * This file is separate from gfxFont.h so that layout can include it * without bringing in gfxFont.h and everything it includes. */ @@ -33,17 +37,17 @@ namespace mozilla { * ambiguity between constructors from /int/ and /T/, which mean * different things. * FractionBits - number of bits to use for the fractional part * Min, Max - [inclusive] limits to the range of values that may be stored * Values are constructed from and exposed as floating-point, but stored * internally as fixed point, so there will be a quantization effect on * fractional values, depending on the number of fractional bits used. * Using (16-bit) fixed-point types rather than floats for these style - * attributes reduces the memory footprint of gfxFontEntry and gfxFontSlantStyle; + * attributes reduces the memory footprint of gfxFontEntry and gfxFontStyle; * it will also tend to reduce the number of distinct font instances that * get created, particularly when styles are animated or set to arbitrary * values (e.g. by sliders in the UI), which should reduce pressure on * graphics resources and improve cache hit rates. */ template<class InternalType, unsigned FractionBits, int Min, int Max> class FontPropertyValue { @@ -53,17 +57,17 @@ public: // constructors to be "trivial" (i.e. the compiler implemented defaults that // do no initialization). // Annoyingly we can't make the default implementations constexpr (at least // in clang). That would be nice to do in order to allow the methods of // subclasses that always return the same value (e.g., FontWeight::Thin()) // to also be constexpr. :/ FontPropertyValue() = default; explicit FontPropertyValue(const FontPropertyValue& aOther) = default; - FontPropertyValue& operator= (const FontPropertyValue& aOther) = default; + FontPropertyValue& operator=(const FontPropertyValue& aOther) = default; bool operator==(const FontPropertyValue& aOther) const { return mValue == aOther.mValue; } bool operator!=(const FontPropertyValue& aOther) const { return mValue != aOther.mValue; @@ -88,19 +92,20 @@ public: // The difference between two values, returned as a raw floating-point number // (which might not be a valid property value in its own right). float operator-(const FontPropertyValue& aOther) const { return (mValue - aOther.mValue) * kInverseScale; } /// Return the raw internal representation, for purposes of hashing. - InternalType ForHash() const + /// (Do not try to interpret the numeric value of this.) + uint16_t ForHash() const { - return mValue; + return uint16_t(mValue); } static constexpr const float kMin = float(Min); static constexpr const float kMax = float(Max); protected: // Construct from a floating-point or integer value, checking that it is // within the allowed range and converting to fixed-point representation. @@ -184,18 +189,20 @@ public: } bool IsNormal() const { return mValue == kNormal; } bool IsBold() const { return mValue >= kBoldThreshold; } float ToFloat() const { return FontPropertyValue::ToFloat(); } int ToIntRounded() const { return FontPropertyValue::ToIntRounded(); } + typedef uint16_t InternalType; + private: - typedef uint16_t InternalType; + friend class WeightRange; explicit FontWeight(InternalType aValue) : FontPropertyValue(aValue) { } static const InternalType kNormal = 400u << kFractionBits; static const InternalType kBold = 700u << kFractionBits; @@ -265,18 +272,20 @@ public: static FontStretch UltraExpanded() { return FontStretch(kUltraExpanded); } bool IsNormal() const { return mValue == kNormal; } float Percentage() const { return ToFloat(); } + typedef uint16_t InternalType; + private: - typedef uint16_t InternalType; + friend class StretchRange; explicit FontStretch(InternalType aValue) : FontPropertyValue(aValue) { } static const InternalType kUltraCondensed = 50u << kFractionBits; static const InternalType kExtraCondensed = (62u << kFractionBits) + kPointFive; @@ -296,17 +305,16 @@ private: * (representable range -128.0 - 127.99609375) * - Define min value (-128.0) as meaning 'normal' * - Define max value (127.99609375) as 'italic' * - Other values represent 'oblique <angle>' * - Note that 'oblique 0deg' is distinct from 'normal' (should it be?) */ class FontSlantStyle final : public FontPropertyValue<int16_t,8,-90,90> { - typedef int16_t InternalType; public: const static constexpr float kDefaultAngle = 14.0; // See comment in FontPropertyValue regarding requirement for a trivial // default constructor. FontSlantStyle() = default; static FontSlantStyle Normal() @@ -319,29 +327,70 @@ public: return FontSlantStyle(kItalic); } static FontSlantStyle Oblique(float aAngle = kDefaultAngle) { return FontSlantStyle(aAngle); } + // Create from a string as generated by ToString. This is for internal use + // when serializing/deserializing entries for the startupcache, and is not + // intended to parse arbitrary (untrusted) strings. + static FontSlantStyle FromString(const char* aString) + { + if (strcmp(aString, "normal") == 0) { + return Normal(); + } else if (strcmp(aString, "italic") == 0) { + return Italic(); + } else { + if (isdigit(aString[0]) && strstr(aString, "deg")) { + float angle = strtof(aString, nullptr); + return Oblique(angle); + } + // Not recognized as an oblique angle; maybe it's from a startup-cache + // created by an older version. Just treat it as 'normal'. + return Normal(); + } + } + bool IsNormal() const { return mValue == kNormal; } bool IsItalic() const { return mValue == kItalic; } bool IsOblique() const { return mValue != kItalic && mValue != kNormal; } float ObliqueAngle() const { // It's not meaningful to get the oblique angle from a style that is // actually 'normal' or 'italic'. MOZ_ASSERT(IsOblique()); return ToFloat(); } + /** + * Write a string representation of the value to aOutString. + * + * NOTE that this APPENDS to the output string, it does not replace + * any existing contents. + */ + void ToString(nsACString& aOutString) const + { + if (IsNormal()) { + aOutString.Append("normal"); + } else if (IsItalic()) { + aOutString.Append("italic"); + } else { + aOutString.AppendPrintf("%gdeg", ObliqueAngle()); + } + } + + typedef int16_t InternalType; + private: + friend class SlantStyleRange; + explicit FontSlantStyle(InternalType aConstant) : FontPropertyValue(aConstant) { } explicit FontSlantStyle(float aAngle) : FontPropertyValue(aAngle) { @@ -356,16 +405,20 @@ private: * Convenience type to hold a <min, max> pair representing a range of values. * * The min and max are both inclusive, so when min == max the range represents * a single value (not an empty range). */ template<class T> class FontPropertyRange { + // This implementation assumes the underlying property type is a 16-bit value + // (see FromScalar and AsScalar below). + static_assert(sizeof(T) == 2, "FontPropertyValue should be a 16-bit type!"); + public: /** * Construct a range from given minimum and maximum values (inclusive). */ FontPropertyRange(T aMin, T aMax) : mValues(aMin, aMax) { MOZ_ASSERT(aMin <= aMax); @@ -374,16 +427,19 @@ public: /** * Construct a range representing a single value (min==max). */ explicit FontPropertyRange(T aValue) : mValues(aValue, aValue) { } + explicit FontPropertyRange(const FontPropertyRange& aOther) = default; + FontPropertyRange& operator=(const FontPropertyRange& aOther) = default; + T Min() const { return mValues.first; } T Max() const { return mValues.second; } /** * Clamp the given value to this range. * * (We can't use mozilla::Clamp here because it only accepts integral types.) */ @@ -404,28 +460,137 @@ public: { return mValues == aOther.mValues; } bool operator!=(const FontPropertyRange& aOther) const { return mValues != aOther.mValues; } + /** + * Conversion of the property range to/from a single 32-bit scalar value, + * suitable for IPC serialization, hashing, caching. + * + * No assumptions should be made about the numeric value of the scalar. + * + * This depends on the underlying property type being a 16-bit value! + */ + typedef uint32_t ScalarType; + + ScalarType AsScalar() const + { + return (mValues.first.ForHash() << 16) | mValues.second.ForHash(); + } + + /* + * FIXME: + * FromScalar is defined in each individual subclass, because I can't + * persuade the compiler to accept a definition here in the template. :\ + * + static FontPropertyRange FromScalar(ScalarType aScalar) + { + return FontPropertyRange(T(typename T::InternalType(aScalar >> 16)), + T(typename T::InternalType(aScalar & 0xffff))); + } + */ + +protected: + std::pair<T,T> mValues; +}; + +class WeightRange : public FontPropertyRange<FontWeight> +{ +public: + WeightRange(FontWeight aMin, FontWeight aMax) + : FontPropertyRange(aMin, aMax) + { + } + + explicit WeightRange(FontWeight aWeight) + : FontPropertyRange(aWeight) + { + } + + WeightRange(const WeightRange& aOther) = default; + void ToString(nsACString& aOutString, const char* aDelim = "..") const { - aOutString.AppendPrintf("%g", Min().ToFloat()); + aOutString.AppendFloat(Min().ToFloat()); if (!IsSingle()) { - aOutString.AppendPrintf("%s%g", aDelim, Max().ToFloat()); + aOutString.Append(aDelim); + aOutString.AppendFloat(Max().ToFloat()); } } -private: - std::pair<T,T> mValues; + static WeightRange FromScalar(ScalarType aScalar) + { + return WeightRange(FontWeight(FontWeight::InternalType(aScalar >> 16)), + FontWeight(FontWeight::InternalType(aScalar & 0xffff))); + } }; -typedef FontPropertyRange<FontWeight> WeightRange; -typedef FontPropertyRange<FontStretch> StretchRange; -typedef FontPropertyRange<FontSlantStyle> StyleRange; +class StretchRange : public FontPropertyRange<FontStretch> +{ +public: + StretchRange(FontStretch aMin, FontStretch aMax) + : FontPropertyRange(aMin, aMax) + { + } + + explicit StretchRange(FontStretch aStretch) + : FontPropertyRange(aStretch) + { + } + + StretchRange(const StretchRange& aOther) = default; + + void ToString(nsACString& aOutString, const char* aDelim = "..") const + { + aOutString.AppendFloat(Min().Percentage()); + if (!IsSingle()) { + aOutString.Append(aDelim); + aOutString.AppendFloat(Max().Percentage()); + } + } + + static StretchRange FromScalar(ScalarType aScalar) + { + return StretchRange( + FontStretch(FontStretch::InternalType(aScalar >> 16)), + FontStretch(FontStretch::InternalType(aScalar & 0xffff))); + } +}; + +class SlantStyleRange : public FontPropertyRange<FontSlantStyle> +{ +public: + SlantStyleRange(FontSlantStyle aMin, FontSlantStyle aMax) + : FontPropertyRange(aMin, aMax) + { + } + + explicit SlantStyleRange(FontSlantStyle aStyle) + : FontPropertyRange(aStyle) + { + } + + SlantStyleRange(const SlantStyleRange& aOther) = default; + + void ToString(nsACString& aOutString, const char* aDelim = "..") const + { + Min().ToString(aOutString); + if (!IsSingle()) { + aOutString.Append(aDelim); + Max().ToString(aOutString); + } + } + + static SlantStyleRange FromScalar(ScalarType aScalar) + { + return SlantStyleRange( + FontSlantStyle(FontSlantStyle::InternalType(aScalar >> 16)), + FontSlantStyle(FontSlantStyle::InternalType(aScalar & 0xffff))); + } +}; } // namespace mozilla #endif // GFX_FONT_PROPERTY_TYPES_H -
--- a/gfx/src/nsFont.cpp +++ b/gfx/src/nsFont.cpp @@ -287,19 +287,16 @@ void nsFont::AddFontFeaturesToStyle(gfxF aStyle->useGrayscaleAntialiasing = true; } aStyle->fontSmoothingBackgroundColor = fontSmoothingBackgroundColor; } void nsFont::AddFontVariationsToStyle(gfxFontStyle *aStyle) const { - // TODO: add variation settings from specific CSS properties - // such as weight, width, stretch - // If auto optical sizing is enabled, and if there's no 'opsz' axis in // fontVariationSettings, then set the automatic value on the style. class VariationTagComparator { public: bool Equals(const gfxFontVariation& aVariation, uint32_t aTag) const { return aVariation.mTag == aTag; } };
--- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -371,17 +371,21 @@ gfxDWriteFontFamily::AddSizeOfIncludingT //////////////////////////////////////////////////////////////////////////////// // gfxDWriteFontEntry gfxFontEntry* gfxDWriteFontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); - return new gfxDWriteFontEntry(Name(), mFont); + gfxDWriteFontEntry* fe = new gfxDWriteFontEntry(Name(), mFont); + fe->mWeightRange = mWeightRange; + fe->mStretchRange = mStretchRange; + fe->mStyleRange = mStyleRange; + return fe; } gfxDWriteFontEntry::~gfxDWriteFontEntry() { } static bool UsingArabicOrHebrewScriptSystemLocale() @@ -767,19 +771,17 @@ gfxDWriteFontEntry::CreateFontFace(IDWri // Do we need to modify DWrite simulations from what mFontFace has? bool needSimulations = (aSimulations & DWRITE_FONT_SIMULATIONS_BOLD) && !(mFontFace->GetSimulations() & DWRITE_FONT_SIMULATIONS_BOLD); // If the IDWriteFontFace5 interface is available, we can go via // IDWriteFontResource to create a new modified face. - if (mFontFace5 && ((aFontStyle && !aFontStyle->variationSettings.IsEmpty()) || - !Weight().IsSingle() || - needSimulations)) { + if (mFontFace5 && (HasVariations() || needSimulations)) { RefPtr<IDWriteFontResource> resource; HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource)); MOZ_ASSERT(SUCCEEDED(hr)); AutoTArray<DWRITE_FONT_AXIS_VALUE, 4> fontAxisValues; // Get the variation settings needed to instantiate the fontEntry // for a particular fontStyle. AutoTArray<gfxFontVariation,4> vars; @@ -952,43 +954,43 @@ gfxDWriteFontList::GetDefaultFontForPlat } } return nullptr; } gfxFontEntry * gfxDWriteFontList::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) { gfxFontEntry *lookup; lookup = LookupInFaceNameLists(aFontName); if (!lookup) { return nullptr; } gfxDWriteFontEntry* dwriteLookup = static_cast<gfxDWriteFontEntry*>(lookup); gfxDWriteFontEntry *fe = new gfxDWriteFontEntry(lookup->Name(), dwriteLookup->mFont, - aWeight, - aStretch, - aStyle); + aWeightForEntry, + aStretchForEntry, + aStyleForEntry); fe->SetForceGDIClassic(dwriteLookup->GetForceGDIClassic()); return fe; } gfxFontEntry * gfxDWriteFontList::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) { RefPtr<IDWriteFontFileStream> fontFileStream; RefPtr<IDWriteFontFile> fontFile; HRESULT hr = gfxDWriteFontFileLoader::CreateCustomFontFile(aFontData, aLength, getter_AddRefs(fontFile), @@ -1008,19 +1010,19 @@ gfxDWriteFontList::MakePlatformFont(cons BOOL isSupported; DWRITE_FONT_FILE_TYPE fileType; UINT32 numFaces; gfxDWriteFontEntry *entry = new gfxDWriteFontEntry(uniqueName, fontFile, fontFileStream, - aWeight, - aStretch, - aStyle); + aWeightForEntry, + aStretchForEntry, + aStyleForEntry); fontFile->Analyze(&isSupported, &fileType, &entry->mFaceType, &numFaces); if (!isSupported || numFaces > 1) { // We don't know how to deal with 0 faces either. delete entry; return nullptr; }
--- a/gfx/thebes/gfxDWriteFontList.h +++ b/gfx/thebes/gfxDWriteFontList.h @@ -110,23 +110,28 @@ public: gfxDWriteFontEntry(const nsAString& aFaceName, IDWriteFont *aFont, bool aIsSystemFont = false) : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr), mIsSystemFont(aIsSystemFont), mForceGDIClassic(false), mHasVariations(false), mHasVariationsInitialized(false) { DWRITE_FONT_STYLE dwriteStyle = aFont->GetStyle(); - mStyle = (dwriteStyle == DWRITE_FONT_STYLE_ITALIC ? - FontSlantStyle::Italic() : - (dwriteStyle == DWRITE_FONT_STYLE_OBLIQUE ? - FontSlantStyle::Oblique() : FontSlantStyle::Normal())); - mStretch = FontStretchFromDWriteStretch(aFont->GetStretch()); + FontSlantStyle style = + (dwriteStyle == DWRITE_FONT_STYLE_ITALIC + ? FontSlantStyle::Italic() + : (dwriteStyle == DWRITE_FONT_STYLE_OBLIQUE + ? FontSlantStyle::Oblique() + : FontSlantStyle::Normal())); + mStyleRange = SlantStyleRange(style); + + mStretchRange = + StretchRange(FontStretchFromDWriteStretch(aFont->GetStretch())); + int weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100); - weight = mozilla::Clamp(weight, 100, 900); mWeightRange = WeightRange(FontWeight(weight)); mIsCJK = UNINITIALIZED_VALUE; } /** * Constructs a font entry using a font. But with custom font values. @@ -136,26 +141,26 @@ public: * \param aFaceName The name of the corresponding font face. * \param aFont DirectWrite font object * \param aWeight Weight of the font * \param aStretch Stretch of the font * \param aStyle italic or oblique of font */ gfxDWriteFontEntry(const nsAString& aFaceName, IDWriteFont *aFont, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle) : gfxFontEntry(aFaceName), mFont(aFont), mFontFile(nullptr), mIsSystemFont(false), mForceGDIClassic(false), mHasVariations(false), mHasVariationsInitialized(false) { - mWeightRange = WeightRange(aWeight); - mStretch = aStretch; - mStyle = aStyle; + mWeightRange = aWeight; + mStretchRange = aStretch; + mStyleRange = aStyle; mIsLocalUserFont = true; mIsCJK = UNINITIALIZED_VALUE; } /** * Constructs a font entry using a font file. * * \param aFaceName The name of the corresponding font face. @@ -163,27 +168,27 @@ public: * \param aFontFileStream DirectWrite fontfile stream object * \param aWeight Weight of the font * \param aStretch Stretch of the font * \param aStyle italic or oblique of font */ gfxDWriteFontEntry(const nsAString& aFaceName, IDWriteFontFile *aFontFile, IDWriteFontFileStream *aFontFileStream, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle) : gfxFontEntry(aFaceName), mFont(nullptr), mFontFile(aFontFile), mFontFileStream(aFontFileStream), mIsSystemFont(false), mForceGDIClassic(false), mHasVariations(false), mHasVariationsInitialized(false) { - mWeightRange = WeightRange(aWeight); - mStretch = aStretch; - mStyle = aStyle; + mWeightRange = aWeight; + mStretchRange = aStretch; + mStyleRange = aStyle; mIsDataUserFont = true; mIsCJK = UNINITIALIZED_VALUE; } gfxFontEntry* Clone() const override; virtual ~gfxDWriteFontEntry(); @@ -400,24 +405,24 @@ public: } // initialize font lists virtual nsresult InitFontListForPlatform() override; gfxFontFamily* CreateFontFamily(const nsAString& aName) const override; virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle); + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry); virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength); bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName); IDWriteGdiInterop *GetGDIInterop() { return mGDIInterop; } bool UseGDIFontTableAccess() { return mGDIFontTableAccess; }
--- a/gfx/thebes/gfxFT2FontBase.cpp +++ b/gfx/thebes/gfxFT2FontBase.cpp @@ -224,20 +224,17 @@ gfxFT2FontBase::InitMetrics() mMetrics.underlineOffset = -underlineSize; mMetrics.strikeoutOffset = 0.25 * emHeight; mMetrics.strikeoutSize = underlineSize; SanitizeMetrics(&mMetrics, false); return; } - if ((!mFontEntry->mVariationSettings.IsEmpty() || - !mStyle.variationSettings.IsEmpty() || - !mFontEntry->Weight().IsSingle()) && - (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { + if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) { // Resolve variations from entry (descriptor) and style (property) AutoTArray<gfxFontVariation,8> settings; mFontEntry->GetVariationsForStyle(settings, mStyle); SetupVarCoords(face, settings, &mCoords); if (!mCoords.IsEmpty()) { #if MOZ_TREE_FREETYPE FT_Set_Var_Design_Coordinates(face, mCoords.Length(), mCoords.Elements()); #else
--- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -220,18 +220,18 @@ FT2FontEntry::~FT2FontEntry() gfxFontEntry* FT2FontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); FT2FontEntry* fe = new FT2FontEntry(Name()); fe->mFilename = mFilename; fe->mFTFontIndex = mFTFontIndex; fe->mWeightRange = mWeightRange; - fe->mStretch = mStretch; - fe->mStyle = mStyle; + fe->mStretchRange = mStretchRange; + fe->mStyleRange = mStyleRange; return fe; } gfxFont* FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) { cairo_scaled_font_t *scaledFont = CreateScaledFont(aFontStyle); if (!scaledFont) { @@ -252,19 +252,19 @@ FT2FontEntry::CreateFontInstance(const g aFontStyle, aNeedsBold); cairo_scaled_font_destroy(scaledFont); return font; } /* static */ FT2FontEntry* FT2FontEntry::CreateFontEntry(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const uint8_t* aFontData, uint32_t aLength) { // Ownership of aFontData is passed in here; the fontEntry must // retain it as long as the FT_Face needs it, and ensure it is // eventually deleted. FT_Face face = Factory::NewFTFaceFromData(nullptr, aFontData, aLength, 0); if (!face) { @@ -277,19 +277,19 @@ FT2FontEntry::CreateFontEntry(const nsAS return nullptr; } // Create our FT2FontEntry, which inherits the name of the userfont entry // as it's not guaranteed that the face has valid names (bug 737315) FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(face, nullptr, 0, aFontName, aFontData, aLength); if (fe) { - fe->mStyle = aStyle; - fe->mWeightRange = WeightRange(aWeight); - fe->mStretch = aStretch; + fe->mStyleRange = aStyle; + fe->mWeightRange = aWeight; + fe->mStretchRange = aStretch; fe->mIsDataUserFont = true; } return fe; } class FTUserFontData { public: FTUserFontData(FT_Face aFace, const uint8_t* aData, uint32_t aLength) @@ -323,23 +323,19 @@ FTFontDestroyFunc(void *data) /* static */ FT2FontEntry* FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE) { FT2FontEntry *fe = new FT2FontEntry(aFLE.faceName()); fe->mFilename = aFLE.filepath(); fe->mFTFontIndex = aFLE.index(); - // The weight transported across IPC is a float, so we need to explicitly - // convert it back to a FontWeight. - fe->mWeightRange = WeightRange(FontWeight(aFLE.minWeight()), - FontWeight(aFLE.maxWeight())); - fe->mStretch = FontStretch(float(aFLE.stretch())); - fe->mStyle = aFLE.italic() - ? FontSlantStyle::Italic() : FontSlantStyle::Normal(); + fe->mWeightRange = WeightRange::FromScalar(aFLE.weightRange()); + fe->mStretchRange = StretchRange::FromScalar(aFLE.stretchRange()); + fe->mStyleRange = SlantStyleRange::FromScalar(aFLE.styleRange()); return fe; } // Helpers to extract font entry properties from an FT_Face static bool FTFaceIsItalic(FT_Face aFace) { return !!(aFace->style_flags & FT_STYLE_FLAG_ITALIC); @@ -387,18 +383,19 @@ FTFaceGetWeight(FT_Face aFace) FT2FontEntry* FT2FontEntry::CreateFontEntry(FT_Face aFace, const char* aFilename, uint8_t aIndex, const nsAString& aName, const uint8_t* aFontData, uint32_t aLength) { FT2FontEntry *fe = new FT2FontEntry(aName); - fe->mStyle = (FTFaceIsItalic(aFace) ? - FontSlantStyle::Italic() : FontSlantStyle::Normal()); + fe->mStyleRange = SlantStyleRange(FTFaceIsItalic(aFace) + ? FontSlantStyle::Italic() + : FontSlantStyle::Normal()); fe->mWeightRange = WeightRange(FTFaceGetWeight(aFace)); fe->mFilename = aFilename; fe->mFTFontIndex = aIndex; if (aFontData) { fe->mFTFace = aFace; int flags = gfxPlatform::GetPlatform()->FontHintingEnabled() ? FT_LOAD_DEFAULT : @@ -456,18 +453,17 @@ FT2FontEntry::CairoFontFace(const gfxFon userFontData, FTFontDestroyFunc); mFTFace = face.forget(); } // If variations are present, we will not use our cached mFontFace // but always create a new cairo_font_face_t because its FT_Face will // have custom variation coordinates applied. if ((!mVariationSettings.IsEmpty() || - (aStyle && !aStyle->variationSettings.IsEmpty()) || - !Weight().IsSingle()) && + (aStyle && !aStyle->variationSettings.IsEmpty())) && (mFTFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { int flags = gfxPlatform::GetPlatform()->FontHintingEnabled() ? FT_LOAD_DEFAULT : (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING); // Resolve variations from entry (descriptor) and style (property) AutoTArray<gfxFontVariation,8> settings; GetVariationsForStyle(settings, aStyle ? *aStyle : gfxFontStyle()); AutoTArray<FT_Fixed,8> coords; @@ -650,27 +646,22 @@ FT2FontFamily::AddFacesToFontList(Infall { for (int i = 0, n = mAvailableFonts.Length(); i < n; ++i) { const FT2FontEntry *fe = static_cast<const FT2FontEntry*>(mAvailableFonts[i].get()); if (!fe) { continue; } - // We convert the weight to a float purely for transport across IPC. - // Ideally we'd avoid doing that. aFontList->AppendElement(FontListEntry(Name(), fe->Name(), fe->mFilename, - fe->Weight().Min().ToFloat(), - fe->Weight().Max().ToFloat(), - fe->Stretch().Percentage(), - fe->mStyle.IsItalic() - ? NS_FONT_STYLE_ITALIC - : NS_FONT_STYLE_NORMAL, + fe->Weight().AsScalar(), + fe->Stretch().AsScalar(), + fe->SlantStyle().AsScalar(), fe->mFTFontIndex)); } } /* * Startup cache support for the font list: * We store the list of families and faces, with their style attributes and the * corresponding font files, in the startup cache. @@ -934,52 +925,75 @@ gfxFT2FontList::AppendFacesFromCachedFac const nsCString& aFaceList, StandardFile aStdFile) { const char *beginning = aFaceList.get(); const char *end = strchr(beginning, ','); while (end) { NS_ConvertUTF8toUTF16 familyName(beginning, end - beginning); ToLowerCase(familyName); + beginning = end + 1; if (!(end = strchr(beginning, ','))) { break; } NS_ConvertUTF8toUTF16 faceName(beginning, end - beginning); + beginning = end + 1; if (!(end = strchr(beginning, ','))) { break; } uint32_t index = strtoul(beginning, nullptr, 10); + beginning = end + 1; if (!(end = strchr(beginning, ','))) { break; } - bool italic = (*beginning != '0'); + nsAutoCString minStyle(beginning, end - beginning); + nsAutoCString maxStyle(minStyle); + int32_t colon = minStyle.FindChar(':'); + if (colon > 0) { + maxStyle.Assign(minStyle.BeginReading() + colon + 1); + minStyle.Truncate(colon - 1); + } + beginning = end + 1; if (!(end = strchr(beginning, ','))) { break; } char* limit; float minWeight = strtof(beginning, &limit); float maxWeight; if (*limit == ':' && limit + 1 < end) { maxWeight = strtof(limit + 1, nullptr); } else { maxWeight = minWeight; } + beginning = end + 1; if (!(end = strchr(beginning, ','))) { break; } - uint32_t stretch = strtoul(beginning, nullptr, 10); + float minStretch = strtof(beginning, &limit); + float maxStretch; + if (*limit == ':' && limit + 1 < end) { + maxStretch = strtof(limit + 1, nullptr); + } else { + maxStretch = minStretch; + } - FontListEntry fle(familyName, faceName, aFileName, - minWeight, maxWeight, - stretch, italic, index); + FontListEntry fle( + familyName, faceName, aFileName, + WeightRange(FontWeight(minWeight), + FontWeight(maxWeight)).AsScalar(), + StretchRange(FontStretch(minStretch), + FontStretch(maxStretch)).AsScalar(), + SlantStyleRange(FontSlantStyle::FromString(minStyle.get()), + FontSlantStyle::FromString(maxStyle.get())).AsScalar(), + index); AppendFaceFromFontListEntry(fle, aStdFile); beginning = end + 1; end = strchr(beginning, ','); } } static void @@ -993,18 +1007,19 @@ AppendToFaceList(nsCString& aFaceList, aFaceList.AppendInt(aFontEntry->mFTFontIndex); aFaceList.Append(','); aFaceList.Append(aFontEntry->IsItalic() ? '1' : '0'); aFaceList.Append(','); aFaceList.AppendFloat(aFontEntry->Weight().Min().ToFloat()); aFaceList.Append(':'); aFaceList.AppendFloat(aFontEntry->Weight().Max().ToFloat()); aFaceList.Append(','); - // FIXME(emilio): Probably the stretch should be converted to float. - aFaceList.AppendInt(int32_t(aFontEntry->Stretch().Percentage())); + aFaceList.AppendFloat(aFontEntry->Stretch().Min().Percentage()); + aFaceList.Append(':'); + aFaceList.AppendFloat(aFontEntry->Stretch().Max().Percentage()); aFaceList.Append(','); } void FT2FontEntry::CheckForBrokenFont(gfxFontFamily *aFamily) { // note if the family is in the "bad underline" blacklist if (aFamily->IsBadUnderlineFamily()) { @@ -1152,23 +1167,25 @@ gfxFT2FontList::AddFaceToList(const nsCS family->AddFontEntry(fe); fe->CheckForBrokenFont(family); AppendToFaceList(aFaceList, name, fe); if (LOG_ENABLED()) { nsAutoCString weightString; fe->Weight().ToString(weightString); + nsAutoCString stretchString; + fe->Stretch().ToString(stretchString); LOG(("(fontinit) added (%s) to family (%s)" - " with style: %s weight: %s stretch: %g%%", + " with style: %s weight: %s stretch: %s", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(family->Name()).get(), fe->IsItalic() ? "italic" : "normal", weightString.get(), - fe->Stretch().Percentage())); + stretchString.get())); } } } void gfxFT2FontList::AppendFacesFromOmnijarEntry(nsZipArchive* aArchive, const nsCString& aEntryName, FontNameCache *aCache, @@ -1468,19 +1485,19 @@ gfxFT2FontList::InitFontListForPlatform( return NS_OK; } // called for each family name, based on the assumption that the // first part of the full name is the family name gfxFontEntry* gfxFT2FontList::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) { // walk over list of names FT2FontEntry* fontEntry = nullptr; nsString fullName(aFontName); for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) { // Check family name, based on the assumption that the // first part of the full name is the family name @@ -1525,19 +1542,19 @@ searchDone: } FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(fontEntry->mFTFace, fontEntry->mFilename.get(), fontEntry->mFTFontIndex, fontEntry->Name(), nullptr); if (fe) { - fe->mStyle = aStyle; - fe->mWeightRange = WeightRange(aWeight); - fe->mStretch = aStretch; + fe->mStyleRange = aStyleForEntry; + fe->mWeightRange = aWeightForEntry; + fe->mStretchRange = aStretchForEntry; fe->mIsLocalUserFont = true; } return fe; } gfxFontFamily* gfxFT2FontList::GetDefaultFontForPlatform(const gfxFontStyle* aStyle) @@ -1550,27 +1567,30 @@ gfxFT2FontList::GetDefaultFontForPlatfor } #endif /* TODO: what about Qt or other platforms that may use this? */ return ff; } gfxFontEntry* gfxFT2FontList::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) { // The FT2 font needs the font data to persist, so we do NOT free it here // but instead pass ownership to the font entry. // Deallocation will happen later, when the font face is destroyed. - return FT2FontEntry::CreateFontEntry(aFontName, aWeight, aStretch, - aStyle, aFontData, aLength); + return FT2FontEntry::CreateFontEntry(aFontName, + aWeightForEntry, + aStretchForEntry, + aStyleForEntry, + aFontData, aLength); } void gfxFT2FontList::GetFontFamilyList(nsTArray<RefPtr<gfxFontFamily> >& aFamilyArray) { for (auto iter = mFontFamilies.Iter(); !iter.Done(); iter.Next()) { RefPtr<gfxFontFamily>& family = iter.Data(); aFamilyArray.AppendElement(family);
--- a/gfx/thebes/gfxFT2FontList.h +++ b/gfx/thebes/gfxFT2FontList.h @@ -38,19 +38,19 @@ public: const nsString& GetName() const { return Name(); } // create a font entry for a downloaded font static FT2FontEntry* CreateFontEntry(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const uint8_t* aFontData, uint32_t aLength); // create a font entry representing an installed font, identified by // a FontListEntry; the freetype and cairo faces will not be instantiated // until actually needed static FT2FontEntry* CreateFontEntry(const FontListEntry& aFLE); @@ -117,24 +117,24 @@ public: class gfxFT2FontList : public gfxPlatformFontList { public: gfxFT2FontList(); virtual ~gfxFT2FontList(); virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) override; + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) override; virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) override; void GetSystemFontList(InfallibleTArray<FontListEntry>* retValue); static gfxFT2FontList* PlatformFontList() { return static_cast<gfxFT2FontList*>(gfxPlatformFontList::PlatformFontList()); }
--- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -240,34 +240,34 @@ gfxFontconfigFontEntry::gfxFontconfigFon mAspect(0.0), mFontData(nullptr), mLength(0) { // italic int slant; if (FcPatternGetInteger(aFontPattern, FC_SLANT, 0, &slant) != FcResultMatch) { slant = FC_SLANT_ROMAN; } if (slant == FC_SLANT_OBLIQUE) { - mStyle = FontSlantStyle::Oblique(); + mStyleRange = SlantStyleRange(FontSlantStyle::Oblique()); } else if (slant > 0) { - mStyle = FontSlantStyle::Italic(); + mStyleRange = SlantStyleRange(FontSlantStyle::Italic()); } // weight int weight; if (FcPatternGetInteger(aFontPattern, FC_WEIGHT, 0, &weight) != FcResultMatch) { weight = FC_WEIGHT_REGULAR; } mWeightRange = WeightRange(MapFcWeight(weight)); // width int width; if (FcPatternGetInteger(aFontPattern, FC_WIDTH, 0, &width) != FcResultMatch) { width = FC_WIDTH_NORMAL; } - mStretch = MapFcWidth(width); + mStretchRange = StretchRange(MapFcWidth(width)); } gfxFontEntry* gfxFontconfigFontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); return new gfxFontconfigFontEntry(Name(), mFontPattern, mIgnoreFcCharmap); } @@ -311,51 +311,51 @@ CreateFaceForPattern(FcPattern* aPattern int index; if (FcPatternGetInteger(aPattern, FC_INDEX, 0, &index) != FcResultMatch) { index = 0; // default to 0 if not found in pattern } return Factory::NewFTFace(nullptr, ToCharPtr(filename), index); } gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const uint8_t *aData, uint32_t aLength, FT_Face aFace) : gfxFontEntry(aFaceName), mFTFace(aFace), mFTFaceInitialized(true), mIgnoreFcCharmap(true), mHasVariationsInitialized(false), mAspect(0.0), mFontData(aData), mLength(aLength) { - mWeightRange = WeightRange(aWeight); - mStyle = aStyle; - mStretch = aStretch; + mWeightRange = aWeight; + mStyleRange = aStyle; + mStretchRange = aStretch; mIsDataUserFont = true; mFontPattern = CreatePatternForFace(mFTFace); mUserFontData = new FTUserFontData(mFTFace, mFontData); } gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, FcPattern* aFontPattern, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle) : gfxFontEntry(aFaceName), mFontPattern(aFontPattern), mFTFace(nullptr), mFTFaceInitialized(false), mHasVariationsInitialized(false), mAspect(0.0), mFontData(nullptr), mLength(0) { - mWeightRange = WeightRange(aWeight); - mStyle = aStyle; - mStretch = aStretch; + mWeightRange = aWeight; + mStyleRange = aStyle; + mStretchRange = aStretch; mIsLocalUserFont = true; // The proper setting of mIgnoreFcCharmap is tricky for fonts loaded // via src:local()... // If the local font happens to come from the application fontset, // we want to set it to true so that color/svg fonts will work even // if the default glyphs are blank; but if the local font is a non- // sfnt face (e.g. legacy type 1) then we need to set it to false @@ -766,19 +766,17 @@ gfxFontconfigFontEntry::CreateScaledFont if (needsOblique) { // disable embedded bitmaps (mimics behavior in 90-synthetic.conf) FcPatternDel(aRenderPattern, FC_EMBEDDED_BITMAP); FcPatternAddBool(aRenderPattern, FC_EMBEDDED_BITMAP, FcFalse); } AutoTArray<FT_Fixed,8> coords; - if (!aStyle->variationSettings.IsEmpty() || - !mVariationSettings.IsEmpty() || - !Weight().IsSingle()) { + if (HasVariations()) { FT_Face ftFace = GetFTFace(); if (ftFace) { AutoTArray<gfxFontVariation,8> settings; GetVariationsForStyle(settings, *aStyle); gfxFT2FontBase::SetupVarCoords(ftFace, settings, &coords); } } @@ -1216,25 +1214,28 @@ gfxFontconfigFontFamily::FindStyleVariat if (fontEntry->IsNormalStyle()) { numRegularFaces++; } if (LOG_FONTLIST_ENABLED()) { nsAutoCString weightString; fontEntry->Weight().ToString(weightString); + nsAutoCString stretchString; + fontEntry->Stretch().ToString(stretchString); + nsAutoCString styleString; + fontEntry->SlantStyle().ToString(styleString); LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %s stretch: %g%%" + " with style: %s weight: %s stretch: %s" " psname: %s fullname: %s", NS_ConvertUTF16toUTF8(fontEntry->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), - (fontEntry->IsItalic()) ? - "italic" : (fontEntry->IsOblique() ? "oblique" : "normal"), + styleString.get(), weightString.get(), - fontEntry->Stretch().Percentage(), + stretchString.get(), NS_ConvertUTF16toUTF8(psname).get(), NS_ConvertUTF16toUTF8(fullname).get())); } } // somewhat arbitrary, but define a family with two or more regular // faces as a family for which intra-family fallback should be used if (numRegularFaces > 1) { @@ -1329,19 +1330,18 @@ gfxFontconfigFontFamily::FindAllFontsFor static_cast<gfxFontconfigFontEntry*>(aFontEntryList[i]); double dist = SizeDistance(entry, aFontStyle, mForceScalable || aIgnoreSizeTolerance); // If the entry is scalable or has a style that does not match // the group of unscalable fonts, then start a new group. if (dist < 0.0 || !bestEntry || bestEntry->Stretch() != entry->Stretch() || - bestEntry->Weight().Min() != entry->Weight().Min() || - bestEntry->Weight().Max() != entry->Weight().Max() || - bestEntry->mStyle != entry->mStyle) { + bestEntry->Weight() != entry->Weight() || + bestEntry->SlantStyle() != entry->SlantStyle()) { // If the best entry in this group is still outside the tolerance, // then skip the entire group. if (bestDist >= kRejectDistance) { skipped++; } // Remove any compacted entries from the previous group. if (skipped) { i -= skipped; @@ -1874,54 +1874,59 @@ gfxFcPlatformFontList::GetDefaultFontFor if (prefFonts && !prefFonts->IsEmpty()) { return (*prefFonts)[0]; } return nullptr; } gfxFontEntry* gfxFcPlatformFontList::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) { nsAutoString keyName(aFontName); ToLowerCase(keyName); // if name is not in the global list, done FcPattern* fontPattern = mLocalNames.Get(keyName); if (!fontPattern) { return nullptr; } return new gfxFontconfigFontEntry(aFontName, fontPattern, - aWeight, aStretch, aStyle); + aWeightForEntry, + aStretchForEntry, + aStyleForEntry); } gfxFontEntry* gfxFcPlatformFontList::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) { FT_Face face = Factory::NewFTFaceFromData(nullptr, aFontData, aLength, 0); if (!face) { free((void*)aFontData); return nullptr; } if (FT_Err_Ok != FT_Select_Charmap(face, FT_ENCODING_UNICODE)) { Factory::ReleaseFTFace(face); free((void*)aFontData); return nullptr; } - return new gfxFontconfigFontEntry(aFontName, aWeight, aStretch, - aStyle, aFontData, aLength, face); + return new gfxFontconfigFontEntry(aFontName, + aWeightForEntry, + aStretchForEntry, + aStyleForEntry, + aFontData, aLength, face); } bool gfxFcPlatformFontList::FindAndAddFamilies(const nsAString& aFamily, nsTArray<gfxFontFamily*>* aOutput, FindFamiliesFlags aFlags, gfxFontStyle* aStyle, gfxFloat aDevToCssSize)
--- a/gfx/thebes/gfxFcPlatformFontList.h +++ b/gfx/thebes/gfxFcPlatformFontList.h @@ -89,29 +89,29 @@ public: // used for system fonts with explicit patterns explicit gfxFontconfigFontEntry(const nsAString& aFaceName, FcPattern* aFontPattern, bool aIgnoreFcCharmap); // used for data fonts where the fontentry takes ownership // of the font data and the FT_Face explicit gfxFontconfigFontEntry(const nsAString& aFaceName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const uint8_t *aData, uint32_t aLength, FT_Face aFace); // used for @font-face local system fonts with explicit patterns explicit gfxFontconfigFontEntry(const nsAString& aFaceName, FcPattern* aFontPattern, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle); + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle); gfxFontEntry* Clone() const override; FcPattern* GetPattern() { return mFontPattern; } nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override; bool TestCharacterMap(uint32_t aCh) override; @@ -291,25 +291,25 @@ public: const nsACString& aGenericFamily, nsTArray<nsString>& aListOfFonts) override; void ReadSystemFontList( InfallibleTArray<mozilla::dom::SystemFontListEntry>* retValue); gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) override; + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) override; gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) override; bool FindAndAddFamilies(const nsAString& aFamily, nsTArray<gfxFontFamily*>* aOutput, FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr, gfxFloat aDevToCssSize = 1.0) override;
--- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -76,18 +76,18 @@ gfxFontEntry::gfxFontEntry() : mHasGraphiteSpaceContextuals(false), mSpaceGlyphIsInvisible(false), mSpaceGlyphIsInvisibleInitialized(false), mCheckedForGraphiteTables(false), mHasCmapTable(false), mGrFaceInitialized(false), mCheckedForColorGlyph(false), mWeightRange(FontWeight(500)), - mStretch(FontStretch::Normal()), - mStyle(FontSlantStyle::Normal()), + mStretchRange(FontStretch::Normal()), + mStyleRange(FontSlantStyle::Normal()), mUVSOffset(0), mUVSData(nullptr), mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE), mCOLR(nullptr), mCPAL(nullptr), mUnitsPerEm(0), mHBFace(nullptr), mGrFace(nullptr), mGrFaceRefCnt(0), @@ -115,18 +115,18 @@ gfxFontEntry::gfxFontEntry(const nsAStri mHasGraphiteSpaceContextuals(false), mSpaceGlyphIsInvisible(false), mSpaceGlyphIsInvisibleInitialized(false), mCheckedForGraphiteTables(false), mHasCmapTable(false), mGrFaceInitialized(false), mCheckedForColorGlyph(false), mWeightRange(FontWeight(500)), - mStretch(FontStretch::Normal()), - mStyle(FontSlantStyle::Normal()), + mStretchRange(FontStretch::Normal()), + mStyleRange(FontSlantStyle::Normal()), mUVSOffset(0), mUVSData(nullptr), mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE), mCOLR(nullptr), mCPAL(nullptr), mUnitsPerEm(0), mHBFace(nullptr), mGrFace(nullptr), mGrFaceRefCnt(0), @@ -1044,50 +1044,87 @@ gfxFontEntry::SetupVariationRanges() switch (axis.mTag) { case HB_TAG('w','g','h','t'): // If the axis range looks like it doesn't fit the CSS font-weight // scale, we don't hook up the high-level property. Setting 'wght' // with font-variation-settings will still work. // Strictly speaking, the min value should be checked against 1.0, // not 0.0, but we'll allow font makers that amount of leeway, as // in practice a number of fonts seem to use 0..1000. - if (axis.mMinValue >= 0.0f && axis.mMaxValue <= 1000.0 && + if (axis.mMinValue >= 0.0f && axis.mMaxValue <= 1000.0f && // If axis.mMaxValue is less than the default weight we already // set up, assume the axis has a non-standard range (like Skia) // and don't try to map it. Weight().Min() <= FontWeight(axis.mMaxValue)) { - mStandardFace = FontWeight(axis.mDefaultValue) == Weight().Min(); + if (FontWeight(axis.mDefaultValue) != Weight().Min()) { + mStandardFace = false; + } mWeightRange = WeightRange(FontWeight(std::max(1.0f, axis.mMinValue)), FontWeight(axis.mMaxValue)); } break; - // XXX todo: - // case HB_TAG('w','d','t','h'): - // case HB_TAG('s','l','n','t'): - // case HB_TAG('i','t','a','l'): + + case HB_TAG('w','d','t','h'): + if (axis.mMinValue >= 0.0f && axis.mMaxValue <= 1000.0f && + Stretch().Min() <= FontStretch(axis.mMaxValue)) { + if (FontStretch(axis.mDefaultValue) != Stretch().Min()) { + mStandardFace = false; + } + mStretchRange = + StretchRange(FontStretch(axis.mMinValue), + FontStretch(axis.mMaxValue)); + } + break; + + case HB_TAG('s','l','n','t'): + if (axis.mMinValue >= -90.0f && axis.mMaxValue <= 90.0f) { + if (FontSlantStyle::Oblique(axis.mDefaultValue) != SlantStyle().Min()) { + mStandardFace = false; + } + mStyleRange = + SlantStyleRange(FontSlantStyle::Oblique(axis.mMinValue), + FontSlantStyle::Oblique(axis.mMaxValue)); + } + break; + + // case HB_TAG('i','t','a','l'): // XXX how to handle? default: continue; } } } void gfxFontEntry::GetVariationsForStyle(nsTArray<gfxFontVariation>& aResult, const gfxFontStyle& aStyle) { // Resolve high-level CSS properties from the requested style // (font-{style,weight,stretch}) to the appropriate variations. - if (!Weight().IsSingle()) { - float clampedWeight = Weight().Clamp(aStyle.weight).ToFloat(); - aResult.AppendElement(gfxFontVariation{HB_TAG('w','g','h','t'), - clampedWeight}); + float clampedWeight = Weight().Clamp(aStyle.weight).ToFloat(); + aResult.AppendElement(gfxFontVariation{HB_TAG('w','g','h','t'), + clampedWeight}); + + float clampedStretch = Stretch().Clamp(aStyle.stretch).Percentage(); + aResult.AppendElement(gfxFontVariation{HB_TAG('w','d','t','h'), + clampedStretch}); + + if (SlantStyle().Min().IsOblique()) { + float clampedSlant = + aStyle.style.IsOblique() + ? SlantStyle().Clamp(aStyle.style).ObliqueAngle() + : aStyle.style.IsItalic() + ? SlantStyle().Clamp(FontSlantStyle::Oblique()).ObliqueAngle() + : SlantStyle().Clamp(FontSlantStyle::Oblique(0.0f)).ObliqueAngle(); + aResult.AppendElement(gfxFontVariation{HB_TAG('s','l','n','t'), + clampedSlant}); } - // XXX todo: 'wdth', 'slnt', 'ital' + // Although there is a registered tag 'ital', it is normally considered + // a binary toggle rather than a variable axis, auto replaceOrAppend = [&aResult](const gfxFontVariation& aSetting) { struct TagEquals { bool Equals(const gfxFontVariation& aIter, uint32_t aTag) const { return aIter.mTag == aTag; } }; auto index = aResult.IndexOf(aSetting.mTag, 0, TagEquals()); @@ -1253,84 +1290,125 @@ gfxFontFamily::FindFontForStyle(const gf FindAllFontsForStyle(aFontStyle, matched, aNeedsSyntheticBold, aIgnoreSizeTolerance); if (!matched.IsEmpty()) { return matched[0]; } return nullptr; } -#define STYLE_SHIFT 2 // number of bits to contain style distance - -// style distance ==> [0,2] -static inline uint32_t -StyleDistance(FontSlantStyle aFontStyle, FontSlantStyle aTargetStyle) +// style distance ==> [0,500] +static inline double +StyleDistance(const gfxFontEntry* aFontEntry, FontSlantStyle aTargetStyle) { - if (aFontStyle == aTargetStyle) { - return 0; // styles match exactly ==> 0 + FontSlantStyle minStyle = aFontEntry->SlantStyle().Min(); + if (aTargetStyle == minStyle) { + return 0.0; // styles match exactly ==> 0 + } + + // Compare oblique angles to see how closely they match. + // The range of angles is [-90.0 .. 90.0], although in practice values + // are unlikely to get anywhere near the extremes. + // The style 'italic' is treated as having the same angle as the default + // for 'oblique', but with a constant added to the distance to reflect + // distinction. + + double extraDistance = 0.0; + const double kReverseDistance = 100.0; + + double target; + if (aTargetStyle.IsNormal()) { + target = 0.0; + extraDistance = 300.0; + } else if (aTargetStyle.IsOblique()) { + target = aTargetStyle.ObliqueAngle(); + } else { + target = FontSlantStyle::Oblique().ObliqueAngle(); + extraDistance = 200.0; } - if (aFontStyle == FontSlantStyle::Normal() || - aTargetStyle == FontSlantStyle::Normal()) { - return 2; // one is normal (but not the other) ==> 2 + + FontSlantStyle maxStyle = aFontEntry->SlantStyle().Max(); + + double minAngle, maxAngle; + // There can only be a range of styles if it's oblique + if (minStyle.IsNormal()) { + minAngle = maxAngle = 0.0; + extraDistance = 300.0; + } else if (minStyle.IsOblique()) { + MOZ_ASSERT(maxStyle.IsOblique()); + minAngle = minStyle.ObliqueAngle(); + maxAngle = maxStyle.ObliqueAngle(); + } else { + minAngle = maxAngle = FontSlantStyle::Oblique().ObliqueAngle(); + extraDistance = 200.0; } - return 1; // neither is normal; must be italic vs oblique ==> 1 + + double distance = 0.0; + if (target < minAngle || target > maxAngle) { + if (target > 0.0) { + distance = minAngle - target; + } else { + distance = target - maxAngle; + } + } + if (distance < 0.0) { + distance = kReverseDistance - distance; + } + + return distance + extraDistance; } -#define REVERSE_STRETCH_DISTANCE 200.0f +// stretch distance ==> [0,2000] +static inline double +StretchDistance(const gfxFontEntry* aFontEntry, FontStretch aTargetStretch) +{ + const double kReverseDistance = 1000.0; + double distance = 0.0; -// stretch distance ==> [0,350] -static inline uint32_t -StretchDistance(FontStretch aFontStretch, FontStretch aTargetStretch) -{ - float distance = 0.0f; - if (aTargetStretch != aFontStretch) { - // stretch values are in the range 50 .. 200 + FontStretch minStretch = aFontEntry->Stretch().Min(); + FontStretch maxStretch = aFontEntry->Stretch().Max(); + + if (aTargetStretch < minStretch || aTargetStretch > maxStretch) { + // stretch values are in the range 0 .. 1000 // if aTargetStretch is >100, we prefer larger values; // if <=100, prefer smaller if (aTargetStretch > FontStretch::Normal()) { - distance = (aFontStretch - aTargetStretch); + distance = (minStretch - aTargetStretch); } else { - distance = (aTargetStretch - aFontStretch); + distance = (aTargetStretch - maxStretch); } // if the computed "distance" here is negative, it means that // aFontEntry lies in the "non-preferred" direction from aTargetStretch, // so we treat that as larger than any preferred-direction distance - // (max possible is 150) by adding an extra 200 to the absolute value + // (max possible is 1000) by adding an extra 1000 to the absolute value if (distance < 0.0f) { - distance = -distance + REVERSE_STRETCH_DISTANCE; + distance = kReverseDistance - distance; } } - return uint32_t(distance); + return distance; } -// CSS currently limits font weights to multiples of 100 but the weight -// matching code below does not assume this. -// // Calculate weight distance with values in the range (0..1000). In general, // heavier weights match towards even heavier weights while lighter weights // match towards even lighter weights. Target weight values in the range // [400..500] are special, since they will first match up to 500, then down // towards 0, then up again towards 999. // // Example: with target 600 and font weight 800, distance will be 200. With // target 300 and font weight 600, distance will be 900, since heavier // weights are farther away than lighter weights. If the target is 5 and the // font weight 995, the distance would be 1590 for the same reason. -#define REVERSE_WEIGHT_DISTANCE 600 -#define WEIGHT_SHIFT 11 // number of bits to contain weight distance - -// weight distance ==> [0,1598] -static inline uint32_t +// weight distance ==> [0,1600] +static inline double WeightDistance(const gfxFontEntry* aFontEntry, FontWeight aTargetWeight) { - // Compute a measure of the "distance" between the requested - // weight and the given fontEntry + const double kReverseDistance = 600.0; - float distance = 0.0f, addedDistance = 0.0f; + double distance = 0.0, addedDistance = 0.0; FontWeight minWeight = aFontEntry->Weight().Min(); FontWeight maxWeight = aFontEntry->Weight().Max(); if (aTargetWeight < minWeight || aTargetWeight > maxWeight) { if (aTargetWeight > FontWeight(500)) { distance = minWeight - aTargetWeight; } else if (aTargetWeight < FontWeight(400)) { distance = aTargetWeight - maxWeight; } else { @@ -1344,45 +1422,47 @@ WeightDistance(const gfxFontEntry* aFont } else { distance = minWeight - aTargetWeight; } } else { // font weights outside use rule for target weights < 400 with // added distance to separate from font weights in // the [400..500] range distance = aTargetWeight - maxWeight; - addedDistance = 100; + addedDistance = 100.0; } } - if (distance < 0.0f) { - distance = -distance + REVERSE_WEIGHT_DISTANCE; + if (distance < 0.0) { + distance = kReverseDistance - distance; } distance += addedDistance; } - return uint32_t(distance); + return distance; } -#define MAX_DISTANCE 0xffffffff +#define MAX_DISTANCE 1.0e20 // >> than any WeightStyleStretchDistance result -static inline uint32_t +static inline double WeightStyleStretchDistance(gfxFontEntry* aFontEntry, const gfxFontStyle& aTargetStyle) { - // weight/style/stretch priority: stretch >> style >> weight - uint32_t stretchDist = - StretchDistance(aFontEntry->mStretch, aTargetStyle.stretch); - uint32_t styleDist = StyleDistance(aFontEntry->mStyle, aTargetStyle.style); - uint32_t weightDist = WeightDistance(aFontEntry, aTargetStyle.weight); + double stretchDist = StretchDistance(aFontEntry, aTargetStyle.stretch); + double styleDist = StyleDistance(aFontEntry, aTargetStyle.style); + double weightDist = WeightDistance(aFontEntry, aTargetStyle.weight); - NS_ASSERTION(weightDist < (1 << WEIGHT_SHIFT), "weight value out of bounds"); - NS_ASSERTION(styleDist < (1 << STYLE_SHIFT), "slope value out of bounds"); + // Sanity-check that the distances are within the expected range + // (update if implementation of the distance functions is changed). + MOZ_ASSERT(stretchDist >= 0.0 && stretchDist <= 2000.0); + MOZ_ASSERT(styleDist >= 0.0 && styleDist <= 500.0); + MOZ_ASSERT(weightDist >= 0.0 && weightDist <= 1600.0); - return (stretchDist << (STYLE_SHIFT + WEIGHT_SHIFT)) | - (styleDist << WEIGHT_SHIFT) | - weightDist; + // weight/style/stretch priority: stretch >> style >> weight + // so we multiply the stretch and style values to make them dominate + // the result + return stretchDist * 1.0e8 + styleDist * 1.0e4 + weightDist; } void gfxFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle, nsTArray<gfxFontEntry*>& aFontEntryList, bool& aNeedsSyntheticBold, bool aIgnoreSizeTolerance) { @@ -1463,24 +1543,24 @@ gfxFontFamily::FindAllFontsForStyle(cons // given but the 99% use case is only a single font entry per // weight/style/stretch distance value. To optimize this, only add entries // to the matched font array when another entry already has the same // weight/style/stretch distance and add the last matched font entry. For // normal platform fonts with a single font entry for each // weight/style/stretch combination, only the last matched font entry will // be added. - uint32_t minDistance = MAX_DISTANCE; + double minDistance = MAX_DISTANCE; gfxFontEntry* matched = nullptr; // iterate in forward order so that faces like 'Bold' are matched before // matching style distance faces such as 'Bold Outline' (see bug 1185812) for (uint32_t i = 0; i < count; i++) { fe = mAvailableFonts[i]; // weight/style/stretch priority: stretch >> style >> weight - uint32_t distance = WeightStyleStretchDistance(fe, aFontStyle); + double distance = WeightStyleStretchDistance(fe, aFontStyle); if (distance < minDistance) { matched = fe; if (!aFontEntryList.IsEmpty()) { aFontEntryList.Clear(); } minDistance = distance; } else if (distance == minDistance) { if (matched) { @@ -1515,26 +1595,29 @@ gfxFontFamily::CheckForSimpleFamily() // if none then the family is unusable anyway } if (count == 1) { mIsSimpleFamily = true; return; } - FontStretch firstStretch = mAvailableFonts[0]->Stretch(); + StretchRange firstStretch = mAvailableFonts[0]->Stretch(); + if (!firstStretch.IsSingle()) { + return; // family with variation fonts is not considered "simple" + } gfxFontEntry *faces[4] = { 0 }; for (uint8_t i = 0; i < count; ++i) { gfxFontEntry *fe = mAvailableFonts[i]; if (fe->Stretch() != firstStretch || fe->IsOblique()) { // simple families don't have varying font-stretch or oblique return; } - if (fe->Weight().Min() != fe->Weight().Max()) { + if (!fe->Weight().IsSingle() || !fe->SlantStyle().IsSingle()) { return; // family with variation fonts is not considered "simple" } uint8_t faceIndex = (fe->IsItalic() ? kItalicMask : 0) | (fe->IsBold() ? kBoldMask : 0); if (faces[faceIndex]) { return; // two faces resolve to the same slot; family isn't "simple" } faces[faceIndex] = fe;
--- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -111,16 +111,18 @@ struct gfxFontFeatureInfo { class gfxFontEntry { public: typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::unicode::Script Script; typedef mozilla::FontWeight FontWeight; typedef mozilla::FontSlantStyle FontSlantStyle; typedef mozilla::FontStretch FontStretch; typedef mozilla::WeightRange WeightRange; + typedef mozilla::SlantStyleRange SlantStyleRange; + typedef mozilla::StretchRange StretchRange; // Used by stylo NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontEntry) explicit gfxFontEntry(const nsAString& aName, bool aIsStandardFace = false); // Create a new entry that refers to the same font as this, but without // additional state that may have been set up (such as family name). @@ -140,40 +142,42 @@ public: // they are intended only for the font-inspection API, not for // perf-critical layout/drawing work. // The "real" name of the face, if available from the font resource; // returns Name() if nothing better is available. virtual nsString RealFaceName(); WeightRange Weight() const { return mWeightRange; } - FontStretch Stretch() const { return mStretch; } + StretchRange Stretch() const { return mStretchRange; } + SlantStyleRange SlantStyle() const { return mStyleRange; } bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; } bool IsLocalUserFont() const { return mIsLocalUserFont; } bool IsFixedPitch() const { return mFixedPitch; } - bool IsItalic() const { return mStyle.IsItalic(); } - bool IsOblique() const { return mStyle.IsOblique(); } - bool IsUpright() const { return mStyle.IsNormal(); } + bool IsItalic() const { return SlantStyle().Min().IsItalic(); } + bool IsOblique() const { return SlantStyle().Min().IsOblique(); } + bool IsUpright() const { return SlantStyle().Min().IsNormal(); } bool IsBold() const { return Weight().Max().IsBold(); } // bold == weights 600 and above bool IgnoreGDEF() const { return mIgnoreGDEF; } bool IgnoreGSUB() const { return mIgnoreGSUB; } // Return whether the face corresponds to "normal" CSS style properties: // font-style: normal; // font-weight: normal; // font-stretch: normal; // If this is false, we might want to fall back to a different face and // possibly apply synthetic styling. bool IsNormalStyle() const { return IsUpright() && Weight().Min() <= FontWeight::Normal() && Weight().Max() >= FontWeight::Normal() && - Stretch().IsNormal(); + Stretch().Min() <= FontStretch::Normal() && + Stretch().Max() >= FontStretch::Normal(); } // whether a feature is supported by the font (limited to a small set // of features for which some form of fallback needs to be implemented) virtual bool SupportsOpenTypeFeature(Script aScript, uint32_t aFeatureTag); bool SupportsGraphiteFeature(uint32_t aFeatureTag); // returns a set containing all input glyph ids for a given feature @@ -413,18 +417,18 @@ public: bool mCheckedForColorGlyph : 1; // bitvector of substitution space features per script, one each // for default and non-default features uint32_t mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; uint32_t mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; WeightRange mWeightRange; - FontStretch mStretch; - FontSlantStyle mStyle; + StretchRange mStretchRange; + SlantStyleRange mStyleRange; RefPtr<gfxCharacterMap> mCharacterMap; uint32_t mUVSOffset; mozilla::UniquePtr<uint8_t[]> mUVSData; mozilla::UniquePtr<gfxUserFontData> mUserFontData; mozilla::UniquePtr<gfxSVGGlyphs> mSVGGlyphs; // list of gfxFonts that are using SVG glyphs nsTArray<gfxFont*> mFontsUsingSVGGlyphs;
--- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -110,44 +110,42 @@ FontTypeToOutPrecision(uint8_t fontType) /*************************************************************** * * GDIFontEntry * */ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType, - FontSlantStyle aStyle, - FontWeight aWeight, - FontStretch aStretch, + SlantStyleRange aStyle, + WeightRange aWeight, + StretchRange aStretch, gfxUserFontData *aUserFontData) : gfxFontEntry(aFaceName), mFontType(aFontType), mForceGDI(false), mUnicodeRanges() { mUserFontData.reset(aUserFontData); - mStyle = aStyle; - mWeightRange = WeightRange(aWeight); - mStretch = aStretch; + mStyleRange = aStyle; + mWeightRange = aWeight; + mStretchRange = aStretch; if (IsType1()) mForceGDI = true; mIsDataUserFont = aUserFontData != nullptr; InitLogFont(aFaceName, aFontType); } gfxFontEntry* GDIFontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); - // GDI fonts don't support variations, so we don't need to worry about - // cloning the weight as a range. - return new GDIFontEntry(Name(), mFontType, mStyle, Weight().Min(), mStretch, - nullptr); + return new GDIFontEntry(Name(), mFontType, SlantStyle(), Weight(), + Stretch(), nullptr); } nsresult GDIFontEntry::ReadCMAP(FontInfoData *aFontInfoData) { AUTO_PROFILER_LABEL("GDIFontEntry::ReadCMAP", OTHER); // attempt this once, if errors occur leave a blank cmap @@ -391,19 +389,19 @@ GDIFontEntry::InitLogFont(const nsAStrin int len = std::min<int>(aName.Length(), LF_FACESIZE - 1); memcpy(&mLogFont.lfFaceName, aName.BeginReading(), len * sizeof(char16_t)); mLogFont.lfFaceName[len] = '\0'; } GDIFontEntry* GDIFontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, - FontSlantStyle aStyle, - FontWeight aWeight, - FontStretch aStretch, + SlantStyleRange aStyle, + WeightRange aWeight, + StretchRange aStretch, gfxUserFontData* aUserFontData) { // jtdfix - need to set charset, unicode ranges, pitch/family GDIFontEntry *fe = new GDIFontEntry(aName, aFontType, aStyle, aWeight, aStretch, aUserFontData); return fe; @@ -480,19 +478,19 @@ GDIFontFamily::FamilyAddStylesProc(const } // We can't set the hasItalicFace flag correctly here, // because we might not have seen the family's italic face(s) yet. // So we'll set that flag for all members after loading all the faces. auto italicStyle = (logFont.lfItalic == 0xFF ? FontSlantStyle::Italic() : FontSlantStyle::Normal()); fe = GDIFontEntry::CreateFontEntry(nsDependentString(lpelfe->elfFullName), - feType, italicStyle, - FontWeight(int32_t(logFont.lfWeight)), - FontStretch::Normal(), + feType, SlantStyleRange(italicStyle), + WeightRange(FontWeight(int32_t(logFont.lfWeight))), + StretchRange(FontStretch::Normal()), nullptr); if (!fe) return 1; ff->AddFontEntry(fe); if (nmetrics->ntmFontSig.fsUsb[0] != 0x00000000 && nmetrics->ntmFontSig.fsUsb[1] != 0x00000000 && @@ -505,25 +503,22 @@ GDIFontFamily::FamilyAddStylesProc(const DWORD range = nmetrics->ntmFontSig.fsUsb[i]; for (uint32_t k = 0; k < 32; ++k) { fe->mUnicodeRanges.set(x++, (range & (1 << k)) != 0); } } } if (LOG_FONTLIST_ENABLED()) { - nsAutoCString stretchString; LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %d stretch: %g%%", + " with style: %s weight: %d stretch: normal", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(ff->Name()).get(), (logFont.lfItalic == 0xff) ? "italic" : "normal", - logFont.lfWeight, - fe->Stretch().Percentage(), - stretchString.get())); + logFont.lfWeight)); } return 1; } void GDIFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) { if (mHasStyles) @@ -711,45 +706,46 @@ gfxGDIFontList::EnumFontFamExProc(ENUMLO family->mCharset.set(metrics.tmCharSet); } return 1; } gfxFontEntry* gfxGDIFontList::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) { gfxFontEntry *lookup; lookup = LookupInFaceNameLists(aFontName); if (!lookup) { return nullptr; } bool isCFF = false; // jtdfix -- need to determine this // use the face name from the lookup font entry, which will be the localized // face name which GDI mapping tables use (e.g. with the system locale set to // Dutch, a fullname of 'Arial Bold' will find a font entry with the face name // 'Arial Vet' which can be used as a key in GDI font lookups). GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(lookup->Name(), gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, - lookup->mStyle, lookup->Weight().Min(), aStretch, nullptr); + lookup->SlantStyle(), lookup->Weight(), aStretchForEntry, nullptr); if (!fe) return nullptr; fe->mIsLocalUserFont = true; // make the new font entry match the userfont entry style characteristics - fe->mWeightRange = WeightRange(aWeight); - fe->mStyle = aStyle; + fe->mWeightRange = aWeightForEntry; + fe->mStyleRange = aStyleForEntry; + fe->mStretchRange = aStretchForEntry; return fe; } // If aFontData contains only a MS/Symbol cmap subtable, not MS/Unicode, // we modify the subtable header to mark it as Unicode instead, because // otherwise GDI will refuse to load the font. // NOTE that this function does not bounds-check every access to the font data. @@ -803,19 +799,19 @@ FixupSymbolEncodedFont(uint8_t* aFontDat return true; } } return false; } gfxFontEntry* gfxGDIFontList::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) { // MakePlatformFont is responsible for deleting the font data with free // so we set up a stack object to ensure it is freed even if we take an // early exit struct FontDataDeleter { explicit FontDataDeleter(const uint8_t* aFontData) @@ -870,17 +866,17 @@ gfxGDIFontList::MakePlatformFont(const n RemoveFontMemResourceEx(fontRef); return nullptr; } // make a new font entry using the unique name WinUserFontData *winUserFontData = new WinUserFontData(fontRef); GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(uniqueName, gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, - aStyle, aWeight, aStretch, winUserFontData); + aStyleForEntry, aWeightForEntry, aStretchForEntry, winUserFontData); if (fe) { fe->mIsDataUserFont = true; } return fe; }
--- a/gfx/thebes/gfxGDIFontList.h +++ b/gfx/thebes/gfxGDIFontList.h @@ -103,20 +103,16 @@ enum gfxWindowsFontType { }; // A single member of a font family (i.e. a single face, such as Times Italic) // represented as a LOGFONT that will resolve to the correct face. // This replaces FontEntry from gfxWindowsFonts.h/cpp. class GDIFontEntry : public gfxFontEntry { public: - typedef mozilla::FontStretch FontStretch; - typedef mozilla::FontSlantStyle FontSlantStyle; - typedef mozilla::FontWeight FontWeight; - LPLOGFONTW GetLogFont() { return &mLogFont; } nsresult ReadCMAP(FontInfoData *aFontInfoData = nullptr) override; void FillLogFont(LOGFONTW *aLogFont, LONG aWeight, gfxFloat aSize); @@ -165,37 +161,31 @@ public: virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const; gfxFontEntry* Clone() const override; // create a font entry for a font with a given name static GDIFontEntry* CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, - FontSlantStyle aStyle, - FontWeight aWeight, - FontStretch aStretch, + SlantStyleRange aStyle, + WeightRange aWeight, + StretchRange aStretch, gfxUserFontData* aUserFontData); - // create a font entry for a font referenced by its fullname - static GDIFontEntry* LoadLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle); - gfxWindowsFontType mFontType; bool mForceGDI; gfxSparseBitSet mUnicodeRanges; protected: friend class gfxGDIFont; GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType, - FontSlantStyle aStyle, FontWeight aWeight, FontStretch aStretch, + SlantStyleRange aStyle, WeightRange aWeight, StretchRange aStretch, gfxUserFontData *aUserFontData); void InitLogFont(const nsAString& aName, gfxWindowsFontType aFontType); virtual gfxFont* CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) override; virtual nsresult CopyFontTable(uint32_t aTableTag, @@ -317,44 +307,40 @@ protected: private: static int CALLBACK FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe, const NEWTEXTMETRICEXW *nmetrics, DWORD fontType, LPARAM data); }; class gfxGDIFontList : public gfxPlatformFontList { public: - typedef mozilla::FontStretch FontStretch; - typedef mozilla::FontSlantStyle FontSlantStyle; - typedef mozilla::FontWeight FontWeight; - static gfxGDIFontList* PlatformFontList() { return static_cast<gfxGDIFontList*>(sPlatformFontList); } // initialize font lists virtual nsresult InitFontListForPlatform() override; gfxFontFamily* CreateFontFamily(const nsAString& aName) const override; bool FindAndAddFamilies(const nsAString& aFamily, nsTArray<gfxFontFamily*>* aOutput, FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr, gfxFloat aDevToCssSize = 1.0) override; virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle); + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry); virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength); virtual void AddSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const; virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, FontListSizes* aSizes) const;
--- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -31,19 +31,17 @@ gfxMacFont::gfxMacFont(const RefPtr<Unsc mCGFont(nullptr), mCTFont(nullptr), mFontFace(nullptr), mFontSmoothingBackgroundColor(aFontStyle->fontSmoothingBackgroundColor), mVariationFont(aFontEntry->HasVariations()) { mApplySyntheticBold = aNeedsBold; - if (mVariationFont && (!aFontStyle->variationSettings.IsEmpty() || - !aFontEntry->mVariationSettings.IsEmpty() || - !aFontEntry->Weight().IsSingle())) { + if (mVariationFont) { CGFontRef baseFont = aUnscaledFont->GetFont(); if (!baseFont) { mIsValid = false; return; } // Get the variation settings needed to instantiate the fontEntry // for a particular fontStyle.
--- a/gfx/thebes/gfxMacPlatformFontList.h +++ b/gfx/thebes/gfxMacPlatformFontList.h @@ -26,23 +26,23 @@ class gfxMacPlatformFontList; // a single member of a font family (i.e. a single face, such as Times Italic) class MacOSFontEntry : public gfxFontEntry { public: friend class gfxMacPlatformFontList; - MacOSFontEntry(const nsAString& aPostscriptName, FontWeight aWeight, + MacOSFontEntry(const nsAString& aPostscriptName, WeightRange aWeight, bool aIsStandardFace = false, double aSizeHint = 0.0); // for use with data fonts MacOSFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef, - FontWeight aWeight, FontStretch aStretch, FontSlantStyle aStyle, + WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle, bool aIsDataUserFont, bool aIsLocal); virtual ~MacOSFontEntry() { if (mTrakTable) { hb_blob_destroy(mTrakTable); } ::CGFontRelease(mFontRef); } @@ -126,24 +126,24 @@ public: gfxFontFamily* CreateFontFamily(const nsAString& aName) const override; static int32_t AppleWeightToCSSWeight(int32_t aAppleWeight); bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName) override; gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) override; + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) override; gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) override; bool FindAndAddFamilies(const nsAString& aFamily, nsTArray<gfxFontFamily*>* aOutput, FindFamiliesFlags aFlags, gfxFontStyle* aStyle = nullptr, gfxFloat aDevToCssSize = 1.0) override;
--- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -359,17 +359,17 @@ MacOSFontEntry::IsCFF() mIsCFFInitialized = true; mIsCFF = HasFontTable(TRUETYPE_TAG('C','F','F',' ')); } return mIsCFF; } MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, - FontWeight aWeight, + WeightRange aWeight, bool aIsStandardFace, double aSizeHint) : gfxFontEntry(aPostscriptName, aIsStandardFace), mFontRef(NULL), mSizeHint(aSizeHint), mFontRefInitialized(false), mRequiresAAT(false), mIsCFF(false), @@ -378,24 +378,24 @@ MacOSFontEntry::MacOSFontEntry(const nsA mHasVariationsInitialized(false), mHasAATSmallCaps(false), mHasAATSmallCapsInitialized(false), mCheckedForTracking(false), mTrakTable(nullptr), mTrakValues(nullptr), mTrakSizeTable(nullptr) { - mWeightRange = WeightRange(aWeight); + mWeightRange = aWeight; } MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, CGFontRef aFontRef, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, bool aIsDataUserFont, bool aIsLocalUserFont) : gfxFontEntry(aPostscriptName, false), mFontRef(NULL), mSizeHint(0.0), mFontRefInitialized(false), mRequiresAAT(false), mIsCFF(false), @@ -408,36 +408,35 @@ MacOSFontEntry::MacOSFontEntry(const nsA mTrakTable(nullptr), mTrakValues(nullptr), mTrakSizeTable(nullptr) { mFontRef = aFontRef; mFontRefInitialized = true; ::CFRetain(mFontRef); - mWeightRange = WeightRange(aWeight); - mStretch = aStretch; + mWeightRange = aWeight; + mStretchRange = aStretch; mFixedPitch = false; // xxx - do we need this for downloaded fonts? - mStyle = aStyle; + mStyleRange = aStyle; NS_ASSERTION(!(aIsDataUserFont && aIsLocalUserFont), "userfont is either a data font or a local font"); mIsDataUserFont = aIsDataUserFont; mIsLocalUserFont = aIsLocalUserFont; } gfxFontEntry* MacOSFontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); MacOSFontEntry* fe = - new MacOSFontEntry(Name(), Weight().Min(), mStandardFace, mSizeHint); - fe->mStyle = mStyle; - fe->mStretch = mStretch; - fe->mWeightRange = mWeightRange; + new MacOSFontEntry(Name(), Weight(), mStandardFace, mSizeHint); + fe->mStyleRange = mStyleRange; + fe->mStretchRange = mStretchRange; fe->mFixedPitch = mFixedPitch; return fe; } CGFontRef MacOSFontEntry::GetFontRef() { if (!mFontRefInitialized) { @@ -900,53 +899,56 @@ gfxMacFontFamily::FindStyleVariations(Fo [facename isEqualToString:@"Bold Italic"] || [facename isEqualToString:@"Bold Oblique"]) { isStandardFace = true; } // create a font entry MacOSFontEntry *fontEntry = - new MacOSFontEntry(postscriptFontName, FontWeight(cssWeight), + new MacOSFontEntry(postscriptFontName, + WeightRange(FontWeight(cssWeight)), isStandardFace, mSizeHint); if (!fontEntry) { break; } // set additional properties based on the traits reported by Cocoa if (macTraits & (NSCondensedFontMask | NSNarrowFontMask | NSCompressedFontMask)) { - fontEntry->mStretch = FontStretch::Condensed(); + fontEntry->mStretchRange = StretchRange(FontStretch::Condensed()); } else if (macTraits & NSExpandedFontMask) { - fontEntry->mStretch = FontStretch::Expanded(); + fontEntry->mStretchRange = StretchRange(FontStretch::Expanded()); } // Cocoa fails to set the Italic traits bit for HelveticaLightItalic, // at least (see bug 611855), so check for style name endings as well if ((macTraits & NSItalicFontMask) || [facename hasSuffix:@"Italic"] || [facename hasSuffix:@"Oblique"]) { - fontEntry->mStyle = FontSlantStyle::Italic(); + fontEntry->mStyleRange = SlantStyleRange(FontSlantStyle::Italic()); } if (macTraits & NSFixedPitchFontMask) { fontEntry->mFixedPitch = true; } fontEntry->SetupVariationRanges(); if (LOG_FONTLIST_ENABLED()) { nsAutoCString weightString; fontEntry->Weight().ToString(weightString); + nsAutoCString stretchString; + fontEntry->Stretch().ToString(stretchString); LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %s stretch: %g%%" + " with style: %s weight: %s stretch: %s" " (apple-weight: %d macTraits: %8.8x)", NS_ConvertUTF16toUTF8(fontEntry->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), fontEntry->IsItalic() ? "italic" : "normal", weightString.get(), - fontEntry->Stretch().Percentage(), + stretchString.get(), appKitWeight, macTraits)); } // insert into font entry array of family AddFontEntry(fontEntry); } SortAvailableFonts(); @@ -1283,20 +1285,19 @@ gfxMacPlatformFontList::InitSingleFaceLi // add only if doesn't exist already if (!mFontFamilies.GetWeak(key)) { RefPtr<gfxFontFamily> familyEntry = new gfxSingleFaceMacFontFamily(familyName); // We need a separate font entry, because its family name will // differ from the one we found in the main list. MacOSFontEntry* fontEntry = - new MacOSFontEntry(fe->Name(), fe->Weight().Min(), true, + new MacOSFontEntry(fe->Name(), fe->Weight(), true, static_cast<const MacOSFontEntry*>(fe)-> mSizeHint); - fontEntry->mWeightRange = fe->mWeightRange; familyEntry->AddFontEntry(fontEntry); familyEntry->SetHasStyles(true); mFontFamilies.Put(key, familyEntry); LOG_FONTLIST(("(fontlist-singleface) added new family: %s, key: %s\n", NS_ConvertUTF16toUTF8(familyName).get(), NS_ConvertUTF16toUTF8(key).get())); } } @@ -1535,60 +1536,55 @@ gfxMacPlatformFontList::AppleWeightToCSS aAppleWeight = 1; else if (aAppleWeight > kAppleMaxWeight) aAppleWeight = kAppleMaxWeight; return gAppleWeightToCSSWeight[aAppleWeight]; } gfxFontEntry* gfxMacPlatformFontList::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) { nsAutoreleasePool localPool; NSString *faceName = GetNSStringForString(aFontName); MacOSFontEntry *newFontEntry; // lookup face based on postscript or full name CGFontRef fontRef = ::CGFontCreateWithFontName(CFStringRef(faceName)); if (!fontRef) { return nullptr; } - MOZ_ASSERT(aWeight >= FontWeight(100) && aWeight <= FontWeight(900), - "bogus font weight value!"); - newFontEntry = - new MacOSFontEntry(aFontName, fontRef, aWeight, aStretch, aStyle, + new MacOSFontEntry(aFontName, fontRef, aWeightForEntry, + aStretchForEntry, aStyleForEntry, false, true); ::CFRelease(fontRef); return newFontEntry; } static void ReleaseData(void *info, const void *data, size_t size) { free((void*)data); } gfxFontEntry* gfxMacPlatformFontList::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) { NS_ASSERTION(aFontData, "MakePlatformFont called with null data"); - MOZ_ASSERT(aWeight >= FontWeight(100) && aWeight <= FontWeight(900), - "bogus font weight value!"); - // create the font entry nsAutoString uniqueName; nsresult rv = gfxFontUtils::MakeUniqueUserFontName(uniqueName); if (NS_FAILED(rv)) { return nullptr; } @@ -1598,18 +1594,19 @@ gfxMacPlatformFontList::MakePlatformFont CGFontRef fontRef = ::CGFontCreateWithDataProvider(provider); ::CGDataProviderRelease(provider); if (!fontRef) { return nullptr; } auto newFontEntry = - MakeUnique<MacOSFontEntry>(uniqueName, fontRef, aWeight, aStretch, - aStyle, true, false); + MakeUnique<MacOSFontEntry>(uniqueName, fontRef, aWeightForEntry, + aStretchForEntry, aStyleForEntry, + true, false); ::CFRelease(fontRef); // if succeeded and font cmap is good, return the new font if (NS_SUCCEEDED(newFontEntry->ReadCMAP())) { return newFontEntry.release(); } // if something is funky about this font, delete immediately
--- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -1740,40 +1740,36 @@ gfxPlatform::IsFontFormatSupported(uint3 } // no format hint set, need to look at data return true; } gfxFontEntry* gfxPlatform::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) { - return gfxPlatformFontList::PlatformFontList()->LookupLocalFont(aFontName, - aWeight, - aStretch, - aStyle); + return gfxPlatformFontList::PlatformFontList()-> + LookupLocalFont(aFontName, aWeightForEntry, aStretchForEntry, + aStyleForEntry); } gfxFontEntry* gfxPlatform::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) { - return gfxPlatformFontList::PlatformFontList()->MakePlatformFont(aFontName, - aWeight, - aStretch, - aStyle, - aFontData, - aLength); + return gfxPlatformFontList::PlatformFontList()-> + MakePlatformFont(aFontName, aWeightForEntry, aStretchForEntry, + aStyleForEntry, aFontData, aLength); } mozilla::layers::DiagnosticTypes gfxPlatform::GetLayerDiagnosticTypes() { mozilla::layers::DiagnosticTypes type = DiagnosticTypes::NO_DIAGNOSTIC; if (gfxPrefs::DrawLayerBorders()) { type |= mozilla::layers::DiagnosticTypes::LAYER_BORDERS;
--- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -154,19 +154,19 @@ struct BackendPrefsData uint32_t mContentBitmask = 0; mozilla::gfx::BackendType mContentDefault = mozilla::gfx::BackendType::NONE; }; class gfxPlatform { friend class SRGBOverrideObserver; public: - typedef mozilla::FontStretch FontStretch; - typedef mozilla::FontSlantStyle FontSlantStyle; - typedef mozilla::FontWeight FontWeight; + typedef mozilla::StretchRange StretchRange; + typedef mozilla::SlantStyleRange SlantStyleRange; + typedef mozilla::WeightRange WeightRange; typedef mozilla::gfx::Color Color; typedef mozilla::gfx::DataSourceSurface DataSourceSurface; typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::gfx::IntSize IntSize; typedef mozilla::gfx::SourceSurface SourceSurface; typedef mozilla::unicode::Script Script; /** @@ -389,35 +389,35 @@ public: gfxFloat aDevToCssSize) = 0; /** * Look up a local platform font using the full font face name. * (Needed to support @font-face src local().) * Ownership of the returned gfxFontEntry is passed to the caller, * who must either AddRef() or delete. */ - virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle); + gfxFontEntry* LookupLocalFont(const nsAString& aFontName, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry); /** * Activate a platform font. (Needed to support @font-face src url().) * aFontData is a NS_Malloc'ed block that must be freed by this function * (or responsibility passed on) when it is no longer needed; the caller * will NOT free it. * Ownership of the returned gfxFontEntry is passed to the caller, * who must either AddRef() or delete. */ - virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, - const uint8_t* aFontData, - uint32_t aLength); + gfxFontEntry* MakePlatformFont(const nsAString& aFontName, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, + const uint8_t* aFontData, + uint32_t aLength); /** * Whether to allow downloadable fonts via @font-face rules */ bool DownloadableFontsEnabled(); /** * True when hinting should be enabled. This setting shouldn't
--- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -93,19 +93,19 @@ struct FontListSizes { class gfxUserFontSet; class gfxPlatformFontList : public gfxFontInfoLoader { friend class InitOtherFamilyNamesRunnable; public: - typedef mozilla::FontStretch FontStretch; - typedef mozilla::FontSlantStyle FontSlantStyle; - typedef mozilla::FontWeight FontWeight; + typedef mozilla::StretchRange StretchRange; + typedef mozilla::SlantStyleRange SlantStyleRange; + typedef mozilla::WeightRange WeightRange; typedef mozilla::unicode::Script Script; static gfxPlatformFontList* PlatformFontList() { return sPlatformFontList; } static nsresult Init() { NS_ASSERTION(!sPlatformFontList, "What's this doing here?"); @@ -183,28 +183,43 @@ public: bool NeedFullnamePostscriptNames() { return mExtraNames != nullptr; } // pure virtual functions, to be provided by concrete subclasses // get the system default font family gfxFontFamily* GetDefaultFont(const gfxFontStyle* aStyle); - // look up a font by name on the host platform + /** + * Look up a font by name on the host platform. + * + * Note that the style attributes (weight, stretch, style) are NOT used in + * selecting the platform font, which is looked up by name only; these are + * values to be recorded in the new font entry. + */ virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) = 0; + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry) = 0; - // create a new platform font from downloaded data (@font-face) - // this method is responsible to ensure aFontData is free()'d + /** + * Create a new platform font from downloaded data (@font-face). + * + * Note that the style attributes (weight, stretch, style) are NOT related + * (necessarily) to any values within the font resource itself; these are + * values to be recorded in the new font entry and used for face selection, + * in place of whatever inherent style attributes the resource may have. + * + * This method takes ownership of the data block passed in as aFontData, + * and must ensure it is free()'d when no longer required. + */ virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeightForEntry, + StretchRange aStretchForEntry, + SlantStyleRange aStyleForEntry, const uint8_t* aFontData, uint32_t aLength) = 0; // get the standard family name on the platform for a given font name // (platforms may override, eg Mac) virtual bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName); // get the default font name which is available on the system from
--- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -268,40 +268,16 @@ gfxPlatformGtk::CreateFontGroup(const Fo gfxTextPerfMetrics* aTextPerf, gfxUserFontSet* aUserFontSet, gfxFloat aDevToCssSize) { return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf, aUserFontSet, aDevToCssSize); } -gfxFontEntry* -gfxPlatformGtk::LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) -{ - gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList(); - return pfl->LookupLocalFont(aFontName, aWeight, aStretch, - aStyle); -} - -gfxFontEntry* -gfxPlatformGtk::MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, - const uint8_t* aFontData, - uint32_t aLength) -{ - gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList(); - return pfl->MakePlatformFont(aFontName, aWeight, aStretch, - aStyle, aFontData, aLength); -} - FT_Library gfxPlatformGtk::GetFTLibrary() { return gfxFcPlatformFontList::GetFTLibrary(); } static int32_t sDPI = 0;
--- a/gfx/thebes/gfxPlatformGtk.h +++ b/gfx/thebes/gfxPlatformGtk.h @@ -57,36 +57,16 @@ public: gfxFontGroup* CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList, const gfxFontStyle *aStyle, gfxTextPerfMetrics* aTextPerf, gfxUserFontSet *aUserFontSet, gfxFloat aDevToCssSize) override; /** - * Look up a local platform font using the full font face name (needed to - * support @font-face src local() ) - */ - virtual gfxFontEntry* LookupLocalFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle) override; - - /** - * Activate a platform font (needed to support @font-face src url() ) - * - */ - virtual gfxFontEntry* MakePlatformFont(const nsAString& aFontName, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, - const uint8_t* aFontData, - uint32_t aLength) override; - - /** * Calls XFlush if xrender is enabled. */ virtual void FlushContentDrawing() override; FT_Library GetFTLibrary() override; static int32_t GetFontScaleDPI(); static double GetFontScaleFactor();
--- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -100,69 +100,66 @@ private: void* mPtr; size_t mLength; const size_t mLimit; off_t mOff; }; gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) : gfxFontEntry(NS_LITERAL_STRING("userfont")), mUserFontLoadState(STATUS_NOT_LOADED), mFontDataLoadingState(NOT_LOADING), mUnsupportedFormat(false), mFontDisplay(aFontDisplay), mLoader(nullptr), mFontSet(aFontSet) { - MOZ_ASSERT(aWeight.ToFloat() != 0.0f, - "aWeight must not be 0; use FontWeight::Normal() instead"); mIsUserFontContainer = true; mSrcList = aFontFaceSrcList; mSrcIndex = 0; - mWeightRange = WeightRange(aWeight); - mStretch = aStretch; - mStyle = aStyle; + mWeightRange = aWeight; + mStretchRange = aStretch; + mStyleRange = aStyle; mFeatureSettings.AppendElements(aFeatureSettings); mVariationSettings.AppendElements(aVariationSettings); mLanguageOverride = aLanguageOverride; mCharacterMap = aUnicodeRanges; } gfxUserFontEntry::~gfxUserFontEntry() { // Assert that we don't drop any gfxUserFontEntry objects during a Servo // traversal, since PostTraversalTask objects can hold raw pointers to // gfxUserFontEntry objects. MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal()); } bool gfxUserFontEntry::Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { - return Weight().Min() == aWeight && - Weight().Max() == aWeight && - mStretch == aStretch && - mStyle == aStyle && + return Weight() == aWeight && + Stretch() == aStretch && + SlantStyle() == aStyle && mFeatureSettings == aFeatureSettings && mVariationSettings == aVariationSettings && mLanguageOverride == aLanguageOverride && mSrcList == aFontFaceSrcList && mFontDisplay == aFontDisplay && ((!aUnicodeRanges && !mCharacterMap) || (aUnicodeRanges && mCharacterMap && mCharacterMap->Equals(aUnicodeRanges))); } @@ -512,19 +509,19 @@ gfxUserFontEntry::DoLoadNextSrc(bool aFo // src local ==> lookup and load immediately if (currSrc.mSourceType == gfxFontFaceSrc::eSourceType_Local) { // Don't look up local fonts if the font whitelist is being used. gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList(); gfxFontEntry* fe = pfl && pfl->IsFontFamilyWhitelistActive() ? nullptr : gfxPlatform::GetPlatform()->LookupLocalFont(currSrc.mLocalName, - Weight().Min(), - mStretch, - mStyle); + Weight(), + Stretch(), + SlantStyle()); nsTArray<gfxUserFontSet*> fontSets; GetUserFontSets(fontSets); for (gfxUserFontSet* fontSet : fontSets) { // We need to note on each gfxUserFontSet that contains the user // font entry that we used a local() rule. fontSet->SetLocalRulesUsed(); } if (fe) { @@ -767,19 +764,19 @@ gfxUserFontEntry::LoadPlatformFont(const // don't allow us to retrieve or measure it directly. // The *OnAlloc function will also tell DMD about this block, as the // OS font code may hold on to it for an extended period. computedSize = UserFontMallocSizeOfOnAlloc(saneData); // Here ownership of saneData is passed to the platform, // which will delete it when no longer required fe = gfxPlatform::GetPlatform()->MakePlatformFont(mName, - Weight().Min(), - mStretch, - mStyle, + Weight(), + Stretch(), + SlantStyle(), saneData, saneLen); if (!fe) { mFontSet->LogMessage(this, "not usable by platform"); } } if (fe) { @@ -932,19 +929,19 @@ gfxUserFontSet::~gfxUserFontSet() fp->RemoveUserFontSet(this); } } already_AddRefed<gfxUserFontEntry> gfxUserFontSet::FindOrCreateUserFontEntry( const nsAString& aFamilyName, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { RefPtr<gfxUserFontEntry> entry; @@ -972,19 +969,19 @@ gfxUserFontSet::FindOrCreateUserFontEntr } return entry.forget(); } already_AddRefed<gfxUserFontEntry> gfxUserFontSet::CreateUserFontEntry( const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { RefPtr<gfxUserFontEntry> userFontEntry = @@ -993,28 +990,25 @@ gfxUserFontSet::CreateUserFontEntry( aLanguageOverride, aUnicodeRanges, aFontDisplay); return userFontEntry.forget(); } gfxUserFontEntry* gfxUserFontSet::FindExistingUserFontEntry( gfxUserFontFamily* aFamily, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { - MOZ_ASSERT(aWeight.ToFloat() != 0.0f, - "aWeight must not be 0; use FontWeight::Normal() instead"); - nsTArray<RefPtr<gfxFontEntry>>& fontList = aFamily->GetFontList(); for (size_t i = 0, count = fontList.Length(); i < count; i++) { if (!fontList[i]->mIsUserFontContainer) { continue; } gfxUserFontEntry* existingUserFontEntry = @@ -1038,23 +1032,25 @@ gfxUserFontSet::AddUserFontEntry(const n gfxUserFontEntry* aUserFontEntry) { gfxUserFontFamily* family = GetFamily(aFamilyName); family->AddFontEntry(aUserFontEntry); if (LOG_ENABLED()) { nsAutoCString weightString; aUserFontEntry->Weight().ToString(weightString); + nsAutoCString stretchString; + aUserFontEntry->Stretch().ToString(stretchString); LOG(("userfonts (%p) added to \"%s\" (%p) style: %s weight: %s " - "stretch: %g%% display: %d", + "stretch: %s display: %d", this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aUserFontEntry, (aUserFontEntry->IsItalic() ? "italic" : (aUserFontEntry->IsOblique() ? "oblique" : "normal")), weightString.get(), - aUserFontEntry->Stretch().Percentage(), + stretchString.get(), aUserFontEntry->GetFontDisplay())); } } void gfxUserFontSet::IncrementGeneration(bool aIsRebuild) { // add one, increment again if zero @@ -1180,19 +1176,19 @@ gfxUserFontSet::UserFontCache::Entry::Ke return false; } } if (mPrivate != aKey->mPrivate) { return false; } - if (mFontEntry->mStyle != fe->mStyle || + if (mFontEntry->SlantStyle() != fe->SlantStyle() || mFontEntry->Weight() != fe->Weight() || - mFontEntry->mStretch != fe->mStretch || + mFontEntry->Stretch() != fe->Stretch() || mFontEntry->mFeatureSettings != fe->mFeatureSettings || mFontEntry->mVariationSettings != fe->mVariationSettings || mFontEntry->mLanguageOverride != fe->mLanguageOverride || mFontEntry->mFamilyName != fe->mFamilyName) { return false; } return true;
--- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -181,18 +181,21 @@ class gfxUserFontEntry; class gfxOTSContext; class gfxUserFontSet { friend class gfxUserFontEntry; friend class gfxOTSContext; public: typedef mozilla::FontStretch FontStretch; + typedef mozilla::StretchRange StretchRange; typedef mozilla::FontSlantStyle FontSlantStyle; + typedef mozilla::SlantStyleRange SlantStyleRange; typedef mozilla::FontWeight FontWeight; + typedef mozilla::WeightRange WeightRange; NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxUserFontSet) gfxUserFontSet(); enum { // no flags ==> no hint set // unknown ==> unknown format hint set @@ -228,33 +231,33 @@ public: // creates a font face without adding it to a particular family // weight - [100, 900] (multiples of 100) // stretch = [FontStretch::UltraCondensed(), FontStretch::UltraExpanded()] // italic style = constants in gfxFontConstants.h, e.g. NS_FONT_STYLE_NORMAL // language override = result of calling nsRuleNode::ParseFontLanguageOverride // TODO: support for unicode ranges not yet implemented virtual already_AddRefed<gfxUserFontEntry> CreateUserFontEntry( const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) = 0; // creates a font face for the specified family, or returns an existing // matching entry on the family if there is one already_AddRefed<gfxUserFontEntry> FindOrCreateUserFontEntry( const nsAString& aFamilyName, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay); // add in a font face for which we have the gfxUserFontEntry already void AddUserFontEntry(const nsAString& aFamilyName, @@ -403,21 +406,19 @@ public: static PLDHashNumber HashKey(const KeyTypePointer aKey) { PLDHashNumber principalHash = aKey->mPrincipal ? aKey->mPrincipal->Hash() : 0; return mozilla::HashGeneric(principalHash + int(aKey->mPrivate), aKey->mURI->Hash(), HashFeatures(aKey->mFontEntry->mFeatureSettings), HashVariations(aKey->mFontEntry->mVariationSettings), mozilla::HashString(aKey->mFontEntry->mFamilyName), - aKey->mFontEntry->Weight().Min().ForHash(), - aKey->mFontEntry->Weight().Max().ForHash(), - // XXX Is this right? - aKey->mFontEntry->mStyle.ForHash(), - aKey->mFontEntry->mStretch.ForHash(), + aKey->mFontEntry->Weight().AsScalar(), + aKey->mFontEntry->SlantStyle().AsScalar(), + aKey->mFontEntry->Stretch().AsScalar(), aKey->mFontEntry->mLanguageOverride); } enum { ALLOW_MEMMOVE = false }; gfxFontSrcURI* GetURI() const { return mURI; } gfxFontSrcPrincipal* GetPrincipal() const { return mPrincipal; } gfxFontEntry* GetFontEntry() const { return mFontEntry; } @@ -498,19 +499,19 @@ protected: // helper method for performing the actual userfont set rebuild virtual void DoRebuildUserFontSet() = 0; // helper method for FindOrCreateUserFontEntry gfxUserFontEntry* FindExistingUserFontEntry( gfxUserFontFamily* aFamily, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay); // creates a new gfxUserFontFamily in mFontFamilies, or returns an existing // family if there is one @@ -538,46 +539,42 @@ protected: class gfxUserFontEntry : public gfxFontEntry { friend class mozilla::PostTraversalTask; friend class gfxUserFontSet; friend class nsUserFontSet; friend class nsFontFaceLoader; friend class gfxOTSContext; public: - typedef mozilla::FontStretch FontStretch; - typedef mozilla::FontSlantStyle FontSlantStyle; - typedef mozilla::FontWeight FontWeight; - enum UserFontLoadState { STATUS_NOT_LOADED = 0, STATUS_LOAD_PENDING, STATUS_LOADING, STATUS_LOADED, STATUS_FAILED }; gfxUserFontEntry(gfxUserFontSet* aFontSet, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay); virtual ~gfxUserFontEntry(); // Return whether the entry matches the given list of attributes bool Matches(const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay); gfxFont* CreateFontInstance(const gfxFontStyle* aFontStyle, bool aNeedsBold) override;
--- a/layout/style/FontFace.h +++ b/layout/style/FontFace.h @@ -43,19 +43,19 @@ class FontFace final : public nsISupport public: class Entry final : public gfxUserFontEntry { friend class FontFace; public: Entry(gfxUserFontSet* aFontSet, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) : gfxUserFontEntry(aFontSet, aFontFaceSrcList, aWeight, aStretch, aStyle, aFeatureSettings, aVariationSettings, aLanguageOverride,
--- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -984,87 +984,108 @@ GetWeightForDescriptor(const nsCSSValue& switch (aVal.GetUnit()) { case eCSSUnit_FontWeight: return aVal.GetFontWeight(); case eCSSUnit_Enumerated: return FontWeight(aVal.GetIntValue()); case eCSSUnit_Normal: case eCSSUnit_Null: return FontWeight::Normal(); - case eCSSUnit_Pair: - // TODO(jfkthame): Handle optional second value of the font descriptor. - return GetWeightForDescriptor(aVal.GetPairValue().mXValue); default: MOZ_ASSERT_UNREACHABLE("Unknown font-weight descriptor value"); return FontWeight::Normal(); } } +static WeightRange +GetWeightRangeForDescriptor(const nsCSSValue& aVal) +{ + if (aVal.GetUnit() == eCSSUnit_Pair) { + return WeightRange(GetWeightForDescriptor(aVal.GetPairValue().mXValue), + GetWeightForDescriptor(aVal.GetPairValue().mYValue)); + } + return WeightRange(GetWeightForDescriptor(aVal)); +} + static FontSlantStyle GetStyleForDescriptor(const nsCSSValue& aVal) { switch (aVal.GetUnit()) { case eCSSUnit_Normal: case eCSSUnit_Null: return FontSlantStyle::Normal(); case eCSSUnit_Enumerated: MOZ_ASSERT(aVal.GetIntValue() == NS_FONT_STYLE_ITALIC); return FontSlantStyle::Italic(); case eCSSUnit_FontSlantStyle: return aVal.GetFontSlantStyle(); - case eCSSUnit_Pair: - // TODO(jfkthame): Handle optional second value of the font descriptor. - return GetStyleForDescriptor(aVal.GetPairValue().mXValue); default: MOZ_ASSERT_UNREACHABLE("Unknown font-style descriptor value"); return FontSlantStyle::Normal(); } } +static SlantStyleRange +GetStyleRangeForDescriptor(const nsCSSValue& aVal) +{ + if (aVal.GetUnit() == eCSSUnit_Pair) { + return SlantStyleRange(GetStyleForDescriptor(aVal.GetPairValue().mXValue), + GetStyleForDescriptor(aVal.GetPairValue().mYValue)); + } + return SlantStyleRange(GetStyleForDescriptor(aVal)); +} + static FontStretch GetStretchForDescriptor(const nsCSSValue& aVal) { switch (aVal.GetUnit()) { case eCSSUnit_Null: return FontStretch::Normal(); case eCSSUnit_FontStretch: return aVal.GetFontStretch(); - case eCSSUnit_Pair: - // TODO(jfkthame): Handle optional second value of the font descriptor. - return GetStretchForDescriptor(aVal.GetPairValue().mXValue); default: MOZ_ASSERT_UNREACHABLE("Unknown font-style descriptor value"); return FontStretch::Normal(); } } +static StretchRange +GetStretchRangeForDescriptor(const nsCSSValue& aVal) +{ + if (aVal.GetUnit() == eCSSUnit_Pair) { + return StretchRange(GetStretchForDescriptor(aVal.GetPairValue().mXValue), + GetStretchForDescriptor(aVal.GetPairValue().mYValue)); + } + return StretchRange(GetStretchForDescriptor(aVal)); +} + /* static */ already_AddRefed<gfxUserFontEntry> FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, FontFace* aFontFace, SheetType aSheetType) { FontFaceSet* set = aFontFace->GetPrimaryFontFaceSet(); nsCSSValue val; nsCSSUnit unit; uint32_t languageOverride = NO_FONT_LANGUAGE_OVERRIDE; uint8_t fontDisplay = NS_FONT_DISPLAY_AUTO; // set up weight aFontFace->GetDesc(eCSSFontDesc_Weight, val); - FontWeight weight = GetWeightForDescriptor(val); + WeightRange weight = GetWeightRangeForDescriptor(val); // set up stretch aFontFace->GetDesc(eCSSFontDesc_Stretch, val); - FontStretch stretch = GetStretchForDescriptor(val); + StretchRange stretch = GetStretchRangeForDescriptor(val); // set up font style aFontFace->GetDesc(eCSSFontDesc_Style, val); - FontSlantStyle italicStyle = GetStyleForDescriptor(val); + SlantStyleRange italicStyle = GetStyleRangeForDescriptor(val); // set up font display aFontFace->GetDesc(eCSSFontDesc_Display, val); unit = val.GetUnit(); if (unit == eCSSUnit_Enumerated) { fontDisplay = val.GetIntValue(); } else { NS_ASSERTION(unit == eCSSUnit_Null, @@ -1284,24 +1305,26 @@ FontFaceSet::LogMessage(gfxUserFontEntry } nsAutoCString familyName; nsAutoCString fontURI; aUserFontEntry->GetFamilyNameAndURIForLogging(familyName, fontURI); nsAutoCString weightString; aUserFontEntry->Weight().ToString(weightString); + nsAutoCString stretchString; + aUserFontEntry->Stretch().ToString(stretchString); nsPrintfCString message ("downloadable font: %s " - "(font-family: \"%s\" style:%s weight:%s stretch:%g%% src index:%d)", + "(font-family: \"%s\" style:%s weight:%s stretch:%s src index:%d)", aMessage, familyName.get(), - aUserFontEntry->IsItalic() ? "italic" : "normal", + aUserFontEntry->IsItalic() ? "italic" : "normal", // XXX todo: oblique? weightString.get(), - aUserFontEntry->Stretch().Percentage(), + stretchString.get(), aUserFontEntry->GetSrcIndex()); if (NS_FAILED(aStatus)) { message.AppendLiteral(": "); switch (aStatus) { case NS_ERROR_DOM_BAD_URI: message.AppendLiteral("bad URI or cross-site access not allowed"); break; @@ -1962,19 +1985,19 @@ FontFaceSet::UserFontSet::DoRebuildUserF return; } mFontFaceSet->MarkUserFontSetDirty(); } /* virtual */ already_AddRefed<gfxUserFontEntry> FontFaceSet::UserFontSet::CreateUserFontEntry( const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { RefPtr<gfxUserFontEntry> entry = new FontFace::Entry(this, aFontFaceSrcList, aWeight, aStretch, aStyle,
--- a/layout/style/FontFaceSet.h +++ b/layout/style/FontFaceSet.h @@ -93,19 +93,19 @@ public: uint32_t& aBufferLength) override; virtual nsresult LogMessage(gfxUserFontEntry* aUserFontEntry, const char* aMessage, uint32_t aFlags = nsIScriptError::errorFlag, nsresult aStatus = NS_OK) override; virtual void DoRebuildUserFontSet() override; already_AddRefed<gfxUserFontEntry> CreateUserFontEntry( const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList, - FontWeight aWeight, - FontStretch aStretch, - FontSlantStyle aStyle, + WeightRange aWeight, + StretchRange aStretch, + SlantStyleRange aStyle, const nsTArray<gfxFontFeature>& aFeatureSettings, const nsTArray<gfxFontVariation>& aVariationSettings, uint32_t aLanguageOverride, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) override; private: RefPtr<FontFaceSet> mFontFaceSet;