source: trunk/src/gui/image/qpixmap.cpp@ 147

Last change on this file since 147 was 95, checked in by Dmitry A. Kuminov, 16 years ago

gui: Added OS/2 stubs for platform-specific parts of all key GUI classes. Non-key classes are temporarily disabled with QT_NO_ defines.

File size: 57.8 KB
RevLine 
[2]1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qglobal.h>
43
44#include "qpixmap.h"
45#include "qpixmapdata_p.h"
46
47#include "qbitmap.h"
48#include "qcolormap.h"
49#include "qimage.h"
50#include "qwidget.h"
51#include "qpainter.h"
52#include "qdatastream.h"
53#include "qbuffer.h"
54#include "qapplication.h"
55#include <private/qapplication_p.h>
56#include <private/qgraphicssystem_p.h>
57#include <private/qwidget_p.h>
58#include "qevent.h"
59#include "qfile.h"
60#include "qfileinfo.h"
61#include "qpixmapcache.h"
62#include "qdatetime.h"
63#include "qimagereader.h"
64#include "qimagewriter.h"
65#include "qpaintengine.h"
66#include "qthread.h"
67
68#ifdef Q_WS_MAC
69# include "private/qt_mac_p.h"
70# include "private/qpixmap_mac_p.h"
71#endif
72
73#if defined(Q_WS_X11)
74# include "qx11info_x11.h"
75# include <private/qt_x11_p.h>
76# include <private/qpixmap_x11_p.h>
77#endif
78
79#include "qpixmap_raster_p.h"
80
81QT_BEGIN_NAMESPACE
82
83// ### Qt 5: remove
84typedef void (*_qt_pixmap_cleanup_hook)(int);
85Q_GUI_EXPORT _qt_pixmap_cleanup_hook qt_pixmap_cleanup_hook = 0;
86
87// ### Qt 5: rename
88typedef void (*_qt_pixmap_cleanup_hook_64)(qint64);
89Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64 = 0;
90
91// ### Qt 5: remove
92Q_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap)
93{
94 return pixmap.cacheKey();
95}
96
97static bool qt_pixmap_thread_test()
98{
99 if (!qApp) {
100 qFatal("QPixmap: Must construct a QApplication before a QPaintDevice");
101 return false;
102 }
103#ifndef Q_WS_WIN
104 if (qApp->thread() != QThread::currentThread()) {
105 qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread");
106 return false;
107 }
108#endif
109 return true;
110}
111
112void QPixmap::init(int w, int h, Type type)
113{
114 init(w, h, int(type));
115}
116
117void QPixmap::init(int w, int h, int type)
118{
119 QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
120 if (gs)
121 data = gs->createPixmapData(static_cast<QPixmapData::PixelType>(type));
122 else
123 data = QGraphicsSystem::createDefaultPixmapData(static_cast<QPixmapData::PixelType>(type));
124
125 data->resize(w, h);
126 data->ref.ref();
127}
128
129/*!
130 \enum QPixmap::ColorMode
131
132 \compat
133
134 This enum type defines the color modes that exist for converting
135 QImage objects to QPixmap. It is provided here for compatibility
136 with earlier versions of Qt.
137
138 Use Qt::ImageConversionFlags instead.
139
140 \value Auto Select \c Color or \c Mono on a case-by-case basis.
141 \value Color Always create colored pixmaps.
142 \value Mono Always create bitmaps.
143*/
144
145/*!
146 Constructs a null pixmap.
147
148 \sa isNull()
149*/
150
151QPixmap::QPixmap()
152 : QPaintDevice()
153{
154 (void) qt_pixmap_thread_test();
155 init(0, 0, QPixmapData::PixmapType);
156}
157
158/*!
159 \fn QPixmap::QPixmap(int width, int height)
160
161 Constructs a pixmap with the given \a width and \a height. If
162 either \a width or \a height is zero, a null pixmap is
163 constructed.
164
165 \warning This will create a QPixmap with uninitialized data. Call
166 fill() to fill the pixmap with an appropriate color before drawing
167 onto it with QPainter.
168
169 \sa isNull()
170*/
171
172QPixmap::QPixmap(int w, int h)
173 : QPaintDevice()
174{
175 if (!qt_pixmap_thread_test())
176 init(0, 0, QPixmapData::PixmapType);
177 else
178 init(w, h, QPixmapData::PixmapType);
179}
180
181/*!
182 \overload
183
184 Constructs a pixmap of the given \a size.
185
186 \warning This will create a QPixmap with uninitialized data. Call
187 fill() to fill the pixmap with an appropriate color before drawing
188 onto it with QPainter.
189*/
190
191QPixmap::QPixmap(const QSize &size)
192 : QPaintDevice()
193{
194 if (!qt_pixmap_thread_test())
195 init(0, 0, QPixmapData::PixmapType);
196 else
197 init(size.width(), size.height(), QPixmapData::PixmapType);
198}
199
200/*!
201 \internal
202*/
203QPixmap::QPixmap(const QSize &s, Type type)
204{
205 if (!qt_pixmap_thread_test())
206 init(0, 0, type);
207 else
208 init(s.width(), s.height(), type);
209}
210
211/*!
212 \internal
213*/
214QPixmap::QPixmap(const QSize &s, int type)
215{
216 if (!qt_pixmap_thread_test())
217 init(0, 0, static_cast<QPixmapData::PixelType>(type));
218 else
219 init(s.width(), s.height(), static_cast<QPixmapData::PixelType>(type));
220}
221
222/*!
223 \internal
224*/
225QPixmap::QPixmap(QPixmapData *d)
226 : QPaintDevice(), data(d)
227{
228 data->ref.ref();
229}
230
231/*!
232 Constructs a pixmap from the file with the given \a fileName. If the
233 file does not exist or is of an unknown format, the pixmap becomes a
234 null pixmap.
235
236 The loader attempts to read the pixmap using the specified \a
237 format. If the \a format is not specified (which is the default),
238 the loader probes the file for a header to guess the file format.
239
240 The file name can either refer to an actual file on disk or to
241 one of the application's embedded resources. See the
242 \l{resources.html}{Resource System} overview for details on how
243 to embed images and other resource files in the application's
244 executable.
245
246 If the image needs to be modified to fit in a lower-resolution
247 result (e.g. converting from 32-bit to 8-bit), use the \a
248 flags to control the conversion.
249
250 The \a fileName, \a format and \a flags parameters are
251 passed on to load(). This means that the data in \a fileName is
252 not compiled into the binary. If \a fileName contains a relative
253 path (e.g. the filename only) the relevant file must be found
254 relative to the runtime working directory.
255
256 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
257 Image Files}
258*/
259
260QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
261 : QPaintDevice()
262{
263 init(0, 0, QPixmapData::PixmapType);
264 if (!qt_pixmap_thread_test())
265 return;
266
267 load(fileName, format, flags);
268}
269
270/*!
271 Constructs a pixmap that is a copy of the given \a pixmap.
272
273 \sa copy()
274*/
275
276QPixmap::QPixmap(const QPixmap &pixmap)
277 : QPaintDevice()
278{
279 if (!qt_pixmap_thread_test()) {
280 init(0, 0, QPixmapData::PixmapType);
281 return;
282 }
283 if (pixmap.paintingActive()) { // make a deep copy
284 data = 0;
285 operator=(pixmap.copy());
286 } else {
287 data = pixmap.data;
288 data->ref.ref();
289 }
290}
291
292/*!
293 Constructs a pixmap from the given \a xpm data, which must be a
294 valid XPM image.
295
296 Errors are silently ignored.
297
298 Note that it's possible to squeeze the XPM variable a little bit
299 by using an unusual declaration:
300
301 \snippet doc/src/snippets/code/src_gui_image_qpixmap.cpp 0
302
303 The extra \c const makes the entire definition read-only, which is
304 slightly more efficient (for example, when the code is in a shared
305 library) and ROMable when the application is to be stored in ROM.
306*/
307#ifndef QT_NO_IMAGEFORMAT_XPM
308QPixmap::QPixmap(const char * const xpm[])
309 : QPaintDevice()
310{
311 init(0, 0, QPixmapData::PixmapType);
312 if (!xpm)
313 return;
314
315 QImage image(xpm);
316 if (!image.isNull()) {
317 if (data->pixelType() == QPixmapData::BitmapType)
318 *this = QBitmap::fromImage(image);
319 else
320 *this = fromImage(image);
321 }
322}
323#endif
324
325
326/*!
327 Destroys the pixmap.
328*/
329
330QPixmap::~QPixmap()
331{
332 deref();
333}
334
335/*!
336 \internal
337*/
338int QPixmap::devType() const
339{
340 return QInternal::Pixmap;
341}
342
343/*!
344 \fn QPixmap QPixmap::copy(int x, int y, int width, int height) const
345 \overload
346
347 Returns a deep copy of the subset of the pixmap that is specified
348 by the rectangle QRect( \a x, \a y, \a width, \a height).
349*/
350
351/*!
352 \fn QPixmap QPixmap::copy(const QRect &rectangle) const
353
354 Returns a deep copy of the subset of the pixmap that is specified
355 by the given \a rectangle. For more information on deep copies,
356 see the \l {Implicit Data Sharing} documentation.
357
358 If the given \a rectangle is empty, the whole image is copied.
359
360 \sa operator=(), QPixmap(), {QPixmap#Pixmap
361 Transformations}{Pixmap Transformations}
362*/
363QPixmap QPixmap::copy(const QRect &rect) const
364{
365 if (isNull())
366 return QPixmap();
367
368 const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect;
369
370 QPixmapData *d;
371 QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem();
372 if (gs)
373 d = gs->createPixmapData(data->pixelType());
374 else
375 d = QGraphicsSystem::createDefaultPixmapData(data->pixelType());
376
377 d->copy(data, r);
378 return QPixmap(d);
379}
380
381/*!
382 Assigns the given \a pixmap to this pixmap and returns a reference
383 to this pixmap.
384
385 \sa copy(), QPixmap()
386*/
387
388QPixmap &QPixmap::operator=(const QPixmap &pixmap)
389{
390 if (paintingActive()) {
391 qWarning("QPixmap::operator=: Cannot assign to pixmap during painting");
392 return *this;
393 }
394 if (pixmap.paintingActive()) { // make a deep copy
395 *this = pixmap.copy();
396 } else {
397 pixmap.data->ref.ref(); // avoid 'x = x'
398 deref();
399 data = pixmap.data;
400 }
401 return *this;
402}
403
404/*!
405 Returns the pixmap as a QVariant.
406*/
407QPixmap::operator QVariant() const
408{
409 return QVariant(QVariant::Pixmap, this);
410}
411
412/*!
413 \fn bool QPixmap::operator!() const
414
415 Returns true if this is a null pixmap; otherwise returns false.
416
417 \sa isNull()
418*/
419
420/*!
421 \fn QPixmap::operator QImage() const
422
423 Returns the pixmap as a QImage.
424
425 Use the toImage() function instead.
426*/
427
428/*!
429 Converts the pixmap to a QImage. Returns a null image if the
430 conversion fails.
431
432 If the pixmap has 1-bit depth, the returned image will also be 1
433 bit deep. If the pixmap has 2- to 8-bit depth, the returned image
434 has 8-bit depth. If the pixmap has greater than 8-bit depth, the
435 returned image has 32-bit depth.
436
437 Note that for the moment, alpha masks on monochrome images are
438 ignored.
439
440 \sa fromImage(), {QImage#Image Formats}{Image Formats}
441*/
442QImage QPixmap::toImage() const
443{
444 if (isNull())
445 return QImage();
446
447 return data->toImage();
448}
449
450/*!
451 \fn QMatrix QPixmap::trueMatrix(const QTransform &matrix, int width, int height)
452
453 Returns the actual matrix used for transforming a pixmap with the
454 given \a width, \a height and \a matrix.
455
456 When transforming a pixmap using the transformed() function, the
457 transformation matrix is internally adjusted to compensate for
458 unwanted translation, i.e. transformed() returns the smallest
459 pixmap containing all transformed points of the original
460 pixmap. This function returns the modified matrix, which maps
461 points correctly from the original pixmap into the new pixmap.
462
463 \sa transformed(), {QPixmap#Pixmap Transformations}{Pixmap
464 Transformations}
465*/
466QTransform QPixmap::trueMatrix(const QTransform &m, int w, int h)
467{
468 return QImage::trueMatrix(m, w, h);
469}
470
471/*!
472 \overload
473
474 This convenience function loads the matrix \a m into a
475 QTransform and calls the overloaded function with the
476 QTransform and the width \a w and the height \a h.
477 */
478QMatrix QPixmap::trueMatrix(const QMatrix &m, int w, int h)
479{
480 return trueMatrix(QTransform(m), w, h).toAffine();
481}
482
483
484/*!
485 \fn bool QPixmap::isQBitmap() const
486
487 Returns true if this is a QBitmap; otherwise returns false.
488*/
489
490bool QPixmap::isQBitmap() const
491{
492 return data->type == QPixmapData::BitmapType;
493}
494
495/*!
496 \fn bool QPixmap::isNull() const
497
498 Returns true if this is a null pixmap; otherwise returns false.
499
500 A null pixmap has zero width, zero height and no contents. You
501 cannot draw in a null pixmap.
502*/
503bool QPixmap::isNull() const
504{
505 return data->width() == 0;
506}
507
508/*!
509 \fn int QPixmap::width() const
510
511 Returns the width of the pixmap.
512
513 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
514*/
515int QPixmap::width() const
516{
517 return data->width();
518}
519
520/*!
521 \fn int QPixmap::height() const
522
523 Returns the height of the pixmap.
524
525 \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
526*/
527int QPixmap::height() const
528{
529 return data->height();
530}
531
532/*!
533 \fn QSize QPixmap::size() const
534
535 Returns the size of the pixmap.
536
537 \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
538 Information}
539*/
540QSize QPixmap::size() const
541{
542 return QSize(data->width(), data->height());
543}
544
545/*!
546 \fn QRect QPixmap::rect() const
547
548 Returns the pixmap's enclosing rectangle.
549
550 \sa {QPixmap#Pixmap Information}{Pixmap Information}
551*/
552QRect QPixmap::rect() const
553{
554 return QRect(0, 0, data->width(), data->height());
555}
556
557/*!
558 \fn int QPixmap::depth() const
559
560 Returns the depth of the pixmap.
561
562 The pixmap depth is also called bits per pixel (bpp) or bit planes
563 of a pixmap. A null pixmap has depth 0.
564
565 \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
566 Information}
567*/
568int QPixmap::depth() const
569{
570 return data->depth();
571}
572
573/*!
574 \fn void QPixmap::resize(const QSize &size)
575 \overload
576 \compat
577
578 Use QPixmap::copy() instead to get the pixmap with the new size.
579
580 \oldcode
581 pixmap.resize(size);
582 \newcode
583 pixmap = pixmap.copy(QRect(QPoint(0, 0), size));
584 \endcode
585*/
586#ifdef QT3_SUPPORT
587void QPixmap::resize_helper(const QSize &s)
588{
589 int w = s.width();
590 int h = s.height();
591 if (w < 1 || h < 1) {
592 *this = QPixmap();
593 return;
594 }
595
596 if (size() == s)
597 return;
598
599 // Create new pixmap
600 QPixmap pm(QSize(w, h), data->type);
601 bool uninit = false;
602#if defined(Q_WS_X11)
603 QX11PixmapData *x11Data = data->classId() == QPixmapData::X11Class ? static_cast<QX11PixmapData*>(data) : 0;
604 if (x11Data) {
605 pm.x11SetScreen(x11Data->xinfo.screen());
606 uninit = x11Data->uninit;
607 }
608#elif defined(Q_WS_MAC)
609 QMacPixmapData *macData = data->classId() == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data) : 0;
610 if (macData)
611 uninit = macData->uninit;
612#endif
613 if (!uninit && !isNull()) {
614 // Copy old pixmap
615 if (hasAlphaChannel())
616 pm.fill(Qt::transparent);
617 QPainter p(&pm);
618 p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
619 }
620
621#if defined(Q_WS_MAC)
622#ifndef QT_MAC_NO_QUICKDRAW
623 if(macData && macData->qd_alpha)
624 macData->macQDUpdateAlpha();
625#endif
626#elif defined(Q_WS_X11)
627 if (x11Data && x11Data->x11_mask) {
628 QX11PixmapData *pmData = static_cast<QX11PixmapData*>(pm.data);
629 pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display,
630 RootWindow(x11Data->xinfo.display(),
631 x11Data->xinfo.screen()),
632 w, h, 1);
633 GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0);
634 XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, qMin(width(), w), qMin(height(), h), 0, 0);
635 XFreeGC(X11->display, gc);
636 }
637#endif
638 *this = pm;
639}
640#endif
641
642/*!
643 \fn void QPixmap::resize(int width, int height)
644 \compat
645
646 Use QPixmap::copy() instead to get the pixmap with the new size.
647
648 \oldcode
649 pixmap.resize(10, 20);
650 \newcode
651 pixmap = pixmap.copy(0, 0, 10, 20);
652 \endcode
653*/
654
655/*!
656 \fn bool QPixmap::selfMask() const
657 \compat
658
659 Returns whether the pixmap is its own mask or not.
660
661 This function is no longer relevant since the concept of self
662 masking doesn't exists anymore.
663*/
664
665/*!
666 Sets a mask bitmap.
667
668 This function merges the \a mask with the pixmap's alpha channel. A pixel
669 value of 1 on the mask means the pixmap's pixel is unchanged; a value of 0
670 means the pixel is transparent. The mask must have the same size as this
671 pixmap.
672
673 Setting a null mask resets the mask, leaving the previously transparent
674 pixels black. The effect of this function is undefined when the pixmap is
675 being painted on.
676
677 This is potentially an expensive operation.
678
679 \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
680 QBitmap
681*/
682void QPixmap::setMask(const QBitmap &mask)
683{
684 if (paintingActive()) {
685 qWarning("QPixmap::setMask: Cannot set mask while pixmap is being painted on");
686 return;
687 }
688
689 if (!mask.isNull() && mask.size() != size()) {
690 qWarning("QPixmap::setMask() mask size differs from pixmap size");
691 return;
692 }
693
694 if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
695 return;
696
697 detach();
698 data->setMask(mask);
699}
700
701#ifndef QT_NO_IMAGE_HEURISTIC_MASK
702/*!
703 Creates and returns a heuristic mask for this pixmap.
704
705 The function works by selecting a color from one of the corners
706 and then chipping away pixels of that color, starting at all the
707 edges. If \a clipTight is true (the default) the mask is just
708 large enough to cover the pixels; otherwise, the mask is larger
709 than the data pixels.
710
711 The mask may not be perfect but it should be reasonable, so you
712 can do things such as the following:
713
714 \snippet doc/src/snippets/code/src_gui_image_qpixmap.cpp 1
715
716 This function is slow because it involves converting to/from a
717 QImage, and non-trivial computations.
718
719 \sa QImage::createHeuristicMask(), createMaskFromColor()
720*/
721QBitmap QPixmap::createHeuristicMask(bool clipTight) const
722{
723 QBitmap m = QBitmap::fromImage(toImage().createHeuristicMask(clipTight));
724 return m;
725}
726#endif
727
728/*!
729 Creates and returns a mask for this pixmap based on the given \a
730 maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the
731 maskColor will be opaque. If \a mode is Qt::MaskOutColor, all pixels
732 matching the maskColor will be transparent.
733
734 This function is slow because it involves converting to/from a
735 QImage.
736
737 \sa createHeuristicMask(), QImage::createMaskFromColor()
738*/
739QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
740{
741 QImage image = toImage().convertToFormat(QImage::Format_ARGB32);
742 return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode));
743}
744
745/*! \overload
746
747 Creates and returns a mask for this pixmap based on the given \a
748 maskColor. Same as calling createMaskFromColor(maskColor,
749 Qt::MaskInColor)
750
751 \sa createHeuristicMask(), QImage::createMaskFromColor()
752*/
753QBitmap QPixmap::createMaskFromColor(const QColor &maskColor) const
754{
755 return createMaskFromColor(maskColor, Qt::MaskInColor);
756}
757
758/*!
759 Loads a pixmap from the file with the given \a fileName. Returns
760 true if the pixmap was successfully loaded; otherwise returns
761 false.
762
763 The loader attempts to read the pixmap using the specified \a
764 format. If the \a format is not specified (which is the default),
765 the loader probes the file for a header to guess the file format.
766
767 The file name can either refer to an actual file on disk or to one
768 of the application's embedded resources. See the
769 \l{resources.html}{Resource System} overview for details on how to
770 embed pixmaps and other resource files in the application's
771 executable.
772
773 If the data needs to be modified to fit in a lower-resolution
774 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
775 control the conversion.
776
777 Note that QPixmaps are automatically added to the QPixmapCache
778 when loaded from a file; the key used is internal and can not
779 be acquired.
780
781 \sa loadFromData(), {QPixmap#Reading and Writing Image
782 Files}{Reading and Writing Image Files}
783*/
784
785bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
786{
787 if (fileName.isEmpty())
788 return false;
789
790 QFileInfo info(fileName);
791 QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') +
792 QString::number(info.size()) + QLatin1Char('_') + QString::number(data->pixelType());
793
794 if (QPixmapCache::find(key, *this))
795 return true;
796
797 QImage image = QImageReader(fileName, format).read();
798 if (image.isNull())
799 return false;
800 QPixmap pm;
801 if (data->pixelType() == QPixmapData::BitmapType)
802 pm = QBitmap::fromImage(image, flags);
803 else
804 pm = fromImage(image, flags);
805 if (!pm.isNull()) {
806 *this = pm;
807 QPixmapCache::insert(key, *this);
808 return true;
809 }
810 return false;
811}
812
813/*!
814 \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
815
816 Loads a pixmap from the \a len first bytes of the given binary \a
817 data. Returns true if the pixmap was loaded successfully;
818 otherwise returns false.
819
820 The loader attempts to read the pixmap using the specified \a
821 format. If the \a format is not specified (which is the default),
822 the loader probes the file for a header to guess the file format.
823
824 If the data needs to be modified to fit in a lower-resolution
825 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
826 control the conversion.
827
828 \sa load(), {QPixmap#Reading and Writing Image Files}{Reading and
829 Writing Image Files}
830*/
831
832bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
833{
834 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buf), len);
835 QBuffer b(&a);
836 b.open(QIODevice::ReadOnly);
837
838 QImage image = QImageReader(&b, format).read();
839 QPixmap pm;
840 if (data->pixelType() == QPixmapData::BitmapType)
841 pm = QBitmap::fromImage(image, flags);
842 else
843 pm = fromImage(image, flags);
844 if (!pm.isNull()) {
845 *this = pm;
846 return true;
847 }
848 return false;
849}
850
851/*!
852 \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
853
854 \overload
855
856 Loads a pixmap from the binary \a data using the specified \a
857 format and conversion \a flags.
858*/
859
860
861/*!
862 Saves the pixmap to the file with the given \a fileName using the
863 specified image file \a format and \a quality factor. Returns true
864 if successful; otherwise returns false.
865
866 The \a quality factor must be in the range [0,100] or -1. Specify
867 0 to obtain small compressed files, 100 for large uncompressed
868 files, and -1 to use the default settings.
869
870 If \a format is 0, an image format will be chosen from \a fileName's
871 suffix.
872
873 \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
874 Image Files}
875*/
876
877bool QPixmap::save(const QString &fileName, const char *format, int quality) const
878{
879 if (isNull())
880 return false; // nothing to save
881 QImageWriter writer(fileName, format);
882 return doImageIO(&writer, quality);
883}
884
885/*!
886 \overload
887
888 This function writes a QPixmap to the given \a device using the
889 specified image file \a format and \a quality factor. This can be
890 used, for example, to save a pixmap directly into a QByteArray:
891
892 \snippet doc/src/snippets/image/image.cpp 1
893*/
894
895bool QPixmap::save(QIODevice* device, const char* format, int quality) const
896{
897 if (isNull())
898 return false; // nothing to save
899 QImageWriter writer(device, format);
900 return doImageIO(&writer, quality);
901}
902
903/*! \internal
904*/
905bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
906{
907 if (quality > 100 || quality < -1)
908 qWarning("QPixmap::save: quality out of range [-1,100]");
909 if (quality >= 0)
910 writer->setQuality(qMin(quality,100));
911 return writer->write(toImage());
912}
913
914
915// The implementation (and documentation) of
916// QPixmap::fill(const QWidget *, const QPoint &)
917// is in qwidget.cpp
918
919/*!
920 \fn void QPixmap::fill(const QWidget *widget, int x, int y)
921 \overload
922
923 Fills the pixmap with the \a widget's background color or pixmap.
924 The given point, (\a x, \a y), defines an offset in widget
925 coordinates to which the pixmap's top-left pixel will be mapped
926 to.
927*/
928
929/*!
930 Fills the pixmap with the given \a color.
931
932 \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
933*/
934
935void QPixmap::fill(const QColor &color)
936{
937 if (isNull())
938 return;
939
940 detach();
941 data->fill(color);
942}
943
944/*! \obsolete
945 Returns a number that identifies the contents of this QPixmap
946 object. Distinct QPixmap objects can only have the same serial
947 number if they refer to the same contents (but they don't have
948 to).
949
950 Use cacheKey() instead.
951
952 \warning The serial number doesn't necessarily change when
953 the pixmap is altered. This means that it may be dangerous to use
954 it as a cache key. For caching pixmaps, we recommend using the
955 QPixmapCache class whenever possible.
956*/
957int QPixmap::serialNumber() const
958{
959 if (isNull())
960 return 0;
961 return data->serialNumber();
962}
963
964/*!
965 Returns a number that identifies this QPixmap. Distinct QPixmap
966 objects can only have the same cache key if they refer to the same
967 contents.
968
969 The cacheKey() will change when the pixmap is altered.
970*/
971qint64 QPixmap::cacheKey() const
972{
973 int classKey = data->classId();
974 if (classKey >= 1024)
975 classKey = -(classKey >> 10);
976 return ((((qint64) classKey) << 56)
977 | (((qint64) data->serialNumber()) << 32)
978 | ((qint64) (data->detach_no)));
979}
980
981static void sendResizeEvents(QWidget *target)
982{
983 QResizeEvent e(target->size(), QSize());
984 QApplication::sendEvent(target, &e);
985
986 const QObjectList children = target->children();
987 for (int i = 0; i < children.size(); ++i) {
988 QWidget *child = static_cast<QWidget*>(children.at(i));
989 if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
990 sendResizeEvents(child);
991 }
992}
993
994/*!
995 \fn QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rectangle)
996
997 Creates a pixmap and paints the given \a widget, restricted by the
998 given \a rectangle, in it. If the \a widget has any children, then
999 they are also painted in the appropriate positions.
1000
1001 If no rectangle is specified (the default) the entire widget is
1002 painted.
1003
1004 If \a widget is 0, the specified rectangle doesn't overlap the
1005 widget's rectangle, or an error occurs, the function will return a
1006 null QPixmap. If the rectangle is a superset of the given \a
1007 widget, the areas outside the \a widget are covered with the
1008 widget's background.
1009
1010 This function actually asks \a widget to paint itself (and its
1011 children to paint themselves) by calling paintEvent() with painter
1012 redirection turned on. But QPixmap also provides the grabWindow()
1013 function which is a bit faster by grabbing pixels directly off the
1014 screen. In addition, if there are overlaying windows,
1015 grabWindow(), unlike grabWidget(), will see them.
1016
1017 \warning Do not grab a widget from its QWidget::paintEvent().
1018 However, it is safe to grab a widget from another widget's
1019 \l {QWidget::}{paintEvent()}.
1020
1021 \sa grabWindow()
1022*/
1023
1024QPixmap QPixmap::grabWidget(QWidget * widget, const QRect &rect)
1025{
1026 if (!widget)
1027 return QPixmap();
1028
1029 if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created))
1030 sendResizeEvents(widget);
1031
1032 QRect r(rect);
1033 if (r.width() < 0)
1034 r.setWidth(widget->width() - rect.x());
1035 if (r.height() < 0)
1036 r.setHeight(widget->height() - rect.y());
1037
1038 if (!r.intersects(widget->rect()))
1039 return QPixmap();
1040
1041 QPixmap res(r.size());
1042 widget->render(&res, QPoint(), r,
1043 QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);
1044 return res;
1045}
1046
1047/*!
1048 \fn QPixmap QPixmap::grabWidget(QWidget *widget, int x, int y, int
1049 width, int height)
1050
1051 \overload
1052
1053 Creates a pixmap and paints the given \a widget, restricted by
1054 QRect(\a x, \a y, \a width, \a height), in it.
1055
1056 \warning Do not grab a widget from its QWidget::paintEvent().
1057 However, it is safe to grab a widget from another widget's
1058 \l {QWidget::}{paintEvent()}.
1059*/
1060
1061
1062/*!
1063 \since 4.5
1064
1065 \enum QPixmap::ShareMode
1066
1067 This enum type defines the share modes that are available when
1068 creating a QPixmap object from a raw X11 Pixmap handle.
1069
1070 \value ImplicitlyShared This mode will cause the QPixmap object to
1071 create a copy of the internal data before it is modified, thus
1072 keeping the original X11 pixmap intact.
1073
1074 \value ExplicitlyShared In this mode, the pixmap data will \e not be
1075 copied before it is modified, which in effect will change the
1076 original X11 pixmap.
1077
1078 \warning This enum is only used for X11 specific functions; using
1079 it is non-portable.
1080
1081 \sa QPixmap::fromX11Pixmap()
1082*/
1083
1084/*!
1085 \since 4.5
1086
1087 \fn QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap, QPixmap::ShareMode mode)
1088
1089 Creates a QPixmap from the native X11 Pixmap handle \a pixmap,
1090 using \a mode as the share mode. The default share mode is
1091 QPixmap::ImplicitlyShared, which means that a copy of the pixmap is
1092 made if someone tries to modify it by e.g. drawing onto it.
1093
1094 QPixmap does \e not take ownership of the \a pixmap handle, and
1095 have to be deleted by the user.
1096
1097 \warning This function is X11 specific; using it is non-portable.
1098
1099 \sa QPixmap::ShareMode
1100*/
1101
1102
1103#if defined(Q_WS_X11) || defined(Q_WS_QWS)
1104
1105/*!
1106 Returns the pixmap's handle to the device context.
1107
1108 Note that, since QPixmap make use of \l {Implicit Data
1109 Sharing}{implicit data sharing}, the detach() function must be
1110 called explicitly to ensure that only \e this pixmap's data is
1111 modified if the pixmap data is shared.
1112
1113 \warning This function is X11 specific; using it is non-portable.
1114
1115 \sa detach()
1116*/
1117
1118Qt::HANDLE QPixmap::handle() const
1119{
1120#if defined(Q_WS_X11)
1121 if (data->classId() == QPixmapData::X11Class)
1122 return static_cast<QX11PixmapData*>(data)->handle();
1123#endif
1124 return 0;
1125}
1126#endif
1127
1128
1129#ifdef QT3_SUPPORT
1130static Qt::ImageConversionFlags colorModeToFlags(QPixmap::ColorMode mode)
1131{
1132 Qt::ImageConversionFlags flags = Qt::AutoColor;
1133 switch (mode) {
1134 case QPixmap::Color:
1135 flags |= Qt::ColorOnly;
1136 break;
1137 case QPixmap::Mono:
1138 flags |= Qt::MonoOnly;
1139 break;
1140 default:
1141 break;// Nothing.
1142 }
1143 return flags;
1144}
1145
1146/*!
1147 Use the constructor that takes a Qt::ImageConversionFlag instead.
1148*/
1149
1150QPixmap::QPixmap(const QString& fileName, const char *format, ColorMode mode)
1151 : QPaintDevice()
1152{
1153 init(0, 0, QPixmapData::PixmapType);
1154 if (!qt_pixmap_thread_test())
1155 return;
1156
1157 load(fileName, format, colorModeToFlags(mode));
1158}
1159
1160/*!
1161 Constructs a pixmap from the QImage \a image.
1162
1163 Use the static fromImage() function instead.
1164*/
1165QPixmap::QPixmap(const QImage& image)
1166 : QPaintDevice()
1167{
1168 init(0, 0, QPixmapData::PixmapType);
1169 if (!qt_pixmap_thread_test())
1170 return;
1171
1172 if (data->pixelType() == QPixmapData::BitmapType)
1173 *this = QBitmap::fromImage(image);
1174 else
1175 *this = fromImage(image);
1176}
1177
1178/*!
1179 \overload
1180
1181 Converts the given \a image to a pixmap that is assigned to this
1182 pixmap.
1183
1184 Use the static fromImage() function instead.
1185*/
1186
1187QPixmap &QPixmap::operator=(const QImage &image)
1188{
1189 if (data->pixelType() == QPixmapData::BitmapType)
1190 *this = QBitmap::fromImage(image);
1191 else
1192 *this = fromImage(image);
1193 return *this;
1194}
1195
1196/*!
1197 Use the load() function that takes a Qt::ImageConversionFlag instead.