diff --git a/declarativeimports/qtextracomponents/qimageitem.cpp b/declarativeimports/qtextracomponents/qimageitem.cpp index 086449d19..97eaec4c8 100644 --- a/declarativeimports/qtextracomponents/qimageitem.cpp +++ b/declarativeimports/qtextracomponents/qimageitem.cpp @@ -24,7 +24,8 @@ QImageItem::QImageItem(QDeclarativeItem *parent) : QDeclarativeItem(parent), - m_smooth(false) + m_smooth(false), + m_fillMode(QImageItem::Stretch) { setFlag(QGraphicsItem::ItemHasNoContents, false); } @@ -71,6 +72,22 @@ int QImageItem::nativeHeight() const return m_image.size().height(); } +QImageItem::FillMode QImageItem::fillMode() const +{ + return m_fillMode; +} + +void QImageItem::setFillMode(QImageItem::FillMode mode) +{ + if (mode == m_fillMode) { + return; + } + + m_fillMode = mode; + update(); + emit fillModeChanged(); +} + void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); @@ -79,15 +96,51 @@ void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option if (m_image.isNull()) { return; } - //do without painter save, faster and the support can be compiled out - const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing); - const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->save(); painter->setRenderHint(QPainter::Antialiasing, m_smooth); painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); - painter->drawImage(boundingRect(), m_image, m_image.rect()); - painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); - painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); + QRect destRect; + switch (m_fillMode) { + case PreserveAspectFit: { + QSize scaled = m_image.size(); + + scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatio); + destRect = QRect(QPoint(0, 0), scaled); + break; + } + case PreserveAspectCrop: { + painter->setClipRect(boundingRect(), Qt::IntersectClip); + QSize scaled = m_image.size(); + scaled.scale(boundingRect().size().toSize(), Qt::KeepAspectRatioByExpanding); + destRect = QRect(QPoint(0, 0), scaled); + break; + } + case TileVertically: { + painter->scale(width()/(qreal)m_image.width(), 1); + destRect = boundingRect().toRect(); + destRect.setWidth(destRect.width() / (width()/(qreal)m_image.width())); + break; + } + case TileHorizontally: { + painter->scale(1, height()/(qreal)m_image.height()); + destRect = boundingRect().toRect(); + destRect.setHeight(destRect.height() / (height()/(qreal)m_image.height())); + break; + } + case Stretch: + case Tile: + default: + destRect = boundingRect().toRect(); + } + + if (m_fillMode >= Tile) { + painter->drawTiledPixmap(destRect, QPixmap::fromImage(m_image)); + } else { + painter->drawImage(destRect, m_image, m_image.rect()); + } + + painter->restore(); } diff --git a/declarativeimports/qtextracomponents/qimageitem.h b/declarativeimports/qtextracomponents/qimageitem.h index a4365b5dc..0c358ec71 100644 --- a/declarativeimports/qtextracomponents/qimageitem.h +++ b/declarativeimports/qtextracomponents/qimageitem.h @@ -30,8 +30,19 @@ class QImageItem : public QDeclarativeItem Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) + Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged) + Q_ENUMS(FillMode) public: + enum FillMode { + Stretch, // the image is scaled to fit + PreserveAspectFit, // the image is scaled uniformly to fit without cropping + PreserveAspectCrop, // the image is scaled uniformly to fill, cropping if necessary + Tile, // the image is duplicated horizontally and vertically + TileVertically, // the image is stretched horizontally and tiled vertically + TileHorizontally //the image is stretched vertically and tiled horizontally + }; + QImageItem(QDeclarativeItem *parent=0); ~QImageItem(); @@ -44,15 +55,20 @@ public: int nativeWidth() const; int nativeHeight() const; + FillMode fillMode() const; + void setFillMode(FillMode mode); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); Q_SIGNALS: void nativeWidthChanged(); void nativeHeightChanged(); + void fillModeChanged(); private: QImage m_image; bool m_smooth; + FillMode m_fillMode; }; #endif