Reviewed by Hyatt.
[WebKit-https.git] / WebCore / kcanvas / KCanvasResources.cpp
1 /*
2     Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3                   2004, 2005 Rob Buis <buis@kde.org>
4
5     This file is part of the KDE project
6
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16
17     You should have received a copy of the GNU Library General Public License
18     aint with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20     Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24 #if SVG_SUPPORT
25 #include "KCanvasResources.h"
26
27 #include "Document.h"
28 #include "GraphicsContext.h"
29 #include "IntRect.h"
30 #include "KCanvasContainer.h"
31 #include "KCanvasImage.h"
32 #include "KCanvasMatrix.h"
33 #include "KCanvasTreeDebug.h"
34 #include "KRenderingDevice.h"
35 #include "RenderPath.h"
36 #include "SVGStyledElement.h"
37 #include "KWQTextStream.h"
38
39 namespace WebCore {
40
41 QTextStream &operator<<(QTextStream &ts, const WebCore::KCanvasResource &r) 
42
43     return r.externalRepresentation(ts); 
44 }
45
46 // KCanvasResource
47 KCanvasResource::KCanvasResource()
48 {
49 }
50
51 KCanvasResource::~KCanvasResource()
52 {
53 }
54
55 void KCanvasResource::addClient(const RenderPath *item)
56 {
57     if(m_clients.find(item) != m_clients.end())
58         return;
59
60     m_clients.append(item);
61 }
62
63 const KCanvasItemList &KCanvasResource::clients() const
64 {
65     return m_clients;
66 }
67
68 void KCanvasResource::invalidate()
69 {
70     KCanvasItemList::ConstIterator it = m_clients.begin();
71     KCanvasItemList::ConstIterator end = m_clients.end();
72
73     for(; it != end; ++it)
74         const_cast<RenderPath *>(*it)->repaint();
75 }
76
77 DeprecatedString KCanvasResource::idInRegistry() const
78 {
79     return registryId;
80 }
81
82 void KCanvasResource::setIdInRegistry(const DeprecatedString& newId)
83 {
84     registryId = newId;
85
86
87 QTextStream& KCanvasResource::externalRepresentation(QTextStream &ts) const
88 {
89     return ts;
90 }
91
92 // KCanvasClipper
93 KCanvasClipper::KCanvasClipper() : KCanvasResource()
94 {
95 }
96
97 KCanvasClipper::~KCanvasClipper()
98 {
99 }
100
101 void KCanvasClipper::resetClipData()
102 {
103     m_clipData.clear();
104 }
105
106 void KCanvasClipper::addClipData(KCanvasPath* path, KCWindRule rule, bool bboxUnits)
107 {
108     m_clipData.addPath(path, rule, bboxUnits);
109 }
110
111 KCClipDataList KCanvasClipper::clipData() const
112 {
113     return m_clipData;
114 }
115
116 QTextStream& KCanvasClipper::externalRepresentation(QTextStream &ts) const
117 {
118     ts << "[type=CLIPPER]";
119     ts << " [clip data=" << clipData() << "]";
120     return ts;
121 }
122
123 // KCanvasMasker
124 KCanvasMasker::KCanvasMasker() : KCanvasResource(), m_mask(0)
125 {
126 }
127
128 KCanvasMasker::~KCanvasMasker()
129 {
130     delete m_mask;
131 }
132
133 void KCanvasMasker::setMask(KCanvasImage *mask)
134 {
135     if (m_mask != mask) {
136         delete m_mask;
137         m_mask = mask;
138     }
139 }
140
141 QTextStream& KCanvasMasker::externalRepresentation(QTextStream &ts) const
142 {
143     ts << "[type=MASKER]";
144     return ts;
145 }
146
147 // KCanvasMarker
148 KCanvasMarker::KCanvasMarker(RenderObject *marker) : KCanvasResource()
149 {
150     m_refX = 0;
151     m_refY = 0;
152     m_marker = marker;
153     setAutoAngle();
154     m_useStrokeWidth = true;
155 }
156
157 KCanvasMarker::~KCanvasMarker()
158 {
159 }
160
161 void KCanvasMarker::setMarker(RenderObject *marker)
162 {
163     m_marker = marker;
164 }
165
166 void KCanvasMarker::setRef(double refX, double refY)
167 {
168     m_refX = refX;
169     m_refY = refY;
170 }
171
172 double KCanvasMarker::refX() const
173 {
174     return m_refX;
175 }
176
177 double KCanvasMarker::refY() const
178 {
179     return m_refY;
180 }
181
182 void KCanvasMarker::setAngle(float angle)
183 {
184     m_angle = angle;
185 }
186
187 float KCanvasMarker::angle() const
188 {
189     return m_angle;
190 }
191
192 void KCanvasMarker::setAutoAngle()
193 {
194     m_angle = -1;
195 }
196
197 void KCanvasMarker::setUseStrokeWidth(bool useStrokeWidth)
198 {
199     m_useStrokeWidth = useStrokeWidth;
200 }
201
202 bool KCanvasMarker::useStrokeWidth() const
203 {
204     return m_useStrokeWidth;
205 }
206
207 void KCanvasMarker::setScale(float scaleX, float scaleY)
208 {
209     m_scaleX = scaleX;
210     m_scaleY = scaleY;
211 }
212
213 float KCanvasMarker::scaleX() const
214 {
215     return m_scaleX;
216 }
217
218 float KCanvasMarker::scaleY() const
219 {
220     return m_scaleY;
221 }
222
223 void KCanvasMarker::draw(GraphicsContext* context, const FloatRect& rect, double x, double y, double strokeWidth, double angle)
224 {
225     if(m_marker)
226     {
227         KCanvasMatrix translation;
228         translation.translate(x, y);
229
230         KCanvasMatrix rotation;
231         rotation.setOperationMode(OPS_POSTMUL);
232         rotation.translate(-m_refX, -m_refY);
233         rotation.scale(m_scaleX, m_scaleY);
234         rotation.rotate(m_angle > -1 ? m_angle : angle);
235         
236         // stroke width
237         if(m_useStrokeWidth)
238             rotation.scale(strokeWidth, strokeWidth);
239
240         // FIXME: PaintInfo should be passed into this method instead.
241         // FIXME: bounding box fractions lost
242         RenderObject::PaintInfo info(context, enclosingIntRect(rect), PaintPhaseForeground, 0, 0);
243         m_marker->setLocalTransform(rotation.multiply(translation).qmatrix());
244         static_cast<KCanvasContainer *>(m_marker)->setDrawsContents(true);
245         m_marker->paint(info, 0, 0);
246         static_cast<KCanvasContainer *>(m_marker)->setDrawsContents(false);
247     }
248 }
249
250 QTextStream& KCanvasMarker::externalRepresentation(QTextStream &ts) const
251 {
252     ts << "[type=MARKER]"
253        << " [angle=";
254     if (angle() == -1) 
255         ts << "auto" << "]";
256     else 
257         ts << angle() << "]";        
258     ts << " [ref x=" << refX() << " y=" << refY() << "]";
259     return ts;
260 }
261
262 KCanvasResource *getResourceById(Document *document, const AtomicString &id)
263 {
264     if (id.isEmpty())
265         return 0;
266     Element *element = document->getElementById(id);
267     SVGElement *svgElement = svg_dynamic_cast(element);
268     if (svgElement && svgElement->isStyled())
269         return static_cast<SVGStyledElement *>(svgElement)->canvasResource();
270     else
271         fprintf(stderr, "Failed to find resource with id: %s\n", id.deprecatedString().ascii());
272     return 0;
273 }
274
275 KCanvasMarker *getMarkerById(Document *document, const AtomicString &id)
276 {
277     KCanvasResource *resource = getResourceById(document, id);
278     if (resource && resource->isMarker())
279         return static_cast<KCanvasMarker *>(resource);
280     return 0;
281 }
282
283 KCanvasClipper *getClipperById(Document *document, const AtomicString &id)
284 {
285     KCanvasResource *resource = getResourceById(document, id);
286     if (resource && resource->isClipper())
287         return static_cast<KCanvasClipper *>(resource);
288     return 0;
289 }
290
291 KCanvasMasker *getMaskerById(Document *document, const AtomicString &id)
292 {
293     KCanvasResource *resource = getResourceById(document, id);
294     if (resource && resource->isMasker())
295         return static_cast<KCanvasMasker *>(resource);
296     return 0;
297 }
298
299 KRenderingPaintServer *getPaintServerById(Document *document, const AtomicString &id)
300 {
301     KCanvasResource *resource = getResourceById(document, id);
302     if (resource && resource->isPaintServer())
303         return static_cast<KRenderingPaintServer *>(resource);
304     return 0;
305 }
306
307 }
308
309 // vim:ts=4:noet
310 #endif // SVG_SUPPORT
311