1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qiconengine.h" |
5 | #include "qiconengine_p.h" |
6 | #include "qpainter.h" |
7 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | /*! |
11 | \class QIconEngine |
12 | |
13 | \brief The QIconEngine class provides an abstract base class for QIcon renderers. |
14 | |
15 | \ingroup painting |
16 | \inmodule QtGui |
17 | |
18 | An icon engine provides the rendering functions for a QIcon. Each icon has a |
19 | corresponding icon engine that is responsible for drawing the icon with a |
20 | requested size, mode and state. |
21 | |
22 | The icon is rendered by the paint() function, and the icon can additionally be |
23 | obtained as a pixmap with the pixmap() function (the default implementation |
24 | simply uses paint() to achieve this). The addPixmap() function can be used to |
25 | add new pixmaps to the icon engine, and is used by QIcon to add specialized |
26 | custom pixmaps. |
27 | |
28 | The paint(), pixmap(), and addPixmap() functions are all virtual, and can |
29 | therefore be reimplemented in subclasses of QIconEngine. |
30 | |
31 | \sa QIconEnginePlugin |
32 | |
33 | */ |
34 | |
35 | /*! |
36 | \fn virtual void QIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0; |
37 | |
38 | Uses the given \a painter to paint the icon with the required \a mode and |
39 | \a state into the rectangle \a rect. |
40 | */ |
41 | |
42 | /*! Returns the actual size of the icon the engine provides for the |
43 | requested \a size, \a mode and \a state. The default implementation |
44 | returns the given \a size. |
45 | */ |
46 | QSize QIconEngine::actualSize(const QSize &size, QIcon::Mode /*mode*/, QIcon::State /*state*/) |
47 | { |
48 | return size; |
49 | } |
50 | |
51 | /*! |
52 | \since 5.6 |
53 | Constructs the icon engine. |
54 | */ |
55 | QIconEngine::QIconEngine() |
56 | { |
57 | } |
58 | |
59 | /*! |
60 | \since 5.8 |
61 | \internal |
62 | */ |
63 | QIconEngine::QIconEngine(const QIconEngine &) |
64 | { |
65 | } |
66 | |
67 | /*! |
68 | Destroys the icon engine. |
69 | */ |
70 | QIconEngine::~QIconEngine() |
71 | { |
72 | } |
73 | |
74 | |
75 | /*! |
76 | Returns the icon as a pixmap with the required \a size, \a mode, |
77 | and \a state. The default implementation creates a new pixmap and |
78 | calls paint() to fill it. |
79 | */ |
80 | QPixmap QIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) |
81 | { |
82 | QPixmap pm(size); |
83 | { |
84 | QPainter p(&pm); |
85 | paint(painter: &p, rect: QRect(QPoint(0,0),size), mode, state); |
86 | } |
87 | return pm; |
88 | } |
89 | |
90 | /*! |
91 | Called by QIcon::addPixmap(). Adds a specialized \a pixmap for the given |
92 | \a mode and \a state. The default pixmap-based engine stores any supplied |
93 | pixmaps, and it uses them instead of scaled pixmaps if the size of a pixmap |
94 | matches the size of icon requested. Custom icon engines that implement |
95 | scalable vector formats are free to ignores any extra pixmaps. |
96 | */ |
97 | void QIconEngine::addPixmap(const QPixmap &/*pixmap*/, QIcon::Mode /*mode*/, QIcon::State /*state*/) |
98 | { |
99 | } |
100 | |
101 | |
102 | /*! Called by QIcon::addFile(). Adds a specialized pixmap from the |
103 | file with the given \a fileName, \a size, \a mode and \a state. The |
104 | default pixmap-based engine stores any supplied file names, and it |
105 | loads the pixmaps on demand instead of using scaled pixmaps if the |
106 | size of a pixmap matches the size of icon requested. Custom icon |
107 | engines that implement scalable vector formats are free to ignores |
108 | any extra files. |
109 | */ |
110 | void QIconEngine::addFile(const QString &/*fileName*/, const QSize &/*size*/, QIcon::Mode /*mode*/, QIcon::State /*state*/) |
111 | { |
112 | } |
113 | |
114 | |
115 | /*! |
116 | \enum QIconEngine::IconEngineHook |
117 | \since 4.5 |
118 | |
119 | These enum values are used for virtual_hook() to allow additional |
120 | queries to icon engine without breaking binary compatibility. |
121 | |
122 | \value IsNullHook Allow to query if this engine represents a null |
123 | icon. The \a data argument of the virtual_hook() is a pointer to a |
124 | bool that can be set to true if the icon is null. This enum value |
125 | was added in Qt 5.7. |
126 | |
127 | \value ScaledPixmapHook Provides a way to get a pixmap that is scaled |
128 | according to the given scale (typically equal to the \l {High |
129 | DPI}{device pixel ratio}). The \a data argument of the virtual_hook() |
130 | function is a \l ScaledPixmapArgument pointer that contains both the input and |
131 | output arguments. This enum value was added in Qt 5.9. |
132 | |
133 | \sa virtual_hook() |
134 | */ |
135 | |
136 | /*! |
137 | \class QIconEngine::ScaledPixmapArgument |
138 | \since 5.9 |
139 | |
140 | \inmodule QtGui |
141 | |
142 | This struct represents arguments to the virtual_hook() function when |
143 | the \a id parameter is QIconEngine::ScaledPixmapHook. |
144 | |
145 | The struct provides a way for icons created via \l QIcon::fromTheme() |
146 | to return pixmaps that are designed for the current \l {High |
147 | DPI}{device pixel ratio}. The scale for such an icon is specified |
148 | using the \l {Icon Theme Specification - Directory Layout}{Scale directory key} |
149 | in the appropriate \c index.theme file. |
150 | |
151 | Icons created via other approaches will return the same result as a call to |
152 | \l pixmap() would, and continue to benefit from Qt's \l {High Resolution |
153 | Versions of Images}{"@nx" high DPI syntax}. |
154 | |
155 | \sa virtual_hook(), QIconEngine::IconEngineHook, {High DPI Icons} |
156 | */ |
157 | |
158 | /*! |
159 | \variable QIconEngine::ScaledPixmapArgument::size |
160 | \brief The requested size of the pixmap. |
161 | */ |
162 | |
163 | /*! |
164 | \variable QIconEngine::ScaledPixmapArgument::mode |
165 | \brief The requested mode of the pixmap. |
166 | |
167 | \sa QIcon::Mode |
168 | */ |
169 | |
170 | /*! |
171 | \variable QIconEngine::ScaledPixmapArgument::state |
172 | \brief The requested state of the pixmap. |
173 | |
174 | \sa QIcon::State |
175 | */ |
176 | |
177 | /*! |
178 | \variable QIconEngine::ScaledPixmapArgument::scale |
179 | \brief The requested scale of the pixmap. |
180 | */ |
181 | |
182 | /*! |
183 | \variable QIconEngine::ScaledPixmapArgument::pixmap |
184 | |
185 | \brief The pixmap that is the best match for the given \l size, \l mode, \l |
186 | state, and \l scale. This is an output parameter that is set after calling |
187 | \l virtual_hook(). |
188 | */ |
189 | |
190 | |
191 | /*! |
192 | Returns a key that identifies this icon engine. |
193 | */ |
194 | QString QIconEngine::key() const |
195 | { |
196 | return QString(); |
197 | } |
198 | |
199 | /*! \fn QIconEngine *QIconEngine::clone() const |
200 | |
201 | Reimplement this method to return a clone of this icon engine. |
202 | */ |
203 | |
204 | /*! |
205 | Reads icon engine contents from the QDataStream \a in. Returns |
206 | true if the contents were read; otherwise returns \c false. |
207 | |
208 | QIconEngine's default implementation always return false. |
209 | */ |
210 | bool QIconEngine::read(QDataStream &) |
211 | { |
212 | return false; |
213 | } |
214 | |
215 | /*! |
216 | Writes the contents of this engine to the QDataStream \a out. |
217 | Returns \c true if the contents were written; otherwise returns \c false. |
218 | |
219 | QIconEngine's default implementation always return false. |
220 | */ |
221 | bool QIconEngine::write(QDataStream &) const |
222 | { |
223 | return false; |
224 | } |
225 | |
226 | /*! |
227 | \since 4.5 |
228 | |
229 | Additional method to allow extending QIconEngine without |
230 | adding new virtual methods (and without breaking binary compatibility). |
231 | The actual action and format of \a data depends on \a id argument |
232 | which is in fact a constant from IconEngineHook enum. |
233 | |
234 | \sa IconEngineHook |
235 | */ |
236 | void QIconEngine::virtual_hook(int id, void *data) |
237 | { |
238 | switch (id) { |
239 | case QIconEngine::ScaledPixmapHook: { |
240 | // We don't have any notion of scale besides "@nx", so just call pixmap() here. |
241 | QIconEngine::ScaledPixmapArgument &arg = |
242 | *reinterpret_cast<QIconEngine::ScaledPixmapArgument*>(data); |
243 | arg.pixmap = pixmap(size: arg.size, mode: arg.mode, state: arg.state); |
244 | break; |
245 | } |
246 | default: |
247 | break; |
248 | } |
249 | } |
250 | |
251 | /*! |
252 | \since 4.5 |
253 | |
254 | Returns sizes of all images that are contained in the engine for the |
255 | specific \a mode and \a state. |
256 | */ |
257 | QList<QSize> QIconEngine::availableSizes(QIcon::Mode /*mode*/, QIcon::State /*state*/) |
258 | { |
259 | return {}; |
260 | } |
261 | |
262 | /*! |
263 | \since 4.7 |
264 | |
265 | Returns the name used to create the engine, if available. |
266 | */ |
267 | QString QIconEngine::iconName() |
268 | { |
269 | return QString(); |
270 | } |
271 | |
272 | /*! |
273 | \since 5.7 |
274 | |
275 | Returns true if this icon engine represent a null QIcon. |
276 | |
277 | \include qiconengine-virtualhookhelper.qdocinc |
278 | */ |
279 | bool QIconEngine::isNull() |
280 | { |
281 | bool isNull = false; |
282 | virtual_hook(id: QIconEngine::IsNullHook, data: &isNull); |
283 | return isNull; |
284 | } |
285 | |
286 | /*! |
287 | \since 5.9 |
288 | |
289 | Returns a pixmap for the given \a size, \a mode, \a state and \a scale. |
290 | |
291 | The \a scale argument is typically equal to the \l {High DPI} |
292 | {device pixel ratio} of the display. |
293 | |
294 | \include qiconengine-virtualhookhelper.qdocinc |
295 | |
296 | \note Some engines may cast \a scale to an integer. |
297 | |
298 | \sa ScaledPixmapArgument |
299 | */ |
300 | QPixmap QIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) |
301 | { |
302 | ScaledPixmapArgument arg; |
303 | arg.size = size; |
304 | arg.mode = mode; |
305 | arg.state = state; |
306 | arg.scale = scale; |
307 | const_cast<QIconEngine *>(this)->virtual_hook(id: QIconEngine::ScaledPixmapHook, data: reinterpret_cast<void*>(&arg)); |
308 | return arg.pixmap; |
309 | } |
310 | |
311 | |
312 | // ------- QProxyIconEngine ----- |
313 | |
314 | void QProxyIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) |
315 | { |
316 | proxiedEngine()->paint(painter, rect, mode, state); |
317 | } |
318 | |
319 | QSize QProxyIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) |
320 | { |
321 | return proxiedEngine()->actualSize(size, mode, state); |
322 | } |
323 | |
324 | QPixmap QProxyIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) |
325 | { |
326 | return proxiedEngine()->pixmap(size, mode, state); |
327 | } |
328 | |
329 | void QProxyIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state) |
330 | { |
331 | proxiedEngine()->addPixmap(pixmap, mode, state); |
332 | } |
333 | |
334 | void QProxyIconEngine::addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state) |
335 | { |
336 | proxiedEngine()->addFile(fileName, size, mode, state); |
337 | } |
338 | |
339 | QString QProxyIconEngine::key() const |
340 | { |
341 | return proxiedEngine()->key(); |
342 | } |
343 | |
344 | QIconEngine *QProxyIconEngine::clone() const |
345 | { |
346 | return proxiedEngine()->clone(); |
347 | } |
348 | |
349 | bool QProxyIconEngine::read(QDataStream &in) |
350 | { |
351 | return proxiedEngine()->read(in); |
352 | } |
353 | |
354 | bool QProxyIconEngine::write(QDataStream &out) const |
355 | { |
356 | return proxiedEngine()->write(out); |
357 | } |
358 | |
359 | QList<QSize> QProxyIconEngine::availableSizes(QIcon::Mode mode, QIcon::State state) |
360 | { |
361 | return proxiedEngine()->availableSizes(mode, state); |
362 | } |
363 | |
364 | QString QProxyIconEngine::iconName() |
365 | { |
366 | return proxiedEngine()->iconName(); |
367 | } |
368 | |
369 | bool QProxyIconEngine::isNull() |
370 | { |
371 | return proxiedEngine()->isNull(); |
372 | } |
373 | |
374 | QPixmap QProxyIconEngine::scaledPixmap(const QSize &size, QIcon::Mode mode, QIcon::State state, qreal scale) |
375 | { |
376 | return proxiedEngine()->scaledPixmap(size, mode, state, scale); |
377 | } |
378 | |
379 | void QProxyIconEngine::virtual_hook(int id, void *data) |
380 | { |
381 | proxiedEngine()->virtual_hook(id, data); |
382 | } |
383 | |
384 | |
385 | QT_END_NAMESPACE |
386 | |