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 QtQuick 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 "qsgsoftwarepublicnodes_p.h"
41#include "qsgsoftwarelayer_p.h"
42#include "qsgsoftwarepixmaptexture_p.h"
43#include "qsgsoftwareinternalimagenode_p.h"
44#include <private/qsgplaintexture_p.h>
45
46QT_BEGIN_NAMESPACE
47
48QSGSoftwareRectangleNode::QSGSoftwareRectangleNode()
49 : m_color(QColor(255, 255, 255))
50{
51 setMaterial((QSGMaterial*)1);
52 setGeometry((QSGGeometry*)1);
53}
54
55void QSGSoftwareRectangleNode::paint(QPainter *painter)
56{
57 painter->fillRect(m_rect, color: m_color);
58}
59
60QSGSoftwareImageNode::QSGSoftwareImageNode()
61 : m_texture(nullptr),
62 m_owns(false),
63 m_filtering(QSGTexture::None),
64 m_transformMode(NoTransform),
65 m_cachedMirroredPixmapIsDirty(false)
66{
67 setMaterial((QSGMaterial*)1);
68 setGeometry((QSGGeometry*)1);
69}
70
71QSGSoftwareImageNode::~QSGSoftwareImageNode()
72{
73 if (m_owns)
74 delete m_texture;
75}
76
77void QSGSoftwareImageNode::setTexture(QSGTexture *texture)
78{
79 if (m_owns)
80 delete m_texture;
81
82 m_texture = texture; markDirty(bits: DirtyMaterial);
83 m_cachedMirroredPixmapIsDirty = true;
84}
85
86void QSGSoftwareImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoordinatesTransformMode transformNode)
87{
88 if (m_transformMode == transformNode)
89 return;
90
91 m_transformMode = transformNode;
92 m_cachedMirroredPixmapIsDirty = true;
93
94 markDirty(bits: DirtyGeometry);
95}
96
97void QSGSoftwareImageNode::paint(QPainter *painter)
98{
99 if (m_cachedMirroredPixmapIsDirty)
100 updateCachedMirroredPixmap();
101
102 painter->setRenderHint(hint: QPainter::SmoothPixmapTransform, on: (m_filtering == QSGTexture::Linear));
103 // Disable antialiased clipping. It causes transformed tiles to have gaps.
104 painter->setRenderHint(hint: QPainter::Antialiasing, on: false);
105
106 if (!m_cachedPixmap.isNull()) {
107 painter->drawPixmap(targetRect: m_rect, pixmap: m_cachedPixmap, sourceRect: m_sourceRect);
108 } else if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(object: m_texture)) {
109 const QPixmap &pm = pt->pixmap();
110 painter->drawPixmap(targetRect: m_rect, pixmap: pm, sourceRect: m_sourceRect);
111 } else if (QSGSoftwareLayer *pt = qobject_cast<QSGSoftwareLayer *>(object: m_texture)) {
112 const QPixmap &pm = pt->pixmap();
113 painter->drawPixmap(targetRect: m_rect, pixmap: pm, sourceRect: m_sourceRect);
114 } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(object: m_texture)) {
115 const QImage &im = pt->image();
116 painter->drawImage(targetRect: m_rect, image: im, sourceRect: m_sourceRect);
117 }
118}
119
120void QSGSoftwareImageNode::updateCachedMirroredPixmap()
121{
122 if (m_transformMode == NoTransform) {
123 m_cachedPixmap = QPixmap();
124 } else {
125 if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(object: m_texture)) {
126 QTransform mirrorTransform;
127 if (m_transformMode.testFlag(flag: MirrorVertically))
128 mirrorTransform = mirrorTransform.scale(sx: 1, sy: -1);
129 if (m_transformMode.testFlag(flag: MirrorHorizontally))
130 mirrorTransform = mirrorTransform.scale(sx: -1, sy: 1);
131 m_cachedPixmap = pt->pixmap().transformed(mirrorTransform);
132 } else if (QSGSoftwareLayer *pt = qobject_cast<QSGSoftwareLayer *>(object: m_texture)) {
133 QTransform mirrorTransform;
134 if (m_transformMode.testFlag(flag: MirrorVertically))
135 mirrorTransform = mirrorTransform.scale(sx: 1, sy: -1);
136 if (m_transformMode.testFlag(flag: MirrorHorizontally))
137 mirrorTransform = mirrorTransform.scale(sx: -1, sy: 1);
138 m_cachedPixmap = pt->pixmap().transformed(mirrorTransform);
139 } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(object: m_texture)) {
140 m_cachedPixmap = QPixmap::fromImage(image: pt->image().mirrored(horizontally: m_transformMode.testFlag(flag: MirrorHorizontally), vertically: m_transformMode.testFlag(flag: MirrorVertically)));
141 } else {
142 m_cachedPixmap = QPixmap();
143 }
144 }
145
146 m_cachedMirroredPixmapIsDirty = false;
147}
148
149QSGSoftwareNinePatchNode::QSGSoftwareNinePatchNode()
150{
151 setMaterial((QSGMaterial*)1);
152 setGeometry((QSGGeometry*)1);
153}
154
155void QSGSoftwareNinePatchNode::setTexture(QSGTexture *texture)
156{
157 QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture*>(object: texture);
158 if (!pt) {
159 qWarning() << "Image used with invalid texture format.";
160 } else {
161 m_pixmap = pt->pixmap();
162 markDirty(bits: DirtyMaterial);
163 }
164 delete texture;
165}
166
167void QSGSoftwareNinePatchNode::setBounds(const QRectF &bounds)
168{
169 if (m_bounds == bounds)
170 return;
171
172 m_bounds = bounds;
173 markDirty(bits: DirtyGeometry);
174}
175
176void QSGSoftwareNinePatchNode::setDevicePixelRatio(qreal ratio)
177{
178 if (m_pixelRatio == ratio)
179 return;
180
181 m_pixelRatio = ratio;
182 markDirty(bits: DirtyGeometry);
183}
184
185void QSGSoftwareNinePatchNode::setPadding(qreal left, qreal top, qreal right, qreal bottom)
186{
187 QMargins margins(qRound(d: left), qRound(d: top), qRound(d: right), qRound(d: bottom));
188 if (m_margins == margins)
189 return;
190
191 m_margins = QMargins(qRound(d: left), qRound(d: top), qRound(d: right), qRound(d: bottom));
192 markDirty(bits: DirtyGeometry);
193}
194
195void QSGSoftwareNinePatchNode::update()
196{
197}
198
199void QSGSoftwareNinePatchNode::paint(QPainter *painter)
200{
201 // Disable antialiased clipping. It causes transformed tiles to have gaps.
202 painter->setRenderHint(hint: QPainter::Antialiasing, on: false);
203
204 if (m_margins.isNull())
205 painter->drawPixmap(targetRect: m_bounds, pixmap: m_pixmap, sourceRect: QRectF(0, 0, m_pixmap.width(), m_pixmap.height()));
206 else
207 QSGSoftwareHelpers::qDrawBorderPixmap(painter, targetRect: m_bounds.toRect(), targetMargins: m_margins, pixmap: m_pixmap, sourceRect: QRect(0, 0, m_pixmap.width(), m_pixmap.height()),
208 sourceMargins: m_margins, rules: Qt::StretchTile, hints: QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
209}
210
211QRectF QSGSoftwareNinePatchNode::bounds() const
212{
213 return m_bounds;
214}
215
216QT_END_NAMESPACE
217

source code of qtdeclarative/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp