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",
|
||||
"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",
|
||||
"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",
|
||||
"widows", "width", "word-break", "word-spacing", "word-wrap", "z-index"
|
||||
];
|
||||
|
@ -1378,6 +1378,7 @@ GK_ATOM(y2, "y2")
|
||||
GK_ATOM(yChannelSelector, "yChannelSelector")
|
||||
GK_ATOM(z, "z")
|
||||
GK_ATOM(zoomAndPan, "zoomAndPan")
|
||||
GK_ATOM(vector_effect, "vector-effect")
|
||||
|
||||
GK_ATOM(accumulate, "accumulate")
|
||||
GK_ATOM(additive, "additive")
|
||||
|
@ -628,6 +628,7 @@ nsIAtom** const kAttributesSVG[] = {
|
||||
// v-ideographic
|
||||
// v-mathematical
|
||||
&nsGkAtoms::values, // values
|
||||
&nsGkAtoms::vector_effect, // vector-effect
|
||||
// vert-adv-y
|
||||
// vert-origin-x
|
||||
// vert-origin-y
|
||||
|
@ -281,6 +281,7 @@ nsSMILCSSProperty::IsPropertyAnimatable(nsCSSProperty aPropID)
|
||||
case eCSSProperty_text_decoration:
|
||||
case eCSSProperty_text_decoration_line:
|
||||
case eCSSProperty_text_rendering:
|
||||
case eCSSProperty_vector_effect:
|
||||
case eCSSProperty_visibility:
|
||||
case eCSSProperty_word_spacing:
|
||||
return true;
|
||||
|
@ -463,6 +463,9 @@ var gFromToBundles = [
|
||||
new TestcaseBundle(gPropList.unicode_bidi, [
|
||||
new AnimTestcaseFromTo("embed", "bidi-override"),
|
||||
]),
|
||||
new TestcaseBundle(gPropList.vector_effect, [
|
||||
new AnimTestcaseFromTo("none", "non-scaling-stroke"),
|
||||
]),
|
||||
new TestcaseBundle(gPropList.visibility, [
|
||||
new AnimTestcaseFromTo("visible", "hidden"),
|
||||
new AnimTestcaseFromTo("hidden", "collapse"),
|
||||
|
@ -116,6 +116,7 @@ var gPropList =
|
||||
text_decoration: new NonAdditiveAttribute("text-decoration", "CSS", "text"),
|
||||
text_rendering: new NonAdditiveAttribute("text-rendering", "CSS", "text"),
|
||||
unicode_bidi: new NonAnimatableAttribute("unicode-bidi", "CSS", "text"),
|
||||
vector_effect: new NonAdditiveAttribute("vector-effect", "CSS", "rect"),
|
||||
visibility: new NonAdditiveAttribute("visibility", "CSS", "rect"),
|
||||
word_spacing: new AdditiveAttribute("word-spacing", "CSS", "text"),
|
||||
writing_mode:
|
||||
|
@ -931,6 +931,7 @@ nsSVGElement::sFillStrokeMap[] = {
|
||||
{ &nsGkAtoms::stroke_miterlimit },
|
||||
{ &nsGkAtoms::stroke_opacity },
|
||||
{ &nsGkAtoms::stroke_width },
|
||||
{ &nsGkAtoms::vector_effect },
|
||||
{ nsnull }
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@ text { font: 20px monospace; }
|
||||
<g transform="scale(2)">
|
||||
<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="rect3b" vector-effect="non-scaling-stroke" x="100" y="100" width="25" height="25" fill="orange" stroke-width="4" stroke="yellow"/>
|
||||
</g>
|
||||
<g transform="scale(2) rotate(45 175 75)">
|
||||
<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 rect2aBounds = doc.getElementById("rect2a").getBoundingClientRect();
|
||||
var rect3aBounds = doc.getElementById("rect3a").getBoundingClientRect();
|
||||
var rect3bBounds = doc.getElementById("rect3b").getBoundingClientRect();
|
||||
var rect4aBounds = doc.getElementById("rect4a").getBoundingClientRect();
|
||||
|
||||
is(rect1aBounds.left, 48, "rect1a.getBoundingClientRect().left");
|
||||
@ -111,6 +112,11 @@ function runTest()
|
||||
is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
|
||||
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);
|
||||
isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");
|
||||
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
|
||||
== nested-viewBox-01.svg pass.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
|
||||
# Bug 588684
|
||||
random-if(gtk2Widget) == objectBoundingBox-and-fePointLight-01.svg objectBoundingBox-and-fePointLight-01-ref.svg
|
||||
|
@ -200,7 +200,7 @@ nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext)
|
||||
|
||||
nsSVGPaintServerFrame *ps =
|
||||
GetPaintServer(&style->mFill, nsSVGEffects::FillProperty());
|
||||
if (ps && ps->SetupPaintServer(aContext, this, opacity))
|
||||
if (ps && ps->SetupPaintServer(aContext, this, &nsStyleSVG::mFill, opacity))
|
||||
return true;
|
||||
|
||||
// On failure, use the fallback colour in case we have an
|
||||
@ -229,6 +229,9 @@ nsSVGGeometryFrame::SetupCairoStrokeGeometry(gfxContext *aContext)
|
||||
return;
|
||||
aContext->SetLineWidth(width);
|
||||
|
||||
// Apply any stroke-specific transform
|
||||
aContext->Multiply(nsSVGUtils::GetStrokeTransform(this));
|
||||
|
||||
const nsStyleSVG* style = GetStyleSVG();
|
||||
|
||||
switch (style->mStrokeLinecap) {
|
||||
@ -283,7 +286,7 @@ nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext)
|
||||
|
||||
nsSVGPaintServerFrame *ps =
|
||||
GetPaintServer(&style->mStroke, nsSVGEffects::StrokeProperty());
|
||||
if (ps && ps->SetupPaintServer(aContext, this, opacity))
|
||||
if (ps && ps->SetupPaintServer(aContext, this, &nsStyleSVG::mStroke, opacity))
|
||||
return true;
|
||||
|
||||
// On failure, use the fallback colour in case we have an
|
||||
|
@ -909,7 +909,7 @@ nsSVGGlyphFrame::SetupCairoState(gfxContext *aContext, gfxPattern **aStrokePatte
|
||||
|
||||
if (ps) {
|
||||
// Gradient or Pattern: can get pattern directly from frame
|
||||
strokePattern = ps->GetPaintServerPattern(this, opacity);
|
||||
strokePattern = ps->GetPaintServerPattern(this, &nsStyleSVG::mStroke, opacity);
|
||||
}
|
||||
|
||||
if (!strokePattern) {
|
||||
|
@ -272,8 +272,9 @@ nsSVGGradientFrame::GetRadialGradientWithLength(PRUint32 aIndex,
|
||||
|
||||
already_AddRefed<gfxPattern>
|
||||
nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||
float aGraphicOpacity,
|
||||
const gfxRect *aOverrideBounds)
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aGraphicOpacity,
|
||||
const gfxRect *aOverrideBounds)
|
||||
{
|
||||
// Get the transform list (if there is one)
|
||||
gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
|
||||
@ -290,6 +291,11 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||
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();
|
||||
|
||||
nsRefPtr<gfxPattern> gradient = CreateGradient();
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
// nsSVGPaintServerFrame methods:
|
||||
virtual already_AddRefed<gfxPattern>
|
||||
GetPaintServerPattern(nsIFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aGraphicOpacity,
|
||||
const gfxRect *aOverrideBounds);
|
||||
|
||||
|
@ -513,7 +513,7 @@ DrawableFromPaintServer(nsIFrame* aFrame,
|
||||
aPaintServerSize.width, aPaintServerSize.height);
|
||||
overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
nsRefPtr<gfxPattern> pattern =
|
||||
server->GetPaintServerPattern(aTarget, 1.0, &overrideBounds);
|
||||
server->GetPaintServerPattern(aTarget, &nsStyleSVG::mFill, 1.0, &overrideBounds);
|
||||
|
||||
if (!pattern)
|
||||
return nsnull;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsSVGPaintServerFrame.h"
|
||||
|
||||
// Keep others in (case-insensitive) order:
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsSVGPaintServerFrame)
|
||||
@ -45,9 +46,10 @@ NS_IMPL_FRAMEARENA_HELPERS(nsSVGPaintServerFrame)
|
||||
bool
|
||||
nsSVGPaintServerFrame::SetupPaintServer(gfxContext *aContext,
|
||||
nsSVGGeometryFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aOpacity)
|
||||
{
|
||||
nsRefPtr<gfxPattern> pattern = GetPaintServerPattern(aSource, aOpacity);
|
||||
nsRefPtr<gfxPattern> pattern = GetPaintServerPattern(aSource, aFillOrStroke, aOpacity);
|
||||
if (!pattern)
|
||||
return false;
|
||||
|
||||
|
@ -70,6 +70,7 @@ public:
|
||||
*/
|
||||
virtual already_AddRefed<gfxPattern>
|
||||
GetPaintServerPattern(nsIFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aOpacity,
|
||||
const gfxRect *aOverrideBounds = nsnull) = 0;
|
||||
|
||||
@ -78,8 +79,9 @@ public:
|
||||
* @return false to skip rendering
|
||||
*/
|
||||
virtual bool SetupPaintServer(gfxContext *aContext,
|
||||
nsSVGGeometryFrame *aSource,
|
||||
float aOpacity);
|
||||
nsSVGGeometryFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aOpacity);
|
||||
|
||||
virtual bool IsFrameOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
@ -178,6 +178,7 @@ nsresult
|
||||
nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
||||
gfxMatrix* patternMatrix,
|
||||
nsIFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aGraphicOpacity,
|
||||
const gfxRect *aOverrideBounds)
|
||||
{
|
||||
@ -252,6 +253,11 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface,
|
||||
// Get the pattern transform
|
||||
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
|
||||
// routine.
|
||||
*patternMatrix = GetPatternMatrix(patternTransform,
|
||||
@ -683,6 +689,7 @@ nsSVGPatternFrame::GetTargetGeometry(gfxMatrix *aCTM,
|
||||
|
||||
already_AddRefed<gfxPattern>
|
||||
nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aGraphicOpacity,
|
||||
const gfxRect *aOverrideBounds)
|
||||
{
|
||||
@ -695,7 +702,7 @@ nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
gfxMatrix pMatrix;
|
||||
nsresult rv = PaintPattern(getter_AddRefs(surface), &pMatrix,
|
||||
aSource, aGraphicOpacity, aOverrideBounds);
|
||||
aSource, aFillOrStroke, aGraphicOpacity, aOverrideBounds);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return nsnull;
|
||||
|
@ -73,6 +73,7 @@ public:
|
||||
// nsSVGPaintServerFrame methods:
|
||||
virtual already_AddRefed<gfxPattern>
|
||||
GetPaintServerPattern(nsIFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aOpacity,
|
||||
const gfxRect *aOverrideBounds);
|
||||
|
||||
@ -141,6 +142,7 @@ protected:
|
||||
nsresult PaintPattern(gfxASurface **surface,
|
||||
gfxMatrix *patternMatrix,
|
||||
nsIFrame *aSource,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aGraphicOpacity,
|
||||
const gfxRect *aOverrideBounds);
|
||||
nsIFrame* GetPatternFirstChild();
|
||||
|
@ -1709,6 +1709,32 @@ nsSVGUtils::WritePPM(const char *fname, gfxImageSurface *aSurface)
|
||||
}
|
||||
#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
|
||||
static gfxRect
|
||||
PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
||||
@ -1719,8 +1745,11 @@ PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
||||
double style_expansion =
|
||||
styleExpansionFactor * aFrame->GetStrokeWidth();
|
||||
|
||||
double dx = style_expansion * (fabs(aMatrix.xx) + fabs(aMatrix.xy));
|
||||
double dy = style_expansion * (fabs(aMatrix.yy) + fabs(aMatrix.yx));
|
||||
gfxMatrix matrix = aMatrix;
|
||||
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;
|
||||
strokeExtents.Inflate(dx, dy);
|
||||
|
@ -631,6 +631,12 @@ public:
|
||||
static bool OuterSVGIsCallingUpdateBounds(nsIFrame *aFrame);
|
||||
#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
|
||||
* the path's device space path extents, its stroke style and its ctm.
|
||||
|
Loading…
Reference in New Issue
Block a user