mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1235979 - Remove spammy printf that got left by accident when bug 1226904 landed. r=thinker (fc6fe64f23) - Bug 1208344 part 1: Make EnsurePhysicalProperty() return the property directly, instead of using in/out-param. r=heycam (9515887dd7) - Bug 1208344 part 2: Make EnsurePhysicalProperty() (not its callers) check whether property is logical. r=heycam (defa671bab) - Bug 1208344 part 3: Rename MapSinglePropertyInto() args, to make src-vs-target distinctions clearer. r=heycam (bfd2e2c9bc) - Bug 1208344 part 4: Make MapSinglePropertyInto() take the source property as an arg (unused for the moment). r=heycam (d1278eb58a) - Bug 1208344 part 5: Add (preffed-off) support for "-webkit-box-orient" CSS property, as a writing-mode-dependent alias for "flex-direction". r=heycam (d8407990aa) - Bug 1208344 part 6: Move new CSS_PROPERTY_LOGICAL_CUSTOM flag up with other LOGICAL flags, and adjust bits accordingly. r=heycam (df27d64733) - Bug 1208344 part 7: Add mochitest to test how "-webkit-box-orient" maps to "flex-direction". r=heycam (c448070877) - Bug 686225 - Work around buggy AAT fonts for Bengali and Kannada scripts. r=jdaggett (17afddbc6c) - Bug 739117 - Avoid bidi-wrapping the text to be shaped if Core Text direction override API is available. r=jdaggett (c492390922) - Bug 1156581 - Add null check to nsSVGEffects::InvalidateRenderingObservers to prevent crashes r=dholbert (4c0460e7ac) - remove windows accents (8b0ad08f11) - Bug 1123654 - Replace use of [deprecated] GetStockObject(DEFAULT_GUI_FONT) with newer API; results in use of Tahoma in place of Microsoft Sans Serif in various contexts. r=jmathies (3a81fc1bed) - put back cleartype for winXP (1c24e5ae09) - Bug 1240180 - Optimize native theme scaling for the single-monitor case. r=emk (a5846457ab) - Bug 1242720 - Use (non-dynamic) resolution from GetDeviceCaps when dealing with native-theme code that does not handle dynamic changes to system DPI. r=emk (7c25841f0b) - More win accent removal (afd6af9fd2) - some more vista or later stuff (1d99554064) - missing bits of Bug 1243720 - Send accessibility theme state down to the content process on Windows. r=jimm (8f00b4f3ca) - Bug 1153460 - Support new Fitzpatrick emoji modifiers and regional symbol indicators in Apple Color Emoji font. r=jdaggett (6faf5f30e6) - Bug 1230497 - Ignore font fallback in Core Text shaping if it's just for a join-control character. r=jdaggett (b612806a42) - Bug 1153460 - Followup to fix warnings-as-errors build failure on a CLOSED TREE. r=bustage. (12d492772c) - bug 1243077 - make it possible to get MaiAtkObject::mAccWrap from an AtkObject* without casting to Accessible* or ProxyAccessible* r=davidb (d8f690b6cd) - Bug 1238403 - Fix inconsistent indenting in layout/style/. r=xidorn (4f24334234) - Bug 717722 - Implement WebKitCSSMatrix. r=baku (c10f90ff6e) - Bug 1241723. Update WebKitCSSMatrix.idl to match latest spec updates. r=baku (5f8c33ff14) - Bug 1241727 - Inverting non-invertible WebKitCSSMatrix should throw NotSupportedError. r=baku (c7791802b8) - Bug 1241575 - Use transform property syntax to parse WebKitCSSMatrix transform list. r=heycam (5f886e2bd9) - bug 1243077 - add AccessibleOrProxy::ChildCount() r=davidb (044537f53c) - bug 1243077 - add AccessibleOrProxy::Role() r=davidb (3f61d03c8e) - bug 1243077 - add AccessibleOrProxy::ChildAt() r=davidb (91288f269f) - bug 1243077 - add AccessibleOrProxy::FirstChild() r=davidb (ea3f984716) - bug 1243077 - add AccessibleOrProxy::LastChild() r=davidb (2181f1740b) - Bug 1237720: Put "-webkit-min-device-pixel-ratio"/"-webkit-max-device-pixel-ratio" behind its own disabled pref. r=heycam (9f75535617) - Bug 1239153: Accept unitless '0' for angle values in CSS -webkit-linear-gradient() expressions. r=heycam (c11657a6c9) - Bug 1239799 part 1: Make check for -webkit-device-pixel-ratio pref more targeted, so we can support other webkit-prefixed media queries. r=heycam (1e8a40127e) - Bug 1239799 part 2: Add support for @media(-webkit-transform-3d) media query, for web compatibility. r=heycam (f7ff08423e) - guard some code for 10.5/10.6 which didn't get run, but coulnd't natively compile (cf68e969fd) - Bug 1019856 - avoid double-buffering in BasicCompositor when window allows it. r=mattwoodrow (e94cfc3fb4)
This commit is contained in:
@@ -1083,11 +1083,16 @@ GetAccessibleWrap(AtkObject* aAtkObj)
|
||||
ProxyAccessible*
|
||||
GetProxy(AtkObject* aObj)
|
||||
{
|
||||
if (!aObj || !IS_MAI_OBJECT(aObj) ||
|
||||
!MAI_ATK_OBJECT(aObj)->accWrap.IsProxy())
|
||||
return GetInternalObj(aObj).AsProxy();
|
||||
}
|
||||
|
||||
AccessibleOrProxy
|
||||
GetInternalObj(AtkObject* aObj)
|
||||
{
|
||||
if (!aObj || !IS_MAI_OBJECT(aObj))
|
||||
return nullptr;
|
||||
|
||||
return MAI_ATK_OBJECT(aObj)->accWrap.AsProxy();
|
||||
return MAI_ATK_OBJECT(aObj)->accWrap;
|
||||
}
|
||||
|
||||
AtkObject*
|
||||
|
||||
@@ -67,6 +67,7 @@ typedef struct _MaiAtkSocketClass
|
||||
|
||||
mozilla::a11y::AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj);
|
||||
mozilla::a11y::ProxyAccessible* GetProxy(AtkObject* aAtkObj);
|
||||
mozilla::a11y::AccessibleOrProxy GetInternalObj(AtkObject* aObj);
|
||||
AtkObject* GetWrapperFor(mozilla::a11y::ProxyAccessible* aProxy);
|
||||
|
||||
extern int atkMajorVersion, atkMinorVersion;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/a11y/Accessible.h"
|
||||
#include "mozilla/a11y/ProxyAccessible.h"
|
||||
#include "mozilla/a11y/Role.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -50,6 +51,61 @@ public:
|
||||
|
||||
bool IsNull() const { return mBits == 0; }
|
||||
|
||||
uint32_t ChildCount() const
|
||||
{
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->ChildrenCount();
|
||||
}
|
||||
|
||||
return AsAccessible()->ChildCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the child object either an accessible or a proxied accessible at
|
||||
* the given index.
|
||||
*/
|
||||
AccessibleOrProxy ChildAt(uint32_t aIdx)
|
||||
{
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->ChildAt(aIdx);
|
||||
}
|
||||
|
||||
return AsAccessible()->GetChildAt(aIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first child object.
|
||||
*/
|
||||
AccessibleOrProxy FirstChild()
|
||||
{
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->FirstChild();
|
||||
}
|
||||
|
||||
return AsAccessible()->FirstChild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first child object.
|
||||
*/
|
||||
AccessibleOrProxy LastChild()
|
||||
{
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->LastChild();
|
||||
}
|
||||
|
||||
return AsAccessible()->LastChild();
|
||||
}
|
||||
|
||||
role Role() const
|
||||
{
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->Role();
|
||||
}
|
||||
|
||||
return AsAccessible()->Role();
|
||||
}
|
||||
|
||||
// XXX these are implementation details that ideally would not be exposed.
|
||||
uintptr_t Bits() const { return mBits; }
|
||||
void SetBits(uintptr_t aBits) { mBits = aBits; }
|
||||
|
||||
@@ -142,7 +142,7 @@ private:
|
||||
DOMMatrixReadOnly& operator=(const DOMMatrixReadOnly&) = delete;
|
||||
};
|
||||
|
||||
class DOMMatrix final : public DOMMatrixReadOnly
|
||||
class DOMMatrix : public DOMMatrixReadOnly
|
||||
{
|
||||
public:
|
||||
explicit DOMMatrix(nsISupports* aParent)
|
||||
@@ -244,8 +244,10 @@ public:
|
||||
DOMMatrix* SkewYSelf(double aSy);
|
||||
DOMMatrix* InvertSelf();
|
||||
DOMMatrix* SetMatrixValue(const nsAString& aTransformList, ErrorResult& aRv);
|
||||
private:
|
||||
protected:
|
||||
void Ensure3DMatrix();
|
||||
|
||||
virtual ~DOMMatrix() {}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "mozilla/dom/WebKitCSSMatrix.h"
|
||||
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/WebKitCSSMatrixBinding.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsStyleTransformMatrix.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static const double sRadPerDegree = 2.0 * M_PI / 360.0;
|
||||
|
||||
bool
|
||||
WebKitCSSMatrix::FeatureEnabled(JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
return Preferences::GetBool("layout.css.DOMMatrix.enabled", false) &&
|
||||
Preferences::GetBool("layout.css.prefixes.webkit", false);
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> obj = new WebKitCSSMatrix(aGlobal.GetAsSupports());
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aTransformList, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> obj = new WebKitCSSMatrix(aGlobal.GetAsSupports());
|
||||
obj = obj->SetMatrixValue(aTransformList, aRv);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Constructor(const GlobalObject& aGlobal,
|
||||
const DOMMatrixReadOnly& aOther, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> obj = new WebKitCSSMatrix(aGlobal.GetAsSupports(),
|
||||
aOther);
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
WebKitCSSMatrix::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return WebKitCSSMatrixBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
WebKitCSSMatrix*
|
||||
WebKitCSSMatrix::SetMatrixValue(const nsAString& aTransformList,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// An empty string is a no-op.
|
||||
if (aTransformList.IsEmpty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
nsCSSValue value;
|
||||
nsCSSParser parser;
|
||||
bool parseSuccess = parser.ParseTransformProperty(aTransformList,
|
||||
true,
|
||||
value);
|
||||
if (!parseSuccess) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// A value of "none" results in a 2D identity matrix.
|
||||
if (value.GetUnit() == eCSSUnit_None) {
|
||||
mMatrix3D = nullptr;
|
||||
mMatrix2D = new gfx::Matrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
// A value other than a transform-list is a syntax error.
|
||||
if (value.GetUnit() != eCSSUnit_SharedList) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RuleNodeCacheConditions dummy;
|
||||
nsStyleTransformMatrix::TransformReferenceBox dummyBox;
|
||||
bool contains3dTransform = false;
|
||||
gfx::Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms(
|
||||
value.GetSharedListValue()->mHead,
|
||||
nullptr, nullptr, dummy, dummyBox,
|
||||
nsPresContext::AppUnitsPerCSSPixel(),
|
||||
&contains3dTransform);
|
||||
|
||||
if (!contains3dTransform) {
|
||||
mMatrix3D = nullptr;
|
||||
mMatrix2D = new gfx::Matrix();
|
||||
|
||||
SetA(transform._11);
|
||||
SetB(transform._12);
|
||||
SetC(transform._21);
|
||||
SetD(transform._22);
|
||||
SetE(transform._41);
|
||||
SetF(transform._42);
|
||||
} else {
|
||||
mMatrix3D = new gfx::Matrix4x4(transform);
|
||||
mMatrix2D = nullptr;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Multiply(const WebKitCSSMatrix& other) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->MultiplySelf(other);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Inverse(ErrorResult& aRv) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->InvertSelfThrow(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
WebKitCSSMatrix*
|
||||
WebKitCSSMatrix::InvertSelfThrow(ErrorResult& aRv)
|
||||
{
|
||||
if (mMatrix3D) {
|
||||
if (!mMatrix3D->Invert()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
} else if (!mMatrix2D->Invert()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Translate(double aTx,
|
||||
double aTy,
|
||||
double aTz) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->TranslateSelf(aTx, aTy, aTz);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Scale(double aScaleX,
|
||||
const Optional<double>& aScaleY,
|
||||
double aScaleZ) const
|
||||
{
|
||||
double scaleX = aScaleX;
|
||||
double scaleY = aScaleY.WasPassed() ? aScaleY.Value() : scaleX;
|
||||
double scaleZ = aScaleZ;
|
||||
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->ScaleNonUniformSelf(scaleX, scaleY, scaleZ);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::Rotate(double aRotX,
|
||||
const Optional<double>& aRotY,
|
||||
const Optional<double>& aRotZ) const
|
||||
{
|
||||
double rotX = aRotX;
|
||||
double rotY;
|
||||
double rotZ;
|
||||
|
||||
if (!aRotY.WasPassed() && !aRotZ.WasPassed()) {
|
||||
rotZ = rotX;
|
||||
rotX = 0;
|
||||
rotY = 0;
|
||||
} else {
|
||||
rotY = aRotY.WasPassed() ? aRotY.Value() : 0;
|
||||
rotZ = aRotZ.WasPassed() ? aRotZ.Value() : 0;
|
||||
}
|
||||
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->Rotate3dSelf(rotX, rotY, rotZ);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
WebKitCSSMatrix*
|
||||
WebKitCSSMatrix::Rotate3dSelf(double aRotX,
|
||||
double aRotY,
|
||||
double aRotZ)
|
||||
{
|
||||
if (aRotX != 0 || aRotY != 0) {
|
||||
Ensure3DMatrix();
|
||||
}
|
||||
|
||||
if (mMatrix3D) {
|
||||
if (fmod(aRotZ, 360) != 0) {
|
||||
mMatrix3D->RotateZ(aRotZ * sRadPerDegree);
|
||||
}
|
||||
if (fmod(aRotY, 360) != 0) {
|
||||
mMatrix3D->RotateY(aRotY * sRadPerDegree);
|
||||
}
|
||||
if (fmod(aRotX, 360) != 0) {
|
||||
mMatrix3D->RotateX(aRotX * sRadPerDegree);
|
||||
}
|
||||
} else if (fmod(aRotZ, 360) != 0) {
|
||||
mMatrix2D->PreRotate(aRotZ * sRadPerDegree);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::RotateAxisAngle(double aX,
|
||||
double aY,
|
||||
double aZ,
|
||||
double aAngle) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->RotateAxisAngleSelf(aX, aY, aZ, aAngle);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::SkewX(double aSx) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->SkewXSelf(aSx);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix>
|
||||
WebKitCSSMatrix::SkewY(double aSy) const
|
||||
{
|
||||
RefPtr<WebKitCSSMatrix> retval = new WebKitCSSMatrix(mParent, *this);
|
||||
retval->SkewYSelf(aSy);
|
||||
|
||||
return retval.forget();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@@ -0,0 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_webkitcssmatrix_h__
|
||||
#define mozilla_dom_webkitcssmatrix_h__
|
||||
|
||||
#include "mozilla/dom/DOMMatrix.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class WebKitCSSMatrix final : public DOMMatrix
|
||||
{
|
||||
public:
|
||||
explicit WebKitCSSMatrix(nsISupports* aParent)
|
||||
: DOMMatrix(aParent)
|
||||
{}
|
||||
|
||||
WebKitCSSMatrix(nsISupports* aParent, const DOMMatrixReadOnly& other)
|
||||
: DOMMatrix(aParent, other)
|
||||
{}
|
||||
|
||||
static bool FeatureEnabled(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
static already_AddRefed<WebKitCSSMatrix>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
static already_AddRefed<WebKitCSSMatrix>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aTransformList, ErrorResult& aRv);
|
||||
static already_AddRefed<WebKitCSSMatrix>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const DOMMatrixReadOnly& aOther, ErrorResult& aRv);
|
||||
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
WebKitCSSMatrix* SetMatrixValue(const nsAString& aTransformList,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<WebKitCSSMatrix> Multiply(const WebKitCSSMatrix& aOther) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Inverse(ErrorResult& aRv) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Translate(double aTx,
|
||||
double aTy,
|
||||
double aTz) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Scale(double aScaleX,
|
||||
const Optional<double>& aScaleY,
|
||||
double aScaleZ) const;
|
||||
already_AddRefed<WebKitCSSMatrix> Rotate(double aRotX,
|
||||
const Optional<double>& aRotY,
|
||||
const Optional<double>& aRotZ) const;
|
||||
already_AddRefed<WebKitCSSMatrix> RotateAxisAngle(double aX,
|
||||
double aY,
|
||||
double aZ,
|
||||
double aAngle) const;
|
||||
already_AddRefed<WebKitCSSMatrix> SkewX(double aSx) const;
|
||||
already_AddRefed<WebKitCSSMatrix> SkewY(double aSy) const;
|
||||
protected:
|
||||
WebKitCSSMatrix* Rotate3dSelf(double aRotX,
|
||||
double aRotY,
|
||||
double aRotZ);
|
||||
|
||||
WebKitCSSMatrix* InvertSelfThrow(ErrorResult& aRv);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_dom_webkitcssmatrix_h__ */
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "WindowNamedPropertiesHandler.h"
|
||||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsHTMLDocument.h"
|
||||
|
||||
@@ -212,6 +212,7 @@ EXPORTS.mozilla.dom += [
|
||||
'TreeWalker.h',
|
||||
'URL.h',
|
||||
'URLSearchParams.h',
|
||||
'WebKitCSSMatrix.h',
|
||||
'WebSocket.h',
|
||||
'WindowOrientationObserver.h',
|
||||
]
|
||||
@@ -359,6 +360,7 @@ UNIFIED_SOURCES += [
|
||||
'TreeWalker.cpp',
|
||||
'URL.cpp',
|
||||
'URLSearchParams.cpp',
|
||||
'WebKitCSSMatrix.cpp',
|
||||
'WebSocket.cpp',
|
||||
'WindowNamedPropertiesHandler.cpp',
|
||||
'WindowOrientationObserver.cpp',
|
||||
|
||||
@@ -1225,6 +1225,7 @@ GK_ATOM(tr, "tr")
|
||||
GK_ATOM(track, "track")
|
||||
GK_ATOM(trailing, "trailing")
|
||||
GK_ATOM(transform, "transform")
|
||||
GK_ATOM(transform_3d, "transform-3d")
|
||||
GK_ATOM(transformiix, "transformiix")
|
||||
GK_ATOM(translate, "translate")
|
||||
GK_ATOM(transparent, "transparent")
|
||||
@@ -2191,8 +2192,6 @@ GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional")
|
||||
GK_ATOM(images_in_menus, "images-in-menus")
|
||||
GK_ATOM(images_in_buttons, "images-in-buttons")
|
||||
GK_ATOM(overlay_scrollbars, "overlay-scrollbars")
|
||||
GK_ATOM(windows_accent_color_applies, "windows-accent-color-applies")
|
||||
GK_ATOM(windows_accent_color_is_dark, "windows-accent-color-is-dark")
|
||||
GK_ATOM(windows_default_theme, "windows-default-theme")
|
||||
GK_ATOM(mac_graphite_theme, "mac-graphite-theme")
|
||||
GK_ATOM(mac_lion_theme, "mac-lion-theme")
|
||||
@@ -2225,8 +2224,6 @@ GK_ATOM(_moz_scrollbar_thumb_proportional, "-moz-scrollbar-thumb-proportional")
|
||||
GK_ATOM(_moz_images_in_menus, "-moz-images-in-menus")
|
||||
GK_ATOM(_moz_images_in_buttons, "-moz-images-in-buttons")
|
||||
GK_ATOM(_moz_overlay_scrollbars, "-moz-overlay-scrollbars")
|
||||
GK_ATOM(_moz_windows_accent_color_applies, "-moz-windows-accent-color-applies")
|
||||
GK_ATOM(_moz_windows_accent_color_is_dark, "-moz-windows-accent-color-is-dark")
|
||||
GK_ATOM(_moz_windows_default_theme, "-moz-windows-default-theme")
|
||||
GK_ATOM(_moz_mac_graphite_theme, "-moz-mac-graphite-theme")
|
||||
GK_ATOM(_moz_mac_lion_theme, "-moz-mac-lion-theme")
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsTextFragment.h"
|
||||
#include "nsString.h"
|
||||
|
||||
@@ -122,3 +122,4 @@ skip-if = buildapp == 'b2g' # Bug 1184427 - no SSL certs on b2g
|
||||
skip-if = buildapp == 'b2g' # Bug 1184427 - no SSL certs on b2g
|
||||
[test_selectevents.html]
|
||||
skip-if = buildapp == 'b2g' || buildapp == 'mulet' # Mouse doesn't select in the same way on b2g
|
||||
[test_WebKitCSSMatrix.html]
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for WebKitCSSMatrix</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
function RoughCompareMatrix(dm1, dm2)
|
||||
{
|
||||
var m1 = dm1.toFloat32Array();
|
||||
var m2 = dm2.toFloat32Array();
|
||||
|
||||
if (m1.length != m2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const tolerance = 1 / 65535;
|
||||
for (var x = 0; x < m1.length; x++) {
|
||||
if (Math.abs(m1[x] - m2[x]) > tolerance) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function CompareMatrix(dm1, dm2)
|
||||
{
|
||||
var m1 = dm1.toFloat32Array();
|
||||
var m2 = dm2.toFloat32Array();
|
||||
|
||||
if (m1.length != m2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var x = 0; x < m1.length; x++) {
|
||||
if (m1[x] != m2[x]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
test(function() {
|
||||
var m = new WebKitCSSMatrix();
|
||||
|
||||
assert_equals(m.m11, 1, "m11 should be 1");
|
||||
assert_equals(m.m22, 1, "m22 should be 1");
|
||||
assert_equals(m.m33, 1, "m33 should be 1");
|
||||
assert_equals(m.m44, 1, "m44 should be 1");
|
||||
assert_equals(m.m12, 0, "m12 should be 0");
|
||||
assert_equals(m.m13, 0, "m13 should be 0");
|
||||
assert_equals(m.m14, 0, "m14 should be 0");
|
||||
assert_equals(m.m21, 0, "m21 should be 0");
|
||||
assert_equals(m.m23, 0, "m23 should be 0");
|
||||
assert_equals(m.m24, 0, "m24 should be 0");
|
||||
assert_equals(m.m31, 0, "m31 should be 0");
|
||||
assert_equals(m.m32, 0, "m32 should be 0");
|
||||
assert_equals(m.m34, 0, "m34 should be 0");
|
||||
assert_equals(m.m41, 0, "m41 should be 0");
|
||||
assert_equals(m.m42, 0, "m42 should be 0");
|
||||
assert_equals(m.m43, 0, "m43 should be 0");
|
||||
}, "Test constructor with no arguments.");
|
||||
|
||||
test(function() {
|
||||
var m = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
assert_equals(m.m11, 1, "m11 should be 1");
|
||||
assert_equals(m.m12, 2, "m12 should be 2");
|
||||
assert_equals(m.m21, 3, "m21 should be 3");
|
||||
assert_equals(m.m22, 4, "m22 should be 4");
|
||||
assert_equals(m.m41, 5, "m41 should be 5");
|
||||
assert_equals(m.m42, 6, "m42 should be 6");
|
||||
}, "Test constructor with transform list.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new WebKitCSSMatrix(m1);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1, m2), "Matrix should be equal.");
|
||||
}, "Test constructor with other matrix.");
|
||||
|
||||
test(function() {
|
||||
var m = new WebKitCSSMatrix();
|
||||
var mr = m.setMatrixValue("matrix(1,2,3,4,5,6)");
|
||||
|
||||
assert_equals(m.m11, 1, "m11 should be 1");
|
||||
assert_equals(m.m12, 2, "m12 should be 2");
|
||||
assert_equals(m.m21, 3, "m21 should be 3");
|
||||
assert_equals(m.m22, 4, "m22 should be 4");
|
||||
assert_equals(m.m41, 5, "m41 should be 5");
|
||||
assert_equals(m.m42, 6, "m42 should be 6");
|
||||
|
||||
assert_equals(m, mr, "Return value of setMatrixValue should be the same matrix.");
|
||||
}, "Test setMatrixValue.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(6,5,4,3,2,1)");
|
||||
var m4 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.multiply(m3);
|
||||
var m2r = m2.multiply(m3);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "multiply should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m4), "Multiply should not mutate original matrix.");
|
||||
}, "Test multiply.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.inverse();
|
||||
var m2r = m2.inverse();
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "inverse should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "inverse should not mutate original matrix.");
|
||||
}, "Test inverse.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.translate(2, 3, 4);
|
||||
var m2r = m2.translate(2, 3, 4);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "translate should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "translate should not mutate original matrix.");
|
||||
}, "Test inverse.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.scale(2);
|
||||
var m2r = m2.scaleNonUniform(2, 2, 1);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "scale should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "scale should not mutate original matrix.");
|
||||
}, "Test scale with 1 argument.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.scale(2, 3);
|
||||
var m2r = m2.scaleNonUniform(2, 3, 1);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "scale should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "scale should not mutate original matrix.");
|
||||
}, "Test scale with 2 arguments.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.scale(2, 3, 4);
|
||||
var m2r = m2.scaleNonUniform(2, 3, 4);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "scale should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "scale should not mutate original matrix.");
|
||||
}, "Test scale with 3 arguments.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.scale(undefined, 3, 4);
|
||||
var m2r = m2.scaleNonUniform(1, 3, 4);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "scale should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "scale should not mutate original matrix.");
|
||||
}, "Test scale with undefined scaleX argument.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.scale(2, undefined, 4);
|
||||
var m2r = m2.scaleNonUniform(2, 2, 4);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "scale should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "scale should not mutate original matrix.");
|
||||
}, "Test scale with undefined scaleY argument.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.scale(2, 3, undefined);
|
||||
var m2r = m2.scaleNonUniform(2, 3, 1);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "scale should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "scale should not mutate original matrix.");
|
||||
}, "Test scale with undefined scaleZ argument.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.rotate(2);
|
||||
var m2r = m2.rotateAxisAngle(0, 0, 1, 2); // Rotate around unit vector on z-axis.
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r));
|
||||
assert_true(CompareMatrix(m1, m3), "rotate should not mutate original matrix.");
|
||||
}, "Test rotate with 1 argument.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.rotate(2, 3);
|
||||
var m2r = m2.rotateAxisAngle(0, 1, 0, 3); // Rotate around unit vector on x-axis.
|
||||
m2r = m2r.rotateAxisAngle(1, 0, 0, 2); // Rotate around unit vector on y-axis.
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r));
|
||||
assert_true(CompareMatrix(m1, m3), "rotate should not mutate original matrix.");
|
||||
}, "Test rotate with 2 arguments.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.rotate(2, 3, 4);
|
||||
var m2r = m2.rotateAxisAngle(0, 0, 1, 4); // Rotate around unit vector on z-axis.
|
||||
m2r = m2r.rotateAxisAngle(0, 1, 0, 3); // Rotate around unit vector on y-axis.
|
||||
m2r = m2r.rotateAxisAngle(1, 0, 0, 2); // Rotate around unit vector on x-axis.
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r));
|
||||
assert_true(CompareMatrix(m1, m3), "rotate should not mutate original matrix.");
|
||||
}, "Test rotate with 3 arguments.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.rotate(2, undefined, undefined);
|
||||
var m2r = m2.rotateAxisAngle(0, 0, 1, 2); // Rotate around unit vector on z-axis.
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r));
|
||||
assert_true(CompareMatrix(m1, m3), "rotate should not mutate original matrix.");
|
||||
}, "Test rotate with rotY and rotZ as undefined.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.rotate(undefined, 3, 4);
|
||||
var m2r = m2.rotateAxisAngle(0, 0, 1, 4); // Rotate around unit vector on z-axis.
|
||||
m2r = m2r.rotateAxisAngle(0, 1, 0, 3); // Rotate around unit vector on y-axis.
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r));
|
||||
assert_true(CompareMatrix(m1, m3), "rotate should not mutate original matrix.");
|
||||
}, "Test rotate with rotX as undefined.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.rotateAxisAngle(2, 3, 4, 5);
|
||||
var m2r = m2.rotateAxisAngle(2, 3, 4, 5);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "rotateAxisAngle should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "rotateAxisAngle should not mutate original matrix.");
|
||||
}, "Test rotateAxisAngle.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.skewX(2);
|
||||
var m2r = m2.skewX(2);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "skewX should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "skewX should not mutate original matrix.");
|
||||
}, "Test skewX.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m2 = new DOMMatrix("matrix(1,2,3,4,5,6)");
|
||||
var m3 = new WebKitCSSMatrix("matrix(1,2,3,4,5,6)");
|
||||
|
||||
var m1r = m1.skewY(2);
|
||||
var m2r = m2.skewY(2);
|
||||
|
||||
assert_true(RoughCompareMatrix(m1r, m2r), "skewY should return the same result as DOMMatrixReadOnly.");
|
||||
assert_true(CompareMatrix(m1, m3), "skewY should not mutate original matrix.");
|
||||
}, "Test skewY.");
|
||||
|
||||
test(function() {
|
||||
var m = new WebKitCSSMatrix("matrix(1,0,0,0,0,0)");
|
||||
assert_throws("NotSupportedError", function() { m.inverse(); }, "Inverting an invertible matrix should throw.")
|
||||
}, "Test that inverting an invertible matrix throws.");
|
||||
|
||||
test(function() {
|
||||
var m1 = new WebKitCSSMatrix("translate(10px, 10px)");
|
||||
var m2 = new DOMMatrix();
|
||||
m2.translateSelf(10, 10);
|
||||
assert_true(RoughCompareMatrix(m1, m2), "translate in constructor should result in translated matrix");
|
||||
|
||||
assert_throws("SyntaxError", function() { new WebKitCSSMatrix("translate(10em, 10em)"); }, "Transform function may not contain relative units.")
|
||||
assert_throws("SyntaxError", function() { new WebKitCSSMatrix("translate(10%, 10%)"); }, "Transform function may not contain percentage.")
|
||||
}, "Test constructor with translate");
|
||||
|
||||
test(function() {
|
||||
assert_throws("SyntaxError", function() { new WebKitCSSMatrix("initial"); }, "initial is not a valid constructor argument.")
|
||||
assert_throws("SyntaxError", function() { new WebKitCSSMatrix("inherit"); }, "inherit is not a valid constructor arugment.")
|
||||
}, "Test invalid constructor arguments.");
|
||||
</script>
|
||||
@@ -1409,18 +1409,32 @@ var interfaceNamesInGlobalScope =
|
||||
"WebGLFramebuffer",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLProgram",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "WebGLQuery", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLRenderbuffer",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLRenderingContext",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "WebGLRenderingContext2", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "WebGLSampler", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLShader",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLShaderPrecisionFormat",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "WebGLSync", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLTexture",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "WebGLTransformFeedback", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebGLUniformLocation",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{name: "WebGLVertexArrayObject", nightly: true},
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebKitCSSMatrix",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"WebSocket",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://compat.spec.whatwg.org/#webkitcssmatrix-interface
|
||||
*/
|
||||
|
||||
[Constructor,
|
||||
Constructor(DOMString transformList),
|
||||
Constructor(WebKitCSSMatrix other),
|
||||
Exposed=Window,
|
||||
Func="mozilla::dom::WebKitCSSMatrix::FeatureEnabled"]
|
||||
interface WebKitCSSMatrix : DOMMatrix {
|
||||
// Mutable transform methods
|
||||
[Throws]
|
||||
WebKitCSSMatrix setMatrixValue(DOMString transformList);
|
||||
|
||||
// Immutable transform methods
|
||||
WebKitCSSMatrix multiply(WebKitCSSMatrix other);
|
||||
[Throws]
|
||||
WebKitCSSMatrix inverse();
|
||||
WebKitCSSMatrix translate(optional unrestricted double tx = 0,
|
||||
optional unrestricted double ty = 0,
|
||||
optional unrestricted double tz = 0);
|
||||
WebKitCSSMatrix scale(optional unrestricted double scaleX = 1,
|
||||
optional unrestricted double scaleY,
|
||||
optional unrestricted double scaleZ = 1);
|
||||
WebKitCSSMatrix rotate(optional unrestricted double rotX = 0,
|
||||
optional unrestricted double rotY,
|
||||
optional unrestricted double rotZ);
|
||||
WebKitCSSMatrix rotateAxisAngle(optional unrestricted double x = 0,
|
||||
optional unrestricted double y = 0,
|
||||
optional unrestricted double z = 0,
|
||||
optional unrestricted double angle = 0);
|
||||
WebKitCSSMatrix skewX(optional unrestricted double sx = 0);
|
||||
WebKitCSSMatrix skewY(optional unrestricted double sy = 0);
|
||||
};
|
||||
@@ -590,6 +590,7 @@ WEBIDL_FILES = [
|
||||
'WebComponents.webidl',
|
||||
'WebGL2RenderingContext.webidl',
|
||||
'WebGLRenderingContext.webidl',
|
||||
'WebKitCSSMatrix.webidl',
|
||||
'WebSocket.webidl',
|
||||
'WheelEvent.webidl',
|
||||
'WifiOptions.webidl',
|
||||
|
||||
@@ -152,6 +152,32 @@ BasicCompositor::CreateRenderTargetFromSource(const IntRect &aRect,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<CompositingRenderTarget>
|
||||
BasicCompositor::CreateRenderTargetForWindow(const IntRect& aRect, SurfaceInitMode aInit, BufferMode aBufferMode)
|
||||
{
|
||||
if (aBufferMode != BufferMode::BUFFER_NONE) {
|
||||
return CreateRenderTarget(aRect, aInit);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aRect.width != 0 && aRect.height != 0, "Trying to create a render target of invalid size");
|
||||
|
||||
if (aRect.width * aRect.height == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mDrawTarget);
|
||||
|
||||
// Adjust bounds rect to account for new origin at (0, 0).
|
||||
IntRect rect(0, 0, aRect.XMost(), aRect.YMost());
|
||||
RefPtr<BasicCompositingRenderTarget> rt = new BasicCompositingRenderTarget(mDrawTarget, rect);
|
||||
|
||||
if (aInit == INIT_MODE_CLEAR) {
|
||||
mDrawTarget->ClearRect(gfx::Rect(aRect));
|
||||
}
|
||||
|
||||
return rt.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DataTextureSource>
|
||||
BasicCompositor::CreateDataTextureSource(TextureFlags aFlags)
|
||||
{
|
||||
@@ -542,13 +568,14 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
*aRenderBoundsOut = Rect();
|
||||
}
|
||||
|
||||
BufferMode bufferMode = BufferMode::BUFFERED;
|
||||
if (mTarget) {
|
||||
// If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Use a dummy
|
||||
// placeholder so that CreateRenderTarget() works.
|
||||
mDrawTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
|
||||
} else {
|
||||
// StartRemoteDrawingInRegion can mutate mInvalidRegion.
|
||||
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
|
||||
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion, &bufferMode);
|
||||
if (!mDrawTarget) {
|
||||
return;
|
||||
}
|
||||
@@ -566,7 +593,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
// Setup an intermediate render target to buffer all compositing. We will
|
||||
// copy this into mDrawTarget (the widget), and/or mTarget in EndFrame()
|
||||
RefPtr<CompositingRenderTarget> target =
|
||||
CreateRenderTarget(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR);
|
||||
CreateRenderTargetForWindow(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR, bufferMode);
|
||||
if (!target) {
|
||||
if (!mTarget) {
|
||||
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
||||
@@ -577,8 +604,7 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||
|
||||
// We only allocate a surface sized to the invalidated region, so we need to
|
||||
// translate future coordinates.
|
||||
mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mInvalidRect.x,
|
||||
-mInvalidRect.y));
|
||||
mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mRenderTarget->GetOrigin()));
|
||||
|
||||
gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget,
|
||||
mInvalidRegion.ToUnknownRegion());
|
||||
@@ -616,22 +642,25 @@ BasicCompositor::EndFrame()
|
||||
// Pop aInvalidregion
|
||||
mRenderTarget->mDrawTarget->PopClip();
|
||||
|
||||
// Note: Most platforms require us to buffer drawing to the widget surface.
|
||||
// That's why we don't draw to mDrawTarget directly.
|
||||
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
|
||||
RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
|
||||
if (mTarget || mRenderTarget->mDrawTarget != mDrawTarget) {
|
||||
// Note: Most platforms require us to buffer drawing to the widget surface.
|
||||
// That's why we don't draw to mDrawTarget directly.
|
||||
RefPtr<SourceSurface> source = mRenderTarget->mDrawTarget->Snapshot();
|
||||
RefPtr<DrawTarget> dest(mTarget ? mTarget : mDrawTarget);
|
||||
|
||||
nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
|
||||
nsIntPoint offset = mTarget ? mTargetBounds.TopLeft() : nsIntPoint();
|
||||
|
||||
// The source DrawTarget is clipped to the invalidation region, so we have
|
||||
// to copy the individual rectangles in the region or else we'll draw blank
|
||||
// pixels.
|
||||
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const LayoutDeviceIntRect& r = iter.Get();
|
||||
dest->CopySurface(source,
|
||||
IntRect(r.x - mInvalidRect.x, r.y - mInvalidRect.y, r.width, r.height),
|
||||
IntPoint(r.x - offset.x, r.y - offset.y));
|
||||
// The source DrawTarget is clipped to the invalidation region, so we have
|
||||
// to copy the individual rectangles in the region or else we'll draw blank
|
||||
// pixels.
|
||||
for (auto iter = mInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
|
||||
const LayoutDeviceIntRect& r = iter.Get();
|
||||
dest->CopySurface(source,
|
||||
IntRect(r.x, r.y, r.width, r.height) - mRenderTarget->GetOrigin(),
|
||||
IntPoint(r.x, r.y) - offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mTarget) {
|
||||
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
||||
}
|
||||
|
||||
@@ -60,6 +60,11 @@ public:
|
||||
const CompositingRenderTarget *aSource,
|
||||
const gfx::IntPoint &aSourcePoint) override;
|
||||
|
||||
virtual already_AddRefed<CompositingRenderTarget>
|
||||
CreateRenderTargetForWindow(const gfx::IntRect& aRect,
|
||||
SurfaceInitMode aInit,
|
||||
BufferMode aBufferMode);
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
|
||||
|
||||
|
||||
+316
-180
@@ -13,40 +13,107 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// standard font descriptors that we construct the first time they're needed
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sDefaultFeaturesDescriptor = nullptr;
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sDisableLigaturesDescriptor = nullptr;
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sIndicFeaturesDescriptor = nullptr;
|
||||
CTFontDescriptorRef gfxCoreTextShaper::sIndicDisableLigaturesDescriptor = nullptr;
|
||||
|
||||
static CFStringRef sCTWritingDirectionAttributeName = nullptr;
|
||||
|
||||
// See CTStringAttributes.h
|
||||
enum {
|
||||
kMyCTWritingDirectionEmbedding = (0 << 1),
|
||||
kMyCTWritingDirectionOverride = (1 << 1)
|
||||
};
|
||||
|
||||
// Helper to create a CFDictionary with the right attributes for shaping our
|
||||
// text, including imposing the given directionality.
|
||||
// This will only be called if we're on 10.8 or later.
|
||||
CFDictionaryRef
|
||||
gfxCoreTextShaper::CreateAttrDict(bool aRightToLeft)
|
||||
{
|
||||
// Because we always shape unidirectional runs, and may have applied
|
||||
// directional overrides, we want to force a direction rather than
|
||||
// allowing CoreText to do its own unicode-based bidi processing.
|
||||
SInt16 dirOverride = kMyCTWritingDirectionOverride |
|
||||
(aRightToLeft ? kCTWritingDirectionRightToLeft
|
||||
: kCTWritingDirectionLeftToRight);
|
||||
CFNumberRef dirNumber =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type, &dirOverride);
|
||||
CFArrayRef dirArray =
|
||||
::CFArrayCreate(kCFAllocatorDefault,
|
||||
(const void **) &dirNumber, 1,
|
||||
&kCFTypeArrayCallBacks);
|
||||
::CFRelease(dirNumber);
|
||||
CFTypeRef attrs[] = { kCTFontAttributeName, sCTWritingDirectionAttributeName };
|
||||
CFTypeRef values[] = { mCTFont, dirArray };
|
||||
CFDictionaryRef attrDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
attrs, values, ArrayLength(attrs),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(dirArray);
|
||||
return attrDict;
|
||||
}
|
||||
|
||||
CFDictionaryRef
|
||||
gfxCoreTextShaper::CreateAttrDictWithoutDirection()
|
||||
{
|
||||
CFTypeRef attrs[] = { kCTFontAttributeName };
|
||||
CFTypeRef values[] = { mCTFont };
|
||||
CFDictionaryRef attrDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
attrs, values, ArrayLength(attrs),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
return attrDict;
|
||||
}
|
||||
|
||||
gfxCoreTextShaper::gfxCoreTextShaper(gfxMacFont *aFont)
|
||||
: gfxFontShaper(aFont)
|
||||
, mAttributesDictLTR(nullptr)
|
||||
, mAttributesDictRTL(nullptr)
|
||||
{
|
||||
// Create our CTFontRef
|
||||
mCTFont = ::CTFontCreateWithGraphicsFont(aFont->GetCGFontRef(),
|
||||
aFont->GetAdjustedSize(),
|
||||
nullptr,
|
||||
GetDefaultFeaturesDescriptor());
|
||||
static bool sInitialized = false;
|
||||
if (!sInitialized) {
|
||||
CFStringRef* pstr = (CFStringRef*)
|
||||
dlsym(RTLD_DEFAULT, "kCTWritingDirectionAttributeName");
|
||||
if (pstr) {
|
||||
sCTWritingDirectionAttributeName = *pstr;
|
||||
}
|
||||
sInitialized = true;
|
||||
}
|
||||
|
||||
// Set up the default attribute dictionary that we will need each time we create a CFAttributedString
|
||||
mAttributesDict = ::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void**) &kCTFontAttributeName,
|
||||
(const void**) &mCTFont,
|
||||
1, // count of attributes
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
// Create our CTFontRef
|
||||
mCTFont = CreateCTFontWithFeatures(aFont->GetAdjustedSize(),
|
||||
GetDefaultFeaturesDescriptor());
|
||||
}
|
||||
|
||||
gfxCoreTextShaper::~gfxCoreTextShaper()
|
||||
{
|
||||
if (mAttributesDict) {
|
||||
::CFRelease(mAttributesDict);
|
||||
if (mAttributesDictLTR) {
|
||||
::CFRelease(mAttributesDictLTR);
|
||||
}
|
||||
if (mAttributesDictRTL) {
|
||||
::CFRelease(mAttributesDictRTL);
|
||||
}
|
||||
if (mCTFont) {
|
||||
::CFRelease(mCTFont);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsBuggyIndicScript(int32_t aScript)
|
||||
{
|
||||
return aScript == MOZ_SCRIPT_BENGALI || aScript == MOZ_SCRIPT_KANNADA;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxCoreTextShaper::ShapeText(DrawTarget *aDrawTarget,
|
||||
const char16_t *aText,
|
||||
@@ -57,70 +124,112 @@ gfxCoreTextShaper::ShapeText(DrawTarget *aDrawTarget,
|
||||
gfxShapedText *aShapedText)
|
||||
{
|
||||
// Create a CFAttributedString with text and style info, so we can use CoreText to lay it out.
|
||||
|
||||
bool isRightToLeft = aShapedText->IsRightToLeft();
|
||||
const UniChar* text = reinterpret_cast<const UniChar*>(aText);
|
||||
uint32_t length = aLength;
|
||||
|
||||
// we need to bidi-wrap the text if the run is RTL,
|
||||
// or if it is an LTR run but may contain (overridden) RTL chars
|
||||
bool bidiWrap = isRightToLeft;
|
||||
if (!bidiWrap && !aShapedText->TextIs8Bit()) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (gfxFontUtils::PotentialRTLChar(aText[i])) {
|
||||
bidiWrap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's a possibility of any bidi, we wrap the text with direction overrides
|
||||
// to ensure neutrals or characters that were bidi-overridden in HTML behave properly.
|
||||
const UniChar beginLTR[] = { 0x202d, 0x20 };
|
||||
const UniChar beginRTL[] = { 0x202e, 0x20 };
|
||||
const UniChar endBidiWrap[] = { 0x20, 0x2e, 0x202c };
|
||||
|
||||
uint32_t startOffset;
|
||||
CFStringRef stringObj;
|
||||
if (bidiWrap) {
|
||||
startOffset = isRightToLeft ?
|
||||
mozilla::ArrayLength(beginRTL) : mozilla::ArrayLength(beginLTR);
|
||||
CFMutableStringRef mutableString =
|
||||
::CFStringCreateMutable(kCFAllocatorDefault,
|
||||
length + startOffset + mozilla::ArrayLength(endBidiWrap));
|
||||
::CFStringAppendCharacters(mutableString,
|
||||
isRightToLeft ? beginRTL : beginLTR,
|
||||
startOffset);
|
||||
::CFStringAppendCharacters(mutableString, reinterpret_cast<const UniChar*>(aText), length);
|
||||
::CFStringAppendCharacters(mutableString,
|
||||
endBidiWrap, mozilla::ArrayLength(endBidiWrap));
|
||||
stringObj = mutableString;
|
||||
} else {
|
||||
CFDictionaryRef attrObj;
|
||||
|
||||
if (sCTWritingDirectionAttributeName) {
|
||||
startOffset = 0;
|
||||
stringObj = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
|
||||
reinterpret_cast<const UniChar*>(aText),
|
||||
length, kCFAllocatorNull);
|
||||
text, length,
|
||||
kCFAllocatorNull);
|
||||
|
||||
// Get an attributes dictionary suitable for shaping text in the
|
||||
// current direction, creating it if necessary.
|
||||
attrObj = isRightToLeft ? mAttributesDictRTL : mAttributesDictLTR;
|
||||
if (!attrObj) {
|
||||
attrObj = CreateAttrDict(isRightToLeft);
|
||||
(isRightToLeft ? mAttributesDictRTL : mAttributesDictLTR) = attrObj;
|
||||
}
|
||||
} else {
|
||||
// OS is too old to support kCTWritingDirectionAttributeName:
|
||||
// we need to bidi-wrap the text if the run is RTL,
|
||||
// or if it is an LTR run but may contain (overridden) RTL chars
|
||||
bool bidiWrap = isRightToLeft;
|
||||
if (!bidiWrap && !aShapedText->TextIs8Bit()) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (gfxFontUtils::PotentialRTLChar(aText[i])) {
|
||||
bidiWrap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's a possibility of any bidi, we wrap the text with
|
||||
// direction overrides to ensure neutrals or characters that were
|
||||
// bidi-overridden in HTML behave properly.
|
||||
static const UniChar beginLTR[] = { 0x202d, 0x20 };
|
||||
static const UniChar beginRTL[] = { 0x202e, 0x20 };
|
||||
static const UniChar endBidiWrap[] = { 0x20, 0x2e, 0x202c };
|
||||
|
||||
if (bidiWrap) {
|
||||
startOffset = isRightToLeft ? ArrayLength(beginRTL)
|
||||
: ArrayLength(beginLTR);
|
||||
CFMutableStringRef mutableString =
|
||||
::CFStringCreateMutable(kCFAllocatorDefault,
|
||||
length + startOffset +
|
||||
ArrayLength(endBidiWrap));
|
||||
::CFStringAppendCharacters(mutableString,
|
||||
isRightToLeft ? beginRTL : beginLTR,
|
||||
startOffset);
|
||||
::CFStringAppendCharacters(mutableString, text, length);
|
||||
::CFStringAppendCharacters(mutableString, endBidiWrap,
|
||||
ArrayLength(endBidiWrap));
|
||||
stringObj = mutableString;
|
||||
} else {
|
||||
startOffset = 0;
|
||||
stringObj =
|
||||
::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
|
||||
text, length,
|
||||
kCFAllocatorNull);
|
||||
}
|
||||
|
||||
// Get an attributes dictionary suitable for shaping text,
|
||||
// creating it if necessary. (This dict is not LTR-specific,
|
||||
// but we use that field to store it anyway.)
|
||||
if (!mAttributesDictLTR) {
|
||||
mAttributesDictLTR = CreateAttrDictWithoutDirection();
|
||||
}
|
||||
attrObj = mAttributesDictLTR;
|
||||
}
|
||||
|
||||
CFDictionaryRef attrObj;
|
||||
if (aShapedText->DisableLigatures()) {
|
||||
// For letterspacing (or maybe other situations) we need to make a copy of the CTFont
|
||||
// with the ligature feature disabled
|
||||
CTFontRef ctFont =
|
||||
CreateCTFontWithDisabledLigatures(::CTFontGetSize(mCTFont));
|
||||
CTFontRef tempCTFont = nullptr;
|
||||
if (IsBuggyIndicScript(aScript)) {
|
||||
// To work around buggy Indic AAT fonts shipped with OS X,
|
||||
// we re-enable the Line Initial Smart Swashes feature that is needed
|
||||
// for "split vowels" to work in at least Bengali and Kannada fonts.
|
||||
// Affected fonts include Bangla MN, Bangla Sangam MN, Kannada MN,
|
||||
// Kannada Sangam MN. See bugs 686225, 728557, 953231, 1145515.
|
||||
tempCTFont =
|
||||
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
|
||||
aShapedText->DisableLigatures()
|
||||
? GetIndicDisableLigaturesDescriptor()
|
||||
: GetIndicFeaturesDescriptor());
|
||||
} else if (aShapedText->DisableLigatures()) {
|
||||
// For letterspacing (or maybe other situations) we need to make
|
||||
// a copy of the CTFont with the ligature feature disabled.
|
||||
tempCTFont =
|
||||
CreateCTFontWithFeatures(::CTFontGetSize(mCTFont),
|
||||
GetDisableLigaturesDescriptor());
|
||||
}
|
||||
|
||||
attrObj =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void**) &kCTFontAttributeName,
|
||||
(const void**) &ctFont,
|
||||
1, // count of attributes
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
// Having created the dict, we're finished with our ligature-disabled CTFontRef
|
||||
::CFRelease(ctFont);
|
||||
} else {
|
||||
attrObj = mAttributesDict;
|
||||
::CFRetain(attrObj);
|
||||
// For the disabled-ligature or buggy-indic-font case, we need to replace
|
||||
// the standard CTFont in the attribute dictionary with a tweaked version.
|
||||
CFMutableDictionaryRef mutableAttr = nullptr;
|
||||
if (tempCTFont) {
|
||||
mutableAttr = ::CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 2,
|
||||
attrObj);
|
||||
::CFDictionaryReplaceValue(mutableAttr,
|
||||
kCTFontAttributeName, tempCTFont);
|
||||
// Having created the dict, we're finished with our temporary
|
||||
// Indic and/or ligature-disabled CTFontRef.
|
||||
::CFRelease(tempCTFont);
|
||||
attrObj = mutableAttr;
|
||||
}
|
||||
|
||||
// Now we can create an attributed string
|
||||
@@ -143,34 +252,47 @@ gfxCoreTextShaper::ShapeText(DrawTarget *aDrawTarget,
|
||||
for (uint32_t runIndex = 0; runIndex < numRuns; runIndex++) {
|
||||
CTRunRef aCTRun =
|
||||
(CTRunRef)::CFArrayGetValueAtIndex(glyphRuns, runIndex);
|
||||
// If the range is purely within bidi-wrapping text, ignore it.
|
||||
CFRange range = ::CTRunGetStringRange(aCTRun);
|
||||
if (uint32_t(range.location + range.length) <= startOffset ||
|
||||
range.location - startOffset >= aLength) {
|
||||
continue;
|
||||
}
|
||||
CFDictionaryRef runAttr = ::CTRunGetAttributes(aCTRun);
|
||||
if (runAttr != attrObj) {
|
||||
// If Core Text manufactured a new dictionary, this may indicate
|
||||
// unexpected font substitution. In that case, we fail (and fall
|
||||
// back to harfbuzz shaping)...
|
||||
const void* font1 = ::CFDictionaryGetValue(attrObj, kCTFontAttributeName);
|
||||
const void* font2 = ::CFDictionaryGetValue(runAttr, kCTFontAttributeName);
|
||||
const void* font1 =
|
||||
::CFDictionaryGetValue(attrObj, kCTFontAttributeName);
|
||||
const void* font2 =
|
||||
::CFDictionaryGetValue(runAttr, kCTFontAttributeName);
|
||||
if (font1 != font2) {
|
||||
// ...except that if the fallback was only for a variation
|
||||
// selector that is otherwise unsupported, we just ignore it.
|
||||
CFRange range = ::CTRunGetStringRange(aCTRun);
|
||||
if (range.length == 1 &&
|
||||
gfxFontUtils::IsVarSelector(aText[range.location -
|
||||
startOffset])) {
|
||||
continue;
|
||||
// selector or join control that is otherwise unsupported,
|
||||
// we just ignore it.
|
||||
if (range.length == 1) {
|
||||
char16_t ch = aText[range.location - startOffset];
|
||||
if (gfxFontUtils::IsJoinControl(ch) ||
|
||||
gfxFontUtils::IsVarSelector(ch)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_WARNING("unexpected font fallback in Core Text");
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (SetGlyphsFromRun(aShapedText, aOffset, aLength, aCTRun, startOffset) != NS_OK) {
|
||||
if (SetGlyphsFromRun(aShapedText, aOffset, aLength, aCTRun,
|
||||
startOffset) != NS_OK) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
::CFRelease(attrObj);
|
||||
if (mutableAttr) {
|
||||
::CFRelease(mutableAttr);
|
||||
}
|
||||
::CFRelease(line);
|
||||
|
||||
return success;
|
||||
@@ -515,64 +637,57 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
|
||||
|
||||
#undef SMALL_GLYPH_RUN
|
||||
|
||||
// Construct the font attribute descriptor that we'll apply by default when creating a CTFontRef.
|
||||
// This will turn off line-edge swashes by default, because we don't know the actual line breaks
|
||||
// when doing glyph shaping.
|
||||
void
|
||||
gfxCoreTextShaper::CreateDefaultFeaturesDescriptor()
|
||||
// Construct the font attribute descriptor that we'll apply by default when
|
||||
// creating a CTFontRef. This will turn off line-edge swashes by default,
|
||||
// because we don't know the actual line breaks when doing glyph shaping.
|
||||
|
||||
// We also cache feature descriptors for shaping with disabled ligatures, and
|
||||
// for buggy Indic AAT font workarounds, created on an as-needed basis.
|
||||
|
||||
#define MAX_FEATURES 3 // max used by any of our Get*Descriptor functions
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::CreateFontFeaturesDescriptor(
|
||||
const std::pair<SInt16,SInt16> aFeatures[],
|
||||
size_t aCount)
|
||||
{
|
||||
if (sDefaultFeaturesDescriptor != nullptr) {
|
||||
return;
|
||||
MOZ_ASSERT(aCount <= MAX_FEATURES);
|
||||
|
||||
CFDictionaryRef featureSettings[MAX_FEATURES];
|
||||
|
||||
for (size_t i = 0; i < aCount; i++) {
|
||||
CFNumberRef type = ::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&aFeatures[i].first);
|
||||
CFNumberRef selector = ::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&aFeatures[i].second);
|
||||
|
||||
CFTypeRef keys[] = { kCTFontFeatureTypeIdentifierKey,
|
||||
kCTFontFeatureSelectorIdentifierKey };
|
||||
CFTypeRef values[] = { type, selector };
|
||||
featureSettings[i] =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) keys,
|
||||
(const void **) values,
|
||||
ArrayLength(keys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
|
||||
::CFRelease(selector);
|
||||
::CFRelease(type);
|
||||
}
|
||||
|
||||
SInt16 val = kSmartSwashType;
|
||||
CFNumberRef swashesType =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&val);
|
||||
val = kLineInitialSwashesOffSelector;
|
||||
CFNumberRef lineInitialsOffSelector =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&val);
|
||||
|
||||
CFTypeRef keys[] = { kCTFontFeatureTypeIdentifierKey,
|
||||
kCTFontFeatureSelectorIdentifierKey };
|
||||
CFTypeRef values[] = { swashesType,
|
||||
lineInitialsOffSelector };
|
||||
CFDictionaryRef featureSettings[2];
|
||||
featureSettings[0] =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) keys,
|
||||
(const void **) values,
|
||||
ArrayLength(keys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(lineInitialsOffSelector);
|
||||
|
||||
val = kLineFinalSwashesOffSelector;
|
||||
CFNumberRef lineFinalsOffSelector =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&val);
|
||||
values[1] = lineFinalsOffSelector;
|
||||
featureSettings[1] =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) keys,
|
||||
(const void **) values,
|
||||
ArrayLength(keys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(lineFinalsOffSelector);
|
||||
::CFRelease(swashesType);
|
||||
|
||||
CFArrayRef featuresArray =
|
||||
::CFArrayCreate(kCFAllocatorDefault,
|
||||
(const void **) featureSettings,
|
||||
ArrayLength(featureSettings),
|
||||
aCount, // not ArrayLength(featureSettings), as we
|
||||
// may not have used all the allocated slots
|
||||
&kCFTypeArrayCallBacks);
|
||||
::CFRelease(featureSettings[0]);
|
||||
::CFRelease(featureSettings[1]);
|
||||
|
||||
for (size_t i = 0; i < aCount; i++) {
|
||||
::CFRelease(featureSettings[i]);
|
||||
}
|
||||
|
||||
const CFTypeRef attrKeys[] = { kCTFontFeatureSettingsAttribute };
|
||||
const CFTypeRef attrValues[] = { featuresArray };
|
||||
@@ -585,76 +700,97 @@ gfxCoreTextShaper::CreateDefaultFeaturesDescriptor()
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(featuresArray);
|
||||
|
||||
sDefaultFeaturesDescriptor =
|
||||
CTFontDescriptorRef descriptor =
|
||||
::CTFontDescriptorCreateWithAttributes(attributesDict);
|
||||
::CFRelease(attributesDict);
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
// Create a CTFontRef, with the Common Ligatures feature disabled
|
||||
CTFontRef
|
||||
gfxCoreTextShaper::CreateCTFontWithDisabledLigatures(CGFloat aSize)
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetDefaultFeaturesDescriptor()
|
||||
{
|
||||
if (sDefaultFeaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kDefaultFeatures[] = {
|
||||
{ kSmartSwashType, kLineInitialSwashesOffSelector },
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector }
|
||||
};
|
||||
sDefaultFeaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kDefaultFeatures,
|
||||
ArrayLength(kDefaultFeatures));
|
||||
}
|
||||
return sDefaultFeaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetDisableLigaturesDescriptor()
|
||||
{
|
||||
if (sDisableLigaturesDescriptor == nullptr) {
|
||||
// initialize cached descriptor to turn off the Common Ligatures feature
|
||||
SInt16 val = kLigaturesType;
|
||||
CFNumberRef ligaturesType =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&val);
|
||||
val = kCommonLigaturesOffSelector;
|
||||
CFNumberRef commonLigaturesOffSelector =
|
||||
::CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberSInt16Type,
|
||||
&val);
|
||||
|
||||
const CFTypeRef keys[] = { kCTFontFeatureTypeIdentifierKey,
|
||||
kCTFontFeatureSelectorIdentifierKey };
|
||||
const CFTypeRef values[] = { ligaturesType,
|
||||
commonLigaturesOffSelector };
|
||||
CFDictionaryRef featureSettingDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) keys,
|
||||
(const void **) values,
|
||||
ArrayLength(keys),
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(ligaturesType);
|
||||
::CFRelease(commonLigaturesOffSelector);
|
||||
|
||||
CFArrayRef featuresArray =
|
||||
::CFArrayCreate(kCFAllocatorDefault,
|
||||
(const void **) &featureSettingDict,
|
||||
1,
|
||||
&kCFTypeArrayCallBacks);
|
||||
::CFRelease(featureSettingDict);
|
||||
|
||||
CFDictionaryRef attributesDict =
|
||||
::CFDictionaryCreate(kCFAllocatorDefault,
|
||||
(const void **) &kCTFontFeatureSettingsAttribute,
|
||||
(const void **) &featuresArray,
|
||||
1, // count of keys & values
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
::CFRelease(featuresArray);
|
||||
|
||||
const std::pair<SInt16,SInt16> kDisableLigatures[] = {
|
||||
{ kSmartSwashType, kLineInitialSwashesOffSelector },
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector },
|
||||
{ kLigaturesType, kCommonLigaturesOffSelector }
|
||||
};
|
||||
sDisableLigaturesDescriptor =
|
||||
::CTFontDescriptorCreateCopyWithAttributes(GetDefaultFeaturesDescriptor(),
|
||||
attributesDict);
|
||||
::CFRelease(attributesDict);
|
||||
CreateFontFeaturesDescriptor(kDisableLigatures,
|
||||
ArrayLength(kDisableLigatures));
|
||||
}
|
||||
return sDisableLigaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetIndicFeaturesDescriptor()
|
||||
{
|
||||
if (sIndicFeaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kIndicFeatures[] = {
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector }
|
||||
};
|
||||
sIndicFeaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kIndicFeatures,
|
||||
ArrayLength(kIndicFeatures));
|
||||
}
|
||||
return sIndicFeaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontDescriptorRef
|
||||
gfxCoreTextShaper::GetIndicDisableLigaturesDescriptor()
|
||||
{
|
||||
if (sIndicDisableLigaturesDescriptor == nullptr) {
|
||||
const std::pair<SInt16,SInt16> kIndicDisableLigatures[] = {
|
||||
{ kSmartSwashType, kLineFinalSwashesOffSelector },
|
||||
{ kLigaturesType, kCommonLigaturesOffSelector }
|
||||
};
|
||||
sIndicDisableLigaturesDescriptor =
|
||||
CreateFontFeaturesDescriptor(kIndicDisableLigatures,
|
||||
ArrayLength(kIndicDisableLigatures));
|
||||
}
|
||||
return sIndicDisableLigaturesDescriptor;
|
||||
}
|
||||
|
||||
CTFontRef
|
||||
gfxCoreTextShaper::CreateCTFontWithFeatures(CGFloat aSize,
|
||||
CTFontDescriptorRef aDescriptor)
|
||||
{
|
||||
gfxMacFont *f = static_cast<gfxMacFont*>(mFont);
|
||||
return ::CTFontCreateWithGraphicsFont(f->GetCGFontRef(), aSize, nullptr,
|
||||
sDisableLigaturesDescriptor);
|
||||
aDescriptor);
|
||||
}
|
||||
|
||||
void
|
||||
gfxCoreTextShaper::Shutdown() // [static]
|
||||
{
|
||||
if (sIndicDisableLigaturesDescriptor != nullptr) {
|
||||
::CFRelease(sIndicDisableLigaturesDescriptor);
|
||||
sIndicDisableLigaturesDescriptor = nullptr;
|
||||
}
|
||||
if (sIndicFeaturesDescriptor != nullptr) {
|
||||
::CFRelease(sIndicFeaturesDescriptor);
|
||||
sIndicFeaturesDescriptor = nullptr;
|
||||
}
|
||||
if (sDisableLigaturesDescriptor != nullptr) {
|
||||
::CFRelease(sDisableLigaturesDescriptor);
|
||||
sDisableLigaturesDescriptor = nullptr;
|
||||
}
|
||||
}
|
||||
if (sDefaultFeaturesDescriptor != nullptr) {
|
||||
::CFRelease(sDefaultFeaturesDescriptor);
|
||||
sDefaultFeaturesDescriptor = nullptr;
|
||||
|
||||
@@ -31,7 +31,10 @@ public:
|
||||
|
||||
protected:
|
||||
CTFontRef mCTFont;
|
||||
CFDictionaryRef mAttributesDict;
|
||||
|
||||
// attributes for shaping text with LTR or RTL directionality
|
||||
CFDictionaryRef mAttributesDictLTR;
|
||||
CFDictionaryRef mAttributesDictRTL;
|
||||
|
||||
nsresult SetGlyphsFromRun(gfxShapedText *aShapedText,
|
||||
uint32_t aOffset,
|
||||
@@ -39,22 +42,30 @@ protected:
|
||||
CTRunRef aCTRun,
|
||||
int32_t aStringOffset);
|
||||
|
||||
CTFontRef CreateCTFontWithDisabledLigatures(CGFloat aSize);
|
||||
CTFontRef CreateCTFontWithFeatures(CGFloat aSize,
|
||||
CTFontDescriptorRef aDescriptor);
|
||||
|
||||
static void CreateDefaultFeaturesDescriptor();
|
||||
CFDictionaryRef CreateAttrDict(bool aRightToLeft);
|
||||
CFDictionaryRef CreateAttrDictWithoutDirection();
|
||||
|
||||
static CTFontDescriptorRef GetDefaultFeaturesDescriptor() {
|
||||
if (sDefaultFeaturesDescriptor == nullptr) {
|
||||
CreateDefaultFeaturesDescriptor();
|
||||
}
|
||||
return sDefaultFeaturesDescriptor;
|
||||
}
|
||||
static CTFontDescriptorRef
|
||||
CreateFontFeaturesDescriptor(const std::pair<SInt16,SInt16> aFeatures[],
|
||||
size_t aCount);
|
||||
|
||||
static CTFontDescriptorRef GetDefaultFeaturesDescriptor();
|
||||
static CTFontDescriptorRef GetDisableLigaturesDescriptor();
|
||||
static CTFontDescriptorRef GetIndicFeaturesDescriptor();
|
||||
static CTFontDescriptorRef GetIndicDisableLigaturesDescriptor();
|
||||
|
||||
// cached font descriptor, created the first time it's needed
|
||||
static CTFontDescriptorRef sDefaultFeaturesDescriptor;
|
||||
|
||||
// cached descriptor for adding disable-ligatures setting to a font
|
||||
static CTFontDescriptorRef sDisableLigaturesDescriptor;
|
||||
|
||||
// feature descriptors for buggy Indic AAT font workaround
|
||||
static CTFontDescriptorRef sIndicFeaturesDescriptor;
|
||||
static CTFontDescriptorRef sIndicDisableLigaturesDescriptor;
|
||||
};
|
||||
|
||||
#endif /* GFX_CORETEXTSHAPER_H */
|
||||
|
||||
@@ -918,22 +918,22 @@ gfxGDIFontList::GetDefaultFont(const gfxFontStyle* aStyle)
|
||||
gfxFontFamily *ff = nullptr;
|
||||
|
||||
// this really shouldn't fail to find a font....
|
||||
HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
|
||||
LOGFONTW logFont;
|
||||
if (hGDI && ::GetObjectW(hGDI, sizeof(logFont), &logFont)) {
|
||||
ff = FindFamily(nsDependentString(logFont.lfFaceName));
|
||||
if (ff) {
|
||||
return ff;
|
||||
}
|
||||
}
|
||||
|
||||
// ...but just in case, try another approach as well
|
||||
NONCLIENTMETRICSW ncm;
|
||||
ncm.cbSize = sizeof(ncm);
|
||||
BOOL status = ::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
|
||||
sizeof(ncm), &ncm, 0);
|
||||
if (status) {
|
||||
ff = FindFamily(nsDependentString(ncm.lfMessageFont.lfFaceName));
|
||||
if (ff) {
|
||||
return ff;
|
||||
}
|
||||
}
|
||||
|
||||
// ...but just in case, try another (long-deprecated) approach as well
|
||||
HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
|
||||
LOGFONTW logFont;
|
||||
if (hGDI && ::GetObjectW(hGDI, sizeof(logFont), &logFont)) {
|
||||
ff = FindFamily(nsDependentString(logFont.lfFaceName));
|
||||
}
|
||||
|
||||
return ff;
|
||||
|
||||
@@ -263,13 +263,15 @@ IncrementScaleRestyleCountIfNeeded(nsIFrame* aFrame, LayerActivity* aActivity)
|
||||
// Compute the new scale due to the CSS transform property.
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
RuleNodeCacheConditions dummy;
|
||||
bool dummyBool;
|
||||
nsStyleTransformMatrix::TransformReferenceBox refBox(aFrame);
|
||||
Matrix4x4 transform =
|
||||
nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead,
|
||||
aFrame->StyleContext(),
|
||||
presContext,
|
||||
dummy, refBox,
|
||||
presContext->AppUnitsPerCSSPixel());
|
||||
presContext->AppUnitsPerCSSPixel(),
|
||||
&dummyBool);
|
||||
Matrix transform2D;
|
||||
if (!transform.Is2D(&transform2D)) {
|
||||
// We don't attempt to handle 3D transforms; just assume the scale changed.
|
||||
|
||||
@@ -326,12 +326,14 @@ static void AddTransformFunctions(nsCSSValueList* aList,
|
||||
}
|
||||
case eCSSKeyword_interpolatematrix:
|
||||
{
|
||||
bool dummy;
|
||||
Matrix4x4 matrix;
|
||||
nsStyleTransformMatrix::ProcessInterpolateMatrix(matrix, array,
|
||||
aContext,
|
||||
aPresContext,
|
||||
conditions,
|
||||
aRefBox);
|
||||
aRefBox,
|
||||
&dummy);
|
||||
aFunctions.AppendElement(TransformMatrix(matrix));
|
||||
break;
|
||||
}
|
||||
@@ -1936,7 +1938,6 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
point = aRect.Center();
|
||||
}
|
||||
temp.AppendElement(FramesWithDepth(transform->GetHitDepthAtPoint(aBuilder, point)));
|
||||
printf("depth %p %f\n", transform, transform->GetHitDepthAtPoint(aBuilder, point));
|
||||
writeFrames = &temp[temp.Length() - 1].mFrames;
|
||||
}
|
||||
} else {
|
||||
@@ -5418,6 +5419,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
|
||||
|
||||
/* Get the matrix, then change its basis to factor in the origin. */
|
||||
RuleNodeCacheConditions dummy;
|
||||
bool dummyBool;
|
||||
Matrix4x4 result;
|
||||
// Call IsSVGTransformed() regardless of the value of
|
||||
// disp->mSpecifiedTransform, since we still need any transformFromSVGParent.
|
||||
@@ -5431,7 +5433,8 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
|
||||
result = nsStyleTransformMatrix::ReadTransforms(aProperties.mTransformList->mHead,
|
||||
frame ? frame->StyleContext() : nullptr,
|
||||
frame ? frame->PresContext() : nullptr,
|
||||
dummy, refBox, aAppUnitsPerPixel);
|
||||
dummy, refBox, aAppUnitsPerPixel,
|
||||
&dummyBool);
|
||||
} else if (hasSVGTransforms) {
|
||||
// Correct the translation components for zoom:
|
||||
float pixelsPerCSSPx = frame->PresContext()->AppUnitsPerCSSPixel() /
|
||||
|
||||
@@ -557,9 +557,9 @@ skip-if(B2G||Mulet) == 363858-1.html 363858-1-ref.html # Initial mulet triage: p
|
||||
skip-if(B2G||Mulet) == 363858-2.html 363858-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == 363858-3.html 363858-3-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == 363858-4.html 363858-4-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy-if(OSX>=1008,45,2) == 363858-5a.html 363858-5-ref.html
|
||||
fuzzy-if(OSX>=1008,45,2) fuzzy-if(winWidget,114,1) == 363858-5a.html 363858-5-ref.html
|
||||
== 363858-5b.html 363858-5-ref.html
|
||||
fuzzy-if(OSX>=1008,45,2) == 363858-6a.html 363858-6-ref.html
|
||||
fuzzy-if(OSX>=1008,45,2) fuzzy-if(winWidget,114,1) == 363858-6a.html 363858-6-ref.html
|
||||
== 363858-6b.html 363858-6-ref.html
|
||||
== 363874.html 363874-ref.html
|
||||
== 363874-max-width.html 363874-max-width-ref.html
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
== placeholder-3.html placeholder-overridden-ref.html
|
||||
== placeholder-4.html placeholder-overridden-ref.html
|
||||
== placeholder-5.html placeholder-visible-ref.html
|
||||
fuzzy-if(winWidget,160,7) fuzzy-if(asyncPan&&!layersGPUAccelerated,146,299) == placeholder-6.html placeholder-overflow-ref.html
|
||||
fuzzy-if(winWidget,160,10) fuzzy-if(Android,1,1) fuzzy-if(asyncPan&&!layersGPUAccelerated,146,299) == placeholder-6.html placeholder-overflow-ref.html
|
||||
skip-if(B2G||Mulet) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
# needs-focus == placeholder-7.html placeholder-focus-ref.html
|
||||
# needs-focus == placeholder-8.html placeholder-focus-ref.html
|
||||
|
||||
@@ -165,6 +165,7 @@ fails-if(cocoaWidget||Android||B2G) HTTP(..) == arabic-fallback-2.html arabic-fa
|
||||
fails-if(cocoaWidget||Android||B2G) HTTP(..) == arabic-fallback-3.html arabic-fallback-3-ref.html
|
||||
fails-if(!cocoaWidget&&!Android&&!B2G) HTTP(..) != arabic-fallback-4.html arabic-fallback-4-notref.html
|
||||
== arabic-marks-1.html arabic-marks-1-ref.html
|
||||
fails-if(OSX<1008) == arabic-final-ligature-spacing.html arabic-final-ligature-spacing-ref.html
|
||||
# harfbuzz fallback mark stacking in the absence of GPOS:
|
||||
HTTP(..) != fallback-mark-stacking-1.html fallback-mark-stacking-1-notref.html
|
||||
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/* A global table that tracks images referenced by CSS variables. */
|
||||
|
||||
#ifndef mozilla_CSSVariableImageTable_h
|
||||
#define mozilla_CSSVariableImageTable_h
|
||||
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsCSSProperty.h"
|
||||
#include "nsCSSValue.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
/**
|
||||
* CSSVariableImageTable maintains a global mapping
|
||||
* (nsStyleContext, nsCSSProperty) -> nsTArray<ImageValue>
|
||||
* which allows us to track the relationship between CSS property values
|
||||
* involving variables and any images they may reference.
|
||||
*
|
||||
* When properties like background-image contain a normal url(), the
|
||||
* Declaration's data block will hold a reference to the ImageValue. When a
|
||||
* token stream is used, the Declaration only holds on to an
|
||||
* nsCSSValueTokenStream object, and the ImageValue would only exist for the
|
||||
* duration of nsRuleNode::WalkRuleTree, in the AutoCSSValueArray. So instead
|
||||
* when we re-parse a token stream and get an ImageValue, we record it in the
|
||||
* CSSVariableImageTable to keep the ImageValue alive. Such ImageValues are
|
||||
* eventually freed the next time the token stream is re-parsed, or when the
|
||||
* associated style context is destroyed.
|
||||
*
|
||||
* To add ImageValues to the CSSVariableImageTable, callers should pass a lambda
|
||||
* to CSSVariableImageTable::ReplaceAll() that calls
|
||||
* CSSVariableImageTable::Add() for each ImageValue that needs to be added to
|
||||
* the table. When callers are sure that the ImageValues for a given
|
||||
* nsStyleContext won't be needed anymore, they can call
|
||||
* CSSVariableImageTable::RemoveAll() to release them.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace CSSVariableImageTable {
|
||||
|
||||
namespace detail {
|
||||
|
||||
typedef nsTArray<RefPtr<css::ImageValue>> ImageValueArray;
|
||||
typedef nsClassHashtable<nsGenericHashKey<nsCSSProperty>, ImageValueArray>
|
||||
PerPropertyImageHashtable;
|
||||
typedef nsClassHashtable<nsPtrHashKey<nsStyleContext>, PerPropertyImageHashtable>
|
||||
CSSVariableImageHashtable;
|
||||
|
||||
inline CSSVariableImageHashtable& GetTable()
|
||||
{
|
||||
static CSSVariableImageHashtable imageTable;
|
||||
return imageTable;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline bool& IsReplacing()
|
||||
{
|
||||
static bool isReplacing = false;
|
||||
return isReplacing;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* ReplaceAll() allows callers to replace the ImageValues associated with a
|
||||
* (nsStyleContext, nsCSSProperty) pair. The memory used by the previous list of
|
||||
* ImageValues is automatically released.
|
||||
*
|
||||
* @param aContext The style context the ImageValues are associated with.
|
||||
* @param aProp The CSS property the ImageValues are associated with.
|
||||
* @param aFunc A lambda that calls CSSVariableImageTable::Add() to add new
|
||||
* ImageValues which will replace the old ones.
|
||||
*/
|
||||
template <typename Lambda>
|
||||
inline void ReplaceAll(nsStyleContext* aContext,
|
||||
nsCSSProperty aProp,
|
||||
Lambda aFunc)
|
||||
{
|
||||
MOZ_ASSERT(aContext);
|
||||
|
||||
auto& imageTable = detail::GetTable();
|
||||
|
||||
// Clear the existing image array, if any, for this property.
|
||||
{
|
||||
auto* perPropertyImageTable = imageTable.Get(aContext);
|
||||
auto* imageList = perPropertyImageTable ? perPropertyImageTable->Get(aProp)
|
||||
: nullptr;
|
||||
if (imageList) {
|
||||
imageList->ClearAndRetainStorage();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!detail::IsReplacing());
|
||||
detail::IsReplacing() = true;
|
||||
#endif
|
||||
|
||||
aFunc();
|
||||
|
||||
#ifdef DEBUG
|
||||
detail::IsReplacing() = false;
|
||||
#endif
|
||||
|
||||
// Clean up.
|
||||
auto* perPropertyImageTable = imageTable.Get(aContext);
|
||||
auto* imageList = perPropertyImageTable ? perPropertyImageTable->Get(aProp)
|
||||
: nullptr;
|
||||
if (imageList) {
|
||||
if (imageList->IsEmpty()) {
|
||||
// We used to have an image array for this property, but now we don't.
|
||||
// Remove the entry in the per-property image table for this property.
|
||||
// That may then allow us to remove the entire per-property image table.
|
||||
perPropertyImageTable->Remove(aProp);
|
||||
if (perPropertyImageTable->Count() == 0) {
|
||||
imageTable.Remove(aContext);
|
||||
}
|
||||
} else {
|
||||
// We still have a non-empty image array for this property. Compact the
|
||||
// storage it's using if possible.
|
||||
imageList->Compact();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new ImageValue @aValue to the CSSVariableImageTable, which will be
|
||||
* associated with @aContext and @aProp.
|
||||
*
|
||||
* It's illegal to call this function outside of a lambda passed to
|
||||
* CSSVariableImageTable::ReplaceAll().
|
||||
*/
|
||||
inline void
|
||||
Add(nsStyleContext* aContext, nsCSSProperty aProp, css::ImageValue* aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue);
|
||||
MOZ_ASSERT(aContext);
|
||||
MOZ_ASSERT(detail::IsReplacing());
|
||||
|
||||
auto& imageTable = detail::GetTable();
|
||||
|
||||
// Ensure there's a per-property image table for this style context.
|
||||
auto* perPropertyImageTable = imageTable.Get(aContext);
|
||||
if (!perPropertyImageTable) {
|
||||
perPropertyImageTable = new detail::PerPropertyImageHashtable();
|
||||
imageTable.Put(aContext, perPropertyImageTable);
|
||||
}
|
||||
|
||||
// Ensure there's an image array for this property.
|
||||
auto* imageList = perPropertyImageTable->Get(aProp);
|
||||
if (!imageList) {
|
||||
imageList = new detail::ImageValueArray();
|
||||
perPropertyImageTable->Put(aProp, imageList);
|
||||
}
|
||||
|
||||
// Append the provided ImageValue to the list.
|
||||
imageList->AppendElement(aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all ImageValues stored in the CSSVariableImageTable for the provided
|
||||
* @aContext.
|
||||
*/
|
||||
inline void
|
||||
RemoveAll(nsStyleContext* aContext)
|
||||
{
|
||||
// Move all ImageValue references into removedImageList so that we can
|
||||
// release them outside of any hashtable methods. (If we just call
|
||||
// Remove(aContext) on the table then we can end up calling back
|
||||
// re-entrantly into hashtable methods, as other style contexts
|
||||
// are released.)
|
||||
detail::ImageValueArray removedImages;
|
||||
auto& imageTable = detail::GetTable();
|
||||
auto* perPropertyImageTable = imageTable.Get(aContext);
|
||||
if (perPropertyImageTable) {
|
||||
for (auto it = perPropertyImageTable->Iter(); !it.Done(); it.Next()) {
|
||||
auto* imageList = it.UserData();
|
||||
removedImages.AppendElements(Move(*imageList));
|
||||
}
|
||||
}
|
||||
imageTable.Remove(aContext);
|
||||
}
|
||||
|
||||
} // namespace CSSVariableImageTable
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_CSSVariableImageTable_h
|
||||
@@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -282,7 +283,8 @@ AppendCSSShadowValue(const nsCSSShadowItem *aShadow,
|
||||
|
||||
// Like nsStyleCoord::CalcValue, but with length in float pixels instead
|
||||
// of nscoord.
|
||||
struct PixelCalcValue {
|
||||
struct PixelCalcValue
|
||||
{
|
||||
float mLength, mPercent;
|
||||
bool mHasPercent;
|
||||
};
|
||||
@@ -3622,12 +3624,14 @@ StyleAnimationValue::GetScaleValue(const nsIFrame* aForFrame) const
|
||||
MOZ_ASSERT(list->mHead);
|
||||
|
||||
RuleNodeCacheConditions dontCare;
|
||||
bool dontCareBool;
|
||||
nsStyleTransformMatrix::TransformReferenceBox refBox(aForFrame);
|
||||
Matrix4x4 transform = nsStyleTransformMatrix::ReadTransforms(
|
||||
list->mHead,
|
||||
aForFrame->StyleContext(),
|
||||
aForFrame->PresContext(), dontCare, refBox,
|
||||
aForFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
aForFrame->PresContext()->AppUnitsPerDevPixel(),
|
||||
&dontCareBool);
|
||||
|
||||
Matrix transform2d;
|
||||
bool canDraw2D = transform.CanDraw2D(&transform2d);
|
||||
@@ -3856,11 +3860,11 @@ void
|
||||
StyleAnimationValue::SetAndAdoptCSSValueTripletValue(
|
||||
nsCSSValueTriplet *aValueTriplet, Unit aUnit)
|
||||
{
|
||||
FreeValue();
|
||||
MOZ_ASSERT(IsCSSValueTripletUnit(aUnit), "bad unit");
|
||||
MOZ_ASSERT(aValueTriplet != nullptr, "value pairs may not be null");
|
||||
mUnit = aUnit;
|
||||
mValue.mCSSValueTriplet = aValueTriplet; // take ownership
|
||||
FreeValue();
|
||||
MOZ_ASSERT(IsCSSValueTripletUnit(aUnit), "bad unit");
|
||||
MOZ_ASSERT(aValueTriplet != nullptr, "value pairs may not be null");
|
||||
mUnit = aUnit;
|
||||
mValue.mCSSValueTriplet = aValueTriplet; // take ownership
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+391
-310
@@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -10,8 +11,10 @@
|
||||
|
||||
#include "nsCSSDataBlock.h"
|
||||
|
||||
#include "CSSVariableImageTable.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/WritingModes.h"
|
||||
#include "nsIDocument.h"
|
||||
@@ -20,6 +23,7 @@
|
||||
#include "nsStyleSet.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::css;
|
||||
|
||||
/**
|
||||
* Does a fast move of aSource to aDest. The previous value in
|
||||
@@ -30,19 +34,63 @@ using namespace mozilla;
|
||||
static bool
|
||||
MoveValue(nsCSSValue* aSource, nsCSSValue* aDest)
|
||||
{
|
||||
bool changed = (*aSource != *aDest);
|
||||
aDest->~nsCSSValue();
|
||||
memcpy(aDest, aSource, sizeof(nsCSSValue));
|
||||
new (aSource) nsCSSValue();
|
||||
return changed;
|
||||
bool changed = (*aSource != *aDest);
|
||||
aDest->~nsCSSValue();
|
||||
memcpy(aDest, aSource, sizeof(nsCSSValue));
|
||||
new (aSource) nsCSSValue();
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function maps "-webkit-box-orient" values to "flex-direction" values,
|
||||
* for a given writing-mode (taken from aRuleData).
|
||||
*
|
||||
* Specifically:
|
||||
* - If aBoxOrientVal is an enumerated value (representing a physical axis),
|
||||
* then we'll map it to the appropriate logical "flex-direction" value, using
|
||||
* the writing mode. The converted value will be emplace()'d into in the
|
||||
* outparam aConvertedValStorage, and we'll return a pointer to that value.
|
||||
* - Otherwise (e.g. if we have "inherit" or "initial"), we won't do any
|
||||
* mapping, and we'll directly return the passed-in aBoxOrientVal.
|
||||
*
|
||||
* Either way, the idea is that our caller can treat the returned value as if
|
||||
* it were a value for "flex-direction".
|
||||
*/
|
||||
static const nsCSSValue*
|
||||
ConvertBoxOrientToFlexDirection(const nsCSSValue* aBoxOrientVal,
|
||||
const nsRuleData* aRuleData,
|
||||
Maybe<nsCSSValue>& aConvertedValStorage)
|
||||
{
|
||||
MOZ_ASSERT(aBoxOrientVal, "expecting a non-null value to convert");
|
||||
MOZ_ASSERT(aConvertedValStorage.isNothing(),
|
||||
"expecting outparam for converted-value to be initially empty");
|
||||
|
||||
if (aBoxOrientVal->GetUnit() != eCSSUnit_Enumerated) {
|
||||
// We probably have "inherit" or "initial" -- just return that & have the
|
||||
// caller directly use it as a "flex-direction" value.
|
||||
return aBoxOrientVal;
|
||||
}
|
||||
|
||||
// OK, we have an enumerated value -- "horizontal" or "vertical".
|
||||
|
||||
WritingMode wm(aRuleData->mStyleContext);
|
||||
// In a horizontal writing-mode, "horizontal" maps to "row".
|
||||
// In a vertical writing-mode, "horizontal" maps to "column".
|
||||
bool isRow = wm.IsVertical() !=
|
||||
(aBoxOrientVal->GetIntValue() == NS_STYLE_BOX_ORIENT_HORIZONTAL);
|
||||
|
||||
aConvertedValStorage.emplace(isRow ? NS_STYLE_FLEX_DIRECTION_ROW :
|
||||
NS_STYLE_FLEX_DIRECTION_COLUMN,
|
||||
eCSSUnit_Enumerated);
|
||||
return aConvertedValStorage.ptr();
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldIgnoreColors(nsRuleData *aRuleData)
|
||||
{
|
||||
return aRuleData->mLevel != SheetType::Agent &&
|
||||
aRuleData->mLevel != SheetType::User &&
|
||||
!aRuleData->mPresContext->UseDocumentColors();
|
||||
return aRuleData->mLevel != SheetType::Agent &&
|
||||
aRuleData->mLevel != SheetType::User &&
|
||||
!aRuleData->mPresContext->UseDocumentColors();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,14 +99,16 @@ ShouldIgnoreColors(nsRuleData *aRuleData)
|
||||
*/
|
||||
static void
|
||||
TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
|
||||
nsCSSValueTokenStream* aTokenStream)
|
||||
nsStyleContext* aContext, nsCSSProperty aProperty,
|
||||
bool aForTokenStream)
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
|
||||
if (aValue.GetUnit() == eCSSUnit_URL) {
|
||||
aValue.StartImageLoad(aDocument);
|
||||
if (aTokenStream) {
|
||||
aTokenStream->mImageValues.PutEntry(aValue.GetImageStructValue());
|
||||
if (aForTokenStream && aContext) {
|
||||
CSSVariableImageTable::Add(aContext, aProperty,
|
||||
aValue.GetImageStructValue());
|
||||
}
|
||||
}
|
||||
else if (aValue.GetUnit() == eCSSUnit_Image) {
|
||||
@@ -66,10 +116,10 @@ TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
|
||||
imgIRequest* request = aValue.GetImageValue(nullptr);
|
||||
|
||||
if (request) {
|
||||
mozilla::css::ImageValue* imageValue = aValue.GetImageStructValue();
|
||||
ImageValue* imageValue = aValue.GetImageStructValue();
|
||||
aDocument->StyleImageLoader()->MaybeRegisterCSSImage(imageValue);
|
||||
if (aTokenStream) {
|
||||
aTokenStream->mImageValues.PutEntry(imageValue);
|
||||
if (aForTokenStream && aContext) {
|
||||
CSSVariableImageTable::Add(aContext, aProperty, imageValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,27 +128,30 @@ TryToStartImageLoadOnValue(const nsCSSValue& aValue, nsIDocument* aDocument,
|
||||
MOZ_ASSERT(arguments->Count() == 6, "unexpected num of arguments");
|
||||
|
||||
const nsCSSValue& image = arguments->Item(1);
|
||||
TryToStartImageLoadOnValue(image, aDocument, aTokenStream);
|
||||
TryToStartImageLoadOnValue(image, aDocument, aContext, aProperty,
|
||||
aForTokenStream);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
TryToStartImageLoad(const nsCSSValue& aValue, nsIDocument* aDocument,
|
||||
nsCSSProperty aProperty,
|
||||
nsCSSValueTokenStream* aTokenStream)
|
||||
nsStyleContext* aContext, nsCSSProperty aProperty,
|
||||
bool aForTokenStream)
|
||||
{
|
||||
if (aValue.GetUnit() == eCSSUnit_List) {
|
||||
for (const nsCSSValueList* l = aValue.GetListValue(); l; l = l->mNext) {
|
||||
TryToStartImageLoad(l->mValue, aDocument, aProperty, aTokenStream);
|
||||
TryToStartImageLoad(l->mValue, aDocument, aContext, aProperty,
|
||||
aForTokenStream);
|
||||
}
|
||||
} else if (nsCSSProps::PropHasFlags(aProperty,
|
||||
CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0)) {
|
||||
if (aValue.GetUnit() == eCSSUnit_Array) {
|
||||
TryToStartImageLoadOnValue(aValue.GetArrayValue()->Item(0), aDocument,
|
||||
aTokenStream);
|
||||
aContext, aProperty, aForTokenStream);
|
||||
}
|
||||
} else {
|
||||
TryToStartImageLoadOnValue(aValue, aDocument, aTokenStream);
|
||||
TryToStartImageLoadOnValue(aValue, aDocument, aContext, aProperty,
|
||||
aForTokenStream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,62 +170,84 @@ ShouldStartImageLoads(nsRuleData *aRuleData, nsCSSProperty aProperty)
|
||||
}
|
||||
|
||||
static void
|
||||
MapSinglePropertyInto(nsCSSProperty aProp,
|
||||
const nsCSSValue* aValue,
|
||||
nsCSSValue* aTarget,
|
||||
MapSinglePropertyInto(nsCSSProperty aSrcProp,
|
||||
const nsCSSValue* aSrcValue,
|
||||
nsCSSProperty aTargetProp,
|
||||
nsCSSValue* aTargetValue,
|
||||
nsRuleData* aRuleData)
|
||||
{
|
||||
MOZ_ASSERT(aValue->GetUnit() != eCSSUnit_Null, "oops");
|
||||
MOZ_ASSERT(!nsCSSProps::PropHasFlags(aTargetProp, CSS_PROPERTY_LOGICAL),
|
||||
"Can't map into a logical property");
|
||||
MOZ_ASSERT(aSrcProp == aTargetProp ||
|
||||
nsCSSProps::PropHasFlags(aSrcProp, CSS_PROPERTY_LOGICAL),
|
||||
"Source & target property must be the same, except when we're "
|
||||
"doing a logical-to-physical property mapping");
|
||||
MOZ_ASSERT(aSrcValue->GetUnit() != eCSSUnit_Null, "oops");
|
||||
|
||||
// Although aTarget is the nsCSSValue we are going to write into,
|
||||
// we also look at its value before writing into it. This is done
|
||||
// when aTarget is a token stream value, which is the case when we
|
||||
// have just re-parsed a property that had a variable reference (in
|
||||
// nsCSSParser::ParsePropertyWithVariableReferences). TryToStartImageLoad
|
||||
// then records any resulting ImageValue objects on the
|
||||
// nsCSSValueTokenStream object we found on aTarget. See the comment
|
||||
// above nsCSSValueTokenStream::mImageValues for why.
|
||||
MOZ_ASSERT(aTarget->GetUnit() == eCSSUnit_TokenStream ||
|
||||
aTarget->GetUnit() == eCSSUnit_Null,
|
||||
"aTarget must only be a token stream (when re-parsing "
|
||||
"properties with variable references) or null");
|
||||
|
||||
nsCSSValueTokenStream* tokenStream =
|
||||
aTarget->GetUnit() == eCSSUnit_TokenStream ?
|
||||
aTarget->GetTokenStreamValue() :
|
||||
nullptr;
|
||||
|
||||
if (ShouldStartImageLoads(aRuleData, aProp)) {
|
||||
nsIDocument* doc = aRuleData->mPresContext->Document();
|
||||
TryToStartImageLoad(*aValue, doc, aProp, tokenStream);
|
||||
// Handle logical properties that have custom value-mapping behavior:
|
||||
Maybe<nsCSSValue> convertedVal; // storage for converted value, if needed
|
||||
bool hasCustomValMapping =
|
||||
nsCSSProps::PropHasFlags(aSrcProp,
|
||||
CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING);
|
||||
if (hasCustomValMapping) {
|
||||
if (aSrcProp == eCSSProperty_webkit_box_orient) {
|
||||
aSrcValue = ConvertBoxOrientToFlexDirection(aSrcValue, aRuleData,
|
||||
convertedVal);
|
||||
}
|
||||
*aTarget = *aValue;
|
||||
if (nsCSSProps::PropHasFlags(aProp,
|
||||
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED) &&
|
||||
ShouldIgnoreColors(aRuleData))
|
||||
{
|
||||
if (aProp == eCSSProperty_background_color) {
|
||||
// Force non-'transparent' background
|
||||
// colors to the user's default.
|
||||
if (aTarget->IsNonTransparentColor()) {
|
||||
aTarget->SetColorValue(aRuleData->mPresContext->
|
||||
DefaultBackgroundColor());
|
||||
}
|
||||
} else {
|
||||
// Ignore 'color', 'border-*-color', etc.
|
||||
*aTarget = nsCSSValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Although aTargetValue is the nsCSSValue we are going to write into,
|
||||
// we also look at its value before writing into it. This is done
|
||||
// when aTargetValue is a token stream value, which is the case when we
|
||||
// have just re-parsed a property that had a variable reference (in
|
||||
// nsCSSParser::ParsePropertyWithVariableReferences). TryToStartImageLoad
|
||||
// then records any resulting ImageValue objects in the
|
||||
// CSSVariableImageTable, to give them the appropriate lifetime.
|
||||
MOZ_ASSERT(aTargetValue->GetUnit() == eCSSUnit_TokenStream ||
|
||||
aTargetValue->GetUnit() == eCSSUnit_Null,
|
||||
"aTargetValue must only be a token stream (when re-parsing "
|
||||
"properties with variable references) or null");
|
||||
|
||||
if (ShouldStartImageLoads(aRuleData, aTargetProp)) {
|
||||
nsIDocument* doc = aRuleData->mPresContext->Document();
|
||||
TryToStartImageLoad(*aSrcValue, doc, aRuleData->mStyleContext,
|
||||
aTargetProp,
|
||||
aTargetValue->GetUnit() == eCSSUnit_TokenStream);
|
||||
}
|
||||
*aTargetValue = *aSrcValue;
|
||||
if (nsCSSProps::PropHasFlags(aTargetProp,
|
||||
CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED) &&
|
||||
ShouldIgnoreColors(aRuleData))
|
||||
{
|
||||
if (aTargetProp == eCSSProperty_background_color) {
|
||||
// Force non-'transparent' background
|
||||
// colors to the user's default.
|
||||
if (aTargetValue->IsNonTransparentColor()) {
|
||||
aTargetValue->SetColorValue(aRuleData->mPresContext->
|
||||
DefaultBackgroundColor());
|
||||
}
|
||||
} else {
|
||||
// Ignore 'color', 'border-*-color', etc.
|
||||
*aTargetValue = nsCSSValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If aProperty is a logical property, converts it to the equivalent physical
|
||||
* If aProperty is a logical property, returns the equivalent physical
|
||||
* property based on writing mode information obtained from aRuleData's
|
||||
* style context.
|
||||
*/
|
||||
static inline void
|
||||
EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
|
||||
static inline nsCSSProperty
|
||||
EnsurePhysicalProperty(nsCSSProperty aProperty, nsRuleData* aRuleData)
|
||||
{
|
||||
if (!nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL)) {
|
||||
return aProperty;
|
||||
}
|
||||
|
||||
bool isSingleProperty =
|
||||
nsCSSProps::PropHasFlags(aProperty,
|
||||
CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING);
|
||||
bool isAxisProperty =
|
||||
nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_AXIS);
|
||||
bool isBlock =
|
||||
@@ -180,7 +255,9 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
|
||||
|
||||
int index;
|
||||
|
||||
if (isAxisProperty) {
|
||||
if (isSingleProperty) {
|
||||
index = 0; // We always map to the same physical property.
|
||||
} else if (isAxisProperty) {
|
||||
LogicalAxis logicalAxis = isBlock ? eLogicalAxisBlock : eLogicalAxisInline;
|
||||
uint8_t wm = aRuleData->mStyleContext->StyleVisibility()->mWritingMode;
|
||||
PhysicalAxis axis =
|
||||
@@ -220,7 +297,8 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
|
||||
const nsCSSProperty* props = nsCSSProps::LogicalGroup(aProperty);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
size_t len = isAxisProperty ? 2 : 4;
|
||||
// Table-length is 1 for single prop, 2 for axis prop, 4 for block prop.
|
||||
size_t len = isSingleProperty ? 1 : (isAxisProperty ? 2 : 4);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
MOZ_ASSERT(props[i] != eCSSProperty_UNKNOWN,
|
||||
"unexpected logical group length");
|
||||
@@ -229,73 +307,75 @@ EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
|
||||
"unexpected logical group length");
|
||||
}
|
||||
#endif
|
||||
aProperty = props[index];
|
||||
return props[index];
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||
{
|
||||
// If we have no data for these structs, then return immediately.
|
||||
// This optimization should make us return most of the time, so we
|
||||
// have to worry much less (although still some) about the speed of
|
||||
// the rest of the function.
|
||||
if (!(aRuleData->mSIDs & mStyleBits))
|
||||
return;
|
||||
// If we have no data for these structs, then return immediately.
|
||||
// This optimization should make us return most of the time, so we
|
||||
// have to worry much less (although still some) about the speed of
|
||||
// the rest of the function.
|
||||
if (!(aRuleData->mSIDs & mStyleBits))
|
||||
return;
|
||||
|
||||
// We process these in reverse order so that we end up mapping the
|
||||
// right property when one can be expressed using both logical and
|
||||
// physical property names.
|
||||
for (uint32_t i = mNumProps; i-- > 0; ) {
|
||||
nsCSSProperty iProp = PropertyAtIndex(i);
|
||||
if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) &
|
||||
aRuleData->mSIDs) {
|
||||
if (nsCSSProps::PropHasFlags(iProp, CSS_PROPERTY_LOGICAL)) {
|
||||
EnsurePhysicalProperty(iProp, aRuleData);
|
||||
// We can't cache anything on the rule tree if we use any data from
|
||||
// the style context, since data cached in the rule tree could be
|
||||
// used with a style context with a different value.
|
||||
uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
|
||||
aRuleData->mConditions.SetWritingModeDependency(wm);
|
||||
}
|
||||
nsCSSValue* target = aRuleData->ValueFor(iProp);
|
||||
if (target->GetUnit() == eCSSUnit_Null) {
|
||||
const nsCSSValue *val = ValueAtIndex(i);
|
||||
// In order for variable resolution to have the right information
|
||||
// about the stylesheet level of a value, that level needs to be
|
||||
// stored on the token stream. We can't do that at creation time
|
||||
// because the CSS parser (which creates the object) has no idea
|
||||
// about the stylesheet level, so we do it here instead, where
|
||||
// the rule walking will have just updated aRuleData.
|
||||
if (val->GetUnit() == eCSSUnit_TokenStream) {
|
||||
val->GetTokenStreamValue()->mLevel = aRuleData->mLevel;
|
||||
}
|
||||
MapSinglePropertyInto(iProp, val, target, aRuleData);
|
||||
}
|
||||
// We process these in reverse order so that we end up mapping the
|
||||
// right property when one can be expressed using both logical and
|
||||
// physical property names.
|
||||
for (uint32_t i = mNumProps; i-- > 0; ) {
|
||||
nsCSSProperty iProp = PropertyAtIndex(i);
|
||||
if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) &
|
||||
aRuleData->mSIDs) {
|
||||
nsCSSProperty physicalProp = EnsurePhysicalProperty(iProp,
|
||||
aRuleData);
|
||||
if (physicalProp != iProp) {
|
||||
// We can't cache anything on the rule tree if we use any data from
|
||||
// the style context, since data cached in the rule tree could be
|
||||
// used with a style context with a different value.
|
||||
uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
|
||||
aRuleData->mConditions.SetWritingModeDependency(wm);
|
||||
}
|
||||
nsCSSValue* target = aRuleData->ValueFor(physicalProp);
|
||||
if (target->GetUnit() == eCSSUnit_Null) {
|
||||
const nsCSSValue *val = ValueAtIndex(i);
|
||||
// In order for variable resolution to have the right information
|
||||
// about the stylesheet level of a value, that level needs to be
|
||||
// stored on the token stream. We can't do that at creation time
|
||||
// because the CSS parser (which creates the object) has no idea
|
||||
// about the stylesheet level, so we do it here instead, where
|
||||
// the rule walking will have just updated aRuleData.
|
||||
if (val->GetUnit() == eCSSUnit_TokenStream) {
|
||||
val->GetTokenStreamValue()->mLevel = aRuleData->mLevel;
|
||||
}
|
||||
MapSinglePropertyInto(iProp, val, physicalProp, target,
|
||||
aRuleData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nsCSSValue*
|
||||
nsCSSCompressedDataBlock::ValueFor(nsCSSProperty aProperty) const
|
||||
{
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
|
||||
"Don't call for shorthands");
|
||||
|
||||
// If we have no data for this struct, then return immediately.
|
||||
// This optimization should make us return most of the time, so we
|
||||
// have to worry much less (although still some) about the speed of
|
||||
// the rest of the function.
|
||||
if (!(nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[aProperty]) &
|
||||
mStyleBits))
|
||||
return nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
if (PropertyAtIndex(i) == aProperty) {
|
||||
return ValueAtIndex(i);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
|
||||
"Don't call for shorthands");
|
||||
|
||||
// If we have no data for this struct, then return immediately.
|
||||
// This optimization should make us return most of the time, so we
|
||||
// have to worry much less (although still some) about the speed of
|
||||
// the rest of the function.
|
||||
if (!(nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[aProperty]) &
|
||||
mStyleBits))
|
||||
return nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
if (PropertyAtIndex(i) == aProperty) {
|
||||
return ValueAtIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -303,64 +383,64 @@ nsCSSCompressedDataBlock::TryReplaceValue(nsCSSProperty aProperty,
|
||||
nsCSSExpandedDataBlock& aFromBlock,
|
||||
bool *aChanged)
|
||||
{
|
||||
nsCSSValue* newValue = aFromBlock.PropertyAt(aProperty);
|
||||
MOZ_ASSERT(newValue && newValue->GetUnit() != eCSSUnit_Null,
|
||||
"cannot replace with empty value");
|
||||
nsCSSValue* newValue = aFromBlock.PropertyAt(aProperty);
|
||||
MOZ_ASSERT(newValue && newValue->GetUnit() != eCSSUnit_Null,
|
||||
"cannot replace with empty value");
|
||||
|
||||
const nsCSSValue* oldValue = ValueFor(aProperty);
|
||||
if (!oldValue) {
|
||||
*aChanged = false;
|
||||
return false;
|
||||
}
|
||||
const nsCSSValue* oldValue = ValueFor(aProperty);
|
||||
if (!oldValue) {
|
||||
*aChanged = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
*aChanged = MoveValue(newValue, const_cast<nsCSSValue*>(oldValue));
|
||||
aFromBlock.ClearPropertyBit(aProperty);
|
||||
return true;
|
||||
*aChanged = MoveValue(newValue, const_cast<nsCSSValue*>(oldValue));
|
||||
aFromBlock.ClearPropertyBit(aProperty);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCSSCompressedDataBlock*
|
||||
nsCSSCompressedDataBlock::Clone() const
|
||||
{
|
||||
nsAutoPtr<nsCSSCompressedDataBlock>
|
||||
result(new(mNumProps) nsCSSCompressedDataBlock(mNumProps));
|
||||
nsAutoPtr<nsCSSCompressedDataBlock>
|
||||
result(new(mNumProps) nsCSSCompressedDataBlock(mNumProps));
|
||||
|
||||
result->mStyleBits = mStyleBits;
|
||||
result->mStyleBits = mStyleBits;
|
||||
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
result->SetPropertyAtIndex(i, PropertyAtIndex(i));
|
||||
result->CopyValueToIndex(i, ValueAtIndex(i));
|
||||
}
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
result->SetPropertyAtIndex(i, PropertyAtIndex(i));
|
||||
result->CopyValueToIndex(i, ValueAtIndex(i));
|
||||
}
|
||||
|
||||
return result.forget();
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
nsCSSCompressedDataBlock::~nsCSSCompressedDataBlock()
|
||||
{
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
#ifdef DEBUG
|
||||
(void)PropertyAtIndex(i); // this checks the property is in range
|
||||
(void)PropertyAtIndex(i); // this checks the property is in range
|
||||
#endif
|
||||
const nsCSSValue* val = ValueAtIndex(i);
|
||||
MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null, "oops");
|
||||
val->~nsCSSValue();
|
||||
}
|
||||
const nsCSSValue* val = ValueAtIndex(i);
|
||||
MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null, "oops");
|
||||
val->~nsCSSValue();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ nsCSSCompressedDataBlock*
|
||||
nsCSSCompressedDataBlock::CreateEmptyBlock()
|
||||
{
|
||||
nsCSSCompressedDataBlock *result = new(0) nsCSSCompressedDataBlock(0);
|
||||
return result;
|
||||
nsCSSCompressedDataBlock *result = new(0) nsCSSCompressedDataBlock(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t
|
||||
nsCSSCompressedDataBlock::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = aMallocSizeOf(this);
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
n += ValueAtIndex(i)->SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
size_t n = aMallocSizeOf(this);
|
||||
for (uint32_t i = 0; i < mNumProps; i++) {
|
||||
n += ValueAtIndex(i)->SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -402,84 +482,84 @@ nsCSSCompressedDataBlock::HasDefaultBorderImageRepeat() const
|
||||
|
||||
nsCSSExpandedDataBlock::nsCSSExpandedDataBlock()
|
||||
{
|
||||
AssertInitialState();
|
||||
AssertInitialState();
|
||||
}
|
||||
|
||||
nsCSSExpandedDataBlock::~nsCSSExpandedDataBlock()
|
||||
{
|
||||
AssertInitialState();
|
||||
AssertInitialState();
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock,
|
||||
bool aImportant)
|
||||
{
|
||||
/*
|
||||
* Save needless copying and allocation by copying the memory
|
||||
* corresponding to the stored data in the compressed block.
|
||||
*/
|
||||
for (uint32_t i = 0; i < aBlock->mNumProps; i++) {
|
||||
nsCSSProperty iProp = aBlock->PropertyAtIndex(i);
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
|
||||
MOZ_ASSERT(!HasPropertyBit(iProp),
|
||||
"compressed block has property multiple times");
|
||||
SetPropertyBit(iProp);
|
||||
if (aImportant)
|
||||
SetImportantBit(iProp);
|
||||
/*
|
||||
* Save needless copying and allocation by copying the memory
|
||||
* corresponding to the stored data in the compressed block.
|
||||
*/
|
||||
for (uint32_t i = 0; i < aBlock->mNumProps; i++) {
|
||||
nsCSSProperty iProp = aBlock->PropertyAtIndex(i);
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
|
||||
MOZ_ASSERT(!HasPropertyBit(iProp),
|
||||
"compressed block has property multiple times");
|
||||
SetPropertyBit(iProp);
|
||||
if (aImportant)
|
||||
SetImportantBit(iProp);
|
||||
|
||||
const nsCSSValue* val = aBlock->ValueAtIndex(i);
|
||||
nsCSSValue* dest = PropertyAt(iProp);
|
||||
MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null, "oops");
|
||||
MOZ_ASSERT(dest->GetUnit() == eCSSUnit_Null,
|
||||
"expanding into non-empty block");
|
||||
const nsCSSValue* val = aBlock->ValueAtIndex(i);
|
||||
nsCSSValue* dest = PropertyAt(iProp);
|
||||
MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null, "oops");
|
||||
MOZ_ASSERT(dest->GetUnit() == eCSSUnit_Null,
|
||||
"expanding into non-empty block");
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
dest->~nsCSSValue();
|
||||
dest->~nsCSSValue();
|
||||
#endif
|
||||
memcpy(dest, val, sizeof(nsCSSValue));
|
||||
}
|
||||
memcpy(dest, val, sizeof(nsCSSValue));
|
||||
}
|
||||
|
||||
// Set the number of properties to zero so that we don't destroy the
|
||||
// remnants of what we just copied.
|
||||
aBlock->SetNumPropsToZero();
|
||||
delete aBlock;
|
||||
// Set the number of properties to zero so that we don't destroy the
|
||||
// remnants of what we just copied.
|
||||
aBlock->SetNumPropsToZero();
|
||||
delete aBlock;
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSExpandedDataBlock::Expand(nsCSSCompressedDataBlock *aNormalBlock,
|
||||
nsCSSCompressedDataBlock *aImportantBlock)
|
||||
{
|
||||
MOZ_ASSERT(aNormalBlock, "unexpected null block");
|
||||
AssertInitialState();
|
||||
MOZ_ASSERT(aNormalBlock, "unexpected null block");
|
||||
AssertInitialState();
|
||||
|
||||
DoExpand(aNormalBlock, false);
|
||||
if (aImportantBlock) {
|
||||
DoExpand(aImportantBlock, true);
|
||||
}
|
||||
DoExpand(aNormalBlock, false);
|
||||
if (aImportantBlock) {
|
||||
DoExpand(aImportantBlock, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSExpandedDataBlock::ComputeNumProps(uint32_t* aNumPropsNormal,
|
||||
uint32_t* aNumPropsImportant)
|
||||
{
|
||||
*aNumPropsNormal = *aNumPropsImportant = 0;
|
||||
for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
|
||||
if (!mPropertiesSet.HasPropertyInChunk(iHigh))
|
||||
continue;
|
||||
for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
|
||||
if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
|
||||
continue;
|
||||
*aNumPropsNormal = *aNumPropsImportant = 0;
|
||||
for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
|
||||
if (!mPropertiesSet.HasPropertyInChunk(iHigh))
|
||||
continue;
|
||||
for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
|
||||
if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
|
||||
continue;
|
||||
#ifdef DEBUG
|
||||
nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
|
||||
nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
|
||||
#endif
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
|
||||
MOZ_ASSERT(PropertyAt(iProp)->GetUnit() != eCSSUnit_Null,
|
||||
"null value while computing size");
|
||||
if (mPropertiesImportant.HasPropertyAt(iHigh, iLow))
|
||||
(*aNumPropsImportant)++;
|
||||
else
|
||||
(*aNumPropsNormal)++;
|
||||
}
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
|
||||
MOZ_ASSERT(PropertyAt(iProp)->GetUnit() != eCSSUnit_Null,
|
||||
"null value while computing size");
|
||||
if (mPropertiesImportant.HasPropertyAt(iHigh, iLow))
|
||||
(*aNumPropsImportant)++;
|
||||
else
|
||||
(*aNumPropsNormal)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -487,110 +567,110 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock,
|
||||
nsCSSCompressedDataBlock **aImportantBlock,
|
||||
const nsTArray<uint32_t>& aOrder)
|
||||
{
|
||||
nsAutoPtr<nsCSSCompressedDataBlock> result_normal, result_important;
|
||||
uint32_t i_normal = 0, i_important = 0;
|
||||
nsAutoPtr<nsCSSCompressedDataBlock> result_normal, result_important;
|
||||
uint32_t i_normal = 0, i_important = 0;
|
||||
|
||||
uint32_t numPropsNormal, numPropsImportant;
|
||||
ComputeNumProps(&numPropsNormal, &numPropsImportant);
|
||||
uint32_t numPropsNormal, numPropsImportant;
|
||||
ComputeNumProps(&numPropsNormal, &numPropsImportant);
|
||||
|
||||
result_normal =
|
||||
new(numPropsNormal) nsCSSCompressedDataBlock(numPropsNormal);
|
||||
result_normal =
|
||||
new(numPropsNormal) nsCSSCompressedDataBlock(numPropsNormal);
|
||||
|
||||
if (numPropsImportant != 0) {
|
||||
result_important =
|
||||
new(numPropsImportant) nsCSSCompressedDataBlock(numPropsImportant);
|
||||
} else {
|
||||
result_important = nullptr;
|
||||
if (numPropsImportant != 0) {
|
||||
result_important =
|
||||
new(numPropsImportant) nsCSSCompressedDataBlock(numPropsImportant);
|
||||
} else {
|
||||
result_important = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save needless copying and allocation by copying the memory
|
||||
* corresponding to the stored data in the expanded block, and then
|
||||
* clearing the data in the expanded block.
|
||||
*/
|
||||
for (size_t i = 0; i < aOrder.Length(); i++) {
|
||||
nsCSSProperty iProp = static_cast<nsCSSProperty>(aOrder[i]);
|
||||
if (iProp >= eCSSProperty_COUNT) {
|
||||
// a custom property
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(mPropertiesSet.HasProperty(iProp),
|
||||
"aOrder identifies a property not in the expanded "
|
||||
"data block");
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
|
||||
bool important = mPropertiesImportant.HasProperty(iProp);
|
||||
nsCSSCompressedDataBlock *result =
|
||||
important ? result_important : result_normal;
|
||||
uint32_t* ip = important ? &i_important : &i_normal;
|
||||
nsCSSValue* val = PropertyAt(iProp);
|
||||
MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null,
|
||||
"Null value while compressing");
|
||||
result->SetPropertyAtIndex(*ip, iProp);
|
||||
result->RawCopyValueToIndex(*ip, val);
|
||||
new (val) nsCSSValue();
|
||||
(*ip)++;
|
||||
result->mStyleBits |=
|
||||
nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save needless copying and allocation by copying the memory
|
||||
* corresponding to the stored data in the expanded block, and then
|
||||
* clearing the data in the expanded block.
|
||||
*/
|
||||
for (size_t i = 0; i < aOrder.Length(); i++) {
|
||||
nsCSSProperty iProp = static_cast<nsCSSProperty>(aOrder[i]);
|
||||
if (iProp >= eCSSProperty_COUNT) {
|
||||
// a custom property
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(mPropertiesSet.HasProperty(iProp),
|
||||
"aOrder identifies a property not in the expanded "
|
||||
"data block");
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(iProp), "out of range");
|
||||
bool important = mPropertiesImportant.HasProperty(iProp);
|
||||
nsCSSCompressedDataBlock *result =
|
||||
important ? result_important : result_normal;
|
||||
uint32_t* ip = important ? &i_important : &i_normal;
|
||||
nsCSSValue* val = PropertyAt(iProp);
|
||||
MOZ_ASSERT(val->GetUnit() != eCSSUnit_Null,
|
||||
"Null value while compressing");
|
||||
result->SetPropertyAtIndex(*ip, iProp);
|
||||
result->RawCopyValueToIndex(*ip, val);
|
||||
new (val) nsCSSValue();
|
||||
(*ip)++;
|
||||
result->mStyleBits |=
|
||||
nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]);
|
||||
}
|
||||
MOZ_ASSERT(numPropsNormal == i_normal, "bad numProps");
|
||||
|
||||
MOZ_ASSERT(numPropsNormal == i_normal, "bad numProps");
|
||||
|
||||
if (result_important) {
|
||||
MOZ_ASSERT(numPropsImportant == i_important, "bad numProps");
|
||||
}
|
||||
if (result_important) {
|
||||
MOZ_ASSERT(numPropsImportant == i_important, "bad numProps");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// assert that we didn't have any other properties on this expanded data
|
||||
// block that we didn't find in aOrder
|
||||
uint32_t numPropsInSet = 0;
|
||||
for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; iHigh++) {
|
||||
if (!mPropertiesSet.HasPropertyInChunk(iHigh)) {
|
||||
continue;
|
||||
}
|
||||
for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; iLow++) {
|
||||
if (mPropertiesSet.HasPropertyAt(iHigh, iLow)) {
|
||||
numPropsInSet++;
|
||||
}
|
||||
}
|
||||
{
|
||||
// assert that we didn't have any other properties on this expanded data
|
||||
// block that we didn't find in aOrder
|
||||
uint32_t numPropsInSet = 0;
|
||||
for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; iHigh++) {
|
||||
if (!mPropertiesSet.HasPropertyInChunk(iHigh)) {
|
||||
continue;
|
||||
}
|
||||
for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; iLow++) {
|
||||
if (mPropertiesSet.HasPropertyAt(iHigh, iLow)) {
|
||||
numPropsInSet++;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(numPropsNormal + numPropsImportant == numPropsInSet,
|
||||
"aOrder missing properties from the expanded data block");
|
||||
}
|
||||
MOZ_ASSERT(numPropsNormal + numPropsImportant == numPropsInSet,
|
||||
"aOrder missing properties from the expanded data block");
|
||||
}
|
||||
#endif
|
||||
|
||||
ClearSets();
|
||||
AssertInitialState();
|
||||
*aNormalBlock = result_normal.forget();
|
||||
*aImportantBlock = result_important.forget();
|
||||
ClearSets();
|
||||
AssertInitialState();
|
||||
*aNormalBlock = result_normal.forget();
|
||||
*aImportantBlock = result_important.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSExpandedDataBlock::AddLonghandProperty(nsCSSProperty aProperty,
|
||||
const nsCSSValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
|
||||
"property out of range");
|
||||
nsCSSValue& storage = *static_cast<nsCSSValue*>(PropertyAt(aProperty));
|
||||
storage = aValue;
|
||||
SetPropertyBit(aProperty);
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
|
||||
"property out of range");
|
||||
nsCSSValue& storage = *static_cast<nsCSSValue*>(PropertyAt(aProperty));
|
||||
storage = aValue;
|
||||
SetPropertyBit(aProperty);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSExpandedDataBlock::Clear()
|
||||
{
|
||||
for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
|
||||
if (!mPropertiesSet.HasPropertyInChunk(iHigh))
|
||||
continue;
|
||||
for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
|
||||
if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
|
||||
continue;
|
||||
nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
|
||||
ClearLonghandProperty(iProp);
|
||||
}
|
||||
for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
|
||||
if (!mPropertiesSet.HasPropertyInChunk(iHigh))
|
||||
continue;
|
||||
for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
|
||||
if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
|
||||
continue;
|
||||
nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
|
||||
ClearLonghandProperty(iProp);
|
||||
}
|
||||
}
|
||||
|
||||
AssertInitialState();
|
||||
AssertInitialState();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -609,11 +689,11 @@ nsCSSExpandedDataBlock::ClearProperty(nsCSSProperty aPropID)
|
||||
void
|
||||
nsCSSExpandedDataBlock::ClearLonghandProperty(nsCSSProperty aPropID)
|
||||
{
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(aPropID), "out of range");
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(aPropID), "out of range");
|
||||
|
||||
ClearPropertyBit(aPropID);
|
||||
ClearImportantBit(aPropID);
|
||||
PropertyAt(aPropID)->Reset();
|
||||
ClearPropertyBit(aPropID);
|
||||
ClearImportantBit(aPropID);
|
||||
PropertyAt(aPropID)->Reset();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -626,26 +706,26 @@ nsCSSExpandedDataBlock::TransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
|
||||
css::Declaration* aDeclaration,
|
||||
nsIDocument* aSheetDocument)
|
||||
{
|
||||
if (!nsCSSProps::IsShorthand(aPropID)) {
|
||||
return DoTransferFromBlock(aFromBlock, aPropID,
|
||||
if (!nsCSSProps::IsShorthand(aPropID)) {
|
||||
return DoTransferFromBlock(aFromBlock, aPropID,
|
||||
aIsImportant, aOverrideImportant,
|
||||
aMustCallValueAppended, aDeclaration,
|
||||
aSheetDocument);
|
||||
}
|
||||
|
||||
// We can pass eIgnoreEnabledState (here, and in ClearProperty above) rather
|
||||
// than a value corresponding to whether we're parsing a UA style sheet or
|
||||
// certified app because we assert in nsCSSProps::AddRefTable that shorthand
|
||||
// properties available in these contexts also have all of their
|
||||
// subproperties available in these contexts.
|
||||
bool changed = false;
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aPropID, aEnabledState) {
|
||||
changed |= DoTransferFromBlock(aFromBlock, *p,
|
||||
aIsImportant, aOverrideImportant,
|
||||
aMustCallValueAppended, aDeclaration,
|
||||
aSheetDocument);
|
||||
}
|
||||
|
||||
// We can pass eIgnoreEnabledState (here, and in ClearProperty above) rather
|
||||
// than a value corresponding to whether we're parsing a UA style sheet or
|
||||
// certified app because we assert in nsCSSProps::AddRefTable that shorthand
|
||||
// properties available in these contexts also have all of their
|
||||
// subproperties available in these contexts.
|
||||
bool changed = false;
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aPropID, aEnabledState) {
|
||||
changed |= DoTransferFromBlock(aFromBlock, *p,
|
||||
aIsImportant, aOverrideImportant,
|
||||
aMustCallValueAppended, aDeclaration,
|
||||
aSheetDocument);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -711,9 +791,8 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID,
|
||||
const nsCSSValue* src = PropertyAt(aPropID);
|
||||
MOZ_ASSERT(src->GetUnit() != eCSSUnit_Null);
|
||||
|
||||
nsCSSProperty physicalProp = aPropID;
|
||||
if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) {
|
||||
EnsurePhysicalProperty(physicalProp, aRuleData);
|
||||
nsCSSProperty physicalProp = EnsurePhysicalProperty(aPropID, aRuleData);
|
||||
if (physicalProp != aPropID) {
|
||||
uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
|
||||
aRuleData->mConditions.SetWritingModeDependency(wm);
|
||||
}
|
||||
@@ -722,20 +801,22 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID,
|
||||
MOZ_ASSERT(dest->GetUnit() == eCSSUnit_TokenStream &&
|
||||
dest->GetTokenStreamValue()->mPropertyID == aPropID);
|
||||
|
||||
MapSinglePropertyInto(physicalProp, src, dest, aRuleData);
|
||||
CSSVariableImageTable::ReplaceAll(aRuleData->mStyleContext, aPropID, [=] {
|
||||
MapSinglePropertyInto(aPropID, src, physicalProp, dest, aRuleData);
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsCSSExpandedDataBlock::DoAssertInitialState()
|
||||
{
|
||||
mPropertiesSet.AssertIsEmpty("not initial state");
|
||||
mPropertiesImportant.AssertIsEmpty("not initial state");
|
||||
mPropertiesSet.AssertIsEmpty("not initial state");
|
||||
mPropertiesImportant.AssertIsEmpty("not initial state");
|
||||
|
||||
for (uint32_t i = 0; i < eCSSProperty_COUNT_no_shorthands; ++i) {
|
||||
nsCSSProperty prop = nsCSSProperty(i);
|
||||
MOZ_ASSERT(PropertyAt(prop)->GetUnit() == eCSSUnit_Null,
|
||||
"not initial state");
|
||||
}
|
||||
for (uint32_t i = 0; i < eCSSProperty_COUNT_no_shorthands; ++i) {
|
||||
nsCSSProperty prop = nsCSSProperty(i);
|
||||
MOZ_ASSERT(PropertyAt(prop)->GetUnit() == eCSSUnit_Null,
|
||||
"not initial state");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+262
-259
@@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -34,137 +35,138 @@ class Declaration;
|
||||
* |css::Declaration|). Mutation is accomplished through
|
||||
* |nsCSSExpandedDataBlock| or in some cases via direct slot access.
|
||||
*/
|
||||
class nsCSSCompressedDataBlock {
|
||||
class nsCSSCompressedDataBlock
|
||||
{
|
||||
private:
|
||||
friend class nsCSSExpandedDataBlock;
|
||||
friend class nsCSSExpandedDataBlock;
|
||||
|
||||
// Only this class (via |CreateEmptyBlock|) or nsCSSExpandedDataBlock
|
||||
// (in |Compress|) can create compressed data blocks.
|
||||
explicit nsCSSCompressedDataBlock(uint32_t aNumProps)
|
||||
: mStyleBits(0), mNumProps(aNumProps)
|
||||
{}
|
||||
// Only this class (via |CreateEmptyBlock|) or nsCSSExpandedDataBlock
|
||||
// (in |Compress|) can create compressed data blocks.
|
||||
explicit nsCSSCompressedDataBlock(uint32_t aNumProps)
|
||||
: mStyleBits(0), mNumProps(aNumProps)
|
||||
{}
|
||||
|
||||
public:
|
||||
~nsCSSCompressedDataBlock();
|
||||
~nsCSSCompressedDataBlock();
|
||||
|
||||
/**
|
||||
* Do what |nsIStyleRule::MapRuleInfoInto| needs to do for a style
|
||||
* rule using this block for storage.
|
||||
*/
|
||||
void MapRuleInfoInto(nsRuleData *aRuleData) const;
|
||||
/**
|
||||
* Do what |nsIStyleRule::MapRuleInfoInto| needs to do for a style
|
||||
* rule using this block for storage.
|
||||
*/
|
||||
void MapRuleInfoInto(nsRuleData *aRuleData) const;
|
||||
|
||||
/**
|
||||
* Return the location at which the *value* for the property is
|
||||
* stored, or null if the block does not contain a value for the
|
||||
* property.
|
||||
*
|
||||
* Inefficient (by design).
|
||||
*
|
||||
* Must not be called for shorthands.
|
||||
*/
|
||||
const nsCSSValue* ValueFor(nsCSSProperty aProperty) const;
|
||||
/**
|
||||
* Return the location at which the *value* for the property is
|
||||
* stored, or null if the block does not contain a value for the
|
||||
* property.
|
||||
*
|
||||
* Inefficient (by design).
|
||||
*
|
||||
* Must not be called for shorthands.
|
||||
*/
|
||||
const nsCSSValue* ValueFor(nsCSSProperty aProperty) const;
|
||||
|
||||
/**
|
||||
* Attempt to replace the value for |aProperty| stored in this block
|
||||
* with the matching value stored in |aFromBlock|.
|
||||
* This method will fail (returning false) if |aProperty| is not
|
||||
* already in this block. It will set |aChanged| to true if it
|
||||
* actually made a change to the block, but regardless, if it
|
||||
* returns true, the value in |aFromBlock| was erased.
|
||||
*/
|
||||
bool TryReplaceValue(nsCSSProperty aProperty,
|
||||
nsCSSExpandedDataBlock& aFromBlock,
|
||||
bool* aChanged);
|
||||
/**
|
||||
* Attempt to replace the value for |aProperty| stored in this block
|
||||
* with the matching value stored in |aFromBlock|.
|
||||
* This method will fail (returning false) if |aProperty| is not
|
||||
* already in this block. It will set |aChanged| to true if it
|
||||
* actually made a change to the block, but regardless, if it
|
||||
* returns true, the value in |aFromBlock| was erased.
|
||||
*/
|
||||
bool TryReplaceValue(nsCSSProperty aProperty,
|
||||
nsCSSExpandedDataBlock& aFromBlock,
|
||||
bool* aChanged);
|
||||
|
||||
/**
|
||||
* Clone this block, or return null on out-of-memory.
|
||||
*/
|
||||
nsCSSCompressedDataBlock* Clone() const;
|
||||
/**
|
||||
* Clone this block, or return null on out-of-memory.
|
||||
*/
|
||||
nsCSSCompressedDataBlock* Clone() const;
|
||||
|
||||
/**
|
||||
* Create a new nsCSSCompressedDataBlock holding no declarations.
|
||||
*/
|
||||
static nsCSSCompressedDataBlock* CreateEmptyBlock();
|
||||
/**
|
||||
* Create a new nsCSSCompressedDataBlock holding no declarations.
|
||||
*/
|
||||
static nsCSSCompressedDataBlock* CreateEmptyBlock();
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
bool HasDefaultBorderImageSlice() const;
|
||||
bool HasDefaultBorderImageWidth() const;
|
||||
bool HasDefaultBorderImageOutset() const;
|
||||
bool HasDefaultBorderImageRepeat() const;
|
||||
bool HasDefaultBorderImageSlice() const;
|
||||
bool HasDefaultBorderImageWidth() const;
|
||||
bool HasDefaultBorderImageOutset() const;
|
||||
bool HasDefaultBorderImageRepeat() const;
|
||||
|
||||
bool HasInheritedStyleData() const
|
||||
{
|
||||
return mStyleBits & NS_STYLE_INHERITED_STRUCT_MASK;
|
||||
}
|
||||
bool HasInheritedStyleData() const
|
||||
{
|
||||
return mStyleBits & NS_STYLE_INHERITED_STRUCT_MASK;
|
||||
}
|
||||
|
||||
private:
|
||||
void* operator new(size_t aBaseSize, uint32_t aNumProps) {
|
||||
MOZ_ASSERT(aBaseSize == sizeof(nsCSSCompressedDataBlock),
|
||||
"unexpected size for nsCSSCompressedDataBlock");
|
||||
return ::operator new(aBaseSize + DataSize(aNumProps));
|
||||
}
|
||||
void* operator new(size_t aBaseSize, uint32_t aNumProps) {
|
||||
MOZ_ASSERT(aBaseSize == sizeof(nsCSSCompressedDataBlock),
|
||||
"unexpected size for nsCSSCompressedDataBlock");
|
||||
return ::operator new(aBaseSize + DataSize(aNumProps));
|
||||
}
|
||||
|
||||
public:
|
||||
// Ideally, |nsCSSProperty| would be |enum nsCSSProperty : int16_t|. But
|
||||
// not all of the compilers we use are modern enough to support small
|
||||
// enums. So we manually squeeze nsCSSProperty into 16 bits ourselves.
|
||||
// The static assertion below ensures it fits.
|
||||
typedef int16_t CompressedCSSProperty;
|
||||
static const size_t MaxCompressedCSSProperty = INT16_MAX;
|
||||
// Ideally, |nsCSSProperty| would be |enum nsCSSProperty : int16_t|. But
|
||||
// not all of the compilers we use are modern enough to support small
|
||||
// enums. So we manually squeeze nsCSSProperty into 16 bits ourselves.
|
||||
// The static assertion below ensures it fits.
|
||||
typedef int16_t CompressedCSSProperty;
|
||||
static const size_t MaxCompressedCSSProperty = INT16_MAX;
|
||||
|
||||
private:
|
||||
static size_t DataSize(uint32_t aNumProps) {
|
||||
return size_t(aNumProps) *
|
||||
(sizeof(nsCSSValue) + sizeof(CompressedCSSProperty));
|
||||
}
|
||||
static size_t DataSize(uint32_t aNumProps) {
|
||||
return size_t(aNumProps) *
|
||||
(sizeof(nsCSSValue) + sizeof(CompressedCSSProperty));
|
||||
}
|
||||
|
||||
int32_t mStyleBits; // the structs for which we have data, according to
|
||||
// |nsCachedStyleData::GetBitForSID|.
|
||||
uint32_t mNumProps;
|
||||
// nsCSSValue elements are stored after these fields, and
|
||||
// nsCSSProperty elements are stored -- each one compressed as a
|
||||
// CompressedCSSProperty -- after the nsCSSValue elements. Space for them
|
||||
// is allocated in |operator new| above. The static assertions following
|
||||
// this class make sure that the value and property elements are aligned
|
||||
// appropriately.
|
||||
int32_t mStyleBits; // the structs for which we have data, according to
|
||||
// |nsCachedStyleData::GetBitForSID|.
|
||||
uint32_t mNumProps;
|
||||
// nsCSSValue elements are stored after these fields, and
|
||||
// nsCSSProperty elements are stored -- each one compressed as a
|
||||
// CompressedCSSProperty -- after the nsCSSValue elements. Space for them
|
||||
// is allocated in |operator new| above. The static assertions following
|
||||
// this class make sure that the value and property elements are aligned
|
||||
// appropriately.
|
||||
|
||||
nsCSSValue* Values() const {
|
||||
return (nsCSSValue*)(this + 1);
|
||||
}
|
||||
nsCSSValue* Values() const {
|
||||
return (nsCSSValue*)(this + 1);
|
||||
}
|
||||
|
||||
CompressedCSSProperty* CompressedProperties() const {
|
||||
return (CompressedCSSProperty*)(Values() + mNumProps);
|
||||
}
|
||||
CompressedCSSProperty* CompressedProperties() const {
|
||||
return (CompressedCSSProperty*)(Values() + mNumProps);
|
||||
}
|
||||
|
||||
nsCSSValue* ValueAtIndex(uint32_t i) const {
|
||||
MOZ_ASSERT(i < mNumProps, "value index out of range");
|
||||
return Values() + i;
|
||||
}
|
||||
nsCSSValue* ValueAtIndex(uint32_t i) const {
|
||||
MOZ_ASSERT(i < mNumProps, "value index out of range");
|
||||
return Values() + i;
|
||||
}
|
||||
|
||||
nsCSSProperty PropertyAtIndex(uint32_t i) const {
|
||||
MOZ_ASSERT(i < mNumProps, "property index out of range");
|
||||
nsCSSProperty prop = (nsCSSProperty)CompressedProperties()[i];
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(prop), "out of range");
|
||||
return prop;
|
||||
}
|
||||
nsCSSProperty PropertyAtIndex(uint32_t i) const {
|
||||
MOZ_ASSERT(i < mNumProps, "property index out of range");
|
||||
nsCSSProperty prop = (nsCSSProperty)CompressedProperties()[i];
|
||||
MOZ_ASSERT(!nsCSSProps::IsShorthand(prop), "out of range");
|
||||
return prop;
|
||||
}
|
||||
|
||||
void CopyValueToIndex(uint32_t i, nsCSSValue* aValue) {
|
||||
new (ValueAtIndex(i)) nsCSSValue(*aValue);
|
||||
}
|
||||
void CopyValueToIndex(uint32_t i, nsCSSValue* aValue) {
|
||||
new (ValueAtIndex(i)) nsCSSValue(*aValue);
|
||||
}
|
||||
|
||||
void RawCopyValueToIndex(uint32_t i, nsCSSValue* aValue) {
|
||||
memcpy(ValueAtIndex(i), aValue, sizeof(nsCSSValue));
|
||||
}
|
||||
void RawCopyValueToIndex(uint32_t i, nsCSSValue* aValue) {
|
||||
memcpy(ValueAtIndex(i), aValue, sizeof(nsCSSValue));
|
||||
}
|
||||
|
||||
void SetPropertyAtIndex(uint32_t i, nsCSSProperty aProperty) {
|
||||
MOZ_ASSERT(i < mNumProps, "set property index out of range");
|
||||
CompressedProperties()[i] = (CompressedCSSProperty)aProperty;
|
||||
}
|
||||
void SetPropertyAtIndex(uint32_t i, nsCSSProperty aProperty) {
|
||||
MOZ_ASSERT(i < mNumProps, "set property index out of range");
|
||||
CompressedProperties()[i] = (CompressedCSSProperty)aProperty;
|
||||
}
|
||||
|
||||
void SetNumPropsToZero() {
|
||||
mNumProps = 0;
|
||||
}
|
||||
void SetNumPropsToZero() {
|
||||
mNumProps = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// Make sure the values and properties are aligned appropriately. (These
|
||||
@@ -172,198 +174,199 @@ private:
|
||||
static_assert(sizeof(nsCSSCompressedDataBlock) == 8,
|
||||
"nsCSSCompressedDataBlock's size has changed");
|
||||
static_assert(NS_ALIGNMENT_OF(nsCSSValue) == 4 || NS_ALIGNMENT_OF(nsCSSValue) == 8,
|
||||
"nsCSSValue doesn't align with nsCSSCompressedDataBlock");
|
||||
"nsCSSValue doesn't align with nsCSSCompressedDataBlock");
|
||||
static_assert(NS_ALIGNMENT_OF(nsCSSCompressedDataBlock::CompressedCSSProperty) == 2,
|
||||
"CompressedCSSProperty doesn't align with nsCSSValue");
|
||||
"CompressedCSSProperty doesn't align with nsCSSValue");
|
||||
|
||||
// Make sure that sizeof(CompressedCSSProperty) is big enough.
|
||||
static_assert(eCSSProperty_COUNT_no_shorthands <=
|
||||
nsCSSCompressedDataBlock::MaxCompressedCSSProperty,
|
||||
"nsCSSProperty doesn't fit in StoredSizeOfCSSProperty");
|
||||
|
||||
class nsCSSExpandedDataBlock {
|
||||
friend class nsCSSCompressedDataBlock;
|
||||
class nsCSSExpandedDataBlock
|
||||
{
|
||||
friend class nsCSSCompressedDataBlock;
|
||||
|
||||
public:
|
||||
nsCSSExpandedDataBlock();
|
||||
~nsCSSExpandedDataBlock();
|
||||
nsCSSExpandedDataBlock();
|
||||
~nsCSSExpandedDataBlock();
|
||||
|
||||
private:
|
||||
/* Property storage may not be accessed directly; use AddLonghandProperty
|
||||
* and friends.
|
||||
*/
|
||||
nsCSSValue mValues[eCSSProperty_COUNT_no_shorthands];
|
||||
/* Property storage may not be accessed directly; use AddLonghandProperty
|
||||
* and friends.
|
||||
*/
|
||||
nsCSSValue mValues[eCSSProperty_COUNT_no_shorthands];
|
||||
|
||||
public:
|
||||
/**
|
||||
* Transfer all of the state from a pair of compressed data blocks
|
||||
* to this expanded block. This expanded block must be clear
|
||||
* beforehand.
|
||||
*
|
||||
* This method DELETES both of the compressed data blocks it is
|
||||
* passed. (This is necessary because ownership of sub-objects
|
||||
* is transferred to the expanded block.)
|
||||
*/
|
||||
void Expand(nsCSSCompressedDataBlock *aNormalBlock,
|
||||
nsCSSCompressedDataBlock *aImportantBlock);
|
||||
/**
|
||||
* Transfer all of the state from a pair of compressed data blocks
|
||||
* to this expanded block. This expanded block must be clear
|
||||
* beforehand.
|
||||
*
|
||||
* This method DELETES both of the compressed data blocks it is
|
||||
* passed. (This is necessary because ownership of sub-objects
|
||||
* is transferred to the expanded block.)
|
||||
*/
|
||||
void Expand(nsCSSCompressedDataBlock *aNormalBlock,
|
||||
nsCSSCompressedDataBlock *aImportantBlock);
|
||||
|
||||
/**
|
||||
* Allocate new compressed blocks and transfer all of the state
|
||||
* from this expanded block to the new blocks, clearing this
|
||||
* expanded block. A normal block will always be allocated, but
|
||||
* an important block will only be allocated if there are
|
||||
* !important properties in the expanded block; otherwise
|
||||
* |*aImportantBlock| will be set to null.
|
||||
*
|
||||
* aOrder is an array of nsCSSProperty values specifying the order
|
||||
* to store values in the two data blocks.
|
||||
*/
|
||||
void Compress(nsCSSCompressedDataBlock **aNormalBlock,
|
||||
nsCSSCompressedDataBlock **aImportantBlock,
|
||||
const nsTArray<uint32_t>& aOrder);
|
||||
/**
|
||||
* Allocate new compressed blocks and transfer all of the state
|
||||
* from this expanded block to the new blocks, clearing this
|
||||
* expanded block. A normal block will always be allocated, but
|
||||
* an important block will only be allocated if there are
|
||||
* !important properties in the expanded block; otherwise
|
||||
* |*aImportantBlock| will be set to null.
|
||||
*
|
||||
* aOrder is an array of nsCSSProperty values specifying the order
|
||||
* to store values in the two data blocks.
|
||||
*/
|
||||
void Compress(nsCSSCompressedDataBlock **aNormalBlock,
|
||||
nsCSSCompressedDataBlock **aImportantBlock,
|
||||
const nsTArray<uint32_t>& aOrder);
|
||||
|
||||
/**
|
||||
* Copy a value into this expanded block. This does NOT destroy
|
||||
* the source value object. |aProperty| cannot be a shorthand.
|
||||
*/
|
||||
void AddLonghandProperty(nsCSSProperty aProperty, const nsCSSValue& aValue);
|
||||
/**
|
||||
* Copy a value into this expanded block. This does NOT destroy
|
||||
* the source value object. |aProperty| cannot be a shorthand.
|
||||
*/
|
||||
void AddLonghandProperty(nsCSSProperty aProperty, const nsCSSValue& aValue);
|
||||
|
||||
/**
|
||||
* Clear the state of this expanded block.
|
||||
*/
|
||||
void Clear();
|
||||
/**
|
||||
* Clear the state of this expanded block.
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
* Clear the data for the given property (including the set and
|
||||
* important bits). Can be used with shorthand properties.
|
||||
*/
|
||||
void ClearProperty(nsCSSProperty aPropID);
|
||||
/**
|
||||
* Clear the data for the given property (including the set and
|
||||
* important bits). Can be used with shorthand properties.
|
||||
*/
|
||||
void ClearProperty(nsCSSProperty aPropID);
|
||||
|
||||
/**
|
||||
* Same as ClearProperty, but faster and cannot be used with shorthands.
|
||||
*/
|
||||
void ClearLonghandProperty(nsCSSProperty aPropID);
|
||||
/**
|
||||
* Same as ClearProperty, but faster and cannot be used with shorthands.
|
||||
*/
|
||||
void ClearLonghandProperty(nsCSSProperty aPropID);
|
||||
|
||||
/**
|
||||
* Transfer the state for |aPropID| (which may be a shorthand)
|
||||
* from |aFromBlock| to this block. The property being transferred
|
||||
* is !important if |aIsImportant| is true, and should replace an
|
||||
* existing !important property regardless of its own importance
|
||||
* if |aOverrideImportant| is true. |aEnabledState| is used to
|
||||
* determine which longhand components of |aPropID| (if it is a
|
||||
* shorthand) to transfer.
|
||||
*
|
||||
* Returns true if something changed, false otherwise. Calls
|
||||
* |ValueAppended| on |aDeclaration| if the property was not
|
||||
* previously set, or in any case if |aMustCallValueAppended| is true.
|
||||
* Calls |SetDocumentAndPageUseCounter| on |aSheetDocument| if it is
|
||||
* non-null and |aPropID| has a use counter.
|
||||
*/
|
||||
bool TransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
|
||||
nsCSSProperty aPropID,
|
||||
nsCSSProps::EnabledState aEnabledState,
|
||||
bool aIsImportant,
|
||||
bool aOverrideImportant,
|
||||
bool aMustCallValueAppended,
|
||||
mozilla::css::Declaration* aDeclaration,
|
||||
nsIDocument* aSheetDocument);
|
||||
/**
|
||||
* Transfer the state for |aPropID| (which may be a shorthand)
|
||||
* from |aFromBlock| to this block. The property being transferred
|
||||
* is !important if |aIsImportant| is true, and should replace an
|
||||
* existing !important property regardless of its own importance
|
||||
* if |aOverrideImportant| is true. |aEnabledState| is used to
|
||||
* determine which longhand components of |aPropID| (if it is a
|
||||
* shorthand) to transfer.
|
||||
*
|
||||
* Returns true if something changed, false otherwise. Calls
|
||||
* |ValueAppended| on |aDeclaration| if the property was not
|
||||
* previously set, or in any case if |aMustCallValueAppended| is true.
|
||||
* Calls |SetDocumentAndPageUseCounter| on |aSheetDocument| if it is
|
||||
* non-null and |aPropID| has a use counter.
|
||||
*/
|
||||
bool TransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
|
||||
nsCSSProperty aPropID,
|
||||
nsCSSProps::EnabledState aEnabledState,
|
||||
bool aIsImportant,
|
||||
bool aOverrideImportant,
|
||||
bool aMustCallValueAppended,
|
||||
mozilla::css::Declaration* aDeclaration,
|
||||
nsIDocument* aSheetDocument);
|
||||
|
||||
/**
|
||||
* Copies the values for aPropID into the specified aRuleData object.
|
||||
*
|
||||
* This is used for copying parsed-at-computed-value-time properties
|
||||
* that had variable references. aPropID must be a longhand property.
|
||||
*/
|
||||
void MapRuleInfoInto(nsCSSProperty aPropID, nsRuleData* aRuleData) const;
|
||||
/**
|
||||
* Copies the values for aPropID into the specified aRuleData object.
|
||||
*
|
||||
* This is used for copying parsed-at-computed-value-time properties
|
||||
* that had variable references. aPropID must be a longhand property.
|
||||
*/
|
||||
void MapRuleInfoInto(nsCSSProperty aPropID, nsRuleData* aRuleData) const;
|
||||
|
||||
void AssertInitialState() {
|
||||
void AssertInitialState() {
|
||||
#ifdef DEBUG
|
||||
DoAssertInitialState();
|
||||
DoAssertInitialState();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Compute the number of properties that will be present in the
|
||||
* result of |Compress|.
|
||||
*/
|
||||
void ComputeNumProps(uint32_t* aNumPropsNormal,
|
||||
uint32_t* aNumPropsImportant);
|
||||
|
||||
void DoExpand(nsCSSCompressedDataBlock *aBlock, bool aImportant);
|
||||
/**
|
||||
* Compute the number of properties that will be present in the
|
||||
* result of |Compress|.
|
||||
*/
|
||||
void ComputeNumProps(uint32_t* aNumPropsNormal,
|
||||
uint32_t* aNumPropsImportant);
|
||||
|
||||
/**
|
||||
* Worker for TransferFromBlock; cannot be used with shorthands.
|
||||
*/
|
||||
bool DoTransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
|
||||
nsCSSProperty aPropID,
|
||||
bool aIsImportant,
|
||||
bool aOverrideImportant,
|
||||
bool aMustCallValueAppended,
|
||||
mozilla::css::Declaration* aDeclaration,
|
||||
nsIDocument* aSheetDocument);
|
||||
void DoExpand(nsCSSCompressedDataBlock *aBlock, bool aImportant);
|
||||
|
||||
/**
|
||||
* Worker for TransferFromBlock; cannot be used with shorthands.
|
||||
*/
|
||||
bool DoTransferFromBlock(nsCSSExpandedDataBlock& aFromBlock,
|
||||
nsCSSProperty aPropID,
|
||||
bool aIsImportant,
|
||||
bool aOverrideImportant,
|
||||
bool aMustCallValueAppended,
|
||||
mozilla::css::Declaration* aDeclaration,
|
||||
nsIDocument* aSheetDocument);
|
||||
|
||||
#ifdef DEBUG
|
||||
void DoAssertInitialState();
|
||||
void DoAssertInitialState();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* mPropertiesSet stores a bit for every property that is present,
|
||||
* to optimize compression of blocks with small numbers of
|
||||
* properties (the norm) and to allow quickly checking whether a
|
||||
* property is set in this block.
|
||||
*/
|
||||
nsCSSPropertySet mPropertiesSet;
|
||||
/*
|
||||
* mPropertiesImportant indicates which properties are '!important'.
|
||||
*/
|
||||
nsCSSPropertySet mPropertiesImportant;
|
||||
/*
|
||||
* mPropertiesSet stores a bit for every property that is present,
|
||||
* to optimize compression of blocks with small numbers of
|
||||
* properties (the norm) and to allow quickly checking whether a
|
||||
* property is set in this block.
|
||||
*/
|
||||
nsCSSPropertySet mPropertiesSet;
|
||||
/*
|
||||
* mPropertiesImportant indicates which properties are '!important'.
|
||||
*/
|
||||
nsCSSPropertySet mPropertiesImportant;
|
||||
|
||||
/*
|
||||
* Return the storage location within |this| of the value of the
|
||||
* property |aProperty|.
|
||||
*/
|
||||
nsCSSValue* PropertyAt(nsCSSProperty aProperty) {
|
||||
MOZ_ASSERT(0 <= aProperty &&
|
||||
aProperty < eCSSProperty_COUNT_no_shorthands,
|
||||
"property out of range");
|
||||
return &mValues[aProperty];
|
||||
}
|
||||
const nsCSSValue* PropertyAt(nsCSSProperty aProperty) const {
|
||||
MOZ_ASSERT(0 <= aProperty &&
|
||||
aProperty < eCSSProperty_COUNT_no_shorthands,
|
||||
"property out of range");
|
||||
return &mValues[aProperty];
|
||||
}
|
||||
/*
|
||||
* Return the storage location within |this| of the value of the
|
||||
* property |aProperty|.
|
||||
*/
|
||||
nsCSSValue* PropertyAt(nsCSSProperty aProperty) {
|
||||
MOZ_ASSERT(0 <= aProperty &&
|
||||
aProperty < eCSSProperty_COUNT_no_shorthands,
|
||||
"property out of range");
|
||||
return &mValues[aProperty];
|
||||
}
|
||||
const nsCSSValue* PropertyAt(nsCSSProperty aProperty) const {
|
||||
MOZ_ASSERT(0 <= aProperty &&
|
||||
aProperty < eCSSProperty_COUNT_no_shorthands,
|
||||
"property out of range");
|
||||
return &mValues[aProperty];
|
||||
}
|
||||
|
||||
void SetPropertyBit(nsCSSProperty aProperty) {
|
||||
mPropertiesSet.AddProperty(aProperty);
|
||||
}
|
||||
void SetPropertyBit(nsCSSProperty aProperty) {
|
||||
mPropertiesSet.AddProperty(aProperty);
|
||||
}
|
||||
|
||||
void ClearPropertyBit(nsCSSProperty aProperty) {
|
||||
mPropertiesSet.RemoveProperty(aProperty);
|
||||
}
|
||||
void ClearPropertyBit(nsCSSProperty aProperty) {
|
||||
mPropertiesSet.RemoveProperty(aProperty);
|
||||
}
|
||||
|
||||
bool HasPropertyBit(nsCSSProperty aProperty) {
|
||||
return mPropertiesSet.HasProperty(aProperty);
|
||||
}
|
||||
bool HasPropertyBit(nsCSSProperty aProperty) {
|
||||
return mPropertiesSet.HasProperty(aProperty);
|
||||
}
|
||||
|
||||
void SetImportantBit(nsCSSProperty aProperty) {
|
||||
mPropertiesImportant.AddProperty(aProperty);
|
||||
}
|
||||
void SetImportantBit(nsCSSProperty aProperty) {
|
||||
mPropertiesImportant.AddProperty(aProperty);
|
||||
}
|
||||
|
||||
void ClearImportantBit(nsCSSProperty aProperty) {
|
||||
mPropertiesImportant.RemoveProperty(aProperty);
|
||||
}
|
||||
void ClearImportantBit(nsCSSProperty aProperty) {
|
||||
mPropertiesImportant.RemoveProperty(aProperty);
|
||||
}
|
||||
|
||||
bool HasImportantBit(nsCSSProperty aProperty) {
|
||||
return mPropertiesImportant.HasProperty(aProperty);
|
||||
}
|
||||
bool HasImportantBit(nsCSSProperty aProperty) {
|
||||
return mPropertiesImportant.HasProperty(aProperty);
|
||||
}
|
||||
|
||||
void ClearSets() {
|
||||
mPropertiesSet.Empty();
|
||||
mPropertiesImportant.Empty();
|
||||
}
|
||||
void ClearSets() {
|
||||
mPropertiesSet.Empty();
|
||||
mPropertiesImportant.Empty();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* !defined(nsCSSDataBlock_h__) */
|
||||
|
||||
+156
-39
@@ -62,6 +62,7 @@ typedef nsCSSProps::KTableEntry KTableEntry;
|
||||
// pref-backed bool values (hooked up in nsCSSParser::Startup)
|
||||
static bool sOpentypeSVGEnabled;
|
||||
static bool sWebkitPrefixedAliasesEnabled;
|
||||
static bool sWebkitDevicePixelRatioEnabled;
|
||||
static bool sUnprefixingServiceEnabled;
|
||||
#ifdef NIGHTLY_BUILD
|
||||
static bool sUnprefixingServiceGloballyWhitelisted;
|
||||
@@ -185,6 +186,10 @@ public:
|
||||
nsIPrincipal* aSheetPrincipal,
|
||||
nsCSSValue& aValue);
|
||||
|
||||
bool ParseTransformProperty(const nsAString& aPropValue,
|
||||
bool aDisallowRelativeValues,
|
||||
nsCSSValue& aResult);
|
||||
|
||||
void ParseMediaList(const nsSubstring& aBuffer,
|
||||
nsIURI* aURL, // for error reporting
|
||||
uint32_t aLineNumber, // for error reporting
|
||||
@@ -904,13 +909,13 @@ protected:
|
||||
bool ParseBorderStyle();
|
||||
bool ParseBorderWidth();
|
||||
|
||||
bool ParseCalc(nsCSSValue &aValue, int32_t aVariantMask);
|
||||
bool ParseCalc(nsCSSValue &aValue, uint32_t aVariantMask);
|
||||
bool ParseCalcAdditiveExpression(nsCSSValue& aValue,
|
||||
int32_t& aVariantMask);
|
||||
uint32_t& aVariantMask);
|
||||
bool ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
|
||||
int32_t& aVariantMask,
|
||||
bool *aHadFinalWS);
|
||||
bool ParseCalcTerm(nsCSSValue& aValue, int32_t& aVariantMask);
|
||||
uint32_t& aVariantMask,
|
||||
bool *aHadFinalWS);
|
||||
bool ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask);
|
||||
bool RequireWhitespace();
|
||||
|
||||
// For "flex" shorthand property, defined in CSS Flexbox spec
|
||||
@@ -1021,7 +1026,7 @@ protected:
|
||||
bool ParseListStyleType(nsCSSValue& aValue);
|
||||
bool ParseMargin();
|
||||
bool ParseClipPath();
|
||||
bool ParseTransform(bool aIsPrefixed);
|
||||
bool ParseTransform(bool aIsPrefixed, bool aDisallowRelativeValues = false);
|
||||
bool ParseObjectPosition();
|
||||
bool ParseOutline();
|
||||
bool ParseOverflow();
|
||||
@@ -1146,7 +1151,7 @@ protected:
|
||||
|
||||
// Variant parsing methods
|
||||
CSSParseResult ParseVariant(nsCSSValue& aValue,
|
||||
int32_t aVariantMask,
|
||||
uint32_t aVariantMask,
|
||||
const KTableEntry aKeywordTable[]);
|
||||
CSSParseResult ParseVariantWithRestrictions(nsCSSValue& aValue,
|
||||
int32_t aVariantMask,
|
||||
@@ -1242,7 +1247,7 @@ protected:
|
||||
bool ParseAttr(nsCSSValue& aValue);
|
||||
bool ParseSymbols(nsCSSValue& aValue);
|
||||
bool SetValueToURL(nsCSSValue& aValue, const nsString& aURL);
|
||||
bool TranslateDimension(nsCSSValue& aValue, int32_t aVariantMask,
|
||||
bool TranslateDimension(nsCSSValue& aValue, uint32_t aVariantMask,
|
||||
float aNumber, const nsString& aUnit);
|
||||
bool ParseImageOrientation(nsCSSValue& aAngle);
|
||||
bool ParseImageRect(nsCSSValue& aImage);
|
||||
@@ -1295,12 +1300,13 @@ protected:
|
||||
bool ParseInsetFunction(nsCSSValue& aValue);
|
||||
|
||||
/* Functions for transform Parsing */
|
||||
bool ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue);
|
||||
bool ParseFunction(nsCSSKeyword aFunction, const int32_t aAllowedTypes[],
|
||||
int32_t aVariantMaskAll, uint16_t aMinElems,
|
||||
bool ParseSingleTransform(bool aIsPrefixed, bool aDisallowRelativeValues,
|
||||
nsCSSValue& aValue);
|
||||
bool ParseFunction(nsCSSKeyword aFunction, const uint32_t aAllowedTypes[],
|
||||
uint32_t aVariantMaskAll, uint16_t aMinElems,
|
||||
uint16_t aMaxElems, nsCSSValue &aValue);
|
||||
bool ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
int32_t aVariantMaskAll,
|
||||
bool ParseFunctionInternals(const uint32_t aVariantMask[],
|
||||
uint32_t aVariantMaskAll,
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue>& aOutput);
|
||||
@@ -1855,6 +1861,48 @@ CSSParserImpl::ParseLonghandProperty(const nsCSSProperty aPropID,
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseTransformProperty(const nsAString& aPropValue,
|
||||
bool aDisallowRelativeValues,
|
||||
nsCSSValue& aValue)
|
||||
{
|
||||
RefPtr<Declaration> declaration = new Declaration();
|
||||
declaration->InitializeEmpty();
|
||||
|
||||
mData.AssertInitialState();
|
||||
mTempData.AssertInitialState();
|
||||
|
||||
nsCSSScanner scanner(aPropValue, 0);
|
||||
css::ErrorReporter reporter(scanner, mSheet, mChildLoader, nullptr);
|
||||
InitScanner(scanner, reporter, nullptr, nullptr, nullptr);
|
||||
|
||||
bool parsedOK = ParseTransform(false, aDisallowRelativeValues);
|
||||
// We should now be at EOF
|
||||
if (parsedOK && GetToken(true)) {
|
||||
parsedOK = false;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
if (parsedOK) {
|
||||
declaration->ExpandTo(&mData);
|
||||
changed = mData.TransferFromBlock(mTempData, eCSSProperty_transform,
|
||||
PropertyEnabledState(), false,
|
||||
true, false, declaration,
|
||||
GetDocument());
|
||||
declaration->CompressFrom(&mData);
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
aValue = *declaration->GetNormalBlock()->ValueFor(eCSSProperty_transform);
|
||||
} else {
|
||||
aValue.Reset();
|
||||
}
|
||||
|
||||
ReleaseScanner();
|
||||
|
||||
return parsedOK;
|
||||
}
|
||||
|
||||
void
|
||||
CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
|
||||
const nsAString& aPropValue,
|
||||
@@ -3485,6 +3533,9 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery)
|
||||
satisfiedReqFlags |= nsMediaFeature::eHasWebkitPrefix;
|
||||
featureString.Rebind(featureString, 8);
|
||||
}
|
||||
if (sWebkitDevicePixelRatioEnabled) {
|
||||
satisfiedReqFlags |= nsMediaFeature::eWebkitDevicePixelRatioPrefEnabled;
|
||||
}
|
||||
|
||||
// Strip off "min-"/"max-" prefix from featureString:
|
||||
if (StringBeginsWith(featureString, NS_LITERAL_STRING("min-"))) {
|
||||
@@ -7337,7 +7388,7 @@ const UnitInfo UnitData[] = {
|
||||
|
||||
bool
|
||||
CSSParserImpl::TranslateDimension(nsCSSValue& aValue,
|
||||
int32_t aVariantMask,
|
||||
uint32_t aVariantMask,
|
||||
float aNumber,
|
||||
const nsString& aUnit)
|
||||
{
|
||||
@@ -7368,6 +7419,11 @@ CSSParserImpl::TranslateDimension(nsCSSValue& aValue,
|
||||
// inside an @page declaration. Fail.
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((VARIANT_ABSOLUTE_DIMENSION & aVariantMask) != 0 &&
|
||||
!nsCSSValue::IsPixelLengthUnit(units)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Must be a zero number...
|
||||
NS_ASSERTION(0 == aNumber, "numbers without units must be 0");
|
||||
@@ -7513,7 +7569,7 @@ CSSParserImpl::ParseOneOrLargerVariant(nsCSSValue& aValue,
|
||||
// Assigns to aValue iff it returns CSSParseResult::Ok.
|
||||
CSSParseResult
|
||||
CSSParserImpl::ParseVariant(nsCSSValue& aValue,
|
||||
int32_t aVariantMask,
|
||||
uint32_t aVariantMask,
|
||||
const KTableEntry aKeywordTable[])
|
||||
{
|
||||
NS_ASSERTION(!(mHashlessColorQuirk && (aVariantMask & VARIANT_COLOR)) ||
|
||||
@@ -9900,10 +9956,16 @@ CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue,
|
||||
if (haveGradientLine) {
|
||||
// Parse a <legacy-gradient-line>
|
||||
cssGradient->mIsLegacySyntax = true;
|
||||
bool haveAngle =
|
||||
ParseSingleTokenVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr);
|
||||
// In -webkit-linear-gradient expressions (handled below), we need to accept
|
||||
// unitless 0 for angles, to match WebKit/Blink.
|
||||
int32_t angleFlags = (aFlags & eGradient_WebkitLegacy) ?
|
||||
VARIANT_ANGLE | VARIANT_ZERO_ANGLE :
|
||||
VARIANT_ANGLE;
|
||||
|
||||
// if we got an angle, we might now have a comma, ending the gradient-line
|
||||
bool haveAngle =
|
||||
ParseSingleTokenVariant(cssGradient->mAngle, angleFlags, nullptr);
|
||||
|
||||
// If we got an angle, we might now have a comma, ending the gradient-line.
|
||||
bool haveAngleComma = haveAngle && ExpectSymbol(',', true);
|
||||
|
||||
// If we're webkit-prefixed & didn't get an angle,
|
||||
@@ -12840,7 +12902,7 @@ CSSParserImpl::ParseBorderColors(nsCSSProperty aProperty)
|
||||
|
||||
// Parse the top level of a calc() expression.
|
||||
bool
|
||||
CSSParserImpl::ParseCalc(nsCSSValue &aValue, int32_t aVariantMask)
|
||||
CSSParserImpl::ParseCalc(nsCSSValue &aValue, uint32_t aVariantMask)
|
||||
{
|
||||
// Parsing calc expressions requires, in a number of cases, looking
|
||||
// for a token that is *either* a value of the property or a number.
|
||||
@@ -12888,7 +12950,7 @@ CSSParserImpl::ParseCalc(nsCSSValue &aValue, int32_t aVariantMask)
|
||||
// data structure.
|
||||
bool
|
||||
CSSParserImpl::ParseCalcAdditiveExpression(nsCSSValue& aValue,
|
||||
int32_t& aVariantMask)
|
||||
uint32_t& aVariantMask)
|
||||
{
|
||||
MOZ_ASSERT(aVariantMask != 0, "unexpected variant mask");
|
||||
nsCSSValue *storage = &aValue;
|
||||
@@ -12948,7 +13010,7 @@ struct ReduceNumberCalcOps : public mozilla::css::BasicFloatCalcOps,
|
||||
// aHadFinalWS parameter.
|
||||
bool
|
||||
CSSParserImpl::ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
|
||||
int32_t& aVariantMask,
|
||||
uint32_t& aVariantMask,
|
||||
bool *aHadFinalWS)
|
||||
{
|
||||
MOZ_ASSERT(aVariantMask != 0, "unexpected variant mask");
|
||||
@@ -12957,7 +13019,7 @@ CSSParserImpl::ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
|
||||
|
||||
nsCSSValue *storage = &aValue;
|
||||
for (;;) {
|
||||
int32_t variantMask;
|
||||
uint32_t variantMask;
|
||||
if (afterDivision || gotValue) {
|
||||
variantMask = VARIANT_NUMBER;
|
||||
} else {
|
||||
@@ -13045,7 +13107,7 @@ CSSParserImpl::ParseCalcMultiplicativeExpression(nsCSSValue& aValue,
|
||||
// aVariantMask*** to reflect which one it has parsed by either
|
||||
// removing VARIANT_NUMBER or removing all other bits.
|
||||
bool
|
||||
CSSParserImpl::ParseCalcTerm(nsCSSValue& aValue, int32_t& aVariantMask)
|
||||
CSSParserImpl::ParseCalcTerm(nsCSSValue& aValue, uint32_t& aVariantMask)
|
||||
{
|
||||
MOZ_ASSERT(aVariantMask != 0, "unexpected variant mask");
|
||||
if (!GetToken(true))
|
||||
@@ -14969,8 +15031,8 @@ CSSParserImpl::ParseTextCombineUpright(nsCSSValue& aValue)
|
||||
* ParseFunction.
|
||||
*/
|
||||
bool
|
||||
CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
int32_t aVariantMaskAll,
|
||||
CSSParserImpl::ParseFunctionInternals(const uint32_t aVariantMask[],
|
||||
uint32_t aVariantMaskAll,
|
||||
uint16_t aMinElems,
|
||||
uint16_t aMaxElems,
|
||||
InfallibleTArray<nsCSSValue> &aOutput)
|
||||
@@ -14981,7 +15043,7 @@ CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
|
||||
for (uint16_t index = 0; index < aMaxElems; ++index) {
|
||||
nsCSSValue newValue;
|
||||
int32_t m = aVariantMaskAll ? aVariantMaskAll : aVariantMask[index];
|
||||
uint32_t m = aVariantMaskAll ? aVariantMaskAll : aVariantMask[index];
|
||||
if (ParseVariant(newValue, m, nullptr) != CSSParseResult::Ok) {
|
||||
break;
|
||||
}
|
||||
@@ -15029,8 +15091,8 @@ CSSParserImpl::ParseFunctionInternals(const int32_t aVariantMask[],
|
||||
*/
|
||||
bool
|
||||
CSSParserImpl::ParseFunction(nsCSSKeyword aFunction,
|
||||
const int32_t aAllowedTypes[],
|
||||
int32_t aAllowedTypesAll,
|
||||
const uint32_t aAllowedTypes[],
|
||||
uint32_t aAllowedTypesAll,
|
||||
uint16_t aMinElems, uint16_t aMaxElems,
|
||||
nsCSSValue &aValue)
|
||||
{
|
||||
@@ -15081,6 +15143,10 @@ CSSParserImpl::ParseFunction(nsCSSKeyword aFunction,
|
||||
* returns an error.
|
||||
*
|
||||
* @param aToken The token identifying the function.
|
||||
* @param aIsPrefixed If true, parse matrices using the matrix syntax
|
||||
* for -moz-transform.
|
||||
* @param aDisallowRelativeValues If true, only allow variants that are
|
||||
* numbers or have non-relative dimensions.
|
||||
* @param aMinElems [out] The minimum number of elements to read.
|
||||
* @param aMaxElems [out] The maximum number of elements to read
|
||||
* @param aVariantMask [out] The variant mask to use during parsing
|
||||
@@ -15088,9 +15154,10 @@ CSSParserImpl::ParseFunction(nsCSSKeyword aFunction,
|
||||
*/
|
||||
static bool GetFunctionParseInformation(nsCSSKeyword aToken,
|
||||
bool aIsPrefixed,
|
||||
bool aDisallowRelativeValues,
|
||||
uint16_t &aMinElems,
|
||||
uint16_t &aMaxElems,
|
||||
const int32_t *& aVariantMask)
|
||||
const uint32_t *& aVariantMask)
|
||||
{
|
||||
/* These types represent the common variant masks that will be used to
|
||||
* parse out the individual functions. The order in the enumeration
|
||||
@@ -15098,12 +15165,16 @@ static bool GetFunctionParseInformation(nsCSSKeyword aToken,
|
||||
*/
|
||||
enum { eLengthPercentCalc,
|
||||
eLengthCalc,
|
||||
eAbsoluteLengthCalc,
|
||||
eTwoLengthPercentCalcs,
|
||||
eTwoAbsoluteLengthCalcs,
|
||||
eTwoLengthPercentCalcsOneLengthCalc,
|
||||
eThreeAbsoluteLengthCalc,
|
||||
eAngle,
|
||||
eTwoAngles,
|
||||
eNumber,
|
||||
ePositiveLength,
|
||||
ePositiveAbsoluteLength,
|
||||
eTwoNumbers,
|
||||
eThreeNumbers,
|
||||
eThreeNumbersOneAngle,
|
||||
@@ -15113,15 +15184,19 @@ static bool GetFunctionParseInformation(nsCSSKeyword aToken,
|
||||
eMatrix3dPrefixed,
|
||||
eNumVariantMasks };
|
||||
static const int32_t kMaxElemsPerFunction = 16;
|
||||
static const int32_t kVariantMasks[eNumVariantMasks][kMaxElemsPerFunction] = {
|
||||
static const uint32_t kVariantMasks[eNumVariantMasks][kMaxElemsPerFunction] = {
|
||||
{VARIANT_LPCALC},
|
||||
{VARIANT_LENGTH|VARIANT_CALC},
|
||||
{VARIANT_LCALC},
|
||||
{VARIANT_LB},
|
||||
{VARIANT_LPCALC, VARIANT_LPCALC},
|
||||
{VARIANT_LPCALC, VARIANT_LPCALC, VARIANT_LENGTH|VARIANT_CALC},
|
||||
{VARIANT_LBCALC, VARIANT_LBCALC},
|
||||
{VARIANT_LPCALC, VARIANT_LPCALC, VARIANT_LCALC},
|
||||
{VARIANT_LBCALC, VARIANT_LBCALC, VARIANT_LBCALC},
|
||||
{VARIANT_ANGLE_OR_ZERO},
|
||||
{VARIANT_ANGLE_OR_ZERO, VARIANT_ANGLE_OR_ZERO},
|
||||
{VARIANT_NUMBER},
|
||||
{VARIANT_LENGTH|VARIANT_POSITIVE_DIMENSION},
|
||||
{VARIANT_LB|VARIANT_POSITIVE_DIMENSION},
|
||||
{VARIANT_NUMBER, VARIANT_NUMBER},
|
||||
{VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER},
|
||||
{VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_ANGLE_OR_ZERO},
|
||||
@@ -15137,10 +15212,31 @@ static bool GetFunctionParseInformation(nsCSSKeyword aToken,
|
||||
VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
|
||||
VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER, VARIANT_NUMBER,
|
||||
VARIANT_LPNCALC, VARIANT_LPNCALC, VARIANT_LNCALC, VARIANT_NUMBER}};
|
||||
// Map from a mask to a congruent mask that excludes relative variants.
|
||||
static const int32_t kNonRelativeVariantMap[eNumVariantMasks] = {
|
||||
eAbsoluteLengthCalc,
|
||||
eAbsoluteLengthCalc,
|
||||
eAbsoluteLengthCalc,
|
||||
eTwoAbsoluteLengthCalcs,
|
||||
eTwoAbsoluteLengthCalcs,
|
||||
eThreeAbsoluteLengthCalc,
|
||||
eThreeAbsoluteLengthCalc,
|
||||
eAngle,
|
||||
eTwoAngles,
|
||||
eNumber,
|
||||
ePositiveAbsoluteLength,
|
||||
ePositiveAbsoluteLength,
|
||||
eTwoNumbers,
|
||||
eThreeNumbers,
|
||||
eThreeNumbersOneAngle,
|
||||
eMatrix,
|
||||
eMatrix,
|
||||
eMatrix3d,
|
||||
eMatrix3d };
|
||||
|
||||
#ifdef DEBUG
|
||||
static const uint8_t kVariantMaskLengths[eNumVariantMasks] =
|
||||
{1, 1, 2, 3, 1, 2, 1, 1, 2, 3, 4, 6, 6, 16, 16};
|
||||
{1, 1, 1, 2, 2, 3, 3, 1, 2, 1, 1, 1, 2, 3, 4, 6, 6, 16, 16};
|
||||
#endif
|
||||
|
||||
int32_t variantIndex = eNumVariantMasks;
|
||||
@@ -15246,6 +15342,10 @@ static bool GetFunctionParseInformation(nsCSSKeyword aToken,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aDisallowRelativeValues) {
|
||||
variantIndex = kNonRelativeVariantMap[variantIndex];
|
||||
}
|
||||
|
||||
NS_ASSERTION(aMinElems > 0, "Didn't update minimum elements!");
|
||||
NS_ASSERTION(aMaxElems > 0, "Didn't update maximum elements!");
|
||||
NS_ASSERTION(aMinElems <= aMaxElems, "aMinElems > aMaxElems!");
|
||||
@@ -15318,7 +15418,9 @@ bool CSSParserImpl::ParseWillChange()
|
||||
* error if something goes wrong.
|
||||
*/
|
||||
bool
|
||||
CSSParserImpl::ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue)
|
||||
CSSParserImpl::ParseSingleTransform(bool aIsPrefixed,
|
||||
bool aDisallowRelativeValues,
|
||||
nsCSSValue& aValue)
|
||||
{
|
||||
if (!GetToken(true))
|
||||
return false;
|
||||
@@ -15328,12 +15430,14 @@ CSSParserImpl::ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
const int32_t* variantMask;
|
||||
const uint32_t* variantMask;
|
||||
uint16_t minElems, maxElems;
|
||||
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
|
||||
|
||||
if (!GetFunctionParseInformation(keyword, aIsPrefixed,
|
||||
minElems, maxElems, variantMask))
|
||||
aDisallowRelativeValues,
|
||||
minElems, maxElems,
|
||||
variantMask))
|
||||
return false;
|
||||
|
||||
return ParseFunction(keyword, variantMask, 0, minElems, maxElems, aValue);
|
||||
@@ -15342,7 +15446,8 @@ CSSParserImpl::ParseSingleTransform(bool aIsPrefixed, nsCSSValue& aValue)
|
||||
/* Parses a transform property list by continuously reading in properties
|
||||
* and constructing a matrix from it.
|
||||
*/
|
||||
bool CSSParserImpl::ParseTransform(bool aIsPrefixed)
|
||||
bool
|
||||
CSSParserImpl::ParseTransform(bool aIsPrefixed, bool aDisallowRelativeValues)
|
||||
{
|
||||
nsCSSValue value;
|
||||
// 'inherit', 'initial', 'unset' and 'none' must be alone
|
||||
@@ -15353,7 +15458,8 @@ bool CSSParserImpl::ParseTransform(bool aIsPrefixed)
|
||||
list->mHead = new nsCSSValueList;
|
||||
nsCSSValueList* cur = list->mHead;
|
||||
for (;;) {
|
||||
if (!ParseSingleTransform(aIsPrefixed, cur->mValue)) {
|
||||
if (!ParseSingleTransform(aIsPrefixed, aDisallowRelativeValues,
|
||||
cur->mValue)) {
|
||||
return false;
|
||||
}
|
||||
if (CheckEndProperty()) {
|
||||
@@ -15727,7 +15833,7 @@ CSSParserImpl::ParseSingleFilter(nsCSSValue* aValue)
|
||||
}
|
||||
|
||||
// Set up the parsing rules based on the filter function.
|
||||
int32_t variantMask = VARIANT_PN;
|
||||
uint32_t variantMask = VARIANT_PN;
|
||||
bool rejectNegativeArgument = true;
|
||||
bool clampArgumentToOne = false;
|
||||
switch (functionName) {
|
||||
@@ -16996,6 +17102,8 @@ nsCSSParser::Startup()
|
||||
"gfx.font_rendering.opentype_svg.enabled");
|
||||
Preferences::AddBoolVarCache(&sWebkitPrefixedAliasesEnabled,
|
||||
"layout.css.prefixes.webkit");
|
||||
Preferences::AddBoolVarCache(&sWebkitDevicePixelRatioEnabled,
|
||||
"layout.css.prefixes.device-pixel-ratio-webkit");
|
||||
Preferences::AddBoolVarCache(&sUnprefixingServiceEnabled,
|
||||
"layout.css.unprefixing-service.enabled");
|
||||
#ifdef NIGHTLY_BUILD
|
||||
@@ -17153,6 +17261,15 @@ nsCSSParser::ParseLonghandProperty(const nsCSSProperty aPropID,
|
||||
aSheetPrincipal, aResult);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSParser::ParseTransformProperty(const nsAString& aPropValue,
|
||||
bool aDisallowRelativeValues,
|
||||
nsCSSValue& aResult)
|
||||
{
|
||||
return static_cast<CSSParserImpl*>(mImpl)->
|
||||
ParseTransformProperty(aPropValue, aDisallowRelativeValues, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSParser::ParseVariable(const nsAString& aVariableName,
|
||||
const nsAString& aPropValue,
|
||||
|
||||
@@ -145,6 +145,15 @@ public:
|
||||
nsIPrincipal* aSheetPrincipal,
|
||||
nsCSSValue& aResult);
|
||||
|
||||
// Parse the value of a CSS transform property. Returns
|
||||
// whether the value was successfully parsed. If
|
||||
// aDisallowRelativeValues is true then this method will
|
||||
// only successfully parse if all values are numbers or
|
||||
// have non-relative dimensions.
|
||||
bool ParseTransformProperty(const nsAString& aPropValue,
|
||||
bool aDisallowRelativeValues,
|
||||
nsCSSValue& aResult);
|
||||
|
||||
// The same as ParseProperty but for a variable.
|
||||
void ParseVariable(const nsAString& aVariableName,
|
||||
const nsAString& aPropValue,
|
||||
|
||||
@@ -1644,6 +1644,22 @@ CSS_PROP_POSITION(
|
||||
kFlexDirectionKTable,
|
||||
offsetof(nsStylePosition, mFlexDirection),
|
||||
eStyleAnimType_EnumU8)
|
||||
/* We treat -webkit-box-orient as a writing-mode-aware logical alias
|
||||
* for "flex-direction": */
|
||||
CSS_PROP_LOGICAL(
|
||||
-webkit-box-orient,
|
||||
webkit_box_orient,
|
||||
WebkitBoxOrient,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_LOGICAL |
|
||||
CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING,
|
||||
"layout.css.prefixes.webkit",
|
||||
VARIANT_HK,
|
||||
kBoxOrientKTable,
|
||||
WebkitBoxOrient,
|
||||
Position,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_SHORTHAND(
|
||||
flex-flow,
|
||||
flex_flow,
|
||||
|
||||
@@ -44,6 +44,17 @@
|
||||
// defined in nCSSProps.cpp named g<name_>LogicalGroupTable
|
||||
// containing the two physical properties in vertical/horizontal
|
||||
// order, followed by an nsCSSProperty_UNKNOWN entry.
|
||||
//
|
||||
// CSS_PROP_LOGICAL_GROUP_SINGLE(name_)
|
||||
// Defines a logical property group in which the logical property always
|
||||
// maps to the same physical property. For such properties, the
|
||||
// "logicalness" is in the value-mapping, not in the property-mapping. For
|
||||
// example, the logical property "-webkit-box-orient" is always mapped to
|
||||
// "flex-direction", but its values ("horizontal", "vertical") map to
|
||||
// different flex-direction values ("row", "column") depending on the
|
||||
// writing-mode. A table must be defined in nsCSSProps.cpp named
|
||||
// g<name_>LogicalGroupTable containing the one physical property,
|
||||
// followed by an nsCSSProperty_UNKNOWN entry.
|
||||
|
||||
CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderColor)
|
||||
CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderStyle)
|
||||
@@ -54,3 +65,4 @@ CSS_PROP_LOGICAL_GROUP_BOX(Offset)
|
||||
CSS_PROP_LOGICAL_GROUP_SHORTHAND(Padding)
|
||||
CSS_PROP_LOGICAL_GROUP_AXIS(MinSize)
|
||||
CSS_PROP_LOGICAL_GROUP_AXIS(Size)
|
||||
CSS_PROP_LOGICAL_GROUP_SINGLE(WebkitBoxOrient)
|
||||
|
||||
@@ -103,10 +103,13 @@ enum nsCSSPropertyLogicalGroup {
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#define CSS_PROP_LOGICAL_GROUP_BOX(name_) \
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#define CSS_PROP_LOGICAL_GROUP_SINGLE(name_) \
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#define CSS_PROP_LOGICAL_GROUP_SHORTHAND(name_) \
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#include "nsCSSPropLogicalGroupList.h"
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SHORTHAND
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SINGLE
|
||||
#undef CSS_PROP_LOGICAL_GROUP_BOX
|
||||
#undef CSS_PROP_LOGICAL_GROUP_AXIS
|
||||
eCSSPropertyLogicalGroup_COUNT
|
||||
|
||||
@@ -2881,12 +2881,19 @@ static const nsCSSProperty gSizeLogicalGroupTable[] = {
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
static const nsCSSProperty gWebkitBoxOrientLogicalGroupTable[] = {
|
||||
eCSSProperty_flex_direction,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
const nsCSSProperty* const
|
||||
nsCSSProps::kLogicalGroupTable[eCSSPropertyLogicalGroup_COUNT] = {
|
||||
#define CSS_PROP_LOGICAL_GROUP_SHORTHAND(id_) g##id_##SubpropTable,
|
||||
#define CSS_PROP_LOGICAL_GROUP_AXIS(name_) g##name_##LogicalGroupTable,
|
||||
#define CSS_PROP_LOGICAL_GROUP_BOX(name_) g##name_##LogicalGroupTable,
|
||||
#define CSS_PROP_LOGICAL_GROUP_SINGLE(name_) g##name_##LogicalGroupTable,
|
||||
#include "nsCSSPropLogicalGroupList.h"
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SINGLE
|
||||
#undef CSS_PROP_LOGICAL_GROUP_BOX
|
||||
#undef CSS_PROP_LOGICAL_GROUP_AXIS
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SHORTHAND
|
||||
@@ -3187,7 +3194,10 @@ nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = {
|
||||
"the CSS_PROPERTY_LOGICAL_BLOCK_AXIS flag"); \
|
||||
static_assert(!((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE), \
|
||||
"only properties defined with CSS_PROP_LOGICAL can use " \
|
||||
"the CSS_PROPERTY_LOGICAL_END_EDGE flag");
|
||||
"the CSS_PROPERTY_LOGICAL_END_EDGE flag"); \
|
||||
static_assert(!((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING),\
|
||||
"only properties defined with CSS_PROP_LOGICAL can use " \
|
||||
"the CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING flag");
|
||||
#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \
|
||||
kwtable_, group_, stylestruct_, \
|
||||
stylestructoffset_, animtype_) \
|
||||
@@ -3200,7 +3210,21 @@ nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = {
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_AXIS) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE)), \
|
||||
"CSS_PROPERTY_LOGICAL_END_EDGE makes no sense when used " \
|
||||
"with CSS_PROPERTY_LOGICAL_AXIS");
|
||||
"with CSS_PROPERTY_LOGICAL_AXIS"); \
|
||||
/* Make sure CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING isn't used */ \
|
||||
/* with other mutually-exclusive flags: */ \
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_AXIS) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\
|
||||
"CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \
|
||||
"sense when used with CSS_PROPERTY_LOGICAL_AXIS"); \
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_BLOCK_AXIS) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\
|
||||
"CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \
|
||||
"sense when used with CSS_PROPERTY_LOGICAL_BLOCK_AXIS"); \
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\
|
||||
"CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \
|
||||
"sense when used with CSS_PROPERTY_LOGICAL_END_EDGE");
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP_LOGICAL
|
||||
#undef CSS_PROP
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#define VARIANT_NONNEGATIVE_DIMENSION 0x20000000 // Only lengths greater than or equal to 0.0
|
||||
// Keyword used iff gfx.font_rendering.opentype_svg.enabled is true:
|
||||
#define VARIANT_OPENTYPE_SVG_KEYWORD 0x40000000
|
||||
#define VARIANT_ABSOLUTE_DIMENSION 0x80000000 // B Only lengths with absolute length unit
|
||||
|
||||
// Variants that can consume more than one token
|
||||
#define VARIANT_MULTIPLE_TOKENS \
|
||||
@@ -106,6 +107,8 @@
|
||||
#define VARIANT_UK (VARIANT_URL | VARIANT_KEYWORD)
|
||||
#define VARIANT_UO (VARIANT_URL | VARIANT_NONE)
|
||||
#define VARIANT_ANGLE_OR_ZERO (VARIANT_ANGLE | VARIANT_ZERO_ANGLE)
|
||||
#define VARIANT_LB (VARIANT_LENGTH | VARIANT_ABSOLUTE_DIMENSION)
|
||||
#define VARIANT_LBCALC (VARIANT_LB | VARIANT_CALC)
|
||||
#define VARIANT_LCALC (VARIANT_LENGTH | VARIANT_CALC)
|
||||
#define VARIANT_LPCALC (VARIANT_LCALC | VARIANT_PERCENT)
|
||||
#define VARIANT_LNCALC (VARIANT_LCALC | VARIANT_NUMBER)
|
||||
@@ -247,20 +250,26 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK &
|
||||
// margin-block-start or margin-inline-start).
|
||||
#define CSS_PROPERTY_LOGICAL_END_EDGE (1<<26)
|
||||
|
||||
// This property is a logical property which always maps to the same physical
|
||||
// property, and its values have some custom processing when being mapped to
|
||||
// the physical property's values. Must not be used in conjunction with
|
||||
// CSS_PROPERTY_LOGICAL_{AXIS,BLOCK_AXIS,END_EDGE}.
|
||||
#define CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING (1<<27)
|
||||
|
||||
// This property can be animated on the compositor.
|
||||
#define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<27)
|
||||
#define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<28)
|
||||
|
||||
// This property is an internal property that is not represented
|
||||
// in the DOM. Properties with this flag must be defined in an #ifndef
|
||||
// CSS_PROP_LIST_EXCLUDE_INTERNAL section of nsCSSPropList.h.
|
||||
#define CSS_PROPERTY_INTERNAL (1<<28)
|
||||
#define CSS_PROPERTY_INTERNAL (1<<29)
|
||||
|
||||
// This property has values that can establish a containing block for
|
||||
// fixed positioned and absolutely positioned elements.
|
||||
// This should be set for any properties that can cause an element to be
|
||||
// such a containing block, as implemented in
|
||||
// nsStyleDisplay::IsFixedPosContainingBlock.
|
||||
#define CSS_PROPERTY_FIXPOS_CB (1<<29)
|
||||
#define CSS_PROPERTY_FIXPOS_CB (1<<30)
|
||||
|
||||
// This property has values that can establish a containing block for
|
||||
// absolutely positioned elements.
|
||||
@@ -269,7 +278,10 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK &
|
||||
// nsStyleDisplay::IsAbsPosContainingBlock.
|
||||
// It does not need to be set for properties that also have
|
||||
// CSS_PROPERTY_FIXPOS_CB set.
|
||||
#define CSS_PROPERTY_ABSPOS_CB (1<<30)
|
||||
#define CSS_PROPERTY_ABSPOS_CB (1u<<31)
|
||||
|
||||
// NOTE: Before adding any new CSS_PROPERTY_* flags here, we'll need to
|
||||
// upgrade kFlagsTable to 64-bits -- see bug 1231384.
|
||||
|
||||
/**
|
||||
* Types of animatable values.
|
||||
@@ -543,8 +555,11 @@ public:
|
||||
* by the sentinel.
|
||||
*
|
||||
* When called with a property that has the CSS_PROPERTY_LOGICAL_AXIS
|
||||
* flag, the returned array will have two values preceding the sentinel;
|
||||
* otherwise it will have four.
|
||||
* flag, the returned array will have two values preceding the sentinel.
|
||||
* When called with a property that has the
|
||||
* CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING flag, the returned array
|
||||
* will have one value preceding the sentinel.
|
||||
* Otherwise it will have four values preceding the sentinel.
|
||||
*
|
||||
* (Note that the running time of this function is proportional to the
|
||||
* number of logical longhand properties that exist. If we start
|
||||
|
||||
@@ -1168,16 +1168,6 @@ InitSystemMetrics()
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::mac_yosemite_theme);
|
||||
}
|
||||
|
||||
rv = LookAndFeel::GetInt(LookAndFeel::eIntID_WindowsAccentColorApplies, &metricResult);
|
||||
if (NS_SUCCEEDED(rv) && metricResult) {
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::windows_accent_color_applies);
|
||||
}
|
||||
|
||||
rv = LookAndFeel::GetInt(LookAndFeel::eIntID_WindowsAccentColorIsDark, &metricResult);
|
||||
if (NS_SUCCEEDED(rv) && metricResult) {
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::windows_accent_color_is_dark);
|
||||
}
|
||||
|
||||
rv = LookAndFeel::GetInt(LookAndFeel::eIntID_DWMCompositor, &metricResult);
|
||||
if (NS_SUCCEEDED(rv) && metricResult) {
|
||||
sSystemMetrics->AppendElement(nsGkAtoms::windows_compositor);
|
||||
|
||||
+47
-47
@@ -543,48 +543,48 @@ void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
|
||||
|
||||
void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
|
||||
{
|
||||
// triplet should not be used for null/inherit/initial values
|
||||
MOZ_ASSERT(aValue &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Initial &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Unset &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Unset,
|
||||
"missing or inappropriate triplet value");
|
||||
Reset();
|
||||
mUnit = eCSSUnit_Triplet;
|
||||
mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue);
|
||||
mValue.mTriplet->AddRef();
|
||||
// triplet should not be used for null/inherit/initial values
|
||||
MOZ_ASSERT(aValue &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Null &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Initial &&
|
||||
aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
|
||||
aValue->mYValue.GetUnit() != eCSSUnit_Unset &&
|
||||
aValue->mZValue.GetUnit() != eCSSUnit_Unset,
|
||||
"missing or inappropriate triplet value");
|
||||
Reset();
|
||||
mUnit = eCSSUnit_Triplet;
|
||||
mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue);
|
||||
mValue.mTriplet->AddRef();
|
||||
}
|
||||
|
||||
void nsCSSValue::SetTripletValue(const nsCSSValue& xValue,
|
||||
const nsCSSValue& yValue,
|
||||
const nsCSSValue& zValue)
|
||||
{
|
||||
// Only allow Null for the z component
|
||||
MOZ_ASSERT(xValue.GetUnit() != eCSSUnit_Null &&
|
||||
yValue.GetUnit() != eCSSUnit_Null &&
|
||||
xValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
yValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
zValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
xValue.GetUnit() != eCSSUnit_Initial &&
|
||||
yValue.GetUnit() != eCSSUnit_Initial &&
|
||||
zValue.GetUnit() != eCSSUnit_Initial &&
|
||||
xValue.GetUnit() != eCSSUnit_Unset &&
|
||||
yValue.GetUnit() != eCSSUnit_Unset &&
|
||||
zValue.GetUnit() != eCSSUnit_Unset,
|
||||
"inappropriate triplet value");
|
||||
Reset();
|
||||
mUnit = eCSSUnit_Triplet;
|
||||
mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue);
|
||||
mValue.mTriplet->AddRef();
|
||||
// Only allow Null for the z component
|
||||
MOZ_ASSERT(xValue.GetUnit() != eCSSUnit_Null &&
|
||||
yValue.GetUnit() != eCSSUnit_Null &&
|
||||
xValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
yValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
zValue.GetUnit() != eCSSUnit_Inherit &&
|
||||
xValue.GetUnit() != eCSSUnit_Initial &&
|
||||
yValue.GetUnit() != eCSSUnit_Initial &&
|
||||
zValue.GetUnit() != eCSSUnit_Initial &&
|
||||
xValue.GetUnit() != eCSSUnit_Unset &&
|
||||
yValue.GetUnit() != eCSSUnit_Unset &&
|
||||
zValue.GetUnit() != eCSSUnit_Unset,
|
||||
"inappropriate triplet value");
|
||||
Reset();
|
||||
mUnit = eCSSUnit_Triplet;
|
||||
mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue);
|
||||
mValue.mTriplet->AddRef();
|
||||
}
|
||||
|
||||
nsCSSRect& nsCSSValue::SetRectValue()
|
||||
@@ -1978,9 +1978,9 @@ nsCSSValueList::Clone() const
|
||||
void
|
||||
nsCSSValueList::CloneInto(nsCSSValueList* aList) const
|
||||
{
|
||||
NS_ASSERTION(!aList->mNext, "Must be an empty list!");
|
||||
aList->mValue = mValue;
|
||||
aList->mNext = mNext ? mNext->Clone() : nullptr;
|
||||
NS_ASSERTION(!aList->mNext, "Must be an empty list!");
|
||||
aList->mValue = mValue;
|
||||
aList->mNext = mNext ? mNext->Clone() : nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2307,15 +2307,15 @@ nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty,
|
||||
nsAString& aResult,
|
||||
nsCSSValue::Serialization aSerialization) const
|
||||
{
|
||||
mXValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
if (mYValue.GetUnit() != eCSSUnit_Null) {
|
||||
aResult.Append(char16_t(' '));
|
||||
mYValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
if (mZValue.GetUnit() != eCSSUnit_Null) {
|
||||
aResult.Append(char16_t(' '));
|
||||
mZValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
}
|
||||
mXValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
if (mYValue.GetUnit() != eCSSUnit_Null) {
|
||||
aResult.Append(char16_t(' '));
|
||||
mYValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
if (mZValue.GetUnit() != eCSSUnit_Null) {
|
||||
aResult.Append(char16_t(' '));
|
||||
mZValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
@@ -468,8 +468,10 @@ public:
|
||||
/**
|
||||
* A "pixel" length unit is a some multiple of CSS pixels.
|
||||
*/
|
||||
static bool IsPixelLengthUnit(nsCSSUnit aUnit)
|
||||
{ return eCSSUnit_Point <= aUnit && aUnit <= eCSSUnit_Pixel; }
|
||||
bool IsPixelLengthUnit() const
|
||||
{ return eCSSUnit_Point <= mUnit && mUnit <= eCSSUnit_Pixel; }
|
||||
{ return IsPixelLengthUnit(mUnit); }
|
||||
bool IsAngularUnit() const
|
||||
{ return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
|
||||
bool IsFrequencyUnit() const
|
||||
@@ -1561,18 +1563,6 @@ public:
|
||||
uint32_t mLineOffset;
|
||||
mozilla::SheetType mLevel;
|
||||
|
||||
// This table is used to hold a reference on to any ImageValue that results
|
||||
// from re-parsing this token stream at computed value time. When properties
|
||||
// like background-image contain a normal url(), the Declaration's data block
|
||||
// will hold a reference to the ImageValue. When a token stream is used,
|
||||
// the Declaration only holds on to this nsCSSValueTokenStream object, and
|
||||
// the ImageValue would only exist for the duration of
|
||||
// nsRuleNode::WalkRuleTree, in the AutoCSSValueArray. So instead when
|
||||
// we re-parse a token stream and get an ImageValue, we record it in this
|
||||
// table so that the Declaration can be the object that keeps holding
|
||||
// a reference to it.
|
||||
nsTHashtable<nsRefPtrHashKey<mozilla::css::ImageValue> > mImageValues;
|
||||
|
||||
private:
|
||||
nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) = delete;
|
||||
nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) = delete;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set tw=78 expandtab softtabstop=2 ts=2 sw=2: */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -1284,29 +1284,29 @@ nsComputedDOMStyle::DoGetPerspectiveOrigin()
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetPerspective()
|
||||
{
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
SetValueToCoord(val, StyleDisplay()->mChildPerspective, false);
|
||||
return val.forget();
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
SetValueToCoord(val, StyleDisplay()->mChildPerspective, false);
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetBackfaceVisibility()
|
||||
{
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility,
|
||||
nsCSSProps::kBackfaceVisibilityKTable));
|
||||
return val.forget();
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility,
|
||||
nsCSSProps::kBackfaceVisibilityKTable));
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
nsComputedDOMStyle::DoGetTransformStyle()
|
||||
{
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle,
|
||||
nsCSSProps::kTransformStyleKTable));
|
||||
return val.forget();
|
||||
RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
|
||||
val->SetIdent(
|
||||
nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle,
|
||||
nsCSSProps::kTransformStyleKTable));
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
/* If the property is "none", hand back "none" wrapped in a value.
|
||||
@@ -1349,13 +1349,15 @@ nsComputedDOMStyle::DoGetTransform()
|
||||
nsSize(0, 0));
|
||||
|
||||
RuleNodeCacheConditions dummy;
|
||||
bool dummyBool;
|
||||
gfx::Matrix4x4 matrix =
|
||||
nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead,
|
||||
mStyleContext,
|
||||
mStyleContext->PresContext(),
|
||||
dummy,
|
||||
refBox,
|
||||
float(mozilla::AppUnitsPerCSSPixel()));
|
||||
float(mozilla::AppUnitsPerCSSPixel()),
|
||||
&dummyBool);
|
||||
|
||||
return MatrixToCSSValue(matrix);
|
||||
}
|
||||
|
||||
+538
-534
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -20,64 +21,71 @@ typedef nsresult
|
||||
const nsMediaFeature* aFeature,
|
||||
nsCSSValue& aResult);
|
||||
|
||||
struct nsMediaFeature {
|
||||
nsIAtom **mName; // extra indirection to point to nsGkAtoms members
|
||||
struct nsMediaFeature
|
||||
{
|
||||
nsIAtom **mName; // extra indirection to point to nsGkAtoms members
|
||||
|
||||
enum RangeType { eMinMaxAllowed, eMinMaxNotAllowed };
|
||||
RangeType mRangeType;
|
||||
enum RangeType { eMinMaxAllowed, eMinMaxNotAllowed };
|
||||
RangeType mRangeType;
|
||||
|
||||
enum ValueType {
|
||||
// All value types allow eCSSUnit_Null to indicate that no value
|
||||
// was given (in addition to the types listed below).
|
||||
eLength, // values are such that nsCSSValue::IsLengthUnit() is true
|
||||
eInteger, // values are eCSSUnit_Integer
|
||||
eFloat, // values are eCSSUnit_Number
|
||||
eBoolInteger,// values are eCSSUnit_Integer (0, -0, or 1 only)
|
||||
eIntRatio, // values are eCSSUnit_Array of two eCSSUnit_Integer
|
||||
eResolution, // values are in eCSSUnit_Inch (for dpi),
|
||||
// eCSSUnit_Pixel (for dppx), or
|
||||
// eCSSUnit_Centimeter (for dpcm)
|
||||
eEnumerated, // values are eCSSUnit_Enumerated (uses keyword table)
|
||||
eIdent // values are eCSSUnit_Ident
|
||||
// Note that a number of pieces of code (both for parsing and
|
||||
// for matching of valueless expressions) assume that all numeric
|
||||
// value types cannot be negative. The parsing code also does
|
||||
// not allow zeros in eIntRatio types.
|
||||
};
|
||||
ValueType mValueType;
|
||||
enum ValueType {
|
||||
// All value types allow eCSSUnit_Null to indicate that no value
|
||||
// was given (in addition to the types listed below).
|
||||
eLength, // values are such that nsCSSValue::IsLengthUnit() is true
|
||||
eInteger, // values are eCSSUnit_Integer
|
||||
eFloat, // values are eCSSUnit_Number
|
||||
eBoolInteger,// values are eCSSUnit_Integer (0, -0, or 1 only)
|
||||
eIntRatio, // values are eCSSUnit_Array of two eCSSUnit_Integer
|
||||
eResolution, // values are in eCSSUnit_Inch (for dpi),
|
||||
// eCSSUnit_Pixel (for dppx), or
|
||||
// eCSSUnit_Centimeter (for dpcm)
|
||||
eEnumerated, // values are eCSSUnit_Enumerated (uses keyword table)
|
||||
eIdent // values are eCSSUnit_Ident
|
||||
// Note that a number of pieces of code (both for parsing and
|
||||
// for matching of valueless expressions) assume that all numeric
|
||||
// value types cannot be negative. The parsing code also does
|
||||
// not allow zeros in eIntRatio types.
|
||||
};
|
||||
ValueType mValueType;
|
||||
|
||||
enum RequirementFlags : uint8_t {
|
||||
// Bitfield of requirements that must be satisfied in order for this
|
||||
// media feature to be active.
|
||||
eNoRequirements = 0,
|
||||
eHasWebkitPrefix = 1 // Feature name must start w/ "-webkit-", even
|
||||
// before any "min-"/"max-" qualifier.
|
||||
};
|
||||
uint8_t mReqFlags;
|
||||
enum RequirementFlags : uint8_t {
|
||||
// Bitfield of requirements that must be satisfied in order for this
|
||||
// media feature to be active.
|
||||
eNoRequirements = 0,
|
||||
eHasWebkitPrefix = 1 << 0, // Feature name must start w/ "-webkit-", even
|
||||
// before any "min-"/"max-" qualifier.
|
||||
|
||||
union {
|
||||
// In static arrays, it's the first member that's initialized. We
|
||||
// need that to be void* so we can initialize both other types.
|
||||
// This member should never be accessed by name.
|
||||
const void* mInitializer_;
|
||||
// If mValueType == eEnumerated: const int32_t*: keyword table in
|
||||
// the same format as the keyword tables in nsCSSProps.
|
||||
const nsCSSProps::KTableEntry* mKeywordTable;
|
||||
// If mGetter == GetSystemMetric (which implies mValueType ==
|
||||
// eBoolInteger): nsIAtom * const *, for the system metric.
|
||||
nsIAtom * const * mMetric;
|
||||
} mData;
|
||||
// Feature is only supported if the pref
|
||||
// "layout.css.prefixes.device-pixel-ratio-webkit" is enabled.
|
||||
// (Should only be used for -webkit-device-pixel-ratio.)
|
||||
eWebkitDevicePixelRatioPrefEnabled = 1 << 1
|
||||
};
|
||||
uint8_t mReqFlags;
|
||||
|
||||
// A function that returns the current value for this feature for a
|
||||
// given presentation. If it returns eCSSUnit_Null, the feature is
|
||||
// not present.
|
||||
nsMediaFeatureValueGetter mGetter;
|
||||
union {
|
||||
// In static arrays, it's the first member that's initialized. We
|
||||
// need that to be void* so we can initialize both other types.
|
||||
// This member should never be accessed by name.
|
||||
const void* mInitializer_;
|
||||
// If mValueType == eEnumerated: const int32_t*: keyword table in
|
||||
// the same format as the keyword tables in nsCSSProps.
|
||||
const nsCSSProps::KTableEntry* mKeywordTable;
|
||||
// If mGetter == GetSystemMetric (which implies mValueType ==
|
||||
// eBoolInteger): nsIAtom * const *, for the system metric.
|
||||
nsIAtom * const * mMetric;
|
||||
} mData;
|
||||
|
||||
// A function that returns the current value for this feature for a
|
||||
// given presentation. If it returns eCSSUnit_Null, the feature is
|
||||
// not present.
|
||||
nsMediaFeatureValueGetter mGetter;
|
||||
};
|
||||
|
||||
class nsMediaFeatures {
|
||||
class nsMediaFeatures
|
||||
{
|
||||
public:
|
||||
// Terminated with an entry whose mName is null.
|
||||
static const nsMediaFeature features[];
|
||||
// Terminated with an entry whose mName is null.
|
||||
static const nsMediaFeature features[];
|
||||
};
|
||||
|
||||
#endif /* !defined(nsMediaFeatures_h_) */
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -526,9 +527,9 @@ nsROCSSPrimitiveValue::GetRGBColorValue(ErrorResult& aRv)
|
||||
void
|
||||
nsROCSSPrimitiveValue::SetNumber(float aValue)
|
||||
{
|
||||
Reset();
|
||||
mValue.mFloat = aValue;
|
||||
mType = CSS_NUMBER;
|
||||
Reset();
|
||||
mValue.mFloat = aValue;
|
||||
mType = CSS_NUMBER;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/* the interface (to internal code) for retrieving computed style data */
|
||||
|
||||
#include "CSSVariableImageTable.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
@@ -167,6 +168,9 @@ nsStyleContext::~nsStyleContext()
|
||||
if (mCachedResetData) {
|
||||
mCachedResetData->Destroy(mBits, presContext);
|
||||
}
|
||||
|
||||
// Free any ImageValues we were holding on to for CSS variable values.
|
||||
CSSVariableImageTable::RemoveAll(this);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -600,7 +604,7 @@ nsStyleContext::ApplyStyleFixups(bool aSkipParentDisplayBasedStyleFixup)
|
||||
presContext->StyleSet()->ResolveStyleFor(docElement, nullptr);
|
||||
auto dir = rootStyle->StyleVisibility()->mDirection;
|
||||
if (dir != StyleVisibility()->mDirection) {
|
||||
nsStyleVisibility* uniqueVisibility =
|
||||
nsStyleVisibility* uniqueVisibility =
|
||||
(nsStyleVisibility*)GetUniqueStyleData(eStyleStruct_Visibility);
|
||||
uniqueVisibility->mDirection = dir;
|
||||
}
|
||||
@@ -1596,6 +1600,6 @@ nsStyleContext::Initialize()
|
||||
{
|
||||
Preferences::AddBoolVarCache(
|
||||
&sExpensiveStyleStructAssertionsEnabled,
|
||||
"layout.css.expensive-style-struct-assertions.enabed");
|
||||
"layout.css.expensive-style-struct-assertions.enabled");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -820,44 +821,43 @@ nsChangeHint nsStyleColumn::CalcDifference(const nsStyleColumn& aOther) const
|
||||
// --------------------
|
||||
// nsStyleSVG
|
||||
//
|
||||
nsStyleSVG::nsStyleSVG()
|
||||
nsStyleSVG::nsStyleSVG()
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleSVG);
|
||||
mFill.mType = eStyleSVGPaintType_Color;
|
||||
mFill.mPaint.mColor = NS_RGB(0,0,0);
|
||||
mFill.mFallbackColor = NS_RGB(0,0,0);
|
||||
mStroke.mType = eStyleSVGPaintType_None;
|
||||
mStroke.mPaint.mColor = NS_RGB(0,0,0);
|
||||
mStroke.mFallbackColor = NS_RGB(0,0,0);
|
||||
mStrokeDasharray = nullptr;
|
||||
MOZ_COUNT_CTOR(nsStyleSVG);
|
||||
mFill.mType = eStyleSVGPaintType_Color;
|
||||
mFill.mPaint.mColor = NS_RGB(0,0,0);
|
||||
mFill.mFallbackColor = NS_RGB(0,0,0);
|
||||
mStroke.mType = eStyleSVGPaintType_None;
|
||||
mStroke.mPaint.mColor = NS_RGB(0,0,0);
|
||||
mStroke.mFallbackColor = NS_RGB(0,0,0);
|
||||
mStrokeDasharray = nullptr;
|
||||
|
||||
mStrokeDashoffset.SetCoordValue(0);
|
||||
mStrokeWidth.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
|
||||
mStrokeDashoffset.SetCoordValue(0);
|
||||
mStrokeWidth.SetCoordValue(nsPresContext::CSSPixelsToAppUnits(1));
|
||||
|
||||
mFillOpacity = 1.0f;
|
||||
mStrokeMiterlimit = 4.0f;
|
||||
mStrokeOpacity = 1.0f;
|
||||
mFillOpacity = 1.0f;
|
||||
mStrokeMiterlimit = 4.0f;
|
||||
mStrokeOpacity = 1.0f;
|
||||
|
||||
mStrokeDasharrayLength = 0;
|
||||
mClipRule = NS_STYLE_FILL_RULE_NONZERO;
|
||||
mColorInterpolation = NS_STYLE_COLOR_INTERPOLATION_SRGB;
|
||||
mColorInterpolationFilters = NS_STYLE_COLOR_INTERPOLATION_LINEARRGB;
|
||||
mFillRule = NS_STYLE_FILL_RULE_NONZERO;
|
||||
mImageRendering = NS_STYLE_IMAGE_RENDERING_AUTO;
|
||||
mPaintOrder = NS_STYLE_PAINT_ORDER_NORMAL;
|
||||
mShapeRendering = NS_STYLE_SHAPE_RENDERING_AUTO;
|
||||
mStrokeLinecap = NS_STYLE_STROKE_LINECAP_BUTT;
|
||||
mStrokeLinejoin = NS_STYLE_STROKE_LINEJOIN_MITER;
|
||||
mTextAnchor = NS_STYLE_TEXT_ANCHOR_START;
|
||||
mTextRendering = NS_STYLE_TEXT_RENDERING_AUTO;
|
||||
mFillOpacitySource = eStyleSVGOpacitySource_Normal;
|
||||
mStrokeOpacitySource = eStyleSVGOpacitySource_Normal;
|
||||
mStrokeDasharrayFromObject = false;
|
||||
mStrokeDashoffsetFromObject = false;
|
||||
mStrokeWidthFromObject = false;
|
||||
}
|
||||
|
||||
nsStyleSVG::~nsStyleSVG()
|
||||
mStrokeDasharrayLength = 0;
|
||||
mClipRule = NS_STYLE_FILL_RULE_NONZERO;
|
||||
mColorInterpolation = NS_STYLE_COLOR_INTERPOLATION_SRGB;
|
||||
mColorInterpolationFilters = NS_STYLE_COLOR_INTERPOLATION_LINEARRGB;
|
||||
mFillRule = NS_STYLE_FILL_RULE_NONZERO;
|
||||
mImageRendering = NS_STYLE_IMAGE_RENDERING_AUTO;
|
||||
mPaintOrder = NS_STYLE_PAINT_ORDER_NORMAL;
|
||||
mShapeRendering = NS_STYLE_SHAPE_RENDERING_AUTO;
|
||||
mStrokeLinecap = NS_STYLE_STROKE_LINECAP_BUTT;
|
||||
mStrokeLinejoin = NS_STYLE_STROKE_LINEJOIN_MITER;
|
||||
mTextAnchor = NS_STYLE_TEXT_ANCHOR_START;
|
||||
mTextRendering = NS_STYLE_TEXT_RENDERING_AUTO;
|
||||
mFillOpacitySource = eStyleSVGOpacitySource_Normal;
|
||||
mStrokeOpacitySource = eStyleSVGOpacitySource_Normal;
|
||||
mStrokeDasharrayFromObject = false;
|
||||
mStrokeDashoffsetFromObject = false;
|
||||
mStrokeWidthFromObject = false;
|
||||
}
|
||||
nsStyleSVG::~nsStyleSVG()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsStyleSVG);
|
||||
delete [] mStrokeDasharray;
|
||||
@@ -1240,21 +1240,21 @@ nsStyleFilter::SetDropShadow(nsCSSShadowArray* aDropShadow)
|
||||
// --------------------
|
||||
// nsStyleSVGReset
|
||||
//
|
||||
nsStyleSVGReset::nsStyleSVGReset()
|
||||
nsStyleSVGReset::nsStyleSVGReset()
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleSVGReset);
|
||||
mStopColor = NS_RGB(0,0,0);
|
||||
mFloodColor = NS_RGB(0,0,0);
|
||||
mLightingColor = NS_RGB(255,255,255);
|
||||
mMask = nullptr;
|
||||
mStopOpacity = 1.0f;
|
||||
mFloodOpacity = 1.0f;
|
||||
mDominantBaseline = NS_STYLE_DOMINANT_BASELINE_AUTO;
|
||||
mVectorEffect = NS_STYLE_VECTOR_EFFECT_NONE;
|
||||
mMaskType = NS_STYLE_MASK_TYPE_LUMINANCE;
|
||||
MOZ_COUNT_CTOR(nsStyleSVGReset);
|
||||
mStopColor = NS_RGB(0,0,0);
|
||||
mFloodColor = NS_RGB(0,0,0);
|
||||
mLightingColor = NS_RGB(255,255,255);
|
||||
mMask = nullptr;
|
||||
mStopOpacity = 1.0f;
|
||||
mFloodOpacity = 1.0f;
|
||||
mDominantBaseline = NS_STYLE_DOMINANT_BASELINE_AUTO;
|
||||
mVectorEffect = NS_STYLE_VECTOR_EFFECT_NONE;
|
||||
mMaskType = NS_STYLE_MASK_TYPE_LUMINANCE;
|
||||
}
|
||||
|
||||
nsStyleSVGReset::~nsStyleSVGReset()
|
||||
nsStyleSVGReset::~nsStyleSVGReset()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsStyleSVGReset);
|
||||
}
|
||||
|
||||
+143
-98
@@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
@@ -97,7 +98,8 @@ static_assert(int(mozilla::SheetType::Count) - 1 <=
|
||||
|
||||
// The lifetime of these objects is managed by the presshell's arena.
|
||||
|
||||
struct nsStyleFont {
|
||||
struct nsStyleFont
|
||||
{
|
||||
nsStyleFont(const nsFont& aFont, nsPresContext *aPresContext);
|
||||
nsStyleFont(const nsStyleFont& aStyleFont);
|
||||
explicit nsStyleFont(nsPresContext *aPresContext);
|
||||
@@ -174,7 +176,8 @@ struct nsStyleFont {
|
||||
nsCOMPtr<nsIAtom> mLanguage; // [inherited]
|
||||
};
|
||||
|
||||
struct nsStyleGradientStop {
|
||||
struct nsStyleGradientStop
|
||||
{
|
||||
nsStyleCoord mLocation; // percent, coord, calc, none
|
||||
nscolor mColor;
|
||||
bool mIsInterpolationHint;
|
||||
@@ -184,7 +187,8 @@ struct nsStyleGradientStop {
|
||||
bool operator!=(const nsStyleGradientStop&) const = delete;
|
||||
};
|
||||
|
||||
class nsStyleGradient final {
|
||||
class nsStyleGradient final
|
||||
{
|
||||
public:
|
||||
nsStyleGradient();
|
||||
uint8_t mShape; // NS_STYLE_GRADIENT_SHAPE_*
|
||||
@@ -239,7 +243,8 @@ enum nsStyleImageType {
|
||||
* region of an image. (Currently, this feature is only supported with an
|
||||
* image of type (1)).
|
||||
*/
|
||||
struct nsStyleImage {
|
||||
struct nsStyleImage
|
||||
{
|
||||
nsStyleImage();
|
||||
~nsStyleImage();
|
||||
nsStyleImage(const nsStyleImage& aOther);
|
||||
@@ -360,7 +365,8 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
struct nsStyleColor {
|
||||
struct nsStyleColor
|
||||
{
|
||||
explicit nsStyleColor(nsPresContext* aPresContext);
|
||||
nsStyleColor(const nsStyleColor& aOther);
|
||||
~nsStyleColor(void) {
|
||||
@@ -392,7 +398,8 @@ struct nsStyleColor {
|
||||
nscolor mColor; // [inherited]
|
||||
};
|
||||
|
||||
struct nsStyleBackground {
|
||||
struct nsStyleBackground
|
||||
{
|
||||
nsStyleBackground();
|
||||
nsStyleBackground(const nsStyleBackground& aOther);
|
||||
~nsStyleBackground();
|
||||
@@ -629,7 +636,8 @@ struct nsStyleBackground {
|
||||
#define NS_SPACING_BORDER 2
|
||||
|
||||
|
||||
struct nsStyleMargin {
|
||||
struct nsStyleMargin
|
||||
{
|
||||
nsStyleMargin(void);
|
||||
nsStyleMargin(const nsStyleMargin& aMargin);
|
||||
~nsStyleMargin(void) {
|
||||
@@ -673,7 +681,8 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
struct nsStylePadding {
|
||||
struct nsStylePadding
|
||||
{
|
||||
nsStylePadding(void);
|
||||
nsStylePadding(const nsStylePadding& aPadding);
|
||||
~nsStylePadding(void) {
|
||||
@@ -721,7 +730,8 @@ protected:
|
||||
nsMargin mCachedPadding;
|
||||
};
|
||||
|
||||
struct nsBorderColors {
|
||||
struct nsBorderColors
|
||||
{
|
||||
nsBorderColors* mNext;
|
||||
nscolor mColor;
|
||||
|
||||
@@ -750,7 +760,8 @@ private:
|
||||
nsBorderColors* Clone(bool aDeep) const;
|
||||
};
|
||||
|
||||
struct nsCSSShadowItem {
|
||||
struct nsCSSShadowItem
|
||||
{
|
||||
nscoord mXOffset;
|
||||
nscoord mYOffset;
|
||||
nscoord mRadius;
|
||||
@@ -781,74 +792,75 @@ struct nsCSSShadowItem {
|
||||
}
|
||||
};
|
||||
|
||||
class nsCSSShadowArray final {
|
||||
public:
|
||||
void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
|
||||
// We can allocate both this nsCSSShadowArray and the
|
||||
// actual array in one allocation. The amount of memory to
|
||||
// allocate is equal to the class's size + the number of bytes for all
|
||||
// but the first array item (because aBaseSize includes one
|
||||
// item, see the private declarations)
|
||||
return ::operator new(aBaseSize +
|
||||
(aArrayLen - 1) * sizeof(nsCSSShadowItem));
|
||||
}
|
||||
class nsCSSShadowArray final
|
||||
{
|
||||
public:
|
||||
void* operator new(size_t aBaseSize, uint32_t aArrayLen) {
|
||||
// We can allocate both this nsCSSShadowArray and the
|
||||
// actual array in one allocation. The amount of memory to
|
||||
// allocate is equal to the class's size + the number of bytes for all
|
||||
// but the first array item (because aBaseSize includes one
|
||||
// item, see the private declarations)
|
||||
return ::operator new(aBaseSize +
|
||||
(aArrayLen - 1) * sizeof(nsCSSShadowItem));
|
||||
}
|
||||
|
||||
explicit nsCSSShadowArray(uint32_t aArrayLen) :
|
||||
mLength(aArrayLen)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsCSSShadowArray);
|
||||
for (uint32_t i = 1; i < mLength; ++i) {
|
||||
// Make sure we call the constructors of each nsCSSShadowItem
|
||||
// (the first one is called for us because we declared it under private)
|
||||
new (&mArray[i]) nsCSSShadowItem();
|
||||
}
|
||||
explicit nsCSSShadowArray(uint32_t aArrayLen) :
|
||||
mLength(aArrayLen)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsCSSShadowArray);
|
||||
for (uint32_t i = 1; i < mLength; ++i) {
|
||||
// Make sure we call the constructors of each nsCSSShadowItem
|
||||
// (the first one is called for us because we declared it under private)
|
||||
new (&mArray[i]) nsCSSShadowItem();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
~nsCSSShadowArray() {
|
||||
MOZ_COUNT_DTOR(nsCSSShadowArray);
|
||||
for (uint32_t i = 1; i < mLength; ++i) {
|
||||
mArray[i].~nsCSSShadowItem();
|
||||
}
|
||||
// Private destructor, to discourage deletion outside of Release():
|
||||
~nsCSSShadowArray() {
|
||||
MOZ_COUNT_DTOR(nsCSSShadowArray);
|
||||
for (uint32_t i = 1; i < mLength; ++i) {
|
||||
mArray[i].~nsCSSShadowItem();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t Length() const { return mLength; }
|
||||
nsCSSShadowItem* ShadowAt(uint32_t i) {
|
||||
MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
|
||||
return &mArray[i];
|
||||
}
|
||||
const nsCSSShadowItem* ShadowAt(uint32_t i) const {
|
||||
MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
|
||||
return &mArray[i];
|
||||
}
|
||||
uint32_t Length() const { return mLength; }
|
||||
nsCSSShadowItem* ShadowAt(uint32_t i) {
|
||||
MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
|
||||
return &mArray[i];
|
||||
}
|
||||
const nsCSSShadowItem* ShadowAt(uint32_t i) const {
|
||||
MOZ_ASSERT(i < mLength, "Accessing too high an index in the text shadow array!");
|
||||
return &mArray[i];
|
||||
}
|
||||
|
||||
bool HasShadowWithInset(bool aInset) {
|
||||
for (uint32_t i = 0; i < mLength; ++i) {
|
||||
if (mArray[i].mInset == aInset)
|
||||
return true;
|
||||
}
|
||||
bool HasShadowWithInset(bool aInset) {
|
||||
for (uint32_t i = 0; i < mLength; ++i) {
|
||||
if (mArray[i].mInset == aInset)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const nsCSSShadowArray& aOther) const {
|
||||
if (mLength != aOther.Length())
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const nsCSSShadowArray& aOther) const {
|
||||
if (mLength != aOther.Length())
|
||||
for (uint32_t i = 0; i < mLength; ++i) {
|
||||
if (ShadowAt(i) != aOther.ShadowAt(i))
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < mLength; ++i) {
|
||||
if (ShadowAt(i) != aOther.ShadowAt(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(nsCSSShadowArray)
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mLength;
|
||||
nsCSSShadowItem mArray[1]; // This MUST be the last item
|
||||
NS_INLINE_DECL_REFCOUNTING(nsCSSShadowArray)
|
||||
|
||||
private:
|
||||
uint32_t mLength;
|
||||
nsCSSShadowItem mArray[1]; // This MUST be the last item
|
||||
};
|
||||
|
||||
// Border widths are rounded to the nearest-below integer number of pixels,
|
||||
@@ -871,7 +883,8 @@ static bool IsVisibleBorderStyle(uint8_t aStyle)
|
||||
aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
|
||||
}
|
||||
|
||||
struct nsStyleBorder {
|
||||
struct nsStyleBorder
|
||||
{
|
||||
explicit nsStyleBorder(nsPresContext* aContext);
|
||||
nsStyleBorder(const nsStyleBorder& aBorder);
|
||||
~nsStyleBorder();
|
||||
@@ -1097,7 +1110,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct nsStyleOutline {
|
||||
struct nsStyleOutline
|
||||
{
|
||||
explicit nsStyleOutline(nsPresContext* aPresContext);
|
||||
nsStyleOutline(const nsStyleOutline& aOutline);
|
||||
~nsStyleOutline(void) {
|
||||
@@ -1195,7 +1209,8 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
struct nsStyleList {
|
||||
struct nsStyleList
|
||||
{
|
||||
explicit nsStyleList(nsPresContext* aPresContext);
|
||||
nsStyleList(const nsStyleList& aStyleList);
|
||||
~nsStyleList(void);
|
||||
@@ -1261,7 +1276,8 @@ public:
|
||||
nsRect mImageRegion; // [inherited] the rect to use within an image
|
||||
};
|
||||
|
||||
struct nsStyleGridLine {
|
||||
struct nsStyleGridLine
|
||||
{
|
||||
// http://dev.w3.org/csswg/css-grid/#typedef-grid-line
|
||||
// XXXmats we could optimize memory size here
|
||||
bool mHasSpan;
|
||||
@@ -1322,7 +1338,8 @@ struct nsStyleGridLine {
|
||||
}
|
||||
};
|
||||
|
||||
struct nsStyleTextOverflowSide {
|
||||
struct nsStyleTextOverflowSide
|
||||
{
|
||||
nsStyleTextOverflowSide() : mType(NS_STYLE_TEXT_OVERFLOW_CLIP) {}
|
||||
|
||||
bool operator==(const nsStyleTextOverflowSide& aOther) const {
|
||||
@@ -1338,7 +1355,8 @@ struct nsStyleTextOverflowSide {
|
||||
uint8_t mType;
|
||||
};
|
||||
|
||||
struct nsStyleTextOverflow {
|
||||
struct nsStyleTextOverflow
|
||||
{
|
||||
nsStyleTextOverflow() : mLogicalDirections(true) {}
|
||||
bool operator==(const nsStyleTextOverflow& aOther) const {
|
||||
return mLeft == aOther.mLeft && mRight == aOther.mRight;
|
||||
@@ -1378,7 +1396,8 @@ struct nsStyleTextOverflow {
|
||||
bool mLogicalDirections; // true when only one value was specified
|
||||
};
|
||||
|
||||
struct nsStyleTextReset {
|
||||
struct nsStyleTextReset
|
||||
{
|
||||
nsStyleTextReset(void);
|
||||
nsStyleTextReset(const nsStyleTextReset& aOther);
|
||||
~nsStyleTextReset(void);
|
||||
@@ -1455,7 +1474,8 @@ protected:
|
||||
nscolor mTextDecorationColor; // [reset] the colors to use for a decoration lines, not used at currentColor
|
||||
};
|
||||
|
||||
struct nsStyleText {
|
||||
struct nsStyleText
|
||||
{
|
||||
explicit nsStyleText(nsPresContext* aPresContext);
|
||||
nsStyleText(const nsStyleText& aOther);
|
||||
~nsStyleText(void);
|
||||
@@ -1566,7 +1586,8 @@ struct nsStyleText {
|
||||
mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const;
|
||||
};
|
||||
|
||||
struct nsStyleImageOrientation {
|
||||
struct nsStyleImageOrientation
|
||||
{
|
||||
static nsStyleImageOrientation CreateAsAngleAndFlip(double aRadians,
|
||||
bool aFlip) {
|
||||
uint8_t orientation(0);
|
||||
@@ -1658,7 +1679,8 @@ protected:
|
||||
uint8_t mOrientation;
|
||||
};
|
||||
|
||||
struct nsStyleVisibility {
|
||||
struct nsStyleVisibility
|
||||
{
|
||||
explicit nsStyleVisibility(nsPresContext* aPresContext);
|
||||
nsStyleVisibility(const nsStyleVisibility& aVisibility);
|
||||
~nsStyleVisibility() {
|
||||
@@ -1706,7 +1728,8 @@ struct nsStyleVisibility {
|
||||
inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
|
||||
};
|
||||
|
||||
struct nsTimingFunction {
|
||||
struct nsTimingFunction
|
||||
{
|
||||
|
||||
enum class Type {
|
||||
Ease, // ease
|
||||
@@ -1833,7 +1856,8 @@ private:
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct StyleTransition {
|
||||
struct StyleTransition
|
||||
{
|
||||
StyleTransition() { /* leaves uninitialized; see also SetInitialValues */ }
|
||||
explicit StyleTransition(const StyleTransition& aCopy);
|
||||
|
||||
@@ -1887,7 +1911,8 @@ private:
|
||||
// eCSSPropertyExtra_variable
|
||||
};
|
||||
|
||||
struct StyleAnimation {
|
||||
struct StyleAnimation
|
||||
{
|
||||
StyleAnimation() { /* leaves uninitialized; see also SetInitialValues */ }
|
||||
explicit StyleAnimation(const StyleAnimation& aCopy);
|
||||
|
||||
@@ -1934,7 +1959,8 @@ private:
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
struct nsStyleDisplay {
|
||||
struct nsStyleDisplay
|
||||
{
|
||||
nsStyleDisplay();
|
||||
nsStyleDisplay(const nsStyleDisplay& aOther);
|
||||
~nsStyleDisplay() {
|
||||
@@ -2213,7 +2239,8 @@ struct nsStyleDisplay {
|
||||
inline uint8_t PhysicalBreakType(mozilla::WritingMode aWM) const;
|
||||
};
|
||||
|
||||
struct nsStyleTable {
|
||||
struct nsStyleTable
|
||||
{
|
||||
nsStyleTable(void);
|
||||
nsStyleTable(const nsStyleTable& aOther);
|
||||
~nsStyleTable(void);
|
||||
@@ -2282,7 +2309,8 @@ struct nsStyleTable {
|
||||
// when there is no <auto-repeat> track, i.e. when mRepeatAutoIndex == -1).
|
||||
// When mIsSubgrid is true, mRepeatAutoLineNameListBefore contains the line
|
||||
// names and mRepeatAutoLineNameListAfter is empty.
|
||||
struct nsStyleGridTemplate {
|
||||
struct nsStyleGridTemplate
|
||||
{
|
||||
nsTArray<nsTArray<nsString>> mLineNameLists;
|
||||
nsTArray<nsStyleCoord> mMinTrackSizingFunctions;
|
||||
nsTArray<nsStyleCoord> mMaxTrackSizingFunctions;
|
||||
@@ -2321,7 +2349,8 @@ struct nsStyleGridTemplate {
|
||||
}
|
||||
};
|
||||
|
||||
struct nsStylePosition {
|
||||
struct nsStylePosition
|
||||
{
|
||||
nsStylePosition(void);
|
||||
nsStylePosition(const nsStylePosition& aOther);
|
||||
~nsStylePosition(void);
|
||||
@@ -2512,7 +2541,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct nsStyleTableBorder {
|
||||
struct nsStyleTableBorder
|
||||
{
|
||||
nsStyleTableBorder();
|
||||
nsStyleTableBorder(const nsStyleTableBorder& aOther);
|
||||
~nsStyleTableBorder(void);
|
||||
@@ -2560,7 +2590,8 @@ enum nsStyleContentType {
|
||||
eStyleContentType_Uninitialized
|
||||
};
|
||||
|
||||
struct nsStyleContentData {
|
||||
struct nsStyleContentData
|
||||
{
|
||||
nsStyleContentType mType;
|
||||
union {
|
||||
char16_t *mString;
|
||||
@@ -2600,7 +2631,8 @@ private:
|
||||
nsStyleContentData(const nsStyleContentData&); // not to be implemented
|
||||
};
|
||||
|
||||
struct nsStyleCounterData {
|
||||
struct nsStyleCounterData
|
||||
{
|
||||
nsString mCounter;
|
||||
int32_t mValue;
|
||||
};
|
||||
@@ -2608,7 +2640,8 @@ struct nsStyleCounterData {
|
||||
|
||||
#define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nullptr; }
|
||||
|
||||
struct nsStyleQuotes {
|
||||
struct nsStyleQuotes
|
||||
{
|
||||
nsStyleQuotes();
|
||||
nsStyleQuotes(const nsStyleQuotes& aQuotes);
|
||||
~nsStyleQuotes();
|
||||
@@ -2690,7 +2723,8 @@ protected:
|
||||
nsString* mQuotes;
|
||||
};
|
||||
|
||||
struct nsStyleContent {
|
||||
struct nsStyleContent
|
||||
{
|
||||
nsStyleContent(void);
|
||||
nsStyleContent(const nsStyleContent& aContent);
|
||||
~nsStyleContent(void);
|
||||
@@ -2799,7 +2833,8 @@ protected:
|
||||
uint32_t mResetCount;
|
||||
};
|
||||
|
||||
struct nsStyleUIReset {
|
||||
struct nsStyleUIReset
|
||||
{
|
||||
nsStyleUIReset(void);
|
||||
nsStyleUIReset(const nsStyleUIReset& aOther);
|
||||
~nsStyleUIReset(void);
|
||||
@@ -2832,7 +2867,8 @@ struct nsStyleUIReset {
|
||||
uint8_t mWindowShadow; // [reset]
|
||||
};
|
||||
|
||||
struct nsCursorImage {
|
||||
struct nsCursorImage
|
||||
{
|
||||
bool mHaveHotspot;
|
||||
float mHotspotX, mHotspotY;
|
||||
|
||||
@@ -2861,7 +2897,8 @@ private:
|
||||
nsCOMPtr<imgIRequest> mImage;
|
||||
};
|
||||
|
||||
struct nsStyleUserInterface {
|
||||
struct nsStyleUserInterface
|
||||
{
|
||||
nsStyleUserInterface(void);
|
||||
nsStyleUserInterface(const nsStyleUserInterface& aOther);
|
||||
~nsStyleUserInterface(void);
|
||||
@@ -2908,7 +2945,8 @@ struct nsStyleUserInterface {
|
||||
void CopyCursorArrayFrom(const nsStyleUserInterface& aSource);
|
||||
};
|
||||
|
||||
struct nsStyleXUL {
|
||||
struct nsStyleXUL
|
||||
{
|
||||
nsStyleXUL();
|
||||
nsStyleXUL(const nsStyleXUL& aSource);
|
||||
~nsStyleXUL();
|
||||
@@ -2944,7 +2982,8 @@ struct nsStyleXUL {
|
||||
bool mStretchStack; // [reset] see nsStyleConsts.h
|
||||
};
|
||||
|
||||
struct nsStyleColumn {
|
||||
struct nsStyleColumn
|
||||
{
|
||||
explicit nsStyleColumn(nsPresContext* aPresContext);
|
||||
nsStyleColumn(const nsStyleColumn& aSource);
|
||||
~nsStyleColumn();
|
||||
@@ -3037,7 +3076,8 @@ struct nsStyleSVGPaint
|
||||
}
|
||||
};
|
||||
|
||||
struct nsStyleSVG {
|
||||
struct nsStyleSVG
|
||||
{
|
||||
nsStyleSVG();
|
||||
nsStyleSVG(const nsStyleSVG& aSource);
|
||||
~nsStyleSVG();
|
||||
@@ -3124,7 +3164,8 @@ struct nsStyleSVG {
|
||||
}
|
||||
};
|
||||
|
||||
class nsStyleBasicShape final {
|
||||
class nsStyleBasicShape final
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
eInset,
|
||||
@@ -3266,7 +3307,8 @@ private:
|
||||
uint8_t mSizingBox; // see NS_STYLE_CLIP_SHAPE_SIZING_* constants in nsStyleConsts.h
|
||||
};
|
||||
|
||||
struct nsStyleFilter {
|
||||
struct nsStyleFilter
|
||||
{
|
||||
nsStyleFilter();
|
||||
nsStyleFilter(const nsStyleFilter& aSource);
|
||||
~nsStyleFilter();
|
||||
@@ -3315,11 +3357,13 @@ private:
|
||||
};
|
||||
|
||||
template<>
|
||||
struct nsTArray_CopyChooser<nsStyleFilter> {
|
||||
struct nsTArray_CopyChooser<nsStyleFilter>
|
||||
{
|
||||
typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
|
||||
};
|
||||
|
||||
struct nsStyleSVGReset {
|
||||
struct nsStyleSVGReset
|
||||
{
|
||||
nsStyleSVGReset();
|
||||
nsStyleSVGReset(const nsStyleSVGReset& aSource);
|
||||
~nsStyleSVGReset();
|
||||
@@ -3370,7 +3414,8 @@ struct nsStyleSVGReset {
|
||||
uint8_t mMaskType; // [reset] see nsStyleConsts.h
|
||||
};
|
||||
|
||||
struct nsStyleVariables {
|
||||
struct nsStyleVariables
|
||||
{
|
||||
nsStyleVariables();
|
||||
nsStyleVariables(const nsStyleVariables& aSource);
|
||||
~nsStyleVariables();
|
||||
|
||||
@@ -279,7 +279,8 @@ ProcessInterpolateMatrix(Matrix4x4& aMatrix,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions,
|
||||
TransformReferenceBox& aRefBox)
|
||||
TransformReferenceBox& aRefBox,
|
||||
bool* aContains3dTransform)
|
||||
{
|
||||
NS_PRECONDITION(aData->Count() == 4, "Invalid array!");
|
||||
|
||||
@@ -288,13 +289,15 @@ ProcessInterpolateMatrix(Matrix4x4& aMatrix,
|
||||
matrix1 = nsStyleTransformMatrix::ReadTransforms(aData->Item(1).GetListValue(),
|
||||
aContext, aPresContext,
|
||||
aConditions,
|
||||
aRefBox, nsPresContext::AppUnitsPerCSSPixel());
|
||||
aRefBox, nsPresContext::AppUnitsPerCSSPixel(),
|
||||
aContains3dTransform);
|
||||
}
|
||||
if (aData->Item(2).GetUnit() == eCSSUnit_List) {
|
||||
matrix2 = ReadTransforms(aData->Item(2).GetListValue(),
|
||||
aContext, aPresContext,
|
||||
aConditions,
|
||||
aRefBox, nsPresContext::AppUnitsPerCSSPixel());
|
||||
aRefBox, nsPresContext::AppUnitsPerCSSPixel(),
|
||||
aContains3dTransform);
|
||||
}
|
||||
double progress = aData->Item(3).GetPercentValue();
|
||||
|
||||
@@ -614,8 +617,10 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions,
|
||||
TransformReferenceBox& aRefBox)
|
||||
TransformReferenceBox& aRefBox,
|
||||
bool* aContains3dTransform)
|
||||
{
|
||||
MOZ_ASSERT(aContains3dTransform);
|
||||
NS_PRECONDITION(aData, "Why did you want to get data from a null array?");
|
||||
// It's OK if aContext and aPresContext are null if the caller already
|
||||
// knows that all length units have been converted to pixels (as
|
||||
@@ -633,6 +638,7 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
aConditions, aRefBox);
|
||||
break;
|
||||
case eCSSKeyword_translatez:
|
||||
*aContains3dTransform = true;
|
||||
ProcessTranslateZ(aMatrix, aData, aContext, aPresContext,
|
||||
aConditions);
|
||||
break;
|
||||
@@ -641,6 +647,7 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
aConditions, aRefBox);
|
||||
break;
|
||||
case eCSSKeyword_translate3d:
|
||||
*aContains3dTransform = true;
|
||||
ProcessTranslate3D(aMatrix, aData, aContext, aPresContext,
|
||||
aConditions, aRefBox);
|
||||
break;
|
||||
@@ -651,12 +658,14 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
ProcessScaleY(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scalez:
|
||||
*aContains3dTransform = true;
|
||||
ProcessScaleZ(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scale:
|
||||
ProcessScale(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_scale3d:
|
||||
*aContains3dTransform = true;
|
||||
ProcessScale3D(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_skewx:
|
||||
@@ -669,16 +678,20 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
ProcessSkew(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotatex:
|
||||
*aContains3dTransform = true;
|
||||
ProcessRotateX(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotatey:
|
||||
*aContains3dTransform = true;
|
||||
ProcessRotateY(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotatez:
|
||||
*aContains3dTransform = true;
|
||||
case eCSSKeyword_rotate:
|
||||
ProcessRotateZ(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_rotate3d:
|
||||
*aContains3dTransform = true;
|
||||
ProcessRotate3D(aMatrix, aData);
|
||||
break;
|
||||
case eCSSKeyword_matrix:
|
||||
@@ -686,14 +699,17 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
aConditions, aRefBox);
|
||||
break;
|
||||
case eCSSKeyword_matrix3d:
|
||||
*aContains3dTransform = true;
|
||||
ProcessMatrix3D(aMatrix, aData, aContext, aPresContext,
|
||||
aConditions, aRefBox);
|
||||
break;
|
||||
case eCSSKeyword_interpolatematrix:
|
||||
ProcessInterpolateMatrix(aMatrix, aData, aContext, aPresContext,
|
||||
aConditions, aRefBox);
|
||||
aConditions, aRefBox,
|
||||
aContains3dTransform);
|
||||
break;
|
||||
case eCSSKeyword_perspective:
|
||||
*aContains3dTransform = true;
|
||||
ProcessPerspective(aMatrix, aData, aContext, aPresContext,
|
||||
aConditions);
|
||||
break;
|
||||
@@ -719,7 +735,8 @@ ReadTransforms(const nsCSSValueList* aList,
|
||||
nsPresContext* aPresContext,
|
||||
RuleNodeCacheConditions& aConditions,
|
||||
TransformReferenceBox& aRefBox,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
float aAppUnitsPerMatrixUnit,
|
||||
bool* aContains3dTransform)
|
||||
{
|
||||
Matrix4x4 result;
|
||||
|
||||
@@ -737,13 +754,14 @@ ReadTransforms(const nsCSSValueList* aList,
|
||||
|
||||
/* Read in a single transform matrix. */
|
||||
MatrixForTransformFunction(result, currElem.GetArrayValue(), aContext,
|
||||
aPresContext, aConditions, aRefBox);
|
||||
aPresContext, aConditions, aRefBox,
|
||||
aContains3dTransform);
|
||||
}
|
||||
|
||||
float scale = float(nsPresContext::AppUnitsPerCSSPixel()) / aAppUnitsPerMatrixUnit;
|
||||
result.PreScale(1/scale, 1/scale, 1/scale);
|
||||
result.PostScale(scale, scale, scale);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,8 @@ namespace nsStyleTransformMatrix {
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
mozilla::RuleNodeCacheConditions& aConditions,
|
||||
TransformReferenceBox& aBounds);
|
||||
TransformReferenceBox& aBounds,
|
||||
bool* aContains3dTransform);
|
||||
|
||||
/**
|
||||
* Given an nsCSSValueList containing -moz-transform functions,
|
||||
@@ -153,6 +154,9 @@ namespace nsStyleTransformMatrix {
|
||||
* result cannot be cached in the rule tree, otherwise untouched.
|
||||
* @param aBounds The frame's bounding rectangle.
|
||||
* @param aAppUnitsPerMatrixUnit The number of app units per device pixel.
|
||||
* @param aContains3dTransform [out] Set to true if aList contains at least
|
||||
* one 3d transform function (as defined in the CSS transforms
|
||||
* specification), false otherwise.
|
||||
*
|
||||
* aContext and aPresContext may be null if all of the (non-percent)
|
||||
* length values in aData are already known to have been converted to
|
||||
@@ -163,8 +167,8 @@ namespace nsStyleTransformMatrix {
|
||||
nsPresContext* aPresContext,
|
||||
mozilla::RuleNodeCacheConditions& aConditions,
|
||||
TransformReferenceBox& aBounds,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
|
||||
float aAppUnitsPerMatrixUnit,
|
||||
bool* aContains3dTransform);
|
||||
} // namespace nsStyleTransformMatrix
|
||||
|
||||
#endif
|
||||
|
||||
@@ -284,4 +284,5 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262,
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
|
||||
[test_visited_reftests.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
|
||||
[test_webkit_box_orient.html]
|
||||
[test_webkit_device_pixel_ratio.html]
|
||||
|
||||
@@ -162,6 +162,8 @@ var validGradientAndElementValues = [
|
||||
"-moz-linear-gradient(10% 10em, red, blue)",
|
||||
"-moz-linear-gradient(44px top, red, blue)",
|
||||
|
||||
"-moz-linear-gradient(0px, red, blue)",
|
||||
"-moz-linear-gradient(0, red, blue)",
|
||||
"-moz-linear-gradient(top left 45deg, red, blue)",
|
||||
"-moz-linear-gradient(20% bottom -300deg, red, blue)",
|
||||
"-moz-linear-gradient(center 20% 1.95929rad, red, blue)",
|
||||
@@ -386,6 +388,10 @@ var invalidGradientAndElementValues = [
|
||||
"-moz-linear-gradient(10 10px -45deg, red, blue) repeat",
|
||||
"-moz-linear-gradient(10px 10 -45deg, red, blue) repeat",
|
||||
"linear-gradient(red -99, yellow, green, blue 120%)",
|
||||
/* Unitless 0 is invalid as an <angle> */
|
||||
"-moz-linear-gradient(top left 0, red, blue)",
|
||||
"-moz-linear-gradient(5px 5px 0, red, blue)",
|
||||
"linear-gradient(0, red, blue)",
|
||||
/* Invalid color, calc() or -moz-image-rect() function */
|
||||
"linear-gradient(red, rgb(0, rubbish, 0) 50%, red)",
|
||||
"linear-gradient(red, red calc(50% + rubbish), red)",
|
||||
@@ -702,6 +708,11 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
"-webkit-linear-gradient(135deg, red, blue)",
|
||||
"-webkit-linear-gradient(280deg, red 60%, blue)",
|
||||
|
||||
// Linear-gradient with unitless-0 <angle> (normally invalid for <angle>
|
||||
// but accepted here for better webkit emulation):
|
||||
"-webkit-linear-gradient(0, red, blue)",
|
||||
"-webkit-linear-gradient(0 red, blue)",
|
||||
|
||||
// Basic radial-gradient syntax (valid when prefixed or unprefixed):
|
||||
"-webkit-radial-gradient(circle, white, black)",
|
||||
"-webkit-radial-gradient(circle, white, black)",
|
||||
@@ -4848,6 +4859,25 @@ function logical_box_prop_get_computed(cs, property)
|
||||
return cs.getPropertyValue(property);
|
||||
}
|
||||
|
||||
// Helper to get computed style of "-webkit-box-orient" from "flex-direction"
|
||||
// and the "writing-mode".
|
||||
function webkit_orient_get_computed(cs, property)
|
||||
{
|
||||
var writingMode = cs.getPropertyValue("writing-mode") || "horizontal-tb";
|
||||
|
||||
var mapping; // map from flex-direction values to -webkit-box-orient values.
|
||||
if (writingMode == "horizontal-tb") {
|
||||
// Horizontal writing-mode
|
||||
mapping = { "row" : "horizontal", "column" : "vertical"};
|
||||
} else {
|
||||
// Vertical writing-mode
|
||||
mapping = { "row" : "vertical", "column" : "horizontal"};
|
||||
}
|
||||
|
||||
var flexDirection = cs.getPropertyValue("flex-direction");
|
||||
return mapping[flexDirection];
|
||||
}
|
||||
|
||||
// Get the computed value for a property. For shorthands, return the
|
||||
// computed values of all the subproperties, delimited by " ; ".
|
||||
function get_computed_value(cs, property)
|
||||
@@ -6992,6 +7022,21 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
alias_for: "order",
|
||||
subproperties: [ "order" ],
|
||||
};
|
||||
/* This one is not an alias - it's implemented as a logical property: */
|
||||
gCSSProperties["-webkit-box-orient"] = {
|
||||
domProp: "webkitBoxOrient",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
logical: true,
|
||||
get_computed: webkit_orient_get_computed,
|
||||
initial_values: [ "horizontal" ],
|
||||
other_values: [ "vertical" ],
|
||||
invalid_values: [
|
||||
"0", "0px", "auto",
|
||||
/* Flex-direction values: */
|
||||
"row", "column", "row-reverse", "column-reverse",
|
||||
],
|
||||
};
|
||||
gCSSProperties["-webkit-box-align"] = {
|
||||
domProp: "webkitBoxAlign",
|
||||
inherited: false,
|
||||
|
||||
@@ -439,6 +439,8 @@ function run() {
|
||||
expression_should_be_parseable("-webkit-max-device-pixel-ratio: 1.0");
|
||||
expression_should_not_be_parseable("max-device-pixel-ratio: 1.0");
|
||||
|
||||
should_apply("(-webkit-transform-3d)");
|
||||
|
||||
features = [ "max-aspect-ratio", "device-aspect-ratio" ];
|
||||
for (i in features) {
|
||||
feature = features[i];
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>
|
||||
Test the writing-mode-dependent mapping of '-webkit-box-orient' values to
|
||||
'flex-direction' values, when emulating -webkit-box styles with modern flexbox
|
||||
</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="testDiv" style="display: none"></div>
|
||||
<script>
|
||||
// Mappings from "-webkit-box-orient" values to "flex-direction" values,
|
||||
// when writing-mode is horizontal:
|
||||
const horizMapping =
|
||||
{ "horizontal" : "row",
|
||||
"vertical" : "column" };
|
||||
|
||||
// Same as above, but now when writing-mode is vertical:
|
||||
const vertMapping =
|
||||
{ "horizontal" : "column",
|
||||
"vertical" : "row" };
|
||||
|
||||
const div = document.getElementById("testDiv");
|
||||
|
||||
// Test the various writing-mode values:
|
||||
testWM("unset", horizMapping);
|
||||
testWM("horizontal-tb", horizMapping);
|
||||
testWM("vertical-lr", vertMapping);
|
||||
testWM("vertical-rl", vertMapping);
|
||||
testWM("sideways-lr", vertMapping);
|
||||
testWM("sideways-rl", vertMapping);
|
||||
|
||||
/**
|
||||
* Main test function:
|
||||
* @param aWritingMode The writing-mode value to test.
|
||||
* @param aMapping Mapping from -webkit-box-orient values to equivalent
|
||||
* flex-direction values, for this writing-mode.
|
||||
*/
|
||||
function testWM(aWritingMode, aMapping) {
|
||||
div.style.writingMode = aWritingMode;
|
||||
for (var webkitBoxOrientVal in aMapping) {
|
||||
div.style.webkitBoxOrient = webkitBoxOrientVal;
|
||||
test(function() {
|
||||
var expectedFlexDir = aMapping[webkitBoxOrientVal];
|
||||
var actualFlexDir = window.getComputedStyle(div, "").flexDirection;
|
||||
assert_equals(actualFlexDir, expectedFlexDir,
|
||||
"Testing the 'flex-direction' value produced by " +
|
||||
"'-webkit-box-orient:" + webkitBoxOrientVal + "'");
|
||||
}, "Testing how '-webkit-box-orient' values influence 'flex-direction' " +
|
||||
"in presence of 'writing-mode:" + aWritingMode + "'");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="filter: url(#a); clip: rect(0px, 4rem, 2px, 2px);">
|
||||
<script>
|
||||
function boom()
|
||||
{
|
||||
document.getElementById("a").style.overflow = "hidden";
|
||||
document.documentElement.style.fontSize = "10px";
|
||||
}
|
||||
window.addEventListener("load", boom, false);
|
||||
</script>
|
||||
|
||||
<set id="a"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 380 B |
@@ -192,6 +192,7 @@ load 1016145.svg
|
||||
load 1028512.svg
|
||||
load 1140080-1.svg
|
||||
load 1149542-1.svg
|
||||
load 1156581-1.svg
|
||||
load 1182496-1.html
|
||||
load 1209525-1.svg
|
||||
load 1223281-1.svg
|
||||
|
||||
@@ -776,14 +776,15 @@ nsSVGEffects::InvalidateRenderingObservers(nsIFrame *aFrame)
|
||||
{
|
||||
NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame must be first continuation");
|
||||
|
||||
if (!aFrame->GetContent()->IsElement())
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (!content || !content->IsElement())
|
||||
return;
|
||||
|
||||
// If the rendering has changed, the bounds may well have changed too:
|
||||
aFrame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty());
|
||||
|
||||
nsSVGRenderingObserverList *observerList =
|
||||
GetObserverList(aFrame->GetContent()->AsElement());
|
||||
GetObserverList(content->AsElement());
|
||||
if (observerList) {
|
||||
observerList->InvalidateAll();
|
||||
return;
|
||||
@@ -827,7 +828,8 @@ nsSVGEffects::InvalidateDirectRenderingObservers(Element *aElement, uint32_t aFl
|
||||
void
|
||||
nsSVGEffects::InvalidateDirectRenderingObservers(nsIFrame *aFrame, uint32_t aFlags /* = 0 */)
|
||||
{
|
||||
if (aFrame->GetContent() && aFrame->GetContent()->IsElement()) {
|
||||
InvalidateDirectRenderingObservers(aFrame->GetContent()->AsElement(), aFlags);
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (content && content->IsElement()) {
|
||||
InvalidateDirectRenderingObservers(content->AsElement(), aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2669,6 +2669,11 @@ pref("layout.css.prefixes.gradients", true);
|
||||
// Are webkit-prefixed properties & property-values supported?
|
||||
pref("layout.css.prefixes.webkit", false);
|
||||
|
||||
// Are "-webkit-{min|max}-device-pixel-ratio" media queries supported?
|
||||
// (Note: this pref has no effect if the master 'layout.css.prefixes.webkit'
|
||||
// pref is set to false.)
|
||||
pref("layout.css.prefixes.device-pixel-ratio-webkit", false);
|
||||
|
||||
// Is the CSS Unprefixing Service enabled? (This service emulates support
|
||||
// for certain vendor-prefixed properties & values, for sites on a "fixlist".)
|
||||
pref("layout.css.unprefixing-service.enabled", true);
|
||||
|
||||
@@ -154,6 +154,9 @@ user_pref("layout.css.object-fit-and-position.enabled", true);
|
||||
// Enable webkit prefixed CSS features for testing
|
||||
user_pref("layout.css.prefixes.webkit", true);
|
||||
|
||||
// Enable -webkit-{min|max}-device-pixel-ratio media queries for testing
|
||||
user_pref("layout.css.prefixes.device-pixel-ratio-webkit", true);
|
||||
|
||||
// Disable spammy layout warnings because they pollute test logs
|
||||
user_pref("layout.spammy_warnings.enabled", false);
|
||||
|
||||
|
||||
@@ -536,7 +536,9 @@ public:
|
||||
return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor());
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
already_AddRefed<mozilla::gfx::DrawTarget>
|
||||
StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode) override;
|
||||
void EndRemoteDrawing() override;
|
||||
void CleanupRemoteDrawing() override;
|
||||
bool InitCompositor(mozilla::layers::Compositor* aCompositor) override;
|
||||
|
||||
@@ -2637,7 +2637,8 @@ nsChildView::SwipeFinished()
|
||||
}
|
||||
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion)
|
||||
nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
BufferMode* aBufferMode)
|
||||
{
|
||||
// should have created the GLPresenter in InitCompositor.
|
||||
MOZ_ASSERT(mGLPresenter);
|
||||
@@ -4406,7 +4407,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
if (!nsCocoaFeatures::OnLionOrLater()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
// This method checks whether the AppleEnableSwipeNavigateWithScrolls global
|
||||
// preference is set. If it isn't, fluid swipe tracking is disabled, and a
|
||||
// horizontal two-finger gesture is always a scroll (even in Safari). This
|
||||
@@ -4435,6 +4436,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
CGFloat deltaX = [anEvent scrollingDeltaX];
|
||||
CGFloat deltaY = [anEvent scrollingDeltaY];
|
||||
return std::abs(deltaX) > std::abs(deltaY) * 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setUsingOMTCompositor:(BOOL)aUseOMTC
|
||||
|
||||
+7
-15
@@ -2227,7 +2227,8 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt = GetDrawTarget(region);
|
||||
BufferMode layerBuffering = BufferMode::BUFFERED;
|
||||
RefPtr<DrawTarget> dt = GetDrawTarget(region, &layerBuffering);
|
||||
if (!dt) {
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2247,7 +2248,6 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
gfxUtils::ClipToRegion(dt, region.ToUnknownRegion());
|
||||
}
|
||||
|
||||
BufferMode layerBuffering;
|
||||
if (shaped) {
|
||||
// The double buffering is done here to extract the shape mask.
|
||||
// (The shape mask won't be necessary when a visual with an alpha
|
||||
@@ -2256,16 +2256,6 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
||||
RefPtr<DrawTarget> destDT = dt->CreateSimilarDrawTarget(boundsRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||
ctx = new gfxContext(destDT, boundsRect.TopLeft());
|
||||
} else {
|
||||
#ifdef MOZ_HAVE_SHMIMAGE
|
||||
if (nsShmImage::UseShm()) {
|
||||
// We're using an xshm mapping as a back buffer.
|
||||
layerBuffering = BufferMode::BUFFER_NONE;
|
||||
} else
|
||||
#endif // MOZ_HAVE_SHMIMAGE
|
||||
{
|
||||
// Get the layer manager to do double buffering (if necessary).
|
||||
layerBuffering = BufferMode::BUFFERED;
|
||||
}
|
||||
ctx = new gfxContext(dt);
|
||||
}
|
||||
|
||||
@@ -6329,7 +6319,7 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
#endif
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion)
|
||||
nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion, BufferMode* aBufferMode)
|
||||
{
|
||||
if (!mGdkWindow) {
|
||||
return nullptr;
|
||||
@@ -6348,12 +6338,14 @@ nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion)
|
||||
if (nsShmImage::UseShm()) {
|
||||
dt = nsShmImage::EnsureShmImage(size,
|
||||
mXDisplay, mXVisual, mXDepth, mShmImage);
|
||||
*aBufferMode = BufferMode::BUFFER_NONE;
|
||||
}
|
||||
# endif // MOZ_HAVE_SHMIMAGE
|
||||
if (!dt) {
|
||||
RefPtr<gfxXlibSurface> surf = new gfxXlibSurface(mXDisplay, mXWindow, mXVisual, size.ToUnknownSize());
|
||||
if (!surf->CairoStatus()) {
|
||||
dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf.get(), surf->GetSize());
|
||||
*aBufferMode = BufferMode::BUFFERED;
|
||||
}
|
||||
}
|
||||
#endif // MOZ_X11
|
||||
@@ -6362,9 +6354,9 @@ nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion)
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion)
|
||||
nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode)
|
||||
{
|
||||
return GetDrawTarget(aInvalidRegion);
|
||||
return GetDrawTarget(aInvalidRegion, aBufferMode);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -206,7 +206,8 @@ public:
|
||||
#endif
|
||||
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget>
|
||||
StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode) override;
|
||||
virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget,
|
||||
LayoutDeviceIntRegion& aInvalidRegion) override;
|
||||
|
||||
@@ -299,7 +300,9 @@ public:
|
||||
virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
|
||||
nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
|
||||
uint8_t* aAlphas, int32_t aStride);
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> GetDrawTarget(const LayoutDeviceIntRegion& aRegion);
|
||||
|
||||
already_AddRefed<mozilla::gfx::DrawTarget> GetDrawTarget(const LayoutDeviceIntRegion& aRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode);
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
|
||||
|
||||
+5
-1
@@ -1259,9 +1259,13 @@ class nsIWidget : public nsISupports {
|
||||
*
|
||||
* Called by BasicCompositor on the compositor thread for OMTC drawing
|
||||
* before each composition.
|
||||
*
|
||||
* The window may specify its buffer mode. If unspecified, it is assumed
|
||||
* to require double-buffering.
|
||||
*/
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawing() = 0;
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) {
|
||||
virtual already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion,
|
||||
mozilla::layers::BufferMode* aBufferMode) {
|
||||
return StartRemoteDrawing();
|
||||
}
|
||||
|
||||
|
||||
@@ -524,6 +524,22 @@ WinUtils::Log(const char *fmt, ...)
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
// static
|
||||
double
|
||||
WinUtils::SystemScaleFactor()
|
||||
{
|
||||
// The result of GetDeviceCaps won't change dynamically, as it predates
|
||||
// per-monitor DPI and support for on-the-fly resolution changes.
|
||||
// Therefore, we only need to look it up once.
|
||||
static int logPixelsY = 0;
|
||||
if (!logPixelsY) {
|
||||
HDC screenDC = GetDC(nullptr);
|
||||
logPixelsY = GetDeviceCaps(screenDC, LOGPIXELSY);
|
||||
ReleaseDC(nullptr, screenDC);
|
||||
}
|
||||
return logPixelsY / 96.0;
|
||||
}
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
typedef enum {
|
||||
MDT_EFFECTIVE_DPI = 0,
|
||||
|
||||
@@ -128,6 +128,15 @@ public:
|
||||
class WinUtils
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Get the system's default logical-to-physical DPI scaling factor,
|
||||
* which is based on the primary display. Note however that unlike
|
||||
* LogToPhysFactor(GetPrimaryMonitor()), this will not change during
|
||||
* a session even if the displays are reconfigured. This scale factor
|
||||
* is used by Windows theme metrics etc, which do not fully support
|
||||
* dynamic resolution changes but are only updated on logout.
|
||||
*/
|
||||
static double SystemScaleFactor();
|
||||
|
||||
static bool IsPerMonitorDPIAware();
|
||||
/**
|
||||
|
||||
@@ -65,7 +65,9 @@ static int32_t GetSystemParam(long flag, int32_t def)
|
||||
return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
|
||||
}
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
|
||||
nsLookAndFeel::nsLookAndFeel()
|
||||
: nsXPLookAndFeel()
|
||||
, mUseAccessibilityTheme(0)
|
||||
{
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE,
|
||||
WinUtils::IsTouchDeviceSupportPresent());
|
||||
@@ -265,23 +267,6 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
|
||||
case eColorID__moz_cellhighlight:
|
||||
idx = COLOR_3DFACE;
|
||||
break;
|
||||
case eColorID__moz_win_accentcolor:
|
||||
res = GetAccentColor(aColor);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
return res;
|
||||
}
|
||||
NS_WARNING("Using fallback for accent color - UI code failed to use the "
|
||||
"-moz-windows-accent-color-applies media query properly");
|
||||
// Seems to be the default color (hardcoded because of bug 1065998)
|
||||
aColor = NS_RGB(158, 158, 158);
|
||||
return NS_OK;
|
||||
case eColorID__moz_win_accentcolortext:
|
||||
res = GetAccentColorText(aColor);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
return res;
|
||||
}
|
||||
aColor = NS_RGB(0, 0, 0);
|
||||
return NS_OK;
|
||||
case eColorID__moz_win_mediatext:
|
||||
if (IsVistaOrLater() && IsAppThemed()) {
|
||||
res = ::GetColorFromTheme(eUXMediaToolbar,
|
||||
@@ -376,7 +361,16 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
|
||||
// High contrast is a misnomer under Win32 -- any theme can be used with it,
|
||||
// e.g. normal contrast with large fonts, low contrast, etc.
|
||||
// The high contrast flag really means -- use this theme and don't override it.
|
||||
aResult = nsUXThemeData::IsHighContrastOn();
|
||||
if (XRE_IsContentProcess()) {
|
||||
// If we're running in the content process, then the parent should
|
||||
// have sent us the accessibility state when nsLookAndFeel
|
||||
// initialized, and stashed it in the mUseAccessibilityTheme cache.
|
||||
aResult = mUseAccessibilityTheme;
|
||||
} else {
|
||||
// Otherwise, we can ask the OS to see if we're using High Contrast
|
||||
// mode.
|
||||
aResult = nsUXThemeData::IsHighContrastOn();
|
||||
}
|
||||
break;
|
||||
case eIntID_ScrollArrowStyle:
|
||||
aResult = eScrollArrowStyle_Single;
|
||||
@@ -426,20 +420,6 @@ nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
|
||||
case eIntID_DWMCompositor:
|
||||
aResult = nsUXThemeData::CheckForCompositor();
|
||||
break;
|
||||
case eIntID_WindowsAccentColorApplies:
|
||||
{
|
||||
nscolor unused;
|
||||
aResult = NS_SUCCEEDED(GetAccentColor(unused)) ? 1 : 0;
|
||||
}
|
||||
break;
|
||||
case eIntID_WindowsAccentColorIsDark:
|
||||
{
|
||||
nscolor accentColor;
|
||||
if (NS_SUCCEEDED(GetAccentColor(accentColor))) {
|
||||
aResult = AccentColorIsDark(accentColor) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eIntID_WindowsGlass:
|
||||
// Aero Glass is only available prior to Windows 8 when DWM is used.
|
||||
aResult = (nsUXThemeData::CheckForCompositor() && !IsWin8OrLater());
|
||||
@@ -559,10 +539,10 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
|
||||
LOGFONTW* ptrLogFont = nullptr;
|
||||
LOGFONTW logFont;
|
||||
NONCLIENTMETRICSW ncm;
|
||||
HGDIOBJ hGDI;
|
||||
char16_t name[LF_FACESIZE];
|
||||
bool useShellDlg = false;
|
||||
|
||||
// Depending on which stock font we want, there are three different
|
||||
// Depending on which stock font we want, there are a couple of
|
||||
// places we might have to look it up.
|
||||
switch (anID) {
|
||||
case LookAndFeel::eFont_Icon:
|
||||
@@ -573,11 +553,7 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
|
||||
ptrLogFont = &logFont;
|
||||
break;
|
||||
|
||||
case LookAndFeel::eFont_Menu:
|
||||
case LookAndFeel::eFont_MessageBox:
|
||||
case LookAndFeel::eFont_SmallCaption:
|
||||
case LookAndFeel::eFont_StatusBar:
|
||||
case LookAndFeel::eFont_Tooltips:
|
||||
default:
|
||||
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
|
||||
if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
|
||||
sizeof(ncm), (PVOID)&ncm, 0))
|
||||
@@ -585,10 +561,11 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
|
||||
|
||||
switch (anID) {
|
||||
case LookAndFeel::eFont_Menu:
|
||||
case LookAndFeel::eFont_PullDownMenu:
|
||||
ptrLogFont = &ncm.lfMenuFont;
|
||||
break;
|
||||
case LookAndFeel::eFont_MessageBox:
|
||||
ptrLogFont = &ncm.lfMessageFont;
|
||||
case LookAndFeel::eFont_Caption:
|
||||
ptrLogFont = &ncm.lfCaptionFont;
|
||||
break;
|
||||
case LookAndFeel::eFont_SmallCaption:
|
||||
ptrLogFont = &ncm.lfSmCaptionFont;
|
||||
@@ -597,36 +574,28 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
|
||||
case LookAndFeel::eFont_Tooltips:
|
||||
ptrLogFont = &ncm.lfStatusFont;
|
||||
break;
|
||||
case LookAndFeel::eFont_Widget:
|
||||
case LookAndFeel::eFont_Dialog:
|
||||
case LookAndFeel::eFont_Button:
|
||||
case LookAndFeel::eFont_Field:
|
||||
case LookAndFeel::eFont_List:
|
||||
// XXX It's not clear to me whether this is exactly the right
|
||||
// set of LookAndFeel values to map to the dialog font; we may
|
||||
// want to add or remove cases here after reviewing the visual
|
||||
// results under various Windows versions.
|
||||
useShellDlg = true;
|
||||
// Fall through so that we can get size from lfMessageFont;
|
||||
// but later we'll use the (virtual) "MS Shell Dlg 2" font name
|
||||
// instead of the LOGFONT's.
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
ptrLogFont = &ncm.lfMessageFont;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LookAndFeel::eFont_Widget:
|
||||
case LookAndFeel::eFont_Window: // css3
|
||||
case LookAndFeel::eFont_Document:
|
||||
case LookAndFeel::eFont_Workspace:
|
||||
case LookAndFeel::eFont_Desktop:
|
||||
case LookAndFeel::eFont_Info:
|
||||
case LookAndFeel::eFont_Dialog:
|
||||
case LookAndFeel::eFont_Button:
|
||||
case LookAndFeel::eFont_PullDownMenu:
|
||||
case LookAndFeel::eFont_List:
|
||||
case LookAndFeel::eFont_Field:
|
||||
case LookAndFeel::eFont_Caption:
|
||||
hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
|
||||
if (!hGDI)
|
||||
return false;
|
||||
|
||||
if (::GetObjectW(hGDI, sizeof(logFont), &logFont) <= 0)
|
||||
return false;
|
||||
|
||||
ptrLogFont = &logFont;
|
||||
break;
|
||||
}
|
||||
|
||||
// Get scaling factor from physical to logical pixels
|
||||
double pixelScale = 1.0 / WinUtils::LogToPhysFactor(aHDC);
|
||||
double pixelScale = 1.0 / WinUtils::SystemScaleFactor();
|
||||
|
||||
// The lfHeight is in pixels, and it needs to be adjusted for the
|
||||
// device it will be displayed on.
|
||||
@@ -675,9 +644,12 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
|
||||
|
||||
aFontStyle.systemFont = true;
|
||||
|
||||
name[0] = 0;
|
||||
memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE*sizeof(char16_t));
|
||||
aFontName = name;
|
||||
if (useShellDlg) {
|
||||
aFontName = NS_LITERAL_STRING("MS Shell Dlg 2");
|
||||
} else {
|
||||
memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE*sizeof(char16_t));
|
||||
aFontName = name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -703,73 +675,28 @@ nsLookAndFeel::GetPasswordCharacterImpl()
|
||||
return UNICODE_BLACK_CIRCLE_CHAR;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsLookAndFeel::GetAccentColor(nscolor& aColor)
|
||||
nsTArray<LookAndFeelInt>
|
||||
nsLookAndFeel::GetIntCacheImpl()
|
||||
{
|
||||
nsresult rv;
|
||||
nsTArray<LookAndFeelInt> lookAndFeelIntCache =
|
||||
nsXPLookAndFeel::GetIntCacheImpl();
|
||||
|
||||
if (!mDwmKey) {
|
||||
mDwmKey = do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
LookAndFeelInt useAccessibilityTheme;
|
||||
useAccessibilityTheme.id = eIntID_UseAccessibilityTheme;
|
||||
useAccessibilityTheme.value = GetInt(eIntID_UseAccessibilityTheme);
|
||||
lookAndFeelIntCache.AppendElement(useAccessibilityTheme);
|
||||
|
||||
return lookAndFeelIntCache;
|
||||
}
|
||||
|
||||
void
|
||||
nsLookAndFeel::SetIntCacheImpl(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache)
|
||||
{
|
||||
for (auto entry : aLookAndFeelIntCache) {
|
||||
if (entry.id == eIntID_UseAccessibilityTheme) {
|
||||
mUseAccessibilityTheme = entry.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rv = mDwmKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
|
||||
NS_LITERAL_STRING("SOFTWARE\\Microsoft\\Windows\\DWM"),
|
||||
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The ColorPrevalence value is set to 1 when the "Show color on title bar"
|
||||
// setting in the Color section of Window's Personalization settings is
|
||||
// turned on.
|
||||
uint32_t accentColor, colorPrevalence;
|
||||
if (NS_SUCCEEDED(mDwmKey->ReadIntValue(NS_LITERAL_STRING("AccentColor"), &accentColor)) &&
|
||||
NS_SUCCEEDED(mDwmKey->ReadIntValue(NS_LITERAL_STRING("ColorPrevalence"), &colorPrevalence)) &&
|
||||
colorPrevalence == 1) {
|
||||
// The order of the color components in the DWORD stored in the registry
|
||||
// happens to be the same order as we store the components in nscolor
|
||||
// so we can just assign directly here.
|
||||
aColor = accentColor;
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
mDwmKey->Close();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
nsLookAndFeel::AccentColorIsDark(nscolor aColor)
|
||||
{
|
||||
float luminance = (NS_GET_R(aColor) * 2 +
|
||||
NS_GET_G(aColor) * 5 +
|
||||
NS_GET_B(aColor)) / 8;
|
||||
|
||||
return (luminance <= 128);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsLookAndFeel::GetAccentColorText(nscolor& aColor)
|
||||
{
|
||||
nscolor accentColor;
|
||||
nsresult rv = GetAccentColor(accentColor);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We want the color that we return for text that will be drawn over
|
||||
// a background that has the accent color to have good contrast with
|
||||
// the accent color. Windows itself uses either white or black text
|
||||
// depending on how light or dark the accent color is. We do the same
|
||||
// here based on the luminance of the accent color with a threshhold
|
||||
// value that seems consistent with what Windows does.
|
||||
|
||||
aColor = AccentColorIsDark(accentColor) ? NS_RGB(255, 255, 255) : NS_RGB(0, 0, 0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
#ifndef __nsLookAndFeel
|
||||
#define __nsLookAndFeel
|
||||
|
||||
#include "nsXPLookAndFeel.h"
|
||||
#include "nsIWindowsRegKey.h"
|
||||
|
||||
/*
|
||||
* Gesture System Metrics
|
||||
@@ -56,29 +54,12 @@ public:
|
||||
gfxFontStyle& aFontStyle,
|
||||
float aDevPixPerCSSPixel);
|
||||
virtual char16_t GetPasswordCharacterImpl();
|
||||
private:
|
||||
/**
|
||||
* Fetches the Windows accent color from the Windows settings if
|
||||
* the accent color is set to apply to the title bar, otherwise
|
||||
* returns an error code.
|
||||
*/
|
||||
nsresult GetAccentColor(nscolor& aColor);
|
||||
|
||||
/**
|
||||
* check if the accent color is dark enough to need white text
|
||||
**/
|
||||
bool AccentColorIsDark(nscolor aColor);
|
||||
|
||||
/**
|
||||
* If the Windows accent color from the Windows settings is set
|
||||
* to apply to the title bar, this computes the color that should
|
||||
* be used for text that is to be written over a background that has
|
||||
* the accent color. Otherwise, (if the accent color should not
|
||||
* apply to the title bar) this returns an error code.
|
||||
*/
|
||||
nsresult GetAccentColorText(nscolor& aColor);
|
||||
|
||||
nsCOMPtr<nsIWindowsRegKey> mDwmKey;
|
||||
virtual nsTArray<LookAndFeelInt> GetIntCacheImpl();
|
||||
virtual void SetIntCacheImpl(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache);
|
||||
|
||||
private:
|
||||
int32_t mUseAccessibilityTheme;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1550,16 +1550,20 @@ AssumeThemePartAndStateAreTransparent(int32_t aPart, int32_t aState)
|
||||
}
|
||||
|
||||
// When running with per-monitor DPI (on Win8.1+), and rendering on a display
|
||||
// with a different DPI setting from the system's primary monitor, we need to
|
||||
// with a different DPI setting from the system's default scaling, we need to
|
||||
// apply scaling to native-themed elements as the Windows theme APIs assume
|
||||
// the primary monitor's resolution.
|
||||
static double
|
||||
// the system default resolution.
|
||||
static inline double
|
||||
GetThemeDpiScaleFactor(nsIFrame* aFrame)
|
||||
{
|
||||
double primaryScale =
|
||||
WinUtils::LogToPhysFactor(WinUtils::GetPrimaryMonitor());
|
||||
nsIWidget* rootWidget = aFrame->PresContext()->GetRootWidget();
|
||||
return rootWidget ? rootWidget->GetDefaultScale().scale / primaryScale : 1.0;
|
||||
if (WinUtils::IsPerMonitorDPIAware() && GetSystemMetrics(SM_CMONITORS) > 1) {
|
||||
nsIWidget* rootWidget = aFrame->PresContext()->GetRootWidget();
|
||||
if (rootWidget) {
|
||||
double systemScale = WinUtils::SystemScaleFactor();
|
||||
return rootWidget->GetDefaultScale().scale / systemScale;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
Reference in New Issue
Block a user