1 | /* |
2 | * Copyright 2006-2007 Aaron Seigo <aseigo@kde.org> |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU Library General Public License as |
6 | * published by the Free Software Foundation; either version 2, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details |
13 | * |
14 | * You should have received a copy of the GNU Library General Public |
15 | * License along with this program; if not, write to the |
16 | * Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #ifndef PLASMA_SVG_H |
21 | #define PLASMA_SVG_H |
22 | |
23 | #include <QtCore/QObject> |
24 | #include <QtGui/QPixmap> |
25 | |
26 | #include <plasma/plasma_export.h> |
27 | |
28 | class QPainter; |
29 | class QPoint; |
30 | class QPointF; |
31 | class QRect; |
32 | class QRectF; |
33 | class QSize; |
34 | class QSizeF; |
35 | class QMatrix; |
36 | |
37 | namespace Plasma |
38 | { |
39 | |
40 | class FrameSvgPrivate; |
41 | class SvgPrivate; |
42 | class Theme; |
43 | |
44 | /** |
45 | * @class Svg plasma/svg.h <Plasma/Svg> |
46 | * |
47 | * @short A theme aware image-centric SVG class |
48 | * |
49 | * Plasma::Svg provides a class for rendering SVG images to a QPainter in a |
50 | * convenient manner. Unless an absolute path to a file is provided, it loads |
51 | * the SVG document using Plasma::Theme. It also provides a number of internal |
52 | * optimizations to help lower the cost of painting SVGs, such as caching. |
53 | * |
54 | * @see Plasma::FrameSvg |
55 | **/ |
56 | class PLASMA_EXPORT Svg : public QObject |
57 | { |
58 | Q_OBJECT |
59 | Q_ENUMS(ContentType) |
60 | Q_PROPERTY(QSize size READ size WRITE resize NOTIFY sizeChanged) |
61 | Q_PROPERTY(bool multipleImages READ containsMultipleImages WRITE setContainsMultipleImages) |
62 | Q_PROPERTY(QString imagePath READ imagePath WRITE setImagePath) |
63 | Q_PROPERTY(bool usingRenderingCache READ isUsingRenderingCache WRITE setUsingRenderingCache) |
64 | |
65 | public: |
66 | /** |
67 | * Constructs an SVG object that implicitly shares and caches rendering. |
68 | * |
69 | * Unlike QSvgRenderer, which this class uses internally, |
70 | * Plasma::Svg represents an image generated from an SVG. As such, it |
71 | * has a related size and transform matrix (the latter being provided |
72 | * by the painter used to paint the image). |
73 | * |
74 | * The size is initialized to be the SVG's native size. |
75 | * |
76 | * @param parent options QObject to parent this to |
77 | * |
78 | * @related Plasma::Theme |
79 | */ |
80 | explicit Svg(QObject *parent = 0); |
81 | ~Svg(); |
82 | |
83 | /** |
84 | * Returns a pixmap of the SVG represented by this object. |
85 | * |
86 | * The size of the pixmap will be the size of this Svg object (size()) |
87 | * if containsMultipleImages is @c true; otherwise, it will be the |
88 | * size of the requested element after the whole SVG has been scaled |
89 | * to size(). |
90 | * |
91 | * @param elementId the ID string of the element to render, or an empty |
92 | * string for the whole SVG (the default) |
93 | * @return a QPixmap of the rendered SVG |
94 | */ |
95 | Q_INVOKABLE QPixmap pixmap(const QString &elementID = QString()); |
96 | |
97 | /** |
98 | * Paints all or part of the SVG represented by this object |
99 | * |
100 | * The size of the painted area will be the size of this Svg object |
101 | * (size()) if containsMultipleImages is @c true; otherwise, it will |
102 | * be the size of the requested element after the whole SVG has been |
103 | * scaled to size(). |
104 | * |
105 | * @param painter the QPainter to use |
106 | * @param point the position to start drawing; the entire svg will be |
107 | * drawn starting at this point. |
108 | * @param elementId the ID string of the element to render, or an empty |
109 | * string for the whole SVG (the default) |
110 | */ |
111 | Q_INVOKABLE void paint(QPainter *painter, const QPointF &point, |
112 | const QString &elementID = QString()); |
113 | |
114 | /** |
115 | * Paints all or part of the SVG represented by this object |
116 | * |
117 | * The size of the painted area will be the size of this Svg object |
118 | * (size()) if containsMultipleImages is @c true; otherwise, it will |
119 | * be the size of the requested element after the whole SVG has been |
120 | * scaled to size(). |
121 | * |
122 | * @param painter the QPainter to use |
123 | * @param x the horizontal coordinate to start painting from |
124 | * @param y the vertical coordinate to start painting from |
125 | * @param elementId the ID string of the element to render, or an empty |
126 | * string for the whole SVG (the default) |
127 | */ |
128 | Q_INVOKABLE void paint(QPainter *painter, int x, int y, |
129 | const QString &elementID = QString()); |
130 | |
131 | /** |
132 | * Paints all or part of the SVG represented by this object |
133 | * |
134 | * @param painter the QPainter to use |
135 | * @param rect the rect to draw into; if smaller than the current size |
136 | * the drawing is starting at this point. |
137 | * @param elementId the ID string of the element to render, or an empty |
138 | * string for the whole SVG (the default) |
139 | */ |
140 | Q_INVOKABLE void paint(QPainter *painter, const QRectF &rect, |
141 | const QString &elementID = QString()); |
142 | |
143 | /** |
144 | * Paints all or part of the SVG represented by this object |
145 | * |
146 | * @param painter the QPainter to use |
147 | * @param x the horizontal coordinate to start painting from |
148 | * @param y the vertical coordinate to start painting from |
149 | * @param width the width of the element to draw |
150 | * @param height the height of the element do draw |
151 | * @param elementId the ID string of the element to render, or an empty |
152 | * string for the whole SVG (the default) |
153 | */ |
154 | Q_INVOKABLE void paint(QPainter *painter, int x, int y, int width, |
155 | int height, const QString &elementID = QString()); |
156 | |
157 | /** |
158 | * The size of the SVG. |
159 | * |
160 | * If the SVG has been resized with resize(), that size will be |
161 | * returned; otherwise, the natural size of the SVG will be returned. |
162 | * |
163 | * If containsMultipleImages is @c true, each element of the SVG |
164 | * will be rendered at this size by default. |
165 | * |
166 | * @return the current size of the SVG |
167 | **/ |
168 | QSize size() const; |
169 | |
170 | /** |
171 | * Resizes the rendered image. |
172 | * |
173 | * Rendering will actually take place on the next call to paint. |
174 | * |
175 | * If containsMultipleImages is @c true, each element of the SVG |
176 | * will be rendered at this size by default; otherwise, the entire |
177 | * image will be scaled to this size and each element will be |
178 | * scaled appropriately. |
179 | * |
180 | * @param width the new width |
181 | * @param height the new height |
182 | **/ |
183 | Q_INVOKABLE void resize(qreal width, qreal height); |
184 | |
185 | /** |
186 | * Resizes the rendered image. |
187 | * |
188 | * Rendering will actually take place on the next call to paint. |
189 | * |
190 | * If containsMultipleImages is @c true, each element of the SVG |
191 | * will be rendered at this size by default; otherwise, the entire |
192 | * image will be scaled to this size and each element will be |
193 | * scaled appropriately. |
194 | * |
195 | * @param size the new size of the image |
196 | **/ |
197 | Q_INVOKABLE void resize(const QSizeF &size); |
198 | |
199 | /** |
200 | * Resizes the rendered image to the natural size of the SVG. |
201 | * |
202 | * Rendering will actually take place on the next call to paint. |
203 | **/ |
204 | Q_INVOKABLE void resize(); |
205 | |
206 | /** |
207 | * Find the size of a given element. |
208 | * |
209 | * This is the size of the element with ID @p elementId after the SVG |
210 | * has been scaled (see resize()). Note that this is unaffected by |
211 | * the containsMultipleImages property. |
212 | * |
213 | * @param elementId the id of the element to check |
214 | * @return the size of a given element, given the current size of the SVG |
215 | **/ |
216 | Q_INVOKABLE QSize elementSize(const QString &elementId) const; |
217 | |
218 | /** |
219 | * The bounding rect of a given element. |
220 | * |
221 | * This is the bounding rect of the element with ID @p elementId after |
222 | * the SVG has been scaled (see resize()). Note that this is |
223 | * unaffected by the containsMultipleImages property. |
224 | * |
225 | * @param elementId the id of the element to check |
226 | * @return the current rect of a given element, given the current size of the SVG |
227 | **/ |
228 | Q_INVOKABLE QRectF elementRect(const QString &elementId) const; |
229 | |
230 | /** |
231 | * Check whether an element exists in the loaded SVG. |
232 | * |
233 | * @param elementId the id of the element to check for |
234 | * @return @c true if the element is defined in the SVG, otherwise @c false |
235 | **/ |
236 | Q_INVOKABLE bool hasElement(const QString &elementId) const; |
237 | |
238 | /** |
239 | * Returns the element (by id) at the given point. |
240 | * |
241 | * An empty string is returned if there no element is at @p point. |
242 | * |
243 | * NOTE: not implemented! This will currently return an empty string! |
244 | * |
245 | * @param point a point in SVG co-ordinates |
246 | * @return an empty string |
247 | */ |
248 | Q_INVOKABLE QString elementAtPoint(const QPoint &point) const; |
249 | |
250 | /** |
251 | * Check whether this object is backed by a valid SVG file. |
252 | * |
253 | * This method can be expensive as it causes disk access. |
254 | * |
255 | * @return @c true if the SVG file exists and the document is valid, |
256 | * otherwise @c false. |
257 | **/ |
258 | Q_INVOKABLE bool isValid() const; |
259 | |
260 | /** |
261 | * Set whether the SVG contains a single image or multiple ones. |
262 | * |
263 | * If this is set to @c true, the SVG will be treated as a |
264 | * collection of related images, rather than a consistent |
265 | * drawing. |
266 | * |
267 | * In particular, when individual elements are rendered, this |
268 | * affects whether the elements are resized to size() by default. |
269 | * See paint() and pixmap(). |
270 | * |
271 | * @param multiple true if the svg contains multiple images |
272 | */ |
273 | void setContainsMultipleImages(bool multiple); |
274 | |
275 | /** |
276 | * Whether the SVG contains multiple images. |
277 | * |
278 | * If this is @c true, the SVG will be treated as a |
279 | * collection of related images, rather than a consistent |
280 | * drawing. |
281 | * |
282 | * @return @c true if the SVG will be treated as containing |
283 | * multiple images, @c false if it will be treated |
284 | * as a coherent image. |
285 | */ |
286 | bool containsMultipleImages() const; |
287 | |
288 | /** |
289 | * Set the SVG file to render. |
290 | * |
291 | * Relative paths are looked for in the current Plasma theme, |
292 | * and should not include the file extension (.svg and .svgz |
293 | * files will be searched for). See Theme::imagePath(). |
294 | * |
295 | * If the parent object of this Svg is a Plasma::Applet, |
296 | * relative paths will be searched for in the applet's package |
297 | * first. |
298 | * |
299 | * @param svgFilePath either an absolute path to an SVG file, or |
300 | * an image name |
301 | */ |
302 | void setImagePath(const QString &svgFilePath); |
303 | |
304 | /** |
305 | * The SVG file to render. |
306 | * |
307 | * If this SVG is themed, this will be a relative path, and will not |
308 | * include a file extension. |
309 | * |
310 | * @return either an absolute path to an SVG file, or an image name |
311 | * @see Theme::imagePath() |
312 | */ |
313 | QString imagePath() const; |
314 | |
315 | /** |
316 | * Sets whether or not to cache the results of rendering to pixmaps. |
317 | * |
318 | * If the SVG is resized and re-rendered often (and does not keep using the |
319 | * same small set of pixmap dimensions), then it may be less efficient to do |
320 | * disk caching. A good example might be a progress meter that uses an Svg |
321 | * object to paint itself: the meter will be changing often enough, with |
322 | * enough unpredictability and without re-use of the previous pixmaps to |
323 | * not get a gain from caching. |
324 | * |
325 | * Most Svg objects should use the caching feature, however. |
326 | * Therefore, the default is to use the render cache. |
327 | * |
328 | * @param useCache true to cache rendered pixmaps |
329 | * @since 4.3 |
330 | */ |
331 | void setUsingRenderingCache(bool useCache); |
332 | |
333 | /** |
334 | * Whether the rendering cache is being used. |
335 | * |
336 | * @return @c true if the Svg object is using caching for rendering results |
337 | * @since 4.3 |
338 | */ |
339 | bool isUsingRenderingCache() const; |
340 | |
341 | /** |
342 | * Sets the Plasma::Theme to use with this Svg object. |
343 | * |
344 | * By default, Svg objects use Plasma::Theme::default(). |
345 | * |
346 | * This determines how relative image paths are interpreted. |
347 | * |
348 | * @param theme the theme object to use |
349 | * @since 4.3 |
350 | */ |
351 | void setTheme(Plasma::Theme *theme); |
352 | |
353 | /** |
354 | * The Plasma::Theme used by this Svg object. |
355 | * |
356 | * This determines how relative image paths are interpreted. |
357 | * |
358 | * @return the theme used by this Svg |
359 | */ |
360 | Theme *theme() const; |
361 | |
362 | Q_SIGNALS: |
363 | /** |
364 | * Emitted whenever the SVG data has changed in such a way that a repaint is required. |
365 | * Any usage of an Svg object that does the painting itself must connect to this signal |
366 | * and respond by updating the painting. Note that connected to Theme::themeChanged is |
367 | * incorrect in such a use case as the Svg itself may not be updated yet nor may theme |
368 | * change be the only case when a repaint is needed. Also note that classes or QML code |
369 | * which take Svg objects as parameters for their own painting all respond to this signal |
370 | * so that in those cases manually responding to the signal is unnecessary; ONLY when |
371 | * direct, manual painting with an Svg object is done in application code is this signal |
372 | * used. |
373 | */ |
374 | void repaintNeeded(); |
375 | |
376 | /** |
377 | * Emitted whenever the size of the Svg is changed. @see resize() |
378 | */ |
379 | void sizeChanged(); |
380 | |
381 | private: |
382 | SvgPrivate *const d; |
383 | |
384 | Q_PRIVATE_SLOT(d, void themeChanged()) |
385 | Q_PRIVATE_SLOT(d, void colorsChanged()) |
386 | |
387 | friend class SvgPrivate; |
388 | friend class FrameSvgPrivate; |
389 | friend class FrameSvg; |
390 | }; |
391 | |
392 | } // Plasma namespace |
393 | |
394 | #endif // multiple inclusion guard |
395 | |
396 | |