patternContentUnits="objectBoundingBox" problems

Good evening SVG crowd,

I ran into a problem, when revisiting our pattern support in WebKit.

Consider following two simple testcases.
patternContentUnits-problem-1.svg:
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
    <pattern id="pattern" patternUnits="userSpaceOnUse"  
patternContentUnits="objectBoundingBox" x="0" y="0" width="100"  
height="100">
        <circle cx="0.5" cy="0.5" r="0.4" fill="green" stroke="red"  
stroke-width="0.01"/>
    </pattern>
</defs>
<rect x="50" y="0" width="190" height="190" fill="url(#pattern)"  
stroke="yellow"/>
</svg>

patternContentUnits-problem-2.svg:
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
    <pattern id="pattern" patternUnits="userSpaceOnUse"  
patternContentUnits="objectBoundingBox" x="0" y="0" width="100"  
height="100">
        <circle cx="0.5" cy="0.5" r="0.4" fill="green" stroke="red"  
stroke-width="0.01"/>
    </pattern>
</defs>
<rect x="0" y="0" width="190" height="190" fill="url(#pattern)"  
stroke="yellow"/>
</svg>

The only difference is the position of the rect that references the  
pattern.

Comparision between:
WebKit (trunk, with some local patches) | Opera 10.61 | Firefox trunk  
| Batik 1.7





I think the problem boils down to the interpretation of  
patternContentUnits="objectBoundingBox". First some background, before  
I ask the actual question:

Let 'objectBoundingBox' be the boundaries rectangle of the element  
that references the pattern.
Let 'patternBoundaries' be the boundaries rectangle of the pattern  
defined by x/y/width/height/patternUnits attributes.

To calculate the pattern boundaries I'm doing: (see http://www.w3.org/TR/SVG11/pservers.html#Patterns 
, 'patternUnits' paragraph)
- patternUnits="userSpaceOnUse"
patternBoundaries = (pattern.x, pattern.y, pattern.width,  
pattern.height)

- patternUnits="objectBoundingBox"
patternBoundaries = (pattern.x * objectBoundingBox.width +  
objectBoundingBox.x, pattern.y * objectBoundingBox.height +  
objectBoundingBox.y, pattern.width * objectBoundingBox.width,  
pattern.height * objectBoundingBox.height)

I think all browsers behave the same here.
WebKit creates the tile image based on the patternBoundaries size, and  
then renders the pattern content into that tile image (let's ignore  
scaling, viewBox, etc. for now)

When encountering patternContentUnits="userSpaceOnUse", no additional  
transform is supplied before rendering the pattern subtree into the  
tile image.
When patternContentUnits="objectBoundingBox" is used I'm translating  
(***) the tile image context by (objectBoundingBox.x,  
objectBoundingBox.y) and then scale by (objectBoundingBox.width,  
objectBoundingBox.height).
(My interpretation of http://www.w3.org/TR/SVG11/ 
pservers.html#Patterns, 'patternContentUnits' paragraph)

That produces the rendering that you can see above.
The rectangle in the first row has objectBoundingBox = (50, 0, 190, 190)
The rectangle in the second row has objectBoundingBox = (0, 0, 190, 190)

We all agree on the rendering of the second testcase, but the first  
row is problematic. When I'm changing the x/y position of the <rect>  
and thus it's objectBoundingBox, the interpretation of what to render  
differs.

<quote>
http://www.w3.org/TR/SVG11/pservers.html#Patterns,  
'patternContentUnits' paragraph says:
If patternContentUnits="objectBoundingBox",  the user coordinate  
system for the contents of the ‘pattern’ element is established using  
the bounding box of the element to which the pattern is applied (see  
Object bounding box units) and then applying the transform specified  
by attribute ‘patternTransform’.
</quote>

<quote>
http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox, says:
Then,  coordinate (0,0) in the new user coordinate system is mapped to  
the (minx,miny) corner of the tight bounding box within the user  
coordinate system of the applicable element and coordinate (1,1) in  
the new user coordinate system is mapped to the (maxx,maxy) corner of  
the tight bounding box of the applicable element.
</quote>

The paragraph above is the reason why I think the tile image context  
needs to be translated and scaled according to the objectBoundingBox  
of the target element, in patternContentUnits="objectBoundingBox" mode.

I can reproduce Operas rendering, when I'm leaving out the translation  
(***) and only scale.
Which one is correct? Batik seems to handle it as WebKit is doing it,  
but Firefox and Opera disagree.

Thanks in advance for taking time to answer!
Cheers,
Niko

P.S. Looking forward to meet you all in Paris!

Received on Thursday, 19 August 2010 11:22:56 UTC