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 "qsgopenvginternalimagenode.h"
41 #include "qsgopenvghelpers.h"
42
43 #include <VG/openvg.h>
44
45 QT_BEGIN_NAMESPACE
46
QSGOpenVGInternalImageNode()47 QSGOpenVGInternalImageNode::QSGOpenVGInternalImageNode()
48 {
49 // Set Dummy material and geometry to avoid asserts
50 setMaterial((QSGMaterial*)1);
51 setGeometry((QSGGeometry*)1);
52 }
53
~QSGOpenVGInternalImageNode()54 QSGOpenVGInternalImageNode::~QSGOpenVGInternalImageNode()
55 {
56 if (m_subSourceRectImage != 0)
57 vgDestroyImage(m_subSourceRectImage);
58 }
59
render()60 void QSGOpenVGInternalImageNode::render()
61 {
62 if (!m_texture) {
63 return;
64 }
65
66 // Set Draw Mode
67 if (opacity() < 1.0) {
68 //Transparent
69 vgSetPaint(opacityPaint(), VG_FILL_PATH);
70 vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
71 } else {
72 vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
73 }
74
75 // Set Transform
76 vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
77 vgLoadMatrix(transform().constData());
78
79 VGImage image = static_cast<VGImage>(m_texture->textureId());
80 QSize textureSize = m_texture->textureSize();
81
82 if (image == VG_INVALID_HANDLE || !textureSize.isValid())
83 return;
84
85
86 // If Mirrored
87 if (m_mirror) {
88 vgTranslate(m_targetRect.width(), 0.0f);
89 vgScale(-1.0, 1.0);
90 }
91
92 if (m_smooth)
93 vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_BETTER);
94 else
95 vgSeti(VG_IMAGE_QUALITY, VG_IMAGE_QUALITY_NONANTIALIASED);
96
97
98 if (m_innerTargetRect != m_targetRect) {
99 // border image
100 QSGOpenVGHelpers::qDrawBorderImage(image, textureSize, m_targetRect, m_innerTargetRect, m_subSourceRect);
101 } else if (m_tileHorizontal || m_tileVertical) {
102 // Tilled Image
103
104 float sx = m_targetRect.width() / (m_subSourceRect.width() * textureSize.width());
105 float sy = m_targetRect.height() / (m_subSourceRect.height() * textureSize.height());
106 QPointF offset(m_subSourceRect.left() * textureSize.width(), m_subSourceRect.top() * textureSize.height());
107
108 QSGOpenVGHelpers::qDrawTiled(image, textureSize, m_targetRect, offset, sx, sy);
109
110 } else {
111 // Regular BLIT
112
113 QRectF sr(m_subSourceRect.left() * textureSize.width(), m_subSourceRect.top() * textureSize.height(),
114 m_subSourceRect.width() * textureSize.width(), m_subSourceRect.height() * textureSize.height());
115
116 if (m_subSourceRectImageDirty) {
117 if (m_subSourceRectImage != 0)
118 vgDestroyImage(m_subSourceRectImage);
119 m_subSourceRectImage = vgChildImage(image, sr.x(), sr.y(), sr.width(), sr.height());
120 m_subSourceRectImageDirty = false;
121 }
122
123 // If the the source rect is the same as the target rect
124 if (sr == m_targetRect) {
125 vgDrawImage(image);
126 } else {
127 // Scale
128 float scaleX = m_targetRect.width() / sr.width();
129 float scaleY = m_targetRect.height() / sr.height();
130 vgTranslate(m_targetRect.x(), m_targetRect.y());
131 vgScale(scaleX, scaleY);
132 vgDrawImage(m_subSourceRectImage);
133 }
134 }
135 }
136
setTargetRect(const QRectF & rect)137 void QSGOpenVGInternalImageNode::setTargetRect(const QRectF &rect)
138 {
139 if (rect == m_targetRect)
140 return;
141 m_targetRect = rect;
142 markDirty(DirtyGeometry);
143 }
144
setInnerTargetRect(const QRectF & rect)145 void QSGOpenVGInternalImageNode::setInnerTargetRect(const QRectF &rect)
146 {
147 if (rect == m_innerTargetRect)
148 return;
149 m_innerTargetRect = rect;
150 markDirty(DirtyGeometry);
151 }
152
setInnerSourceRect(const QRectF & rect)153 void QSGOpenVGInternalImageNode::setInnerSourceRect(const QRectF &rect)
154 {
155 if (rect == m_innerSourceRect)
156 return;
157 m_innerSourceRect = rect;
158 markDirty(DirtyGeometry);
159 }
160
setSubSourceRect(const QRectF & rect)161 void QSGOpenVGInternalImageNode::setSubSourceRect(const QRectF &rect)
162 {
163 if (rect == m_subSourceRect)
164 return;
165 m_subSourceRect = rect;
166 m_subSourceRectImageDirty = true;
167 markDirty(DirtyGeometry);
168 }
169
setTexture(QSGTexture * texture)170 void QSGOpenVGInternalImageNode::setTexture(QSGTexture *texture)
171 {
172 m_texture = texture;
173 m_subSourceRectImageDirty = true;
174 markDirty(DirtyMaterial);
175 }
176
setMirror(bool mirror)177 void QSGOpenVGInternalImageNode::setMirror(bool mirror)
178 {
179 if (m_mirror != mirror) {
180 m_mirror = mirror;
181 markDirty(DirtyMaterial);
182 }
183 }
184
setMipmapFiltering(QSGTexture::Filtering)185 void QSGOpenVGInternalImageNode::setMipmapFiltering(QSGTexture::Filtering)
186 {
187 }
188
setFiltering(QSGTexture::Filtering filtering)189 void QSGOpenVGInternalImageNode::setFiltering(QSGTexture::Filtering filtering)
190 {
191 bool smooth = (filtering == QSGTexture::Linear);
192 if (smooth == m_smooth)
193 return;
194
195 m_smooth = smooth;
196 markDirty(DirtyMaterial);
197 }
198
setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)199 void QSGOpenVGInternalImageNode::setHorizontalWrapMode(QSGTexture::WrapMode wrapMode)
200 {
201 bool tileHorizontal = (wrapMode == QSGTexture::Repeat);
202 if (tileHorizontal == m_tileHorizontal)
203 return;
204
205 m_tileHorizontal = tileHorizontal;
206 markDirty(DirtyMaterial);
207 }
208
setVerticalWrapMode(QSGTexture::WrapMode wrapMode)209 void QSGOpenVGInternalImageNode::setVerticalWrapMode(QSGTexture::WrapMode wrapMode)
210 {
211 bool tileVertical = (wrapMode == QSGTexture::Repeat);
212 if (tileVertical == m_tileVertical)
213 return;
214
215 m_tileVertical = (wrapMode == QSGTexture::Repeat);
216 markDirty(DirtyMaterial);
217 }
218
update()219 void QSGOpenVGInternalImageNode::update()
220 {
221 }
222
preprocess()223 void QSGOpenVGInternalImageNode::preprocess()
224 {
225 bool doDirty = false;
226 QSGLayer *t = qobject_cast<QSGLayer *>(m_texture);
227 if (t) {
228 doDirty = t->updateTexture();
229 markDirty(DirtyGeometry);
230 }
231 if (doDirty)
232 markDirty(DirtyMaterial);
233 }
234
235 QT_END_NAMESPACE
236
237
238
239
240