Reviewed by Eric. Landed by rwlbuis.
[WebKit-https.git] / WebCore / platform / qt / PathQt.cpp
1 /*
2  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3  *
4  * All rights reserved.
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 #include "config.h"
29 #include "Path.h"
30
31 #include "FloatRect.h"
32 #include <QPainterPath>
33 #include <QMatrix>
34
35 #include <math.h>
36
37 namespace WebCore {
38
39 Path::Path()
40     : m_path(new QPainterPath())
41 {
42 }
43
44 Path::~Path()
45 {
46     delete m_path;
47     m_path = 0;
48 }
49
50 Path::Path(const Path& other)
51     : m_path(new QPainterPath(*other.platformPath()))
52 {
53 }
54
55 Path& Path::operator=(const Path& other)
56 {
57     if (&other != this) {
58         delete m_path;
59         m_path = new QPainterPath(*other.platformPath());
60     }
61
62     return *this;
63 }
64
65 bool Path::contains(const FloatPoint& point) const
66 {
67     return m_path->contains(point);
68 }
69
70 void Path::translate(const FloatSize& size)
71 {
72     QMatrix matrix;
73     matrix.translate(size.width(), size.height());
74     *m_path = (*m_path) * matrix;
75 }
76
77 FloatRect Path::boundingRect() const
78 {
79     return m_path->boundingRect();
80 }
81
82 void Path::moveTo(const FloatPoint& point)
83 {
84     m_path->moveTo(point);
85 }
86
87 void Path::addLineTo(const FloatPoint& p)
88 {
89     m_path->lineTo(p);
90 }
91
92 void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p)
93 {
94     m_path->quadTo(cp, p);
95 }
96
97 void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
98 {
99     m_path->cubicTo(cp1, cp2, p);
100 }
101
102 void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
103 {
104     //FIXME: busted
105     qWarning("arcTo is busted");
106     m_path->arcTo(p1.x(), p1.y(), p2.x(), p2.y(), radius, 90);
107 }
108
109 void Path::closeSubpath()
110 {
111     m_path->closeSubpath();
112 }
113
114 #define DEGREES(t) ((t) * 180.0 / M_PI)
115 void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise)
116 {
117     qreal xc = p.x();
118     qreal yc = p.y();
119     qreal radius = r;
120
121
122     //### HACK
123     // In Qt we don't switch the coordinate system for degrees
124     // and still use the 0,0 as bottom left for degrees so we need
125     // to switch
126     sar = -sar;
127     ear = -ear;
128     anticlockwise = !anticlockwise;
129     //end hack
130
131     float sa = DEGREES(sar);
132     float ea = DEGREES(ear);
133
134     double span = 0;
135
136     double xs     = xc - radius;
137     double ys     = yc - radius;
138     double width  = radius*2;
139     double height = radius*2;
140
141     if (!anticlockwise && (ea < sa))
142         span += 360;
143     else if (anticlockwise && (sa < ea))
144         span -= 360;
145
146     //### this is also due to switched coordinate system
147     // we would end up with a 0 span instead of 360
148     if (!(qFuzzyCompare(span + (ea - sa), 0.0) &&
149           qFuzzyCompare(abs(span), 360.0))) {
150         span += ea - sa;
151     }
152
153     m_path->moveTo(QPointF(xc + radius  * cos(sar),
154                           yc - radius  * sin(sar)));
155     m_path->arcTo(xs, ys, width, height, sa, span);
156 }
157
158 void Path::addRect(const FloatRect& r)
159 {
160     m_path->addRect(r.x(), r.y(), r.width(), r.height());
161 }
162
163 void Path::addEllipse(const FloatRect& r)
164 {
165     m_path->addEllipse(r.x(), r.y(), r.width(), r.height());
166 }
167
168 void Path::clear()
169 {
170     *m_path = QPainterPath();
171 }
172
173 }
174
175 // vim: ts=4 sw=4 et