diff --git a/accessible/base/TextAttrs.cpp b/accessible/base/TextAttrs.cpp index 52f14655838a..d64398728521 100644 --- a/accessible/base/TextAttrs.cpp +++ b/accessible/base/TextAttrs.cpp @@ -655,9 +655,10 @@ TextAttrsMgr::FontWeightTextAttr:: // which may not be the weight of the font face used to render the // characters. On Mac, font->GetStyle()->weight will just give the same // number as getComputedStyle(). fontEntry->Weight() will give the weight - // of the font face used. + // range supported by the font face used, so we clamp the weight that was + // requested by style to what is actually supported by the font. gfxFontEntry *fontEntry = font->GetFontEntry(); - return fontEntry->Weight(); + return fontEntry->Weight().Clamp(font->GetStyle()->weight); } //////////////////////////////////////////////////////////////////////////////// diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index f06409670f51..00af1f148dea 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -117,7 +117,8 @@ struct FontListEntry { nsString familyName; nsString faceName; nsCString filepath; - float weight; + float minWeight; + float maxWeight; int16_t stretch; uint8_t italic; uint8_t index; diff --git a/gfx/src/FontPropertyTypes.h b/gfx/src/FontPropertyTypes.h index d511739a5218..366d692ffee7 100644 --- a/gfx/src/FontPropertyTypes.h +++ b/gfx/src/FontPropertyTypes.h @@ -8,9 +8,13 @@ #ifndef GFX_FONT_PROPERTY_TYPES_H #define GFX_FONT_PROPERTY_TYPES_H +#include #include #include +#include + #include "mozilla/Assertions.h" +#include "nsString.h" /* * This file is separate from gfxFont.h so that layout can include it @@ -330,7 +334,80 @@ private: static const int16_t kItalic = INT16_MAX; }; + +/** + * Convenience type to hold a 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 FontPropertyRange +{ +public: + /** + * Construct a range from given minimum and maximum values (inclusive). + */ + FontPropertyRange(T aMin, T aMax) + : mValues(aMin, aMax) + { + MOZ_ASSERT(aMin <= aMax); + } + + /** + * Construct a range representing a single value (min==max). + */ + explicit FontPropertyRange(T aValue) + : mValues(aValue, aValue) + { + } + + 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.) + */ + T Clamp(T aValue) const + { + return aValue <= Min() ? Min() : (aValue >= Max() ? Max() : aValue); + } + + /** + * Return whether the range consists of a single unique value. + */ + bool IsSingle() const + { + return Min() == Max(); + } + + bool operator==(const FontPropertyRange& aOther) const + { + return mValues == aOther.mValues; + } + bool operator!=(const FontPropertyRange& aOther) const + { + return mValues != aOther.mValues; + } + + void ToString(nsACString& aOutString, const char* aDelim = "..") const + { + aOutString.AppendPrintf("%g", Min().ToFloat()); + if (!IsSingle()) { + aOutString.AppendPrintf("%s%g", aDelim, Max().ToFloat()); + } + } + +private: + std::pair mValues; +}; + +typedef FontPropertyRange WeightRange; +typedef FontPropertyRange StretchRange; +typedef FontPropertyRange StyleRange; + } // namespace mozilla #endif // GFX_FONT_PROPERTY_TYPES_H - diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index 136a82eb81af..3669c6764835 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -190,6 +190,9 @@ gfxDWriteFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) gfxDWriteFontEntry *fe = new gfxDWriteFontEntry(fullID, font, mIsSystemFontFamily); fe->SetForceGDIClassic(mForceGDIClassic); + + fe->SetupVariationRanges(); + AddFontEntry(fe); // postscript/fullname if needed @@ -219,13 +222,16 @@ gfxDWriteFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) } if (LOG_FONTLIST_ENABLED()) { + nsAutoCString weightString; + fe->Weight().ToString(weightString); LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %g stretch: %d psname: %s fullname: %s", + " with style: %s weight: %s stretch: %d psname: %s fullname: %s", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), (fe->IsItalic()) ? "italic" : (fe->IsOblique() ? "oblique" : "normal"), - fe->Weight().ToFloat(), fe->Stretch(), + weightString.get(), + fe->Stretch(), NS_ConvertUTF16toUTF8(psname).get(), NS_ConvertUTF16toUTF8(fullname).get())); } @@ -669,14 +675,14 @@ gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, // XXX todo: consider caching a small number of variation instances? RefPtr fontFace; nsresult rv = CreateFontFace(getter_AddRefs(fontFace), - &aFontStyle->variationSettings, + aFontStyle, sims); if (NS_FAILED(rv)) { return nullptr; } RefPtr unscaledFont = new UnscaledFontDWrite(fontFace, mIsSystemFont ? mFont : nullptr, sims); - return new gfxDWriteFont(unscaledFont, this, aFontStyle, aNeedsBold); + return new gfxDWriteFont(unscaledFont, this, nullptr, aNeedsBold); } ThreadSafeWeakPtr& unscaledFontPtr = @@ -684,7 +690,7 @@ gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, RefPtr unscaledFont(unscaledFontPtr); if (!unscaledFont) { RefPtr fontFace; - nsresult rv = CreateFontFace(getter_AddRefs(fontFace), nullptr, sims); + nsresult rv = CreateFontFace(getter_AddRefs(fontFace), aFontStyle, sims); if (NS_FAILED(rv)) { return nullptr; } @@ -698,7 +704,7 @@ gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle, nsresult gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, - const nsTArray* aVariations, + const gfxFontStyle* aFontStyle, DWRITE_FONT_SIMULATIONS aSimulations) { // Convert an OpenType font tag from our uint32_t representation @@ -766,29 +772,22 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, // If the IDWriteFontFace5 interface is available, we can go via // IDWriteFontResource to create a new modified face. - if (mFontFace5 && (aVariations && !aVariations->IsEmpty() || + if (mFontFace5 && ((aFontStyle && !aFontStyle->variationSettings.IsEmpty()) || + !Weight().IsSingle() || needSimulations)) { RefPtr resource; HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource)); MOZ_ASSERT(SUCCEEDED(hr)); AutoTArray fontAxisValues; - if (aVariations) { - // Merge mVariationSettings and *aVariations if both present - const nsTArray* vars; - AutoTArray mergedSettings; - if (!aVariations) { - vars = &mVariationSettings; - } else { - if (mVariationSettings.IsEmpty()) { - vars = aVariations; - } else { - gfxFontUtils::MergeVariations(mVariationSettings, - *aVariations, - &mergedSettings); - vars = &mergedSettings; - } - } - for (const auto& v : *vars) { + + // Get the variation settings needed to instantiate the fontEntry + // for a particular fontStyle. + AutoTArray vars; + GetVariationsForStyle(vars, *aFontStyle); + + // Copy variation settings to DWrite's type. + if (!vars.IsEmpty()) { + for (const auto& v : vars) { DWRITE_FONT_AXIS_VALUE axisValue = { makeDWriteAxisTag(v.mTag), v.mValue @@ -796,6 +795,7 @@ gfxDWriteFontEntry::CreateFontFace(IDWriteFontFace **aFontFace, fontAxisValues.AppendElement(axisValue); } } + IDWriteFontFace5* ff5; resource->CreateFontFace(aSimulations, fontAxisValues.Elements(), @@ -1151,13 +1151,16 @@ gfxDWriteFontList::InitFontListForPlatform() if (LOG_FONTLIST_ENABLED()) { gfxFontEntry *fe = faces[i]; + nsAutoCString weightString; + fe->Weight().ToString(weightString); LOG_FONTLIST(("(fontlist) moved (%s) to family (%s)" - " with style: %s weight: %g stretch: %d", + " with style: %s weight: %s stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(gillSansMTFamily->Name()).get(), (fe->IsItalic()) ? "italic" : (fe->IsOblique() ? "oblique" : "normal"), - fe->Weight().ToFloat(), fe->Stretch())); + weightString.get(), + fe->Stretch())); } } diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h index 015ce39ef41c..d8594a494849 100644 --- a/gfx/thebes/gfxDWriteFontList.h +++ b/gfx/thebes/gfxDWriteFontList.h @@ -122,7 +122,7 @@ public: int weight = NS_ROUNDUP(aFont->GetWeight() - 50, 100); weight = mozilla::Clamp(weight, 100, 900); - mWeight = FontWeight(weight); + mWeightRange = WeightRange(FontWeight(weight)); mIsCJK = UNINITIALIZED_VALUE; } @@ -147,7 +147,7 @@ public: mIsSystemFont(false), mForceGDIClassic(false), mHasVariations(false), mHasVariationsInitialized(false) { - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStretch = aStretch; mStyle = aStyle; mIsLocalUserFont = true; @@ -175,7 +175,7 @@ public: mIsSystemFont(false), mForceGDIClassic(false), mHasVariations(false), mHasVariationsInitialized(false) { - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStretch = aStretch; mStyle = aStyle; mIsDataUserFont = true; @@ -216,7 +216,7 @@ protected: nsresult CreateFontFace( IDWriteFontFace **aFontFace, - const nsTArray* aVariations = nullptr, + const gfxFontStyle* aFontStyle = nullptr, DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE); static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont); diff --git a/gfx/thebes/gfxDWriteFonts.cpp b/gfx/thebes/gfxDWriteFonts.cpp index d3a453ff3116..46f70db1fa67 100644 --- a/gfx/thebes/gfxDWriteFonts.cpp +++ b/gfx/thebes/gfxDWriteFonts.cpp @@ -157,7 +157,8 @@ void gfxDWriteFont::ComputeMetrics(AntialiasOption anAAOption) { DWRITE_FONT_METRICS fontMetrics; - if (!(mFontEntry->Weight() == FontWeight(900) && + if (!(mFontEntry->Weight().Min() == FontWeight(900) && + mFontEntry->Weight().Max() == FontWeight(900) && !mFontEntry->IsUserFont() && mFontEntry->Name().EqualsLiteral("Arial Black") && GetFakeMetricsForArialBlack(&fontMetrics))) diff --git a/gfx/thebes/gfxFT2FontBase.cpp b/gfx/thebes/gfxFT2FontBase.cpp index c226e64cdf2a..495415f0b4bb 100644 --- a/gfx/thebes/gfxFT2FontBase.cpp +++ b/gfx/thebes/gfxFT2FontBase.cpp @@ -230,22 +230,13 @@ gfxFT2FontBase::InitMetrics() } if ((!mFontEntry->mVariationSettings.IsEmpty() || - !mStyle.variationSettings.IsEmpty()) && + !mStyle.variationSettings.IsEmpty() || + !mFontEntry->Weight().IsSingle()) && (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { // Resolve variations from entry (descriptor) and style (property) - const nsTArray* settings; - AutoTArray mergedSettings; - if (mFontEntry->mVariationSettings.IsEmpty()) { - settings = &mStyle.variationSettings; - } else if (mStyle.variationSettings.IsEmpty()) { - settings = &mFontEntry->mVariationSettings; - } else { - gfxFontUtils::MergeVariations(mFontEntry->mVariationSettings, - mStyle.variationSettings, - &mergedSettings); - settings = &mergedSettings; - } - SetupVarCoords(face, *settings, &mCoords); + AutoTArray 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()); diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index 22c4c50d0ea2..4d4f42c85d61 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -224,7 +224,7 @@ FT2FontEntry::Clone() const FT2FontEntry* fe = new FT2FontEntry(Name()); fe->mFilename = mFilename; fe->mFTFontIndex = mFTFontIndex; - fe->mWeight = mWeight; + fe->mWeightRange = mWeightRange; fe->mStretch = mStretch; fe->mStyle = mStyle; return fe; @@ -283,7 +283,7 @@ FT2FontEntry::CreateFontEntry(const nsAString& aFontName, aFontData, aLength); if (fe) { fe->mStyle = aStyle; - fe->mWeight = aWeight; + fe->mWeightRange = WeightRange(aWeight); fe->mStretch = aStretch; fe->mIsDataUserFont = true; } @@ -330,7 +330,8 @@ FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE) fe->mFTFontIndex = aFLE.index(); // The weight transported across IPC is a float, so we need to explicitly // convert it back to a FontWeight. - fe->mWeight = FontWeight(aFLE.weight()); + fe->mWeightRange = WeightRange(FontWeight(aFLE.minWeight()), + FontWeight(aFLE.maxWeight())); fe->mStretch = aFLE.stretch(); fe->mStyle = (aFLE.italic() ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL); return fe; @@ -392,7 +393,7 @@ FT2FontEntry::CreateFontEntry(FT_Face aFace, FT2FontEntry *fe = new FT2FontEntry(aName); fe->mStyle = (FTFaceIsItalic(aFace) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL); - fe->mWeight = FTFaceGetWeight(aFace); + fe->mWeightRange = WeightRange(FTFaceGetWeight(aFace)); fe->mFilename = aFilename; fe->mFTFontIndex = aIndex; @@ -459,28 +460,17 @@ FT2FontEntry::CairoFontFace(const gfxFontStyle* aStyle) // 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())) && + (aStyle && !aStyle->variationSettings.IsEmpty()) || + !Weight().IsSingle()) && (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) - const nsTArray* settings; - AutoTArray mergedSettings; - if (aStyle) { - if (mVariationSettings.IsEmpty()) { - settings = &aStyle->variationSettings; - } else { - gfxFontUtils::MergeVariations(mVariationSettings, - aStyle->variationSettings, - &mergedSettings); - settings = &mergedSettings; - } - } else { - settings = &mVariationSettings; - } + AutoTArray settings; + GetVariationsForStyle(settings, aStyle ? *aStyle : gfxFontStyle()); AutoTArray coords; - gfxFT2FontBase::SetupVarCoords(mFTFace, *settings, &coords); + gfxFT2FontBase::SetupVarCoords(mFTFace, settings, &coords); // Create a separate FT_Face because we need to apply custom // variation settings to it. FT_Face ftFace; @@ -668,7 +658,8 @@ FT2FontFamily::AddFacesToFontList(InfallibleTArray* aFontList) // Ideally we'd avoid doing that. aFontList->AppendElement(FontListEntry(Name(), fe->Name(), fe->mFilename, - fe->Weight().ToFloat(), + fe->Weight().Min().ToFloat(), + fe->Weight().Max().ToFloat(), fe->Stretch(), fe->mStyle, fe->mFTFontIndex)); @@ -963,7 +954,14 @@ gfxFT2FontList::AppendFacesFromCachedFaceList( if (!(end = strchr(beginning, ','))) { break; } - uint32_t weight = strtoul(beginning, nullptr, 10); + 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; @@ -971,7 +969,8 @@ gfxFT2FontList::AppendFacesFromCachedFaceList( uint32_t stretch = strtoul(beginning, nullptr, 10); FontListEntry fle(familyName, faceName, aFileName, - weight, stretch, italic, index); + minWeight, maxWeight, + stretch, italic, index); AppendFaceFromFontListEntry(fle, aStdFile); beginning = end + 1; @@ -991,7 +990,9 @@ AppendToFaceList(nsCString& aFaceList, aFaceList.Append(','); aFaceList.Append(aFontEntry->IsItalic() ? '1' : '0'); aFaceList.Append(','); - aFaceList.AppendFloat(aFontEntry->Weight().ToFloat()); + aFaceList.AppendFloat(aFontEntry->Weight().Min().ToFloat()); + aFaceList.Append(':'); + aFaceList.AppendFloat(aFontEntry->Weight().Max().ToFloat()); aFaceList.Append(','); aFaceList.AppendInt(aFontEntry->Stretch()); aFaceList.Append(','); @@ -1149,12 +1150,15 @@ gfxFT2FontList::AddFaceToList(const nsCString& aEntryName, uint32_t aIndex, AppendToFaceList(aFaceList, name, fe); if (LOG_ENABLED()) { + nsAutoCString weightString; + fe->Weight().ToString(weightString); LOG(("(fontinit) added (%s) to family (%s)" - " with style: %s weight: %g stretch: %d", + " with style: %s weight: %s stretch: %d", NS_ConvertUTF16toUTF8(fe->Name()).get(), NS_ConvertUTF16toUTF8(family->Name()).get(), fe->IsItalic() ? "italic" : "normal", - fe->Weight().ToFloat(), fe->Stretch())); + weightString.get(), + fe->Stretch())); } } } @@ -1522,7 +1526,7 @@ searchDone: fontEntry->Name(), nullptr); if (fe) { fe->mStyle = aStyle; - fe->mWeight = aWeight; + fe->mWeightRange = WeightRange(aWeight); fe->mStretch = aStretch; fe->mIsLocalUserFont = true; } diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 2a78b2fe521e..66e9d12faa72 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -250,7 +250,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, if (FcPatternGetInteger(aFontPattern, FC_WEIGHT, 0, &weight) != FcResultMatch) { weight = FC_WEIGHT_REGULAR; } - mWeight = MapFcWeight(weight); + mWeightRange = WeightRange(MapFcWeight(weight)); // width int width; @@ -322,7 +322,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, mIgnoreFcCharmap(true), mAspect(0.0), mFontData(aData), mLength(aLength) { - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStyle = aStyle; mStretch = aStretch; mIsDataUserFont = true; @@ -341,7 +341,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName, mFTFace(nullptr), mFTFaceInitialized(false), mAspect(0.0), mFontData(nullptr), mLength(0) { - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStyle = aStyle; mStretch = aStretch; mIsLocalUserFont = true; @@ -764,22 +764,14 @@ gfxFontconfigFontEntry::CreateScaledFont(FcPattern* aRenderPattern, } AutoTArray coords; - if (!aStyle->variationSettings.IsEmpty() || !mVariationSettings.IsEmpty()) { + if (!aStyle->variationSettings.IsEmpty() || + !mVariationSettings.IsEmpty() || + !Weight().IsSingle()) { FT_Face ftFace = GetFTFace(); if (ftFace) { - const nsTArray* settings; - AutoTArray mergedSettings; - if (mVariationSettings.IsEmpty()) { - settings = &aStyle->variationSettings; - } else if (aStyle->variationSettings.IsEmpty()) { - settings = &mVariationSettings; - } else { - gfxFontUtils::MergeVariations(mVariationSettings, - aStyle->variationSettings, - &mergedSettings); - settings = &mergedSettings; - } - gfxFT2FontBase::SetupVarCoords(ftFace, *settings, &coords); + AutoTArray settings; + GetVariationsForStyle(settings, *aStyle); + gfxFT2FontBase::SetupVarCoords(ftFace, settings, &coords); } } @@ -1194,6 +1186,9 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) gfxFontconfigFontEntry *fontEntry = new gfxFontconfigFontEntry(faceName, face, mContainsAppFonts); + + fontEntry->SetupVariationRanges(); + AddFontEntry(fontEntry); if (fontEntry->IsNormalStyle()) { @@ -1201,14 +1196,17 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) } if (LOG_FONTLIST_ENABLED()) { + nsAutoCString weightString; + fontEntry->Weight().ToString(weightString); LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %g stretch: %d" + " with style: %s weight: %s stretch: %d" " psname: %s fullname: %s", NS_ConvertUTF16toUTF8(fontEntry->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), (fontEntry->IsItalic()) ? "italic" : (fontEntry->IsOblique() ? "oblique" : "normal"), - fontEntry->Weight().ToFloat(), fontEntry->Stretch(), + weightString.get(), + fontEntry->Stretch(), NS_ConvertUTF16toUTF8(psname).get(), NS_ConvertUTF16toUTF8(fullname).get())); } @@ -1313,7 +1311,8 @@ gfxFontconfigFontFamily::FindAllFontsForStyle(const gfxFontStyle& aFontStyle, if (dist < 0.0 || !bestEntry || bestEntry->Stretch() != entry->Stretch() || - bestEntry->Weight() != entry->Weight() || + bestEntry->Weight().Min() != entry->Weight().Min() || + bestEntry->Weight().Max() != entry->Weight().Max() || bestEntry->mStyle != entry->mStyle) { // If the best entry in this group is still outside the tolerance, // then skip the entire group. diff --git a/gfx/thebes/gfxFontEntry.cpp b/gfx/thebes/gfxFontEntry.cpp index 7bf40ca415f9..4b49536596d7 100644 --- a/gfx/thebes/gfxFontEntry.cpp +++ b/gfx/thebes/gfxFontEntry.cpp @@ -80,7 +80,8 @@ gfxFontEntry::gfxFontEntry() : mHasCmapTable(false), mGrFaceInitialized(false), mCheckedForColorGlyph(false), - mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL), + mWeightRange(FontWeight(500)), + mStretch(NS_FONT_STRETCH_NORMAL), mUVSOffset(0), mUVSData(nullptr), mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE), mCOLR(nullptr), @@ -117,7 +118,8 @@ gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) : mHasCmapTable(false), mGrFaceInitialized(false), mCheckedForColorGlyph(false), - mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL), + mWeightRange(FontWeight(500)), + mStretch(NS_FONT_STRETCH_NORMAL), mUVSOffset(0), mUVSData(nullptr), mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE), mCOLR(nullptr), @@ -1028,6 +1030,86 @@ gfxFontEntry::GetColorLayersInfo(uint32_t aGlyphId, aLayerColors); } +void +gfxFontEntry::SetupVariationRanges() +{ + if (!HasVariations() || IsUserFont()) { + return; + } + AutoTArray axes; + GetVariationAxes(axes); + for (const auto& axis : axes) { + 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.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(); + 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'): + default: + continue; + } + } +} + +void +gfxFontEntry::GetVariationsForStyle(nsTArray& 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}); + } + + // XXX todo: 'wdth', 'slnt', 'ital' + + 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()); + if (index == aResult.NoIndex) { + aResult.AppendElement(aSetting); + } else { + aResult[index].mValue = aSetting.mValue; + } + }; + + // The low-level font-variation-settings descriptor from @font-face, + // if present, takes precedence over automatic variation settings + // from high-level properties. + for (const auto& v : mVariationSettings) { + replaceOrAppend(v); + } + + // And the low-level font-variation-settings property takes precedence + // over the descriptor. + for (const auto& v : aStyle.variationSettings) { + replaceOrAppend(v); + } +} + size_t gfxFontEntry::FontTableHashEntry::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { @@ -1236,33 +1318,35 @@ StretchDistance(int32_t aFontStretch, int32_t aTargetStretch) // weight distance ==> [0,1598] static inline uint32_t -WeightDistance(FontWeight aFontWeight, FontWeight aTargetWeight) +WeightDistance(const gfxFontEntry* aFontEntry, FontWeight aTargetWeight) { // Compute a measure of the "distance" between the requested // weight and the given fontEntry float distance = 0.0f, addedDistance = 0.0f; - if (aTargetWeight != aFontWeight) { + FontWeight minWeight = aFontEntry->Weight().Min(); + FontWeight maxWeight = aFontEntry->Weight().Max(); + if (aTargetWeight < minWeight || aTargetWeight > maxWeight) { if (aTargetWeight > FontWeight(500)) { - distance = aFontWeight - aTargetWeight; + distance = minWeight - aTargetWeight; } else if (aTargetWeight < FontWeight(400)) { - distance = aTargetWeight - aFontWeight; + distance = aTargetWeight - maxWeight; } else { // special case - target is between 400 and 500 // font weights between 400 and 500 are close - if (aFontWeight >= FontWeight(400) && - aFontWeight <= FontWeight(500)) { - if (aFontWeight < aTargetWeight) { - distance = FontWeight(500) - aFontWeight; + if (maxWeight >= FontWeight(400) && + minWeight <= FontWeight(500)) { + if (maxWeight < aTargetWeight) { + distance = FontWeight(500) - maxWeight; } else { - distance = aFontWeight - aTargetWeight; + 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 - aFontWeight; + distance = aTargetWeight - maxWeight; addedDistance = 100; } } @@ -1284,8 +1368,7 @@ WeightStyleStretchDistance(gfxFontEntry* aFontEntry, uint32_t stretchDist = StretchDistance(aFontEntry->mStretch, aTargetStyle.stretch); uint32_t styleDist = StyleDistance(aFontEntry->mStyle, aTargetStyle.style); - uint32_t weightDist = - WeightDistance(aFontEntry->Weight(), aTargetStyle.weight); + uint32_t 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"); @@ -1444,8 +1527,11 @@ gfxFontFamily::CheckForSimpleFamily() // simple families don't have varying font-stretch or oblique return; } + if (fe->Weight().Min() != fe->Weight().Max()) { + return; // family with variation fonts is not considered "simple" + } uint8_t faceIndex = (fe->IsItalic() ? kItalicMask : 0) | - (fe->Weight() >= FontWeight(600) ? kBoldMask : 0); + (fe->IsBold() ? kBoldMask : 0); if (faces[faceIndex]) { return; // two faces resolve to the same slot; family isn't "simple" } @@ -1492,33 +1578,41 @@ void gfxFontFamily::LocalizedName(nsAString& aLocalizedName) } // metric for how close a given font matches a style -static int32_t +static float CalcStyleMatch(gfxFontEntry *aFontEntry, const gfxFontStyle *aStyle) { - int32_t rank = 0; + float rank = 0; if (aStyle) { - // italics - bool wantUpright = (aStyle->style == NS_FONT_STYLE_NORMAL); - if (aFontEntry->IsUpright() == wantUpright) { - rank += 10; - } + // TODO: stretch + + // italics + bool wantUpright = (aStyle->style == NS_FONT_STYLE_NORMAL); + if (aFontEntry->IsUpright() == wantUpright) { + rank += 5000.0f; + } // measure of closeness of weight to the desired value - rank += 9 - Abs((aFontEntry->Weight() - aStyle->weight) / 100.0f); + if (aFontEntry->Weight().Min() > aStyle->weight) { + rank += aFontEntry->Weight().Min() - aStyle->weight; + } else if (aFontEntry->Weight().Max() < aStyle->weight) { + rank += aStyle->weight - aFontEntry->Weight().Max(); + } else { + rank += 2000.0f; // the font supports the exact weight wanted + } } else { // if no font to match, prefer non-bold, non-italic fonts if (aFontEntry->IsUpright()) { - rank += 3; + rank += 2000.0f; } if (!aFontEntry->IsBold()) { - rank += 2; + rank += 1000.0f; } } return rank; } -#define RANK_MATCHED_CMAP 20 +#define RANK_MATCHED_CMAP 10000.0f void gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData) @@ -1536,7 +1630,7 @@ gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData) needsBold, true); if (fe && !fe->SkipDuringSystemFallback()) { - int32_t rank = 0; + float rank = 0; if (fe->HasCharacter(aMatchData->mCh)) { rank += RANK_MATCHED_CMAP; @@ -1596,7 +1690,7 @@ gfxFontFamily::SearchAllFontsForChar(GlobalFontMatch *aMatchData) for (i = 0; i < numFonts; i++) { gfxFontEntry *fe = mAvailableFonts[i]; if (fe && fe->HasCharacter(aMatchData->mCh)) { - int32_t rank = RANK_MATCHED_CMAP; + float rank = RANK_MATCHED_CMAP; rank += CalcStyleMatch(fe, aMatchData->mStyle); if (rank > aMatchData->mMatchRank || (rank == aMatchData->mMatchRank && diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h index 3a16aa7df32c..15d39cced23e 100644 --- a/gfx/thebes/gfxFontEntry.h +++ b/gfx/thebes/gfxFontEntry.h @@ -111,6 +111,7 @@ struct gfxFontFeatureInfo { class gfxFontEntry { public: typedef mozilla::FontWeight FontWeight; + typedef mozilla::WeightRange WeightRange; typedef mozilla::gfx::DrawTarget DrawTarget; typedef mozilla::unicode::Script Script; @@ -141,7 +142,7 @@ public: // returns Name() if nothing better is available. virtual nsString RealFaceName(); - FontWeight Weight() const { return mWeight; } + WeightRange Weight() const { return mWeightRange; } uint16_t Stretch() const { return mStretch; } bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; } @@ -150,7 +151,7 @@ public: bool IsItalic() const { return mStyle == NS_FONT_STYLE_ITALIC; } bool IsOblique() const { return mStyle == NS_FONT_STYLE_OBLIQUE; } bool IsUpright() const { return mStyle == NS_FONT_STYLE_NORMAL; } - bool IsBold() const { return mWeight.IsBold(); } // bold == weights 600 and above + bool IsBold() const { return Weight().Max().IsBold(); } // bold == weights 600 and above bool IgnoreGDEF() const { return mIgnoreGDEF; } bool IgnoreGSUB() const { return mIgnoreGSUB; } @@ -163,7 +164,8 @@ public: bool IsNormalStyle() const { return IsUpright() && - Weight() == FontWeight::Normal() && + Weight().Min() <= FontWeight::Normal() && + Weight().Max() >= FontWeight::Normal() && Stretch() == NS_FONT_STRETCH_NORMAL; } @@ -368,6 +370,16 @@ public: { } + // Set up the entry's weight/stretch/style ranges according to axes found + // by GetVariationAxes (for installed fonts; do NOT call this for user + // fonts, where the ranges are provided by @font-face descriptors). + void SetupVariationRanges(); + + // Get variation axis settings that should be used to implement a particular + // font style using this resource. + void GetVariationsForStyle(nsTArray& aResult, + const gfxFontStyle& aStyle); + // Get the font's list of features (if any) for DevTools support. void GetFeatureInfo(nsTArray& aFeatureInfo); @@ -404,7 +416,7 @@ public: uint32_t mDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; uint32_t mNonDefaultSubSpaceFeatures[(int(Script::NUM_SCRIPT_CODES) + 31) / 32]; - FontWeight mWeight; + WeightRange mWeightRange; uint16_t mStretch; RefPtr mCharacterMap; @@ -610,14 +622,14 @@ struct GlobalFontMatch { GlobalFontMatch(const uint32_t aCharacter, const gfxFontStyle *aStyle) : mCh(aCharacter), mStyle(aStyle), - mMatchRank(0), mCount(0), mCmapsTested(0) + mMatchRank(0.0f), mCount(0), mCmapsTested(0) { } const uint32_t mCh; // codepoint to be matched const gfxFontStyle* mStyle; // style to match - int32_t mMatchRank; // metric indicating closest match + float mMatchRank; // metric indicating closest match RefPtr mBestMatch; // current best match RefPtr mMatchedFamily; // the family it belongs to uint32_t mCount; // number of fonts matched diff --git a/gfx/thebes/gfxFontUtils.cpp b/gfx/thebes/gfxFontUtils.cpp index 56eb5672b852..b3c1cae1bbb6 100644 --- a/gfx/thebes/gfxFontUtils.cpp +++ b/gfx/thebes/gfxFontUtils.cpp @@ -1944,24 +1944,6 @@ gfxFontUtils::GetVariationInstances(gfxFontEntry* aFontEntry, } } -void -gfxFontUtils::MergeVariations(const nsTArray& aEntrySettings, - const nsTArray& aStyleSettings, - nsTArray* aMerged) -{ - MOZ_ASSERT(!aEntrySettings.IsEmpty() && - !aStyleSettings.IsEmpty() && - aMerged->IsEmpty()); - // Settings from the CSS style will take precedence over those from the - // font entry (i.e. from the @font-face descriptor). - aMerged->AppendElements(aStyleSettings); - for (auto& setting : aEntrySettings) { - if (!aMerged->Contains(setting.mTag, VariationTagComparator())) { - aMerged->AppendElement(setting); - } - } -} - #ifdef XP_WIN /* static */ diff --git a/gfx/thebes/gfxFontUtils.h b/gfx/thebes/gfxFontUtils.h index 269fa1ddb66d..250df442c3a2 100644 --- a/gfx/thebes/gfxFontUtils.h +++ b/gfx/thebes/gfxFontUtils.h @@ -1010,22 +1010,6 @@ public: GetVariationInstances(gfxFontEntry* aFontEntry, nsTArray& aInstances); - // Merge a list of font-variation-settings from a font entry and a list - // from a gfxFontStyle, to get a combined collection of settings that can - // be used to instantiate a font. - static void - MergeVariations(const nsTArray& aEntrySettings, - const nsTArray& aStyleSettings, - nsTArray* aMerged); - - // Helper used by MergeVariations, and other code that wants to check - // whether an array of variation settings includes a particular tag. - struct VariationTagComparator { - bool Equals(const gfxFontVariation& aVariation, uint32_t aTag) const { - return aVariation.mTag == aTag; - } - }; - protected: friend struct MacCharsetMappingComparator; diff --git a/gfx/thebes/gfxGDIFont.cpp b/gfx/thebes/gfxGDIFont.cpp index f5dc770b2fc7..138bfdb3265e 100644 --- a/gfx/thebes/gfxGDIFont.cpp +++ b/gfx/thebes/gfxGDIFont.cpp @@ -460,7 +460,10 @@ gfxGDIFont::FillLogFont(LOGFONTW& aLogFont, gfxFloat aSize) weight = mNeedsBold ? 700 : 200; } } else { - weight = mNeedsBold ? 700 : fe->Weight().ToIntRounded(); + // GDI doesn't support variation fonts, so for system fonts we know + // that the entry has only a single weight, not a range. + MOZ_ASSERT(fe->Weight().IsSingle()); + weight = mNeedsBold ? 700 : fe->Weight().Min().ToIntRounded(); } fe->FillLogFont(&aLogFont, weight, aSize); diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index 5368f7ad3374..9b297d0ecd48 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -126,7 +126,7 @@ GDIFontEntry::GDIFontEntry(const nsAString& aFaceName, { mUserFontData.reset(aUserFontData); mStyle = aStyle; - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStretch = aStretch; if (IsType1()) mForceGDI = true; @@ -139,7 +139,9 @@ gfxFontEntry* GDIFontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); - return new GDIFontEntry(Name(), mFontType, mStyle, mWeight, mStretch, + // 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); } @@ -305,7 +307,7 @@ GDIFontEntry::TestCharacterMap(uint32_t aCh) if (!IsUpright()) { fakeStyle.style = NS_FONT_STYLE_ITALIC; } - fakeStyle.weight = mWeight; + fakeStyle.weight = Weight().Min(); RefPtr tempFont = FindOrMakeFont(&fakeStyle, false); if (!tempFont || !tempFont->Valid()) @@ -384,7 +386,7 @@ GDIFontEntry::InitLogFont(const nsAString& aName, // it may give us a regular one based on weight. Windows should // do fake italic for us in that case. mLogFont.lfItalic = !IsUpright(); - mLogFont.lfWeight = int(mWeight.ToFloat()); + mLogFont.lfWeight = Weight().Min().ToIntRounded(); int len = std::min(aName.Length(), LF_FACESIZE - 1); memcpy(&mLogFont.lfFaceName, aName.BeginReading(), len * sizeof(char16_t)); @@ -467,7 +469,7 @@ GDIFontFamily::FamilyAddStylesProc(const ENUMLOGFONTEXW *lpelfe, for (uint32_t i = 0; i < ff->mAvailableFonts.Length(); ++i) { fe = static_cast(ff->mAvailableFonts[i].get()); // check if we already know about this face - if (fe->mWeight == FontWeight(int32_t(logFont.lfWeight)) && + if (fe->Weight().Min() == FontWeight(int32_t(logFont.lfWeight)) && fe->IsItalic() == (logFont.lfItalic == 0xFF)) { // update the charset bit here since this could be different // XXX Can we still do this now that we store mCharset @@ -729,7 +731,7 @@ gfxGDIFontList::LookupLocalFont(const nsAString& aFontName, // '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->mWeight, aStretch, nullptr); + lookup->mStyle, lookup->Weight().Min(), aStretch, nullptr); if (!fe) return nullptr; @@ -737,7 +739,7 @@ gfxGDIFontList::LookupLocalFont(const nsAString& aFontName, fe->mIsLocalUserFont = true; // make the new font entry match the userfont entry style characteristics - fe->mWeight = aWeight; + fe->mWeightRange = WeightRange(aWeight); fe->mStyle = aStyle; return fe; diff --git a/gfx/thebes/gfxMacFont.cpp b/gfx/thebes/gfxMacFont.cpp index d27d7056b6cf..b0fe4d43376a 100644 --- a/gfx/thebes/gfxMacFont.cpp +++ b/gfx/thebes/gfxMacFont.cpp @@ -37,33 +37,23 @@ gfxMacFont::gfxMacFont(const RefPtr& aUnscaledFont, mApplySyntheticBold = aNeedsBold; if (mVariationFont && (!aFontStyle->variationSettings.IsEmpty() || - !aFontEntry->mVariationSettings.IsEmpty())) { + !aFontEntry->mVariationSettings.IsEmpty() || + !aFontEntry->Weight().IsSingle())) { CGFontRef baseFont = aUnscaledFont->GetFont(); if (!baseFont) { mIsValid = false; return; } - // Probably one of the lists of variations, either from the @font-face - // descriptor or from the property, will be empty. So skip merging them - // unless really necessary. - const nsTArray* vars; - AutoTArray mergedSettings; - if (aFontStyle->variationSettings.IsEmpty()) { - vars = &aFontEntry->mVariationSettings; - } else if (aFontEntry->mVariationSettings.IsEmpty()) { - vars = &aFontStyle->variationSettings; - } else { - gfxFontUtils::MergeVariations(aFontEntry->mVariationSettings, - aFontStyle->variationSettings, - &mergedSettings); - vars = &mergedSettings; - } + // Get the variation settings needed to instantiate the fontEntry + // for a particular fontStyle. + AutoTArray vars; + aFontEntry->GetVariationsForStyle(vars, *aFontStyle); mCGFont = UnscaledFontMac::CreateCGFontWithVariations(baseFont, - vars->Length(), - vars->Elements()); + vars.Length(), + vars.Elements()); if (!mCGFont) { ::CFRetain(baseFont); mCGFont = baseFont; diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm index ded271823d8e..53a634d00e59 100644 --- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -383,7 +383,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, mTrakValues(nullptr), mTrakSizeTable(nullptr) { - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); } MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, @@ -413,7 +413,7 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, mFontRefInitialized = true; ::CFRetain(mFontRef); - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStretch = aStretch; mFixedPitch = false; // xxx - do we need this for downloaded fonts? mStyle = aStyle; @@ -429,9 +429,10 @@ MacOSFontEntry::Clone() const { MOZ_ASSERT(!IsUserFont(), "we can only clone installed fonts!"); MacOSFontEntry* fe = - new MacOSFontEntry(Name(), mWeight, mStandardFace, mSizeHint); + new MacOSFontEntry(Name(), Weight().Min(), mStandardFace, mSizeHint); fe->mStyle = mStyle; fe->mStretch = mStretch; + fe->mWeightRange = mWeightRange; fe->mFixedPitch = mFixedPitch; return fe; } @@ -928,14 +929,19 @@ gfxMacFontFamily::FindStyleVariations(FontInfoData *aFontInfoData) fontEntry->mFixedPitch = true; } + fontEntry->SetupVariationRanges(); + if (LOG_FONTLIST_ENABLED()) { + nsAutoCString weightString; + fontEntry->Weight().ToString(weightString); LOG_FONTLIST(("(fontlist) added (%s) to family (%s)" - " with style: %s weight: %d stretch: %d" + " with style: %s weight: %s stretch: %d" " (apple-weight: %d macTraits: %8.8x)", NS_ConvertUTF16toUTF8(fontEntry->Name()).get(), NS_ConvertUTF16toUTF8(Name()).get(), fontEntry->IsItalic() ? "italic" : "normal", - cssWeight, fontEntry->Stretch(), + weightString.get(), + fontEntry->Stretch(), appKitWeight, macTraits)); } @@ -1282,9 +1288,10 @@ gfxMacPlatformFontList::InitSingleFaceList() // 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->mWeight, true, + new MacOSFontEntry(fe->Name(), fe->Weight().Min(), true, static_cast(fe)-> mSizeHint); + fontEntry->mWeightRange = fe->mWeightRange; familyEntry->AddFontEntry(fontEntry); familyEntry->SetHasStyles(true); mFontFamilies.Put(key, familyEntry); diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 023e7db501d2..2aab9c8d6e2b 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -126,7 +126,7 @@ gfxUserFontEntry::gfxUserFontEntry(gfxUserFontSet* aFontSet, mIsUserFontContainer = true; mSrcList = aFontFaceSrcList; mSrcIndex = 0; - mWeight = aWeight; + mWeightRange = WeightRange(aWeight); mStretch = aStretch; mStyle = aStyle; mFeatureSettings.AppendElements(aFeatureSettings); @@ -154,7 +154,8 @@ gfxUserFontEntry::Matches(const nsTArray& aFontFaceSrcList, gfxCharacterMap* aUnicodeRanges, uint8_t aFontDisplay) { - return mWeight == aWeight && + return Weight().Min() == aWeight && + Weight().Max() == aWeight && mStretch == aStretch && mStyle == aStyle && mFeatureSettings == aFeatureSettings && @@ -516,7 +517,7 @@ gfxUserFontEntry::DoLoadNextSrc(bool aForceAsync) gfxFontEntry* fe = pfl && pfl->IsFontFamilyWhitelistActive() ? nullptr : gfxPlatform::GetPlatform()->LookupLocalFont(currSrc.mLocalName, - mWeight, + Weight().Min(), mStretch, mStyle); nsTArray fontSets; @@ -771,7 +772,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength) // Here ownership of saneData is passed to the platform, // which will delete it when no longer required fe = gfxPlatform::GetPlatform()->MakePlatformFont(mName, - mWeight, + Weight().Min(), mStretch, mStyle, saneData, @@ -1040,12 +1041,15 @@ gfxUserFontSet::AddUserFontEntry(const nsAString& aFamilyName, family->AddFontEntry(aUserFontEntry); if (LOG_ENABLED()) { - LOG(("userfonts (%p) added to \"%s\" (%p) style: %s weight: %g " + nsAutoCString weightString; + aUserFontEntry->Weight().ToString(weightString); + LOG(("userfonts (%p) added to \"%s\" (%p) style: %s weight: %s " "stretch: %d display: %d", this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aUserFontEntry, (aUserFontEntry->IsItalic() ? "italic" : (aUserFontEntry->IsOblique() ? "oblique" : "normal")), - aUserFontEntry->Weight().ToFloat(), aUserFontEntry->Stretch(), + weightString.get(), + aUserFontEntry->Stretch(), aUserFontEntry->GetFontDisplay())); } } @@ -1182,7 +1186,7 @@ gfxUserFontSet::UserFontCache::Entry::KeyEquals(const KeyTypePointer aKey) const } if (mFontEntry->mStyle != fe->mStyle || - mFontEntry->mWeight != fe->mWeight || + mFontEntry->Weight() != fe->Weight() || mFontEntry->mStretch != fe->mStretch || mFontEntry->mFeatureSettings != fe->mFeatureSettings || mFontEntry->mVariationSettings != fe->mVariationSettings || diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index 3ffc361cede6..c8467084332a 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -406,7 +406,8 @@ public: HashFeatures(aKey->mFontEntry->mFeatureSettings), HashVariations(aKey->mFontEntry->mVariationSettings), mozilla::HashString(aKey->mFontEntry->mFamilyName), - aKey->mFontEntry->mWeight.ForHash(), + aKey->mFontEntry->Weight().Min().ForHash(), + aKey->mFontEntry->Weight().Max().ForHash(), (aKey->mFontEntry->mStyle | (aKey->mFontEntry->mStretch << 11) ) ^ aKey->mFontEntry->mLanguageOverride); diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index 128496437c97..aee7b4d5cc46 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -1247,13 +1247,15 @@ FontFaceSet::LogMessage(gfxUserFontEntry* aUserFontEntry, nsAutoCString fontURI; aUserFontEntry->GetFamilyNameAndURIForLogging(familyName, fontURI); + nsAutoCString weightString; + aUserFontEntry->Weight().ToString(weightString); nsPrintfCString message ("downloadable font: %s " - "(font-family: \"%s\" style:%s weight:%g stretch:%s src index:%d)", + "(font-family: \"%s\" style:%s weight:%s stretch:%s src index:%d)", aMessage, familyName.get(), aUserFontEntry->IsItalic() ? "italic" : "normal", - aUserFontEntry->Weight().ToFloat(), + weightString.get(), nsCSSProps::ValueToKeyword(aUserFontEntry->Stretch(), nsCSSProps::kFontStretchKTable).get(), aUserFontEntry->GetSrcIndex());