• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • sources
  • kde-4.12
  • kdelibs
  • khtml
  • svg
SVGTransformDistance.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3 
4  This file is part of the WebKit project
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20  */
21 
22 #include "config.h"
23 #include "wtf/Platform.h"
24 #if ENABLE(SVG)
25 #include "SVGTransformDistance.h"
26 
27 #include "FloatConversion.h"
28 #include "FloatPoint.h"
29 #include "FloatSize.h"
30 #include "SVGTransform.h"
31 
32 #include <math.h>
33 
34 namespace WebCore {
35 
36 SVGTransformDistance::SVGTransformDistance()
37  : m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
38  , m_angle(0)
39 {
40 }
41 
42 SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, float angle, float cx, float cy, const AffineTransform& transform)
43  : m_type(type)
44  , m_angle(angle)
45  , m_cx(cx)
46  , m_cy(cy)
47  , m_transform(transform)
48 {
49 }
50 
51 SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, const SVGTransform& toSVGTransform)
52  : m_type(fromSVGTransform.type())
53  , m_angle(0)
54  , m_cx(0)
55  , m_cy(0)
56 {
57  ASSERT(m_type == toSVGTransform.type());
58 
59  switch (m_type) {
60  case SVGTransform::SVG_TRANSFORM_UNKNOWN:
61  return;
62  case SVGTransform::SVG_TRANSFORM_MATRIX:
63  // FIXME: need to be able to subtract to matrices
64  return;
65  case SVGTransform::SVG_TRANSFORM_ROTATE:
66  {
67  FloatSize centerDistance = toSVGTransform.rotationCenter() - fromSVGTransform.rotationCenter();
68  m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
69  m_cx = centerDistance.width();
70  m_cy = centerDistance.height();
71  return;
72  }
73  case SVGTransform::SVG_TRANSFORM_TRANSLATE:
74  {
75  FloatSize translationDistance = toSVGTransform.translate() - fromSVGTransform.translate();
76  m_transform.translate(translationDistance.width(), translationDistance.height());
77  return;
78  }
79  case SVGTransform::SVG_TRANSFORM_SCALE:
80  {
81  float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width();
82  float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height();
83  m_transform.scale(scaleX, scaleY);
84  return;
85  }
86  case SVGTransform::SVG_TRANSFORM_SKEWX:
87  case SVGTransform::SVG_TRANSFORM_SKEWY:
88  m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
89  return;
90  }
91 }
92 
93 SVGTransformDistance SVGTransformDistance::scaledDistance(float scaleFactor) const
94 {
95  switch (m_type) {
96  case SVGTransform::SVG_TRANSFORM_UNKNOWN:
97  return SVGTransformDistance();
98  case SVGTransform::SVG_TRANSFORM_ROTATE:
99  return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
100  case SVGTransform::SVG_TRANSFORM_SCALE:
101  case SVGTransform::SVG_TRANSFORM_MATRIX:
102  return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
103  case SVGTransform::SVG_TRANSFORM_TRANSLATE:
104  {
105  AffineTransform newTransform(m_transform);
106  newTransform.setE(m_transform.e() * scaleFactor);
107  newTransform.setF(m_transform.f() * scaleFactor);
108  return SVGTransformDistance(m_type, 0, 0, 0, newTransform);
109  }
110  case SVGTransform::SVG_TRANSFORM_SKEWX:
111  case SVGTransform::SVG_TRANSFORM_SKEWY:
112  return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
113  }
114 
115  ASSERT_NOT_REACHED();
116  return SVGTransformDistance();
117 }
118 
119 SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second)
120 {
121  ASSERT(first.type() == second.type());
122 
123  SVGTransform transform;
124 
125  switch (first.type()) {
126  case SVGTransform::SVG_TRANSFORM_UNKNOWN:
127  return SVGTransform();
128  case SVGTransform::SVG_TRANSFORM_ROTATE:
129  {
130  transform.setRotate(first.angle() + second.angle(), first.rotationCenter().x() + second.rotationCenter().x(),
131  first.rotationCenter().y() + second.rotationCenter().y());
132  return transform;
133  }
134  case SVGTransform::SVG_TRANSFORM_MATRIX:
135  transform.setMatrix(first.matrix() * second.matrix());
136  return transform;
137  case SVGTransform::SVG_TRANSFORM_TRANSLATE:
138  {
139  float dx = first.translate().x() + second.translate().x();
140  float dy = first.translate().y() + second.translate().y();
141  transform.setTranslate(dx, dy);
142  return transform;
143  }
144  case SVGTransform::SVG_TRANSFORM_SCALE:
145  {
146  FloatSize scale = first.scale() + second.scale();
147  transform.setScale(scale.width(), scale.height());
148  return transform;
149  }
150  case SVGTransform::SVG_TRANSFORM_SKEWX:
151  transform.setSkewX(first.angle() + second.angle());
152  return transform;
153  case SVGTransform::SVG_TRANSFORM_SKEWY:
154  transform.setSkewY(first.angle() + second.angle());
155  return transform;
156  }
157 
158  ASSERT_NOT_REACHED();
159  return SVGTransform();
160 }
161 
162 void SVGTransformDistance::addSVGTransform(const SVGTransform& transform, bool absoluteValue)
163 {
164  // If this is the first add, set the type for this SVGTransformDistance
165  if (m_type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
166  m_type = transform.type();
167 
168  ASSERT(m_type == transform.type());
169 
170  switch (m_type) {
171  case SVGTransform::SVG_TRANSFORM_UNKNOWN:
172  return;
173  case SVGTransform::SVG_TRANSFORM_MATRIX:
174  m_transform *= transform.matrix(); // FIXME: what does 'distance' between two transforms mean? how should we respect 'absoluteValue' here?
175  return;
176  case SVGTransform::SVG_TRANSFORM_ROTATE:
177  m_angle += absoluteValue ? fabsf(transform.angle()) : transform.angle();
178  m_cx += absoluteValue ? fabsf(transform.rotationCenter().x()) : transform.rotationCenter().x();
179  m_cy += absoluteValue ? fabsf(transform.rotationCenter().y()) : transform.rotationCenter().y();
180  // fall through
181  case SVGTransform::SVG_TRANSFORM_TRANSLATE:
182  {
183  float dx = absoluteValue ? fabsf(transform.translate().x()) : transform.translate().x();
184  float dy = absoluteValue ? fabsf(transform.translate().y()) : transform.translate().y();
185  m_transform.translate(dx, dy);
186  return;
187  }
188  case SVGTransform::SVG_TRANSFORM_SCALE:
189  {
190  float scaleX = absoluteValue ? fabsf(transform.scale().width()) : transform.scale().width();
191  float scaleY = absoluteValue ? fabsf(transform.scale().height()) : transform.scale().height();
192  m_transform.scale(scaleX, scaleY);
193  return;
194  }
195  case SVGTransform::SVG_TRANSFORM_SKEWX:
196  case SVGTransform::SVG_TRANSFORM_SKEWY:
197  m_angle += absoluteValue ? fabsf(transform.angle()) : transform.angle();
198  return;
199  }
200 
201  ASSERT_NOT_REACHED();
202  return;
203 }
204 
205 SVGTransform SVGTransformDistance::addToSVGTransform(const SVGTransform& transform) const
206 {
207  ASSERT(m_type == transform.type() || transform == SVGTransform());
208 
209  SVGTransform newTransform(transform);
210 
211  switch (m_type) {
212  case SVGTransform::SVG_TRANSFORM_UNKNOWN:
213  return SVGTransform();
214  case SVGTransform::SVG_TRANSFORM_MATRIX:
215  return SVGTransform(transform.matrix() * m_transform);
216  case SVGTransform::SVG_TRANSFORM_TRANSLATE:
217  {
218  FloatPoint translation = transform.translate();
219  translation += FloatSize::narrowPrecision(m_transform.e(), m_transform.f());
220  newTransform.setTranslate(translation.x(), translation.y());
221  return newTransform;
222  }
223  case SVGTransform::SVG_TRANSFORM_SCALE:
224  {
225  FloatSize scale = transform.scale();
226  scale += FloatSize::narrowPrecision(m_transform.a(), m_transform.d());
227  newTransform.setScale(scale.width(), scale.height());
228  return newTransform;
229  }
230  case SVGTransform::SVG_TRANSFORM_ROTATE:
231  {
232  // FIXME: I'm not certain the translation is calculated correctly here
233  FloatPoint center = transform.rotationCenter();
234  newTransform.setRotate(transform.angle() + m_angle,
235  center.x() + m_cx,
236  center.y() + m_cy);
237  return newTransform;
238  }
239  case SVGTransform::SVG_TRANSFORM_SKEWX:
240  newTransform.setSkewX(transform.angle() + m_angle);
241  return newTransform;
242  case SVGTransform::SVG_TRANSFORM_SKEWY:
243  newTransform.setSkewY(transform.angle() + m_angle);
244  return newTransform;
245  }
246 
247  ASSERT_NOT_REACHED();
248  return SVGTransform();
249 }
250 
251 bool SVGTransformDistance::isZero() const
252 {
253  return (m_transform == AffineTransform() && m_angle == 0);
254 }
255 
256 float SVGTransformDistance::distance() const
257 {
258  switch (m_type) {
259  case SVGTransform::SVG_TRANSFORM_UNKNOWN:
260  return 0.0f;
261  case SVGTransform::SVG_TRANSFORM_ROTATE:
262  return sqrtf(m_angle * m_angle + m_cx * m_cx + m_cy * m_cy);
263  case SVGTransform::SVG_TRANSFORM_MATRIX:
264  return 0.0f; // I'm not quite sure yet what distance between two matrices means.
265  case SVGTransform::SVG_TRANSFORM_SCALE:
266  return static_cast<float>(sqrt(m_transform.a() * m_transform.a() + m_transform.d() * m_transform.d()));
267  case SVGTransform::SVG_TRANSFORM_TRANSLATE:
268  return static_cast<float>(sqrt(m_transform.e() * m_transform.e() + m_transform.f() * m_transform.f()));
269  case SVGTransform::SVG_TRANSFORM_SKEWX:
270  case SVGTransform::SVG_TRANSFORM_SKEWY:
271  return m_angle;
272  }
273  ASSERT_NOT_REACHED();
274  return 0.0f;
275 }
276 
277 }
278 
279 #endif
FloatConversion.h
FloatPoint.h
SVGTransform.h
FloatSize.h
SVGTransformDistance.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:51:22 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal