gecko-dev/layout/style/StyleAnimationValue.cpp

5634 строки
201 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
2012-05-21 15:12:37 +04:00
/* 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/. */
/* Utilities for animation of computed style values */
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/RuleNodeCacheConditions.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "mozilla/Tuple.h"
#include "mozilla/UniquePtr.h"
#include "nsAutoPtr.h"
#include "nsCOMArray.h"
#ifdef MOZ_OLD_STYLE
#include "nsIStyleRule.h"
#include "mozilla/css/StyleRule.h"
#endif
#include "nsString.h"
#include "nsStyleContext.h"
#ifdef MOZ_OLD_STYLE
#include "nsStyleSet.h"
#endif
#include "nsComputedDOMStyle.h"
#include "nsContentUtils.h"
#include "nsCSSParser.h"
#include "nsCSSPseudoElements.h"
#ifdef MOZ_OLD_STYLE
#include "mozilla/css/Declaration.h"
#endif
#include "mozilla/dom/Element.h"
2012-10-22 17:53:31 +04:00
#include "mozilla/FloatingPoint.h"
#include "mozilla/Likely.h"
#include "mozilla/ServoBindings.h" // RawServoDeclarationBlock
#include "mozilla/ServoCSSParser.h"
#include "gfxMatrix.h"
#include "gfxQuaternion.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
2014-08-29 22:47:30 +04:00
#include "gfx2DGlue.h"
#include "nsStyleContextInlines.h"
using namespace mozilla;
using namespace mozilla::css;
2014-08-29 22:47:30 +04:00
using namespace mozilla::gfx;
using nsStyleTransformMatrix::Decompose2DMatrix;
using nsStyleTransformMatrix::Decompose3DMatrix;
using nsStyleTransformMatrix::ShearType;
#ifdef MOZ_OLD_STYLE
// HELPER METHODS
// --------------
/*
* Given two units, this method returns a common unit that they can both be
* converted into, if possible. This is intended to facilitate
* interpolation, distance-computation, and addition between "similar" units.
*
* The ordering of the arguments should not affect the output of this method.
*
* If there's no sensible common unit, this method returns eUnit_Null.
*
* @param aFirstUnit One unit to resolve.
* @param aFirstUnit The other unit to resolve.
* @return A "common" unit that both source units can be converted into, or
* eUnit_Null if that's not possible.
*/
static
StyleAnimationValue::Unit
GetCommonUnit(nsCSSPropertyID aProperty,
StyleAnimationValue::Unit aFirstUnit,
StyleAnimationValue::Unit aSecondUnit)
{
if (aFirstUnit != aSecondUnit) {
if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_STORES_CALC) &&
(aFirstUnit == StyleAnimationValue::eUnit_Coord ||
aFirstUnit == StyleAnimationValue::eUnit_Percent ||
aFirstUnit == StyleAnimationValue::eUnit_Calc) &&
(aSecondUnit == StyleAnimationValue::eUnit_Coord ||
aSecondUnit == StyleAnimationValue::eUnit_Percent ||
aSecondUnit == StyleAnimationValue::eUnit_Calc)) {
// We can use calc() as the common unit.
return StyleAnimationValue::eUnit_Calc;
}
if ((aFirstUnit == StyleAnimationValue::eUnit_Color ||
aFirstUnit == StyleAnimationValue::eUnit_CurrentColor ||
aFirstUnit == StyleAnimationValue::eUnit_ComplexColor) &&
(aSecondUnit == StyleAnimationValue::eUnit_Color ||
aSecondUnit == StyleAnimationValue::eUnit_CurrentColor ||
aSecondUnit == StyleAnimationValue::eUnit_ComplexColor)) {
// We can use complex color as the common unit.
return StyleAnimationValue::eUnit_ComplexColor;
}
return StyleAnimationValue::eUnit_Null;
}
return aFirstUnit;
}
static
nsCSSUnit
GetCommonUnit(nsCSSPropertyID aProperty,
nsCSSUnit aFirstUnit,
nsCSSUnit aSecondUnit)
{
if (aFirstUnit != aSecondUnit) {
if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_STORES_CALC) &&
(aFirstUnit == eCSSUnit_Pixel ||
aFirstUnit == eCSSUnit_Percent ||
aFirstUnit == eCSSUnit_Calc) &&
(aSecondUnit == eCSSUnit_Pixel ||
aSecondUnit == eCSSUnit_Percent ||
aSecondUnit == eCSSUnit_Calc)) {
// We can use calc() as the common unit.
return eCSSUnit_Calc;
}
return eCSSUnit_Null;
}
return aFirstUnit;
}
static nsCSSKeyword
ToPrimitive(nsCSSKeyword aKeyword)
{
switch (aKeyword) {
case eCSSKeyword_translatex:
case eCSSKeyword_translatey:
case eCSSKeyword_translatez:
case eCSSKeyword_translate:
return eCSSKeyword_translate3d;
case eCSSKeyword_scalex:
case eCSSKeyword_scaley:
case eCSSKeyword_scalez:
case eCSSKeyword_scale:
return eCSSKeyword_scale3d;
default:
return aKeyword;
}
}
static bool
HasAccumulateMatrix(const nsCSSValueList* aList)
{
const nsCSSValueList *item = aList;
do {
nsCSSKeyword func =
nsStyleTransformMatrix::TransformFunctionOf(item->mValue.GetArrayValue());
if (func == eCSSKeyword_accumulatematrix) {
return true;
}
item = item->mNext;
} while (item);
return false;
}
static bool
TransformFunctionsMatch(nsCSSKeyword func1, nsCSSKeyword func2)
{
// Handle eCSSKeyword_accumulatematrix as different function to be calculated
// (decomposed and recomposed) them later.
if (func1 == eCSSKeyword_accumulatematrix ||
func2 == eCSSKeyword_accumulatematrix) {
return false;
}
return ToPrimitive(func1) == ToPrimitive(func2);
}
static bool
TransformFunctionListsMatch(const nsCSSValueList *list1,
const nsCSSValueList *list2)
{
const nsCSSValueList *item1 = list1, *item2 = list2;
do {
nsCSSKeyword func1 = nsStyleTransformMatrix::TransformFunctionOf(
item1->mValue.GetArrayValue());
nsCSSKeyword func2 = nsStyleTransformMatrix::TransformFunctionOf(
item2->mValue.GetArrayValue());
if (!TransformFunctionsMatch(func1, func2)) {
return false;
}
item1 = item1->mNext;
item2 = item2->mNext;
} while (item1 && item2);
// Length match?
return !item1 && !item2;
}
#endif
static already_AddRefed<nsCSSValue::Array>
AppendFunction(nsCSSKeyword aTransformFunction)
{
uint32_t nargs;
switch (aTransformFunction) {
case eCSSKeyword_matrix3d:
nargs = 16;
break;
case eCSSKeyword_matrix:
nargs = 6;
break;
case eCSSKeyword_rotate3d:
nargs = 4;
break;
case eCSSKeyword_interpolatematrix:
case eCSSKeyword_accumulatematrix:
case eCSSKeyword_translate3d:
case eCSSKeyword_scale3d:
nargs = 3;
break;
case eCSSKeyword_translate:
case eCSSKeyword_skew:
case eCSSKeyword_scale:
nargs = 2;
break;
default:
NS_ERROR("must be a transform function");
Bug 1235306 - Fix -Wimplicit-fallthrough warnings in layout/. r=dholbert layout/base/nsCSSRendering.cpp:3913:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:3943:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:4066:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:4096:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRenderingBorders.cpp:646:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:4639:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:4659:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:5004:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:5200:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/TouchManager.cpp:192:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/TouchManager.cpp:196:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2497:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2687:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2973:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4277:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4310:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4313:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:6703:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:6751:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsGridContainerFrame.cpp:2649:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsGridContainerFrame.cpp:935:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1141:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1145:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1148:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:2942:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:2958:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:3134:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:3150:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/printing/nsPrintPreviewListener.cpp:199:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/CSSLexer.cpp:129:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:1069:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:366:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:442:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:981:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:3597:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:3616:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:539:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:540:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:542:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10628:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10630:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10671:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10673:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10769:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10770:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10774:43 [-Wimplicit-fallthrough] fallthrough annotation does not directly precede switch label layout/style/nsCSSParser.cpp:10775:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10776:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10780:43 [-Wimplicit-fallthrough] fallthrough annotation does not directly precede switch label layout/style/nsCSSParser.cpp:2542:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:2715:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:4124:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:4313:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9513:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9697:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9699:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9743:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9745:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9826:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9827:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9832:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9833:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9980:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:160:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:187:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:722:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:753:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:139:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:1687:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:1869:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/FixedTableLayoutStrategy.cpp:264:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/FixedTableLayoutStrategy.cpp:267:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:1043:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:930:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:953:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:997:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6943:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6953:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6959:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6966:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6974:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7151:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7161:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7170:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7177:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7186:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableRowFrame.cpp:663:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:112:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:142:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:157:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:86:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:87:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:88:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:90:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsSliderFrame.cpp:551:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsSliderFrame.cpp:560:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsXULPopupManager.cpp:2268:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels
2015-11-23 08:33:47 +03:00
MOZ_FALLTHROUGH;
case eCSSKeyword_translatex:
case eCSSKeyword_translatey:
case eCSSKeyword_translatez:
case eCSSKeyword_scalex:
case eCSSKeyword_scaley:
case eCSSKeyword_scalez:
case eCSSKeyword_skewx:
case eCSSKeyword_skewy:
case eCSSKeyword_rotate:
case eCSSKeyword_rotatex:
case eCSSKeyword_rotatey:
case eCSSKeyword_rotatez:
case eCSSKeyword_perspective:
nargs = 1;
break;
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(nargs + 1);
arr->Item(0).SetIntValue(aTransformFunction, eCSSUnit_Enumerated);
return arr.forget();
}
#ifdef MOZ_OLD_STYLE
static already_AddRefed<nsCSSValue::Array>
ToPrimitive(nsCSSValue::Array* aArray)
{
nsCSSKeyword tfunc = nsStyleTransformMatrix::TransformFunctionOf(aArray);
nsCSSKeyword primitive = ToPrimitive(tfunc);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> arr = AppendFunction(primitive);
// FIXME: This would produce fewer calc() expressions if the
// zero were of compatible type (length vs. percent) when
// needed.
nsCSSValue zero(0.0f, eCSSUnit_Pixel);
nsCSSValue one(1.0f, eCSSUnit_Number);
switch(tfunc) {
case eCSSKeyword_translate:
{
MOZ_ASSERT(aArray->Count() == 2 || aArray->Count() == 3,
"unexpected count");
arr->Item(1) = aArray->Item(1);
arr->Item(2) = aArray->Count() == 3 ? aArray->Item(2) : zero;
arr->Item(3) = zero;
break;
}
case eCSSKeyword_translatex:
{
MOZ_ASSERT(aArray->Count() == 2, "unexpected count");
arr->Item(1) = aArray->Item(1);
arr->Item(2) = zero;
arr->Item(3) = zero;
break;
}
case eCSSKeyword_translatey:
{
MOZ_ASSERT(aArray->Count() == 2, "unexpected count");
arr->Item(1) = zero;
arr->Item(2) = aArray->Item(1);
arr->Item(3) = zero;
break;
}
case eCSSKeyword_translatez:
{
MOZ_ASSERT(aArray->Count() == 2, "unexpected count");
arr->Item(1) = zero;
arr->Item(2) = zero;
arr->Item(3) = aArray->Item(1);
break;
}
case eCSSKeyword_scale:
{
MOZ_ASSERT(aArray->Count() == 2 || aArray->Count() == 3,
"unexpected count");
arr->Item(1) = aArray->Item(1);
arr->Item(2) = aArray->Count() == 3 ? aArray->Item(2) : aArray->Item(1);
arr->Item(3) = one;
break;
}
case eCSSKeyword_scalex:
{
MOZ_ASSERT(aArray->Count() == 2, "unexpected count");
arr->Item(1) = aArray->Item(1);
arr->Item(2) = one;
arr->Item(3) = one;
break;
}
case eCSSKeyword_scaley:
{
MOZ_ASSERT(aArray->Count() == 2, "unexpected count");
arr->Item(1) = one;
arr->Item(2) = aArray->Item(1);
arr->Item(3) = one;
break;
}
case eCSSKeyword_scalez:
{
MOZ_ASSERT(aArray->Count() == 2, "unexpected count");
arr->Item(1) = one;
arr->Item(2) = one;
arr->Item(3) = aArray->Item(1);
break;
}
default:
arr = aArray;
}
return arr.forget();
}
static void
AppendCSSShadowValue(const nsCSSShadowItem *aShadow,
nsCSSValueList **&aResultTail,
nsCSSPropertyID aProperty)
{
MOZ_ASSERT(aShadow, "shadow expected");
// X, Y, Radius, Spread, Color, Inset
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(6);
arr->Item(0).SetIntegerCoordValue(aShadow->mXOffset);
arr->Item(1).SetIntegerCoordValue(aShadow->mYOffset);
arr->Item(2).SetIntegerCoordValue(aShadow->mRadius);
if (aProperty == eCSSProperty_box_shadow) {
arr->Item(3).SetIntegerCoordValue(aShadow->mSpread);
}
if (aShadow->mHasColor) {
arr->Item(4).SetColorValue(aShadow->mColor);
}
if (aShadow->mInset) {
arr->Item(5).SetEnumValue(StyleBoxShadowType::Inset);
}
nsCSSValueList *resultItem = new nsCSSValueList;
resultItem->mValue.SetArrayValue(arr, eCSSUnit_Array);
*aResultTail = resultItem;
aResultTail = &resultItem->mNext;
}
// Like nsStyleCoord::CalcValue, but with length in float pixels instead
// of nscoord.
struct PixelCalcValue
{
float mLength, mPercent;
bool mHasPercent;
};
// Requires a canonical calc() value that we generated.
static PixelCalcValue
ExtractCalcValueInternal(const nsCSSValue& aValue)
{
MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Calc, "unexpected unit");
nsCSSValue::Array *arr = aValue.GetArrayValue();
MOZ_ASSERT(arr->Count() == 1, "unexpected length");
const nsCSSValue &topval = arr->Item(0);
PixelCalcValue result;
if (topval.GetUnit() == eCSSUnit_Pixel) {
result.mLength = topval.GetFloatValue();
result.mPercent = 0.0f;
result.mHasPercent = false;
} else {
MOZ_ASSERT(topval.GetUnit() == eCSSUnit_Calc_Plus,
"unexpected unit");
nsCSSValue::Array *arr2 = topval.GetArrayValue();
const nsCSSValue &len = arr2->Item(0);
const nsCSSValue &pct = arr2->Item(1);
MOZ_ASSERT(len.GetUnit() == eCSSUnit_Pixel, "unexpected unit");
MOZ_ASSERT(pct.GetUnit() == eCSSUnit_Percent, "unexpected unit");
result.mLength = len.GetFloatValue();
result.mPercent = pct.GetPercentValue();
result.mHasPercent = true;
}
return result;
}
// Requires a canonical calc() value that we generated.
static PixelCalcValue
ExtractCalcValue(const StyleAnimationValue& aValue)
{
PixelCalcValue result;
if (aValue.GetUnit() == StyleAnimationValue::eUnit_Coord) {
result.mLength =
nsPresContext::AppUnitsToFloatCSSPixels(aValue.GetCoordValue());
result.mPercent = 0.0f;
result.mHasPercent = false;
return result;
}
if (aValue.GetUnit() == StyleAnimationValue::eUnit_Percent) {
result.mLength = 0.0f;
result.mPercent = aValue.GetPercentValue();
result.mHasPercent = true;
return result;
}
MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Calc,
"unexpected unit");
nsCSSValue *val = aValue.GetCSSValueValue();
return ExtractCalcValueInternal(*val);
}
static PixelCalcValue
ExtractCalcValue(const nsCSSValue& aValue)
{
PixelCalcValue result;
if (aValue.GetUnit() == eCSSUnit_Pixel) {
result.mLength = aValue.GetFloatValue();
result.mPercent = 0.0f;
result.mHasPercent = false;
return result;
}
if (aValue.GetUnit() == eCSSUnit_Percent) {
result.mLength = 0.0f;
result.mPercent = aValue.GetPercentValue();
result.mHasPercent = true;
return result;
}
return ExtractCalcValueInternal(aValue);
}
static void
CalcValueToCSSValue(const nsStyleCoord::CalcValue* aCalc, nsCSSValue& aValue)
{
aValue.SetCalcValue(aCalc);
}
static void
CalcValueToCSSValue(const PixelCalcValue& aCalc, nsCSSValue& aValue)
{
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(1);
if (!aCalc.mHasPercent) {
arr->Item(0).SetFloatValue(aCalc.mLength, eCSSUnit_Pixel);
} else {
nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2);
arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus);
arr2->Item(0).SetFloatValue(aCalc.mLength, eCSSUnit_Pixel);
arr2->Item(1).SetPercentValue(aCalc.mPercent);
}
aValue.SetArrayValue(arr, eCSSUnit_Calc);
}
static double
CalcPositionSquareDistance(const nsCSSValue& aPos1,
const nsCSSValue& aPos2)
{
NS_ASSERTION(aPos1.GetUnit() == eCSSUnit_Array &&
aPos2.GetUnit() == eCSSUnit_Array,
"Expected two arrays");
PixelCalcValue calcVal[4];
nsCSSValue::Array* posArray = aPos1.GetArrayValue();
MOZ_ASSERT(posArray->Count() == 4, "Invalid position value");
NS_ASSERTION(posArray->Item(0).GetUnit() == eCSSUnit_Null &&
posArray->Item(2).GetUnit() == eCSSUnit_Null,
"Invalid list used");
for (int i = 0; i < 2; ++i) {
MOZ_ASSERT(posArray->Item(i*2+1).GetUnit() != eCSSUnit_Null,
"Invalid position value");
calcVal[i] = ExtractCalcValue(posArray->Item(i*2+1));
}
posArray = aPos2.GetArrayValue();
MOZ_ASSERT(posArray->Count() == 4, "Invalid position value");
NS_ASSERTION(posArray->Item(0).GetUnit() == eCSSUnit_Null &&
posArray->Item(2).GetUnit() == eCSSUnit_Null,
"Invalid list used");
for (int i = 0; i < 2; ++i) {
MOZ_ASSERT(posArray->Item(i*2+1).GetUnit() != eCSSUnit_Null,
"Invalid position value");
calcVal[i+2] = ExtractCalcValue(posArray->Item(i*2+1));
}
double squareDistance = 0.0;
for (int i = 0; i < 2; ++i) {
float difflen = calcVal[i+2].mLength - calcVal[i].mLength;
float diffpct = calcVal[i+2].mPercent - calcVal[i].mPercent;
squareDistance += difflen * difflen + diffpct * diffpct;
}
return squareDistance;
}
static PixelCalcValue
CalcBackgroundCoord(const nsCSSValue& aCoord)
{
NS_ASSERTION(aCoord.GetUnit() == eCSSUnit_Array,
"Expected array");
nsCSSValue::Array* array = aCoord.GetArrayValue();
MOZ_ASSERT(array->Count() == 2 &&
array->Item(0).GetUnit() == eCSSUnit_Null &&
array->Item(1).GetUnit() != eCSSUnit_Null,
"Invalid position value");
return ExtractCalcValue(array->Item(1));
}
static double
CalcPositionCoordSquareDistance(const nsCSSValue& aPos1,
const nsCSSValue& aPos2)
{
PixelCalcValue calcVal1 = CalcBackgroundCoord(aPos1);
PixelCalcValue calcVal2 = CalcBackgroundCoord(aPos2);
float difflen = calcVal2.mLength - calcVal1.mLength;
float diffpct = calcVal2.mPercent - calcVal1.mPercent;
return difflen * difflen + diffpct * diffpct;
}
// Ensure that a float/double value isn't NaN by returning zero instead
// (NaN doesn't have a sign) as a general restriction for floating point
// values in RestrictValue.
template<typename T>
MOZ_ALWAYS_INLINE T
EnsureNotNan(T aValue)
{
return aValue;
}
template<>
MOZ_ALWAYS_INLINE float
EnsureNotNan(float aValue)
{
// This would benefit from a MOZ_FLOAT_IS_NaN if we had one.
return MOZ_LIKELY(!mozilla::IsNaN(aValue)) ? aValue : 0;
}
template<>
MOZ_ALWAYS_INLINE double
EnsureNotNan(double aValue)
{
return MOZ_LIKELY(!mozilla::IsNaN(aValue)) ? aValue : 0;
}
template <typename T>
T
RestrictValue(uint32_t aRestrictions, T aValue)
{
T result = EnsureNotNan(aValue);
switch (aRestrictions) {
case 0:
break;
case CSS_PROPERTY_VALUE_NONNEGATIVE:
if (result < 0) {
result = 0;
}
break;
case CSS_PROPERTY_VALUE_AT_LEAST_ONE:
if (result < 1) {
result = 1;
}
break;
default:
MOZ_ASSERT(false, "bad value restriction");
break;
}
return result;
}
template <typename T>
T
RestrictValue(nsCSSPropertyID aProperty, T aValue)
{
return RestrictValue(nsCSSProps::ValueRestrictions(aProperty), aValue);
}
static void
AddCSSValueAngle(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult)
{
if (aValue1.GetUnit() == aValue2.GetUnit()) {
// To avoid floating point error, if the units match, maintain the unit.
aResult.SetFloatValue(
EnsureNotNan(aCoeff1 * aValue1.GetFloatValue() +
aCoeff2 * aValue2.GetFloatValue()),
aValue1.GetUnit());
} else {
aResult.SetFloatValue(
EnsureNotNan(aCoeff1 * aValue1.GetAngleValueInRadians() +
aCoeff2 * aValue2.GetAngleValueInRadians()),
eCSSUnit_Radian);
}
}
static inline void
AddCSSValuePercent(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult, uint32_t aValueRestrictions = 0)
{
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Percent, "unexpected unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Percent, "unexpected unit");
aResult.SetPercentValue(RestrictValue(aValueRestrictions,
aCoeff1 * aValue1.GetPercentValue() +
aCoeff2 * aValue2.GetPercentValue()));
}
// Add two canonical-form calc values (eUnit_Calc) to make another
// canonical-form calc value.
static void
AddCSSValueCanonicalCalc(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult)
{
PixelCalcValue v1 = ExtractCalcValue(aValue1);
PixelCalcValue v2 = ExtractCalcValue(aValue2);
PixelCalcValue result;
result.mLength = aCoeff1 * v1.mLength + aCoeff2 * v2.mLength;
result.mPercent = aCoeff1 * v1.mPercent + aCoeff2 * v2.mPercent;
result.mHasPercent = v1.mHasPercent || v2.mHasPercent;
MOZ_ASSERT(result.mHasPercent || result.mPercent == 0.0f,
"can't have a nonzero percentage part without having percentages");
CalcValueToCSSValue(result, aResult);
}
static inline void
AddCSSValuePixel(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult, uint32_t aValueRestrictions = 0)
{
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Pixel, "unexpected unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Pixel, "unexpected unit");
aResult.SetFloatValue(RestrictValue(aValueRestrictions,
aCoeff1 * aValue1.GetFloatValue() +
aCoeff2 * aValue2.GetFloatValue()),
eCSSUnit_Pixel);
}
static bool
AddCSSValuePixelPercentCalc(const uint32_t aValueRestrictions,
const nsCSSUnit aCommonUnit,
double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult)
{
switch (aCommonUnit) {
case eCSSUnit_Pixel:
AddCSSValuePixel(aCoeff1, aValue1,
aCoeff2, aValue2,
aResult, aValueRestrictions);
break;
case eCSSUnit_Percent:
AddCSSValuePercent(aCoeff1, aValue1,
aCoeff2, aValue2,
aResult, aValueRestrictions);
break;
case eCSSUnit_Calc:
AddCSSValueCanonicalCalc(aCoeff1, aValue1,
aCoeff2, aValue2,
aResult);
break;
default:
return false;
}
return true;
}
static void
AddTransformTranslate(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult)
{
// Only three possible units: eCSSUnit_Pixel, eCSSUnit_Percent, or
// eCSSUnit_Calc.
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Percent ||
aValue1.GetUnit() == eCSSUnit_Pixel ||
aValue1.IsCalcUnit(),
"unexpected unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Percent ||
aValue2.GetUnit() == eCSSUnit_Pixel ||
aValue2.IsCalcUnit(),
"unexpected unit");
AddCSSValuePixelPercentCalc(0,
(aValue1.GetUnit() != aValue2.GetUnit() ||
aValue1.IsCalcUnit())
? eCSSUnit_Calc
: aValue1.GetUnit(),
aCoeff1, aValue1,
aCoeff2, aValue2,
aResult);
}
// Unclamped AddWeightedColors.
static RGBAColorData
AddWeightedColors(double aCoeff1, const RGBAColorData& aValue1,
double aCoeff2, const RGBAColorData& aValue2)
{
float factor1 = aValue1.mA * aCoeff1;
float factor2 = aValue2.mA * aCoeff2;
float resultA = factor1 + factor2;
if (resultA <= 0.0) {
return {0, 0, 0, 0};
}
if (resultA > 1.0) {
resultA = 1.0;
}
float resultFactor = 1.0f / resultA;
return RGBAColorData(
(aValue1.mR * factor1 + aValue2.mR * factor2) * resultFactor,
(aValue1.mG * factor1 + aValue2.mG * factor2) * resultFactor,
(aValue1.mB * factor1 + aValue2.mB * factor2) * resultFactor,
resultA);
}
// CLASS METHODS
// -------------
static RGBAColorData
ExtractColor(const nsCSSValue& aValue)
{
MOZ_ASSERT(aValue.IsNumericColorUnit(), "The unit should be color");
// PercentageRGBColor and PercentageRGBAColor component value might be
// greater than 1.0 in case when the color value is accumulated, so we
// can't use nsCSSValue::GetColorValue() here because that function
// clamps its values.
if (aValue.GetUnit() == eCSSUnit_PercentageRGBColor ||
aValue.GetUnit() == eCSSUnit_PercentageRGBAColor) {
nsCSSValueFloatColor* floatColor = aValue.GetFloatColorValue();
return {
floatColor->Comp1(),
floatColor->Comp2(),
floatColor->Comp3(),
floatColor->Alpha()
};
}
return RGBAColorData(aValue.GetColorValue());
}
static RGBAColorData
ExtractColor(const StyleAnimationValue& aValue)
{
MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Color);
nsCSSValue* value = aValue.GetCSSValueValue();
MOZ_ASSERT(value, "CSS value must be valid");
return ExtractColor(*value);
}
static ComplexColorData
ExtractComplexColor(const StyleAnimationValue& aValue)
{
switch (aValue.GetUnit()) {
case StyleAnimationValue::eUnit_Color:
return ComplexColorData(ExtractColor(aValue), 0.0f);
case StyleAnimationValue::eUnit_CurrentColor:
return ComplexColorData({0, 0, 0, 0}, 1.0f);
case StyleAnimationValue::eUnit_ComplexColor:
return ComplexColorData(aValue.GetComplexColorData());
default:
MOZ_ASSERT_UNREACHABLE("Unknown unit");
return ComplexColorData({0, 0, 0, 0}, 0.0f);
}
}
StyleAnimationValue
StyleAnimationValue::Add(nsCSSPropertyID aProperty,
const StyleAnimationValue& aA,
StyleAnimationValue&& aB)
{
StyleAnimationValue result(Move(aB));
Unit commonUnit =
GetCommonUnit(aProperty, result.GetUnit(), aA.GetUnit());
switch (commonUnit) {
case eUnit_Color: {
RGBAColorData color1 = ExtractColor(result);
RGBAColorData color2 = ExtractColor(aA);
result.mValue.mCSSValue->SetRGBAColorValue(
AddWeightedColors(1.0, color1, 1, color2));
break;
}
case eUnit_Filter:
case eUnit_Shadow: {
// If |aA| has no function list, don't concatinate anything, just return
// |aB| as the result.
if (!aA.GetCSSValueListValue() ||
aA.GetCSSValueListValue()->mValue.GetUnit() == eCSSUnit_None) {
break;
}
UniquePtr<nsCSSValueList> resultList(aA.GetCSSValueListValue()->Clone());
// If |aB| has function list, concatinate it to |aA|, then return
// the concatinated list.
if (result.GetCSSValueListValue() &&
result.GetCSSValueListValue()->mValue.GetUnit() != eCSSUnit_None) {
nsCSSValueList* listA = resultList.get();
while (listA->mNext) {
listA = listA->mNext;
}
listA->mNext = result.GetCSSValueListValue();
}
result.mValue.mCSSValueList = resultList.release();
break;
}
case eUnit_Transform: {
// If |aA| is 'transform:none', don't concatinate anything, just return
// |aB| as the result.
if (aA.GetCSSValueSharedListValue()->mHead->mValue.GetUnit() ==
eCSSUnit_None) {
break;
}
UniquePtr<nsCSSValueList>
resultList(aA.GetCSSValueSharedListValue()->mHead->Clone());
// If |aB| is not 'transform:none', concatinate it to |aA|, then return
// the concatinated list.
if (result.GetCSSValueSharedListValue()->mHead->mValue.GetUnit() !=
eCSSUnit_None) {
nsCSSValueList* listA = resultList.get();
while (listA->mNext) {
listA = listA->mNext;
}
listA->mNext = result.GetCSSValueSharedListValue()->mHead->Clone();
}
result.SetTransformValue(new nsCSSValueSharedList(resultList.release()));
break;
}
default:
Unused << AddWeighted(aProperty,
1.0, result,
1, aA,
result);
break;
}
return result;
}
double
StyleAnimationValue::ComputeColorDistance(const RGBAColorData& aStartColor,
const RGBAColorData& aEndColor)
{
// http://www.w3.org/TR/smil-animation/#animateColorElement says
// that we should use Euclidean RGB cube distance. However, we
// have to extend that to RGBA. For now, we'll just use the
// Euclidean distance in the (part of the) 4-cube of premultiplied
// colors.
double startA = aStartColor.mA;
double startR = aStartColor.mR * startA;
double startG = aStartColor.mG * startA;
double startB = aStartColor.mB * startA;
double endA = aEndColor.mA;
double endR = aEndColor.mR * endA;
double endG = aEndColor.mG * endA;
double endB = aEndColor.mB * endA;
double diffA = startA - endA;
double diffR = startR - endR;
double diffG = startG - endG;
double diffB = startB - endB;
return sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB);
}
enum class ColorAdditionType {
Clamped, // Clamp each color channel after adding.
Unclamped // Do not clamp color channels after adding.
};
static UniquePtr<nsCSSValueList>
AddWeightedFilterFunction(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
ColorAdditionType aColorAdditionType);
static inline float
GetNumberOrPercent(const nsCSSValue &aValue);
static bool
ComputeSingleShadowSquareDistance(const nsCSSValueList* aShadow1,
const nsCSSValueList* aShadow2,
double& aSquareDistance,
nsCSSPropertyID aProperty)
{
MOZ_ASSERT(aShadow1->mValue.GetUnit() == eCSSUnit_Array, "wrong unit");
MOZ_ASSERT(aShadow2->mValue.GetUnit() == eCSSUnit_Array, "wrong unit");
const nsCSSValue::Array* array1 = aShadow1->mValue.GetArrayValue();
const nsCSSValue::Array* array2 = aShadow2->mValue.GetArrayValue();
double squareDistance = 0.0;
// X, Y, Radius, Spread
for (size_t i = 0; i < 4; ++i) {
// Spread value is not necessary on text-shadow,
// so we skip the computing distance.
if (i == 3 && (aProperty != eCSSProperty_box_shadow)) {
continue;
}
MOZ_ASSERT(array1->Item(i).GetUnit() == eCSSUnit_Pixel,
"unexpected unit");
MOZ_ASSERT(array2->Item(i).GetUnit() == eCSSUnit_Pixel,
"unexpected unit");
double diff = array1->Item(i).GetFloatValue() -
array2->Item(i).GetFloatValue();
squareDistance += diff * diff;
}
// Color, Inset
const nsCSSValue& color1 = array1->Item(4);
const nsCSSValue& color2 = array2->Item(4);
const nsCSSValue& inset1 = array1->Item(5);
const nsCSSValue& inset2 = array2->Item(5);
if ((color1.GetUnit() != color2.GetUnit() &&
(!color1.IsNumericColorUnit() ||
!color2.IsNumericColorUnit())) ||
inset1 != inset2) {
// According to AddWeightedShadowItems, we don't know how to animate
// between color and no-color, or between inset and not-inset,
// so we cannot compute the distance either.
// Note: There are only two possible states of the inset value:
// (1) GetUnit() == eCSSUnit_Null
// (2) GetUnit() == eCSSUnit_Enumerated &&
// GetIntValue() == NS_STYLE_BOX_SHADOW_INSET
return false;
}
// We compute the distance of colors only if both are numeric color units.
if (color1.GetUnit() != eCSSUnit_Null) {
double colorDistance =
StyleAnimationValue::ComputeColorDistance(ExtractColor(color1),
ExtractColor(color2));
squareDistance += colorDistance * colorDistance;
}
aSquareDistance = squareDistance;
return true;
}
// Return false if we cannot compute the distance between these filter
// functions.
static bool
ComputeFilterSquareDistance(const nsCSSValueList* aList1,
const nsCSSValueList* aList2,
double& aSquareDistance)
{
MOZ_ASSERT(aList1, "expected filter list");
MOZ_ASSERT(aList2, "expected filter list");
MOZ_ASSERT(aList1->mValue.GetUnit() == eCSSUnit_Function,
"expected function");
MOZ_ASSERT(aList2->mValue.GetUnit() == eCSSUnit_Function,
"expected function");
RefPtr<nsCSSValue::Array> a1 = aList1->mValue.GetArrayValue();
RefPtr<nsCSSValue::Array> a2 = aList2->mValue.GetArrayValue();
nsCSSKeyword filterFunction = a1->Item(0).GetKeywordValue();
if (filterFunction != a2->Item(0).GetKeywordValue()) {
return false;
}
const nsCSSValue& func1 = a1->Item(1);
const nsCSSValue& func2 = a2->Item(1);
switch (filterFunction) {
case eCSSKeyword_blur: {
nsCSSValue diff;
// In AddWeightedFilterFunctionImpl, blur may have different units, so we
// use eCSSUnit_Calc for that case.
if (!AddCSSValuePixelPercentCalc(0,
func1.GetUnit() == func2.GetUnit()
? func1.GetUnit()
: eCSSUnit_Calc,
1.0, func2,
-1.0, func1,
diff)) {
return false;
}
// ExtractCalcValue makes sure mHasPercent and mPercent are correct.
PixelCalcValue v = ExtractCalcValue(diff);
aSquareDistance = v.mLength * v.mLength + v.mPercent * v.mPercent;
break;
}
case eCSSKeyword_grayscale:
case eCSSKeyword_invert:
case eCSSKeyword_sepia:
case eCSSKeyword_brightness:
case eCSSKeyword_contrast:
case eCSSKeyword_opacity:
case eCSSKeyword_saturate: {
double diff =
EnsureNotNan(GetNumberOrPercent(func2) - GetNumberOrPercent(func1));
aSquareDistance = diff * diff;
break;
}
case eCSSKeyword_hue_rotate: {
nsCSSValue v;
AddCSSValueAngle(1.0, func2, -1.0, func1, v);
double diff = v.GetAngleValueInRadians();
aSquareDistance = diff * diff;
break;
}
case eCSSKeyword_drop_shadow: {
MOZ_ASSERT(!func1.GetListValue()->mNext && !func2.GetListValue()->mNext,
"drop-shadow filter func doesn't support lists");
if (!ComputeSingleShadowSquareDistance(func1.GetListValue(),
func2.GetListValue(),
aSquareDistance,
eCSSProperty_filter)) {
return false;
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE("unknown filter function");
return false;
}
return true;
}
static bool
ComputeFilterListDistance(const nsCSSValueList* aList1,
const nsCSSValueList* aList2,
double& aDistance)
{
double squareDistance = 0.0;
while (aList1 || aList2) {
// Return false if one of the lists is neither none nor a function.
if ((aList1 && aList1->mValue.GetUnit() != eCSSUnit_Function) ||
(aList2 && aList2->mValue.GetUnit() != eCSSUnit_Function)) {
return false;
}
MOZ_ASSERT(aList1 || aList2, "one function list item must not be null");
double currentSquareDistance = 0.0;
if (!aList1) {
// This is a tricky to get an equivalent none filter function by 0.0
// coefficients. Although we don't guarantee this function can get the
// correct default values, it can reuse the code from the interpolation.
UniquePtr<nsCSSValueList> none =
AddWeightedFilterFunction(0, aList2, 0, aList2,
ColorAdditionType::Clamped);
if (!ComputeFilterSquareDistance(none.get(), aList2,
currentSquareDistance)) {
return false;
}
aList2 = aList2->mNext;
} else if (!aList2) {
UniquePtr<nsCSSValueList> none =
AddWeightedFilterFunction(0, aList1, 0, aList1,
ColorAdditionType::Clamped);
if (!ComputeFilterSquareDistance(aList1, none.get(),
currentSquareDistance)) {
return false;
}
aList1 = aList1->mNext;
} else {
if (!ComputeFilterSquareDistance(aList1, aList2,
currentSquareDistance)) {
return false;
}
aList1 = aList1->mNext;
aList2 = aList2->mNext;
}
squareDistance += currentSquareDistance;
}
aDistance = sqrt(squareDistance);
return true;
}
enum class Restrictions {
Enable,
Disable
};
static already_AddRefed<nsCSSValue::Array>
AddShapeFunction(nsCSSPropertyID aProperty,
double aCoeff1, const nsCSSValue::Array* aArray1,
double aCoeff2, const nsCSSValue::Array* aArray2,
Restrictions aRestriction = Restrictions::Enable);
static bool
ComputeShapeDistance(nsCSSPropertyID aProperty,
const nsCSSValue::Array* aArray1,
const nsCSSValue::Array* aArray2,
double& aDistance)
{
// Use AddShapeFunction to get the difference between two shape functions.
RefPtr<nsCSSValue::Array> diffShape =
AddShapeFunction(aProperty, 1.0, aArray2, -1.0, aArray1,
Restrictions::Disable);
if (!diffShape) {
return false;
}
// A helper function to convert a calc() diff value into a double distance.
auto pixelCalcDistance = [](const PixelCalcValue& aValue) {
MOZ_ASSERT(aValue.mHasPercent || aValue.mPercent == 0.0f,
"can't have a nonzero percentage part without having percentages");
return aValue.mLength * aValue.mLength + aValue.mPercent * aValue.mPercent;
};
double squareDistance = 0.0;
const nsCSSValue::Array* func = diffShape->Item(0).GetArrayValue();
nsCSSKeyword shapeFuncName = func->Item(0).GetKeywordValue();
switch (shapeFuncName) {
case eCSSKeyword_ellipse:
case eCSSKeyword_circle: {
// Skip the first element which is the function keyword.
// Also, skip the last element which is an array for <position>
const size_t len = func->Count();
for (size_t i = 1; i < len - 1; ++i) {
squareDistance += pixelCalcDistance(ExtractCalcValue(func->Item(i)));
}
// Only iterate over elements 1 and 3. The <position> is 'uncomputed' to
// only those elements. See also the comment in SetPositionValue.
for (size_t i = 1; i < 4; i += 2) {
const nsCSSValue& value = func->Item(len - 1).GetArrayValue()->Item(i);
squareDistance += pixelCalcDistance(ExtractCalcValue(value));
}
break;
}
case eCSSKeyword_polygon: {
// Don't care about the first element which is the function keyword, and
// the second element which is the fill rule.
const nsCSSValuePairList* list = func->Item(2).GetPairListValue();
do {
squareDistance += pixelCalcDistance(ExtractCalcValue(list->mXValue)) +
pixelCalcDistance(ExtractCalcValue(list->mYValue));
list = list->mNext;
} while (list);
break;
}
case eCSSKeyword_inset: {
// Items 1-4 are respectively the top, right, bottom and left offsets
// from the reference box.
for (size_t i = 1; i <= 4; ++i) {
const nsCSSValue& value = func->Item(i);
squareDistance += pixelCalcDistance(ExtractCalcValue(value));
}
// Item 5 contains the radii of the rounded corners for the inset
// rectangle.
const nsCSSValue::Array* array = func->Item(5).GetArrayValue();
const size_t len = array->Count();
for (size_t i = 0; i < len; ++i) {
const nsCSSValuePair& pair = array->Item(i).GetPairValue();
squareDistance += pixelCalcDistance(ExtractCalcValue(pair.mXValue)) +
pixelCalcDistance(ExtractCalcValue(pair.mYValue));
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unknown shape type");
}
aDistance = sqrt(squareDistance);
return true;
}
static nsCSSValueList*
AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
nsCSSKeyword aOperatorType = eCSSKeyword_interpolatematrix);
static double
ComputeTransform2DMatrixDistance(const Matrix& aMatrix1,
const Matrix& aMatrix2)
{
Point3D scale1(1, 1, 1);
Point3D translate1;
gfxQuaternion rotate1;
nsStyleTransformMatrix::ShearArray shear1{0.0f, 0.0f, 0.0f};
Decompose2DMatrix(aMatrix1, scale1, shear1, rotate1, translate1);
Point3D scale2(1, 1, 1);
Point3D translate2;
gfxQuaternion rotate2;
nsStyleTransformMatrix::ShearArray shear2{0.0f, 0.0f, 0.0f};
Decompose2DMatrix(aMatrix2, scale2, shear2, rotate2, translate2);
// Note:
// 1. Shear factor is the tangent value of shear angle, so we need to
// call atan() to get the angle. For 2D transform, we only have XYSHEAR.
// 2. The quaternion vector of the decomposed 2d matrix is got by
// "gfxQuaternion(0, 0, sin(rotate/2), cos(rotate/2))"
// ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
// z w
// Therefore, we can get the rotate angle by 2 * atan2f(z, w).
//
// However, we can also get the rotate angle by the inner product of
// two quaternion vectors, just as what we do for eCSSKeyword_rotate3d.
// e.g.
// rotate3d(0, 0, 1, 60deg) => rotate3d(0, 0, 1, 120deg);
// quaternion 1: (0, 0, sin(30deg), cos(30deg)) = (0, 0, 1/2, sqrt(3)/2)
// quaternion 2: (0, 0, sin(60deg), cos(60deg)) = (0, 0, sqrt(3)/2, 1/2)
// inner product: sqrt(3)/4 + sqrt(3)/4 = sqrt(3)/2
// Finally, the rotate angle: 2 * acos(sqrt(3)/2) = 60deg
//
// I think doing atan() may be faster than doing inner product together
// with acos(), so let's adopt atan2f().
const Point3D diffTranslate = translate2 - translate1;
const Point3D diffScale = scale2 - scale1;
const double diffShear = atan(shear2[ShearType::XYSHEAR]) -
atan(shear1[ShearType::XYSHEAR]);
const double diffRotate = 2.0 * (atan2f(rotate2.z, rotate2.w) -
atan2f(rotate1.z, rotate1.w));
// Returns the sum of squares because we will take a square root in
// ComputeTransformListDistance.
return diffTranslate.DotProduct(diffTranslate) +
diffScale.DotProduct(diffScale) +
diffRotate * diffRotate +
diffShear * diffShear;
}
static double
ComputeTransform3DMatrixDistance(const Matrix4x4& aMatrix1,
const Matrix4x4& aMatrix2)
{
Point3D scale1(1, 1, 1);
Point3D translate1;
Point4D perspective1(0, 0, 0, 1);
gfxQuaternion rotate1;
nsStyleTransformMatrix::ShearArray shear1{0.0f, 0.0f, 0.0f};
Decompose3DMatrix(aMatrix1, scale1, shear1, rotate1, translate1,
perspective1);
Point3D scale2(1, 1, 1);
Point3D translate2;
Point4D perspective2(0, 0, 0, 1);
gfxQuaternion rotate2;
nsStyleTransformMatrix::ShearArray shear2{0.0f, 0.0f, 0.0f};
Decompose3DMatrix(aMatrix2, scale2, shear2, rotate2, translate2,
perspective2);
// Note:
// 1. Shear factor is the tangent value of shear angle, so we need to
// call atan() to get the angle.
// 2. We use the same way to get the rotate angle of two quaternion vectors as
// what we do for rotate3d.
const Point3D diffTranslate = translate2 - translate1;
const Point3D diffScale = scale2 - scale1;
const Point3D diffShear(atan(shear2[ShearType::XYSHEAR]) -
atan(shear1[ShearType::XYSHEAR]),
atan(shear2[ShearType::XZSHEAR]) -
atan(shear1[ShearType::XZSHEAR]),
atan(shear2[ShearType::YZSHEAR]) -
atan(shear1[ShearType::YZSHEAR]));
const Point4D diffPerspective = perspective2 - perspective1;
const double dot = clamped(rotate1.DotProduct(rotate2), -1.0, 1.0);
const double diffRotate = 2.0 * acos(dot);
// Returns the sum of squares because we will take a square root in
// ComputeTransformListDistance.
return diffTranslate.DotProduct(diffTranslate) +
diffScale.DotProduct(diffScale) +
diffPerspective.DotProduct(diffPerspective) +
diffShear.DotProduct(diffShear) +
diffRotate * diffRotate;
}
static double
ComputeTransformDistance(nsCSSValue::Array* aArray1,
nsCSSValue::Array* aArray2)
{
MOZ_ASSERT(aArray1, "aArray1 should be non-null.");
MOZ_ASSERT(aArray2, "aArray2 should be non-null.");
// Normalize translate and scale functions to equivalent "translate3d" and
// "scale3d" functions.
RefPtr<nsCSSValue::Array> a1 = ToPrimitive(aArray1),
a2 = ToPrimitive(aArray2);
nsCSSKeyword tfunc = nsStyleTransformMatrix::TransformFunctionOf(a1);
MOZ_ASSERT(nsStyleTransformMatrix::TransformFunctionOf(a2) == tfunc);
double distance = 0.0;
switch (tfunc) {
case eCSSKeyword_translate3d: {
MOZ_ASSERT(a1->Count() == 4, "unexpected count");
MOZ_ASSERT(a2->Count() == 4, "unexpected count");
nsCSSValue x, y, z;
AddTransformTranslate(1.0, a2->Item(1), -1.0, a1->Item(1), x);
AddTransformTranslate(1.0, a2->Item(2), -1.0, a1->Item(2), y);
AddTransformTranslate(1.0, a2->Item(3), -1.0, a1->Item(3), z);
// Drop percent part because we only compute distance by computed values.
double c1 = ExtractCalcValue(x).mLength;
double c2 = ExtractCalcValue(y).mLength;
double c3 = z.GetFloatValue();
distance = c1 * c1 + c2 * c2 + c3 * c3;
break;
}
case eCSSKeyword_scale3d: {
MOZ_ASSERT(a1->Count() == 4, "unexpected count");
MOZ_ASSERT(a2->Count() == 4, "unexpected count");
auto ComputeScaleDiff = [](const nsCSSValue& aValue1,
const nsCSSValue& aValue2) {
float v1 = aValue1.GetFloatValue();
float v2 = aValue2.GetFloatValue();
return EnsureNotNan(v2 - v1);
};
double c1 = ComputeScaleDiff(a1->Item(1), a2->Item(1));
double c2 = ComputeScaleDiff(a1->Item(2), a2->Item(2));
double c3 = ComputeScaleDiff(a1->Item(3), a2->Item(3));
distance = c1 * c1 + c2 * c2 + c3 * c3;
break;
}
case eCSSKeyword_skew: {
MOZ_ASSERT(a1->Count() == 2 || a1->Count() == 3, "unexpected count");
MOZ_ASSERT(a2->Count() == 2 || a2->Count() == 3, "unexpected count");
const nsCSSValue zero(0.0f, eCSSUnit_Radian);
nsCSSValue x, y;
AddCSSValueAngle(1.0, a2->Item(1), -1.0, a1->Item(1), x);
AddCSSValueAngle(1.0, a2->Count() == 3 ? a2->Item(2) : zero,
-1.0, a1->Count() == 3 ? a1->Item(2) : zero,
y);
distance = x.GetAngleValueInRadians() * x.GetAngleValueInRadians() +
y.GetAngleValueInRadians() * y.GetAngleValueInRadians();
break;
}
case eCSSKeyword_skewx:
case eCSSKeyword_skewy:
case eCSSKeyword_rotate:
case eCSSKeyword_rotatex:
case eCSSKeyword_rotatey:
case eCSSKeyword_rotatez: {
MOZ_ASSERT(a1->Count() == 2, "unexpected count");
MOZ_ASSERT(a2->Count() == 2, "unexpected count");
nsCSSValue angle;
AddCSSValueAngle(1.0, a2->Item(1), -1.0, a1->Item(1), angle);
distance = angle.GetAngleValueInRadians() *
angle.GetAngleValueInRadians();
break;
}
case eCSSKeyword_rotate3d: {
MOZ_ASSERT(a1->Count() == 5, "unexpected count");
MOZ_ASSERT(a2->Count() == 5, "unexpected count");
Point3D vector1(a1->Item(1).GetFloatValue(),
a1->Item(2).GetFloatValue(),
a1->Item(3).GetFloatValue());
double angle1 = a1->Item(4).GetAngleValueInRadians();
Point3D vector2(a2->Item(1).GetFloatValue(),
a2->Item(2).GetFloatValue(),
a2->Item(3).GetFloatValue());
double angle2 = a2->Item(4).GetAngleValueInRadians();
auto normalizeVector = [](Point3D& vector, double& angle) {
if (vector.Length() > 0) {
vector.Normalize();
} else {
vector.x = 0.0;
vector.y = 0.0;
vector.z = 1.0;
angle = 0.0;
}
};
normalizeVector(vector1, angle1);
normalizeVector(vector2, angle2);
if (vector1 == vector2) {
// Handle rotate3d with matched (normalized) vectors.
distance = EnsureNotNan(angle2 - angle1);
} else {
// Use quaternion vectors to get the angle difference. Both q1 and q2
// are unit vectors, so we can get their angle difference by
// cos(theta/2) = (q1 dot q2) / (|q1| * |q2|) = q1 dot q2.
gfxQuaternion q1(vector1, angle1);
gfxQuaternion q2(vector2, angle2);
distance =
EnsureNotNan(2.0 * acos(clamped(q1.DotProduct(q2), -1.0, 1.0)));
}
distance = distance * distance;
break;
}
case eCSSKeyword_perspective: {
MOZ_ASSERT(a1->Count() == 2, "unexpected count");
MOZ_ASSERT(a2->Count() == 2, "unexpected count");
// We convert a perspective function into an equivalent matrix3d, and
// then do matrix decomposition to get the distance.
// Why don't we just subtract one perspective depth from the other?
// I think it's better to follow the logic of our interpolation,
// which does linear interpolation between two decomposed perspective
// vectors.
// e.g.
// Do interpolation between perspective(100px) and perspective(1000px).
// 1) Convert them into matrix3d, and then do matrix decomposition:
// perspective vector 1: perspective(0, 0, -1/100, 1);
// perspective vector 2: perspective(0, 0, -1/1000, 1);
// 2) Do linear interpolation between these two vectors.
// Therefore, we use the same rule to get the distance as what we do for
// matrix3d.
using nsStyleTransformMatrix::ApplyPerspectiveToMatrix;
Matrix4x4 m1;
ApplyPerspectiveToMatrix(m1, a1->Item(1).GetFloatValue());
Matrix4x4 m2;
ApplyPerspectiveToMatrix(m2, a2->Item(1).GetFloatValue());
distance = ComputeTransform3DMatrixDistance(m1, m2);
break;
}
case eCSSKeyword_matrix: {
MOZ_ASSERT(a1->Count() == 7, "unexpected count");
MOZ_ASSERT(a2->Count() == 7, "unexpected count");
distance = ComputeTransform2DMatrixDistance(
nsStyleTransformMatrix::CSSValueArrayTo2DMatrix(a1),
nsStyleTransformMatrix::CSSValueArrayTo2DMatrix(a2));
break;
}
case eCSSKeyword_matrix3d: {
MOZ_ASSERT(a1->Count() == 17, "unexpected count");
MOZ_ASSERT(a2->Count() == 17, "unexpected count");
distance = ComputeTransform3DMatrixDistance(
nsStyleTransformMatrix::CSSValueArrayTo3DMatrix(a1),
nsStyleTransformMatrix::CSSValueArrayTo3DMatrix(a2));
break;
}
case eCSSKeyword_interpolatematrix:
case eCSSKeyword_accumulatematrix:
default:
MOZ_ASSERT_UNREACHABLE("Unsupported transform function");
break;
}
return distance;
}
static double
ComputeTransformListDistance(const nsCSSValueList* aList1,
const nsCSSValueList* aList2)
{
MOZ_ASSERT(aList1, "aList1 should be non-null.");
MOZ_ASSERT(aList2, "aList2 should be non-null.");
double distance = 0.0;
do {
distance += ComputeTransformDistance(aList1->mValue.GetArrayValue(),
aList2->mValue.GetArrayValue());
aList1 = aList1->mNext;
aList2 = aList2->mNext;
MOZ_ASSERT(!aList1 == !aList2,
"aList1 and aList2 should have the same length.");
} while (aList1);
return sqrt(distance);
}
static double
ComputeMismatchedTransfromListDistance(const nsCSSValueList* aList1,
const nsCSSValueList* aList2,
GeckoStyleContext* aStyleContext)
{
// We need nsStyleContext and nsPresContext to compute calc() values while
// processing the translate part of transforms.
if (!aStyleContext) {
return 0.0;
}
RuleNodeCacheConditions dontCare;
bool dontCareBool;
nsStyleTransformMatrix::TransformReferenceBox emptyRefBox;
Matrix4x4 m1 = nsStyleTransformMatrix::ReadTransforms(
aList1,
aStyleContext,
aStyleContext->PresContext(),
dontCare,
emptyRefBox,
nsPresContext::AppUnitsPerCSSPixel(),
&dontCareBool);
Matrix4x4 m2 = nsStyleTransformMatrix::ReadTransforms(
aList2,
aStyleContext,
aStyleContext->PresContext(),
dontCare,
emptyRefBox,
nsPresContext::AppUnitsPerCSSPixel(),
&dontCareBool);
return sqrt(ComputeTransform3DMatrixDistance(m1, m2));
}
bool
StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
const StyleAnimationValue& aStartValue,
const StyleAnimationValue& aEndValue,
GeckoStyleContext* aStyleContext,
double& aDistance)
{
Unit commonUnit =
GetCommonUnit(aProperty, aStartValue.GetUnit(), aEndValue.GetUnit());
switch (commonUnit) {
case eUnit_Null:
case eUnit_Auto:
case eUnit_None:
case eUnit_Normal:
case eUnit_UnparsedString:
case eUnit_URL:
case eUnit_DiscreteCSSValue:
return false;
case eUnit_Enumerated:
switch (aProperty) {
case eCSSProperty_font_stretch: {
// just like eUnit_Integer.
int32_t startInt = aStartValue.GetIntValue();
int32_t endInt = aEndValue.GetIntValue();
aDistance = Abs(endInt - startInt);
return true;
}
default:
return false;
}
case eUnit_Visibility: {
int32_t startEnum = aStartValue.GetIntValue();
int32_t endEnum = aEndValue.GetIntValue();
if (startEnum == endEnum) {
aDistance = 0;
return true;
}
if ((startEnum == NS_STYLE_VISIBILITY_VISIBLE) ==
(endEnum == NS_STYLE_VISIBILITY_VISIBLE)) {
return false;
}
aDistance = 1;
return true;
}
case eUnit_Integer: {
int32_t startInt = aStartValue.GetIntValue();
int32_t endInt = aEndValue.GetIntValue();
aDistance = Abs(double(endInt) - double(startInt));
return true;
}
case eUnit_Coord: {
nscoord startCoord = aStartValue.GetCoordValue();
nscoord endCoord = aEndValue.GetCoordValue();
aDistance = Abs(double(endCoord) - double(startCoord));
return true;
}
case eUnit_Percent: {
float startPct = aStartValue.GetPercentValue();
float endPct = aEndValue.GetPercentValue();
aDistance = Abs(double(endPct) - double(startPct));
return true;
}
case eUnit_Float: {
float startFloat = aStartValue.GetFloatValue();
float endFloat = aEndValue.GetFloatValue();
aDistance = Abs(double(endFloat) - double(startFloat));
return true;
}
case eUnit_Color: {
aDistance = ComputeColorDistance(ExtractColor(aStartValue),
ExtractColor(aEndValue));
return true;
}
case eUnit_CurrentColor: {
aDistance = 0;
return true;
}
case eUnit_ComplexColor: {
ComplexColorData color1 = ExtractComplexColor(aStartValue);
ComplexColorData color2 = ExtractComplexColor(aEndValue);
// Common case is interpolating between a color and a currentcolor
if (color1.IsNumericColor() && color2.IsCurrentColor()) {
double dist = ComputeColorDistance(color1.mColor, NS_RGBA(0, 0, 0, 0));
aDistance = sqrt(dist * dist + 1);
return true;
}
if (color1.IsCurrentColor() && color2.IsNumericColor()) {
double dist = ComputeColorDistance(NS_RGBA(0, 0, 0, 0), color2.mColor);
aDistance = sqrt(dist * dist + 1);
return true;
}
// If we ever reach here, we may want to use the code in
// bug 1299741 comment 79 to compute it.
MOZ_ASSERT_UNREACHABLE("We shouldn't get here as we only call "
"ComputeDistance on pre-interpolation values");
aDistance = 0.0;
return true;
}
case eUnit_Calc: {
PixelCalcValue v1 = ExtractCalcValue(aStartValue);
PixelCalcValue v2 = ExtractCalcValue(aEndValue);
float difflen = v2.mLength - v1.mLength;
float diffpct = v2.mPercent - v1.mPercent;
aDistance = sqrt(difflen * difflen + diffpct * diffpct);
return true;
}
case eUnit_ObjectPosition: {
const nsCSSValue* position1 = aStartValue.GetCSSValueValue();
const nsCSSValue* position2 = aEndValue.GetCSSValueValue();
double squareDistance =
CalcPositionSquareDistance(*position1,
*position2);
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_CSSValuePair: {
const nsCSSValuePair *pair1 = aStartValue.GetCSSValuePairValue();
const nsCSSValuePair *pair2 = aEndValue.GetCSSValuePairValue();
nsCSSUnit unit[2];
unit[0] = GetCommonUnit(aProperty, pair1->mXValue.GetUnit(),
pair2->mXValue.GetUnit());
unit[1] = GetCommonUnit(aProperty, pair1->mYValue.GetUnit(),
pair2->mYValue.GetUnit());
if (unit[0] == eCSSUnit_Null || unit[1] == eCSSUnit_Null ||
unit[0] == eCSSUnit_URL || unit[0] == eCSSUnit_Enumerated) {
return false;
}
double squareDistance = 0.0;
static nsCSSValue nsCSSValuePair::* const pairValues[2] = {
&nsCSSValuePair::mXValue, &nsCSSValuePair::mYValue
};
for (uint32_t i = 0; i < 2; ++i) {
nsCSSValue nsCSSValuePair::*member = pairValues[i];
double diffsquared;
switch (unit[i]) {
case eCSSUnit_Pixel: {
float diff = (pair1->*member).GetFloatValue() -
(pair2->*member).GetFloatValue();
diffsquared = diff * diff;
break;
}
case eCSSUnit_Percent: {
float diff = (pair1->*member).GetPercentValue() -
(pair2->*member).GetPercentValue();
diffsquared = diff * diff;
break;
}
case eCSSUnit_Calc: {
PixelCalcValue v1 = ExtractCalcValue(pair1->*member);
PixelCalcValue v2 = ExtractCalcValue(pair2->*member);
float difflen = v2.mLength - v1.mLength;
float diffpct = v2.mPercent - v1.mPercent;
diffsquared = difflen * difflen + diffpct * diffpct;
break;
}
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
squareDistance += diffsquared;
}
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_CSSValueTriplet: {
const nsCSSValueTriplet *triplet1 = aStartValue.GetCSSValueTripletValue();
const nsCSSValueTriplet *triplet2 = aEndValue.GetCSSValueTripletValue();
nsCSSUnit unit[3];
unit[0] = GetCommonUnit(aProperty, triplet1->mXValue.GetUnit(),
triplet2->mXValue.GetUnit());
unit[1] = GetCommonUnit(aProperty, triplet1->mYValue.GetUnit(),
triplet2->mYValue.GetUnit());
unit[2] = GetCommonUnit(aProperty, triplet1->mZValue.GetUnit(),
triplet2->mZValue.GetUnit());
if (unit[0] == eCSSUnit_Null || unit[1] == eCSSUnit_Null ||
unit[2] == eCSSUnit_Null) {
return false;
}
double squareDistance = 0.0;
static nsCSSValue nsCSSValueTriplet::* const pairValues[3] = {
&nsCSSValueTriplet::mXValue, &nsCSSValueTriplet::mYValue, &nsCSSValueTriplet::mZValue
};
for (uint32_t i = 0; i < 3; ++i) {
nsCSSValue nsCSSValueTriplet::*member = pairValues[i];
double diffsquared;
switch (unit[i]) {
case eCSSUnit_Pixel: {
float diff = (triplet1->*member).GetFloatValue() -
(triplet2->*member).GetFloatValue();
diffsquared = diff * diff;
break;
}
case eCSSUnit_Percent: {
float diff = (triplet1->*member).GetPercentValue() -
(triplet2->*member).GetPercentValue();
diffsquared = diff * diff;
break;
}
case eCSSUnit_Calc: {
PixelCalcValue v1 = ExtractCalcValue(triplet1->*member);
PixelCalcValue v2 = ExtractCalcValue(triplet2->*member);
float difflen = v2.mLength - v1.mLength;
float diffpct = v2.mPercent - v1.mPercent;
diffsquared = difflen * difflen + diffpct * diffpct;
break;
}
case eCSSUnit_Null:
diffsquared = 0;
break;
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
squareDistance += diffsquared;
}
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_CSSRect: {
const nsCSSRect *rect1 = aStartValue.GetCSSRectValue();
const nsCSSRect *rect2 = aEndValue.GetCSSRectValue();
if (rect1->mTop.GetUnit() != rect2->mTop.GetUnit() ||
rect1->mRight.GetUnit() != rect2->mRight.GetUnit() ||
rect1->mBottom.GetUnit() != rect2->mBottom.GetUnit() ||
rect1->mLeft.GetUnit() != rect2->mLeft.GetUnit()) {
// At least until we have calc()
return false;
}
double squareDistance = 0.0;
for (uint32_t i = 0; i < ArrayLength(nsCSSRect::sides); ++i) {
nsCSSValue nsCSSRect::*member = nsCSSRect::sides[i];
MOZ_ASSERT((rect1->*member).GetUnit() == (rect2->*member).GetUnit(),
"should have returned above");
double diff;
switch ((rect1->*member).GetUnit()) {
case eCSSUnit_Pixel:
diff = (rect1->*member).GetFloatValue() -
(rect2->*member).GetFloatValue();
break;
case eCSSUnit_Auto:
diff = 0;
break;
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
squareDistance += diff * diff;
}
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_Dasharray: {
// NOTE: This produces results on substantially different scales
// for length values and percentage values, which might even be
// mixed in the same property value. This means the result isn't
// particularly useful for paced animation.
// Call AddWeighted to make us lists of the same length.
StyleAnimationValue normValue1, normValue2;
if (!AddWeighted(aProperty, 1.0, aStartValue, 0.0, aEndValue,
normValue1) ||
!AddWeighted(aProperty, 0.0, aStartValue, 1.0, aEndValue,
normValue2)) {
return false;
}
double squareDistance = 0.0;
const nsCSSValueList *list1 = normValue1.GetCSSValueListValue();
const nsCSSValueList *list2 = normValue2.GetCSSValueListValue();
MOZ_ASSERT(!list1 == !list2, "lists should be same length");
while (list1) {
const nsCSSValue &val1 = list1->mValue;
const nsCSSValue &val2 = list2->mValue;
MOZ_ASSERT(val1.GetUnit() == val2.GetUnit(),
"unit match should be assured by AddWeighted");
double diff;
switch (val1.GetUnit()) {
case eCSSUnit_Percent:
diff = val1.GetPercentValue() - val2.GetPercentValue();
break;
case eCSSUnit_Number:
diff = val1.GetFloatValue() - val2.GetFloatValue();
break;
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
squareDistance += diff * diff;
list1 = list1->mNext;
list2 = list2->mNext;
MOZ_ASSERT(!list1 == !list2, "lists should be same length");
}
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_Shadow: {
// Call AddWeighted to make us lists of the same length.
StyleAnimationValue normValue1, normValue2;
if (!AddWeighted(aProperty, 1.0, aStartValue, 0.0, aEndValue,
normValue1) ||
!AddWeighted(aProperty, 0.0, aStartValue, 1.0, aEndValue,
normValue2)) {
return false;
}
const nsCSSValueList* shadow1 = normValue1.GetCSSValueListValue();
const nsCSSValueList* shadow2 = normValue2.GetCSSValueListValue();
aDistance = 0.0;
MOZ_ASSERT(!shadow1 == !shadow2, "lists should be same length");
while (shadow1) {
double squareDistance = 0.0;
if (!ComputeSingleShadowSquareDistance(shadow1, shadow2,
squareDistance,
aProperty)) {
NS_ERROR("Unexpected ComputeSingleShadowSquareDistance failure; "
"why didn't we fail earlier, in AddWeighted calls above?");
}
aDistance += squareDistance; // cumulative distance^2; sqrt()'d below.
shadow1 = shadow1->mNext;
shadow2 = shadow2->mNext;
MOZ_ASSERT(!shadow1 == !shadow2, "lists should be same length");
}
aDistance = sqrt(aDistance);
return true;
}
case eUnit_Shape:
return ComputeShapeDistance(aProperty,
aStartValue.GetCSSValueArrayValue(),
aEndValue.GetCSSValueArrayValue(),
aDistance);
case eUnit_Filter:
return ComputeFilterListDistance(aStartValue.GetCSSValueListValue(),
aEndValue.GetCSSValueListValue(),
aDistance);
case eUnit_Transform: {
// FIXME: We don't have an official spec to define the distance of
// two transform lists, but paced spacing (defined in Web Animations API)
// needs this, so we implement this according to the concept of the
// interpolation of two transform lists.
// Issue: https://www.w3.org/TR/web-animations-1/#issue-789f9fd1
const nsCSSValueList* list1 =
aStartValue.GetCSSValueSharedListValue()->mHead;
const nsCSSValueList* list2 =
aEndValue.GetCSSValueSharedListValue()->mHead;
MOZ_ASSERT(list1);
MOZ_ASSERT(list2);
if (list1->mValue.GetUnit() == eCSSUnit_None &&
list2->mValue.GetUnit() == eCSSUnit_None) {
// Both none, nothing happens.
aDistance = 0.0;
} else if (list1->mValue.GetUnit() == eCSSUnit_None) {
nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list2, 0, list2));
aDistance = ComputeTransformListDistance(none, list2);
} else if (list2->mValue.GetUnit() == eCSSUnit_None) {
nsAutoPtr<nsCSSValueList> none(AddTransformLists(0, list1, 0, list1));
aDistance = ComputeTransformListDistance(list1, none);
} else if (TransformFunctionListsMatch(list1, list2)) {
aDistance = ComputeTransformListDistance(list1, list2);
} else {
aDistance =
ComputeMismatchedTransfromListDistance(list1, list2, aStyleContext);
}
return true;
}
case eUnit_BackgroundPositionCoord: {
const nsCSSValueList *position1 = aStartValue.GetCSSValueListValue();
const nsCSSValueList *position2 = aEndValue.GetCSSValueListValue();
double squareDistance = 0.0;
MOZ_ASSERT(!position1 == !position2, "lists should be same length");
while (position1 && position2) {
squareDistance += CalcPositionCoordSquareDistance(position1->mValue,
position2->mValue);
position1 = position1->mNext;
position2 = position2->mNext;
}
// fail if lists differ in length.
if (position1 || position2) {
return false;
}
aDistance = sqrt(squareDistance);
return true;
}
case eUnit_CSSValuePairList: {
const nsCSSValuePairList *list1 = aStartValue.GetCSSValuePairListValue();
const nsCSSValuePairList *list2 = aEndValue.GetCSSValuePairListValue();
double squareDistance = 0.0;
do {
static nsCSSValue nsCSSValuePairList::* const pairListValues[] = {
&nsCSSValuePairList::mXValue,
&nsCSSValuePairList::mYValue,
};
for (uint32_t i = 0; i < ArrayLength(pairListValues); ++i) {
const nsCSSValue &v1 = list1->*(pairListValues[i]);
const nsCSSValue &v2 = list2->*(pairListValues[i]);
nsCSSUnit unit =
GetCommonUnit(aProperty, v1.GetUnit(), v2.GetUnit());
if (unit == eCSSUnit_Null) {
return false;
}
double diffsquared = 0.0;
switch (unit) {
case eCSSUnit_Number:
case eCSSUnit_Pixel: {
float diff = v1.GetFloatValue() - v2.GetFloatValue();
diffsquared = diff * diff;
break;
}
case eCSSUnit_Percent: {
float diff = v1.GetPercentValue() - v2.GetPercentValue();
diffsquared = diff * diff;
break;
}
case eCSSUnit_Calc: {
PixelCalcValue val1 = ExtractCalcValue(v1);
PixelCalcValue val2 = ExtractCalcValue(v2);
float difflen = val2.mLength - val1.mLength;
float diffpct = val2.mPercent - val1.mPercent;
diffsquared = difflen * difflen + diffpct * diffpct;
break;
}
default:
if (v1 != v2) {
return false;
}
break;
}
squareDistance += diffsquared;
}
list1 = list1->mNext;
list2 = list2->mNext;
} while (list1 && list2);
if (list1 || list2) {
// We can't interpolate lists of different lengths.
return false;
}
aDistance = sqrt(squareDistance);
return true;
}
}
MOZ_ASSERT(false, "Can't compute distance using the given common unit");
return false;
}
static inline void
AddCSSValueNumber(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult, uint32_t aValueRestrictions = 0)
{
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Number, "unexpected unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Number, "unexpected unit");
aResult.SetFloatValue(RestrictValue(aValueRestrictions,
aCoeff1 * aValue1.GetFloatValue() +
aCoeff2 * aValue2.GetFloatValue()),
eCSSUnit_Number);
}
static inline float
GetNumberOrPercent(const nsCSSValue &aValue)
{
nsCSSUnit unit = aValue.GetUnit();
MOZ_ASSERT(unit == eCSSUnit_Number || unit == eCSSUnit_Percent,
"unexpected unit");
return (unit == eCSSUnit_Number) ?
aValue.GetFloatValue() : aValue.GetPercentValue();
}
static inline void
AddCSSValuePercentNumber(const uint32_t aValueRestrictions,
double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult, float aInitialVal)
{
float n1 = GetNumberOrPercent(aValue1);
float n2 = GetNumberOrPercent(aValue2);
// Rather than interpolating aValue1 and aValue2 directly, we
// interpolate their *distances from aInitialVal* (the initial value,
// which is either 1 or 0 for "filter" functions). This matters in
// cases where aInitialVal is nonzero and the coefficients don't add
// up to 1. For example, if initialVal is 1, aCoeff1 is 0.5, and
// aCoeff2 is 0, then we'll return the value halfway between 1 and
// aValue1, rather than the value halfway between 0 and aValue1.
// Note that we do something similar in AddTransformScale().
float result = (n1 - aInitialVal) * aCoeff1 + (n2 - aInitialVal) * aCoeff2;
aResult.SetFloatValue(RestrictValue(aValueRestrictions, result + aInitialVal),
eCSSUnit_Number);
}
// Multiplies |aValue| color by |aDilutionRatio|.
static nscolor
DiluteColor(const RGBAColorData& aValue, double aDilutionRatio)
{
float resultA = aValue.mA * aDilutionRatio;
return resultA <= 0.0 ? NS_RGBA(0, 0, 0, 0)
: aValue.WithAlpha(resultA).ToColor();
}
// Clamped AddWeightedColors.
static nscolor
AddWeightedColorsAndClamp(double aCoeff1, const RGBAColorData& aValue1,
double aCoeff2, const RGBAColorData& aValue2)
{
// We are using AddWeighted() with a zero aCoeff2 for colors to
// pretend AddWeighted() against transparent color, i.e. rgba(0, 0, 0, 0).
// But unpremultiplication in AddWeightedColors() does not work well
// for such cases, so we use another function named DiluteColor() which
// has a similar logic to AddWeightedColors().
return aCoeff2 == 0.0
? DiluteColor(aValue1, aCoeff1)
: AddWeightedColors(aCoeff1, aValue1, aCoeff2, aValue2).ToColor();
}
static void
AppendToCSSValueList(UniquePtr<nsCSSValueList>& aHead,
UniquePtr<nsCSSValueList>&& aValueToAppend,
nsCSSValueList** aTail)
{
MOZ_ASSERT(!aHead == !*aTail,
"Can't have head w/o tail, & vice versa");
if (!aHead) {
aHead = Move(aValueToAppend);
*aTail = aHead.get();
} else {
(*aTail) = (*aTail)->mNext = aValueToAppend.release();
}
}
static void
AppendToCSSValuePairList(UniquePtr<nsCSSValuePairList>& aHead,
UniquePtr<nsCSSValuePairList>&& aValueToAppend,
nsCSSValuePairList** aTail)
{
MOZ_ASSERT(!aHead == !*aTail,
"Can't have head w/o tail, & vice versa");
if (!aHead) {
aHead = Move(aValueToAppend);
*aTail = aHead.get();
} else {
(*aTail) = (*aTail)->mNext = aValueToAppend.release();
}
}
static UniquePtr<nsCSSValueList>
AddWeightedShadowItems(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
ColorAdditionType aColorAdditionType,
nsCSSPropertyID aProperty)
{
// X, Y, Radius, Spread, Color, Inset
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Array,
"wrong unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Array,
"wrong unit");
nsCSSValue::Array *array1 = aValue1.GetArrayValue();
nsCSSValue::Array *array2 = aValue2.GetArrayValue();
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> resultArray = nsCSSValue::Array::Create(6);
for (size_t i = 0; i < 4; ++i) {
// The text-shadow is not need to spread radius,
// So we skip this interpolation.
if (i == 3 && (aProperty != eCSSProperty_box_shadow)) continue;
AddCSSValuePixel(aCoeff1, array1->Item(i), aCoeff2, array2->Item(i),
resultArray->Item(i),
// blur radius must be nonnegative
(i == 2) ? CSS_PROPERTY_VALUE_NONNEGATIVE : 0);
}
const nsCSSValue& colorValue1 = array1->Item(4);
const nsCSSValue& colorValue2 = array2->Item(4);
const nsCSSValue& inset1 = array1->Item(5);
const nsCSSValue& inset2 = array2->Item(5);
if ((colorValue1.GetUnit() != colorValue2.GetUnit() &&
(!colorValue1.IsNumericColorUnit() ||
!colorValue2.IsNumericColorUnit())) ||
inset1.GetUnit() != inset2.GetUnit()) {
// We don't know how to animate between color and no-color, or
// between inset and not-inset.
// NOTE: In case when both colors' units are eCSSUnit_Null, that means
// neither color value was specified, so we can interpolate.
return nullptr;
}
if (colorValue1.GetUnit() != eCSSUnit_Null) {
RGBAColorData color1 = ExtractColor(colorValue1);
RGBAColorData color2 = ExtractColor(colorValue2);
if (aColorAdditionType == ColorAdditionType::Clamped) {
resultArray->Item(4).SetColorValue(
AddWeightedColorsAndClamp(aCoeff1, color1, aCoeff2, color2));
} else {
resultArray->Item(4).SetRGBAColorValue(
AddWeightedColors(aCoeff1, color1, aCoeff2, color2));
}
}
MOZ_ASSERT(inset1 == inset2, "should match");
resultArray->Item(5) = inset1;
auto resultItem = MakeUnique<nsCSSValueList>();
resultItem->mValue.SetArrayValue(resultArray, eCSSUnit_Array);
return resultItem;
}
static void
AddTransformScale(double aCoeff1, const nsCSSValue &aValue1,
double aCoeff2, const nsCSSValue &aValue2,
nsCSSValue &aResult)
{
// Handle scale, and the two matrix components where identity is 1, by
// subtracting 1, multiplying by the coefficients, and then adding 1
// back. This gets the right AddWeighted behavior and gets us the
// interpolation-against-identity behavior for free.
MOZ_ASSERT(aValue1.GetUnit() == eCSSUnit_Number, "unexpected unit");
MOZ_ASSERT(aValue2.GetUnit() == eCSSUnit_Number, "unexpected unit");
float v1 = aValue1.GetFloatValue() - 1.0f,
v2 = aValue2.GetFloatValue() - 1.0f;
float result = v1 * aCoeff1 + v2 * aCoeff2;
aResult.SetFloatValue(EnsureNotNan(result + 1.0f), eCSSUnit_Number);
}
static nsCSSValueList*
AddDifferentTransformLists(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
nsCSSKeyword aOperatorType)
{
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> arr;
arr = AnimationValue::AppendTransformFunction(aOperatorType, resultTail);
if (aCoeff1 == 0) {
// If the first coeffient is zero, we don't need to care about the first
// list at all.
arr->Item(1).Reset();
} else if (aList1 == aList2) {
// If we have the same list, clear the first list, add the first coefficient
// into the second one so that we can simply multiply the second list by the
// second coefficient value.
arr->Item(1).Reset();
aCoeff2 += aCoeff1;
} else {
MOZ_ASSERT((aOperatorType == eCSSKeyword_accumulatematrix &&
aCoeff1 == 1.0) ||
(aOperatorType == eCSSKeyword_interpolatematrix &&
FuzzyEqualsAdditive(aCoeff1 + aCoeff2, 1.0)),
"|aCoeff1| should be 1.0 for accumulation, "
"|aCoeff1| + |aCoeff2| == 1.0 for interpolation");
aList1->CloneInto(arr->Item(1).SetListValue());
}
aList2->CloneInto(arr->Item(2).SetListValue());
arr->Item(3).SetPercentValue(aCoeff2);
return result.forget();
}
static UniquePtr<nsCSSValueList>
AddWeightedFilterFunctionImpl(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
ColorAdditionType aColorAdditionType)
{
// AddWeightedFilterFunction should be our only caller, and it should ensure
// that both args are non-null.
MOZ_ASSERT(aList1, "expected filter list");
MOZ_ASSERT(aList2, "expected filter list");
MOZ_ASSERT(aList1->mValue.GetUnit() == eCSSUnit_Function,
"expected function");
MOZ_ASSERT(aList2->mValue.GetUnit() == eCSSUnit_Function,
"expected function");
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> a1 = aList1->mValue.GetArrayValue(),
a2 = aList2->mValue.GetArrayValue();
nsCSSKeyword filterFunction = a1->Item(0).GetKeywordValue();
if (filterFunction != a2->Item(0).GetKeywordValue()) {
return nullptr; // Can't add two filters of different types.
}
auto resultList = MakeUnique<nsCSSValueList>();
nsCSSValue::Array* result =
resultList->mValue.InitFunction(filterFunction, 1);
// "hue-rotate" is the only filter-function that accepts negative values, and
// we don't use this "restrictions" variable in its clause below.
const uint32_t restrictions = CSS_PROPERTY_VALUE_NONNEGATIVE;
const nsCSSValue& funcArg1 = a1->Item(1);
const nsCSSValue& funcArg2 = a2->Item(1);
nsCSSValue& resultArg = result->Item(1);
float initialVal = 1.0f;
switch (filterFunction) {
case eCSSKeyword_blur: {
nsCSSUnit unit;
if (funcArg1.GetUnit() == funcArg2.GetUnit()) {
unit = funcArg1.GetUnit();
} else {
// If units differ, we'll just combine them with calc().
unit = eCSSUnit_Calc;
}
if (!AddCSSValuePixelPercentCalc(restrictions,
unit,
aCoeff1, funcArg1,
aCoeff2, funcArg2,
resultArg)) {
return nullptr;
}
break;
}
case eCSSKeyword_grayscale:
case eCSSKeyword_invert:
case eCSSKeyword_sepia:
initialVal = 0.0f;
Bug 1235306 - Fix -Wimplicit-fallthrough warnings in layout/. r=dholbert layout/base/nsCSSRendering.cpp:3913:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:3943:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:4066:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:4096:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRenderingBorders.cpp:646:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:4639:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:4659:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:5004:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:5200:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/TouchManager.cpp:192:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/TouchManager.cpp:196:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2497:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2687:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2973:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4277:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4310:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4313:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:6703:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:6751:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsGridContainerFrame.cpp:2649:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsGridContainerFrame.cpp:935:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1141:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1145:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1148:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:2942:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:2958:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:3134:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:3150:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/printing/nsPrintPreviewListener.cpp:199:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/CSSLexer.cpp:129:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:1069:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:366:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:442:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:981:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:3597:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:3616:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:539:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:540:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:542:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10628:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10630:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10671:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10673:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10769:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10770:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10774:43 [-Wimplicit-fallthrough] fallthrough annotation does not directly precede switch label layout/style/nsCSSParser.cpp:10775:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10776:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10780:43 [-Wimplicit-fallthrough] fallthrough annotation does not directly precede switch label layout/style/nsCSSParser.cpp:2542:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:2715:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:4124:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:4313:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9513:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9697:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9699:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9743:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9745:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9826:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9827:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9832:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9833:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9980:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:160:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:187:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:722:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:753:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:139:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:1687:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:1869:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/FixedTableLayoutStrategy.cpp:264:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/FixedTableLayoutStrategy.cpp:267:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:1043:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:930:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:953:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:997:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6943:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6953:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6959:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6966:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6974:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7151:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7161:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7170:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7177:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7186:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableRowFrame.cpp:663:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:112:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:142:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:157:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:86:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:87:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:88:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:90:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsSliderFrame.cpp:551:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsSliderFrame.cpp:560:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsXULPopupManager.cpp:2268:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels
2015-11-23 08:33:47 +03:00
MOZ_FALLTHROUGH;
case eCSSKeyword_brightness:
case eCSSKeyword_contrast:
case eCSSKeyword_opacity:
case eCSSKeyword_saturate:
AddCSSValuePercentNumber(restrictions,
aCoeff1, funcArg1,
aCoeff2, funcArg2,
resultArg,
initialVal);
break;
case eCSSKeyword_hue_rotate:
AddCSSValueAngle(aCoeff1, funcArg1,
aCoeff2, funcArg2,
resultArg);
break;
case eCSSKeyword_drop_shadow: {
MOZ_ASSERT(!funcArg1.GetListValue()->mNext &&
!funcArg2.GetListValue()->mNext,
"drop-shadow filter func doesn't support lists");
UniquePtr<nsCSSValueList> shadowValue =
AddWeightedShadowItems(aCoeff1,
funcArg1.GetListValue()->mValue,
aCoeff2,
funcArg2.GetListValue()->mValue,
aColorAdditionType,
eCSSProperty_filter);
if (!shadowValue) {
return nullptr;
}
resultArg.AdoptListValue(Move(shadowValue));
break;
}
default:
MOZ_ASSERT(false, "unknown filter function");
return nullptr;
}
return resultList;
}
static UniquePtr<nsCSSValueList>
AddWeightedFilterFunction(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
ColorAdditionType aColorAdditionType)
{
MOZ_ASSERT(aList1 || aList2,
"one function list item must not be null");
// Note that one of our arguments could be null, indicating that
// it's the initial value. Rather than adding special null-handling
// logic, we just check for null values and replace them with
// 0 * the other value. That way, AddWeightedFilterFunctionImpl can assume
// its args are non-null.
if (!aList1) {
return AddWeightedFilterFunctionImpl(aCoeff2, aList2, 0, aList2,
aColorAdditionType);
}
if (!aList2) {
return AddWeightedFilterFunctionImpl(aCoeff1, aList1, 0, aList1,
aColorAdditionType);
}
return AddWeightedFilterFunctionImpl(aCoeff1, aList1, aCoeff2, aList2,
aColorAdditionType);
}
static inline uint32_t
ShapeArgumentCount(nsCSSKeyword aShapeFunction)
{
switch (aShapeFunction) {
case eCSSKeyword_circle:
return 2; // radius and center point
case eCSSKeyword_polygon:
return 2; // fill rule and a list of points
case eCSSKeyword_ellipse:
return 3; // two radii and center point
case eCSSKeyword_inset:
return 5; // four edge offsets and a list of corner radii
default:
MOZ_ASSERT_UNREACHABLE("Unknown shape type");
return 0;
}
}
static void
AddPositions(double aCoeff1, const nsCSSValue& aPos1,
double aCoeff2, const nsCSSValue& aPos2,
nsCSSValue& aResultPos)
{
MOZ_ASSERT(aPos1.GetUnit() == eCSSUnit_Array &&
aPos2.GetUnit() == eCSSUnit_Array,
"Args should be CSS <position>s, encoded as arrays");
const nsCSSValue::Array* posArray1 = aPos1.GetArrayValue();
const nsCSSValue::Array* posArray2 = aPos2.GetArrayValue();
MOZ_ASSERT(posArray1->Count() == 4 && posArray2->Count() == 4,
"CSSParserImpl::ParsePositionValue creates an array of length "
"4 - how did we get here?");
nsCSSValue::Array* resultPosArray = nsCSSValue::Array::Create(4);
aResultPos.SetArrayValue(resultPosArray, eCSSUnit_Array);
// Only iterate over elements 1 and 3. The <position> is 'uncomputed' to
// only those elements. See also the comment in SetPositionValue.
for (size_t i = 1; i < 4; i += 2) {
const nsCSSValue& v1 = posArray1->Item(i);
const nsCSSValue& v2 = posArray2->Item(i);
nsCSSValue& vr = resultPosArray->Item(i);
AddCSSValueCanonicalCalc(aCoeff1, v1,
aCoeff2, v2, vr);
}
}
static Maybe<nsCSSValuePair>
AddCSSValuePair(nsCSSPropertyID aProperty, uint32_t aRestrictions,
double aCoeff1, const nsCSSValuePair* aPair1,
double aCoeff2, const nsCSSValuePair* aPair2)
{
MOZ_ASSERT(aPair1, "expected pair");
MOZ_ASSERT(aPair2, "expected pair");
Maybe<nsCSSValuePair> result;
nsCSSUnit unit[2];
unit[0] = GetCommonUnit(aProperty, aPair1->mXValue.GetUnit(),
aPair2->mXValue.GetUnit());
unit[1] = GetCommonUnit(aProperty, aPair1->mYValue.GetUnit(),
aPair2->mYValue.GetUnit());
if (unit[0] == eCSSUnit_Null || unit[1] == eCSSUnit_Null ||
unit[0] == eCSSUnit_URL || unit[0] == eCSSUnit_Enumerated) {
return result; // Nothing() (returning |result| for RVO)
}
result.emplace();
static nsCSSValue nsCSSValuePair::* const pairValues[2] = {
&nsCSSValuePair::mXValue, &nsCSSValuePair::mYValue
};
for (uint32_t i = 0; i < 2; ++i) {
nsCSSValue nsCSSValuePair::*member = pairValues[i];
if (!AddCSSValuePixelPercentCalc(aRestrictions, unit[i],
aCoeff1, aPair1->*member,
aCoeff2, aPair2->*member,
result.ref().*member) ) {
MOZ_ASSERT(false, "unexpected unit");
result.reset();
return result; // Nothing() (returning |result| for RVO)
}
}
return result;
}
static UniquePtr<nsCSSValuePairList>
AddCSSValuePairList(nsCSSPropertyID aProperty,
double aCoeff1, const nsCSSValuePairList* aList1,
double aCoeff2, const nsCSSValuePairList* aList2)
{
MOZ_ASSERT(aList1, "Can't add a null list");
MOZ_ASSERT(aList2, "Can't add a null list");
auto result = MakeUnique<nsCSSValuePairList>();
nsCSSValuePairList* resultPtr = result.get();
do {
static nsCSSValue nsCSSValuePairList::* const pairListValues[] = {
&nsCSSValuePairList::mXValue,
&nsCSSValuePairList::mYValue,
};
uint32_t restrictions = nsCSSProps::ValueRestrictions(aProperty);
for (uint32_t i = 0; i < ArrayLength(pairListValues); ++i) {
const nsCSSValue& v1 = aList1->*(pairListValues[i]);
const nsCSSValue& v2 = aList2->*(pairListValues[i]);
nsCSSValue& vr = resultPtr->*(pairListValues[i]);
nsCSSUnit unit =
GetCommonUnit(aProperty, v1.GetUnit(), v2.GetUnit());
if (unit == eCSSUnit_Null) {
return nullptr;
}
if (unit == eCSSUnit_Number) {
AddCSSValueNumber(aCoeff1, v1,
aCoeff2, v2,
vr, restrictions);
} else if (!AddCSSValuePixelPercentCalc(restrictions, unit,
aCoeff1, v1,
aCoeff2, v2, vr)) {
if (v1 != v2) {
return nullptr;
}
vr = v1;
}
}
aList1 = aList1->mNext;
aList2 = aList2->mNext;
if (!aList1 || !aList2) {
break;
}
resultPtr->mNext = new nsCSSValuePairList;
resultPtr = resultPtr->mNext;
} while (aList1 && aList2);
if (aList1 || aList2) {
return nullptr; // We can't interpolate lists of different lengths
}
return result;
}
static already_AddRefed<nsCSSValue::Array>
AddShapeFunction(nsCSSPropertyID aProperty,
double aCoeff1, const nsCSSValue::Array* aArray1,
double aCoeff2, const nsCSSValue::Array* aArray2,
Restrictions aRestriction)
{
MOZ_ASSERT(aArray1 && aArray1->Count() == 2, "expected shape function");
MOZ_ASSERT(aArray2 && aArray2->Count() == 2, "expected shape function");
MOZ_ASSERT(aArray1->Item(0).GetUnit() == eCSSUnit_Function,
"expected function");
MOZ_ASSERT(aArray2->Item(0).GetUnit() == eCSSUnit_Function,
"expected function");
MOZ_ASSERT(aArray1->Item(1).GetUnit() == eCSSUnit_Enumerated,
"expected geometry-box");
MOZ_ASSERT(aArray2->Item(1).GetUnit() == eCSSUnit_Enumerated,
"expected geometry-box");
if (aArray1->Item(1).GetIntValue() != aArray2->Item(1).GetIntValue()) {
return nullptr; // Both shapes must use the same reference box.
}
const nsCSSValue::Array* func1 = aArray1->Item(0).GetArrayValue();
const nsCSSValue::Array* func2 = aArray2->Item(0).GetArrayValue();
nsCSSKeyword shapeFuncName = func1->Item(0).GetKeywordValue();
if (shapeFuncName != func2->Item(0).GetKeywordValue()) {
return nullptr; // Can't add two shapes of different types.
}
RefPtr<nsCSSValue::Array> result = nsCSSValue::Array::Create(2);
nsCSSValue::Array* resultFuncArgs =
result->Item(0).InitFunction(shapeFuncName,
ShapeArgumentCount(shapeFuncName));
switch (shapeFuncName) {
case eCSSKeyword_ellipse:
// Add ellipses' |ry| values (but fail if we encounter an enum):
if (!AddCSSValuePixelPercentCalc(aRestriction == Restrictions::Enable
? CSS_PROPERTY_VALUE_NONNEGATIVE
: 0,
GetCommonUnit(aProperty,
func1->Item(2).GetUnit(),
func2->Item(2).GetUnit()),
aCoeff1, func1->Item(2),
aCoeff2, func2->Item(2),
resultFuncArgs->Item(2))) {
return nullptr;
}
MOZ_FALLTHROUGH; // to handle rx and center point
case eCSSKeyword_circle: {
// Add circles' |r| (or ellipses' |rx|) values:
if (!AddCSSValuePixelPercentCalc(aRestriction == Restrictions::Enable
? CSS_PROPERTY_VALUE_NONNEGATIVE
: 0,
GetCommonUnit(aProperty,
func1->Item(1).GetUnit(),
func2->Item(1).GetUnit()),
aCoeff1, func1->Item(1),
aCoeff2, func2->Item(1),
resultFuncArgs->Item(1))) {
return nullptr;
}
// Add center points (defined as a <position>).
size_t posIndex = shapeFuncName == eCSSKeyword_circle ? 2 : 3;
AddPositions(aCoeff1, func1->Item(posIndex),
aCoeff2, func2->Item(posIndex),
resultFuncArgs->Item(posIndex));
break;
}
case eCSSKeyword_polygon: {
// Add polygons' corresponding points (if the fill rule matches):
int32_t fillRule = func1->Item(1).GetIntValue();
if (fillRule != func2->Item(1).GetIntValue()) {
return nullptr; // can't interpolate between different fill rules
}
resultFuncArgs->Item(1).SetIntValue(fillRule, eCSSUnit_Enumerated);
const nsCSSValuePairList* points1 = func1->Item(2).GetPairListValue();
const nsCSSValuePairList* points2 = func2->Item(2).GetPairListValue();
UniquePtr<nsCSSValuePairList> resultPoints =
AddCSSValuePairList(aProperty, aCoeff1, points1, aCoeff2, points2);
if (!resultPoints) {
return nullptr;
}
resultFuncArgs->Item(2).AdoptPairListValue(Move(resultPoints));
break;
}
case eCSSKeyword_inset: {
MOZ_ASSERT(func1->Count() == 6 && func2->Count() == 6,
"Update for CSSParserImpl::ParseInsetFunction changes");
// Items 1-4 are respectively the top, right, bottom and left offsets
// from the reference box.
for (size_t i = 1; i <= 4; ++i) {
if (!AddCSSValuePixelPercentCalc(aRestriction == Restrictions::Enable
? CSS_PROPERTY_VALUE_NONNEGATIVE
: 0,
GetCommonUnit(aProperty,
func1->Item(i).GetUnit(),
func2->Item(i).GetUnit()),
aCoeff1, func1->Item(i),
aCoeff2, func2->Item(i),
resultFuncArgs->Item(i))) {
return nullptr;
}
}
// Item 5 contains the radii of the rounded corners for the inset
// rectangle.
MOZ_ASSERT(func1->Item(5).GetUnit() == eCSSUnit_Array &&
func2->Item(5).GetUnit() == eCSSUnit_Array,
"Expected two arrays");
const nsCSSValue::Array* radii1 = func1->Item(5).GetArrayValue();
const nsCSSValue::Array* radii2 = func2->Item(5).GetArrayValue();
MOZ_ASSERT(radii1->Count() == 4 && radii2->Count() == 4);
nsCSSValue::Array* resultRadii = nsCSSValue::Array::Create(4);
resultFuncArgs->Item(5).SetArrayValue(resultRadii, eCSSUnit_Array);
// We use an arbitrary border-radius property here to get the appropriate
// restrictions for radii since this is a <border-radius> value.
uint32_t restrictions =
aRestriction == Restrictions::Enable
? nsCSSProps::ValueRestrictions(eCSSProperty_border_top_left_radius)
: 0;
for (size_t i = 0; i < 4; ++i) {
const nsCSSValuePair& pair1 = radii1->Item(i).GetPairValue();
const nsCSSValuePair& pair2 = radii2->Item(i).GetPairValue();
const Maybe<nsCSSValuePair> pairResult =
AddCSSValuePair(aProperty, restrictions,
aCoeff1, &pair1,
aCoeff2, &pair2);
if (!pairResult) {
return nullptr;
}
resultRadii->Item(i).SetPairValue(pairResult.ptr());
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unknown shape type");
return nullptr;
}
// set the geometry-box value
result->Item(1).SetIntValue(aArray1->Item(1).GetIntValue(),
eCSSUnit_Enumerated);
return result.forget();
}
static nsCSSValueList*
AddTransformLists(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
nsCSSKeyword aOperatorType)
{
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
do {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> a1 = ToPrimitive(aList1->mValue.GetArrayValue()),
a2 = ToPrimitive(aList2->mValue.GetArrayValue());
MOZ_ASSERT(
TransformFunctionsMatch(nsStyleTransformMatrix::TransformFunctionOf(a1),
nsStyleTransformMatrix::TransformFunctionOf(a2)),
"transform function mismatch");
MOZ_ASSERT(!*resultTail,
"resultTail isn't pointing to the tail (may leak)");
nsCSSKeyword tfunc = nsStyleTransformMatrix::TransformFunctionOf(a1);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> arr;
if (tfunc != eCSSKeyword_matrix &&
tfunc != eCSSKeyword_matrix3d &&
tfunc != eCSSKeyword_interpolatematrix &&
tfunc != eCSSKeyword_rotate3d &&
tfunc != eCSSKeyword_perspective) {
arr = AnimationValue::AppendTransformFunction(tfunc, resultTail);
}
switch (tfunc) {
case eCSSKeyword_translate3d: {
MOZ_ASSERT(a1->Count() == 4, "unexpected count");
MOZ_ASSERT(a2->Count() == 4, "unexpected count");
AddTransformTranslate(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1));
AddTransformTranslate(aCoeff1, a1->Item(2), aCoeff2, a2->Item(2),
arr->Item(2));
AddTransformTranslate(aCoeff1, a1->Item(3), aCoeff2, a2->Item(3),
arr->Item(3));
break;
}
case eCSSKeyword_scale3d: {
MOZ_ASSERT(a1->Count() == 4, "unexpected count");
MOZ_ASSERT(a2->Count() == 4, "unexpected count");
AddTransformScale(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1));
AddTransformScale(aCoeff1, a1->Item(2), aCoeff2, a2->Item(2),
arr->Item(2));
AddTransformScale(aCoeff1, a1->Item(3), aCoeff2, a2->Item(3),
arr->Item(3));
break;
}
// It would probably be nicer to animate skew in tangent space
// rather than angle space. However, it's easy to specify
// skews with infinite tangents, and behavior changes pretty
// drastically when crossing such skews (since the direction of
// animation flips), so interop is probably more important here.
case eCSSKeyword_skew: {
MOZ_ASSERT(a1->Count() == 2 || a1->Count() == 3,
"unexpected count");
MOZ_ASSERT(a2->Count() == 2 || a2->Count() == 3,
"unexpected count");
nsCSSValue zero(0.0f, eCSSUnit_Radian);
// Add Y component of skew.
AddCSSValueAngle(aCoeff1,
a1->Count() == 3 ? a1->Item(2) : zero,
aCoeff2,
a2->Count() == 3 ? a2->Item(2) : zero,
arr->Item(2));
// Add X component of skew (which can be merged with case below
// in non-DEBUG).
AddCSSValueAngle(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1));
break;
}
case eCSSKeyword_skewx:
case eCSSKeyword_skewy:
case eCSSKeyword_rotate:
case eCSSKeyword_rotatex:
case eCSSKeyword_rotatey:
case eCSSKeyword_rotatez: {
MOZ_ASSERT(a1->Count() == 2, "unexpected count");
MOZ_ASSERT(a2->Count() == 2, "unexpected count");
AddCSSValueAngle(aCoeff1, a1->Item(1), aCoeff2, a2->Item(1),
arr->Item(1));
break;
}
case eCSSKeyword_rotate3d: {
2014-08-29 22:47:30 +04:00
Point3D vector1(a1->Item(1).GetFloatValue(),
a1->Item(2).GetFloatValue(),
a1->Item(3).GetFloatValue());
vector1.Normalize();
2014-08-29 22:47:30 +04:00
Point3D vector2(a2->Item(1).GetFloatValue(),
a2->Item(2).GetFloatValue(),
a2->Item(3).GetFloatValue());
vector2.Normalize();
// Handle rotate3d with matched (normalized) vectors,
// otherwise fallthrough to the next switch statement
// and do matrix decomposition.
if (vector1 == vector2) {
// We skipped appending a transform function above for rotate3d,
// so do it now.
arr = AnimationValue::AppendTransformFunction(tfunc, resultTail);
arr->Item(1).SetFloatValue(vector1.x, eCSSUnit_Number);
arr->Item(2).SetFloatValue(vector1.y, eCSSUnit_Number);
arr->Item(3).SetFloatValue(vector1.z, eCSSUnit_Number);
AddCSSValueAngle(aCoeff1, a1->Item(4), aCoeff2, a2->Item(4),
arr->Item(4));
break;
}
Bug 1235306 - Fix -Wimplicit-fallthrough warnings in layout/. r=dholbert layout/base/nsCSSRendering.cpp:3913:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:3943:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:4066:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRendering.cpp:4096:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsCSSRenderingBorders.cpp:646:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:4639:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:4659:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:5004:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/nsLayoutUtils.cpp:5200:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/TouchManager.cpp:192:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/base/TouchManager.cpp:196:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2497:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2687:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFlexContainerFrame.cpp:2973:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4277:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4310:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:4313:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:6703:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsFrame.cpp:6751:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsGridContainerFrame.cpp:2649:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsGridContainerFrame.cpp:935:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1141:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1145:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsHTMLReflowState.cpp:1148:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:2942:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:2958:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:3134:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/generic/nsLineLayout.cpp:3150:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/printing/nsPrintPreviewListener.cpp:199:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/CSSLexer.cpp:129:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:1069:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:366:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:442:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/Declaration.cpp:981:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:3597:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:3616:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:539:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:540:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsComputedDOMStyle.cpp:542:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10628:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10630:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10671:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10673:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10769:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10770:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10774:43 [-Wimplicit-fallthrough] fallthrough annotation does not directly precede switch label layout/style/nsCSSParser.cpp:10775:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10776:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:10780:43 [-Wimplicit-fallthrough] fallthrough annotation does not directly precede switch label layout/style/nsCSSParser.cpp:2542:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:2715:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:4124:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:4313:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9513:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9697:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9699:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9743:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9745:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9826:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9827:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9832:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9833:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsCSSParser.cpp:9980:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:160:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:187:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:722:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/nsRuleNode.cpp:753:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:139:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:1687:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/style/StyleAnimationValue.cpp:1869:7 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/FixedTableLayoutStrategy.cpp:264:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/FixedTableLayoutStrategy.cpp:267:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:1043:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:930:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:953:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsCellMap.cpp:997:3 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6943:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6953:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6959:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6966:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:6974:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7151:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7161:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7170:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7177:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableFrame.cpp:7186:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/nsTableRowFrame.cpp:663:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:112:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:142:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/tables/SpanningCellSorter.cpp:157:9 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:86:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:87:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:88:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsResizerFrame.cpp:90:13 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsSliderFrame.cpp:551:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsSliderFrame.cpp:560:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels layout/xul/nsXULPopupManager.cpp:2268:5 [-Wimplicit-fallthrough] unannotated fall-through between switch labels
2015-11-23 08:33:47 +03:00
MOZ_FALLTHROUGH;
}
case eCSSKeyword_matrix:
case eCSSKeyword_matrix3d:
case eCSSKeyword_perspective:
if (aCoeff1 == 0.0 && aCoeff2 == 0.0) {
// Special case. If both coefficients are 0.0, we should apply an
// identity transform function.
arr = AnimationValue::AppendTransformFunction(tfunc, resultTail);
if (tfunc == eCSSKeyword_rotate3d) {
arr->Item(1).SetFloatValue(0.0, eCSSUnit_Number);
arr->Item(2).SetFloatValue(0.0, eCSSUnit_Number);
arr->Item(3).SetFloatValue(1.0, eCSSUnit_Number);
arr->Item(4).SetFloatValue(0.0, eCSSUnit_Radian);
} else if (tfunc == eCSSKeyword_perspective) {
// The parameter of the identity perspective function is
// positive infinite.
arr->Item(1).SetFloatValue(std::numeric_limits<float>::infinity(),
eCSSUnit_Pixel);
} else {
nsStyleTransformMatrix::SetIdentityMatrix(arr);
}
break;
}
MOZ_FALLTHROUGH;
case eCSSKeyword_interpolatematrix: {
// FIXME: If the matrix contains only numbers then we could decompose
// here.
// Construct temporary lists with only this item in them.
nsCSSValueList tempList1, tempList2;
tempList1.mValue = aList1->mValue;
tempList2.mValue = aList2->mValue;
if (aList1 == aList2) {
*resultTail =
AddDifferentTransformLists(aCoeff1, &tempList1,
aCoeff2, &tempList1,
aOperatorType);
} else {
*resultTail =
AddDifferentTransformLists(aCoeff1, &tempList1,
aCoeff2, &tempList2,
aOperatorType);
}
// Now advance resultTail to point to the new tail slot.
while (*resultTail) {
resultTail = &(*resultTail)->mNext;
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE(
"unknown transform function or accumulatematrix");
}
aList1 = aList1->mNext;
aList2 = aList2->mNext;
} while (aList1);
MOZ_ASSERT(!aList2, "list length mismatch");
MOZ_ASSERT(!*resultTail,
"resultTail isn't pointing to the tail");
return result.forget();
}
static void
AddPositionCoords(double aCoeff1, const nsCSSValue& aPos1,
double aCoeff2, const nsCSSValue& aPos2,
nsCSSValue& aResultPos)
{
const nsCSSValue::Array* posArray1 = aPos1.GetArrayValue();
const nsCSSValue::Array* posArray2 = aPos2.GetArrayValue();
nsCSSValue::Array* resultPosArray = nsCSSValue::Array::Create(2);
aResultPos.SetArrayValue(resultPosArray, eCSSUnit_Array);
/* Only compute element 1. The <position-coord> is
* 'uncomputed' to only that element.
*/
const nsCSSValue& v1 = posArray1->Item(1);
const nsCSSValue& v2 = posArray2->Item(1);
nsCSSValue& vr = resultPosArray->Item(1);
AddCSSValueCanonicalCalc(aCoeff1, v1,
aCoeff2, v2, vr);
}
static UniquePtr<nsCSSValueList>
AddWeightedShadowList(double aCoeff1,
const nsCSSValueList* aShadow1,
double aCoeff2,
const nsCSSValueList* aShadow2,
ColorAdditionType aColorAdditionType,
nsCSSPropertyID aProperty)
{
// This is implemented according to:
// http://dev.w3.org/csswg/css3-transitions/#animation-of-property-types-
// and the third item in the summary of:
// http://lists.w3.org/Archives/Public/www-style/2009Jul/0050.html
UniquePtr<nsCSSValueList> result;
nsCSSValueList* tail = nullptr;
while (aShadow1 && aShadow2) {
UniquePtr<nsCSSValueList> shadowValue =
AddWeightedShadowItems(aCoeff1, aShadow1->mValue,
aCoeff2, aShadow2->mValue,
aColorAdditionType,
aProperty);
if (!shadowValue) {
return nullptr;
}
aShadow1 = aShadow1->mNext;
aShadow2 = aShadow2->mNext;
AppendToCSSValueList(result, Move(shadowValue), &tail);
}
if (aShadow1 || aShadow2) {
const nsCSSValueList *longShadow;
double longCoeff;
if (aShadow1) {
longShadow = aShadow1;
longCoeff = aCoeff1;
} else {
longShadow = aShadow2;
longCoeff = aCoeff2;
}
while (longShadow) {
// Passing coefficients that add to less than 1 produces the
// desired result of interpolating "0 0 0 transparent" with
// the current shadow.
UniquePtr<nsCSSValueList> shadowValue =
AddWeightedShadowItems(longCoeff, longShadow->mValue,
0.0, longShadow->mValue,
aColorAdditionType, aProperty);
if (!shadowValue) {
return nullptr;
}
longShadow = longShadow->mNext;
AppendToCSSValueList(result, Move(shadowValue), &tail);
}
}
return result;
}
static UniquePtr<nsCSSValueList>
AddWeightedFilterList(double aCoeff1, const nsCSSValueList* aList1,
double aCoeff2, const nsCSSValueList* aList2,
ColorAdditionType aColorAdditionType)
{
UniquePtr<nsCSSValueList> result;
nsCSSValueList* tail = nullptr;
while (aList1 || aList2) {
if ((aList1 && aList1->mValue.GetUnit() != eCSSUnit_Function) ||
(aList2 && aList2->mValue.GetUnit() != eCSSUnit_Function)) {
// If we don't have filter-functions, we must have filter-URLs, which
// we can't add or interpolate.
return nullptr;
}
UniquePtr<nsCSSValueList> resultFunction =
AddWeightedFilterFunction(aCoeff1, aList1, aCoeff2, aList2,
aColorAdditionType);
if (!resultFunction) {
// filter function mismatch
return nullptr;
}
AppendToCSSValueList(result, Move(resultFunction), &tail);
// move to next aList items
if (aList1) {
aList1 = aList1->mNext;
}
if (aList2) {
aList2 = aList2->mNext;
}
}
return result;
}
bool
StyleAnimationValue::AddWeighted(nsCSSPropertyID aProperty,
double aCoeff1,
const StyleAnimationValue& aValue1,
double aCoeff2,
const StyleAnimationValue& aValue2,
StyleAnimationValue& aResultValue)
{
Unit commonUnit =
GetCommonUnit(aProperty, aValue1.GetUnit(), aValue2.GetUnit());
// Maybe need a followup method to convert the inputs into the common
// unit-type, if they don't already match it. (Or would it make sense to do
// that in GetCommonUnit? in which case maybe ConvertToCommonUnit would be
// better.)
switch (commonUnit) {
case eUnit_Null:
case eUnit_Auto:
case eUnit_None:
case eUnit_Normal:
case eUnit_UnparsedString:
case eUnit_URL:
case eUnit_DiscreteCSSValue:
return false;
case eUnit_Enumerated:
switch (aProperty) {
case eCSSProperty_font_stretch: {
// https://drafts.csswg.org/css-fonts-3/#font-stretch-animation
double interpolatedValue = aCoeff1 * double(aValue1.GetIntValue()) +
aCoeff2 * double(aValue2.GetIntValue());
int32_t result = floor(interpolatedValue + 0.5);
if (result < NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED) {
result = NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED;
} else if (result > NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED) {
result = NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED;
}
aResultValue.SetIntValue(result, eUnit_Enumerated);
return true;
}
default:
return false;
}
case eUnit_Visibility: {
int32_t enum1 = aValue1.GetIntValue();
int32_t enum2 = aValue2.GetIntValue();
if (enum1 == enum2) {
aResultValue.SetIntValue(enum1, eUnit_Visibility);
return true;
}
if ((enum1 == NS_STYLE_VISIBILITY_VISIBLE) ==
(enum2 == NS_STYLE_VISIBILITY_VISIBLE)) {
return false;
}
int32_t val1 = enum1 == NS_STYLE_VISIBILITY_VISIBLE;
int32_t val2 = enum2 == NS_STYLE_VISIBILITY_VISIBLE;
double interp = aCoeff1 * val1 + aCoeff2 * val2;
int32_t result = interp > 0.0 ? NS_STYLE_VISIBILITY_VISIBLE
: (val1 ? enum2 : enum1);
aResultValue.SetIntValue(result, eUnit_Visibility);
return true;
}
case eUnit_Integer: {
// https://drafts.csswg.org/css-transitions/#animtype-integer
double interpolatedValue = aCoeff1 * double(aValue1.GetIntValue()) +
aCoeff2 * double(aValue2.GetIntValue());
int32_t result = floor(interpolatedValue + 0.5);
if (aProperty == eCSSProperty_font_weight) {
// https://drafts.csswg.org/css-transitions/#animtype-font-weight
result += 50;
result -= result % 100;
result = Clamp(result, 100, 900);
} else {
result = RestrictValue(aProperty, result);
}
aResultValue.SetIntValue(result, eUnit_Integer);
return true;
}
case eUnit_Coord: {
aResultValue.SetCoordValue(RestrictValue(aProperty, NSToCoordRound(
aCoeff1 * aValue1.GetCoordValue() +
aCoeff2 * aValue2.GetCoordValue())));
return true;
}
case eUnit_Percent: {
aResultValue.SetPercentValue(RestrictValue(aProperty,
aCoeff1 * aValue1.GetPercentValue() +
aCoeff2 * aValue2.GetPercentValue()));
return true;
}
case eUnit_Float: {
aResultValue.SetFloatValue(RestrictValue(aProperty,
aCoeff1 * aValue1.GetFloatValue() +
aCoeff2 * aValue2.GetFloatValue()));
return true;
}
case eUnit_Color: {
RGBAColorData color1 = ExtractColor(aValue1);
RGBAColorData color2 = ExtractColor(aValue2);
auto resultColor = MakeUnique<nsCSSValue>();
resultColor->SetColorValue(
AddWeightedColorsAndClamp(aCoeff1, color1, aCoeff2, color2));
aResultValue.SetAndAdoptCSSValueValue(resultColor.release(), eUnit_Color);
return true;
}
case eUnit_CurrentColor: {
aResultValue.SetCurrentColorValue();
return true;
}
case eUnit_ComplexColor: {
ComplexColorData color1 = ExtractComplexColor(aValue1);
ComplexColorData color2 = ExtractComplexColor(aValue2);
RefPtr<ComplexColorValue> result = new ComplexColorValue;
// Common case is interpolating between a color and a currentcolor.
if (color1.IsNumericColor() && color2.IsCurrentColor()) {
result->mColor = color1.mColor;
result->mForegroundRatio = aCoeff2;
} else if (color1.IsCurrentColor() && color2.IsNumericColor()) {
result->mColor = color2.mColor;
result->mForegroundRatio = aCoeff1;
} else {
float ratio1 = 1.0f - color1.mForegroundRatio;
float ratio2 = 1.0f - color2.mForegroundRatio;
float alpha1 = color1.mColor.mA * ratio1;
float alpha2 = color2.mColor.mA * ratio2;
RGBAColorData resultColor =
AddWeightedColors(aCoeff1, color1.mColor.WithAlpha(alpha1),
aCoeff2, color2.mColor.WithAlpha(alpha2));
float resultRatio = color1.mForegroundRatio * aCoeff1 +
color2.mForegroundRatio * aCoeff2;
float resultAlpha = resultColor.mA / (1.0f - resultRatio);
result->mColor = resultColor.WithAlpha(resultAlpha);
result->mForegroundRatio = resultRatio;
}
aResultValue.SetComplexColorValue(result.forget());
return true;
}
case eUnit_Calc: {
PixelCalcValue v1 = ExtractCalcValue(aValue1);
PixelCalcValue v2 = ExtractCalcValue(aValue2);
double len = aCoeff1 * v1.mLength + aCoeff2 * v2.mLength;
double pct = aCoeff1 * v1.mPercent + aCoeff2 * v2.mPercent;
bool hasPct = (aCoeff1 != 0.0 && v1.mHasPercent) ||
(aCoeff2 != 0.0 && v2.mHasPercent);
nsCSSValue *val = new nsCSSValue();
nsCSSValue::Array *arr = nsCSSValue::Array::Create(1);
val->SetArrayValue(arr, eCSSUnit_Calc);
if (hasPct) {
nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2);
arr2->Item(0).SetFloatValue(len, eCSSUnit_Pixel);
arr2->Item(1).SetPercentValue(pct);
arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus);
} else {
arr->Item(0).SetFloatValue(len, eCSSUnit_Pixel);
}
aResultValue.SetAndAdoptCSSValueValue(val, eUnit_Calc);
return true;
}
case eUnit_ObjectPosition: {
const nsCSSValue* position1 = aValue1.GetCSSValueValue();
const nsCSSValue* position2 = aValue2.GetCSSValueValue();
nsAutoPtr<nsCSSValue> result(new nsCSSValue);
AddPositions(aCoeff1, *position1,
aCoeff2, *position2, *result);
aResultValue.SetAndAdoptCSSValueValue(result.forget(),
eUnit_ObjectPosition);
return true;
}
case eUnit_CSSValuePair: {
uint32_t restrictions = nsCSSProps::ValueRestrictions(aProperty);
Maybe<nsCSSValuePair> result =
AddCSSValuePair(aProperty, restrictions,
aCoeff1, aValue1.GetCSSValuePairValue(),
aCoeff2, aValue2.GetCSSValuePairValue());
if (!result) {
return false;
}
// We need a heap allocated object to adopt here:
auto heapResult = MakeUnique<nsCSSValuePair>(*result);
aResultValue.SetAndAdoptCSSValuePairValue(heapResult.release(),
eUnit_CSSValuePair);
return true;
}
case eUnit_CSSValueTriplet: {
nsCSSValueTriplet triplet1(*aValue1.GetCSSValueTripletValue());
nsCSSValueTriplet triplet2(*aValue2.GetCSSValueTripletValue());
nsCSSUnit unit[3];
unit[0] = GetCommonUnit(aProperty, triplet1.mXValue.GetUnit(),
triplet2.mXValue.GetUnit());
unit[1] = GetCommonUnit(aProperty, triplet1.mYValue.GetUnit(),
triplet2.mYValue.GetUnit());
unit[2] = GetCommonUnit(aProperty, triplet1.mZValue.GetUnit(),
triplet2.mZValue.GetUnit());
if (unit[0] == eCSSUnit_Null || unit[1] == eCSSUnit_Null ||
unit[2] == eCSSUnit_Null) {
return false;
}
nsAutoPtr<nsCSSValueTriplet> result(new nsCSSValueTriplet);
static nsCSSValue nsCSSValueTriplet::* const tripletValues[3] = {
&nsCSSValueTriplet::mXValue, &nsCSSValueTriplet::mYValue, &nsCSSValueTriplet::mZValue
};
uint32_t restrictions = nsCSSProps::ValueRestrictions(aProperty);
for (uint32_t i = 0; i < 3; ++i) {
nsCSSValue nsCSSValueTriplet::*member = tripletValues[i];
if (!AddCSSValuePixelPercentCalc(restrictions, unit[i],
aCoeff1, &triplet1->*member,
aCoeff2, &triplet2->*member,
result->*member) ) {
MOZ_ASSERT(false, "unexpected unit");
return false;
}
}
aResultValue.SetAndAdoptCSSValueTripletValue(result.forget(),
eUnit_CSSValueTriplet);
return true;
}
case eUnit_CSSRect: {
MOZ_ASSERT(nsCSSProps::ValueRestrictions(aProperty) == 0,
"must add code for handling value restrictions");
const nsCSSRect *rect1 = aValue1.GetCSSRectValue();
const nsCSSRect *rect2 = aValue2.GetCSSRectValue();
if (rect1->mTop.GetUnit() != rect2->mTop.GetUnit() ||
rect1->mRight.GetUnit() != rect2->mRight.GetUnit() ||
rect1->mBottom.GetUnit() != rect2->mBottom.GetUnit() ||
rect1->mLeft.GetUnit() != rect2->mLeft.GetUnit()) {
// At least until we have calc()
return false;
}
nsAutoPtr<nsCSSRect> result(new nsCSSRect);
for (uint32_t i = 0; i < ArrayLength(nsCSSRect::sides); ++i) {
nsCSSValue nsCSSRect::*member = nsCSSRect::sides[i];
MOZ_ASSERT((rect1->*member).GetUnit() == (rect2->*member).GetUnit(),
"should have returned above");
switch ((rect1->*member).GetUnit()) {
case eCSSUnit_Pixel:
AddCSSValuePixel(aCoeff1, rect1->*member, aCoeff2, rect2->*member,
result->*member);
break;
case eCSSUnit_Auto:
if (float(aCoeff1 + aCoeff2) != 1.0f) {
// Interpolating between two auto values makes sense;
// adding in other ratios does not.
return false;
}
(result->*member).SetAutoValue();
break;
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
}
aResultValue.SetAndAdoptCSSRectValue(result.forget(), eUnit_CSSRect);
return true;
}
case eUnit_Dasharray: {
const nsCSSValueList *list1 = aValue1.GetCSSValueListValue();
const nsCSSValueList *list2 = aValue2.GetCSSValueListValue();
uint32_t len1 = 0, len2 = 0;
for (const nsCSSValueList *v = list1; v; v = v->mNext) {
++len1;
}
for (const nsCSSValueList *v = list2; v; v = v->mNext) {
++len2;
}
MOZ_ASSERT(len1 > 0 && len2 > 0, "unexpected length");
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = EuclidLCM<uint32_t>(len1, len2); i != i_end; ++i) {
const nsCSSValue &v1 = list1->mValue;
const nsCSSValue &v2 = list2->mValue;
MOZ_ASSERT(v1.GetUnit() == eCSSUnit_Number ||
v1.GetUnit() == eCSSUnit_Percent, "unexpected");
MOZ_ASSERT(v2.GetUnit() == eCSSUnit_Number ||
v2.GetUnit() == eCSSUnit_Percent, "unexpected");
if (v1.GetUnit() != v2.GetUnit()) {
// Can't animate between lengths and percentages (until calc()).
return false;
}
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
if (v1.GetUnit() == eCSSUnit_Number) {
AddCSSValueNumber(aCoeff1, v1, aCoeff2, v2, item->mValue,
CSS_PROPERTY_VALUE_NONNEGATIVE);
} else {
AddCSSValuePercent(aCoeff1, v1, aCoeff2, v2, item->mValue,
CSS_PROPERTY_VALUE_NONNEGATIVE);
}
list1 = list1->mNext;
if (!list1) {
list1 = aValue1.GetCSSValueListValue();
}
list2 = list2->mNext;
if (!list2) {
list2 = aValue2.GetCSSValueListValue();
}
}
aResultValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_Dasharray);
return true;
}
case eUnit_Shadow: {
UniquePtr<nsCSSValueList> result =
AddWeightedShadowList(aCoeff1,
aValue1.GetCSSValueListValue(),
aCoeff2,
aValue2.GetCSSValueListValue(),
ColorAdditionType::Clamped,
aProperty);
if (!result) {
return false;
}
aResultValue.SetAndAdoptCSSValueListValue(result.release(), eUnit_Shadow);
return true;
}
case eUnit_Shape: {
RefPtr<nsCSSValue::Array> result =
AddShapeFunction(aProperty,
aCoeff1, aValue1.GetCSSValueArrayValue(),
aCoeff2, aValue2.GetCSSValueArrayValue());
if (!result) {
return false;
}
aResultValue.SetCSSValueArrayValue(result, eUnit_Shape);
return true;
}
case eUnit_Filter: {
UniquePtr<nsCSSValueList> result =
AddWeightedFilterList(aCoeff1, aValue1.GetCSSValueListValue(),
aCoeff2, aValue2.GetCSSValueListValue(),
ColorAdditionType::Clamped);
if (!result) {
return false;
}
aResultValue.SetAndAdoptCSSValueListValue(result.release(),
eUnit_Filter);
return true;
}
case eUnit_Transform: {
const nsCSSValueList* list1 = aValue1.GetCSSValueSharedListValue()->mHead;
const nsCSSValueList* list2 = aValue2.GetCSSValueSharedListValue()->mHead;
MOZ_ASSERT(list1);
MOZ_ASSERT(list2);
// We want to avoid the matrix decomposition when we can, since
// avoiding it can produce better results both for compound
// transforms and for skew and skewY (see below). We can do this
// in two cases:
// (1) if one of the transforms is 'none'
// (2) if the lists have the same length and the transform
// functions match
nsAutoPtr<nsCSSValueList> result;
if (list1->mValue.GetUnit() == eCSSUnit_None) {
if (list2->mValue.GetUnit() == eCSSUnit_None) {
result = new nsCSSValueList;
if (result) {
result->mValue.SetNoneValue();
}
} else if (HasAccumulateMatrix(list2)) {
result = AddDifferentTransformLists(0, list2, aCoeff2, list2,
eCSSKeyword_interpolatematrix);
} else {
result = AddTransformLists(0, list2, aCoeff2, list2);
}
} else {
if (list2->mValue.GetUnit() == eCSSUnit_None) {
if (HasAccumulateMatrix(list1)) {
result = AddDifferentTransformLists(0, list1,
aCoeff1, list1,
eCSSKeyword_interpolatematrix);
} else {
result = AddTransformLists(0, list1, aCoeff1, list1);
}
} else if (TransformFunctionListsMatch(list1, list2)) {
result = AddTransformLists(aCoeff1, list1, aCoeff2, list2,
eCSSKeyword_interpolatematrix);
} else {
result = AddDifferentTransformLists(aCoeff1, list1,
aCoeff2, list2,
eCSSKeyword_interpolatematrix);
}
}
aResultValue.SetTransformValue(new nsCSSValueSharedList(result.forget()));
return true;
}
case eUnit_BackgroundPositionCoord: {
const nsCSSValueList *position1 = aValue1.GetCSSValueListValue();
const nsCSSValueList *position2 = aValue2.GetCSSValueListValue();
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
while (position1 && position2) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
AddPositionCoords(aCoeff1, position1->mValue,
aCoeff2, position2->mValue, item->mValue);
position1 = position1->mNext;
position2 = position2->mNext;
}
// Check for different lengths
if (position1 || position2) {
return false;
}
aResultValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_BackgroundPositionCoord);
return true;
}
case eUnit_CSSValuePairList: {
const nsCSSValuePairList *list1 = aValue1.GetCSSValuePairListValue();
const nsCSSValuePairList *list2 = aValue2.GetCSSValuePairListValue();
UniquePtr<nsCSSValuePairList> result =
AddCSSValuePairList(aProperty, aCoeff1, list1, aCoeff2, list2);
if (!result) {
return false;
}
aResultValue.SetAndAdoptCSSValuePairListValue(result.release());
return true;
}
}
MOZ_ASSERT(false, "Can't interpolate using the given common unit");
return false;
}
StyleAnimationValue
StyleAnimationValue::Accumulate(nsCSSPropertyID aProperty,
const StyleAnimationValue& aA,
StyleAnimationValue&& aB,
uint64_t aCount)
{
StyleAnimationValue result(Move(aB));
if (aCount == 0) {
return result;
}
Unit commonUnit =
GetCommonUnit(aProperty, result.GetUnit(), aA.GetUnit());
switch (commonUnit) {
case eUnit_Filter: {
UniquePtr<nsCSSValueList> resultList =
AddWeightedFilterList(1.0, result.GetCSSValueListValue(),
aCount, aA.GetCSSValueListValue(),
ColorAdditionType::Unclamped);
if (resultList) {
result.SetAndAdoptCSSValueListValue(resultList.release(), eUnit_Filter);
}
break;
}
case eUnit_Shadow: {
UniquePtr<nsCSSValueList> resultList =
AddWeightedShadowList(1.0, result.GetCSSValueListValue(),
aCount, aA.GetCSSValueListValue(),
ColorAdditionType::Unclamped,
aProperty);
if (resultList) {
result.SetAndAdoptCSSValueListValue(resultList.release(), eUnit_Shadow);
}
break;
}
case eUnit_Color: {
RGBAColorData color1 = ExtractColor(result);
RGBAColorData color2 = ExtractColor(aA);
result.mValue.mCSSValue->SetRGBAColorValue(
AddWeightedColors(1.0, color1, aCount, color2));
break;
}
case eUnit_Transform: {
const nsCSSValueList* listA =
aA.GetCSSValueSharedListValue()->mHead;
const nsCSSValueList* listB =
result.GetCSSValueSharedListValue()->mHead;
MOZ_ASSERT(listA);
MOZ_ASSERT(listB);
nsAutoPtr<nsCSSValueList> resultList;
if (listA->mValue.GetUnit() == eCSSUnit_None) {
// If |aA| is 'none' then we are calculating:
//
// none * |aCount| + |aB|
// = none + |aB|
// = |aB|
//
// Hence the result should just be |aB|, even if |aB| is also 'none'.
// Since |result| is already initialized to |aB|, we just return that.
break;
} else if (listB->mValue.GetUnit() == eCSSUnit_None) {
resultList = AddTransformLists(0.0, listA, aCount, listA,
eCSSKeyword_accumulatematrix);
} else if (TransformFunctionListsMatch(listA, listB)) {
resultList = AddTransformLists(1.0, listB, aCount, listA,
eCSSKeyword_accumulatematrix);
} else {
resultList = AddDifferentTransformLists(1.0, listB,
aCount, listA,
eCSSKeyword_accumulatematrix);
}
result.SetTransformValue(new nsCSSValueSharedList(resultList.forget()));
break;
}
default:
Unused << AddWeighted(aProperty,
1.0, result,
aCount, aA,
result);
break;
}
return result;
}
static already_AddRefed<css::StyleRule>
BuildStyleRule(nsCSSPropertyID aProperty,
dom::Element* aTargetElement,
const nsAString& aSpecifiedValue,
bool aUseSVGMode)
{
// Set up an empty CSS Declaration
RefPtr<css::Declaration> declaration(new css::Declaration());
declaration->InitializeEmpty();
bool changed; // ignored, but needed as outparam for ParseProperty
nsIDocument* doc = aTargetElement->OwnerDoc();
nsCOMPtr<nsIURI> baseURI = aTargetElement->GetBaseURI();
nsCSSParser parser(doc->CSSLoader());
nsCSSPropertyID propertyToCheck = nsCSSProps::IsShorthand(aProperty) ?
nsCSSProps::SubpropertyEntryFor(aProperty)[0] : aProperty;
// Get a parser, parse the property, and check for CSS parsing errors.
// If this fails, we bail out and delete the declaration.
parser.ParseProperty(aProperty, aSpecifiedValue, doc->GetDocumentURI(),
baseURI, aTargetElement->NodePrincipal(), declaration,
&changed, false, aUseSVGMode);
// check whether property parsed without CSS parsing errors
if (!declaration->HasNonImportantValueFor(propertyToCheck)) {
return nullptr;
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<css::StyleRule> rule = new css::StyleRule(nullptr,
declaration,
0, 0);
return rule.forget();
}
static already_AddRefed<css::StyleRule>
BuildStyleRule(nsCSSPropertyID aProperty,
dom::Element* aTargetElement,
const nsCSSValue& aSpecifiedValue,
bool aUseSVGMode)
{
MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
"Should be a longhand property");
// Check if longhand failed to parse correctly.
if (aSpecifiedValue.GetUnit() == eCSSUnit_Null) {
return nullptr;
}
// Set up an empty CSS Declaration
RefPtr<css::Declaration> declaration(new css::Declaration());
declaration->InitializeEmpty();
// Add our longhand value
nsCSSExpandedDataBlock block;
declaration->ExpandTo(&block);
block.AddLonghandProperty(aProperty, aSpecifiedValue);
declaration->ValueAppended(aProperty);
declaration->CompressFrom(&block);
RefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration, 0, 0);
return rule.forget();
}
static bool
ComputeValuesFromStyleContext(
nsCSSPropertyID aProperty,
CSSEnabledState aEnabledState,
GeckoStyleContext* aStyleContext,
nsTArray<PropertyStyleAnimationValuePair>& aValues)
{
// Extract computed value of our property (or all longhand components, if
// aProperty is a shorthand) from the temporary style context
if (nsCSSProps::IsShorthand(aProperty)) {
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty, aEnabledState) {
if (nsCSSProps::kAnimTypeTable[*p] == eStyleAnimType_None) {
// Skip non-animatable component longhands.
continue;
}
PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
pair->mProperty = *p;
if (!StyleAnimationValue::ExtractComputedValue(*p, aStyleContext,
pair->mValue.mGecko)) {
return false;
}
}
return true;
}
PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
pair->mProperty = aProperty;
return StyleAnimationValue::ExtractComputedValue(aProperty, aStyleContext,
pair->mValue.mGecko);
}
static bool
ComputeValuesFromStyleRule(nsCSSPropertyID aProperty,
CSSEnabledState aEnabledState,
GeckoStyleContext* aStyleContext,
css::StyleRule* aStyleRule,
nsTArray<PropertyStyleAnimationValuePair>& aValues,
bool* aIsContextSensitive)
{
MOZ_ASSERT(aStyleContext);
if (!nsCSSProps::IsEnabled(aProperty, aEnabledState)) {
return false;
}
MOZ_ASSERT(aStyleContext->PresContext()->StyleSet()->IsGecko(),
"ServoStyleSet should not use StyleAnimationValue for animations");
nsStyleSet* styleSet = aStyleContext->PresContext()->StyleSet()->AsGecko();
RefPtr<GeckoStyleContext> tmpStyleContext;
if (aIsContextSensitive) {
MOZ_ASSERT(!nsCSSProps::IsShorthand(aProperty),
"to correctly set aIsContextSensitive for shorthand properties, "
"this code must be adjusted");
nsCOMArray<nsIStyleRule> ruleArray;
ruleArray.AppendObject(styleSet->InitialStyleRule());
css::Declaration* declaration = aStyleRule->GetDeclaration();
ruleArray.AppendObject(declaration);
declaration->SetImmutable();
tmpStyleContext =
styleSet->ResolveStyleByAddingRules(aStyleContext, ruleArray);
if (!tmpStyleContext) {
return false;
}
// Force walk of rule tree
nsStyleStructID sid = nsCSSProps::kSIDTable[aProperty];
tmpStyleContext->StyleData(sid);
// The rule node will have unconditional cached style data if the value is
// not context-sensitive. So if there's nothing cached, it's not context
// sensitive.
*aIsContextSensitive =
!tmpStyleContext->RuleNode()->NodeHasCachedUnconditionalData(sid);
}
// If we're not concerned whether the property is context sensitive then just
// add the rule to a new temporary style context alongside the target
// element's style context.
// Also, if we previously discovered that this property IS context-sensitive
// then we need to throw the temporary style context out since the property's
// value may have been biased by the 'initial' values supplied.
if (!aIsContextSensitive || *aIsContextSensitive) {
nsCOMArray<nsIStyleRule> ruleArray;
css::Declaration* declaration = aStyleRule->GetDeclaration();
ruleArray.AppendObject(declaration);
declaration->SetImmutable();
tmpStyleContext =
styleSet->ResolveStyleByAddingRules(aStyleContext, ruleArray);
if (!tmpStyleContext) {
return false;
}
}
return ComputeValuesFromStyleContext(aProperty, aEnabledState,
tmpStyleContext, aValues);
}
/* static */ bool
StyleAnimationValue::ComputeValue(nsCSSPropertyID aProperty,
dom::Element* aTargetElement,
GeckoStyleContext* aStyleContext,
const nsAString& aSpecifiedValue,
bool aUseSVGMode,
StyleAnimationValue& aComputedValue,
bool* aIsContextSensitive)
{
MOZ_ASSERT(aTargetElement, "null target element");
// Parse specified value into a temporary css::StyleRule
// Note: BuildStyleRule needs an element's OwnerDoc, BaseURI, and Principal.
// If it is a pseudo element, use its parent element's OwnerDoc, BaseURI,
// and Principal.
RefPtr<css::StyleRule> styleRule =
BuildStyleRule(aProperty, aTargetElement, aSpecifiedValue, aUseSVGMode);
if (!styleRule) {
return false;
}
if (nsCSSProps::IsShorthand(aProperty) ||
nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_None) {
// Just capture the specified value
aComputedValue.SetUnparsedStringValue(nsString(aSpecifiedValue));
if (aIsContextSensitive) {
// Since we're just returning the string as-is, aComputedValue isn't going
// to change depending on the context
*aIsContextSensitive = false;
}
return true;
}
AutoTArray<PropertyStyleAnimationValuePair,1> values;
bool ok = ComputeValuesFromStyleRule(aProperty,
CSSEnabledState::eIgnoreEnabledState,
aStyleContext, styleRule,
values, aIsContextSensitive);
if (!ok) {
return false;
}
MOZ_ASSERT(values.Length() == 1);
MOZ_ASSERT(values[0].mProperty == aProperty);
aComputedValue = values[0].mValue.mGecko;
return true;
}
template <class T>
bool
ComputeValuesFromSpecifiedValue(
nsCSSPropertyID aProperty,
CSSEnabledState aEnabledState,
dom::Element* aTargetElement,
GeckoStyleContext* aStyleContext,
T& aSpecifiedValue,
bool aUseSVGMode,
nsTArray<PropertyStyleAnimationValuePair>& aResult)
{
MOZ_ASSERT(aTargetElement, "null target element");
// Parse specified value into a temporary css::StyleRule
// Note: BuildStyleRule needs an element's OwnerDoc, BaseURI, and Principal.
// If it is a pseudo element, use its parent element's OwnerDoc, BaseURI,
// and Principal.
RefPtr<css::StyleRule> styleRule =
BuildStyleRule(aProperty, aTargetElement, aSpecifiedValue, aUseSVGMode);
if (!styleRule) {
return false;
}
aResult.Clear();
return ComputeValuesFromStyleRule(aProperty, aEnabledState,
aStyleContext, styleRule, aResult,
/* aIsContextSensitive */ nullptr);
}
/* static */ bool
StyleAnimationValue::ComputeValues(
nsCSSPropertyID aProperty,
CSSEnabledState aEnabledState,
dom::Element* aTargetElement,
GeckoStyleContext* aStyleContext,
const nsAString& aSpecifiedValue,
bool aUseSVGMode,
nsTArray<PropertyStyleAnimationValuePair>& aResult)
{
return ComputeValuesFromSpecifiedValue(aProperty, aEnabledState,
aTargetElement, aStyleContext,
aSpecifiedValue, aUseSVGMode,
aResult);
}
/* static */ bool
StyleAnimationValue::ComputeValues(
nsCSSPropertyID aProperty,
CSSEnabledState aEnabledState,
dom::Element* aTargetElement,
GeckoStyleContext* aStyleContext,
const nsCSSValue& aSpecifiedValue,
bool aUseSVGMode,
nsTArray<PropertyStyleAnimationValuePair>& aResult)
{
return ComputeValuesFromSpecifiedValue(aProperty, aEnabledState,
aTargetElement, aStyleContext,
aSpecifiedValue, aUseSVGMode,
aResult);
}
bool
StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty,
const StyleAnimationValue& aComputedValue,
nsCSSValue& aSpecifiedValue)
{
Unit unit = aComputedValue.GetUnit();
switch (unit) {
case eUnit_Normal:
aSpecifiedValue.SetNormalValue();
break;
case eUnit_Auto:
aSpecifiedValue.SetAutoValue();
break;
case eUnit_None:
aSpecifiedValue.SetNoneValue();
break;
case eUnit_Enumerated:
case eUnit_Visibility:
aSpecifiedValue.
SetIntValue(aComputedValue.GetIntValue(), eCSSUnit_Enumerated);
break;
case eUnit_Integer:
aSpecifiedValue.
SetIntValue(aComputedValue.GetIntValue(), eCSSUnit_Integer);
break;
case eUnit_Coord:
aSpecifiedValue.SetIntegerCoordValue(aComputedValue.GetCoordValue());
break;
case eUnit_Percent:
aSpecifiedValue.SetPercentValue(aComputedValue.GetPercentValue());
break;
case eUnit_Float:
aSpecifiedValue.
SetFloatValue(aComputedValue.GetFloatValue(), eCSSUnit_Number);
break;
case eUnit_CurrentColor:
aSpecifiedValue.SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor);
break;
case eUnit_Calc:
case eUnit_Color:
case eUnit_ObjectPosition:
case eUnit_URL:
case eUnit_DiscreteCSSValue: {
nsCSSValue* val = aComputedValue.GetCSSValueValue();
// Sanity-check that the underlying unit in the nsCSSValue is what we
// expect for our StyleAnimationValue::Unit:
MOZ_ASSERT((unit == eUnit_Calc && val->GetUnit() == eCSSUnit_Calc) ||
(unit == eUnit_Color &&
nsCSSValue::IsNumericColorUnit(val->GetUnit())) ||
(unit == eUnit_ObjectPosition &&
val->GetUnit() == eCSSUnit_Array) ||
(unit == eUnit_URL && val->GetUnit() == eCSSUnit_URL) ||
unit == eUnit_DiscreteCSSValue,
"unexpected unit");
aSpecifiedValue = *val;
break;
}
case eUnit_ComplexColor: {
aSpecifiedValue.SetComplexColorValue(
do_AddRef(aComputedValue.mValue.mComplexColor));
break;
}
case eUnit_CSSValuePair: {
// Rule node processing expects pair values to be collapsed to a
// single value if both halves would be equal, for most but not
// all properties. At present, all animatable properties that
// use pairs do expect collapsing.
const nsCSSValuePair* pair = aComputedValue.GetCSSValuePairValue();
if (pair->mXValue == pair->mYValue) {
aSpecifiedValue = pair->mXValue;
} else {
aSpecifiedValue.SetPairValue(pair);
}
} break;
case eUnit_CSSValueTriplet: {
// Rule node processing expects triplet values to be collapsed to a
// single value if both halves would be equal, for most but not
// all properties. At present, all animatable properties that
// use pairs do expect collapsing.
const nsCSSValueTriplet* triplet = aComputedValue.GetCSSValueTripletValue();
if (triplet->mXValue == triplet->mYValue && triplet->mYValue == triplet->mZValue) {
aSpecifiedValue = triplet->mXValue;
} else {
aSpecifiedValue.SetTripletValue(triplet);
}
} break;
case eUnit_CSSRect: {
nsCSSRect& rect = aSpecifiedValue.SetRectValue();
rect = *aComputedValue.GetCSSRectValue();
} break;
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPositionCoord:
Bug 1260655 - Allow StyleAnimationValue::UncomputeValue to produce values whose storage is independent of the passed-in computed value; r=heycam When we go to switch CSS Animations over to using KeyframeEffectReadOnly::SetFrames we will need a way to represent any filled-in from/to values as nsCSSValue objects. These objects are built from the current computed style. We currently use StyleAnimationValue::ExtractComputedValue for this which returns a StyleAnimationValue. In order to convert this to an nsCSSValue we can use StyleAnimationValue::UncomputeValue. However, in some cases, the nsCSSValue objects returned by that method are dependent on the passed-in StyleAnimationValue object. This patch adds an overload to UncomputeValue that takes an rvalue StyleAnimationValue reference and produces an nsCSSValue that is independent of the StyleAnimationValue through a combination of copying data and transferring ownership of data. This patch also adjusts the return value for the case of filter and shadow lists when the list is empty so that we return a none value in this case. These are the only list types which are allowed to have a null list value. Not only does this produce the correct result when these values are serialized (the initial value for 'filter', 'text-shadow', and 'box-shadow' is 'none') it also means that UncomputeValue should never return an nsCSSValue whose unit is null which is important because when we later pass that value to BuildStyleRule it will treat a null nsCSSValue as an error case (specifically, "longhand failed to parse"). MozReview-Commit-ID: 4RoCn39ntiJ
2016-03-30 06:39:59 +03:00
{
nsCSSValueList* computedList = aComputedValue.GetCSSValueListValue();
if (computedList) {
aSpecifiedValue.SetDependentListValue(computedList);
} else {
aSpecifiedValue.SetNoneValue();
}
}
break;
case eUnit_Shape: {
nsCSSValue::Array* computedArray = aComputedValue.GetCSSValueArrayValue();
aSpecifiedValue.SetArrayValue(computedArray, eCSSUnit_Array);
break;
}
case eUnit_Transform:
aSpecifiedValue.
SetSharedListValue(aComputedValue.GetCSSValueSharedListValue());
break;
case eUnit_CSSValuePairList:
aSpecifiedValue.
SetDependentPairListValue(aComputedValue.GetCSSValuePairListValue());
break;
default:
return false;
}
return true;
}
Bug 1260655 - Allow StyleAnimationValue::UncomputeValue to produce values whose storage is independent of the passed-in computed value; r=heycam When we go to switch CSS Animations over to using KeyframeEffectReadOnly::SetFrames we will need a way to represent any filled-in from/to values as nsCSSValue objects. These objects are built from the current computed style. We currently use StyleAnimationValue::ExtractComputedValue for this which returns a StyleAnimationValue. In order to convert this to an nsCSSValue we can use StyleAnimationValue::UncomputeValue. However, in some cases, the nsCSSValue objects returned by that method are dependent on the passed-in StyleAnimationValue object. This patch adds an overload to UncomputeValue that takes an rvalue StyleAnimationValue reference and produces an nsCSSValue that is independent of the StyleAnimationValue through a combination of copying data and transferring ownership of data. This patch also adjusts the return value for the case of filter and shadow lists when the list is empty so that we return a none value in this case. These are the only list types which are allowed to have a null list value. Not only does this produce the correct result when these values are serialized (the initial value for 'filter', 'text-shadow', and 'box-shadow' is 'none') it also means that UncomputeValue should never return an nsCSSValue whose unit is null which is important because when we later pass that value to BuildStyleRule it will treat a null nsCSSValue as an error case (specifically, "longhand failed to parse"). MozReview-Commit-ID: 4RoCn39ntiJ
2016-03-30 06:39:59 +03:00
bool
StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty,
Bug 1260655 - Allow StyleAnimationValue::UncomputeValue to produce values whose storage is independent of the passed-in computed value; r=heycam When we go to switch CSS Animations over to using KeyframeEffectReadOnly::SetFrames we will need a way to represent any filled-in from/to values as nsCSSValue objects. These objects are built from the current computed style. We currently use StyleAnimationValue::ExtractComputedValue for this which returns a StyleAnimationValue. In order to convert this to an nsCSSValue we can use StyleAnimationValue::UncomputeValue. However, in some cases, the nsCSSValue objects returned by that method are dependent on the passed-in StyleAnimationValue object. This patch adds an overload to UncomputeValue that takes an rvalue StyleAnimationValue reference and produces an nsCSSValue that is independent of the StyleAnimationValue through a combination of copying data and transferring ownership of data. This patch also adjusts the return value for the case of filter and shadow lists when the list is empty so that we return a none value in this case. These are the only list types which are allowed to have a null list value. Not only does this produce the correct result when these values are serialized (the initial value for 'filter', 'text-shadow', and 'box-shadow' is 'none') it also means that UncomputeValue should never return an nsCSSValue whose unit is null which is important because when we later pass that value to BuildStyleRule it will treat a null nsCSSValue as an error case (specifically, "longhand failed to parse"). MozReview-Commit-ID: 4RoCn39ntiJ
2016-03-30 06:39:59 +03:00
StyleAnimationValue&& aComputedValue,
nsCSSValue& aSpecifiedValue)
{
Unit unit = aComputedValue.GetUnit();
switch (unit) {
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPositionCoord:
Bug 1260655 - Allow StyleAnimationValue::UncomputeValue to produce values whose storage is independent of the passed-in computed value; r=heycam When we go to switch CSS Animations over to using KeyframeEffectReadOnly::SetFrames we will need a way to represent any filled-in from/to values as nsCSSValue objects. These objects are built from the current computed style. We currently use StyleAnimationValue::ExtractComputedValue for this which returns a StyleAnimationValue. In order to convert this to an nsCSSValue we can use StyleAnimationValue::UncomputeValue. However, in some cases, the nsCSSValue objects returned by that method are dependent on the passed-in StyleAnimationValue object. This patch adds an overload to UncomputeValue that takes an rvalue StyleAnimationValue reference and produces an nsCSSValue that is independent of the StyleAnimationValue through a combination of copying data and transferring ownership of data. This patch also adjusts the return value for the case of filter and shadow lists when the list is empty so that we return a none value in this case. These are the only list types which are allowed to have a null list value. Not only does this produce the correct result when these values are serialized (the initial value for 'filter', 'text-shadow', and 'box-shadow' is 'none') it also means that UncomputeValue should never return an nsCSSValue whose unit is null which is important because when we later pass that value to BuildStyleRule it will treat a null nsCSSValue as an error case (specifically, "longhand failed to parse"). MozReview-Commit-ID: 4RoCn39ntiJ
2016-03-30 06:39:59 +03:00
{
UniquePtr<nsCSSValueList> computedList =
aComputedValue.TakeCSSValueListValue();
if (computedList) {
aSpecifiedValue.AdoptListValue(Move(computedList));
Bug 1260655 - Allow StyleAnimationValue::UncomputeValue to produce values whose storage is independent of the passed-in computed value; r=heycam When we go to switch CSS Animations over to using KeyframeEffectReadOnly::SetFrames we will need a way to represent any filled-in from/to values as nsCSSValue objects. These objects are built from the current computed style. We currently use StyleAnimationValue::ExtractComputedValue for this which returns a StyleAnimationValue. In order to convert this to an nsCSSValue we can use StyleAnimationValue::UncomputeValue. However, in some cases, the nsCSSValue objects returned by that method are dependent on the passed-in StyleAnimationValue object. This patch adds an overload to UncomputeValue that takes an rvalue StyleAnimationValue reference and produces an nsCSSValue that is independent of the StyleAnimationValue through a combination of copying data and transferring ownership of data. This patch also adjusts the return value for the case of filter and shadow lists when the list is empty so that we return a none value in this case. These are the only list types which are allowed to have a null list value. Not only does this produce the correct result when these values are serialized (the initial value for 'filter', 'text-shadow', and 'box-shadow' is 'none') it also means that UncomputeValue should never return an nsCSSValue whose unit is null which is important because when we later pass that value to BuildStyleRule it will treat a null nsCSSValue as an error case (specifically, "longhand failed to parse"). MozReview-Commit-ID: 4RoCn39ntiJ
2016-03-30 06:39:59 +03:00
} else {
aSpecifiedValue.SetNoneValue();
}
}
break;
case eUnit_CSSValuePairList:
{
UniquePtr<nsCSSValuePairList> computedList =
aComputedValue.TakeCSSValuePairListValue();
MOZ_ASSERT(computedList, "Pair list should never be null");
aSpecifiedValue.AdoptPairListValue(Move(computedList));
Bug 1260655 - Allow StyleAnimationValue::UncomputeValue to produce values whose storage is independent of the passed-in computed value; r=heycam When we go to switch CSS Animations over to using KeyframeEffectReadOnly::SetFrames we will need a way to represent any filled-in from/to values as nsCSSValue objects. These objects are built from the current computed style. We currently use StyleAnimationValue::ExtractComputedValue for this which returns a StyleAnimationValue. In order to convert this to an nsCSSValue we can use StyleAnimationValue::UncomputeValue. However, in some cases, the nsCSSValue objects returned by that method are dependent on the passed-in StyleAnimationValue object. This patch adds an overload to UncomputeValue that takes an rvalue StyleAnimationValue reference and produces an nsCSSValue that is independent of the StyleAnimationValue through a combination of copying data and transferring ownership of data. This patch also adjusts the return value for the case of filter and shadow lists when the list is empty so that we return a none value in this case. These are the only list types which are allowed to have a null list value. Not only does this produce the correct result when these values are serialized (the initial value for 'filter', 'text-shadow', and 'box-shadow' is 'none') it also means that UncomputeValue should never return an nsCSSValue whose unit is null which is important because when we later pass that value to BuildStyleRule it will treat a null nsCSSValue as an error case (specifically, "longhand failed to parse"). MozReview-Commit-ID: 4RoCn39ntiJ
2016-03-30 06:39:59 +03:00
}
break;
default:
return UncomputeValue(aProperty, aComputedValue, aSpecifiedValue);
}
return true;
}
bool
StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty,
const StyleAnimationValue& aComputedValue,
nsAString& aSpecifiedValue)
{
aSpecifiedValue.Truncate(); // Clear outparam, if it's not already empty
if (aComputedValue.GetUnit() == eUnit_UnparsedString) {
aComputedValue.GetStringValue(aSpecifiedValue);
return true;
}
nsCSSValue val;
if (!StyleAnimationValue::UncomputeValue(aProperty, aComputedValue, val)) {
return false;
}
val.AppendToString(aProperty, aSpecifiedValue);
return true;
}
template<typename T>
inline const T&
StyleDataAtOffset(const void* aStyleStruct, ptrdiff_t aOffset)
{
return *reinterpret_cast<const T*>(
reinterpret_cast<const uint8_t*>(aStyleStruct) + aOffset);
}
static bool
StyleCoordToValue(const nsStyleCoord& aCoord, StyleAnimationValue& aValue)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Normal:
aValue.SetNormalValue();
break;
case eStyleUnit_Auto:
aValue.SetAutoValue();
break;
case eStyleUnit_None:
aValue.SetNoneValue();
break;
case eStyleUnit_Percent:
aValue.SetPercentValue(aCoord.GetPercentValue());
break;
case eStyleUnit_Factor:
aValue.SetFloatValue(aCoord.GetFactorValue());
break;
case eStyleUnit_Coord:
aValue.SetCoordValue(aCoord.GetCoordValue());
break;
case eStyleUnit_Enumerated:
aValue.SetIntValue(aCoord.GetIntValue(),
StyleAnimationValue::eUnit_Enumerated);
break;
case eStyleUnit_Integer:
aValue.SetIntValue(aCoord.GetIntValue(),
StyleAnimationValue::eUnit_Integer);
break;
case eStyleUnit_Calc: {
nsAutoPtr<nsCSSValue> val(new nsCSSValue);
CalcValueToCSSValue(aCoord.GetCalcValue(), *val);
aValue.SetAndAdoptCSSValueValue(val.forget(),
StyleAnimationValue::eUnit_Calc);
break;
}
default:
return false;
}
return true;
}
static bool
StyleCoordToCSSValue(const nsStyleCoord& aCoord, nsCSSValue& aCSSValue)
{
switch (aCoord.GetUnit()) {
case eStyleUnit_Coord:
aCSSValue.SetIntegerCoordValue(aCoord.GetCoordValue());
break;
case eStyleUnit_Factor:
aCSSValue.SetFloatValue(aCoord.GetFactorValue(), eCSSUnit_Number);
break;
case eStyleUnit_Percent:
aCSSValue.SetPercentValue(aCoord.GetPercentValue());
break;
case eStyleUnit_Calc:
CalcValueToCSSValue(aCoord.GetCalcValue(), aCSSValue);
break;
case eStyleUnit_Degree:
aCSSValue.SetFloatValue(aCoord.GetAngleValue(), eCSSUnit_Degree);
break;
case eStyleUnit_Grad:
aCSSValue.SetFloatValue(aCoord.GetAngleValue(), eCSSUnit_Grad);
break;
case eStyleUnit_Radian:
aCSSValue.SetFloatValue(aCoord.GetAngleValue(), eCSSUnit_Radian);
break;
case eStyleUnit_Turn:
aCSSValue.SetFloatValue(aCoord.GetAngleValue(), eCSSUnit_Turn);
break;
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
return true;
}
static void
SetPositionValue(const Position& aPos, nsCSSValue& aCSSValue)
{
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> posArray = nsCSSValue::Array::Create(4);
aCSSValue.SetArrayValue(posArray.get(), eCSSUnit_Array);
// NOTE: Array entries #0 and #2 here are intentionally left untouched, with
// eCSSUnit_Null. The purpose of these entries in our specified-style
// <position> representation is to store edge names. But for values
// extracted from computed style (which is what we're dealing with here),
// we'll just have a normalized "x,y" position, with no edge names needed.
nsCSSValue& xValue = posArray->Item(1);
nsCSSValue& yValue = posArray->Item(3);
CalcValueToCSSValue(&aPos.mXPosition, xValue);
CalcValueToCSSValue(&aPos.mYPosition, yValue);
}
static void
SetPositionCoordValue(const Position::Coord& aPosCoord,
nsCSSValue& aCSSValue)
{
RefPtr<nsCSSValue::Array> posArray = nsCSSValue::Array::Create(2);
aCSSValue.SetArrayValue(posArray.get(), eCSSUnit_Array);
// NOTE: Array entry #0 here is intentionally left untouched, with
// eCSSUnit_Null. The purpose of this entry in our specified-style
// <position-coord> representation is to store edge names. But for values
// extracted from computed style (which is what we're dealing with here),
// we'll just have a normalized "x"/"y" position, with no edge names needed.
nsCSSValue& value = posArray->Item(1);
CalcValueToCSSValue(&aPosCoord, value);
}
/*
* Assign |aOutput = aInput|, except with any non-pixel lengths
* replaced with the equivalent in pixels, and any non-canonical calc()
* expressions replaced with canonical ones.
*/
static void
SubstitutePixelValues(GeckoStyleContext* aStyleContext,
const nsCSSValue& aInput, nsCSSValue& aOutput)
{
if (aInput.IsCalcUnit()) {
RuleNodeCacheConditions conditions;
nsRuleNode::ComputedCalc c =
nsRuleNode::SpecifiedCalcToComputedCalc(aInput, aStyleContext,
aStyleContext->PresContext(),
conditions);
nsStyleCoord::CalcValue c2;
c2.mLength = c.mLength;
c2.mPercent = c.mPercent;
c2.mHasPercent = true; // doesn't matter for transform translate
CalcValueToCSSValue(&c2, aOutput);
} else if (aInput.UnitHasArrayValue()) {
const nsCSSValue::Array *inputArray = aInput.GetArrayValue();
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<nsCSSValue::Array> outputArray =
nsCSSValue::Array::Create(inputArray->Count());
for (size_t i = 0, i_end = inputArray->Count(); i < i_end; ++i) {
SubstitutePixelValues(aStyleContext,
inputArray->Item(i), outputArray->Item(i));
}
aOutput.SetArrayValue(outputArray, aInput.GetUnit());
} else if (aInput.IsLengthUnit() &&
aInput.GetUnit() != eCSSUnit_Pixel) {
RuleNodeCacheConditions conditions;
nscoord len = nsRuleNode::CalcLength(aInput, aStyleContext,
aStyleContext->PresContext(),
conditions);
aOutput.SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(len),
eCSSUnit_Pixel);
} else {
aOutput = aInput;
}
}
static void
ExtractImageLayerPositionXList(const nsStyleImageLayers& aLayer,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(aLayer.mPositionXCount > 0, "unexpected count");
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = aLayer.mPositionXCount; i != i_end; ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
SetPositionCoordValue(aLayer.mLayers[i].mPosition.mXPosition,
item->mValue);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
StyleAnimationValue::eUnit_BackgroundPositionCoord);
}
static void
ExtractImageLayerPositionYList(const nsStyleImageLayers& aLayer,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(aLayer.mPositionYCount > 0, "unexpected count");
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = aLayer.mPositionYCount; i != i_end; ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
SetPositionCoordValue(aLayer.mLayers[i].mPosition.mYPosition,
item->mValue);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
StyleAnimationValue::eUnit_BackgroundPositionCoord);
}
static void
ExtractImageLayerSizePairList(const nsStyleImageLayers& aLayer,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(aLayer.mSizeCount > 0, "unexpected count");
nsAutoPtr<nsCSSValuePairList> result;
nsCSSValuePairList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = aLayer.mSizeCount; i != i_end; ++i) {
nsCSSValuePairList *item = new nsCSSValuePairList;
*resultTail = item;
resultTail = &item->mNext;
const nsStyleImageLayers::Size &size = aLayer.mLayers[i].mSize;
switch (size.mWidthType) {
case nsStyleImageLayers::Size::eContain:
case nsStyleImageLayers::Size::eCover:
item->mXValue.SetIntValue(size.mWidthType,
eCSSUnit_Enumerated);
break;
case nsStyleImageLayers::Size::eAuto:
item->mXValue.SetAutoValue();
break;
case nsStyleImageLayers::Size::eLengthPercentage:
// XXXbz is there a good reason we can't just
// CalcValueToCSSValue(&size.mWidth, item->mXValue) here?
if (!size.mWidth.mHasPercent &&
// negative values must have come from calc()
size.mWidth.mLength >= 0) {
MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
"Shouldn't have mPercent");
item->mXValue.SetIntegerCoordValue(size.mWidth.mLength);
} else if (size.mWidth.mLength == 0 &&
// negative values must have come from calc()
size.mWidth.mPercent >= 0.0f) {
item->mXValue.SetPercentValue(size.mWidth.mPercent);
} else {
CalcValueToCSSValue(&size.mWidth, item->mXValue);
}
break;
}
switch (size.mHeightType) {
case nsStyleImageLayers::Size::eContain:
case nsStyleImageLayers::Size::eCover:
// leave it null
break;
case nsStyleImageLayers::Size::eAuto:
item->mYValue.SetAutoValue();
break;
case nsStyleImageLayers::Size::eLengthPercentage:
// XXXbz is there a good reason we can't just
// CalcValueToCSSValue(&size.mHeight, item->mYValue) here?
if (!size.mHeight.mHasPercent &&
// negative values must have come from calc()
size.mHeight.mLength >= 0) {
MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
"Shouldn't have mPercent");
item->mYValue.SetIntegerCoordValue(size.mHeight.mLength);
} else if (size.mHeight.mLength == 0 &&
// negative values must have come from calc()
size.mHeight.mPercent >= 0.0f) {
item->mYValue.SetPercentValue(size.mHeight.mPercent);
} else {
CalcValueToCSSValue(&size.mHeight, item->mYValue);
}
break;
}
}
aComputedValue.SetAndAdoptCSSValuePairListValue(result.forget());
}
static bool
StyleShapeSourceToCSSArray(const StyleShapeSource& aShapeSource,
nsCSSValue::Array* aResult)
{
MOZ_ASSERT(aResult->Count() == 2,
"Expected array to be presized for a function and the sizing-box");
const UniquePtr<StyleBasicShape>& shape = aShapeSource.GetBasicShape();
nsCSSKeyword functionName = shape->GetShapeTypeName();
RefPtr<nsCSSValue::Array> functionArray;
switch (shape->GetShapeType()) {
case StyleBasicShapeType::Circle:
case StyleBasicShapeType::Ellipse: {
const nsTArray<nsStyleCoord>& coords = shape->Coordinates();
MOZ_ASSERT(coords.Length() == ShapeArgumentCount(functionName) - 1,
"Unexpected radii count");
// The "+1" is for the center point:
functionArray = aResult->Item(0).InitFunction(functionName,
coords.Length() + 1);
for (size_t i = 0; i < coords.Length(); ++i) {
if (coords[i].GetUnit() == eStyleUnit_Enumerated) {
functionArray->Item(i + 1).SetIntValue(coords[i].GetIntValue(),
eCSSUnit_Enumerated);
} else if (!StyleCoordToCSSValue(coords[i],
functionArray->Item(i + 1))) {
return false;
}
}
// Set functionArray's last item to the circle or ellipse's center point:
SetPositionValue(shape->GetPosition(),
functionArray->Item(functionArray->Count() - 1));
break;
}
case StyleBasicShapeType::Polygon: {
functionArray =
aResult->Item(0).InitFunction(functionName,
ShapeArgumentCount(functionName));
functionArray->Item(1).SetEnumValue(shape->GetFillRule());
nsCSSValuePairList* list = functionArray->Item(2).SetPairListValue();
const nsTArray<nsStyleCoord>& coords = shape->Coordinates();
MOZ_ASSERT((coords.Length() % 2) == 0);
for (size_t i = 0; i < coords.Length(); i += 2) {
if (i > 0) {
list->mNext = new nsCSSValuePairList;
list = list->mNext;
}
if (!StyleCoordToCSSValue(coords[i], list->mXValue) ||
!StyleCoordToCSSValue(coords[i + 1], list->mYValue)) {
return false;
}
}
break;
}
case StyleBasicShapeType::Inset: {
const nsTArray<nsStyleCoord>& coords = shape->Coordinates();
MOZ_ASSERT(coords.Length() == ShapeArgumentCount(functionName) - 1,
"Unexpected offset count");
functionArray =
aResult->Item(0).InitFunction(functionName, coords.Length() + 1);
for (size_t i = 0; i < coords.Length(); ++i) {
if (!StyleCoordToCSSValue(coords[i], functionArray->Item(i + 1))) {
return false;
}
}
RefPtr<nsCSSValue::Array> radiusArray = nsCSSValue::Array::Create(4);
const nsStyleCorners& radii = shape->GetRadius();
NS_FOR_CSS_FULL_CORNERS(corner) {
auto pair = MakeUnique<nsCSSValuePair>();
if (!StyleCoordToCSSValue(radii.Get(FullToHalfCorner(corner, false)),
pair->mXValue) ||
!StyleCoordToCSSValue(radii.Get(FullToHalfCorner(corner, true)),
pair->mYValue)) {
return false;
}
radiusArray->Item(corner).SetPairValue(pair.get());
}
// Set the last item in functionArray to the radius array:
functionArray->Item(functionArray->Count() - 1).
SetArrayValue(radiusArray, eCSSUnit_Array);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Unknown shape type");
return false;
}
aResult->Item(1).SetEnumValue(aShapeSource.GetReferenceBox());
return true;
}
static bool
ExtractComputedValueFromShapeSource(const StyleShapeSource& aShapeSource,
StyleAnimationValue& aComputedValue)
{
const StyleShapeSourceType type = aShapeSource.GetType();
if (type == StyleShapeSourceType::URL) {
auto result = MakeUnique<nsCSSValue>();
result->SetURLValue(aShapeSource.GetURL());
aComputedValue.SetAndAdoptCSSValueValue(result.release(),
StyleAnimationValue::eUnit_URL);
} else if (type == StyleShapeSourceType::Box) {
aComputedValue.SetEnumValue(aShapeSource.GetReferenceBox());
} else if (type == StyleShapeSourceType::Shape) {
RefPtr<nsCSSValue::Array> result = nsCSSValue::Array::Create(2);
if (!StyleShapeSourceToCSSArray(aShapeSource, result)) {
return false;
}
aComputedValue.SetCSSValueArrayValue(result,
StyleAnimationValue::eUnit_Shape);
} else if (type == StyleShapeSourceType::Image) {
// XXX: Won't implement because Gecko style system will be removed.
return false;
} else {
MOZ_ASSERT(type == StyleShapeSourceType::None, "unknown type");
aComputedValue.SetNoneValue();
}
return true;
}
static void
SetFallbackValue(nsCSSValuePair* aPair, const nsStyleSVGPaint& aPaint)
{
if (aPaint.GetFallbackType() == eStyleSVGFallbackType_Color) {
aPair->mYValue.SetColorValue(aPaint.GetFallbackColor());
} else {
aPair->mYValue.SetNoneValue();
}
}
bool
StyleAnimationValue::ExtractComputedValue(nsCSSPropertyID aProperty,
GeckoStyleContext* aStyleContext,
StyleAnimationValue& aComputedValue)
{
MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
"bad property");
const void* styleStruct =
aStyleContext->StyleData(nsCSSProps::kSIDTable[aProperty]);
ptrdiff_t ssOffset = nsCSSProps::kStyleStructOffsetTable[aProperty];
nsStyleAnimType animType = nsCSSProps::kAnimTypeTable[aProperty];
MOZ_ASSERT(0 <= ssOffset ||
animType == eStyleAnimType_Custom ||
animType == eStyleAnimType_Discrete,
"all animation types other than Custom and Discrete must " \
"specify a style struct offset to extract values from");
switch (animType) {
case eStyleAnimType_Custom:
switch (aProperty) {
// For border-width, ignore the border-image business (which
// only exists until we update our implementation to the current
// spec) and use GetComputedBorder
#define BORDER_WIDTH_CASE(prop_, side_) \
case prop_: \
aComputedValue.SetCoordValue( \
static_cast<const nsStyleBorder*>(styleStruct)-> \
GetComputedBorder().side_); \
break;
BORDER_WIDTH_CASE(eCSSProperty_border_bottom_width, bottom)
BORDER_WIDTH_CASE(eCSSProperty_border_left_width, left)
BORDER_WIDTH_CASE(eCSSProperty_border_right_width, right)
BORDER_WIDTH_CASE(eCSSProperty_border_top_width, top)
#undef BORDER_WIDTH_CASE
case eCSSProperty_column_rule_width:
aComputedValue.SetCoordValue(
static_cast<const nsStyleColumn*>(styleStruct)->
GetComputedColumnRuleWidth());
break;
case eCSSProperty_column_count: {
const nsStyleColumn *styleColumn =
static_cast<const nsStyleColumn*>(styleStruct);
if (styleColumn->mColumnCount == NS_STYLE_COLUMN_COUNT_AUTO) {
aComputedValue.SetAutoValue();
} else {
aComputedValue.SetIntValue(styleColumn->mColumnCount,
eUnit_Integer);
}
break;
}
case eCSSProperty_order: {
const nsStylePosition *stylePosition =
static_cast<const nsStylePosition*>(styleStruct);
aComputedValue.SetIntValue(stylePosition->mOrder,
eUnit_Integer);
break;
}
case eCSSProperty_border_spacing: {
const nsStyleTableBorder *styleTableBorder =
static_cast<const nsStyleTableBorder*>(styleStruct);
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetIntegerCoordValue(styleTableBorder->mBorderSpacingCol);
pair->mYValue.SetIntegerCoordValue(styleTableBorder->mBorderSpacingRow);
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
break;
}
case eCSSProperty_transform_origin: {
const nsStyleDisplay *styleDisplay =
static_cast<const nsStyleDisplay*>(styleStruct);
nsAutoPtr<nsCSSValueTriplet> triplet(new nsCSSValueTriplet);
if (!StyleCoordToCSSValue(styleDisplay->mTransformOrigin[0],
triplet->mXValue) ||
!StyleCoordToCSSValue(styleDisplay->mTransformOrigin[1],
triplet->mYValue) ||
!StyleCoordToCSSValue(styleDisplay->mTransformOrigin[2],
triplet->mZValue)) {
return false;
}
aComputedValue.SetAndAdoptCSSValueTripletValue(triplet.forget(),
eUnit_CSSValueTriplet);
break;
}
case eCSSProperty_perspective_origin: {
const nsStyleDisplay *styleDisplay =
static_cast<const nsStyleDisplay*>(styleStruct);
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
if (!StyleCoordToCSSValue(styleDisplay->mPerspectiveOrigin[0],
pair->mXValue) ||
!StyleCoordToCSSValue(styleDisplay->mPerspectiveOrigin[1],
pair->mYValue)) {
return false;
}
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
break;
}
case eCSSProperty__moz_window_transform_origin: {
const nsStyleUIReset *styleUIReset =
static_cast<const nsStyleUIReset*>(styleStruct);
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
if (!StyleCoordToCSSValue(styleUIReset->mWindowTransformOrigin[0],
pair->mXValue) ||
!StyleCoordToCSSValue(styleUIReset->mWindowTransformOrigin[1],
pair->mYValue)) {
return false;
}
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
break;
}
case eCSSProperty_stroke_dasharray: {
const nsStyleSVG *svg = static_cast<const nsStyleSVG*>(styleStruct);
if (!svg->mStrokeDasharray.IsEmpty()) {
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = svg->mStrokeDasharray.Length();
i != i_end; ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
const nsStyleCoord &coord = svg->mStrokeDasharray[i];
nsCSSValue &value = item->mValue;
switch (coord.GetUnit()) {
case eStyleUnit_Coord:
// Number means the same thing as length; we want to
// animate them the same way. Normalize both to number
// since it has more accuracy (float vs nscoord).
value.SetFloatValue(nsPresContext::
AppUnitsToFloatCSSPixels(coord.GetCoordValue()),
eCSSUnit_Number);
break;
case eStyleUnit_Factor:
value.SetFloatValue(coord.GetFactorValue(),
eCSSUnit_Number);
break;
case eStyleUnit_Percent:
value.SetPercentValue(coord.GetPercentValue());
break;
default:
MOZ_ASSERT(false, "unexpected unit");
return false;
}
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_Dasharray);
} else if (svg->StrokeDasharrayFromObject()) {
// An empty dasharray with StrokeDasharrayFromObject() == true
// corresponds to the "context-value" keyword.
aComputedValue.SetIntValue(NS_STYLE_STROKE_PROP_CONTEXT_VALUE,
eUnit_Enumerated);
} else {
// Otherwise, an empty dasharray corresponds to the "none" keyword.
aComputedValue.SetNoneValue();
}
break;
}
case eCSSProperty_font_stretch: {
int16_t stretch =
static_cast<const nsStyleFont*>(styleStruct)->mFont.stretch;
Bug 895322 - Part 1: Replace the usages of MOZ_STATIC_ASSERT with C++11 static_assert; r=Waldo This patch was mostly generated by running the following scripts on the codebase, with some manual changes made afterwards: # static_assert.sh #!/bin/bash # Command to convert an NSPR integer type to the equivalent standard integer type function convert() { echo "Converting $1 to $2..." find . ! -wholename "*nsprpub*" \ ! -wholename "*security/nss*" \ ! -wholename "*/.hg*" \ ! -wholename "obj-ff-dbg*" \ ! -name nsXPCOMCID.h \ ! -name prtypes.h \ -type f \ \( -iname "*.cpp" \ -o -iname "*.h" \ -o -iname "*.cc" \ -o -iname "*.mm" \) | \ xargs -n 1 `dirname $0`/assert_replacer.py #sed -i -e "s/\b$1\b/$2/g" } convert MOZ_STATIC_ASSERT static_assert hg rev --no-backup mfbt/Assertions.h \ media/webrtc/signaling/src/sipcc/core/includes/ccapi.h \ modules/libmar/src/mar_private.h \ modules/libmar/src/mar.h # assert_replacer.py #!/usr/bin/python import sys import re pattern = re.compile(r"\bMOZ_STATIC_ASSERT\b") def replaceInPlace(fname): print fname f = open(fname, "rw+") lines = f.readlines() for i in range(0, len(lines)): while True: index = re.search(pattern, lines[i]) if index != None: index = index.start() lines[i] = lines[i][0:index] + "static_assert" + lines[i][index+len("MOZ_STATIC_ASSERT"):] for j in range(i + 1, len(lines)): if lines[j].find(" ", index) == index: lines[j] = lines[j][0:index] + lines[j][index+4:] else: break else: break f.seek(0, 0) f.truncate() f.write("".join(lines)) f.close() argc = len(sys.argv) for i in range(1, argc): replaceInPlace(sys.argv[i]) --HG-- extra : rebase_source : 4b4a4047d82f2c205b9fad8d56dfc3f1afc0b045
2013-07-18 21:59:53 +04:00
static_assert(NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED == -4 &&
NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED == 4,
"font stretch constants not as expected");
if (stretch < NS_STYLE_FONT_STRETCH_ULTRA_CONDENSED ||
stretch > NS_STYLE_FONT_STRETCH_ULTRA_EXPANDED) {
return false;
}
aComputedValue.SetIntValue(stretch, eUnit_Enumerated);
return true;
}
case eCSSProperty_font_weight: {
uint16_t weight =
static_cast<const nsStyleFont*>(styleStruct)->mFont.weight;
if (weight % 100 != 0) {
return false;
}
aComputedValue.SetIntValue(weight, eUnit_Integer);
return true;
}
case eCSSProperty__moz_image_region: {
const nsStyleList *list =
static_cast<const nsStyleList*>(styleStruct);
const nsRect &srect = list->mImageRegion;
if (srect.IsEmpty()) {
aComputedValue.SetAutoValue();
break;
}
nsCSSRect *vrect = new nsCSSRect;
vrect->mLeft.SetIntegerCoordValue(srect.x);
vrect->mTop.SetIntegerCoordValue(srect.y);
vrect->mRight.SetIntegerCoordValue(srect.XMost());
vrect->mBottom.SetIntegerCoordValue(srect.YMost());
aComputedValue.SetAndAdoptCSSRectValue(vrect, eUnit_CSSRect);
break;
}
case eCSSProperty_clip: {
const nsStyleEffects* effects =
static_cast<const nsStyleEffects*>(styleStruct);
if (!(effects->mClipFlags & NS_STYLE_CLIP_RECT)) {
aComputedValue.SetAutoValue();
} else {
nsCSSRect *vrect = new nsCSSRect;
const nsRect &srect = effects->mClip;
if (effects->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) {
vrect->mTop.SetAutoValue();
} else {
vrect->mTop.SetIntegerCoordValue(srect.y);
}
if (effects->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) {
vrect->mRight.SetAutoValue();
} else {
vrect->mRight.SetIntegerCoordValue(srect.XMost());
}
if (effects->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) {
vrect->mBottom.SetAutoValue();
} else {
vrect->mBottom.SetIntegerCoordValue(srect.YMost());
}
if (effects->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) {
vrect->mLeft.SetAutoValue();
} else {
vrect->mLeft.SetIntegerCoordValue(srect.x);
}
aComputedValue.SetAndAdoptCSSRectValue(vrect, eUnit_CSSRect);
}
break;
}
case eCSSProperty_object_position: {
const nsStylePosition* stylePos =
static_cast<const nsStylePosition*>(styleStruct);
nsAutoPtr<nsCSSValue> val(new nsCSSValue);
SetPositionValue(stylePos->mObjectPosition, *val);
aComputedValue.SetAndAdoptCSSValueValue(val.forget(),
eUnit_ObjectPosition);
break;
}
case eCSSProperty_background_position_x: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleBackground*>(styleStruct)->mImage;
ExtractImageLayerPositionXList(layers, aComputedValue);
break;
}
case eCSSProperty_background_position_y: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleBackground*>(styleStruct)->mImage;
ExtractImageLayerPositionYList(layers, aComputedValue);
break;
}
case eCSSProperty_mask_position_x: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
ExtractImageLayerPositionXList(layers, aComputedValue);
break;
}
case eCSSProperty_mask_position_y: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
ExtractImageLayerPositionYList(layers, aComputedValue);
break;
}
case eCSSProperty_background_size: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleBackground*>(styleStruct)->mImage;
ExtractImageLayerSizePairList(layers, aComputedValue);
break;
}
case eCSSProperty_mask_size: {
const nsStyleImageLayers& layers =
static_cast<const nsStyleSVGReset*>(styleStruct)->mMask;
ExtractImageLayerSizePairList(layers, aComputedValue);
break;
}
case eCSSProperty_clip_path: {
const nsStyleSVGReset* svgReset =
static_cast<const nsStyleSVGReset*>(styleStruct);
if (!ExtractComputedValueFromShapeSource(svgReset->mClipPath,
aComputedValue)) {
return false;
}
break;
}
case eCSSProperty_shape_outside: {
const nsStyleDisplay* styleDisplay =
static_cast<const nsStyleDisplay*>(styleStruct);
if (!ExtractComputedValueFromShapeSource(styleDisplay->mShapeOutside,
aComputedValue)) {
return false;
};
break;
}
case eCSSProperty_filter: {
const nsStyleEffects* effects =
static_cast<const nsStyleEffects*>(styleStruct);
const nsTArray<nsStyleFilter>& filters = effects->mFilters;
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0; i < filters.Length(); ++i) {
nsCSSValueList *item = new nsCSSValueList;
*resultTail = item;
resultTail = &item->mNext;
const nsStyleFilter& filter = filters[i];
int32_t type = filter.GetType();
if (type == NS_STYLE_FILTER_URL) {
item->mValue.SetURLValue(filter.GetURL());
} else {
nsCSSKeyword functionName =
nsCSSProps::ValueToKeywordEnum(type,
nsCSSProps::kFilterFunctionKTable);
nsCSSValue::Array* filterArray =
item->mValue.InitFunction(functionName, 1);
if (type >= NS_STYLE_FILTER_BLUR && type <= NS_STYLE_FILTER_HUE_ROTATE) {
if (!StyleCoordToCSSValue(
filter.GetFilterParameter(),
filterArray->Item(1))) {
return false;
}
} else if (type == NS_STYLE_FILTER_DROP_SHADOW) {
nsCSSValueList* shadowResult = filterArray->Item(1).SetListValue();
nsAutoPtr<nsCSSValueList> tmpShadowValue;
nsCSSValueList **tmpShadowResultTail = getter_Transfers(tmpShadowValue);
nsCSSShadowArray* shadowArray = filter.GetDropShadow();
MOZ_ASSERT(shadowArray->Length() == 1,
"expected exactly one shadow");
AppendCSSShadowValue(shadowArray->ShadowAt(0),
tmpShadowResultTail, aProperty);
*shadowResult = *tmpShadowValue;
} else {
// We checked all possible nsStyleFilter types but
// NS_STYLE_FILTER_NULL before. We should never enter this path.
NS_NOTREACHED("no other filter functions defined");
return false;
}
}
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_Filter);
break;
}
case eCSSProperty_transform: {
const nsStyleDisplay *display =
static_cast<const nsStyleDisplay*>(styleStruct);
nsAutoPtr<nsCSSValueList> result;
RefPtr<nsCSSValueSharedList> transformList = display->GetCombinedTransform();
if (transformList) {
// Clone, and convert all lengths (not percents) to pixels.
nsCSSValueList **resultTail = getter_Transfers(result);
for (const nsCSSValueList *l = transformList->mHead;
l; l = l->mNext) {
nsCSSValueList *clone = new nsCSSValueList;
*resultTail = clone;
resultTail = &clone->mNext;
SubstitutePixelValues(aStyleContext, l->mValue, clone->mValue);
}
} else {
result = new nsCSSValueList();
result->mValue.SetNoneValue();
}
aComputedValue.SetTransformValue(
new nsCSSValueSharedList(result.forget()));
break;
}
case eCSSProperty__moz_window_transform: {
const nsStyleUIReset *uiReset =
static_cast<const nsStyleUIReset*>(styleStruct);
nsAutoPtr<nsCSSValueList> result;
if (uiReset->mSpecifiedWindowTransform) {
// Clone, and convert all lengths (not percents) to pixels.
nsCSSValueList **resultTail = getter_Transfers(result);
for (const nsCSSValueList *l = uiReset->mSpecifiedWindowTransform->mHead;
l; l = l->mNext) {
nsCSSValueList *clone = new nsCSSValueList;
*resultTail = clone;
resultTail = &clone->mNext;
SubstitutePixelValues(aStyleContext, l->mValue, clone->mValue);
}
} else {
result = new nsCSSValueList();
result->mValue.SetNoneValue();
}
aComputedValue.SetTransformValue(
new nsCSSValueSharedList(result.forget()));
break;
}
case eCSSProperty_font_variation_settings: {
auto font = static_cast<const nsStyleFont*>(styleStruct);
UniquePtr<nsCSSValuePairList> result;
if (!font->mFont.fontVariationSettings.IsEmpty()) {
// Make a new list that clones the current settings
nsCSSValuePairList* tail = nullptr;
for (auto v : font->mFont.fontVariationSettings) {
auto clone = MakeUnique<nsCSSValuePairList>();
// OpenType font tags are stored in nsFont as 32-bit unsigned
// values, but represented in CSS as 4-character ASCII strings,
// beginning with the high byte of the value. So to clone the
// tag here, we append each of its 4 bytes to a string.
nsAutoString tagString;
tagString.Append(char(v.mTag >> 24));
tagString.Append(char(v.mTag >> 16));
tagString.Append(char(v.mTag >> 8));
tagString.Append(char(v.mTag));
clone->mXValue.SetStringValue(tagString, eCSSUnit_String);
clone->mYValue.SetFloatValue(v.mValue, eCSSUnit_Number);
AppendToCSSValuePairList(result, Move(clone), &tail);
}
aComputedValue.SetAndAdoptCSSValuePairListValue(result.release());
} else {
aComputedValue.SetNormalValue();
}
break;
}
default:
MOZ_ASSERT(false, "missing property implementation");
return false;
};
return true;
case eStyleAnimType_Coord: {
const nsStyleCoord& coord =
StyleDataAtOffset<nsStyleCoord>(styleStruct, ssOffset);
if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_NUMBERS_ARE_PIXELS) &&
coord.GetUnit() == eStyleUnit_Coord) {
// For SVG properties where number means the same thing as length,
// we want to animate them the same way. Normalize both to number
// since it has more accuracy (float vs nscoord).
aComputedValue.SetFloatValue(nsPresContext::
AppUnitsToFloatCSSPixels(coord.GetCoordValue()));
return true;
}
return StyleCoordToValue(coord, aComputedValue);
}
case eStyleAnimType_Sides_Top:
case eStyleAnimType_Sides_Right:
case eStyleAnimType_Sides_Bottom:
case eStyleAnimType_Sides_Left: {
Bug 895322 - Part 1: Replace the usages of MOZ_STATIC_ASSERT with C++11 static_assert; r=Waldo This patch was mostly generated by running the following scripts on the codebase, with some manual changes made afterwards: # static_assert.sh #!/bin/bash # Command to convert an NSPR integer type to the equivalent standard integer type function convert() { echo "Converting $1 to $2..." find . ! -wholename "*nsprpub*" \ ! -wholename "*security/nss*" \ ! -wholename "*/.hg*" \ ! -wholename "obj-ff-dbg*" \ ! -name nsXPCOMCID.h \ ! -name prtypes.h \ -type f \ \( -iname "*.cpp" \ -o -iname "*.h" \ -o -iname "*.cc" \ -o -iname "*.mm" \) | \ xargs -n 1 `dirname $0`/assert_replacer.py #sed -i -e "s/\b$1\b/$2/g" } convert MOZ_STATIC_ASSERT static_assert hg rev --no-backup mfbt/Assertions.h \ media/webrtc/signaling/src/sipcc/core/includes/ccapi.h \ modules/libmar/src/mar_private.h \ modules/libmar/src/mar.h # assert_replacer.py #!/usr/bin/python import sys import re pattern = re.compile(r"\bMOZ_STATIC_ASSERT\b") def replaceInPlace(fname): print fname f = open(fname, "rw+") lines = f.readlines() for i in range(0, len(lines)): while True: index = re.search(pattern, lines[i]) if index != None: index = index.start() lines[i] = lines[i][0:index] + "static_assert" + lines[i][index+len("MOZ_STATIC_ASSERT"):] for j in range(i + 1, len(lines)): if lines[j].find(" ", index) == index: lines[j] = lines[j][0:index] + lines[j][index+4:] else: break else: break f.seek(0, 0) f.truncate() f.write("".join(lines)) f.close() argc = len(sys.argv) for i in range(1, argc): replaceInPlace(sys.argv[i]) --HG-- extra : rebase_source : 4b4a4047d82f2c205b9fad8d56dfc3f1afc0b045
2013-07-18 21:59:53 +04:00
static_assert(
eSideTop == eStyleAnimType_Sides_Top -eStyleAnimType_Sides_Top &&
eSideRight == eStyleAnimType_Sides_Right -eStyleAnimType_Sides_Top &&
eSideBottom == eStyleAnimType_Sides_Bottom-eStyleAnimType_Sides_Top &&
eSideLeft == eStyleAnimType_Sides_Left -eStyleAnimType_Sides_Top,
"box side constants out of sync with animation side constants");
const nsStyleCoord &coord =
StyleDataAtOffset<nsStyleSides>(styleStruct, ssOffset).
Get(mozilla::Side(animType - eStyleAnimType_Sides_Top));
return StyleCoordToValue(coord, aComputedValue);
}
case eStyleAnimType_Corner_TopLeft:
case eStyleAnimType_Corner_TopRight:
case eStyleAnimType_Corner_BottomRight:
case eStyleAnimType_Corner_BottomLeft: {
Bug 895322 - Part 1: Replace the usages of MOZ_STATIC_ASSERT with C++11 static_assert; r=Waldo This patch was mostly generated by running the following scripts on the codebase, with some manual changes made afterwards: # static_assert.sh #!/bin/bash # Command to convert an NSPR integer type to the equivalent standard integer type function convert() { echo "Converting $1 to $2..." find . ! -wholename "*nsprpub*" \ ! -wholename "*security/nss*" \ ! -wholename "*/.hg*" \ ! -wholename "obj-ff-dbg*" \ ! -name nsXPCOMCID.h \ ! -name prtypes.h \ -type f \ \( -iname "*.cpp" \ -o -iname "*.h" \ -o -iname "*.cc" \ -o -iname "*.mm" \) | \ xargs -n 1 `dirname $0`/assert_replacer.py #sed -i -e "s/\b$1\b/$2/g" } convert MOZ_STATIC_ASSERT static_assert hg rev --no-backup mfbt/Assertions.h \ media/webrtc/signaling/src/sipcc/core/includes/ccapi.h \ modules/libmar/src/mar_private.h \ modules/libmar/src/mar.h # assert_replacer.py #!/usr/bin/python import sys import re pattern = re.compile(r"\bMOZ_STATIC_ASSERT\b") def replaceInPlace(fname): print fname f = open(fname, "rw+") lines = f.readlines() for i in range(0, len(lines)): while True: index = re.search(pattern, lines[i]) if index != None: index = index.start() lines[i] = lines[i][0:index] + "static_assert" + lines[i][index+len("MOZ_STATIC_ASSERT"):] for j in range(i + 1, len(lines)): if lines[j].find(" ", index) == index: lines[j] = lines[j][0:index] + lines[j][index+4:] else: break else: break f.seek(0, 0) f.truncate() f.write("".join(lines)) f.close() argc = len(sys.argv) for i in range(1, argc): replaceInPlace(sys.argv[i]) --HG-- extra : rebase_source : 4b4a4047d82f2c205b9fad8d56dfc3f1afc0b045
2013-07-18 21:59:53 +04:00
static_assert(
eCornerTopLeft == eStyleAnimType_Corner_TopLeft -
eStyleAnimType_Corner_TopLeft &&
eCornerTopRight == eStyleAnimType_Corner_TopRight -
eStyleAnimType_Corner_TopLeft &&
eCornerBottomRight == eStyleAnimType_Corner_BottomRight -
eStyleAnimType_Corner_TopLeft &&
eCornerBottomLeft == eStyleAnimType_Corner_BottomLeft -
eStyleAnimType_Corner_TopLeft,
"box corner constants out of sync with animation corner constants");
const nsStyleCorners& corners =
StyleDataAtOffset<nsStyleCorners>(styleStruct, ssOffset);
Corner fullCorner = Corner(animType - eStyleAnimType_Corner_TopLeft);
const nsStyleCoord &horiz =
corners.Get(FullToHalfCorner(fullCorner, false));
const nsStyleCoord &vert =
corners.Get(FullToHalfCorner(fullCorner, true));
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
if (!StyleCoordToCSSValue(horiz, pair->mXValue) ||
!StyleCoordToCSSValue(vert, pair->mYValue)) {
return false;
}
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
return true;
}
case eStyleAnimType_nscoord:
aComputedValue.SetCoordValue(
StyleDataAtOffset<nscoord>(styleStruct, ssOffset));
return true;
case eStyleAnimType_float:
aComputedValue.SetFloatValue(
StyleDataAtOffset<float>(styleStruct, ssOffset));
if (aProperty == eCSSProperty_font_size_adjust &&
aComputedValue.GetFloatValue() == -1.0f) {
// In nsStyleFont, we set mFont.sizeAdjust to -1.0 to represent
// font-size-adjust: none. Here, we have to treat this as a keyword
// instead of a float value, to make sure we don't end up doing
// interpolation with it.
aComputedValue.SetNoneValue();
}
return true;
case eStyleAnimType_Color:
aComputedValue.SetColorValue(
StyleDataAtOffset<nscolor>(styleStruct, ssOffset));
return true;
case eStyleAnimType_ComplexColor: {
auto& color = StyleDataAtOffset<StyleComplexColor>(styleStruct, ssOffset);
if (color.mIsAuto) {
aComputedValue.SetAutoValue();
} else {
aComputedValue.SetComplexColorValue(color);
}
return true;
}
case eStyleAnimType_PaintServer: {
const nsStyleSVGPaint& paint =
StyleDataAtOffset<nsStyleSVGPaint>(styleStruct, ssOffset);
switch (paint.Type()) {
case eStyleSVGPaintType_Color:
aComputedValue.SetColorValue(paint.GetColor());
return true;
case eStyleSVGPaintType_Server: {
css::URLValue* url = paint.GetPaintServer();
if (!url) {
NS_WARNING("Null paint server");
return false;
}
if (paint.GetFallbackType() != eStyleSVGFallbackType_NotSet) {
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetURLValue(url);
SetFallbackValue(pair, paint);
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
} else {
auto result = MakeUnique<nsCSSValue>();
result->SetURLValue(url);
aComputedValue.SetAndAdoptCSSValueValue(
result.release(), eUnit_URL);
}
return true;
}
case eStyleSVGPaintType_ContextFill:
case eStyleSVGPaintType_ContextStroke: {
int32_t value = paint.Type() == eStyleSVGPaintType_ContextFill ?
NS_COLOR_CONTEXT_FILL : NS_COLOR_CONTEXT_STROKE;
if (paint.GetFallbackType() != eStyleSVGFallbackType_NotSet) {
nsAutoPtr<nsCSSValuePair> pair(new nsCSSValuePair);
pair->mXValue.SetIntValue(value, eCSSUnit_Enumerated);
SetFallbackValue(pair, paint);
aComputedValue.SetAndAdoptCSSValuePairValue(pair.forget(),
eUnit_CSSValuePair);
} else {
aComputedValue.SetIntValue(value, eUnit_Enumerated);
}
return true;
}
default:
MOZ_ASSERT(paint.Type() == eStyleSVGPaintType_None,
"Unexpected SVG paint type");
aComputedValue.SetNoneValue();
return true;
}
}
case eStyleAnimType_Shadow: {
const nsCSSShadowArray* shadowArray =
StyleDataAtOffset<RefPtr<nsCSSShadowArray>>(styleStruct, ssOffset);
if (!shadowArray) {
aComputedValue.SetAndAdoptCSSValueListValue(nullptr, eUnit_Shadow);
return true;
}
nsAutoPtr<nsCSSValueList> result;
nsCSSValueList **resultTail = getter_Transfers(result);
for (uint32_t i = 0, i_end = shadowArray->Length(); i < i_end; ++i) {
AppendCSSShadowValue(shadowArray->ShadowAt(i), resultTail, aProperty);
}
aComputedValue.SetAndAdoptCSSValueListValue(result.forget(),
eUnit_Shadow);
return true;
}
case eStyleAnimType_Discrete: {
if (aProperty == eCSSProperty_visibility) {
aComputedValue.SetIntValue(
static_cast<const nsStyleVisibility*>(styleStruct)->mVisible,
eUnit_Visibility);
return true;
}
if (aStyleContext->IsServo()) {
NS_ERROR("stylo: extracting discretely animated values not supported");
return false;
}
auto cssValue = MakeUnique<nsCSSValue>(eCSSUnit_Unset);
aStyleContext->RuleNode()->GetDiscretelyAnimatedCSSValue(aProperty,
cssValue.get());
aComputedValue.SetAndAdoptCSSValueValue(cssValue.release(),
eUnit_DiscreteCSSValue);
return true;
}
case eStyleAnimType_None:
NS_NOTREACHED("shouldn't use on non-animatable properties");
}
return false;
}
Size
StyleAnimationValue::GetScaleValue(const nsIFrame* aForFrame) const
{
MOZ_ASSERT(GetUnit() == StyleAnimationValue::eUnit_Transform);
nsCSSValueSharedList* list = GetCSSValueSharedListValue();
return nsStyleTransformMatrix::GetScaleValue(list, aForFrame);
}
StyleAnimationValue::StyleAnimationValue(int32_t aInt, Unit aUnit,
IntegerConstructorType)
{
NS_ASSERTION(IsIntUnit(aUnit), "unit must be of integer type");
mUnit = aUnit;
mValue.mInt = aInt;
}
StyleAnimationValue::StyleAnimationValue(nscoord aLength, CoordConstructorType)
{
mUnit = eUnit_Coord;
mValue.mCoord = aLength;
}
StyleAnimationValue::StyleAnimationValue(float aPercent,
PercentConstructorType)
{
mUnit = eUnit_Percent;
mValue.mFloat = aPercent;
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
StyleAnimationValue::StyleAnimationValue(float aFloat, FloatConstructorType)
{
mUnit = eUnit_Float;
mValue.mFloat = aFloat;
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
StyleAnimationValue::StyleAnimationValue(nscolor aColor, ColorConstructorType)
{
mUnit = eUnit_Color;
mValue.mCSSValue = new nsCSSValue();
mValue.mCSSValue->SetColorValue(aColor);
}
StyleAnimationValue&
StyleAnimationValue::operator=(const StyleAnimationValue& aOther)
{
if (this == &aOther) {
return *this;
}
FreeValue();
mUnit = aOther.mUnit;
switch (mUnit) {
case eUnit_Null:
case eUnit_Normal:
case eUnit_Auto:
case eUnit_None:
case eUnit_CurrentColor:
break;
case eUnit_Enumerated:
case eUnit_Visibility:
case eUnit_Integer:
mValue.mInt = aOther.mValue.mInt;
break;
case eUnit_Coord:
mValue.mCoord = aOther.mValue.mCoord;
break;
case eUnit_Percent:
case eUnit_Float:
mValue.mFloat = aOther.mValue.mFloat;
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
break;
case eUnit_Calc:
case eUnit_Color:
case eUnit_ObjectPosition:
case eUnit_URL:
case eUnit_DiscreteCSSValue:
MOZ_ASSERT(IsCSSValueUnit(mUnit),
"This clause is for handling nsCSSValue-backed units");
MOZ_ASSERT(aOther.mValue.mCSSValue, "values may not be null");
mValue.mCSSValue = new nsCSSValue(*aOther.mValue.mCSSValue);
break;
case eUnit_CSSValuePair:
MOZ_ASSERT(aOther.mValue.mCSSValuePair,
"value pairs may not be null");
mValue.mCSSValuePair = new nsCSSValuePair(*aOther.mValue.mCSSValuePair);
break;
case eUnit_CSSValueTriplet:
MOZ_ASSERT(aOther.mValue.mCSSValueTriplet,
"value triplets may not be null");
mValue.mCSSValueTriplet = new nsCSSValueTriplet(*aOther.mValue.mCSSValueTriplet);
break;
case eUnit_CSSRect:
MOZ_ASSERT(aOther.mValue.mCSSRect, "rects may not be null");
mValue.mCSSRect = new nsCSSRect(*aOther.mValue.mCSSRect);
break;
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPositionCoord:
MOZ_ASSERT(mUnit == eUnit_Shadow || mUnit == eUnit_Filter ||
aOther.mValue.mCSSValueList,
"value lists other than shadows and filters may not be null");
if (aOther.mValue.mCSSValueList) {
mValue.mCSSValueList = aOther.mValue.mCSSValueList->Clone();
} else {
mValue.mCSSValueList = nullptr;
}
break;
case eUnit_Shape:
MOZ_ASSERT(aOther.mValue.mCSSValueArray,
"value arrays may not be null");
mValue.mCSSValueArray = aOther.mValue.mCSSValueArray;
mValue.mCSSValueArray->AddRef();
break;
case eUnit_Transform:
mValue.mCSSValueSharedList = aOther.mValue.mCSSValueSharedList;
mValue.mCSSValueSharedList->AddRef();
break;
case eUnit_CSSValuePairList:
MOZ_ASSERT(aOther.mValue.mCSSValuePairList,
"value pair lists may not be null");
mValue.mCSSValuePairList = aOther.mValue.mCSSValuePairList->Clone();
break;
case eUnit_UnparsedString:
MOZ_ASSERT(aOther.mValue.mString, "expecting non-null string");
mValue.mString = aOther.mValue.mString;
mValue.mString->AddRef();
break;
case eUnit_ComplexColor:
MOZ_ASSERT(aOther.mValue.mComplexColor);
mValue.mComplexColor = aOther.mValue.mComplexColor;
mValue.mComplexColor->AddRef();
break;
}
return *this;
}
void
StyleAnimationValue::SetNormalValue()
{
FreeValue();
mUnit = eUnit_Normal;
}
void
StyleAnimationValue::SetAutoValue()
{
FreeValue();
mUnit = eUnit_Auto;
}
void
StyleAnimationValue::SetNoneValue()
{
FreeValue();
mUnit = eUnit_None;
}
void
StyleAnimationValue::SetIntValue(int32_t aInt, Unit aUnit)
{
NS_ASSERTION(IsIntUnit(aUnit), "unit must be of integer type");
FreeValue();
mUnit = aUnit;
mValue.mInt = aInt;
}
void
StyleAnimationValue::SetCoordValue(nscoord aLength)
{
FreeValue();
mUnit = eUnit_Coord;
mValue.mCoord = aLength;
}
void
StyleAnimationValue::SetPercentValue(float aPercent)
{
FreeValue();
mUnit = eUnit_Percent;
mValue.mFloat = aPercent;
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
void
StyleAnimationValue::SetFloatValue(float aFloat)
{
FreeValue();
mUnit = eUnit_Float;
mValue.mFloat = aFloat;
MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
}
void
StyleAnimationValue::SetColorValue(nscolor aColor)
{
FreeValue();
mUnit = eUnit_Color;
mValue.mCSSValue = new nsCSSValue();
mValue.mCSSValue->SetColorValue(aColor);
}
void
StyleAnimationValue::SetCurrentColorValue()
{
FreeValue();
mUnit = eUnit_CurrentColor;
}
void
StyleAnimationValue::SetComplexColorValue(const StyleComplexColor& aColor)
{
if (aColor.mIsAuto) {
SetAutoValue();
} else if (aColor.IsCurrentColor()) {
SetCurrentColorValue();
} else if (aColor.IsNumericColor()) {
SetColorValue(aColor.mColor);
} else {
SetComplexColorValue(do_AddRef(new ComplexColorValue(aColor)));
}
}
void
StyleAnimationValue::SetComplexColorValue(
already_AddRefed<ComplexColorValue> aValue)
{
FreeValue();
mUnit = eUnit_ComplexColor;
mValue.mComplexColor = aValue.take();
}
void
StyleAnimationValue::SetUnparsedStringValue(const nsString& aString)
{
FreeValue();
mUnit = eUnit_UnparsedString;
mValue.mString = nsCSSValue::BufferFromString(aString).take();
}
void
StyleAnimationValue::SetAndAdoptCSSValueValue(nsCSSValue *aValue,
Unit aUnit)
{
FreeValue();
MOZ_ASSERT(IsCSSValueUnit(aUnit), "bad unit");
MOZ_ASSERT(aValue != nullptr, "values may not be null");
mUnit = aUnit;
mValue.mCSSValue = aValue; // take ownership
}
void
StyleAnimationValue::SetAndAdoptCSSValuePairValue(nsCSSValuePair *aValuePair,
Unit aUnit)
{
FreeValue();
MOZ_ASSERT(IsCSSValuePairUnit(aUnit), "bad unit");
MOZ_ASSERT(aValuePair != nullptr, "value pairs may not be null");
mUnit = aUnit;
mValue.mCSSValuePair = aValuePair; // take ownership
}
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
}
void
StyleAnimationValue::SetAndAdoptCSSRectValue(nsCSSRect *aRect, Unit aUnit)
{
FreeValue();
MOZ_ASSERT(IsCSSRectUnit(aUnit), "bad unit");
MOZ_ASSERT(aRect != nullptr, "value pairs may not be null");
mUnit = aUnit;
mValue.mCSSRect = aRect; // take ownership
}
void
StyleAnimationValue::SetCSSValueArrayValue(nsCSSValue::Array* aValue,
Unit aUnit)
{
FreeValue();
MOZ_ASSERT(IsCSSValueArrayUnit(aUnit), "bad unit");
MOZ_ASSERT(aValue != nullptr,
"not currently expecting any arrays to be null");
mUnit = aUnit;
mValue.mCSSValueArray = aValue;
mValue.mCSSValueArray->AddRef();
}
void
StyleAnimationValue::SetAndAdoptCSSValueListValue(nsCSSValueList *aValueList,
Unit aUnit)
{
FreeValue();
MOZ_ASSERT(IsCSSValueListUnit(aUnit), "bad unit");
MOZ_ASSERT(aUnit == eUnit_Shadow || aUnit == eUnit_Filter ||
aValueList != nullptr,
"value lists other than shadows and filters may not be null");
mUnit = aUnit;
mValue.mCSSValueList = aValueList; // take ownership
}
void
StyleAnimationValue::SetTransformValue(nsCSSValueSharedList* aList)
{
FreeValue();
mUnit = eUnit_Transform;
mValue.mCSSValueSharedList = aList;
mValue.mCSSValueSharedList->AddRef();
}
void
StyleAnimationValue::SetAndAdoptCSSValuePairListValue(
nsCSSValuePairList *aValuePairList)
{
FreeValue();
MOZ_ASSERT(aValuePairList, "may not be null");
mUnit = eUnit_CSSValuePairList;
mValue.mCSSValuePairList = aValuePairList; // take ownership
}
void
StyleAnimationValue::FreeValue()
{
if (IsCSSValueUnit(mUnit)) {
delete mValue.mCSSValue;
} else if (IsCSSValueListUnit(mUnit)) {
delete mValue.mCSSValueList;
} else if (IsCSSValueSharedListValue(mUnit)) {
mValue.mCSSValueSharedList->Release();
} else if (IsCSSValuePairUnit(mUnit)) {
delete mValue.mCSSValuePair;
} else if (IsCSSValueTripletUnit(mUnit)) {
delete mValue.mCSSValueTriplet;
} else if (IsCSSRectUnit(mUnit)) {
delete mValue.mCSSRect;
} else if (IsCSSValuePairListUnit(mUnit)) {
delete mValue.mCSSValuePairList;
} else if (IsCSSValueArrayUnit(mUnit)) {
mValue.mCSSValueArray->Release();
} else if (IsStringUnit(mUnit)) {
MOZ_ASSERT(mValue.mString, "expecting non-null string");
mValue.mString->Release();
} else if (mUnit == eUnit_ComplexColor) {
mValue.mComplexColor->Release();
}
}
bool
StyleAnimationValue::operator==(const StyleAnimationValue& aOther) const
{
if (mUnit != aOther.mUnit) {
return false;
}
switch (mUnit) {
case eUnit_Null:
case eUnit_Normal:
case eUnit_Auto:
case eUnit_None:
case eUnit_CurrentColor:
return true;
case eUnit_Enumerated:
case eUnit_Visibility:
case eUnit_Integer:
return mValue.mInt == aOther.mValue.mInt;
case eUnit_Coord:
return mValue.mCoord == aOther.mValue.mCoord;
case eUnit_Percent:
case eUnit_Float:
return mValue.mFloat == aOther.mValue.mFloat;
case eUnit_Calc:
case eUnit_Color:
case eUnit_ObjectPosition:
case eUnit_URL:
case eUnit_DiscreteCSSValue:
MOZ_ASSERT(IsCSSValueUnit(mUnit),
"This clause is for handling nsCSSValue-backed units");
return *mValue.mCSSValue == *aOther.mValue.mCSSValue;
case eUnit_CSSValuePair:
return *mValue.mCSSValuePair == *aOther.mValue.mCSSValuePair;
case eUnit_CSSValueTriplet:
return *mValue.mCSSValueTriplet == *aOther.mValue.mCSSValueTriplet;
case eUnit_CSSRect:
return *mValue.mCSSRect == *aOther.mValue.mCSSRect;
case eUnit_Dasharray:
case eUnit_Shadow:
case eUnit_Filter:
case eUnit_BackgroundPositionCoord:
return nsCSSValueList::Equal(mValue.mCSSValueList,
aOther.mValue.mCSSValueList);
case eUnit_Shape:
return *mValue.mCSSValueArray == *aOther.mValue.mCSSValueArray;
case eUnit_Transform:
return *mValue.mCSSValueSharedList == *aOther.mValue.mCSSValueSharedList;
case eUnit_CSSValuePairList:
return nsCSSValuePairList::Equal(mValue.mCSSValuePairList,
aOther.mValue.mCSSValuePairList);
case eUnit_UnparsedString:
return (NS_strcmp(GetStringBufferValue(),
aOther.GetStringBufferValue()) == 0);
case eUnit_ComplexColor:
return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
}
NS_NOTREACHED("incomplete case");
return false;
}
#endif
// AnimationValue Implementation
bool
AnimationValue::operator==(const AnimationValue& aOther) const
{
#ifdef MOZ_OLD_STYLE
// It is possible to compare an empty AnimationValue with others, so both
// mServo and mGecko could be null while comparing.
MOZ_ASSERT(!mServo || mGecko.IsNull());
#endif
if (mServo && aOther.mServo) {
return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo);
}
if (!mServo && !aOther.mServo) {
#ifdef MOZ_OLD_STYLE
return mGecko == aOther.mGecko;
#else
return true;
#endif
}
return false;
}
bool
AnimationValue::operator!=(const AnimationValue& aOther) const
{
return !operator==(aOther);
}
float
AnimationValue::GetOpacity() const
{
#ifdef MOZ_OLD_STYLE
MOZ_ASSERT(!mServo != mGecko.IsNull());
MOZ_ASSERT(mServo || mGecko.GetUnit() == StyleAnimationValue::eUnit_Float,
"Should have the correct unit on Gecko backend");
#else
MOZ_ASSERT(mServo);
#endif
if (mServo) {
return Servo_AnimationValue_GetOpacity(mServo);
}
#ifdef MOZ_OLD_STYLE
return mGecko.GetFloatValue();
#else
MOZ_CRASH("old style system disabled");
#endif
}
already_AddRefed<const nsCSSValueSharedList>
AnimationValue::GetTransformList() const
{
#ifdef MOZ_OLD_STYLE
MOZ_ASSERT(!mServo != mGecko.IsNull());
MOZ_ASSERT(mServo || mGecko.GetUnit() == StyleAnimationValue::eUnit_Transform,
"The unit of interpolated value for transform should be "
"transform on Gecko backend");
#else
MOZ_ASSERT(mServo);
#endif
RefPtr<nsCSSValueSharedList> transform;
if (mServo) {
Servo_AnimationValue_GetTransform(mServo, &transform);
} else {
#ifdef MOZ_OLD_STYLE
transform = mGecko.GetCSSValueSharedListValue();
#else
MOZ_CRASH("old style system disabled");
#endif
}
return transform.forget();
}
Size
AnimationValue::GetScaleValue(const nsIFrame* aFrame) const
{
#ifdef MOZ_OLD_STYLE
MOZ_ASSERT(!mServo != mGecko.IsNull());
#else
MOZ_ASSERT(mServo);
#endif
if (mServo) {
RefPtr<nsCSSValueSharedList> list;
Servo_AnimationValue_GetTransform(mServo, &list);
return nsStyleTransformMatrix::GetScaleValue(list, aFrame);
}
#ifdef MOZ_OLD_STYLE
return mGecko.GetScaleValue(aFrame);
#else
MOZ_CRASH("old style system disabled");
#endif
}
void
AnimationValue::SerializeSpecifiedValue(nsCSSPropertyID aProperty,
nsAString& aString) const
{
#ifdef MOZ_OLD_STYLE
MOZ_ASSERT(!mServo != mGecko.IsNull());
#else
MOZ_ASSERT(mServo);
#endif
if (mServo) {
Servo_AnimationValue_Serialize(mServo, aProperty, &aString);
return;
}
#ifdef MOZ_OLD_STYLE
DebugOnly<bool> uncomputeResult =
StyleAnimationValue::UncomputeValue(aProperty, mGecko, aString);
MOZ_ASSERT(uncomputeResult, "failed to uncompute StyleAnimationValue");
#else
MOZ_CRASH("old style system disabled");
#endif
}
bool
AnimationValue::IsInterpolableWith(nsCSSPropertyID aProperty,
const AnimationValue& aToValue) const
{
if (IsNull() || aToValue.IsNull()) {
return false;
}
#ifdef MOZ_OLD_STYLE
MOZ_ASSERT(!mServo != mGecko.IsNull());
MOZ_ASSERT(mGecko.IsNull() == aToValue.mGecko.IsNull() &&
!mServo == !aToValue.mServo,
"Animation values should have the same style engine");
#else
MOZ_ASSERT(mServo);
MOZ_ASSERT(aToValue.mServo);
#endif
if (mServo) {
return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo);
}
#ifdef MOZ_OLD_STYLE
// If this is ever a performance problem, we could add a
// StyleAnimationValue::IsInterpolatable method, but it seems fine for now.
StyleAnimationValue dummy;
return StyleAnimationValue::Interpolate(
aProperty, mGecko, aToValue.mGecko, 0.5, dummy);
#else
MOZ_CRASH("old style system disabled");
#endif
}
double
AnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
const AnimationValue& aOther,
nsStyleContext* aStyleContext) const
{
if (IsNull() || aOther.IsNull()) {
return 0.0;
}
#ifdef MOZ_OLD_STYLE
MOZ_ASSERT(!mServo != mGecko.IsNull());
MOZ_ASSERT(mGecko.IsNull() == aOther.mGecko.IsNull() &&
!mServo == !aOther.mServo,
"Animation values should have the same style engine");
#else
MOZ_ASSERT(mServo);
MOZ_ASSERT(aOther.mServo);
#endif
double distance= 0.0;
if (mServo) {
distance = Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo);
return distance < 0.0
? 0.0
: distance;
}
#ifdef MOZ_OLD_STYLE
return StyleAnimationValue::ComputeDistance(aProperty,
mGecko,
aOther.mGecko,
aStyleContext->AsGecko(),
distance)
? distance
: 0.0;
#else
MOZ_CRASH("old style system disabled");
#endif
}
/* static */ AnimationValue
AnimationValue::FromString(nsCSSPropertyID aProperty,
const nsAString& aValue,
Element* aElement)
{
MOZ_ASSERT(aElement);
AnimationValue result;
nsCOMPtr<nsIDocument> doc = aElement->GetComposedDoc();
if (!doc) {
return result;
}
nsCOMPtr<nsIPresShell> shell = doc->GetShell();
if (!shell) {
return result;
}
// GetStyleContext() flushes style, so we shouldn't assume that any
// non-owning references we have are still valid.
RefPtr<nsStyleContext> styleContext =
nsComputedDOMStyle::GetStyleContext(aElement, nullptr);
MOZ_ASSERT(styleContext);
if (auto* servoContext = styleContext->GetAsServo()) {
RefPtr<RawServoDeclarationBlock> declarations =
ServoCSSParser::ParseProperty(aProperty, aValue,
ServoCSSParser::GetParsingEnvironment(doc));
if (!declarations) {
return result;
}
result.mServo =
shell->StyleSet()->AsServo()->ComputeAnimationValue(aElement,
declarations,
servoContext);
return result;
}
#ifdef MOZ_OLD_STYLE
if (!StyleAnimationValue::ComputeValue(aProperty, aElement,
styleContext->AsGecko(),
aValue, false /* |aUseSVGMode| */,
result.mGecko)) {
MOZ_ASSERT(result.IsNull());
}
return result;
#else
MOZ_CRASH("old style system disabled");
#endif
}
/* static */ AnimationValue
AnimationValue::Opacity(StyleBackendType aBackendType, float aOpacity)
{
AnimationValue result;
switch (aBackendType) {
case StyleBackendType::Servo:
result.mServo = Servo_AnimationValue_Opacity(aOpacity).Consume();
break;
case StyleBackendType::Gecko:
#ifdef MOZ_OLD_STYLE
result.mGecko.SetFloatValue(aOpacity);
#else
MOZ_CRASH("old style system disabled");
#endif
break;
default:
MOZ_ASSERT_UNREACHABLE("Unsupported style backend");
}
return result;
}
/* static */ AnimationValue
AnimationValue::Transform(StyleBackendType aBackendType,
nsCSSValueSharedList& aList)
{
AnimationValue result;
switch (aBackendType) {
case StyleBackendType::Servo:
result.mServo = Servo_AnimationValue_Transform(aList).Consume();
break;
case StyleBackendType::Gecko:
#ifdef MOZ_OLD_STYLE
result.mGecko.SetTransformValue(&aList);
#else
MOZ_CRASH("old style system disabled");
#endif
break;
default:
MOZ_ASSERT_UNREACHABLE("Unsupported style backend");
}
return result;
}
/* static */ already_AddRefed<nsCSSValue::Array>
AnimationValue::AppendTransformFunction(nsCSSKeyword aTransformFunction,
nsCSSValueList**& aListTail)
{
RefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction);
nsCSSValueList *item = new nsCSSValueList;
item->mValue.SetArrayValue(arr, eCSSUnit_Function);
*aListTail = item;
aListTail = &item->mNext;
return arr.forget();
}