Changeset 19202 in webkit


Ignore:
Timestamp:
Jan 28, 2007 4:03:01 PM (17 years ago)
Author:
eseidel
Message:

2007-01-28 Charles Ying <charles_ying@yahoo.com>

Reviewed by eseidel. Landed by eseidel.

Fix http://bugs.webkit.org/show_bug.cgi?id=12429

animateTransform rotate, with cx/cy is broken


SVGTransform now contains a float point to store the rotation center, needed

to track rotation center for interpolation by animateTransform.


SVGTransform now has an additional constructor:

SVGTransform(type) to make empty base value transforms that match their
distanced values.


Removed m_colorDistance and m_transformDistance from their respective classes

as they are now computed at update time.

Fix a case where animateTransform did not parse transform values correctly

according to BNF in W3C spec:

Test case in:

  • manual-tests/animation/animateTransform-toanimation.svg: Added.

Fix a case where animateTransform only specified a to animation only.

Test case in:

  • manual-tests/animation/animateTransform-parser.svg: Added.
  • ksvg2/svg/SVGAnimateColorElement.cpp: (WebCore::SVGAnimateColorElement::updateAnimationBaseValueFromElement): (WebCore::SVGAnimateColorElement::updateAnimatedValue): (WebCore::SVGAnimateColorElement::calculateFromAndToValues):
  • ksvg2/svg/SVGAnimateColorElement.h:
  • ksvg2/svg/SVGAnimateTransformElement.cpp: (WebCore::SVGAnimateTransformElement::updateAnimatedValue): (WebCore::SVGAnimateTransformElement::updateAnimationBaseValueFromElement): (WebCore::SVGAnimateTransformElement::calculateFromAndToValues): (WebCore::SVGAnimateTransformElement::parseTransformValue):
  • ksvg2/svg/SVGAnimateTransformElement.h:
  • ksvg2/svg/SVGTransform.cpp: (SVGTransform::SVGTransform): (SVGTransform::angle): (SVGTransform::rotationCenter): (SVGTransform::setTranslate): (SVGTransform::setScale): (SVGTransform::setRotate): (SVGTransform::setSkewX): (SVGTransform::setSkewY):
  • ksvg2/svg/SVGTransform.h:
  • ksvg2/svg/SVGTransformDistance.cpp: (WebCore::SVGTransformDistance::SVGTransformDistance): (WebCore::SVGTransformDistance::scaledDistance): (WebCore::SVGTransformDistance::addSVGTransforms): (WebCore::SVGTransformDistance::addSVGTransform): (WebCore::SVGTransformDistance::addToSVGTransform): (WebCore::SVGTransformDistance::distance):
  • ksvg2/svg/SVGTransformDistance.h:
  • manual-tests/animation/animateTransform-parser.svg: Added.
  • manual-tests/animation/animateTransform-toanimation.svg: Added.
Location:
trunk/WebCore
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r19197 r19202  
     12007-01-28  Charles Ying  <charles_ying@yahoo.com>
     2
     3        Reviewed by eseidel.  Landed by eseidel.
     4
     5        Fix http://bugs.webkit.org/show_bug.cgi?id=12429
     6            animateTransform rotate, with cx/cy is broken
     7           
     8        SVGTransform now contains a float point to store the rotation center, needed
     9            to track rotation center for interpolation by animateTransform.
     10           
     11        SVGTransform now has an additional constructor:
     12            SVGTransform(type) to make empty base value transforms that match their
     13            distanced values.
     14           
     15        Removed m_colorDistance and m_transformDistance from their respective classes
     16            as they are now computed at update time.
     17
     18        Fix a case where animateTransform did not parse transform values correctly
     19            according to BNF in W3C spec:
     20
     21        Test case in:
     22        * manual-tests/animation/animateTransform-toanimation.svg: Added.
     23
     24        Fix a case where animateTransform only specified a to animation only.
     25
     26        Test case in:
     27        * manual-tests/animation/animateTransform-parser.svg: Added.
     28
     29        * ksvg2/svg/SVGAnimateColorElement.cpp:
     30        (WebCore::SVGAnimateColorElement::updateAnimationBaseValueFromElement):
     31        (WebCore::SVGAnimateColorElement::updateAnimatedValue):
     32        (WebCore::SVGAnimateColorElement::calculateFromAndToValues):
     33        * ksvg2/svg/SVGAnimateColorElement.h:
     34        * ksvg2/svg/SVGAnimateTransformElement.cpp:
     35        (WebCore::SVGAnimateTransformElement::updateAnimatedValue):
     36        (WebCore::SVGAnimateTransformElement::updateAnimationBaseValueFromElement):
     37        (WebCore::SVGAnimateTransformElement::calculateFromAndToValues):
     38        (WebCore::SVGAnimateTransformElement::parseTransformValue):
     39        * ksvg2/svg/SVGAnimateTransformElement.h:
     40        * ksvg2/svg/SVGTransform.cpp:
     41        (SVGTransform::SVGTransform):
     42        (SVGTransform::angle):
     43        (SVGTransform::rotationCenter):
     44        (SVGTransform::setTranslate):
     45        (SVGTransform::setScale):
     46        (SVGTransform::setRotate):
     47        (SVGTransform::setSkewX):
     48        (SVGTransform::setSkewY):
     49        * ksvg2/svg/SVGTransform.h:
     50        * ksvg2/svg/SVGTransformDistance.cpp:
     51        (WebCore::SVGTransformDistance::SVGTransformDistance):
     52        (WebCore::SVGTransformDistance::scaledDistance):
     53        (WebCore::SVGTransformDistance::addSVGTransforms):
     54        (WebCore::SVGTransformDistance::addSVGTransform):
     55        (WebCore::SVGTransformDistance::addToSVGTransform):
     56        (WebCore::SVGTransformDistance::distance):
     57        * ksvg2/svg/SVGTransformDistance.h:
     58        * manual-tests/animation/animateTransform-parser.svg: Added.
     59        * manual-tests/animation/animateTransform-toanimation.svg: Added.
     60
    1612007-01-27  Adam Roben  <aroben@apple.com>
    262
  • trunk/WebCore/ksvg2/svg/SVGAnimateColorElement.cpp

    r19168 r19202  
    4848{
    4949    m_baseColor = SVGColor::colorFromRGBColorString(targetAttributeAnimatedValue());
    50     m_colorDistance = ColorDistance();
    5150    m_fromColor = Color();
    5251    m_toColor = Color();
     
    6867        m_animatedColor = ColorDistance(m_baseColor, m_toColor).scaledDistance(timePercentage).addToColorAndClamp(m_baseColor);
    6968    else
    70         m_animatedColor = m_colorDistance.scaledDistance(percentagePast).addToColorAndClamp(m_fromColor);
     69        m_animatedColor = ColorDistance(m_fromColor, m_toColor).scaledDistance(percentagePast).addToColorAndClamp(m_fromColor);
    7170    return (m_animatedColor != m_baseColor);
    7271}
     
    9796    }
    9897   
    99     m_colorDistance = ColorDistance(m_fromColor, m_toColor);
    100     return !m_colorDistance.isZero();
     98    return true;
    10199}
    102100
  • trunk/WebCore/ksvg2/svg/SVGAnimateColorElement.h

    r19168 r19202  
    5454        Color m_toColor;
    5555        Color m_fromColor;
    56 
    57         ColorDistance m_colorDistance;
    5856    };
    5957
  • trunk/WebCore/ksvg2/svg/SVGAnimateTransformElement.cpp

    r19168 r19202  
    3333#include "SVGTransform.h"
    3434#include "SVGTransformList.h"
     35#include "SVGParserUtilities.h"
    3536#include <math.h>
    3637#include <wtf/MathExtras.h>
     
    7980        m_animatedTransform = SVGTransformDistance(m_baseTransform, m_toTransform).scaledDistance(timePercentage).addToSVGTransform(m_baseTransform);
    8081    else
    81         m_animatedTransform = m_transformDistance.scaledDistance(percentagePast).addToSVGTransform(m_fromTransform);
     82        m_animatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentagePast).addToSVGTransform(m_fromTransform);
    8283    return (m_animatedTransform != m_baseTransform);
    8384}
     
    99100   
    100101    m_baseTransform = transformList->concatenateForType(m_type);
     102   
     103    // If a base value is empty, its type should match m_type instead of being unknown.
     104    // It's not certain whether this should be part of SVGTransformList or not -- cying
     105    if (m_baseTransform.type() == SVGTransform::SVG_TRANSFORM_UNKNOWN)
     106        m_baseTransform = SVGTransform(m_type);
    101107       
    102108    return true;
     
    123129bool SVGAnimateTransformElement::calculateFromAndToValues(EAnimationMode animationMode, unsigned valueIndex)
    124130{
    125     switch (detectAnimationMode()) {
     131    switch (animationMode) {
    126132    case FROM_TO_ANIMATION:
    127133        m_fromTransform = parseTransformValue(m_from);
     
    145151        ASSERT_NOT_REACHED();
    146152    }
    147     m_transformDistance = SVGTransformDistance(m_fromTransform, m_toTransform);
    148     return !m_transformDistance.isZero();
     153   
     154    return true;
    149155}
    150156
     
    156162    if (parse.isEmpty())
    157163        return SVGTransform();
    158    
    159     int commaPos = parse.find(','); // In case two values are passed...
    160 
     164
     165    // Careful, cur changes as parseNumber is called.
     166    const UChar* cur = parse.characters();
     167    const UChar* end = cur + parse.length();
     168   
    161169    SVGTransform parsedTransform;
    162170   
     
    165173        {
    166174            double tx = 0.0, ty = 0.0;
    167             if (commaPos != - 1) {
    168                 tx = parse.substring(0, commaPos).toDouble();
    169                 ty = parse.substring(commaPos + 1).toDouble();
    170             } else
    171                 tx = parse.toDouble();
     175           
     176            if (!parseNumber(cur, end, tx))
     177                tx = 0.0;
     178           
     179            if (!parseNumber(cur, end, ty))
     180                ty = 0.0;
    172181
    173182            parsedTransform.setTranslate(tx, ty);
     
    177186        {
    178187            double sx = 1.0, sy = 1.0;
    179             if (commaPos != - 1) {
    180                 sx = parse.substring(0, commaPos).toDouble();
    181                 sy = parse.substring(commaPos + 1).toDouble();
    182             } else {
    183                 sx = parse.toDouble();
     188
     189            if (!parseNumber(cur, end, sx))
     190                sx = 1.0;
     191           
     192            if (!parseNumber(cur, end, sy))
    184193                sy = sx;
    185             }
    186 
     194           
    187195            parsedTransform.setScale(sx, sy);
    188196            break;
     
    191199        {
    192200            double angle = 0, cx = 0, cy = 0;
    193             if (commaPos != - 1) {
    194                 angle = parse.substring(0, commaPos).toDouble(); // TODO: probably needs it's own 'angle' parser
    195    
    196                 int commaPosTwo = parse.find(',', commaPos + 1); // In case three values are passed...
    197                 if (commaPosTwo != -1) {
    198                     cx = parse.substring(commaPos + 1, commaPosTwo - commaPos - 1).toDouble();
    199                     cy = parse.substring(commaPosTwo + 1).toDouble();
     201
     202            if (parseNumber(cur, end, angle)) {
     203                // Successful, try to read cx and cy. It's either both cx and cy or none
     204                if (!parseNumber(cur, end, cx) || !parseNumber(cur, end, cy)) {
     205                    cx = 0;
     206                    cy = 0;
    200207                }
    201208            }
    202             else
    203                 angle = parse.toDouble();
    204209
    205210            parsedTransform.setRotate(angle, cx, cy);
     
    209214        case SVGTransform::SVG_TRANSFORM_SKEWY:
    210215        {
    211             double angle = parse.toDouble(); // TODO: probably needs it's own 'angle' parser
     216            double angle = 0;
     217           
     218            if (!parseNumber(cur, end, angle))
     219                angle = 0;
    212220           
    213221            if (m_type == SVGTransform::SVG_TRANSFORM_SKEWX)
  • trunk/WebCore/ksvg2/svg/SVGAnimateTransformElement.h

    r19168 r19202  
    6464        SVGTransform m_baseTransform;
    6565        SVGTransform m_animatedTransform;
    66        
    67         SVGTransformDistance m_transformDistance;
    6866    };
    6967
  • trunk/WebCore/ksvg2/svg/SVGTransform.cpp

    r19168 r19202  
    3838}
    3939
     40SVGTransform::SVGTransform(SVGTransformType type)
     41    : m_type(type)
     42    , m_angle(0)
     43    , m_center(FloatPoint())
     44    , m_matrix(AffineTransform())
     45{
     46}
     47
    4048SVGTransform::SVGTransform(const AffineTransform& matrix)
    4149    : m_type(SVG_TRANSFORM_MATRIX)
     
    6472}
    6573
    66 double SVGTransform::angle() const
     74float SVGTransform::angle() const
    6775{
    6876    return m_angle;
     77}
     78
     79FloatPoint SVGTransform::rotationCenter() const
     80{
     81    return m_center;
    6982}
    7083
     
    7790}
    7891
    79 void SVGTransform::setTranslate(double tx, double ty)
     92void SVGTransform::setTranslate(float tx, float ty)
    8093{
    8194    m_type = SVG_TRANSFORM_TRANSLATE;
     
    91104}
    92105
    93 void SVGTransform::setScale(double sx, double sy)
     106void SVGTransform::setScale(float sx, float sy)
    94107{
    95108    m_type = SVG_TRANSFORM_SCALE;
    96109    m_angle = 0;
     110    m_center = FloatPoint();
    97111
    98112    m_matrix.reset();
     
    105119}
    106120
    107 void SVGTransform::setRotate(double angle, double cx, double cy)
     121void SVGTransform::setRotate(float angle, float cx, float cy)
    108122{
    109123    m_type = SVG_TRANSFORM_ROTATE;
    110124    m_angle = angle;
     125    m_center = FloatPoint(cx, cy);
    111126
    112127    // TODO: toString() implementation, which can show cx, cy (need to be stored?)
     
    117132}
    118133
    119 void SVGTransform::setSkewX(double angle)
     134void SVGTransform::setSkewX(float angle)
    120135{
    121136    m_type = SVG_TRANSFORM_SKEWX;
     
    126141}
    127142
    128 void SVGTransform::setSkewY(double angle)
     143void SVGTransform::setSkewY(float angle)
    129144{
    130145    m_type = SVG_TRANSFORM_SKEWY;
  • trunk/WebCore/ksvg2/svg/SVGTransform.h

    r19168 r19202  
    2626
    2727#include "AffineTransform.h"
     28#include "FloatPoint.h"
    2829#include "Shared.h"
    2930#include <wtf/RefPtr.h>
     
    3132namespace WebCore {
    3233   
    33     class FloatPoint;
    3434    class FloatSize;
    3535
     
    4747 
    4848        SVGTransform();
     49        SVGTransform(SVGTransformType type);
    4950        explicit SVGTransform(const AffineTransform&);
    5051        virtual ~SVGTransform();
     
    5455        AffineTransform matrix() const;
    5556   
    56         double angle() const;
     57        float angle() const;
     58        FloatPoint rotationCenter() const;
    5759
    5860        void setMatrix(const AffineTransform&);
    59         void setTranslate(double tx, double ty);
    60         void setScale(double sx, double sy);
    61         void setRotate(double angle, double cx, double cy);
    62         void setSkewX(double angle);
    63         void setSkewY(double angle);
     61        void setTranslate(float tx, float ty);
     62        void setScale(float sx, float sy);
     63        void setRotate(float angle, float cx, float cy);
     64        void setSkewX(float angle);
     65        void setSkewY(float angle);
    6466       
    6567        // Internal use only (animation system)
     
    7173    private:
    7274        SVGTransformType m_type;
    73         double m_angle;
     75        float m_angle;
     76        FloatPoint m_center;
    7477        AffineTransform m_matrix;
    7578    };
  • trunk/WebCore/ksvg2/svg/SVGTransformDistance.cpp

    r19190 r19202  
    3838}
    3939
    40 SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, double angle, const AffineTransform& transform)
     40SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, double angle, double cx, double cy, const AffineTransform& transform)
    4141    : m_type(type)
    4242    , m_angle(angle)
     43    , m_cx(cx)
     44    , m_cy(cy)
    4345    , m_transform(transform)
    4446{
     
    4850    : m_type(fromSVGTransform.type())
    4951    , m_angle(0)
     52    , m_cx(0)
     53    , m_cy(0)
    5054{
    5155    ASSERT(m_type == toSVGTransform.type());
     
    5862        return;
    5963    case SVGTransform::SVG_TRANSFORM_ROTATE:
     64    {
     65        FloatSize centerDistance = toSVGTransform.rotationCenter() - fromSVGTransform.rotationCenter();
    6066        m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
    61         // fall through
     67        m_cx = centerDistance.width();
     68        m_cy = centerDistance.height();
     69        return;
     70    }
    6271    case SVGTransform::SVG_TRANSFORM_TRANSLATE:
    6372    {
     
    8695        return SVGTransformDistance();
    8796    case SVGTransform::SVG_TRANSFORM_ROTATE:
    88         return SVGTransformDistance(m_type, m_angle * scaleFactor, AffineTransform());
    89     case SVGTransform::SVG_TRANSFORM_SCALE:
    90     case SVGTransform::SVG_TRANSFORM_MATRIX:
    91         return SVGTransformDistance(m_type, m_angle * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
     97        return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
     98    case SVGTransform::SVG_TRANSFORM_SCALE:
     99    case SVGTransform::SVG_TRANSFORM_MATRIX:
     100        return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
    92101    case SVGTransform::SVG_TRANSFORM_TRANSLATE:
    93102    {
     
    95104        newTransform.setE(m_transform.e() * scaleFactor);
    96105        newTransform.setF(m_transform.f() * scaleFactor);
    97         return SVGTransformDistance(m_type, 0, newTransform);
    98     }
    99     case SVGTransform::SVG_TRANSFORM_SKEWX:
    100     case SVGTransform::SVG_TRANSFORM_SKEWY:
    101         return SVGTransformDistance(m_type, m_angle * scaleFactor, AffineTransform());
     106        return SVGTransformDistance(m_type, 0, 0, 0, newTransform);
     107    }
     108    case SVGTransform::SVG_TRANSFORM_SKEWX:
     109    case SVGTransform::SVG_TRANSFORM_SKEWY:
     110        return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
    102111    }
    103112   
     
    117126    case SVGTransform::SVG_TRANSFORM_ROTATE:
    118127    {
    119         // FIXME: I'm not sure that the translation is correct here
    120         float dx = first.translate().x() + second.translate().x();
    121         float dy = first.translate().y() + second.translate().y();
    122         transform.setRotate(first.angle() + second.angle(), dx, dy);
     128        transform.setRotate(first.angle() + second.angle(), first.rotationCenter().x() + second.rotationCenter().x(),
     129                            first.rotationCenter().y() + second.rotationCenter().y());
    123130        return transform;
    124131    }
     
    167174    case SVGTransform::SVG_TRANSFORM_ROTATE:
    168175        m_angle += absoluteValue ? fabsf(transform.angle()) : transform.angle();
     176        m_cx += absoluteValue ? fabsf(transform.rotationCenter().x()) : transform.rotationCenter().x();
     177        m_cy += absoluteValue ? fabsf(transform.rotationCenter().y()) : transform.rotationCenter().y();
    169178        // fall through
    170179    case SVGTransform::SVG_TRANSFORM_TRANSLATE:
     
    220229    {
    221230        // FIXME: I'm not certain the translation is calculated correctly here
    222         FloatPoint translation = transform.translate();
    223         translation += FloatSize(m_transform.e(), m_transform.f());
    224         newTransform.setRotate(transform.angle() + m_angle, translation.x(), translation.y());
     231        FloatPoint center = transform.rotationCenter();
     232        newTransform.setRotate(transform.angle() + m_angle, center.x() + m_cx, center.y() + m_cy);
    225233        return newTransform;
    226234    }
     
    248256        return 0;
    249257    case SVGTransform::SVG_TRANSFORM_ROTATE:
    250         return sqrtf(m_angle * m_angle + m_transform.e() * m_transform.e() + m_transform.f() * m_transform.f());
     258        return sqrtf(m_angle * m_angle + m_cx * m_cx + m_cy * m_cy);
    251259    case SVGTransform::SVG_TRANSFORM_MATRIX:
    252260        return 0; // I'm not quite sure yet what distance between two matrices means.
  • trunk/WebCore/ksvg2/svg/SVGTransformDistance.h

    r19168 r19202  
    4545        float distance() const;
    4646    private:
    47         SVGTransformDistance(SVGTransform::SVGTransformType, double angle, const AffineTransform&);
     47        SVGTransformDistance(SVGTransform::SVGTransformType, double angle, double cx, double cy, const AffineTransform&);
    4848           
    4949        SVGTransform::SVGTransformType m_type;
    5050        double m_angle;
     51        double m_cx;
     52        double m_cy;
    5153        AffineTransform m_transform; // for storing scale, translation or matrix transforms
    5254    };
Note: See TracChangeset for help on using the changeset viewer.