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