Changeset 110532 in webkit


Ignore:
Timestamp:
Mar 12, 2012 7:45:38 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

SVG should support transform-origin and relative values
https://bugs.webkit.org/show_bug.cgi?id=79068

Patch by Hans Muller <hmuller@adobe.com> on 2012-03-12
Reviewed by Dirk Schulze.

Source/WebCore:

Added SVG support for the CSS 'transform-origin' property and for percentage
values in the transform translate function. The changes conform to
http://dev.w3.org/csswg/css3-transforms/.

Tests: svg/transforms/percent-transform-values.xhtml

svg/transforms/transform-origin-css-property.xhtml

  • css/svg.css:

(*):
(html|* > svg):
Default transform-origin for SVG elements is 0 0.

  • platform/Length.h:

(WebCore::Length::calcFloatValue):
Added a calcFloatValue overload whose max parameter (for percent lengths) is a float.
The original version will be obsolete when the sub-pixel layout support is completed.

  • rendering/style/RenderStyle.cpp:
  • rendering/style/RenderStyle.h:

(WebCore):
(WebCore::requireTransformOrigin):
Transforms that only include translations don't depend on the transform-origin.

(WebCore::RenderStyle::applyTransform):
SVG elements interpret non-percentage/keyword transform-origin values relative to their viewport,
unlike HTML which interprets all transform-origin values relative to the element's origin.
The new FloatRect applyTransform() function handles SVG semantics. Similarly, SVG elements interpret
percentage/keyword transform-origin values relative to the origin of their objectBoundingBox(), HTML
uses the borderBox. All this per http://dev.w3.org/csswg/css3-transforms/.

  • svg/SVGStyledTransformableElement.cpp:

(WebCore::SVGStyledTransformableElement::animatedLocalTransform):

LayoutTests:

Added tests for SVG CSS transform-origin property support and for
CSS translations specified with percentages and applied to an SVG element.

  • svg/transforms/change-transform-origin-css-expected.xhtml: Added.
  • svg/transforms/change-transform-origin-css.xhtml: Added.
  • svg/transforms/change-transform-origin-presentation-attribute-expected.xhtml: Added.
  • svg/transforms/change-transform-origin-presentation-attribute.xhtml: Added.
  • svg/transforms/percent-transform-values-expected.txt: Added.
  • svg/transforms/percent-transform-values.xhtml: Added.
  • svg/transforms/transform-origin-css-property-expected.xhtml: Added.
  • svg/transforms/transform-origin-css-property.xhtml: Added.
Location:
trunk
Files:
8 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r110530 r110532  
     12012-03-12  Hans Muller  <hmuller@adobe.com>
     2
     3        SVG should support transform-origin and relative values
     4        https://bugs.webkit.org/show_bug.cgi?id=79068
     5
     6        Reviewed by Dirk Schulze.
     7
     8        Added tests for SVG CSS transform-origin property support and for
     9        CSS translations specified with percentages and applied to an SVG element.
     10
     11        * svg/transforms/change-transform-origin-css-expected.xhtml: Added.
     12        * svg/transforms/change-transform-origin-css.xhtml: Added.
     13        * svg/transforms/change-transform-origin-presentation-attribute-expected.xhtml: Added.
     14        * svg/transforms/change-transform-origin-presentation-attribute.xhtml: Added.
     15        * svg/transforms/percent-transform-values-expected.txt: Added.
     16        * svg/transforms/percent-transform-values.xhtml: Added.
     17        * svg/transforms/transform-origin-css-property-expected.xhtml: Added.
     18        * svg/transforms/transform-origin-css-property.xhtml: Added.
     19
    1202012-03-12  Sam Weinig  <sam@webkit.org>
    221
  • trunk/LayoutTests/platform/chromium/test_expectations.txt

    r110524 r110532  
    930930// SVG TESTS
    931931// -----------------------------------------------------------------
     932
     933// Chromium failure needs investigation
     934BUGWK79068 : svg/transforms/transform-origin-css-property.xhtml = FAIL
    932935
    933936// New test requires rebaseline
  • trunk/Source/WebCore/ChangeLog

    r110529 r110532  
     12012-03-12  Hans Muller  <hmuller@adobe.com>
     2
     3        SVG should support transform-origin and relative values
     4        https://bugs.webkit.org/show_bug.cgi?id=79068
     5
     6        Reviewed by Dirk Schulze.
     7
     8        Added SVG support for the CSS 'transform-origin' property and for percentage
     9        values in the transform translate function.  The changes conform to
     10        http://dev.w3.org/csswg/css3-transforms/.
     11
     12        Tests: svg/transforms/percent-transform-values.xhtml
     13               svg/transforms/transform-origin-css-property.xhtml
     14
     15        * css/svg.css:
     16        (*):
     17        (html|* > svg):
     18        Default transform-origin for SVG elements is 0 0.
     19
     20        * platform/Length.h:
     21        (WebCore::Length::calcFloatValue):
     22        Added a calcFloatValue overload whose max parameter (for percent lengths) is a float.
     23        The original version will be obsolete when the sub-pixel layout support is completed.
     24
     25        * rendering/style/RenderStyle.cpp:
     26        * rendering/style/RenderStyle.h:
     27        (WebCore):
     28        (WebCore::requireTransformOrigin):
     29        Transforms that only include translations don't depend on the transform-origin.
     30
     31        (WebCore::RenderStyle::applyTransform):
     32        SVG elements interpret non-percentage/keyword transform-origin values relative to their viewport,
     33        unlike HTML which interprets all transform-origin values relative to the element's origin.
     34        The new FloatRect applyTransform() function handles SVG semantics. Similarly, SVG elements interpret
     35        percentage/keyword transform-origin values relative to the origin of their objectBoundingBox(), HTML
     36        uses the borderBox.  All this per http://dev.w3.org/csswg/css3-transforms/.
     37
     38        * svg/SVGStyledTransformableElement.cpp:
     39        (WebCore::SVGStyledTransformableElement::animatedLocalTransform):
     40
    1412012-03-12  Dana Jansens  <danakj@chromium.org>
    242
  • trunk/Source/WebCore/css/svg.css

    r105513 r110532  
    2727
    2828@namespace "http://www.w3.org/2000/svg";
     29@namespace html "http://www.w3.org/1999/xhtml";
    2930
    3031/*
     
    6465    outline: auto 5px -webkit-focus-ring-color
    6566}
     67
     68/* CSS transform specification: "transform-origin 0 0 for SVG elements without associated CSS layout box, 50% 50% for all other elements". */
     69 
     70* {
     71    -webkit-transform-origin: 0 0;
     72}
     73
     74html|* > svg {
     75    -webkit-transform-origin: 50% 50%;
     76}
  • trunk/Source/WebCore/platform/Length.h

    r110148 r110532  
    33    Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
    44    Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com)
     5    Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
    56
    67    This library is free software; you can redistribute it and/or
     
    204205    }
    205206
     207    // FIXME: when subpixel layout is supported this copy of calcFloatValue() can be removed. See bug 71143.
    206208    float calcFloatValue(int maxValue) const
    207209    {
     
    226228    }
    227229
     230    float calcFloatValue(float maxValue) const
     231    {
     232        switch (type()) {
     233        case Fixed:
     234            return getFloatValue();
     235        case Percent:
     236            return static_cast<float>(maxValue * percent() / 100.0f);
     237        case Auto:
     238            return static_cast<float>(maxValue);
     239        case Calculated:
     240            return nonNanCalculatedValue(maxValue);
     241        case Relative:
     242        case Intrinsic:
     243        case MinIntrinsic:
     244        case Undefined:
     245            ASSERT_NOT_REACHED();
     246            return 0;
     247        }
     248        ASSERT_NOT_REACHED();
     249        return 0;
     250    }
     251
    228252    bool isUndefined() const { return type() == Undefined; }
    229253
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r110260 r110532  
    22 * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
    33 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     4 * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
    45 *
    56 * This library is free software; you can redistribute it and/or
     
    770771    rareNonInheritedData.access()->m_content = ContentData::create(quote);
    771772}
    772 
    773 void RenderStyle::applyTransform(TransformationMatrix& transform, const LayoutSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
     773   
     774inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation> >& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin)
    774775{
    775776    // transform-origin brackets the transform with translate operations.
    776777    // Optimize for the case where the only transform is a translation, since the transform-origin is irrelevant
    777778    // in that case.
    778     bool applyTransformOrigin = false;
    779     unsigned s = rareNonInheritedData->m_transform->m_operations.operations().size();
    780     unsigned i;
    781     if (applyOrigin == IncludeTransformOrigin) {
    782         for (i = 0; i < s; i++) {
    783             TransformOperation::OperationType type = rareNonInheritedData->m_transform->m_operations.operations()[i]->getOperationType();
    784             if (type != TransformOperation::TRANSLATE_X
    785                     && type != TransformOperation::TRANSLATE_Y
    786                     && type != TransformOperation::TRANSLATE
    787                     && type != TransformOperation::TRANSLATE_Z
    788                     && type != TransformOperation::TRANSLATE_3D
    789                     ) {
    790                 applyTransformOrigin = true;
    791                 break;
    792             }
    793         }
    794     }
    795 
     779    if (applyOrigin != RenderStyle::IncludeTransformOrigin)
     780        return false;
     781
     782    unsigned size = transformOperations.size();
     783    for (unsigned i = 0; i < size; ++i) {
     784        TransformOperation::OperationType type = transformOperations[i]->getOperationType();
     785        if (type != TransformOperation::TRANSLATE_X
     786            && type != TransformOperation::TRANSLATE_Y
     787            && type != TransformOperation::TRANSLATE
     788            && type != TransformOperation::TRANSLATE_Z
     789            && type != TransformOperation::TRANSLATE_3D)
     790            return true;
     791    }
     792   
     793    return false;
     794}
     795
     796void RenderStyle::applyTransform(TransformationMatrix& transform, const LayoutSize& borderBoxSize, ApplyTransformOrigin applyOrigin) const
     797{
     798    // FIXME: when subpixel layout is supported (bug 71143) the body of this function could be replaced by
     799    // applyTransform(transform, FloatRect(FloatPoint(), borderBoxSize), applyOrigin);
     800   
     801    const Vector<RefPtr<TransformOperation> >& transformOperations = rareNonInheritedData->m_transform->m_operations.operations();
     802    bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin);
     803
     804    if (applyTransformOrigin)
     805        transform.translate3d(transformOriginX().calcFloatValue(borderBoxSize.width()), transformOriginY().calcFloatValue(borderBoxSize.height()), transformOriginZ());
     806
     807    unsigned size = transformOperations.size();
     808    for (unsigned i = 0; i < size; ++i)
     809        transformOperations[i]->apply(transform, borderBoxSize);
     810
     811    if (applyTransformOrigin)
     812        transform.translate3d(-transformOriginX().calcFloatValue(borderBoxSize.width()), -transformOriginY().calcFloatValue(borderBoxSize.height()), -transformOriginZ());
     813}
     814
     815void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, ApplyTransformOrigin applyOrigin) const
     816{
     817    const Vector<RefPtr<TransformOperation> >& transformOperations = rareNonInheritedData->m_transform->m_operations.operations();
     818    bool applyTransformOrigin = requireTransformOrigin(transformOperations, applyOrigin);
     819   
     820    float offsetX = transformOriginX().type() == Percent ? boundingBox.x() : 0;
     821    float offsetY = transformOriginY().type() == Percent ? boundingBox.y() : 0;
     822   
    796823    if (applyTransformOrigin) {
    797         transform.translate3d(transformOriginX().calcFloatValue(borderBoxSize.width()), transformOriginY().calcFloatValue(borderBoxSize.height()), transformOriginZ());
    798     }
    799 
    800     for (i = 0; i < s; i++)
    801         rareNonInheritedData->m_transform->m_operations.operations()[i]->apply(transform, borderBoxSize);
    802 
     824        transform.translate3d(transformOriginX().calcFloatValue(boundingBox.width()) + offsetX,
     825                              transformOriginY().calcFloatValue(boundingBox.height()) + offsetY,
     826                              transformOriginZ());
     827    }
     828   
     829    unsigned size = transformOperations.size();
     830    for (unsigned i = 0; i < size; ++i)
     831        transformOperations[i]->apply(transform, boundingBox.size());
     832   
    803833    if (applyTransformOrigin) {
    804         transform.translate3d(-transformOriginX().calcFloatValue(borderBoxSize.width()), -transformOriginY().calcFloatValue(borderBoxSize.height()), -transformOriginZ());
     834        transform.translate3d(-transformOriginX().calcFloatValue(boundingBox.width()) - offsetX,
     835                              -transformOriginY().calcFloatValue(boundingBox.height()) - offsetY,
     836                              -transformOriginZ());
    805837    }
    806838}
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r109785 r110532  
    895895    enum ApplyTransformOrigin { IncludeTransformOrigin, ExcludeTransformOrigin };
    896896    void applyTransform(TransformationMatrix&, const LayoutSize& borderBoxSize, ApplyTransformOrigin = IncludeTransformOrigin) const;
     897    void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, ApplyTransformOrigin = IncludeTransformOrigin) const;
    897898    void setPageScaleTransform(float);
    898899
  • trunk/Source/WebCore/svg/SVGStyledTransformableElement.cpp

    r106769 r110532  
    6767    RenderStyle* style = renderer() ? renderer()->style() : 0;
    6868
    69     // if CSS property was set, use that, otherwise fallback to attribute (if set)
     69    // If CSS property was set, use that, otherwise fallback to attribute (if set).
    7070    if (style && style->hasTransform()) {
    71         TransformationMatrix t;
    72         // For now, the transform-origin is not taken into account
    73         // Also, any percentage values will not be taken into account
    74         style->applyTransform(t, IntSize(0, 0), RenderStyle::ExcludeTransformOrigin);
    75         // Flatten any 3D transform
    76         matrix = t.toAffineTransform();
     71        // Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath.
     72        // See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/
     73        TransformationMatrix transform;
     74        style->applyTransform(transform, renderer()->objectBoundingBox());
     75
     76        // Flatten any 3D transform.
     77        matrix = transform.toAffineTransform();
    7778    } else
    7879        transform().concatenate(matrix);
Note: See TracChangeset for help on using the changeset viewer.