Bug 103725

Summary: getBBox() return wrong bounding box in <use> tag
Product: WebKit Reporter: skybach
Component: SVGAssignee: Nobody <webkit-unassigned>
Status: RESOLVED WONTFIX    
Severity: Major CC: krit, pdr, webkit, zimmermann
Priority: P2    
Version: 420+   
Hardware: All   
OS: All   

Description skybach 2012-11-30 02:21:14 PST
getBBox() return wrong bounding box in <use> tag
Comment 1 Philip Rogers 2012-11-30 11:52:29 PST
Hi skybach, thank you for taking the time to file this bug. I'm not able to reproduce this. Can you provide an example and list what browser version you are using?

The following works for me:
<html>
<body>
<svg width="500" height="500">
  <rect id="rect" x="100" y="100" width="100" height="100" opacity="0.5" fill="green"/>
  <use id="use" xlink:href="#rect" x="50" y="50" />
</svg>
<script>
  var use = document.getElementById('use');
  var bbox = use.getBBox();
  console.log(bbox); // prints SVGRect {height: 100, width: 100, y: 100, x: 100}
</script>
</body>
</html>

For now I'm marking this as WORKSFORME but we can reopen if necessary.
Comment 2 skybach 2012-12-02 17:38:40 PST
Shouldn't it print 
{height: 100, width: 100, y: 50, x: 50}
instead?

Since we are getting the bbox on <use>.
It can also link to an external file, which from a usage point of view, is a encapsulated container?
I also notice that <use> width and height attribute does not force a resize on the child content.
Am I using <use> wrongly?
Comment 3 Philip Rogers 2012-12-03 16:27:48 PST
(In reply to comment #2)
> Shouldn't it print 
> {height: 100, width: 100, y: 50, x: 50}
> instead?
> 
> Since we are getting the bbox on <use>.
> It can also link to an external file, which from a usage point of view, is a encapsulated container?
> I also notice that <use> width and height attribute does not force a resize on the child content.
> Am I using <use> wrongly?

Re-opening because there seems to be some confusion about this.

For the record, here's how the major browsers are currently working:
Chrome Canary - {height: 100, width: 100, y: 100, x: 100}
Firefox Nightly - {height: 100, width: 100, y: 100, x: 100}
IE10 - {height: 100, width: 100, y: 100, x: 100}
Opera next: {height: 100, width: 100, y: 150, x: 150}

It looks like Cr/FF/IE are returning the bbox of the referenced element whereas Opera is returning the bbox of the the rendered content. I think Opera might be the most intuitive. I do not think {height: 100, width: 100, y: 50, x: 50} makes sense.

In particular, we (Chrome, IE) seem inconsistent in the multiple-use case:
<html>
<body>
<svg width="500" height="500">
  <rect id="rect" x="0" y="0" width="100" height="100" opacity="0.5" fill="green"/>
  <use id="use" xlink:href="#rect" x="50" y="50" />
  <use id="use2" xlink:href="#use" x="200" y="200" />
</svg>
<script>
  console.log(document.getElementById('rect').getBBox());
  console.log(document.getElementById('use').getBBox());
  console.log(document.getElementById('use2').getBBox());
</script>
</body>
</html>

@Dirk, should we be adding the x,y offset from the <use> attributes in returning the bbox?
Relevant spec: http://www.w3.org/TR/SVG/single-page.html#types-__svg__SVGLocatable__getBBox
Comment 4 Philip Rogers 2012-12-03 16:42:54 PST
(In reply to comment #3)
> (In reply to comment #2)
> > Shouldn't it print 
> > {height: 100, width: 100, y: 50, x: 50}
> > instead?
> > 
> > Since we are getting the bbox on <use>.
> > It can also link to an external file, which from a usage point of view, is a encapsulated container?
> > I also notice that <use> width and height attribute does not force a resize on the child content.
> > Am I using <use> wrongly?
> 
> Re-opening because there seems to be some confusion about this.
> 
> For the record, here's how the major browsers are currently working:
> Chrome Canary - {height: 100, width: 100, y: 100, x: 100}
> Firefox Nightly - {height: 100, width: 100, y: 100, x: 100}
> IE10 - {height: 100, width: 100, y: 100, x: 100}
> Opera next: {height: 100, width: 100, y: 150, x: 150}
> 
> It looks like Cr/FF/IE are returning the bbox of the referenced element whereas Opera is returning the bbox of the the rendered content. I think Opera might be the most intuitive. I do not think {height: 100, width: 100, y: 50, x: 50} makes sense.
> 
> In particular, we (Chrome, IE) seem inconsistent in the multiple-use case:
> <html>
> <body>
> <svg width="500" height="500">
>   <rect id="rect" x="0" y="0" width="100" height="100" opacity="0.5" fill="green"/>
>   <use id="use" xlink:href="#rect" x="50" y="50" />
>   <use id="use2" xlink:href="#use" x="200" y="200" />
> </svg>
> <script>
>   console.log(document.getElementById('rect').getBBox());
>   console.log(document.getElementById('use').getBBox());
>   console.log(document.getElementById('use2').getBBox());
> </script>
> </body>
> </html>
> 
> @Dirk, should we be adding the x,y offset from the <use> attributes in returning the bbox?
> Relevant spec: http://www.w3.org/TR/SVG/single-page.html#types-__svg__SVGLocatable__getBBox

Dirk on irc/#ksvg set me straight. This comes down to transforms on the current element not contributing to the bbox. When the <use> tree is built, we effectively replace <use> with <g> with all attributes except x,y,width,height. Therefore, these results make sense after all and Cr/FF/IE are consistent.

I'll file a bug against Opera.
Comment 5 webkit 2012-12-07 01:40:15 PST
This exact issue has been discussed on www-svg before:
http://lists.w3.org/Archives/Public/www-svg/2010Jan/0049.html

It all comes down to how x,y on <use> should be interpreted. I'd argue that Opera's behaviour is the most intuitive to authors, and is the behaviour our users have asked us for, on www-svg and elsewhere. Yes, the x,y does get treated as a transform in the generated shadowtree, but they're still x,y-attributes on the <use> element, and so it's reasonable to expect that they behave the same as every other x,y attribute pair (in other words: they affect the bbox of the element).
Comment 6 Dirk Schulze 2012-12-07 08:51:00 PST
(In reply to comment #5)
> This exact issue has been discussed on www-svg before:
> http://lists.w3.org/Archives/Public/www-svg/2010Jan/0049.html
> 
> It all comes down to how x,y on <use> should be interpreted. I'd argue that Opera's behaviour is the most intuitive to authors, and is the behaviour our users have asked us for, on www-svg and elsewhere. Yes, the x,y does get treated as a transform in the generated shadowtree, but they're still x,y-attributes on the <use> element, and so it's reasonable to expect that they behave the same as every other x,y attribute pair (in other words: they affect the bbox of the element).

Philip did not quote the relevant section [1]:

""
In the generated content, the ‘use’ will be replaced by ‘g’, where all attributes from the ‘use’ element except for ‘x’, ‘y’, ‘width’, ‘height’ and ‘xlink:href’ are transferred to the generated ‘g’ element. An additional transformation translate(x,y) is appended to the end (i.e., right-side) of the ‘transform’ attribute on the generated ‘g’, where x and y represent the values of the ‘x’ and ‘y’ attributes on the ‘use’ element. The referenced object and its contents are deep-cloned into the generated tree.
""

This means x,y are used as transformation on the virtual g. The transform of an element does not contribute to its bounding box (but the parents bounding box). This is why Opera is wrong.

[1] http://www.w3.org/TR/SVG/struct.html#UseElement
Comment 7 Philip Rogers 2012-12-11 15:35:28 PST
(In reply to comment #5)
> This exact issue has been discussed on www-svg before:
> http://lists.w3.org/Archives/Public/www-svg/2010Jan/0049.html
> 
> It all comes down to how x,y on <use> should be interpreted. I'd argue that Opera's behaviour is the most intuitive to authors, and is the behaviour our users have asked us for, on www-svg and elsewhere. Yes, the x,y does get treated as a transform in the generated shadowtree, but they're still x,y-attributes on the <use> element, and so it's reasonable to expect that they behave the same as every other x,y attribute pair (in other words: they affect the bbox of the element).

Erik,
As I said in comment #3, I also agree that Opera's implementation is the most intuitive for users. Users will almost certainly not know how the <use> tree is implemented.
Would Opera be willing to change their implementation for the sake of cross-browser consistency? If not, we should really bring this back up on www-svg.
Comment 8 webkit 2012-12-13 04:04:44 PST
Opera follows the SVG Tiny 1.2 REC, which defined this in much more detail than SVG 1.1 ever did.

See http://www.w3.org/TR/SVGTiny12/svgudom.html#svg__SVGLocatable_getBBox (and look at the examples below there, as well as the definition of boundingbox).

IMHO SVG2 should follow that instead.