mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 879659 - Part 3: Implement <marker orient="auto-start-reverse">. r=longsonr
This commit is contained in:
parent
3c1809b4b3
commit
ec8519bdbb
@ -61,12 +61,22 @@ nsresult
|
||||
nsSVGOrientType::SetBaseValue(uint16_t aValue,
|
||||
nsSVGElement *aSVGElement)
|
||||
{
|
||||
if (aValue == SVG_MARKER_ORIENT_AUTO || aValue == SVG_MARKER_ORIENT_ANGLE) {
|
||||
if (aValue == SVG_MARKER_ORIENT_AUTO_START_REVERSE &&
|
||||
!SVGMarkerElement::MarkerImprovementsPrefEnabled()) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
if (aValue == SVG_MARKER_ORIENT_AUTO ||
|
||||
aValue == SVG_MARKER_ORIENT_ANGLE ||
|
||||
aValue == SVG_MARKER_ORIENT_AUTO_START_REVERSE) {
|
||||
SetBaseValue(aValue);
|
||||
aSVGElement->SetAttr(
|
||||
kNameSpaceID_None, nsGkAtoms::orient, nullptr,
|
||||
(aValue == SVG_MARKER_ORIENT_AUTO ?
|
||||
NS_LITERAL_STRING("auto") : NS_LITERAL_STRING("0")),
|
||||
NS_LITERAL_STRING("auto") :
|
||||
aValue == SVG_MARKER_ORIENT_ANGLE ?
|
||||
NS_LITERAL_STRING("0") :
|
||||
NS_LITERAL_STRING("auto-start-reverse")),
|
||||
true);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -206,6 +216,12 @@ SVGMarkerElement::ParseAttribute(int32_t aNameSpaceID, nsIAtom* aName,
|
||||
aResult.SetTo(aValue);
|
||||
return true;
|
||||
}
|
||||
if (aValue.EqualsLiteral("auto-start-reverse") &&
|
||||
MarkerImprovementsPrefEnabled()) {
|
||||
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO_START_REVERSE);
|
||||
aResult.SetTo(aValue);
|
||||
return true;
|
||||
}
|
||||
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
|
||||
}
|
||||
return SVGMarkerElementBase::ParseAttribute(aNameSpaceID, aName,
|
||||
@ -282,14 +298,24 @@ SVGMarkerElement::GetPreserveAspectRatio()
|
||||
|
||||
gfxMatrix
|
||||
SVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAutoAngle)
|
||||
float aX, float aY, float aAutoAngle,
|
||||
bool aIsStart)
|
||||
{
|
||||
gfxFloat scale = mEnumAttributes[MARKERUNITS].GetAnimValue() ==
|
||||
SVG_MARKERUNITS_STROKEWIDTH ? aStrokeWidth : 1.0;
|
||||
|
||||
gfxFloat angle = mOrientType.GetAnimValue() == SVG_MARKER_ORIENT_AUTO ?
|
||||
aAutoAngle :
|
||||
mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0;
|
||||
gfxFloat angle;
|
||||
switch (mOrientType.GetAnimValueInternal()) {
|
||||
case SVG_MARKER_ORIENT_AUTO:
|
||||
angle = aAutoAngle;
|
||||
break;
|
||||
case SVG_MARKER_ORIENT_AUTO_START_REVERSE:
|
||||
angle = aAutoAngle + (aIsStart ? M_PI : 0.0);
|
||||
break;
|
||||
default: // SVG_MARKER_ORIENT_ANGLE
|
||||
angle = mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return gfxMatrix(cos(angle) * scale, sin(angle) * scale,
|
||||
-sin(angle) * scale, cos(angle) * scale,
|
||||
|
@ -30,9 +30,10 @@ static const unsigned short SVG_MARKERUNITS_USERSPACEONUSE = 1;
|
||||
static const unsigned short SVG_MARKERUNITS_STROKEWIDTH = 2;
|
||||
|
||||
// Marker Orientation Types
|
||||
static const unsigned short SVG_MARKER_ORIENT_UNKNOWN = 0;
|
||||
static const unsigned short SVG_MARKER_ORIENT_AUTO = 1;
|
||||
static const unsigned short SVG_MARKER_ORIENT_ANGLE = 2;
|
||||
static const unsigned short SVG_MARKER_ORIENT_UNKNOWN = 0;
|
||||
static const unsigned short SVG_MARKER_ORIENT_AUTO = 1;
|
||||
static const unsigned short SVG_MARKER_ORIENT_ANGLE = 2;
|
||||
static const unsigned short SVG_MARKER_ORIENT_AUTO_START_REVERSE = 3;
|
||||
|
||||
class nsSVGOrientType
|
||||
{
|
||||
@ -52,9 +53,15 @@ public:
|
||||
void SetAnimValue(uint16_t aValue)
|
||||
{ mAnimVal = uint8_t(aValue); }
|
||||
|
||||
// we want to avoid exposing SVG_MARKER_ORIENT_AUTO_START_REVERSE to
|
||||
// Web content
|
||||
uint16_t GetBaseValue() const
|
||||
{ return mBaseVal; }
|
||||
{ return mAnimVal == SVG_MARKER_ORIENT_AUTO_START_REVERSE ?
|
||||
SVG_MARKER_ORIENT_UNKNOWN : mBaseVal; }
|
||||
uint16_t GetAnimValue() const
|
||||
{ return mAnimVal == SVG_MARKER_ORIENT_AUTO_START_REVERSE ?
|
||||
SVG_MARKER_ORIENT_UNKNOWN : mAnimVal; }
|
||||
uint16_t GetAnimValueInternal() const
|
||||
{ return mAnimVal; }
|
||||
|
||||
already_AddRefed<SVGAnimatedEnumeration>
|
||||
@ -115,7 +122,8 @@ public:
|
||||
|
||||
// public helpers
|
||||
gfxMatrix GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAutoAngle);
|
||||
float aX, float aY, float aAutoAngle,
|
||||
bool aIsStart);
|
||||
nsSVGViewBoxRect GetViewBoxRect();
|
||||
gfxMatrix GetViewBoxTransform();
|
||||
|
||||
|
@ -15,14 +15,20 @@ class nsSMILValue;
|
||||
* This nsISMILType class is a special case for the 'orient' attribute on SVG's
|
||||
* 'marker' element.
|
||||
*
|
||||
* orient = "auto | <angle>"
|
||||
* orient = "auto | auto-start-reverse | <angle>"
|
||||
*
|
||||
* Unusually, this attribute doesn't have just a single corresponding DOM
|
||||
* property, but rather is split into two properties: 'orientType' (of type
|
||||
* SVGAnimatedEnumeration) and 'orientAngle' (of type SVGAnimatedAngle). If
|
||||
* 'orientType.animVal' is not SVG_MARKER_ORIENT_AUTO, then
|
||||
* 'orientType.animVal' is SVG_MARKER_ORIENT_ANGLE, then
|
||||
* 'orientAngle.animVal' contains the angle that is being used. The lacuna
|
||||
* value is 0.
|
||||
*
|
||||
* The SVG 2 specification does not define a
|
||||
* SVG_MARKER_ORIENT_AUTO_START_REVERSE constant value for orientType to use;
|
||||
* instead, if the attribute is set to "auto-start-reverse",
|
||||
* SVG_MARKER_ORIENT_UNKNOWN is used. Internally, however, we do use a
|
||||
* constant with this name.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -379,6 +379,8 @@ nsSVGAngle::SMILOrient::ValueFromString(const nsAString& aStr,
|
||||
nsSMILValue val(&SVGOrientSMILType::sSingleton);
|
||||
if (aStr.EqualsLiteral("auto")) {
|
||||
val.mU.mOrient.mOrientType = SVG_MARKER_ORIENT_AUTO;
|
||||
} else if (aStr.EqualsLiteral("auto-start-reverse")) {
|
||||
val.mU.mOrient.mOrientType = SVG_MARKER_ORIENT_AUTO_START_REVERSE;
|
||||
} else {
|
||||
float value;
|
||||
uint16_t unitType;
|
||||
@ -426,7 +428,8 @@ nsSVGAngle::SMILOrient::SetAnimValue(const nsSMILValue& aValue)
|
||||
|
||||
if (aValue.mType == &SVGOrientSMILType::sSingleton) {
|
||||
mOrientType->SetAnimValue(aValue.mU.mOrient.mOrientType);
|
||||
if (aValue.mU.mOrient.mOrientType == SVG_MARKER_ORIENT_AUTO) {
|
||||
if (aValue.mU.mOrient.mOrientType == SVG_MARKER_ORIENT_AUTO ||
|
||||
aValue.mU.mOrient.mOrientType == SVG_MARKER_ORIENT_AUTO_START_REVERSE) {
|
||||
mAngle->SetAnimValue(0.0f, SVG_ANGLETYPE_UNSPECIFIED, mSVGElement);
|
||||
} else {
|
||||
mAngle->SetAnimValue(aValue.mU.mOrient.mAngle, aValue.mU.mOrient.mUnit, mSVGElement);
|
||||
|
@ -169,6 +169,13 @@ function runTests()
|
||||
|
||||
marker.setAttribute("orient", "auto");
|
||||
is(marker.getAttribute("orient"), "auto", "checking 'auto' string preserved");
|
||||
is(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_AUTO, "type baseVal");
|
||||
is(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_AUTO, "type animVal");
|
||||
|
||||
marker.setAttribute("orient", "auto-start-reverse");
|
||||
is(marker.getAttribute("orient"), "auto-start-reverse", "checking 'auto-start-reverse' string preserved");
|
||||
is(marker.orientType.baseVal, SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN, "type baseVal");
|
||||
is(marker.orientType.animVal, SVGMarkerElement.SVG_MARKER_ORIENT_UNKNOWN, "type animVal");
|
||||
|
||||
marker.setAttribute("orient", "");
|
||||
ok(marker.getAttribute("orient") === "", "empty angle attribute");
|
||||
@ -296,7 +303,11 @@ function runTests()
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", runTests, false);
|
||||
function runTestsWithPref() {
|
||||
SpecialPowers.pushPrefEnv({ 'set': [['svg.marker-improvements.enabled', true]] }, runTests);
|
||||
}
|
||||
|
||||
window.addEventListener("load", runTestsWithPref, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
69
layout/reftests/svg/marker-orientation-02-ref.svg
Normal file
69
layout/reftests/svg/marker-orientation-02-ref.svg
Normal file
@ -0,0 +1,69 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Reference for test that marker orientation is correct at the end of
|
||||
arcs when orient="auto-start-reverse-start-reverse" is used</title>
|
||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=769115 -->
|
||||
|
||||
<defs>
|
||||
<g id="m1" transform="translate(-20,-20)" fill="blue">
|
||||
<rect x="5" y="15" width="22" height="10"/>
|
||||
<path d="M 25,10 35,20 25,30 z"/>
|
||||
</g>
|
||||
|
||||
<g id="m2" transform="translate(-20,-20)" fill="red">
|
||||
<rect x="5" y="15" width="22" height="10"/>
|
||||
<path d="M 25,10 35,20 25,30 z"/>
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<g fill="none">
|
||||
<!-- arcs that go from the left of the circle to... -->
|
||||
<g>
|
||||
<!-- ...90 degrees anti-clockwise -->
|
||||
<use xlink:href="#m1" transform="translate(100,100)rotate(270)"/>
|
||||
<use xlink:href="#m2" transform="rotate(-90,150,100)translate(100,100)rotate(90)"/>
|
||||
<!-- ...180 degrees anti-clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(-180,150,100)translate(100,100)rotate(90)"/>
|
||||
<!-- ...270 degrees anti-clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(-270,150,100)translate(100,100)rotate(90)"/>
|
||||
</g>
|
||||
|
||||
<!-- arcs that go from the left of the circle to... -->
|
||||
<g transform="translate(250,0)">
|
||||
<!-- ...90 degrees anti-clockwise -->
|
||||
<use xlink:href="#m1" transform="translate(100,100)rotate(90)"/>
|
||||
<use xlink:href="#m2" transform="rotate(90,150,100)translate(100,100)rotate(-90)"/>
|
||||
<!-- ...180 degrees anti-clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(180,150,100)translate(100,100)rotate(-90)"/>
|
||||
<!-- ...270 degrees anti-clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(270,150,100)translate(100,100)rotate(-90)"/>
|
||||
</g>
|
||||
|
||||
<!-- arcs that go from the right of the circle to... -->
|
||||
<g transform="translate(0,250)">
|
||||
<!-- ...90 degrees anti-clockwise -->
|
||||
<use xlink:href="#m1" transform="translate(200,100)rotate(270)"/>
|
||||
<use xlink:href="#m2" transform="rotate(90,150,100)translate(200,100)rotate(90)"/>
|
||||
<!-- ...180 degrees anti-clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(180,150,100)translate(200,100)rotate(90)"/>
|
||||
<!-- ...270 degrees anti-clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(270,150,100)translate(200,100)rotate(90)"/>
|
||||
</g>
|
||||
|
||||
<!-- arcs that go from the right of the circle to... -->
|
||||
<g transform="translate(250,250)">
|
||||
<!-- ...90 degrees clockwise -->
|
||||
<use xlink:href="#m1" transform="translate(200,100)rotate(90)"/>
|
||||
<use xlink:href="#m2" transform="rotate(-90,150,100)translate(200,100)rotate(-90)"/>
|
||||
<!-- ...180 degrees clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(-180,150,100)translate(200,100)rotate(-90)"/>
|
||||
<!-- ...270 degrees clockwise -->
|
||||
<use xlink:href="#m2" transform="rotate(-270,150,100)translate(200,100)rotate(-90)"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
64
layout/reftests/svg/marker-orientation-02.svg
Normal file
64
layout/reftests/svg/marker-orientation-02.svg
Normal file
@ -0,0 +1,64 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<title>Test that marker orientation is correct at the end of arcs when
|
||||
orient="auto-start-reverse-start-reverse" is used</title>
|
||||
<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=769115 -->
|
||||
|
||||
<marker id="m1" markerWidth="40" markerHeight="40" refX="20" refY="20"
|
||||
markerUnits="userSpaceOnUse" orient="auto-start-reverse" fill="blue">
|
||||
<rect x="5" y="15" width="22" height="10"/>
|
||||
<path d="M 25,10 35,20 25,30 z"/>
|
||||
</marker>
|
||||
|
||||
<marker id="m2" markerWidth="40" markerHeight="40" refX="20" refY="20"
|
||||
markerUnits="userSpaceOnUse" orient="auto-start-reverse" fill="red">
|
||||
<rect x="5" y="15" width="22" height="10"/>
|
||||
<path d="M 25,10 35,20 25,30 z"/>
|
||||
</marker>
|
||||
|
||||
<g fill="none">
|
||||
<!-- arcs that go from the left of the circle to... -->
|
||||
<g marker-end="url(#m2)">
|
||||
<!-- ...90 degrees anti-clockwise -->
|
||||
<path d="M100,100 A 50,50 0 1 0 150,50" marker-start="url(#m1)"/>
|
||||
<!-- ...180 degrees anti-clockwise -->
|
||||
<path d="M100,100 A 50,50 0 0 0 200,100"/>
|
||||
<!-- ...270 degrees anti-clockwise -->
|
||||
<path d="M100,100 A 50,50 0 0 0 150,150"/>
|
||||
</g>
|
||||
|
||||
<!-- arcs that go from the left of the circle to... -->
|
||||
<g marker-end="url(#m2)" transform="translate(250,0)">
|
||||
<!-- ...90 degrees clockwise -->
|
||||
<path d="M100,100 A 50,50 0 0 1 150,50" marker-start="url(#m1)"/>
|
||||
<!-- ...180 degrees clockwise -->
|
||||
<path d="M100,100 A 50,50 0 1 1 200,100"/>
|
||||
<!-- ...270 degrees clockwise -->
|
||||
<path d="M100,100 A 50,50 0 1 1 150,150"/>
|
||||
</g>
|
||||
|
||||
<!-- arcs that go from the right of the circle to... -->
|
||||
<g marker-end="url(#m2)" transform="translate(0,250)">
|
||||
<!-- ...90 degrees anti-clockwise -->
|
||||
<path d="M200,100 A 50,50 0 0 1 150,150" marker-start="url(#m1)"/>
|
||||
<!-- ...180 degrees anti-clockwise -->
|
||||
<path d="M200,100 A 50,50 0 0 1 100,100"/>
|
||||
<!-- ...270 degrees anti-clockwise -->
|
||||
<path d="M200,100 A 50,50 0 1 1 150,50"/>
|
||||
</g>
|
||||
|
||||
<!-- arcs that go from the right of the circle to... -->
|
||||
<g marker-end="url(#m2)" transform="translate(250,250)">
|
||||
<!-- ...90 degrees anti-clockwise -->
|
||||
<path d="M200,100 A 50,50 0 0 0 150,50" marker-start="url(#m1)"/>
|
||||
<!-- ...180 degrees anti-clockwise -->
|
||||
<path d="M200,100 A 50,50 0 1 0 100,100"/>
|
||||
<!-- ...270 degrees anti-clockwise -->
|
||||
<path d="M200,100 A 50,50 0 1 0 150,150"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
@ -184,6 +184,7 @@ fuzzy-if(Android,9,980) == gradient-live-01d.svg gradient-live-01-ref.svg
|
||||
== marker-attribute-01.svg pass.svg
|
||||
== marker-viewBox-01.svg marker-viewBox-01-ref.svg
|
||||
== marker-orientation-01.svg marker-orientation-01-ref.svg
|
||||
pref(svg.marker-improvements.enabled,true) == marker-orientation-02.svg marker-orientation-02-ref.svg
|
||||
== mask-basic-01.svg pass.svg
|
||||
== mask-basic-02.svg mask-basic-02-ref.svg
|
||||
== mask-basic-03.svg pass.svg
|
||||
|
@ -85,7 +85,8 @@ nsSVGMarkerFrame::GetCanvasTM(uint32_t aFor)
|
||||
gfxMatrix markedTM = mMarkedFrame->GetCanvasTM(aFor);
|
||||
mInUse2 = false;
|
||||
|
||||
gfxMatrix markerTM = content->GetMarkerTransform(mStrokeWidth, mX, mY, mAutoAngle);
|
||||
gfxMatrix markerTM = content->GetMarkerTransform(mStrokeWidth, mX, mY,
|
||||
mAutoAngle, mIsStart);
|
||||
gfxMatrix viewBoxTM = content->GetViewBoxTransform();
|
||||
|
||||
return viewBoxTM * markerTM * markedTM;
|
||||
@ -118,6 +119,7 @@ nsSVGMarkerFrame::PaintMark(nsRenderingContext *aContext,
|
||||
mX = aMark->x;
|
||||
mY = aMark->y;
|
||||
mAutoAngle = aMark->angle;
|
||||
mIsStart = aMark->type == nsSVGMark::eStart;
|
||||
|
||||
gfxContext *gfx = aContext->ThebesContext();
|
||||
|
||||
@ -175,9 +177,10 @@ nsSVGMarkerFrame::GetMarkBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
mX = aMark->x;
|
||||
mY = aMark->y;
|
||||
mAutoAngle = aMark->angle;
|
||||
mIsStart = aMark->type == nsSVGMark::eStart;
|
||||
|
||||
gfxMatrix markerTM =
|
||||
content->GetMarkerTransform(mStrokeWidth, mX, mY, mAutoAngle);
|
||||
content->GetMarkerTransform(mStrokeWidth, mX, mY, mAutoAngle, mIsStart);
|
||||
gfxMatrix viewBoxTM = content->GetViewBoxTransform();
|
||||
|
||||
gfxMatrix tm = viewBoxTM * markerTM * aToBBoxUserspace;
|
||||
|
@ -94,6 +94,7 @@ private:
|
||||
// stuff needed for callback
|
||||
nsSVGPathGeometryFrame *mMarkedFrame;
|
||||
float mStrokeWidth, mX, mY, mAutoAngle;
|
||||
bool mIsStart; // whether the callback is for a marker-start marker
|
||||
|
||||
// nsSVGContainerFrame methods:
|
||||
virtual gfxMatrix GetCanvasTM(uint32_t aFor) MOZ_OVERRIDE;
|
||||
|
Loading…
Reference in New Issue
Block a user