00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "wtf/Platform.h"
00024 #if ENABLE(SVG)
00025 #include "SVGTransformDistance.h"
00026
00027 #include "FloatConversion.h"
00028 #include "FloatPoint.h"
00029 #include "FloatSize.h"
00030 #include "SVGTransform.h"
00031
00032 #include <math.h>
00033
00034 namespace WebCore {
00035
00036 SVGTransformDistance::SVGTransformDistance()
00037 : m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
00038 , m_angle(0)
00039 {
00040 }
00041
00042 SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, float angle, float cx, float cy, const AffineTransform& transform)
00043 : m_type(type)
00044 , m_angle(angle)
00045 , m_cx(cx)
00046 , m_cy(cy)
00047 , m_transform(transform)
00048 {
00049 }
00050
00051 SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, const SVGTransform& toSVGTransform)
00052 : m_type(fromSVGTransform.type())
00053 , m_angle(0)
00054 , m_cx(0)
00055 , m_cy(0)
00056 {
00057 ASSERT(m_type == toSVGTransform.type());
00058
00059 switch (m_type) {
00060 case SVGTransform::SVG_TRANSFORM_UNKNOWN:
00061 return;
00062 case SVGTransform::SVG_TRANSFORM_MATRIX:
00063
00064 return;
00065 case SVGTransform::SVG_TRANSFORM_ROTATE:
00066 {
00067 FloatSize centerDistance = toSVGTransform.rotationCenter() - fromSVGTransform.rotationCenter();
00068 m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
00069 m_cx = centerDistance.width();
00070 m_cy = centerDistance.height();
00071 return;
00072 }
00073 case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00074 {
00075 FloatSize translationDistance = toSVGTransform.translate() - fromSVGTransform.translate();
00076 m_transform.translate(translationDistance.width(), translationDistance.height());
00077 return;
00078 }
00079 case SVGTransform::SVG_TRANSFORM_SCALE:
00080 {
00081 float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width();
00082 float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height();
00083 m_transform.scale(scaleX, scaleY);
00084 return;
00085 }
00086 case SVGTransform::SVG_TRANSFORM_SKEWX:
00087 case SVGTransform::SVG_TRANSFORM_SKEWY:
00088 m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
00089 return;
00090 }
00091 }
00092
00093 SVGTransformDistance SVGTransformDistance::scaledDistance(float scaleFactor) const
00094 {
00095 switch (m_type) {
00096 case SVGTransform::SVG_TRANSFORM_UNKNOWN:
00097 return SVGTransformDistance();
00098 case SVGTransform::SVG_TRANSFORM_ROTATE:
00099 return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
00100 case SVGTransform::SVG_TRANSFORM_SCALE:
00101 case SVGTransform::SVG_TRANSFORM_MATRIX:
00102 return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
00103 case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00104 {
00105 AffineTransform newTransform(m_transform);
00106 newTransform.setE(m_transform.e() * scaleFactor);
00107 newTransform.setF(m_transform.f() * scaleFactor);
00108 return SVGTransformDistance(m_type, 0, 0, 0, newTransform);
00109 }
00110 case SVGTransform::SVG_TRANSFORM_SKEWX:
00111 case SVGTransform::SVG_TRANSFORM_SKEWY:
00112 return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
00113 }
00114
00115 ASSERT_NOT_REACHED();
00116 return SVGTransformDistance();
00117 }
00118
00119 SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second)
00120 {
00121 ASSERT(first.type() == second.type());
00122
00123 SVGTransform transform;
00124
00125 switch (first.type()) {
00126 case SVGTransform::SVG_TRANSFORM_UNKNOWN:
00127 return SVGTransform();
00128 case SVGTransform::SVG_TRANSFORM_ROTATE:
00129 {
00130 transform.setRotate(first.angle() + second.angle(), first.rotationCenter().x() + second.rotationCenter().x(),
00131 first.rotationCenter().y() + second.rotationCenter().y());
00132 return transform;
00133 }
00134 case SVGTransform::SVG_TRANSFORM_MATRIX:
00135 transform.setMatrix(first.matrix() * second.matrix());
00136 return transform;
00137 case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00138 {
00139 float dx = first.translate().x() + second.translate().x();
00140 float dy = first.translate().y() + second.translate().y();
00141 transform.setTranslate(dx, dy);
00142 return transform;
00143 }
00144 case SVGTransform::SVG_TRANSFORM_SCALE:
00145 {
00146 FloatSize scale = first.scale() + second.scale();
00147 transform.setScale(scale.width(), scale.height());
00148 return transform;
00149 }
00150 case SVGTransform::SVG_TRANSFORM_SKEWX:
00151 transform.setSkewX(first.angle() + second.angle());
00152 return transform;
00153 case SVGTransform::SVG_TRANSFORM_SKEWY:
00154 transform.setSkewY(first.angle() + second.angle());
00155 return transform;
00156 }
00157
00158 ASSERT_NOT_REACHED();
00159 return SVGTransform();
00160 }
00161
00162 void SVGTransformDistance::addSVGTransform(const SVGTransform& transform, bool absoluteValue)
00163 {
00164
00165 if (m_type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
00166 m_type = transform.type();
00167
00168 ASSERT(m_type == transform.type());
00169
00170 switch (m_type) {
00171 case SVGTransform::SVG_TRANSFORM_UNKNOWN:
00172 return;
00173 case SVGTransform::SVG_TRANSFORM_MATRIX:
00174 m_transform *= transform.matrix();
00175 return;
00176 case SVGTransform::SVG_TRANSFORM_ROTATE:
00177 m_angle += absoluteValue ? fabsf(transform.angle()) : transform.angle();
00178 m_cx += absoluteValue ? fabsf(transform.rotationCenter().x()) : transform.rotationCenter().x();
00179 m_cy += absoluteValue ? fabsf(transform.rotationCenter().y()) : transform.rotationCenter().y();
00180
00181 case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00182 {
00183 float dx = absoluteValue ? fabsf(transform.translate().x()) : transform.translate().x();
00184 float dy = absoluteValue ? fabsf(transform.translate().y()) : transform.translate().y();
00185 m_transform.translate(dx, dy);
00186 return;
00187 }
00188 case SVGTransform::SVG_TRANSFORM_SCALE:
00189 {
00190 float scaleX = absoluteValue ? fabsf(transform.scale().width()) : transform.scale().width();
00191 float scaleY = absoluteValue ? fabsf(transform.scale().height()) : transform.scale().height();
00192 m_transform.scale(scaleX, scaleY);
00193 return;
00194 }
00195 case SVGTransform::SVG_TRANSFORM_SKEWX:
00196 case SVGTransform::SVG_TRANSFORM_SKEWY:
00197 m_angle += absoluteValue ? fabsf(transform.angle()) : transform.angle();
00198 return;
00199 }
00200
00201 ASSERT_NOT_REACHED();
00202 return;
00203 }
00204
00205 SVGTransform SVGTransformDistance::addToSVGTransform(const SVGTransform& transform) const
00206 {
00207 ASSERT(m_type == transform.type() || transform == SVGTransform());
00208
00209 SVGTransform newTransform(transform);
00210
00211 switch (m_type) {
00212 case SVGTransform::SVG_TRANSFORM_UNKNOWN:
00213 return SVGTransform();
00214 case SVGTransform::SVG_TRANSFORM_MATRIX:
00215 return SVGTransform(transform.matrix() * m_transform);
00216 case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00217 {
00218 FloatPoint translation = transform.translate();
00219 translation += FloatSize::narrowPrecision(m_transform.e(), m_transform.f());
00220 newTransform.setTranslate(translation.x(), translation.y());
00221 return newTransform;
00222 }
00223 case SVGTransform::SVG_TRANSFORM_SCALE:
00224 {
00225 FloatSize scale = transform.scale();
00226 scale += FloatSize::narrowPrecision(m_transform.a(), m_transform.d());
00227 newTransform.setScale(scale.width(), scale.height());
00228 return newTransform;
00229 }
00230 case SVGTransform::SVG_TRANSFORM_ROTATE:
00231 {
00232
00233 FloatPoint center = transform.rotationCenter();
00234 newTransform.setRotate(transform.angle() + m_angle,
00235 center.x() + m_cx,
00236 center.y() + m_cy);
00237 return newTransform;
00238 }
00239 case SVGTransform::SVG_TRANSFORM_SKEWX:
00240 newTransform.setSkewX(transform.angle() + m_angle);
00241 return newTransform;
00242 case SVGTransform::SVG_TRANSFORM_SKEWY:
00243 newTransform.setSkewY(transform.angle() + m_angle);
00244 return newTransform;
00245 }
00246
00247 ASSERT_NOT_REACHED();
00248 return SVGTransform();
00249 }
00250
00251 bool SVGTransformDistance::isZero() const
00252 {
00253 return (m_transform == AffineTransform() && m_angle == 0);
00254 }
00255
00256 float SVGTransformDistance::distance() const
00257 {
00258 switch (m_type) {
00259 case SVGTransform::SVG_TRANSFORM_UNKNOWN:
00260 return 0.0f;
00261 case SVGTransform::SVG_TRANSFORM_ROTATE:
00262 return sqrtf(m_angle * m_angle + m_cx * m_cx + m_cy * m_cy);
00263 case SVGTransform::SVG_TRANSFORM_MATRIX:
00264 return 0.0f;
00265 case SVGTransform::SVG_TRANSFORM_SCALE:
00266 return static_cast<float>(sqrt(m_transform.a() * m_transform.a() + m_transform.d() * m_transform.d()));
00267 case SVGTransform::SVG_TRANSFORM_TRANSLATE:
00268 return static_cast<float>(sqrt(m_transform.e() * m_transform.e() + m_transform.f() * m_transform.f()));
00269 case SVGTransform::SVG_TRANSFORM_SKEWX:
00270 case SVGTransform::SVG_TRANSFORM_SKEWY:
00271 return m_angle;
00272 }
00273 ASSERT_NOT_REACHED();
00274 return 0.0f;
00275 }
00276
00277 }
00278
00279 #endif