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

KHTML

  • khtml
  • platform
  • graphics
Path.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved.
3 * 2006 Rob Buis <buis@kde.org>
4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28
29#include "config.h"
30#include "wtf/Platform.h"
31#include "Path.h"
32
33#include "FloatPoint.h"
34#include "FloatRect.h"
35#include "PathTraversalState.h"
36#include <math.h>
37#include <wtf/MathExtras.h>
38
39const float QUARTER = 0.552f; // approximation of control point positions on a bezier
40 // to simulate a quarter of a circle.
41
42using namespace WebCore;
43
44namespace khtml {
45
46static void pathLengthApplierFunction(void* info, const PathElement* element)
47{
48 PathTraversalState& traversalState = *static_cast<PathTraversalState*>(info);
49 if (traversalState.m_success)
50 return;
51 traversalState.m_previous = traversalState.m_current;
52 FloatPoint* points = element->points;
53 float segmentLength = 0.0f;
54 switch (element->type) {
55 case PathElementMoveToPoint:
56 segmentLength = traversalState.moveTo(points[0]);
57 break;
58 case PathElementAddLineToPoint:
59 segmentLength = traversalState.lineTo(points[0]);
60 break;
61 case PathElementAddQuadCurveToPoint:
62 segmentLength = traversalState.quadraticBezierTo(points[0], points[1]);
63 break;
64 case PathElementAddCurveToPoint:
65 segmentLength = traversalState.cubicBezierTo(points[0], points[1], points[2]);
66 break;
67 case PathElementCloseSubpath:
68 segmentLength = traversalState.closeSubpath();
69 break;
70 }
71 traversalState.m_totalLength += segmentLength;
72 if ((traversalState.m_action == PathTraversalState::TraversalPointAtLength ||
73 traversalState.m_action == PathTraversalState::TraversalNormalAngleAtLength) &&
74 (traversalState.m_totalLength >= traversalState.m_desiredLength)) {
75 FloatSize change = traversalState.m_current - traversalState.m_previous;
76 float slope = atan2f(change.height(), change.width());
77
78 if (traversalState.m_action == PathTraversalState::TraversalPointAtLength) {
79 float offset = traversalState.m_desiredLength - traversalState.m_totalLength;
80 traversalState.m_current.move(offset * cosf(slope), offset * sinf(slope));
81 } else {
82 static const float rad2deg = 180.0f / piFloat;
83 traversalState.m_normalAngle = slope * rad2deg;
84 }
85
86 traversalState.m_success = true;
87 }
88}
89
90float Path::length()
91{
92 PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
93 apply(&traversalState, pathLengthApplierFunction);
94 return traversalState.m_totalLength;
95}
96
97FloatPoint Path::pointAtLength(float length, bool& ok)
98{
99 PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
100 traversalState.m_desiredLength = length;
101 apply(&traversalState, pathLengthApplierFunction);
102 ok = traversalState.m_success;
103 return traversalState.m_current;
104}
105
106float Path::normalAngleAtLength(float length, bool& ok)
107{
108 PathTraversalState traversalState(PathTraversalState::TraversalNormalAngleAtLength);
109 traversalState.m_desiredLength = length;
110 apply(&traversalState, pathLengthApplierFunction);
111 ok = traversalState.m_success;
112 return traversalState.m_normalAngle;
113}
114
115Path Path::createRoundedRectangle(const FloatRect& rectangle, const FloatSize& roundingRadii)
116{
117 Path path;
118 float x = rectangle.x();
119 float y = rectangle.y();
120 float width = rectangle.width();
121 float height = rectangle.height();
122 float rx = roundingRadii.width();
123 float ry = roundingRadii.height();
124 if (width <= 0.0f || height <= 0.0f)
125 return path;
126
127 float dx = rx, dy = ry;
128 // If rx is greater than half of the width of the rectangle
129 // then set rx to half of the width (required in SVG spec)
130 if (dx > width * 0.5f)
131 dx = width * 0.5f;
132
133 // If ry is greater than half of the height of the rectangle
134 // then set ry to half of the height (required in SVG spec)
135 if (dy > height * 0.5f)
136 dy = height * 0.5f;
137
138 path.moveTo(FloatPoint(x + dx, y));
139
140 if (dx < width * 0.5f)
141 path.addLineTo(FloatPoint(x + width - rx, y));
142
143 path.addBezierCurveTo(FloatPoint(x + width - dx * (1 - QUARTER), y), FloatPoint(x + width, y + dy * (1 - QUARTER)), FloatPoint(x + width, y + dy));
144
145 if (dy < height * 0.5)
146 path.addLineTo(FloatPoint(x + width, y + height - dy));
147
148 path.addBezierCurveTo(FloatPoint(x + width, y + height - dy * (1 - QUARTER)), FloatPoint(x + width - dx * (1 - QUARTER), y + height), FloatPoint(x + width - dx, y + height));
149
150 if (dx < width * 0.5)
151 path.addLineTo(FloatPoint(x + dx, y + height));
152
153 path.addBezierCurveTo(FloatPoint(x + dx * (1 - QUARTER), y + height), FloatPoint(x, y + height - dy * (1 - QUARTER)), FloatPoint(x, y + height - dy));
154
155 if (dy < height * 0.5)
156 path.addLineTo(FloatPoint(x, y + dy));
157
158 path.addBezierCurveTo(FloatPoint(x, y + dy * (1 - QUARTER)), FloatPoint(x + dx * (1 - QUARTER), y), FloatPoint(x + dx, y));
159
160 path.closeSubpath();
161
162 return path;
163}
164
165Path Path::createRoundedRectangle(const FloatRect& rectangle, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius)
166{
167 Path path;
168
169 float width = rectangle.width();
170 float height = rectangle.height();
171 if (width <= 0.0 || height <= 0.0)
172 return path;
173
174 if (width < topLeftRadius.width() + topRightRadius.width()
175 || width < bottomLeftRadius.width() + bottomRightRadius.width()
176 || height < topLeftRadius.height() + bottomLeftRadius.height()
177 || height < topRightRadius.height() + bottomRightRadius.height())
178 // If all the radii cannot be accommodated, return a rect.
179 return createRectangle(rectangle);
180
181 float x = rectangle.x();
182 float y = rectangle.y();
183
184 path.moveTo(FloatPoint(x + topLeftRadius.width(), y));
185
186 path.addLineTo(FloatPoint(x + width - topRightRadius.width(), y));
187
188 path.addBezierCurveTo(FloatPoint(x + width - topRightRadius.width() * (1 - QUARTER), y), FloatPoint(x + width, y + topRightRadius.height() * (1 - QUARTER)), FloatPoint(x + width, y + topRightRadius.height()));
189
190 path.addLineTo(FloatPoint(x + width, y + height - bottomRightRadius.height()));
191
192 path.addBezierCurveTo(FloatPoint(x + width, y + height - bottomRightRadius.height() * (1 - QUARTER)), FloatPoint(x + width - bottomRightRadius.width() * (1 - QUARTER), y + height), FloatPoint(x + width - bottomRightRadius.width(), y + height));
193
194 path.addLineTo(FloatPoint(x + bottomLeftRadius.width(), y + height));
195
196 path.addBezierCurveTo(FloatPoint(x + bottomLeftRadius.width() * (1 - QUARTER), y + height), FloatPoint(x, y + height - bottomLeftRadius.height() * (1 - QUARTER)), FloatPoint(x, y + height - bottomLeftRadius.height()));
197
198 path.addLineTo(FloatPoint(x, y + topLeftRadius.height()));
199
200 path.addBezierCurveTo(FloatPoint(x, y + topLeftRadius.height() * (1 - QUARTER)), FloatPoint(x + topLeftRadius.width() * (1 - QUARTER), y), FloatPoint(x + topLeftRadius.width(), y));
201
202 path.closeSubpath();
203
204 return path;
205}
206
207Path Path::createRectangle(const FloatRect& rectangle)
208{
209 Path path;
210 float x = rectangle.x();
211 float y = rectangle.y();
212 float width = rectangle.width();
213 float height = rectangle.height();
214 if (width <= 0.0f || height <= 0.0f)
215 return path;
216
217 path.moveTo(FloatPoint(x, y));
218 path.addLineTo(FloatPoint(x + width, y));
219 path.addLineTo(FloatPoint(x + width, y + height));
220 path.addLineTo(FloatPoint(x, y + height));
221 path.closeSubpath();
222
223 return path;
224}
225
226Path Path::createEllipse(const FloatPoint& center, float rx, float ry)
227{
228 float cx = center.x();
229 float cy = center.y();
230 Path path;
231 if (rx <= 0.0f || ry <= 0.0f)
232 return path;
233
234 float x = cx;
235 float y = cy;
236
237 unsigned step = 0, num = 100;
238 bool running = true;
239 while (running)
240 {
241 if (step == num)
242 {
243 running = false;
244 break;
245 }
246
247 float angle = static_cast<float>(step) / static_cast<float>(num) * 2.0f * piFloat;
248 x = cx + cosf(angle) * rx;
249 y = cy + sinf(angle) * ry;
250
251 step++;
252 if (step == 1)
253 path.moveTo(FloatPoint(x, y));
254 else
255 path.addLineTo(FloatPoint(x, y));
256 }
257
258 path.closeSubpath();
259
260 return path;
261}
262
263Path Path::createCircle(const FloatPoint& center, float r)
264{
265 return createEllipse(center, r, r);
266}
267
268Path Path::createLine(const FloatPoint& start, const FloatPoint& end)
269{
270 Path path;
271 if (start.x() == end.x() && start.y() == end.y())
272 return path;
273
274 path.moveTo(start);
275 path.addLineTo(end);
276
277 return path;
278}
279
280}
FloatPoint.h
FloatRect.h
PathTraversalState.h
QUARTER
const float QUARTER
Definition: Path.cpp:39
Path.h
WebCore::FloatPoint
Definition: FloatPoint.h:61
WebCore::FloatPoint::y
float y() const
Definition: FloatPoint.h:70
WebCore::FloatPoint::x
float x() const
Definition: FloatPoint.h:69
WebCore::FloatPoint::move
void move(float dx, float dy)
Definition: FloatPoint.h:74
WebCore::FloatRect
Definition: FloatRect.h:59
WebCore::FloatRect::width
float width() const
Definition: FloatRect.h:78
WebCore::FloatRect::height
float height() const
Definition: FloatRect.h:79
WebCore::FloatRect::y
float y() const
Definition: FloatRect.h:77
WebCore::FloatRect::x
float x() const
Definition: FloatRect.h:76
WebCore::FloatSize
Definition: FloatSize.h:48
WebCore::FloatSize::height
float height() const
Definition: FloatSize.h:57
WebCore::FloatSize::width
float width() const
Definition: FloatSize.h:56
WebCore::PathTraversalState
Definition: PathTraversalState.h:39
WebCore::PathTraversalState::m_success
bool m_success
Definition: PathTraversalState.h:58
WebCore::PathTraversalState::m_normalAngle
float m_normalAngle
Definition: PathTraversalState.h:71
WebCore::PathTraversalState::quadraticBezierTo
float quadraticBezierTo(const FloatPoint &newControl, const FloatPoint &newEnd)
Definition: PathTraversalState.cpp:180
WebCore::PathTraversalState::m_totalLength
float m_totalLength
Definition: PathTraversalState.h:65
WebCore::PathTraversalState::closeSubpath
float closeSubpath()
Definition: PathTraversalState.cpp:160
WebCore::PathTraversalState::lineTo
float lineTo(const FloatPoint &)
Definition: PathTraversalState.cpp:173
WebCore::PathTraversalState::m_desiredLength
float m_desiredLength
Definition: PathTraversalState.h:67
WebCore::PathTraversalState::m_previous
FloatPoint m_previous
Definition: PathTraversalState.h:70
WebCore::PathTraversalState::cubicBezierTo
float cubicBezierTo(const FloatPoint &newControl1, const FloatPoint &newControl2, const FloatPoint &newEnd)
Definition: PathTraversalState.cpp:193
WebCore::PathTraversalState::TraversalTotalLength
@ TraversalTotalLength
Definition: PathTraversalState.h:42
WebCore::PathTraversalState::TraversalPointAtLength
@ TraversalPointAtLength
Definition: PathTraversalState.h:43
WebCore::PathTraversalState::TraversalNormalAngleAtLength
@ TraversalNormalAngleAtLength
Definition: PathTraversalState.h:45
WebCore::PathTraversalState::m_current
FloatPoint m_current
Definition: PathTraversalState.h:60
WebCore::PathTraversalState::moveTo
float moveTo(const FloatPoint &)
Definition: PathTraversalState.cpp:167
WebCore::PathTraversalState::m_action
PathTraversalAction m_action
Definition: PathTraversalState.h:57
khtml::Path
Definition: Path.h:68
khtml::Path::addLineTo
void addLineTo(const FloatPoint &)
Definition: PathQt.cpp:97
khtml::Path::createRectangle
static Path createRectangle(const FloatRect &)
Definition: Path.cpp:207
khtml::Path::createLine
static Path createLine(const FloatPoint &, const FloatPoint &)
Definition: Path.cpp:268
khtml::Path::length
float length()
Definition: Path.cpp:90
khtml::Path::apply
void apply(void *info, PathApplierFunction) const
Definition: PathQt.cpp:224
khtml::Path::closeSubpath
void closeSubpath()
Definition: PathQt.cpp:119
khtml::Path::normalAngleAtLength
float normalAngleAtLength(float length, bool &ok)
Definition: Path.cpp:106
khtml::Path::moveTo
void moveTo(const FloatPoint &)
Definition: PathQt.cpp:92
khtml::Path::pointAtLength
FloatPoint pointAtLength(float length, bool &ok)
Definition: Path.cpp:97
khtml::Path::createRoundedRectangle
static Path createRoundedRectangle(const FloatRect &, const FloatSize &roundingRadii)
Definition: Path.cpp:115
khtml::Path::createCircle
static Path createCircle(const FloatPoint &center, float r)
Definition: Path.cpp:263
khtml::Path::addBezierCurveTo
void addBezierCurveTo(const FloatPoint &controlPoint1, const FloatPoint &controlPoint2, const FloatPoint &)
Definition: PathQt.cpp:107
khtml::Path::createEllipse
static Path createEllipse(const FloatPoint &center, float rx, float ry)
Definition: Path.cpp:226
ok
KGuiItem ok()
end
const KShortcut & end()
WebCore
Definition: CSSHelper.h:7
khtml
khtml::PathElementCloseSubpath
@ PathElementCloseSubpath
Definition: Path.h:58
khtml::PathElementAddCurveToPoint
@ PathElementAddCurveToPoint
Definition: Path.h:57
khtml::PathElementAddLineToPoint
@ PathElementAddLineToPoint
Definition: Path.h:55
khtml::PathElementAddQuadCurveToPoint
@ PathElementAddQuadCurveToPoint
Definition: Path.h:56
khtml::PathElementMoveToPoint
@ PathElementMoveToPoint
Definition: Path.h:54
khtml::pathLengthApplierFunction
static void pathLengthApplierFunction(void *info, const PathElement *element)
Definition: Path.cpp:46
khtml::PathElement
Definition: Path.h:61
khtml::PathElement::points
FloatPoint * points
Definition: Path.h:63
khtml::PathElement::type
PathElementType type
Definition: Path.h:62
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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