Bug 53767 - SVG <use> element is not repositioned when moved to x=0 y=0 through script
Summary: SVG <use> element is not repositioned when moved to x=0 y=0 through script
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Rob Buis
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-04 07:33 PST by Alexis Deveria
Modified: 2011-07-24 13:11 PDT (History)
5 users (show)

See Also:


Attachments
Example of the problem, the green rect should cover the red one after one second. (797 bytes, image/svg+xml)
2011-02-04 07:35 PST, Alexis Deveria
no flags Details
Patch (7.42 KB, patch)
2011-07-22 18:09 PDT, Rob Buis
no flags Details | Formatted Diff | Diff
Patch (9.71 KB, patch)
2011-07-23 09:45 PDT, Rob Buis
zimmermann: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Alexis Deveria 2011-02-04 07:33:29 PST
SVG <use> elements will appear with x="0" y="0" statically and can moved using any other values in JS, but exactly x=0 and y=0 results in no visual difference. Same problem when removing both x and y attributes.
Comment 1 Alexis Deveria 2011-02-04 07:35:07 PST
Created attachment 81217 [details]
Example of the problem, the green rect should cover the red one after one second.
Comment 2 Rob Buis 2011-07-22 18:09:17 PDT
Created attachment 101798 [details]
Patch
Comment 3 Dirk Schulze 2011-07-22 22:29:40 PDT
Comment on attachment 101798 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=101798&action=review

> Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp:53
> +    m_yOffset = y;
> +    if (renderer())
> +        static_cast<RenderSVGTransformableContainer*>(renderer())->setNeedsTransformUpdate();

Si it is not only 0,0 affected but every other position as well? Because according your patch I don't see a reason why just 0,0 should be affected.
Comment 4 Nikolas Zimmermann 2011-07-22 23:37:59 PDT
Comment on attachment 101798 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=101798&action=review

>> Source/WebCore/rendering/svg/SVGShadowTreeElements.cpp:53
>> +        static_cast<RenderSVGTransformableContainer*>(renderer())->setNeedsTransformUpdate();
> 
> Si it is not only 0,0 affected but every other position as well? Because according your patch I don't see a reason why just 0,0 should be affected.

The more interessting question is why would you need a "transform update" if transform did not change?

Note that RenderSVGShadowTreeRootContainer inherits from RenderSVGTransformableContainer, and
bool RenderSVGTransformableContainer::calculateLocalTransform()

contains special code to apply the container offset to the local transform. This should work even _without_ touching setNeedsTransformUpdate.
If it doesn't there's another bug that you're hiding by this workaround.

r- for this reason.
Comment 5 Nikolas Zimmermann 2011-07-22 23:41:51 PDT
Good point Dirk - why is only x/y=0 affected.
Here's the answer:

bool RenderSVGTransformableContainer::calculateLocalTransform()
{
    SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
......

    FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(element)->containerTranslation();
    if (!translation.width() && !translation.height())
        return needsUpdate;

if translation width/height (corresponds to x/y) is 0 we'll ignore updating the transform.
We need to store the previous translation, and compare it with the current translation, if they are equal just "return needsUpdate" otherwhise go on....

That explains why only x=0&&y=0 failed here, and avoids the setNeedsTransformUpdate hack from your current patch...
Comment 6 Rob Buis 2011-07-23 05:32:28 PDT
Hi guys,

(In reply to comment #5)
> Good point Dirk - why is only x/y=0 affected.
> Here's the answer:
> 
> bool RenderSVGTransformableContainer::calculateLocalTransform()
> {
>     SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
> ......
> 
>     FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(element)->containerTranslation();
>     if (!translation.width() && !translation.height())
>         return needsUpdate;
> 
> if translation width/height (corresponds to x/y) is 0 we'll ignore updating the transform.
> We need to store the previous translation, and compare it with the current translation, if they are equal just "return needsUpdate" otherwhise go on....
> 
> That explains why only x=0&&y=0 failed here, and avoids the setNeedsTransformUpdate hack from your current patch...

Was just about to hint at the same code (just woken up) :)
Will have a look at it again.
Cheers,

Rob.
Comment 7 Rob Buis 2011-07-23 09:45:15 PDT
Created attachment 101814 [details]
Patch
Comment 8 Nikolas Zimmermann 2011-07-24 02:44:50 PDT
Comment on attachment 101814 [details]
Patch

Excellent patch, r=me!
Comment 9 Rob Buis 2011-07-24 13:11:36 PDT
Landed in r91644.