79c87e626ef41c39cb157e1dc669b5c1fe8c7cdf
[WebKit-https.git] / WebCore / platform / graphics / svg / qt / SVGResourceClipperQt.cpp
1 /*
2     Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <wildfox@kde.org>
3                   2004, 2005, 2006 Rob Buis <buis@kde.org>
4                   2005 Apple Computer, Inc.
5
6     This file is part of the KDE project
7
8     This library is free software; you can redistribute it and/or
9     modify it under the terms of the GNU Library General Public
10     License as published by the Free Software Foundation; either
11     version 2 of the License, or (at your option) any later version.
12
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Library General Public License for more details.
17
18     You should have received a copy of the GNU Library General Public License
19     aint with this library; see the file COPYING.LIB.  If not, write to
20     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21     Boston, MA 02111-1307, USA.
22 */
23
24 #include "config.h"
25 #include "SVGResourceClipper.h"
26
27 #include "KRenderingDeviceQt.h"
28
29 namespace WebCore {
30
31 void SVGResourceClipper::applyClip(const FloatRect& boundingBox) const
32 {
33     KRenderingDeviceContext* context = renderingDevice()->currentContext();
34     KRenderingDeviceContextQt* qtContext = static_cast<KRenderingDeviceContextQt*>(context);
35     if (m_clipData.count() < 1)
36         return;
37
38     context->clearPath();
39
40     QPainterPath newPath;
41
42     bool heterogenousClipRules = false;
43     WindRule clipRule = m_clipData[0].windRule;
44
45     for (unsigned int x = 0; x < m_clipData.count(); x++) {
46         ClipData clipData = m_clipData[x];
47         if (clipData.windRule != clipRule)
48             heterogenousClipRules = true;
49        
50         QPainterPath path = *(clipData.path.platformPath());
51         if (path.isEmpty())
52             continue;
53
54         if (!newPath.isEmpty())
55             newPath.closeSubpath();
56
57         // Respect clipping units...
58         QMatrix transform;
59
60         if (clipData.bboxUnits) {
61             transform.translate(boundingBox.x(), boundingBox.y());
62             transform.scale(boundingBox.width(), boundingBox.height());
63         }
64
65         // TODO: support heterogenous clip rules!
66         //clipRule = (clipData.windRule() == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill);
67
68         for (int i = 0; i < path.elementCount(); ++i) {
69             const QPainterPath::Element &cur = path.elementAt(i);
70
71             switch (cur.type) {
72                 case QPainterPath::MoveToElement:
73                     newPath.moveTo(QPointF(cur.x, cur.y) * transform);
74                     break;
75                 case QPainterPath::LineToElement:
76                     newPath.lineTo(QPointF(cur.x, cur.y) * transform);
77                     break;
78                 case QPainterPath::CurveToElement:
79                 {
80                     const QPainterPath::Element &c1 = path.elementAt(i + 1);
81                     const QPainterPath::Element &c2 = path.elementAt(i + 2);
82
83                     Q_ASSERT(c1.type == QPainterPath::CurveToDataElement);
84                     Q_ASSERT(c2.type == QPainterPath::CurveToDataElement);
85
86                     newPath.cubicTo(QPointF(cur.x, cur.y) * transform,
87                                     QPointF(c1.x, c1.y) * transform,
88                                     QPointF(c2.x, c2.y) * transform);
89
90                     i += 2;
91                     break;
92                 }
93                 case QPainterPath::CurveToDataElement:
94                     Q_ASSERT(false);
95                     break;
96             }
97         }
98     }
99
100     if (m_clipData.count()) {
101         // FIXME!
102         // We don't currently allow for heterogenous clip rules.
103         // we would have to detect such, draw to a mask, and then clip
104         // to that mask
105         // if (!CGContextIsPathEmpty(cgContext)) {
106             if (clipRule == RULE_EVENODD)
107                 newPath.setFillRule(Qt::OddEvenFill);
108             else
109                 newPath.setFillRule(Qt::WindingFill);
110         // }
111     }
112
113     qtContext->painter().setClipPath(newPath);
114 }
115
116 } // namespace WebCore
117
118 // vim:ts=4:noet
119 /*
120     Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <wildfox@kde.org>
121                   2004, 2005, 2006 Rob Buis <buis@kde.org>
122                   2005 Apple Computer, Inc.
123
124     This file is part of the KDE project
125
126     This library is free software; you can redistribute it and/or
127     modify it under the terms of the GNU Library General Public
128     License as published by the Free Software Foundation; either
129     version 2 of the License, or (at your option) any later version.
130
131     This library is distributed in the hope that it will be useful,
132     but WITHOUT ANY WARRANTY; without even the implied warranty of
133     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
134     Library General Public License for more details.
135
136     You should have received a copy of the GNU Library General Public License
137     aint with this library; see the file COPYING.LIB.  If not, write to
138     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
139     Boston, MA 02111-1307, USA.
140 */
141
142 #include "config.h"
143
144 #include "KCanvasClipperQt.h"
145 #include "KRenderingDeviceQt.h"
146
147 namespace WebCore {
148
149 void KCanvasClipperQt::applyClip(const FloatRect& boundingBox) const
150 {
151     KRenderingDeviceContext* context = renderingDevice()->currentContext();
152     KRenderingDeviceContextQt* qtContext = static_cast<KRenderingDeviceContextQt*>(context);
153     if (m_clipData.count() < 1)
154         return;
155
156     context->clearPath();
157
158     QPainterPath newPath;
159
160     bool heterogenousClipRules = false;
161     WindRule clipRule = m_clipData[0].windRule();
162
163     for (unsigned int x = 0; x < m_clipData.count(); x++) {
164         KCClipData clipData = m_clipData[x];
165         if (clipData.windRule() != clipRule)
166             heterogenousClipRules = true;
167        
168         QPainterPath path = *(clipData.path.platformPath());
169         if (path.isEmpty())
170             continue;
171
172         if (!newPath.isEmpty())
173             newPath.closeSubpath();
174
175         // Respect clipping units...
176         QMatrix transform;
177
178         if (clipData.bboxUnits) {
179             transform.translate(boundingBox.x(), boundingBox.y());
180             transform.scale(boundingBox.width(), boundingBox.height());
181         }
182
183         // TODO: support heterogenous clip rules!
184         //clipRule = (clipData.windRule() == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill);
185
186         for (int i = 0; i < path.elementCount(); ++i) {
187             const QPainterPath::Element &cur = path.elementAt(i);
188
189             switch (cur.type) {
190                 case QPainterPath::MoveToElement:
191                     newPath.moveTo(QPointF(cur.x, cur.y) * transform);
192                     break;
193                 case QPainterPath::LineToElement:
194                     newPath.lineTo(QPointF(cur.x, cur.y) * transform);
195                     break;
196                 case QPainterPath::CurveToElement:
197                 {
198                     const QPainterPath::Element &c1 = path.elementAt(i + 1);
199                     const QPainterPath::Element &c2 = path.elementAt(i + 2);
200
201                     Q_ASSERT(c1.type == QPainterPath::CurveToDataElement);
202                     Q_ASSERT(c2.type == QPainterPath::CurveToDataElement);
203
204                     newPath.cubicTo(QPointF(cur.x, cur.y) * transform,
205                                     QPointF(c1.x, c1.y) * transform,
206                                     QPointF(c2.x, c2.y) * transform);
207
208                     i += 2;
209                     break;
210                 }
211                 case QPainterPath::CurveToDataElement:
212                     Q_ASSERT(false);
213                     break;
214             }
215         }
216     }
217
218     if (m_clipData.count()) {
219         // FIXME!
220         // We don't currently allow for heterogenous clip rules.
221         // we would have to detect such, draw to a mask, and then clip
222         // to that mask
223         // if (!CGContextIsPathEmpty(cgContext)) {
224             if (clipRule == RULE_EVENODD)
225                 newPath.setFillRule(Qt::OddEvenFill);
226             else
227                 newPath.setFillRule(Qt::WindingFill);
228         // }
229     }
230
231     qtContext->painter().setClipPath(newPath);
232 }
233
234 }
235
236 // vim:ts=4:noet