📄 qpixmap_raster.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qpixmap.h"#include "qpixmap_p.h"#include "qbitmap.h"#include "qimage.h"#include "qwidget.h"#include "qpainter.h"#include "qdatastream.h"#include "qbuffer.h"#include "qapplication.h"#include <private/qwidget_p.h>#include "qevent.h"#include "qfile.h"#include "qfileinfo.h"#include "qdatetime.h"#include "qpixmapcache.h"#include "qimagereader.h"#include "qimagewriter.h"#include "qdebug.h"#include "qpaintengine.h"#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)#include <private/qpaintengine_d3d_p.h>#include <d3d9.h>extern QDirect3DPaintEngine *qt_d3dEngine();#endifextern int qt_defaultDpi();extern int qt_defaultDpiX();extern int qt_defaultDpiY();// ### Qt 5: removetypedef void (*_qt_pixmap_cleanup_hook)(int);Q_GUI_EXPORT _qt_pixmap_cleanup_hook qt_pixmap_cleanup_hook = 0;// ### Qt 5: renametypedef void (*_qt_pixmap_cleanup_hook_64)(qint64);Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64 = 0;// ### Qt 5: removeQ_GUI_EXPORT qint64 qt_pixmap_id(const QPixmap &pixmap){ return pixmap.cacheKey();}QPixmap::QPixmap() : QPaintDevice(){ init(0, 0);}#ifdef QT3_SUPPORTQPixmap::QPixmap(const QImage& image) : QPaintDevice(){ init(0, 0); *this = fromImage(image);}#endifQPixmap::QPixmap(int w, int h) : QPaintDevice(){ init(w, h);}QPixmap::QPixmap(const QSize &size) : QPaintDevice(){ init(size.width(), size.height());}QPixmap::QPixmap(const QSize &size, enum QPixmap::Type type) : QPaintDevice(){ init(size.width(), size.height(), type);}QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags) : QPaintDevice(){ init(0, 0); load(fileName, format, flags);}QPixmap::QPixmap(const QPixmap &pixmap) : QPaintDevice(){ if (pixmap.paintingActive()) { // make a deep copy data = 0; operator=(pixmap.copy()); } else { data = pixmap.data; data->ref(); }}#ifndef QT_NO_IMAGEFORMAT_XPMQPixmap::QPixmap(const char * const xpm[]) : QPaintDevice(){ init(0, 0); QImage image(xpm); if (!image.isNull()) (*this) = fromImage(image);}#endif // QT_NO_IMAGEFORMAT_XPMQPixmap::~QPixmap(){ deref();}int QPixmap::devType() const{ return QInternal::Pixmap;}QPixmap &QPixmap::operator=(const QPixmap &pixmap){ if (paintingActive()) { qWarning("QPixmap::operator=: Cannot assign to pixmap during painting"); return *this; } if (pixmap.paintingActive()) { // make a deep copy *this = pixmap.copy(); } else { pixmap.data->ref(); // avoid 'x = x' deref(); data = pixmap.data; } return *this;}#ifdef QT3_SUPPORTQPixmap &QPixmap::operator=(const QImage &image){ (*this) = fromImage(image); return *this;}#endifQPixmap::operator QVariant() const{ return QVariant(QVariant::Pixmap, this);}bool QPixmap::isNull() const{ return data->image.isNull();}int QPixmap::width() const{ return data->image.width();}int QPixmap::height() const{ return data->image.height();}QSize QPixmap::size() const{ return data->image.size();}QRect QPixmap::rect() const{ return data->image.rect();}int QPixmap::depth() const{ return data->image.depth();}int QPixmap::defaultDepth(){ return 32; //###}void QPixmap::fill(const QColor &fillColor){ uint pixel; detach(); if (data->image.depth() == 1) { int gray = qGray(fillColor.rgba()); // Pick the best approximate color in the image's colortable. if (qAbs(qGray(data->image.color(0)) - gray) < qAbs(qGray(data->image.color(1)) - gray)) { pixel = 0; } else { pixel = 1; } } else if (data->image.depth() == 32#ifdef Q_WS_QWS || data->image.depth() == 16#endif ) { int alpha = fillColor.alpha(); if (alpha != 255) { if (data->image.format() == QImage::Format_RGB32#ifdef Q_WS_QWS || data->image.format() == QImage::Format_RGB16#endif ) data->image = data->image.convertToFormat(QImage::Format_ARGB32_Premultiplied); // Premultiply pixel value. pixel = qRgba(fillColor.red() * alpha / 255, fillColor.green() * alpha / 255, fillColor.blue() * alpha / 255, alpha);#ifdef Q_WS_QWS } else if (data->image.depth() == 16) { pixel = qt_convRgbTo16(fillColor.rgba());#endif } else { pixel = fillColor.rgba(); } } else { pixel = 0; // ### what about 8 bits } data->image.fill(pixel);}#ifdef QT3_SUPPORTvoid QPixmap::resize_helper(const QSize &size){ if (size == data->image.size()) return; detach(); if (size.isEmpty()) data->image = QImage(); else if (data->image.isNull()) *this = QPixmap(size, data->type); else data->image = data->image.copy(0, 0, size.width(), size.height());}#endifconst uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };QBitmap QPixmap::mask() const{ if (!data->image.hasAlphaChannel() || data->image.depth() != 32) { return QBitmap(); } // Create image and setup color table int w = data->image.width(); int h = data->image.height(); QImage mask = data->createBitmapImage(w, h); int bpl = mask.bytesPerLine(); // copy over the data for (int y=0; y<h; ++y) { QRgb *src = (QRgb *) data->image.scanLine(y); uchar *dest = mask.scanLine(y); memset(dest, 0, bpl); for (int x=0; x<w; ++x) { if (qAlpha(*src) > 0) dest[x>>3] |= qt_pixmap_bit_mask[x&7]; ++src; } } return QBitmap::fromImage(mask);}void QPixmap::setMask(const QBitmap &mask){ if (paintingActive()) { qWarning("QPixmap::setMask: Cannot set mask while pixmap is being painted on"); return; } if (mask.size().isEmpty()) { if (depth() != 1) { detach(); data->image = data->image.convertToFormat(QImage::Format_RGB32); } } else if (mask.size() != size()) { qWarning("QPixmap::setMask() mask size differs from pixmap size"); } else { detach(); const QImage imageMask = mask.toImage().convertToFormat(QImage::Format_MonoLSB); int w = width(); int h = height(); switch (depth()) { case 1: for (int y=0; y<h; ++y) { const uchar *mscan = imageMask.scanLine(y); uchar *tscan = data->image.scanLine(y); int bytesPerLine = data->image.bytesPerLine(); for (int i=0; i<bytesPerLine; ++i) tscan[i] &= mscan[i]; } break; case 32: data->image = data->image.convertToFormat(QImage::Format_ARGB32_Premultiplied); for (int y=0; y<h; ++y) { const uchar *mscan = imageMask.scanLine(y); QRgb *tscan = (QRgb *) data->image.scanLine(y); for (int x=0; x<w; ++x) { if (!(mscan[x>>3] & qt_pixmap_bit_mask[x&7])) tscan[x] = 0; } } break; } }}bool QPixmap::hasAlpha() const{ return data->image.hasAlphaChannel();}bool QPixmap::hasAlphaChannel() const{ return data->image.hasAlphaChannel();}#ifndef QT_NO_IMAGE_HEURISTIC_MASKQBitmap QPixmap::createHeuristicMask(bool clipTight ) const{ QBitmap m = fromImage(toImage().createHeuristicMask(clipTight)); return m;}#endifQBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const{ QImage image = toImage().convertToFormat(QImage::Format_ARGB32); return QBitmap::fromImage(image.createMaskFromColor(maskColor.rgba(), mode));}QBitmap QPixmap::createMaskFromColor(const QColor &maskColor) const{ return createMaskFromColor(maskColor, Qt::MaskInColor);}static void sendResizeEvents(QWidget *target){ QResizeEvent e(target->size(), QSize()); QApplication::sendEvent(target, &e); const QObjectList children = target->children(); for (int i = 0; i < children.size(); ++i) { QWidget *child = static_cast<QWidget*>(children.at(i)); if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent)) sendResizeEvents(child); }}QPixmap QPixmap::grabWidget(QWidget *widget, const QRect &rect){ if (!widget)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -