зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1454598 - part 2 - Allow variation fonts to record a weight range in gfxFontEntry, and update font-matching to handle ranges. r=jwatt
This commit is contained in:
Родитель
c75bb6f48d
Коммит
6ca182d055
|
@ -656,9 +656,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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8,10 +8,13 @@
|
|||
#ifndef GFX_FONT_PROPERTY_TYPES_H
|
||||
#define GFX_FONT_PROPERTY_TYPES_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "nsStringFwd.h"
|
||||
#include "nsString.h"
|
||||
|
||||
/*
|
||||
* This file is separate from gfxFont.h so that layout can include it
|
||||
|
@ -348,6 +351,80 @@ private:
|
|||
static const InternalType kItalic = INT16_MAX;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
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<T,T> mValues;
|
||||
};
|
||||
|
||||
typedef FontPropertyRange<FontWeight> WeightRange;
|
||||
typedef FontPropertyRange<FontStretch> StretchRange;
|
||||
typedef FontPropertyRange<FontSlantStyle> StyleRange;
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GFX_FONT_PROPERTY_TYPES_H
|
||||
|
|
|
@ -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,7 +675,7 @@ gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
|
|||
// XXX todo: consider caching a small number of variation instances?
|
||||
RefPtr<IDWriteFontFace> fontFace;
|
||||
nsresult rv = CreateFontFace(getter_AddRefs(fontFace),
|
||||
&aFontStyle->variationSettings,
|
||||
aFontStyle,
|
||||
sims);
|
||||
if (NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
|
@ -684,7 +690,7 @@ gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
|
|||
RefPtr<UnscaledFontDWrite> unscaledFont(unscaledFontPtr);
|
||||
if (!unscaledFont) {
|
||||
RefPtr<IDWriteFontFace> 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<gfxFontVariation>* 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<IDWriteFontResource> resource;
|
||||
HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource));
|
||||
MOZ_ASSERT(SUCCEEDED(hr));
|
||||
AutoTArray<DWRITE_FONT_AXIS_VALUE, 4> fontAxisValues;
|
||||
if (aVariations) {
|
||||
// Merge mVariationSettings and *aVariations if both present
|
||||
const nsTArray<gfxFontVariation>* vars;
|
||||
AutoTArray<gfxFontVariation,4> 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<gfxFontVariation,4> 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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,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;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
mIsSystemFont(false), mForceGDIClassic(false),
|
||||
mHasVariations(false), mHasVariationsInitialized(false)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
mWeightRange = WeightRange(aWeight);
|
||||
mStretch = aStretch;
|
||||
mStyle = aStyle;
|
||||
mIsLocalUserFont = true;
|
||||
|
@ -176,7 +176,7 @@ public:
|
|||
mIsSystemFont(false), mForceGDIClassic(false),
|
||||
mHasVariations(false), mHasVariationsInitialized(false)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
mWeightRange = WeightRange(aWeight);
|
||||
mStretch = aStretch;
|
||||
mStyle = aStyle;
|
||||
mIsDataUserFont = true;
|
||||
|
@ -217,7 +217,7 @@ protected:
|
|||
|
||||
nsresult CreateFontFace(
|
||||
IDWriteFontFace **aFontFace,
|
||||
const nsTArray<gfxFontVariation>* aVariations = nullptr,
|
||||
const gfxFontStyle* aFontStyle = nullptr,
|
||||
DWRITE_FONT_SIMULATIONS aSimulations = DWRITE_FONT_SIMULATIONS_NONE);
|
||||
|
||||
static bool InitLogFont(IDWriteFont *aFont, LOGFONTW *aLogFont);
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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<gfxFontVariation>* settings;
|
||||
AutoTArray<gfxFontVariation,8> 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<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());
|
||||
|
|
|
@ -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 = FontStretch(float(aFLE.stretch()));
|
||||
fe->mStyle = aFLE.italic()
|
||||
? FontSlantStyle::Italic() : FontSlantStyle::Normal();
|
||||
|
@ -393,7 +394,7 @@ FT2FontEntry::CreateFontEntry(FT_Face aFace,
|
|||
FT2FontEntry *fe = new FT2FontEntry(aName);
|
||||
fe->mStyle = (FTFaceIsItalic(aFace) ?
|
||||
FontSlantStyle::Italic() : FontSlantStyle::Normal());
|
||||
fe->mWeight = FTFaceGetWeight(aFace);
|
||||
fe->mWeightRange = WeightRange(FTFaceGetWeight(aFace));
|
||||
fe->mFilename = aFilename;
|
||||
fe->mFTFontIndex = aIndex;
|
||||
|
||||
|
@ -460,28 +461,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<gfxFontVariation>* settings;
|
||||
AutoTArray<gfxFontVariation,8> mergedSettings;
|
||||
if (aStyle) {
|
||||
if (mVariationSettings.IsEmpty()) {
|
||||
settings = &aStyle->variationSettings;
|
||||
} else {
|
||||
gfxFontUtils::MergeVariations(mVariationSettings,
|
||||
aStyle->variationSettings,
|
||||
&mergedSettings);
|
||||
settings = &mergedSettings;
|
||||
}
|
||||
} else {
|
||||
settings = &mVariationSettings;
|
||||
}
|
||||
AutoTArray<gfxFontVariation,8> settings;
|
||||
GetVariationsForStyle(settings, aStyle ? *aStyle : gfxFontStyle());
|
||||
AutoTArray<FT_Fixed,8> 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;
|
||||
|
@ -670,7 +660,8 @@ FT2FontFamily::AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList)
|
|||
aFontList->AppendElement(FontListEntry(Name(),
|
||||
fe->Name(),
|
||||
fe->mFilename,
|
||||
fe->Weight().ToFloat(),
|
||||
fe->Weight().Min().ToFloat(),
|
||||
fe->Weight().Max().ToFloat(),
|
||||
fe->Stretch().Percentage(),
|
||||
fe->mStyle.IsItalic()
|
||||
? NS_FONT_STYLE_ITALIC
|
||||
|
@ -967,7 +958,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;
|
||||
|
@ -975,7 +973,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;
|
||||
|
@ -995,7 +994,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(',');
|
||||
// FIXME(emilio): Probably the stretch should be converted to float.
|
||||
aFaceList.AppendInt(int32_t(aFontEntry->Stretch().Percentage()));
|
||||
|
@ -1154,12 +1155,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: %g%%",
|
||||
" with style: %s weight: %s stretch: %g%%",
|
||||
NS_ConvertUTF16toUTF8(fe->Name()).get(),
|
||||
NS_ConvertUTF16toUTF8(family->Name()).get(),
|
||||
fe->IsItalic() ? "italic" : "normal",
|
||||
fe->Weight().ToFloat(), fe->Stretch().Percentage()));
|
||||
weightString.get(),
|
||||
fe->Stretch().Percentage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1527,7 +1531,7 @@ searchDone:
|
|||
fontEntry->Name(), nullptr);
|
||||
if (fe) {
|
||||
fe->mStyle = aStyle;
|
||||
fe->mWeight = aWeight;
|
||||
fe->mWeightRange = WeightRange(aWeight);
|
||||
fe->mStretch = aStretch;
|
||||
fe->mIsLocalUserFont = true;
|
||||
}
|
||||
|
|
|
@ -255,7 +255,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;
|
||||
|
@ -328,7 +328,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
|
|||
mHasVariationsInitialized(false),
|
||||
mAspect(0.0), mFontData(aData), mLength(aLength)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
mWeightRange = WeightRange(aWeight);
|
||||
mStyle = aStyle;
|
||||
mStretch = aStretch;
|
||||
mIsDataUserFont = true;
|
||||
|
@ -348,7 +348,7 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsAString& aFaceName,
|
|||
mHasVariationsInitialized(false),
|
||||
mAspect(0.0), mFontData(nullptr), mLength(0)
|
||||
{
|
||||
mWeight = aWeight;
|
||||
mWeightRange = WeightRange(aWeight);
|
||||
mStyle = aStyle;
|
||||
mStretch = aStretch;
|
||||
mIsLocalUserFont = true;
|
||||
|
@ -771,22 +771,14 @@ gfxFontconfigFontEntry::CreateScaledFont(FcPattern* aRenderPattern,
|
|||
}
|
||||
|
||||
AutoTArray<FT_Fixed,8> coords;
|
||||
if (!aStyle->variationSettings.IsEmpty() || !mVariationSettings.IsEmpty()) {
|
||||
if (!aStyle->variationSettings.IsEmpty() ||
|
||||
!mVariationSettings.IsEmpty() ||
|
||||
!Weight().IsSingle()) {
|
||||
FT_Face ftFace = GetFTFace();
|
||||
if (ftFace) {
|
||||
const nsTArray<gfxFontVariation>* settings;
|
||||
AutoTArray<gfxFontVariation,8> 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<gfxFontVariation,8> settings;
|
||||
GetVariationsForStyle(settings, *aStyle);
|
||||
gfxFT2FontBase::SetupVarCoords(ftFace, settings, &coords);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,6 +1210,8 @@ gfxFontconfigFontFamily::FindStyleVariations(FontInfoData *aFontInfoData)
|
|||
|
||||
gfxFontconfigFontEntry *fontEntry =
|
||||
new gfxFontconfigFontEntry(faceName, face, mContainsAppFonts);
|
||||
fontEntry->SetupVariationRanges();
|
||||
|
||||
AddFontEntry(fontEntry);
|
||||
|
||||
if (fontEntry->IsNormalStyle()) {
|
||||
|
@ -1225,14 +1219,16 @@ 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: %g%%"
|
||||
" with style: %s weight: %s stretch: %g%%"
|
||||
" psname: %s fullname: %s",
|
||||
NS_ConvertUTF16toUTF8(fontEntry->Name()).get(),
|
||||
NS_ConvertUTF16toUTF8(Name()).get(),
|
||||
(fontEntry->IsItalic()) ?
|
||||
"italic" : (fontEntry->IsOblique() ? "oblique" : "normal"),
|
||||
fontEntry->Weight().ToFloat(),
|
||||
weightString.get(),
|
||||
fontEntry->Stretch().Percentage(),
|
||||
NS_ConvertUTF16toUTF8(psname).get(),
|
||||
NS_ConvertUTF16toUTF8(fullname).get()));
|
||||
|
@ -1338,7 +1334,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.
|
||||
|
|
|
@ -80,7 +80,7 @@ gfxFontEntry::gfxFontEntry() :
|
|||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
mCheckedForColorGlyph(false),
|
||||
mWeight(500),
|
||||
mWeightRange(FontWeight(500)),
|
||||
mStretch(FontStretch::Normal()),
|
||||
mStyle(FontSlantStyle::Normal()),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
|
@ -119,7 +119,7 @@ gfxFontEntry::gfxFontEntry(const nsAString& aName, bool aIsStandardFace) :
|
|||
mHasCmapTable(false),
|
||||
mGrFaceInitialized(false),
|
||||
mCheckedForColorGlyph(false),
|
||||
mWeight(500),
|
||||
mWeightRange(FontWeight(500)),
|
||||
mStretch(FontStretch::Normal()),
|
||||
mStyle(FontSlantStyle::Normal()),
|
||||
mUVSOffset(0), mUVSData(nullptr),
|
||||
|
@ -1032,6 +1032,86 @@ gfxFontEntry::GetColorLayersInfo(uint32_t aGlyphId,
|
|||
aLayerColors);
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontEntry::SetupVariationRanges()
|
||||
{
|
||||
if (!HasVariations() || IsUserFont()) {
|
||||
return;
|
||||
}
|
||||
AutoTArray<gfxFontVariationAxis,4> 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<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});
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
|
@ -1240,33 +1320,35 @@ StretchDistance(FontStretch aFontStretch, FontStretch 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;
|
||||
}
|
||||
}
|
||||
|
@ -1288,8 +1370,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");
|
||||
|
@ -1448,8 +1529,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"
|
||||
}
|
||||
|
@ -1496,33 +1580,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) {
|
||||
// TODO: stretch
|
||||
|
||||
// italics
|
||||
bool wantUpright = aStyle->style.IsNormal();
|
||||
if (aFontEntry->IsUpright() == wantUpright) {
|
||||
rank += 10;
|
||||
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)
|
||||
|
@ -1540,7 +1632,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;
|
||||
|
@ -1600,7 +1692,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 &&
|
||||
|
|
|
@ -115,6 +115,7 @@ public:
|
|||
typedef mozilla::FontWeight FontWeight;
|
||||
typedef mozilla::FontSlantStyle FontSlantStyle;
|
||||
typedef mozilla::FontStretch FontStretch;
|
||||
typedef mozilla::WeightRange WeightRange;
|
||||
|
||||
// Used by stylo
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontEntry)
|
||||
|
@ -143,7 +144,7 @@ public:
|
|||
// returns Name() if nothing better is available.
|
||||
virtual nsString RealFaceName();
|
||||
|
||||
FontWeight Weight() const { return mWeight; }
|
||||
WeightRange Weight() const { return mWeightRange; }
|
||||
FontStretch Stretch() const { return mStretch; }
|
||||
|
||||
bool IsUserFont() const { return mIsDataUserFont || mIsLocalUserFont; }
|
||||
|
@ -152,7 +153,7 @@ public:
|
|||
bool IsItalic() const { return mStyle.IsItalic(); }
|
||||
bool IsOblique() const { return mStyle.IsOblique(); }
|
||||
bool IsUpright() const { return mStyle.IsNormal(); }
|
||||
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; }
|
||||
|
||||
|
@ -165,7 +166,8 @@ public:
|
|||
bool IsNormalStyle() const
|
||||
{
|
||||
return IsUpright() &&
|
||||
Weight() == FontWeight::Normal() &&
|
||||
Weight().Min() <= FontWeight::Normal() &&
|
||||
Weight().Max() >= FontWeight::Normal() &&
|
||||
Stretch().IsNormal();
|
||||
}
|
||||
|
||||
|
@ -370,6 +372,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<gfxFontVariation>& aResult,
|
||||
const gfxFontStyle& aStyle);
|
||||
|
||||
// Get the font's list of features (if any) for DevTools support.
|
||||
void GetFeatureInfo(nsTArray<gfxFontFeatureInfo>& aFeatureInfo);
|
||||
|
||||
|
@ -405,7 +417,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;
|
||||
FontStretch mStretch;
|
||||
FontSlantStyle mStyle;
|
||||
|
||||
|
@ -612,14 +624,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<gfxFontEntry> mBestMatch; // current best match
|
||||
RefPtr<gfxFontFamily> mMatchedFamily; // the family it belongs to
|
||||
uint32_t mCount; // number of fonts matched
|
||||
|
|
|
@ -1944,24 +1944,6 @@ gfxFontUtils::GetVariationInstances(gfxFontEntry* aFontEntry,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontUtils::MergeVariations(const nsTArray<gfxFontVariation>& aEntrySettings,
|
||||
const nsTArray<gfxFontVariation>& aStyleSettings,
|
||||
nsTArray<gfxFontVariation>* 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 */
|
||||
|
|
|
@ -1010,22 +1010,6 @@ public:
|
|||
GetVariationInstances(gfxFontEntry* aFontEntry,
|
||||
nsTArray<gfxFontVariationInstance>& 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<gfxFontVariation>& aEntrySettings,
|
||||
const nsTArray<gfxFontVariation>& aStyleSettings,
|
||||
nsTArray<gfxFontVariation>* 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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 = FontSlantStyle::Italic();
|
||||
}
|
||||
fakeStyle.weight = mWeight;
|
||||
fakeStyle.weight = Weight().Min();
|
||||
|
||||
RefPtr<gfxFont> 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<int>(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<GDIFontEntry*>(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
|
||||
|
@ -733,7 +735,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;
|
||||
|
@ -741,7 +743,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;
|
||||
|
|
|
@ -37,33 +37,23 @@ gfxMacFont::gfxMacFont(const RefPtr<UnscaledFontMac>& 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<gfxFontVariation>* vars;
|
||||
AutoTArray<gfxFontVariation,4> 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<gfxFontVariation,4> vars;
|
||||
aFontEntry->GetVariationsForStyle(vars, *aFontStyle);
|
||||
|
||||
mCGFont =
|
||||
UnscaledFontMac::CreateCGFontWithVariations(baseFont,
|
||||
vars->Length(),
|
||||
vars->Elements());
|
||||
vars.Length(),
|
||||
vars.Elements());
|
||||
if (!mCGFont) {
|
||||
::CFRetain(baseFont);
|
||||
mCGFont = baseFont;
|
||||
|
|
|
@ -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: %g%%"
|
||||
" with style: %s weight: %s stretch: %g%%"
|
||||
" (apple-weight: %d macTraits: %8.8x)",
|
||||
NS_ConvertUTF16toUTF8(fontEntry->Name()).get(),
|
||||
NS_ConvertUTF16toUTF8(Name()).get(),
|
||||
fontEntry->IsItalic() ? "italic" : "normal",
|
||||
cssWeight, fontEntry->Stretch().Percentage(),
|
||||
weightString.get(),
|
||||
fontEntry->Stretch().Percentage(),
|
||||
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<const MacOSFontEntry*>(fe)->
|
||||
mSizeHint);
|
||||
fontEntry->mWeightRange = fe->mWeightRange;
|
||||
familyEntry->AddFontEntry(fontEntry);
|
||||
familyEntry->SetHasStyles(true);
|
||||
mFontFamilies.Put(key, familyEntry);
|
||||
|
|
|
@ -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<gfxFontFaceSrc>& 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<gfxUserFontSet*> 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,14 @@ 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: %g%% display: %d",
|
||||
this, NS_ConvertUTF16toUTF8(aFamilyName).get(), aUserFontEntry,
|
||||
(aUserFontEntry->IsItalic() ? "italic" :
|
||||
(aUserFontEntry->IsOblique() ? "oblique" : "normal")),
|
||||
aUserFontEntry->Weight().ToFloat(),
|
||||
weightString.get(),
|
||||
aUserFontEntry->Stretch().Percentage(),
|
||||
aUserFontEntry->GetFontDisplay()));
|
||||
}
|
||||
|
@ -1183,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 ||
|
||||
|
|
|
@ -408,7 +408,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(),
|
||||
// XXX Is this right?
|
||||
aKey->mFontEntry->mStyle.ForHash(),
|
||||
aKey->mFontEntry->mStretch.ForHash(),
|
||||
|
|
|
@ -1288,13 +1288,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:%g%% src index:%d)",
|
||||
"(font-family: \"%s\" style:%s weight:%s stretch:%g%% src index:%d)",
|
||||
aMessage,
|
||||
familyName.get(),
|
||||
aUserFontEntry->IsItalic() ? "italic" : "normal",
|
||||
aUserFontEntry->Weight().ToFloat(),
|
||||
weightString.get(),
|
||||
aUserFontEntry->Stretch().Percentage(),
|
||||
aUserFontEntry->GetSrcIndex());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче