This fixes the font-stretch issues diego is finding in bug 1911075. Differential Revision: https://phabricator.services.mozilla.com/D31250
255 lines
9.3 KiB
C++
255 lines
9.3 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/*
|
|
* methods for dealing with CSS properties and tables of the keyword
|
|
* values they accept
|
|
*/
|
|
|
|
#ifndef nsCSSProps_h_
|
|
#define nsCSSProps_h_
|
|
|
|
#include <ostream>
|
|
|
|
#include "NonCustomCSSPropertyId.h"
|
|
#include "mozilla/CSSEnabledState.h"
|
|
#include "mozilla/CSSPropFlags.h"
|
|
#include "mozilla/Maybe.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/UseCounter.h"
|
|
#include "nsString.h"
|
|
#include "nsStyleStructFwd.h"
|
|
|
|
// Length of the "--" prefix on custom names (such as custom property names,
|
|
// and, in the future, custom media query names).
|
|
#define CSS_CUSTOM_NAME_PREFIX_LENGTH 2
|
|
|
|
namespace mozilla {
|
|
class ComputedStyle;
|
|
namespace gfx {
|
|
class gfxVarReceiver;
|
|
}
|
|
} // namespace mozilla
|
|
|
|
extern "C" {
|
|
NonCustomCSSPropertyId Servo_ResolveLogicalProperty(
|
|
NonCustomCSSPropertyId, const mozilla::ComputedStyle*);
|
|
NonCustomCSSPropertyId Servo_Property_LookupEnabledForAllContent(
|
|
const nsACString*);
|
|
const uint8_t* Servo_Property_GetName(NonCustomCSSPropertyId,
|
|
uint32_t* aLength);
|
|
}
|
|
|
|
class nsCSSProps {
|
|
public:
|
|
using EnabledState = mozilla::CSSEnabledState;
|
|
using Flags = mozilla::CSSPropFlags;
|
|
|
|
static void Init();
|
|
|
|
// Looks up the property with name aProperty and returns its corresponding
|
|
// NonCustomCSSPropertyId value. If aProperty is the name of a custom
|
|
// property, then eCSSPropertyExtra_variable will be returned.
|
|
//
|
|
// This only returns properties enabled for all content, and resolves aliases
|
|
// to return the aliased property.
|
|
static NonCustomCSSPropertyId LookupProperty(const nsACString& aProperty) {
|
|
return Servo_Property_LookupEnabledForAllContent(&aProperty);
|
|
}
|
|
|
|
// As above, but looked up using a property's IDL name, and resolves
|
|
// aliases to return the aliased property.
|
|
// eCSSPropertyExtra_variable won't be returned from this method.
|
|
static NonCustomCSSPropertyId LookupPropertyByIDLName(
|
|
const nsACString& aPropertyIDLName, EnabledState aEnabled);
|
|
|
|
// Returns whether aProperty is a custom property name, i.e. begins with
|
|
// "--". This assumes that the CSS Variables pref has been enabled.
|
|
static bool IsCustomPropertyName(const nsACString& aProperty);
|
|
|
|
static bool IsShorthand(NonCustomCSSPropertyId aProperty) {
|
|
if (aProperty == eCSSPropertyExtra_variable) {
|
|
return false;
|
|
}
|
|
MOZ_ASSERT(
|
|
aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT,
|
|
"out of range");
|
|
return aProperty >= eCSSProperty_COUNT_no_shorthands;
|
|
}
|
|
|
|
// Same but for @font-face descriptors
|
|
static mozilla::Maybe<mozilla::FontFaceDescriptorId> LookupFontDesc(
|
|
const nsACString&);
|
|
static mozilla::Maybe<mozilla::CounterStyleDescriptorId>
|
|
LookupCounterStyleDesc(const nsACString&);
|
|
|
|
// The relevant invariants are asserted in Document.cpp
|
|
static mozilla::UseCounter UseCounterFor(NonCustomCSSPropertyId aProperty) {
|
|
MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN &&
|
|
aProperty < eCSSProperty_COUNT_with_aliases,
|
|
"out of range");
|
|
return mozilla::UseCounter(size_t(mozilla::eUseCounter_FirstCSSProperty) +
|
|
size_t(aProperty));
|
|
}
|
|
|
|
// Given a property enum, get the string value
|
|
//
|
|
// This string is static.
|
|
static nsDependentCSubstring GetStringValue(
|
|
NonCustomCSSPropertyId aProperty) {
|
|
uint32_t len;
|
|
const uint8_t* chars = Servo_Property_GetName(aProperty, &len);
|
|
return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
|
|
}
|
|
|
|
static const nsCString& GetStringValue(mozilla::FontFaceDescriptorId);
|
|
static const nsCString& GetStringValue(mozilla::CounterStyleDescriptorId);
|
|
|
|
static Flags PropFlags(NonCustomCSSPropertyId);
|
|
static bool PropHasFlags(NonCustomCSSPropertyId aProperty, Flags aFlags) {
|
|
return (PropFlags(aProperty) & aFlags) == aFlags;
|
|
}
|
|
|
|
static NonCustomCSSPropertyId Physicalize(
|
|
NonCustomCSSPropertyId aProperty, const mozilla::ComputedStyle& aStyle) {
|
|
MOZ_ASSERT(!IsShorthand(aProperty));
|
|
if (PropHasFlags(aProperty, Flags::IsLogical)) {
|
|
return Servo_ResolveLogicalProperty(aProperty, &aStyle);
|
|
}
|
|
return aProperty;
|
|
}
|
|
|
|
private:
|
|
// A table for shorthand properties. The appropriate index is the
|
|
// property id minus eCSSProperty_COUNT_no_shorthands.
|
|
static const NonCustomCSSPropertyId* const
|
|
kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands];
|
|
|
|
public:
|
|
/**
|
|
* Returns true if the backdrop-filter pref and the gfx blocklist are enabled.
|
|
*/
|
|
static bool IsBackdropFilterAvailable(JSContext*, JSObject*) {
|
|
return IsEnabled(eCSSProperty_backdrop_filter, EnabledState::ForAllContent);
|
|
}
|
|
|
|
/**
|
|
* Recoumputes the enabled state of a pref. If aPrefName is nullptr,
|
|
* recomputes the state of all prefs in gPropertyEnabled.
|
|
* aClosure is the pref callback closure data, which is not used.
|
|
*/
|
|
static void RecomputeEnabledState(const char* aPrefName,
|
|
void* aClosure = nullptr);
|
|
|
|
/**
|
|
* Retrieve a singleton receiver to register with gfxVars
|
|
*/
|
|
static mozilla::gfx::gfxVarReceiver& GfxVarReceiver();
|
|
|
|
static const NonCustomCSSPropertyId* SubpropertyEntryFor(
|
|
NonCustomCSSPropertyId aProperty) {
|
|
MOZ_ASSERT(eCSSProperty_COUNT_no_shorthands <= aProperty &&
|
|
aProperty < eCSSProperty_COUNT,
|
|
"out of range");
|
|
return kSubpropertyTable[aProperty - eCSSProperty_COUNT_no_shorthands];
|
|
}
|
|
|
|
private:
|
|
static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases];
|
|
// Defined in the generated nsCSSPropsGenerated.inc.
|
|
static const char* const kIDLNameTable[eCSSProperty_COUNT_with_aliases];
|
|
static const int32_t
|
|
kIDLNameSortPositionTable[eCSSProperty_COUNT_with_aliases];
|
|
|
|
public:
|
|
/**
|
|
* Returns the IDL name of the specified property, which must be a
|
|
* longhand, logical or shorthand property. The IDL name is the property
|
|
* name with any hyphen-lowercase character pairs replaced by an
|
|
* uppercase character:
|
|
* https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
|
|
*
|
|
* As a special case, the string "cssFloat" is returned for the float
|
|
* property. nullptr is returned for internal properties.
|
|
*/
|
|
static const char* PropertyIDLName(NonCustomCSSPropertyId aProperty) {
|
|
MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN);
|
|
MOZ_ASSERT(aProperty < eCSSProperty_COUNT_with_aliases);
|
|
return kIDLNameTable[aProperty];
|
|
}
|
|
|
|
/**
|
|
* Returns the position of the specified property in a list of all
|
|
* properties sorted by their IDL name.
|
|
*/
|
|
static int32_t PropertyIDLNameSortPosition(NonCustomCSSPropertyId aProperty) {
|
|
MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN);
|
|
MOZ_ASSERT(aProperty < eCSSProperty_COUNT_with_aliases);
|
|
return kIDLNameSortPositionTable[aProperty];
|
|
}
|
|
|
|
static bool IsEnabled(NonCustomCSSPropertyId aProperty,
|
|
EnabledState aEnabled) {
|
|
MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN);
|
|
MOZ_ASSERT(aProperty < eCSSProperty_COUNT_with_aliases);
|
|
// In the child process, assert that we're not trying to parse stylesheets
|
|
// before we've gotten all our prefs.
|
|
MOZ_ASSERT_IF(!XRE_IsParentProcess(),
|
|
mozilla::Preferences::ArePrefsInitedInContentProcess());
|
|
if (gPropertyEnabled[aProperty]) {
|
|
return true;
|
|
}
|
|
if (aEnabled == EnabledState::IgnoreEnabledState) {
|
|
return true;
|
|
}
|
|
if ((aEnabled & EnabledState::InUASheets) &&
|
|
PropHasFlags(aProperty, Flags::EnabledInUASheets)) {
|
|
return true;
|
|
}
|
|
if ((aEnabled & EnabledState::InChrome) &&
|
|
PropHasFlags(aProperty, Flags::EnabledInChrome)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
struct PropertyPref {
|
|
NonCustomCSSPropertyId mPropId;
|
|
const char* mPref;
|
|
};
|
|
static const PropertyPref kPropertyPrefTable[];
|
|
|
|
template <typename Id>
|
|
struct DescriptorTableEntry {
|
|
Id mId;
|
|
nsLiteralCString mName;
|
|
};
|
|
|
|
static const DescriptorTableEntry<mozilla::FontFaceDescriptorId>
|
|
kFontFaceDescs[mozilla::kFontFaceDescriptorCount];
|
|
static const DescriptorTableEntry<mozilla::CounterStyleDescriptorId>
|
|
kCounterStyleDescs[mozilla::kCounterStyleDescriptorCount];
|
|
|
|
// Storing the enabledstate_ value in an NonCustomCSSPropertyId variable is a
|
|
// small hack to avoid needing a separate variable declaration for its real type
|
|
// (CSSEnabledState), which would then require using a block and
|
|
// therefore a pair of macros by consumers for the start and end of the loop.
|
|
#define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(it_, prop_, enabledstate_) \
|
|
for (const NonCustomCSSPropertyId * \
|
|
it_ = nsCSSProps::SubpropertyEntryFor(prop_), \
|
|
es_ = \
|
|
(NonCustomCSSPropertyId)((enabledstate_) | CSSEnabledState(0)); \
|
|
*it_ != eCSSProperty_UNKNOWN; ++it_) \
|
|
if (nsCSSProps::IsEnabled(*it_, (mozilla::CSSEnabledState)es_))
|
|
};
|
|
|
|
// MOZ_DBG support for NonCustomCSSPropertyId
|
|
|
|
inline std::ostream& operator<<(std::ostream& aOut,
|
|
NonCustomCSSPropertyId aProperty) {
|
|
return aOut << nsCSSProps::GetStringValue(aProperty);
|
|
}
|
|
|
|
#endif /* nsCSSProps_h_ */
|