--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -5882,93 +5882,103 @@ nsComputedDOMStyle::BasicShapeRadiiToStr
if (horizontalString == verticalString) {
return;
}
aCssText.AppendLiteral(" / ");
aCssText.Append(verticalString);
}
already_AddRefed<CSSValue>
+nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
+ const nsStyleBasicShape* aStyleBasicShape)
+{
+ MOZ_ASSERT(aStyleBasicShape, "Expect a valid basic shape pointer!");
+
+ nsStyleBasicShape::Type type = aStyleBasicShape->GetShapeType();
+ // Shape function name and opening parenthesis.
+ nsAutoString shapeFunctionString;
+ AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(
+ aStyleBasicShape->GetShapeTypeName()),
+ shapeFunctionString);
+ shapeFunctionString.Append('(');
+ switch (type) {
+ case nsStyleBasicShape::Type::ePolygon: {
+ bool hasEvenOdd = aStyleBasicShape->GetFillRule() ==
+ NS_STYLE_FILL_RULE_EVENODD;
+ if (hasEvenOdd) {
+ shapeFunctionString.AppendLiteral("evenodd");
+ }
+ for (size_t i = 0;
+ i < aStyleBasicShape->Coordinates().Length(); i += 2) {
+ nsAutoString coordString;
+ if (i > 0 || hasEvenOdd) {
+ shapeFunctionString.AppendLiteral(", ");
+ }
+ SetCssTextToCoord(coordString,
+ aStyleBasicShape->Coordinates()[i]);
+ shapeFunctionString.Append(coordString);
+ shapeFunctionString.Append(' ');
+ SetCssTextToCoord(coordString,
+ aStyleBasicShape->Coordinates()[i + 1]);
+ shapeFunctionString.Append(coordString);
+ }
+ break;
+ }
+ case nsStyleBasicShape::Type::eCircle:
+ case nsStyleBasicShape::Type::eEllipse: {
+ const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
+ MOZ_ASSERT(radii.Length() ==
+ (type == nsStyleBasicShape::Type::eCircle ? 1 : 2),
+ "wrong number of radii");
+ for (size_t i = 0; i < radii.Length(); ++i) {
+ nsAutoString radius;
+ RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
+ bool clampNegativeCalc = true;
+ SetValueToCoord(value, radii[i], clampNegativeCalc, nullptr,
+ nsCSSProps::kShapeRadiusKTable);
+ value->GetCssText(radius);
+ shapeFunctionString.Append(radius);
+ shapeFunctionString.Append(' ');
+ }
+ shapeFunctionString.AppendLiteral("at ");
+
+ RefPtr<nsDOMCSSValueList> position = GetROCSSValueList(false);
+ nsAutoString positionString;
+ SetValueToPosition(aStyleBasicShape->GetPosition(), position);
+ position->GetCssText(positionString);
+ shapeFunctionString.Append(positionString);
+ break;
+ }
+ case nsStyleBasicShape::Type::eInset: {
+ BoxValuesToString(shapeFunctionString, aStyleBasicShape->Coordinates());
+ if (aStyleBasicShape->HasRadius()) {
+ shapeFunctionString.AppendLiteral(" round ");
+ nsAutoString radiiString;
+ BasicShapeRadiiToString(radiiString, aStyleBasicShape->GetRadius());
+ shapeFunctionString.Append(radiiString);
+ }
+ break;
+ }
+ default:
+ NS_NOTREACHED("unexpected type");
+ }
+ shapeFunctionString.Append(')');
+ RefPtr<nsROCSSPrimitiveValue> functionValue = new nsROCSSPrimitiveValue;
+ functionValue->SetString(shapeFunctionString);
+ return functionValue.forget();
+}
+
+already_AddRefed<CSSValue>
nsComputedDOMStyle::CreatePrimitiveValueForClipPath(
const nsStyleBasicShape* aStyleBasicShape, uint8_t aSizingBox)
{
RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
if (aStyleBasicShape) {
- nsStyleBasicShape::Type type = aStyleBasicShape->GetShapeType();
- // Shape function name and opening parenthesis.
- nsAutoString shapeFunctionString;
- AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(
- aStyleBasicShape->GetShapeTypeName()),
- shapeFunctionString);
- shapeFunctionString.Append('(');
- switch (type) {
- case nsStyleBasicShape::Type::ePolygon: {
- bool hasEvenOdd = aStyleBasicShape->GetFillRule() ==
- NS_STYLE_FILL_RULE_EVENODD;
- if (hasEvenOdd) {
- shapeFunctionString.AppendLiteral("evenodd");
- }
- for (size_t i = 0;
- i < aStyleBasicShape->Coordinates().Length(); i += 2) {
- nsAutoString coordString;
- if (i > 0 || hasEvenOdd) {
- shapeFunctionString.AppendLiteral(", ");
- }
- SetCssTextToCoord(coordString,
- aStyleBasicShape->Coordinates()[i]);
- shapeFunctionString.Append(coordString);
- shapeFunctionString.Append(' ');
- SetCssTextToCoord(coordString,
- aStyleBasicShape->Coordinates()[i + 1]);
- shapeFunctionString.Append(coordString);
- }
- break;
- }
- case nsStyleBasicShape::Type::eCircle:
- case nsStyleBasicShape::Type::eEllipse: {
- const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
- MOZ_ASSERT(radii.Length() ==
- (type == nsStyleBasicShape::Type::eCircle ? 1 : 2),
- "wrong number of radii");
- for (size_t i = 0; i < radii.Length(); ++i) {
- nsAutoString radius;
- RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
- bool clampNegativeCalc = true;
- SetValueToCoord(value, radii[i], clampNegativeCalc, nullptr,
- nsCSSProps::kShapeRadiusKTable);
- value->GetCssText(radius);
- shapeFunctionString.Append(radius);
- shapeFunctionString.Append(' ');
- }
- shapeFunctionString.AppendLiteral("at ");
-
- RefPtr<nsDOMCSSValueList> position = GetROCSSValueList(false);
- nsAutoString positionString;
- SetValueToPosition(aStyleBasicShape->GetPosition(), position);
- position->GetCssText(positionString);
- shapeFunctionString.Append(positionString);
- break;
- }
- case nsStyleBasicShape::Type::eInset: {
- BoxValuesToString(shapeFunctionString, aStyleBasicShape->Coordinates());
- if (aStyleBasicShape->HasRadius()) {
- shapeFunctionString.AppendLiteral(" round ");
- nsAutoString radiiString;
- BasicShapeRadiiToString(radiiString, aStyleBasicShape->GetRadius());
- shapeFunctionString.Append(radiiString);
- }
- break;
- }
- default:
- NS_NOTREACHED("unexpected type");
- }
- shapeFunctionString.Append(')');
- RefPtr<nsROCSSPrimitiveValue> functionValue = new nsROCSSPrimitiveValue;
- functionValue->SetString(shapeFunctionString);
- valueList->AppendCSSValue(functionValue.forget());
+ valueList->AppendCSSValue(
+ CreatePrimitiveValueForBasicShape(aStyleBasicShape));
}
if (aSizingBox == NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
return valueList.forget();
}
nsAutoString boxString;
AppendASCIItoUTF16(
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -9517,16 +9517,165 @@ nsRuleNode::ComputeSVGData(void* aStartS
svg->mTextAnchor, conditions,
SETDSC_ENUMERATED | SETDSC_UNSET_INHERIT,
parentSVG->mTextAnchor,
NS_STYLE_TEXT_ANCHOR_START, 0, 0, 0, 0);
COMPUTE_END_INHERITED(SVG, svg)
}
+already_AddRefed<nsStyleBasicShape>
+nsRuleNode::GetStyleBasicShapeFromCSSValue(const nsCSSValue& aValue,
+ nsStyleContext* aStyleContext,
+ nsPresContext* aPresContext,
+ RuleNodeCacheConditions& aConditions)
+{
+ RefPtr<nsStyleBasicShape> basicShape;
+
+ nsCSSValue::Array* shapeFunction = aValue.GetArrayValue();
+ nsCSSKeyword functionName =
+ (nsCSSKeyword)shapeFunction->Item(0).GetIntValue();
+
+ if (functionName == eCSSKeyword_polygon) {
+ MOZ_ASSERT(!basicShape, "did not expect value");
+ basicShape = new nsStyleBasicShape(nsStyleBasicShape::ePolygon);
+ MOZ_ASSERT(shapeFunction->Count() > 1,
+ "polygon has wrong number of arguments");
+ size_t j = 1;
+ if (shapeFunction->Item(j).GetUnit() == eCSSUnit_Enumerated) {
+ basicShape->SetFillRule(shapeFunction->Item(j).GetIntValue());
+ ++j;
+ }
+ const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
+ SETCOORD_STORE_CALC;
+ const nsCSSValuePairList* curPair =
+ shapeFunction->Item(j).GetPairListValue();
+ nsTArray<nsStyleCoord>& coordinates = basicShape->Coordinates();
+ while (curPair) {
+ nsStyleCoord xCoord, yCoord;
+ DebugOnly<bool> didSetCoordX = SetCoord(curPair->mXValue, xCoord,
+ nsStyleCoord(), mask,
+ aStyleContext, aPresContext,
+ aConditions);
+ coordinates.AppendElement(xCoord);
+ MOZ_ASSERT(didSetCoordX, "unexpected x coordinate unit");
+ DebugOnly<bool> didSetCoordY = SetCoord(curPair->mYValue, yCoord,
+ nsStyleCoord(), mask,
+ aStyleContext, aPresContext,
+ aConditions);
+ coordinates.AppendElement(yCoord);
+ MOZ_ASSERT(didSetCoordY, "unexpected y coordinate unit");
+ curPair = curPair->mNext;
+ }
+ } else if (functionName == eCSSKeyword_circle ||
+ functionName == eCSSKeyword_ellipse) {
+ nsStyleBasicShape::Type type = functionName == eCSSKeyword_circle ?
+ nsStyleBasicShape::eCircle :
+ nsStyleBasicShape::eEllipse;
+ MOZ_ASSERT(!basicShape, "did not expect value");
+ basicShape = new nsStyleBasicShape(type);
+ const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
+ SETCOORD_STORE_CALC | SETCOORD_ENUMERATED;
+ size_t count = type == nsStyleBasicShape::eCircle ? 2 : 3;
+ MOZ_ASSERT(shapeFunction->Count() == count + 1,
+ "unexpected arguments count");
+ MOZ_ASSERT(type == nsStyleBasicShape::eCircle ||
+ (shapeFunction->Item(1).GetUnit() == eCSSUnit_Null) ==
+ (shapeFunction->Item(2).GetUnit() == eCSSUnit_Null),
+ "ellipse should have two radii or none");
+ for (size_t j = 1; j < count; ++j) {
+ const nsCSSValue& val = shapeFunction->Item(j);
+ nsStyleCoord radius;
+ if (val.GetUnit() != eCSSUnit_Null) {
+ DebugOnly<bool> didSetRadius = SetCoord(val, radius,
+ nsStyleCoord(), mask,
+ aStyleContext,
+ aPresContext,
+ aConditions);
+ MOZ_ASSERT(didSetRadius, "unexpected radius unit");
+ } else {
+ radius.SetIntValue(NS_RADIUS_CLOSEST_SIDE, eStyleUnit_Enumerated);
+ }
+ basicShape->Coordinates().AppendElement(radius);
+ }
+ const nsCSSValue& positionVal = shapeFunction->Item(count);
+ if (positionVal.GetUnit() == eCSSUnit_Array) {
+ ComputePositionValue(aStyleContext, positionVal,
+ basicShape->GetPosition(),
+ aConditions);
+ } else {
+ MOZ_ASSERT(positionVal.GetUnit() == eCSSUnit_Null,
+ "expected no value");
+ }
+ } else if (functionName == eCSSKeyword_inset) {
+ MOZ_ASSERT(!basicShape, "did not expect value");
+ basicShape = new nsStyleBasicShape(nsStyleBasicShape::eInset);
+ MOZ_ASSERT(shapeFunction->Count() == 6,
+ "inset function has wrong number of arguments");
+ MOZ_ASSERT(shapeFunction->Item(1).GetUnit() != eCSSUnit_Null,
+ "no shape arguments defined");
+ const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
+ SETCOORD_STORE_CALC;
+ nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
+ for (size_t j = 1; j <= 4; ++j) {
+ const nsCSSValue& val = shapeFunction->Item(j);
+ nsStyleCoord inset;
+ // Fill missing values to get 4 at the end.
+ if (val.GetUnit() == eCSSUnit_Null) {
+ if (j == 4) {
+ inset = coords[1];
+ } else {
+ MOZ_ASSERT(j != 1, "first argument not specified");
+ inset = coords[0];
+ }
+ } else {
+ DebugOnly<bool> didSetInset = SetCoord(val, inset,
+ nsStyleCoord(), mask,
+ aStyleContext, aPresContext,
+ aConditions);
+ MOZ_ASSERT(didSetInset, "unexpected inset unit");
+ }
+ coords.AppendElement(inset);
+ }
+
+ nsStyleCorners& insetRadius = basicShape->GetRadius();
+ if (shapeFunction->Item(5).GetUnit() == eCSSUnit_Array) {
+ nsCSSValue::Array* radiiArray = shapeFunction->Item(5).GetArrayValue();
+ NS_FOR_CSS_FULL_CORNERS(corner) {
+ int cx = NS_FULL_TO_HALF_CORNER(corner, false);
+ int cy = NS_FULL_TO_HALF_CORNER(corner, true);
+ const nsCSSValue& radius = radiiArray->Item(corner);
+ nsStyleCoord coordX, coordY;
+ DebugOnly<bool> didSetRadii = SetPairCoords(radius, coordX, coordY,
+ nsStyleCoord(),
+ nsStyleCoord(), mask,
+ aStyleContext,
+ aPresContext,
+ aConditions);
+ MOZ_ASSERT(didSetRadii, "unexpected radius unit");
+ insetRadius.Set(cx, coordX);
+ insetRadius.Set(cy, coordY);
+ }
+ } else {
+ MOZ_ASSERT(shapeFunction->Item(5).GetUnit() == eCSSUnit_Null,
+ "unexpected value");
+ // Initialize border-radius
+ nsStyleCoord zero;
+ zero.SetCoordValue(0);
+ NS_FOR_CSS_HALF_CORNERS(j) {
+ insetRadius.Set(j, zero);
+ }
+ }
+ } else {
+ NS_NOTREACHED("unexpected basic shape function");
+ }
+
+ return basicShape.forget();
+}
+
void
nsRuleNode::SetStyleClipPathToCSSValue(nsStyleClipPath* aStyleClipPath,
const nsCSSValue* aValue,
nsStyleContext* aStyleContext,
nsPresContext* aPresContext,
RuleNodeCacheConditions& aConditions)
{
MOZ_ASSERT(aValue->GetUnit() == eCSSUnit_Array,
@@ -9543,153 +9692,18 @@ nsRuleNode::SetStyleClipPathToCSSValue(n
int32_t type = array->Item(i).GetIntValue();
if (type > NS_STYLE_CLIP_SHAPE_SIZING_VIEW ||
type < NS_STYLE_CLIP_SHAPE_SIZING_NOBOX) {
NS_NOTREACHED("unexpected reference box");
return;
}
sizingBox = (uint8_t)type;
} else if (array->Item(i).GetUnit() == eCSSUnit_Function) {
- nsCSSValue::Array* shapeFunction = array->Item(i).GetArrayValue();
- nsCSSKeyword functionName =
- (nsCSSKeyword)shapeFunction->Item(0).GetIntValue();
- if (functionName == eCSSKeyword_polygon) {
- MOZ_ASSERT(!basicShape, "did not expect value");
- basicShape = new nsStyleBasicShape(nsStyleBasicShape::ePolygon);
- MOZ_ASSERT(shapeFunction->Count() > 1,
- "polygon has wrong number of arguments");
- size_t j = 1;
- if (shapeFunction->Item(j).GetUnit() == eCSSUnit_Enumerated) {
- basicShape->SetFillRule(shapeFunction->Item(j).GetIntValue());
- ++j;
- }
- const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
- SETCOORD_STORE_CALC;
- const nsCSSValuePairList* curPair =
- shapeFunction->Item(j).GetPairListValue();
- nsTArray<nsStyleCoord>& coordinates = basicShape->Coordinates();
- while (curPair) {
- nsStyleCoord xCoord, yCoord;
- DebugOnly<bool> didSetCoordX = SetCoord(curPair->mXValue, xCoord,
- nsStyleCoord(), mask,
- aStyleContext, aPresContext,
- aConditions);
- coordinates.AppendElement(xCoord);
- MOZ_ASSERT(didSetCoordX, "unexpected x coordinate unit");
- DebugOnly<bool> didSetCoordY = SetCoord(curPair->mYValue, yCoord,
- nsStyleCoord(), mask,
- aStyleContext, aPresContext,
- aConditions);
- coordinates.AppendElement(yCoord);
- MOZ_ASSERT(didSetCoordY, "unexpected y coordinate unit");
- curPair = curPair->mNext;
- }
- } else if (functionName == eCSSKeyword_circle ||
- functionName == eCSSKeyword_ellipse) {
- nsStyleBasicShape::Type type = functionName == eCSSKeyword_circle ?
- nsStyleBasicShape::eCircle :
- nsStyleBasicShape::eEllipse;
- MOZ_ASSERT(!basicShape, "did not expect value");
- basicShape = new nsStyleBasicShape(type);
- const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
- SETCOORD_STORE_CALC | SETCOORD_ENUMERATED;
- size_t count = type == nsStyleBasicShape::eCircle ? 2 : 3;
- MOZ_ASSERT(shapeFunction->Count() == count + 1,
- "unexpected arguments count");
- MOZ_ASSERT(type == nsStyleBasicShape::eCircle ||
- (shapeFunction->Item(1).GetUnit() == eCSSUnit_Null) ==
- (shapeFunction->Item(2).GetUnit() == eCSSUnit_Null),
- "ellipse should have two radii or none");
- for (size_t j = 1; j < count; ++j) {
- const nsCSSValue& val = shapeFunction->Item(j);
- nsStyleCoord radius;
- if (val.GetUnit() != eCSSUnit_Null) {
- DebugOnly<bool> didSetRadius = SetCoord(val, radius,
- nsStyleCoord(), mask,
- aStyleContext,
- aPresContext,
- aConditions);
- MOZ_ASSERT(didSetRadius, "unexpected radius unit");
- } else {
- radius.SetIntValue(NS_RADIUS_CLOSEST_SIDE, eStyleUnit_Enumerated);
- }
- basicShape->Coordinates().AppendElement(radius);
- }
- const nsCSSValue& positionVal = shapeFunction->Item(count);
- if (positionVal.GetUnit() == eCSSUnit_Array) {
- ComputePositionValue(aStyleContext, positionVal,
- basicShape->GetPosition(),
- aConditions);
- } else {
- MOZ_ASSERT(positionVal.GetUnit() == eCSSUnit_Null,
- "expected no value");
- }
- } else if (functionName == eCSSKeyword_inset) {
- MOZ_ASSERT(!basicShape, "did not expect value");
- basicShape = new nsStyleBasicShape(nsStyleBasicShape::eInset);
- MOZ_ASSERT(shapeFunction->Count() == 6,
- "inset function has wrong number of arguments");
- MOZ_ASSERT(shapeFunction->Item(1).GetUnit() != eCSSUnit_Null,
- "no shape arguments defined");
- const int32_t mask = SETCOORD_PERCENT | SETCOORD_LENGTH |
- SETCOORD_STORE_CALC;
- nsTArray<nsStyleCoord>& coords = basicShape->Coordinates();
- for (size_t j = 1; j <= 4; ++j) {
- const nsCSSValue& val = shapeFunction->Item(j);
- nsStyleCoord inset;
- // Fill missing values to get 4 at the end.
- if (val.GetUnit() == eCSSUnit_Null) {
- if (j == 4) {
- inset = coords[1];
- } else {
- MOZ_ASSERT(j != 1, "first argument not specified");
- inset = coords[0];
- }
- } else {
- DebugOnly<bool> didSetInset = SetCoord(val, inset,
- nsStyleCoord(), mask,
- aStyleContext, aPresContext,
- aConditions);
- MOZ_ASSERT(didSetInset, "unexpected inset unit");
- }
- coords.AppendElement(inset);
- }
-
- nsStyleCorners& insetRadius = basicShape->GetRadius();
- if (shapeFunction->Item(5).GetUnit() == eCSSUnit_Array) {
- nsCSSValue::Array* radiiArray = shapeFunction->Item(5).GetArrayValue();
- NS_FOR_CSS_FULL_CORNERS(corner) {
- int cx = NS_FULL_TO_HALF_CORNER(corner, false);
- int cy = NS_FULL_TO_HALF_CORNER(corner, true);
- const nsCSSValue& radius = radiiArray->Item(corner);
- nsStyleCoord coordX, coordY;
- DebugOnly<bool> didSetRadii = SetPairCoords(radius, coordX, coordY,
- nsStyleCoord(),
- nsStyleCoord(), mask,
- aStyleContext,
- aPresContext,
- aConditions);
- MOZ_ASSERT(didSetRadii, "unexpected radius unit");
- insetRadius.Set(cx, coordX);
- insetRadius.Set(cy, coordY);
- }
- } else {
- MOZ_ASSERT(shapeFunction->Item(5).GetUnit() == eCSSUnit_Null,
- "unexpected value");
- // Initialize border-radius
- nsStyleCoord zero;
- zero.SetCoordValue(0);
- NS_FOR_CSS_HALF_CORNERS(j) {
- insetRadius.Set(j, zero);
- }
- }
- } else {
- NS_NOTREACHED("unexpected basic shape function");
- return;
- }
+ basicShape = GetStyleBasicShapeFromCSSValue(array->Item(i), aStyleContext,
+ aPresContext, aConditions);
} else {
NS_NOTREACHED("unexpected value");
return;
}
}
if (basicShape) {
aStyleClipPath->SetBasicShape(basicShape, sizingBox);