mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 528332 - Implement non-scaling-stroke vector-effect. Part 2 - SVG changes r=dholbert
This commit is contained in:
parent
3ca6774243
commit
38cb4c47d9
@ -11275,7 +11275,7 @@ define("examples/textview/textStyler", ['orion/textview/annotations'], function(
|
|||||||
"target", "target-name", "target-new", "target-position", "text-align", "text-align-last", "text-decoration", "text-emphasis",
|
"target", "target-name", "target-new", "target-position", "text-align", "text-align-last", "text-decoration", "text-emphasis",
|
||||||
"text-height", "text-indent", "text-justify", "text-outline", "text-shadow", "text-transform", "text-wrap", "top", "transform",
|
"text-height", "text-indent", "text-justify", "text-outline", "text-shadow", "text-transform", "text-wrap", "top", "transform",
|
||||||
"transform-origin", "transform-style", "transition", "transition-delay", "transition-duration", "transition-property",
|
"transform-origin", "transform-style", "transition", "transition-delay", "transition-duration", "transition-property",
|
||||||
"transition-timing-function", "unicode-bidi", "vertical-align", "visibility", "voice-balance", "voice-duration", "voice-family",
|
"transition-timing-function", "unicode-bidi", "vector-effect", "vertical-align", "visibility", "voice-balance", "voice-duration", "voice-family",
|
||||||
"voice-pitch", "voice-pitch-range", "voice-rate", "voice-stress", "voice-volume", "volume", "white-space", "white-space-collapse",
|
"voice-pitch", "voice-pitch-range", "voice-rate", "voice-stress", "voice-volume", "volume", "white-space", "white-space-collapse",
|
||||||
"widows", "width", "word-break", "word-spacing", "word-wrap", "z-index"
|
"widows", "width", "word-break", "word-spacing", "word-wrap", "z-index"
|
||||||
];
|
];
|
||||||
|
@ -1378,6 +1378,7 @@ GK_ATOM(y2, "y2")
|
|||||||
GK_ATOM(yChannelSelector, "yChannelSelector")
|
GK_ATOM(yChannelSelector, "yChannelSelector")
|
||||||
GK_ATOM(z, "z")
|
GK_ATOM(z, "z")
|
||||||
GK_ATOM(zoomAndPan, "zoomAndPan")
|
GK_ATOM(zoomAndPan, "zoomAndPan")
|
||||||
|
GK_ATOM(vector_effect, "vector-effect")
|
||||||
|
|
||||||
GK_ATOM(accumulate, "accumulate")
|
GK_ATOM(accumulate, "accumulate")
|
||||||
GK_ATOM(additive, "additive")
|
GK_ATOM(additive, "additive")
|
||||||
|
@ -628,6 +628,7 @@ nsIAtom** const kAttributesSVG[] = {
|
|||||||
// v-ideographic
|
// v-ideographic
|
||||||
// v-mathematical
|
// v-mathematical
|
||||||
&nsGkAtoms::values, // values
|
&nsGkAtoms::values, // values
|
||||||
|
&nsGkAtoms::vector_effect, // vector-effect
|
||||||
// vert-adv-y
|
// vert-adv-y
|
||||||
// vert-origin-x
|
// vert-origin-x
|
||||||
// vert-origin-y
|
// vert-origin-y
|
||||||
|
@ -281,6 +281,7 @@ nsSMILCSSProperty::IsPropertyAnimatable(nsCSSProperty aPropID)
|
|||||||
case eCSSProperty_text_decoration:
|
case eCSSProperty_text_decoration:
|
||||||
case eCSSProperty_text_decoration_line:
|
case eCSSProperty_text_decoration_line:
|
||||||
case eCSSProperty_text_rendering:
|
case eCSSProperty_text_rendering:
|
||||||
|
case eCSSProperty_vector_effect:
|
||||||
case eCSSProperty_visibility:
|
case eCSSProperty_visibility:
|
||||||
case eCSSProperty_word_spacing:
|
case eCSSProperty_word_spacing:
|
||||||
return true;
|
return true;
|
||||||
|
@ -463,6 +463,9 @@ var gFromToBundles = [
|
|||||||
new TestcaseBundle(gPropList.unicode_bidi, [
|
new TestcaseBundle(gPropList.unicode_bidi, [
|
||||||
new AnimTestcaseFromTo("embed", "bidi-override"),
|
new AnimTestcaseFromTo("embed", "bidi-override"),
|
||||||
]),
|
]),
|
||||||
|
new TestcaseBundle(gPropList.vector_effect, [
|
||||||
|
new AnimTestcaseFromTo("none", "non-scaling-stroke"),
|
||||||
|
]),
|
||||||
new TestcaseBundle(gPropList.visibility, [
|
new TestcaseBundle(gPropList.visibility, [
|
||||||
new AnimTestcaseFromTo("visible", "hidden"),
|
new AnimTestcaseFromTo("visible", "hidden"),
|
||||||
new AnimTestcaseFromTo("hidden", "collapse"),
|
new AnimTestcaseFromTo("hidden", "collapse"),
|
||||||
|
@ -116,6 +116,7 @@ var gPropList =
|
|||||||
text_decoration: new NonAdditiveAttribute("text-decoration", "CSS", "text"),
|
text_decoration: new NonAdditiveAttribute("text-decoration", "CSS", "text"),
|
||||||
text_rendering: new NonAdditiveAttribute("text-rendering", "CSS", "text"),
|
text_rendering: new NonAdditiveAttribute("text-rendering", "CSS", "text"),
|
||||||
unicode_bidi: new NonAnimatableAttribute("unicode-bidi", "CSS", "text"),
|
unicode_bidi: new NonAnimatableAttribute("unicode-bidi", "CSS", "text"),
|
||||||
|
vector_effect: new NonAdditiveAttribute("vector-effect", "CSS", "rect"),
|
||||||
visibility: new NonAdditiveAttribute("visibility", "CSS", "rect"),
|
visibility: new NonAdditiveAttribute("visibility", "CSS", "rect"),
|
||||||
word_spacing: new AdditiveAttribute("word-spacing", "CSS", "text"),
|
word_spacing: new AdditiveAttribute("word-spacing", "CSS", "text"),
|
||||||
writing_mode:
|
writing_mode:
|
||||||
|
@ -931,6 +931,7 @@ nsSVGElement::sFillStrokeMap[] = {
|
|||||||
{ &nsGkAtoms::stroke_miterlimit },
|
{ &nsGkAtoms::stroke_miterlimit },
|
||||||
{ &nsGkAtoms::stroke_opacity },
|
{ &nsGkAtoms::stroke_opacity },
|
||||||
{ &nsGkAtoms::stroke_width },
|
{ &nsGkAtoms::stroke_width },
|
||||||
|
{ &nsGkAtoms::vector_effect },
|
||||||
{ nsnull }
|
{ nsnull }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ text { font: 20px monospace; }
|
|||||||
<g transform="scale(2)">
|
<g transform="scale(2)">
|
||||||
<rect id="rect3" x="25" y="80" width="50" height="50" fill="green"/>
|
<rect id="rect3" x="25" y="80" width="50" height="50" fill="green"/>
|
||||||
<rect id="rect3a" x="25" y="80" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
|
<rect id="rect3a" x="25" y="80" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
|
||||||
|
<rect id="rect3b" vector-effect="non-scaling-stroke" x="100" y="100" width="25" height="25" fill="orange" stroke-width="4" stroke="yellow"/>
|
||||||
</g>
|
</g>
|
||||||
<g transform="scale(2) rotate(45 175 75)">
|
<g transform="scale(2) rotate(45 175 75)">
|
||||||
<rect id="rect4" x="150" y="50" width="50" height="50" fill="yellow"/>
|
<rect id="rect4" x="150" y="50" width="50" height="50" fill="yellow"/>
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
@ -93,6 +93,7 @@ function runTest()
|
|||||||
var rect1aBounds = doc.getElementById("rect1a").getBoundingClientRect();
|
var rect1aBounds = doc.getElementById("rect1a").getBoundingClientRect();
|
||||||
var rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
|
var rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
|
||||||
var rect3aBounds = doc.getElementById("rect3a").getBoundingClientRect();
|
var rect3aBounds = doc.getElementById("rect3a").getBoundingClientRect();
|
||||||
|
var rect3bBounds = doc.getElementById("rect3b").getBoundingClientRect();
|
||||||
var rect4aBounds = doc.getElementById("rect4a").getBoundingClientRect();
|
var rect4aBounds = doc.getElementById("rect4a").getBoundingClientRect();
|
||||||
|
|
||||||
is(rect1aBounds.left, 48, "rect1a.getBoundingClientRect().left");
|
is(rect1aBounds.left, 48, "rect1a.getBoundingClientRect().left");
|
||||||
@ -111,6 +112,11 @@ function runTest()
|
|||||||
is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
|
is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
|
||||||
is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
|
is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
|
||||||
|
|
||||||
|
is(rect3bBounds.left, 198, "rect3b.getBoundingClientRect().left");
|
||||||
|
is(rect3bBounds.top, 198, "rect3b.getBoundingClientRect().top");
|
||||||
|
is(rect3bBounds.width, 54, "rect3b.getBoundingClientRect().width");
|
||||||
|
is(rect3bBounds.height, 54, "rect3b.getBoundingClientRect().height");
|
||||||
|
|
||||||
rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
|
rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
|
||||||
isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
|
isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
|
||||||
isWithAbsTolerance(rect4aBounds.top, rect.top, 0.1, "rect4a.getBoundingClientRect().top");
|
isWithAbsTolerance(rect4aBounds.top, rect.top, 0.1, "rect4a.getBoundingClientRect().top");
|
||||||
|
33
layout/reftests/svg/non-scaling-stroke-01-ref.svg
Normal file
33
layout/reftests/svg/non-scaling-stroke-01-ref.svg
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css" >
|
||||||
|
rect {
|
||||||
|
stroke-width: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad2" x1="180" y1="250" x2="280" y2="300" gradientUnits="userSpaceOnUse" gradientTransform="scale(0.25,1)">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(1,0.5), skewX(45)">
|
||||||
|
<rect x="0" y="0" width="10" height="10" fill="red"/>
|
||||||
|
<rect x="10" y="0" width="10" height="10" fill="green"/>
|
||||||
|
<rect x="0" y="10" width="10" height="10" fill="blue"/>
|
||||||
|
<rect x="10" y="10" width="10" height="10" fill="yellow"/>
|
||||||
|
</pattern>
|
||||||
|
<rect id="rect" width="100" height="50" fill="none"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect x="20" y="20" width="100" height="50" fill="none" stroke="url(#grad1)"/>
|
||||||
|
|
||||||
|
<rect x="20" y="100" width="100" height="50" fill="none" stroke="url(#grad2)" />
|
||||||
|
|
||||||
|
<use xlink:href="#rect" transform="translate(20, 180)" stroke="url(#pattern)"/>
|
||||||
|
|
||||||
|
<use xlink:href="#rect" x="20" y="260" stroke="green"/>
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
36
layout/reftests/svg/non-scaling-stroke-01.svg
Normal file
36
layout/reftests/svg/non-scaling-stroke-01.svg
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css" >
|
||||||
|
rect {
|
||||||
|
stroke-width: 15px;
|
||||||
|
vector-effect: non-scaling-stroke;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad2" x1="100" y1="150" x2="200" y2="200" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(4,0.5), skewX(45)">
|
||||||
|
<rect x="0" y="0" width="10" height="10" fill="red"/>
|
||||||
|
<rect x="10" y="0" width="10" height="10" fill="green"/>
|
||||||
|
<rect x="0" y="10" width="10" height="10" fill="blue"/>
|
||||||
|
<rect x="10" y="10" width="10" height="10" fill="yellow"/>
|
||||||
|
</pattern>
|
||||||
|
<rect id="rect" width="400" height="50" fill="none"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<g transform="translate(20,20)">
|
||||||
|
<rect width="400" height="50" fill="none" stroke="url(#grad1)" transform="scale(0.25,1)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<rect width="400" height="50" fill="none" stroke="url(#grad2)" transform="translate(20,100) scale(0.25,1)"/>
|
||||||
|
|
||||||
|
<use xlink:href="#rect" transform="translate(20, 180) scale(0.25,1)" stroke="url(#pattern)"/>
|
||||||
|
|
||||||
|
<use xlink:href="#rect" x="40" y="80" transform="translate(10, 180) scale(0.25,1)" stroke="green"/>
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
33
layout/reftests/svg/non-scaling-stroke-02-ref.svg
Normal file
33
layout/reftests/svg/non-scaling-stroke-02-ref.svg
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||||
|
<style type="text/css" >
|
||||||
|
rect {
|
||||||
|
stroke-width: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad2" x1="360" y1="500" x2="560" y2="600" gradientUnits="userSpaceOnUse" gradientTransform="scale(0.25,1)">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<pattern id="pattern" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse" patternTransform="scale(1,0.5), skewX(45)">
|
||||||
|
<rect x="0" y="0" width="20" height="20" fill="red"/>
|
||||||
|
<rect x="20" y="0" width="20" height="20" fill="green"/>
|
||||||
|
<rect x="0" y="20" width="20" height="20" fill="blue"/>
|
||||||
|
<rect x="20" y="20" width="20" height="20" fill="yellow"/>
|
||||||
|
</pattern>
|
||||||
|
<rect id="rect" width="200" height="100" fill="none"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect x="40" y="40" width="200" height="100" fill="none" stroke="url(#grad1)"/>
|
||||||
|
|
||||||
|
<rect x="40" y="200" width="200" height="100" fill="none" stroke="url(#grad2)" />
|
||||||
|
|
||||||
|
<use xlink:href="#rect" transform="translate(40, 360)" stroke="url(#pattern)"/>
|
||||||
|
|
||||||
|
<use xlink:href="#rect" x="40" y="520" stroke="green"/>
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
36
layout/reftests/svg/non-scaling-stroke-02.svg
Normal file
36
layout/reftests/svg/non-scaling-stroke-02.svg
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" reftest-zoom="2" overflow="hidden">
|
||||||
|
<style type="text/css" >
|
||||||
|
rect {
|
||||||
|
stroke-width: 15px;
|
||||||
|
vector-effect: non-scaling-stroke;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="grad2" x1="100" y1="150" x2="200" y2="200" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="blue"/>
|
||||||
|
<stop offset="1" stop-color="yellow"/>
|
||||||
|
</linearGradient>
|
||||||
|
<pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" patternTransform="scale(4,0.5), skewX(45)">
|
||||||
|
<rect x="0" y="0" width="10" height="10" fill="red"/>
|
||||||
|
<rect x="10" y="0" width="10" height="10" fill="green"/>
|
||||||
|
<rect x="0" y="10" width="10" height="10" fill="blue"/>
|
||||||
|
<rect x="10" y="10" width="10" height="10" fill="yellow"/>
|
||||||
|
</pattern>
|
||||||
|
<rect id="rect" width="400" height="50" fill="none"/>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<g transform="translate(20,20)">
|
||||||
|
<rect width="400" height="50" fill="none" stroke="url(#grad1)" transform="scale(0.25,1)"/>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<rect width="400" height="50" fill="none" stroke="url(#grad2)" transform="translate(20,100) scale(0.25,1)"/>
|
||||||
|
|
||||||
|
<use xlink:href="#rect" transform="translate(20, 180) scale(0.25,1)" stroke="url(#pattern)"/>
|
||||||
|
|
||||||
|
<use xlink:href="#rect" x="40" y="80" transform="translate(10, 180) scale(0.25,1)" stroke="green"/>
|
||||||
|
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -174,6 +174,8 @@ fails == inline-in-xul-basic-01.xul pass.svg
|
|||||||
== mask-transformed-01.svg mask-transformed-01-ref.svg
|
== mask-transformed-01.svg mask-transformed-01-ref.svg
|
||||||
== nested-viewBox-01.svg pass.svg
|
== nested-viewBox-01.svg pass.svg
|
||||||
== nesting-invalid-01.svg nesting-invalid-01-ref.svg
|
== nesting-invalid-01.svg nesting-invalid-01-ref.svg
|
||||||
|
== non-scaling-stroke-01.svg non-scaling-stroke-01-ref.svg
|
||||||
|
== non-scaling-stroke-02.svg non-scaling-stroke-02-ref.svg
|
||||||
== objectBoundingBox-and-clipPath.svg pass.svg
|
== objectBoundingBox-and-clipPath.svg pass.svg
|
||||||
# Bug 588684
|
# Bug 588684
|
||||||
random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-01.svg objectBoundingBox-and-fePointLight-01-ref.svg
|
random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-01.svg objectBoundingBox-and-fePointLight-01-ref.svg
|
||||||
|
@ -200,7 +200,7 @@ nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext)
|
|||||||
|
|
||||||
nsSVGPaintServerFrame *ps =
|
nsSVGPaintServerFrame *ps =
|
||||||
GetPaintServer(&style->mFill, nsSVGEffects::FillProperty());
|
GetPaintServer(&style->mFill, nsSVGEffects::FillProperty());
|
||||||
if (ps && ps->SetupPaintServer(aContext, this, opacity))
|
if (ps && ps->SetupPaintServer(aContext, this, &nsStyleSVG::mFill, opacity))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// On failure, use the fallback colour in case we have an
|
// On failure, use the fallback colour in case we have an
|
||||||
@ -229,6 +229,9 @@ nsSVGGeometryFrame::SetupCairoStrokeGeometry(gfxContext *aContext)
|
|||||||
return;
|
return;
|
||||||
aContext->SetLineWidth(width);
|
aContext->SetLineWidth(width);
|
||||||
|
|
||||||
|
// Apply any stroke-specific transform
|
||||||
|
aContext->Multiply(nsSVGUtils::GetStrokeTransform(this));
|
||||||
|
|
||||||
const nsStyleSVG* style = GetStyleSVG();
|
const nsStyleSVG* style = GetStyleSVG();
|
||||||
|
|
||||||
switch (style->mStrokeLinecap) {
|
switch (style->mStrokeLinecap) {
|
||||||
@ -283,7 +286,7 @@ nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext)
|
|||||||
|
|
||||||
nsSVGPaintServerFrame *ps =
|
nsSVGPaintServerFrame *ps =
|
||||||
GetPaintServer(&style->mStroke, nsSVGEffects::StrokeProperty());
|
GetPaintServer(&style->mStroke, nsSVGEffects::StrokeProperty());
|
||||||
if (ps && ps->SetupPaintServer(aContext, this, opacity))
|
if (ps && ps->SetupPaintServer(aContext, this, &nsStyleSVG::mStroke, opacity))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// On failure, use the fallback colour in case we have an
|
// On failure, use the fallback colour in case we have an
|
||||||
|
@ -909,7 +909,7 @@ nsSVGGlyphFrame::SetupCairoState(gfxContext *aContext, gfxPattern **aStrokePatte
|
|||||||
|
|
||||||
if (ps) {
|
if (ps) {
|
||||||
// Gradient or Pattern: can get pattern directly from frame
|
// Gradient or Pattern: can get pattern directly from frame
|
||||||
strokePattern = ps->GetPaintServerPattern(this, opacity);
|
strokePattern = ps->GetPaintServerPattern(this, &nsStyleSVG::mStroke, opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strokePattern) {
|
if (!strokePattern) {
|
||||||
|
@ -272,8 +272,9 @@ nsSVGGradientFrame::GetRadialGradientWithLength(PRUint32 aIndex,
|
|||||||
|
|
||||||
already_AddRefed<gfxPattern>
|
already_AddRefed<gfxPattern>
|
||||||
nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
|
nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||||
float aGraphicOpacity,
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
const gfxRect *aOverrideBounds)
|
float aGraphicOpacity,
|
||||||
|
const gfxRect *aOverrideBounds)
|
||||||
{
|
{
|
||||||
// Get the transform list (if there is one)
|
// Get the transform list (if there is one)
|
||||||
gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
|
gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
|
||||||
@ -290,6 +291,11 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
|
|||||||
return pattern.forget();
|
return pattern.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// revert the vector effect transform so that the gradient appears unchanged
|
||||||
|
if (aFillOrStroke == &nsStyleSVG::mStroke) {
|
||||||
|
patternMatrix.Multiply(nsSVGUtils::GetStrokeTransform(aSource).Invert());
|
||||||
|
}
|
||||||
|
|
||||||
patternMatrix.Invert();
|
patternMatrix.Invert();
|
||||||
|
|
||||||
nsRefPtr<gfxPattern> gradient = CreateGradient();
|
nsRefPtr<gfxPattern> gradient = CreateGradient();
|
||||||
|
@ -77,6 +77,7 @@ public:
|
|||||||
// nsSVGPaintServerFrame methods:
|
// nsSVGPaintServerFrame methods:
|
||||||
virtual already_AddRefed<gfxPattern>
|
virtual already_AddRefed<gfxPattern>
|
||||||
GetPaintServerPattern(nsIFrame *aSource,
|
GetPaintServerPattern(nsIFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aGraphicOpacity,
|
float aGraphicOpacity,
|
||||||
const gfxRect *aOverrideBounds);
|
const gfxRect *aOverrideBounds);
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ DrawableFromPaintServer(nsIFrame* aFrame,
|
|||||||
aPaintServerSize.width, aPaintServerSize.height);
|
aPaintServerSize.width, aPaintServerSize.height);
|
||||||
overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
|
overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
nsRefPtr<gfxPattern> pattern =
|
nsRefPtr<gfxPattern> pattern =
|
||||||
server->GetPaintServerPattern(aTarget, 1.0, &overrideBounds);
|
server->GetPaintServerPattern(aTarget, &nsStyleSVG::mFill, 1.0, &overrideBounds);
|
||||||
|
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "nsSVGPaintServerFrame.h"
|
#include "nsSVGPaintServerFrame.h"
|
||||||
|
|
||||||
// Keep others in (case-insensitive) order:
|
// Keep others in (case-insensitive) order:
|
||||||
|
#include "nsSVGElement.h"
|
||||||
#include "nsSVGGeometryFrame.h"
|
#include "nsSVGGeometryFrame.h"
|
||||||
|
|
||||||
NS_IMPL_FRAMEARENA_HELPERS(nsSVGPaintServerFrame)
|
NS_IMPL_FRAMEARENA_HELPERS(nsSVGPaintServerFrame)
|
||||||
@ -45,9 +46,10 @@ NS_IMPL_FRAMEARENA_HELPERS(nsSVGPaintServerFrame)
|
|||||||
bool
|
bool
|
||||||
nsSVGPaintServerFrame::SetupPaintServer(gfxContext *aContext,
|
nsSVGPaintServerFrame::SetupPaintServer(gfxContext *aContext,
|
||||||
nsSVGGeometryFrame *aSource,
|
nsSVGGeometryFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aOpacity)
|
float aOpacity)
|
||||||
{
|
{
|
||||||
nsRefPtr<gfxPattern> pattern = GetPaintServerPattern(aSource, aOpacity);
|
nsRefPtr<gfxPattern> pattern = GetPaintServerPattern(aSource, aFillOrStroke, aOpacity);
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual already_AddRefed<gfxPattern>
|
virtual already_AddRefed<gfxPattern>
|
||||||
GetPaintServerPattern(nsIFrame *aSource,
|
GetPaintServerPattern(nsIFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
const gfxRect *aOverrideBounds = nsnull) = 0;
|
const gfxRect *aOverrideBounds = nsnull) = 0;
|
||||||
|
|
||||||
@ -78,8 +79,9 @@ public:
|
|||||||
* @return false to skip rendering
|
* @return false to skip rendering
|
||||||
*/
|
*/
|
||||||
virtual bool SetupPaintServer(gfxContext *aContext,
|
virtual bool SetupPaintServer(gfxContext *aContext,
|
||||||
nsSVGGeometryFrame *aSource,
|
nsSVGGeometryFrame *aSource,
|
||||||
float aOpacity);
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
|
float aOpacity);
|
||||||
|
|
||||||
virtual bool IsFrameOfType(PRUint32 aFlags) const
|
virtual bool IsFrameOfType(PRUint32 aFlags) const
|
||||||
{
|
{
|
||||||
|
@ -178,6 +178,7 @@ nsresult
|
|||||||
nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
||||||
gfxMatrix* patternMatrix,
|
gfxMatrix* patternMatrix,
|
||||||
nsIFrame *aSource,
|
nsIFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aGraphicOpacity,
|
float aGraphicOpacity,
|
||||||
const gfxRect *aOverrideBounds)
|
const gfxRect *aOverrideBounds)
|
||||||
{
|
{
|
||||||
@ -252,6 +253,11 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
|||||||
// Get the pattern transform
|
// Get the pattern transform
|
||||||
gfxMatrix patternTransform = GetPatternTransform();
|
gfxMatrix patternTransform = GetPatternTransform();
|
||||||
|
|
||||||
|
// revert the vector effect transform so that the pattern appears unchanged
|
||||||
|
if (aFillOrStroke == &nsStyleSVG::mStroke) {
|
||||||
|
patternTransform.Multiply(nsSVGUtils::GetStrokeTransform(aSource).Invert());
|
||||||
|
}
|
||||||
|
|
||||||
// Get the transformation matrix that we will hand to the renderer's pattern
|
// Get the transformation matrix that we will hand to the renderer's pattern
|
||||||
// routine.
|
// routine.
|
||||||
*patternMatrix = GetPatternMatrix(patternTransform,
|
*patternMatrix = GetPatternMatrix(patternTransform,
|
||||||
@ -683,6 +689,7 @@ nsSVGPatternFrame::GetTargetGeometry(gfxMatrix *aCTM,
|
|||||||
|
|
||||||
already_AddRefed<gfxPattern>
|
already_AddRefed<gfxPattern>
|
||||||
nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
|
nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aGraphicOpacity,
|
float aGraphicOpacity,
|
||||||
const gfxRect *aOverrideBounds)
|
const gfxRect *aOverrideBounds)
|
||||||
{
|
{
|
||||||
@ -695,7 +702,7 @@ nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
|
|||||||
nsRefPtr<gfxASurface> surface;
|
nsRefPtr<gfxASurface> surface;
|
||||||
gfxMatrix pMatrix;
|
gfxMatrix pMatrix;
|
||||||
nsresult rv = PaintPattern(getter_AddRefs(surface), &pMatrix,
|
nsresult rv = PaintPattern(getter_AddRefs(surface), &pMatrix,
|
||||||
aSource, aGraphicOpacity, aOverrideBounds);
|
aSource, aFillOrStroke, aGraphicOpacity, aOverrideBounds);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
@ -73,6 +73,7 @@ public:
|
|||||||
// nsSVGPaintServerFrame methods:
|
// nsSVGPaintServerFrame methods:
|
||||||
virtual already_AddRefed<gfxPattern>
|
virtual already_AddRefed<gfxPattern>
|
||||||
GetPaintServerPattern(nsIFrame *aSource,
|
GetPaintServerPattern(nsIFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
const gfxRect *aOverrideBounds);
|
const gfxRect *aOverrideBounds);
|
||||||
|
|
||||||
@ -141,6 +142,7 @@ protected:
|
|||||||
nsresult PaintPattern(gfxASurface **surface,
|
nsresult PaintPattern(gfxASurface **surface,
|
||||||
gfxMatrix *patternMatrix,
|
gfxMatrix *patternMatrix,
|
||||||
nsIFrame *aSource,
|
nsIFrame *aSource,
|
||||||
|
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||||
float aGraphicOpacity,
|
float aGraphicOpacity,
|
||||||
const gfxRect *aOverrideBounds);
|
const gfxRect *aOverrideBounds);
|
||||||
nsIFrame* GetPatternFirstChild();
|
nsIFrame* GetPatternFirstChild();
|
||||||
|
@ -1709,6 +1709,32 @@ nsSVGUtils::WritePPM(const char *fname, gfxImageSurface *aSurface)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
gfxMatrix
|
||||||
|
nsSVGUtils::GetStrokeTransform(nsIFrame *aFrame)
|
||||||
|
{
|
||||||
|
if (aFrame->GetStyleSVGReset()->mVectorEffect ==
|
||||||
|
NS_STYLE_VECTOR_EFFECT_NON_SCALING_STROKE) {
|
||||||
|
|
||||||
|
if (aFrame->GetContent()->IsNodeOfType(nsINode::eTEXT)) {
|
||||||
|
aFrame = aFrame->GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIContent *content = aFrame->GetContent();
|
||||||
|
NS_ABORT_IF_FALSE(content->IsSVG(), "bad cast");
|
||||||
|
|
||||||
|
// a non-scaling stroke is in the screen co-ordinate
|
||||||
|
// space rather so we need to invert the transform
|
||||||
|
// to the screen co-ordinate space to get there.
|
||||||
|
// See http://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke
|
||||||
|
gfxMatrix transform = nsSVGUtils::GetCTM(
|
||||||
|
static_cast<nsSVGElement*>(content), true);
|
||||||
|
if (!transform.IsSingular()) {
|
||||||
|
return transform.Invert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gfxMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
// The logic here comes from _cairo_stroke_style_max_distance_from_path
|
// The logic here comes from _cairo_stroke_style_max_distance_from_path
|
||||||
static gfxRect
|
static gfxRect
|
||||||
PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
||||||
@ -1719,8 +1745,11 @@ PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
|||||||
double style_expansion =
|
double style_expansion =
|
||||||
styleExpansionFactor * aFrame->GetStrokeWidth();
|
styleExpansionFactor * aFrame->GetStrokeWidth();
|
||||||
|
|
||||||
double dx = style_expansion * (fabs(aMatrix.xx) + fabs(aMatrix.xy));
|
gfxMatrix matrix = aMatrix;
|
||||||
double dy = style_expansion * (fabs(aMatrix.yy) + fabs(aMatrix.yx));
|
matrix.Multiply(nsSVGUtils::GetStrokeTransform(aFrame));
|
||||||
|
|
||||||
|
double dx = style_expansion * (fabs(matrix.xx) + fabs(matrix.xy));
|
||||||
|
double dy = style_expansion * (fabs(matrix.yy) + fabs(matrix.yx));
|
||||||
|
|
||||||
gfxRect strokeExtents = aPathExtents;
|
gfxRect strokeExtents = aPathExtents;
|
||||||
strokeExtents.Inflate(dx, dy);
|
strokeExtents.Inflate(dx, dy);
|
||||||
|
@ -631,6 +631,12 @@ public:
|
|||||||
static bool OuterSVGIsCallingUpdateBounds(nsIFrame *aFrame);
|
static bool OuterSVGIsCallingUpdateBounds(nsIFrame *aFrame);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get any additional transforms that apply only to stroking
|
||||||
|
* e.g. non-scaling-stroke
|
||||||
|
*/
|
||||||
|
static gfxMatrix GetStrokeTransform(nsIFrame *aFrame);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the maximum possible device space stroke extents of a path given
|
* Compute the maximum possible device space stroke extents of a path given
|
||||||
* the path's device space path extents, its stroke style and its ctm.
|
* the path's device space path extents, its stroke style and its ctm.
|
||||||
|
Loading…
Reference in New Issue
Block a user