22void qDrawBorderPixmap(QPainter *painter,
const QRect &targetRect,
const QMargins &targetMarginsIn,
23 const QPixmap &pixmap,
const QRect &sourceRect,
const QMargins &sourceMarginsIn,
24 const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
26 QPainter::PixmapFragment d;
33 QMargins sourceMargins = normalizedMargins(sourceMarginsIn);
34 QMargins targetMargins = normalizedMargins(targetMarginsIn);
36 const qreal sourceDpr = pixmap.devicePixelRatio();
37 sourceMargins *= sourceDpr;
40 const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
41 const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
42 const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
43 const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
44 const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
45 const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
47 const int targetCenterTop = targetRect.top() + targetMargins.top();
48 const int targetCenterLeft = targetRect.left() + targetMargins.left();
49 const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
50 const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
51 const int targetCenterWidth = targetCenterRight - targetCenterLeft;
52 const int targetCenterHeight = targetCenterBottom - targetCenterTop;
54 QVarLengthArray<qreal, 16> xTarget;
55 QVarLengthArray<qreal, 16> yTarget;
59 if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
60 columns = qMax(3, 2 + qCeil((targetCenterWidth * sourceDpr) / qreal(sourceCenterWidth)));
61 if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
62 rows = qMax(3, 2 + qCeil((targetCenterHeight * sourceDpr) / qreal(sourceCenterHeight)));
64 xTarget.resize(columns + 1);
65 yTarget.resize(rows + 1);
67 xTarget[0] = targetRect.left();
68 xTarget[1] = targetCenterLeft;
69 xTarget[columns - 1] = targetCenterRight;
70 xTarget[columns] = targetRect.left() + targetRect.width();
72 yTarget[0] = targetRect.top();
73 yTarget[1] = targetCenterTop;
74 yTarget[rows - 1] = targetCenterBottom;
75 yTarget[rows] = targetRect.top() + targetRect.height();
77 qreal dx = targetCenterWidth;
78 qreal dy = targetCenterHeight;
80 switch (rules.horizontal) {
82 dx = targetCenterWidth;
85 dx = sourceCenterWidth / sourceDpr;
88 dx = targetCenterWidth / qreal(columns - 2);
92 for (
int i = 2; i < columns - 1; ++i)
93 xTarget[i] = xTarget[i - 1] + dx;
95 switch (rules.vertical) {
97 dy = targetCenterHeight;
100 dy = sourceCenterHeight / sourceDpr;
103 dy = targetCenterHeight / qreal(rows - 2);
107 for (
int i = 2; i < rows - 1; ++i)
108 yTarget[i] = yTarget[i - 1] + dy;
111 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) {
112 d.x = (0.5 * (xTarget[1] + xTarget[0]));
113 d.y = (0.5 * (yTarget[1] + yTarget[0]));
114 d.sourceLeft = sourceRect.left();
115 d.sourceTop = sourceRect.top();
116 d.width = sourceMargins.left();
117 d.height = sourceMargins.top();
118 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
119 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
121 opaqueData.append(d);
123 translucentData.append(d);
125 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) {
126 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
127 d.y = (0.5 * (yTarget[1] + yTarget[0]));
128 d.sourceLeft = sourceCenterRight;
129 d.sourceTop = sourceRect.top();
130 d.width = sourceMargins.right();
131 d.height = sourceMargins.top();
132 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
133 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
135 opaqueData.append(d);
137 translucentData.append(d);
139 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) {
140 d.x = (0.5 * (xTarget[1] + xTarget[0]));
141 d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
142 d.sourceLeft = sourceRect.left();
143 d.sourceTop = sourceCenterBottom;
144 d.width = sourceMargins.left();
145 d.height = sourceMargins.bottom();
146 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
147 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
149 opaqueData.append(d);
151 translucentData.append(d);
153 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) {
154 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
155 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
156 d.sourceLeft = sourceCenterRight;
157 d.sourceTop = sourceCenterBottom;
158 d.width = sourceMargins.right();
159 d.height = sourceMargins.bottom();
160 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
161 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
163 opaqueData.append(d);
165 translucentData.append(d);
169 if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
170 if (targetMargins.top() > 0 && sourceMargins.top() > 0) {
172 d.sourceLeft = sourceCenterLeft;
173 d.sourceTop = sourceRect.top();
174 d.width = sourceCenterWidth;
175 d.height = sourceMargins.top();
176 d.y = (0.5 * (yTarget[1] + yTarget[0]));
177 d.scaleX = dx / d.width;
178 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
179 for (
int i = 1; i < columns - 1; ++i) {
180 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
183 if (rules.horizontal == Qt::RepeatTile)
184 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
186 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) {
188 d.sourceLeft = sourceCenterLeft;
189 d.sourceTop = sourceCenterBottom;
190 d.width = sourceCenterWidth;
191 d.height = sourceMargins.bottom();
192 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
193 d.scaleX = dx / d.width;
194 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
195 for (
int i = 1; i < columns - 1; ++i) {
196 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
199 if (rules.horizontal == Qt::RepeatTile)
200 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
205 if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
206 if (targetMargins.left() > 0 && sourceMargins.left() > 0) {
208 d.sourceLeft = sourceRect.left();
209 d.sourceTop = sourceCenterTop;
210 d.width = sourceMargins.left();
211 d.height = sourceCenterHeight;
212 d.x = (0.5 * (xTarget[1] + xTarget[0]));
213 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
214 d.scaleY = dy / d.height;
215 for (
int i = 1; i < rows - 1; ++i) {
216 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
219 if (rules.vertical == Qt::RepeatTile)
220 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
222 if (targetMargins.right() > 0 && sourceMargins.right() > 0) {
224 d.sourceLeft = sourceCenterRight;
225 d.sourceTop = sourceCenterTop;
226 d.width = sourceMargins.right();
227 d.height = sourceCenterHeight;
228 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
229 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
230 d.scaleY = dy / d.height;
231 for (
int i = 1; i < rows - 1; ++i) {
232 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
235 if (rules.vertical == Qt::RepeatTile)
236 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
241 if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
243 d.sourceLeft = sourceCenterLeft;
244 d.sourceTop = sourceCenterTop;
245 d.width = sourceCenterWidth;
246 d.height = sourceCenterHeight;
247 d.scaleX = dx / d.width;
248 d.scaleY = dy / d.height;
250 qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
251 qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
253 for (
int j = 1; j < rows - 1; ++j) {
254 d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
255 for (
int i = 1; i < columns - 1; ++i) {
256 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
259 if (rules.horizontal == Qt::RepeatTile)
260 data[data.size() - 1].width = repeatWidth;
262 if (rules.vertical == Qt::RepeatTile) {
263 for (
int i = 1; i < columns - 1; ++i)
264 data[data.size() - i].height = repeatHeight;
268 if (opaqueData.size())
269 painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
270 if (translucentData.size())
271 painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
409 painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
411 painter->setRenderHint(QPainter::Antialiasing,
false);
413 updateCachedMirroredPixmap();
414 const QPixmap &pm = m_mirrorHorizontally || m_mirrorVertically || m_textureIsLayer ? m_cachedMirroredPixmap : pixmap();
416 if (m_innerTargetRect != m_targetRect) {
418 QMargins margins(m_innerTargetRect.left() - m_targetRect.left(), m_innerTargetRect.top() - m_targetRect.top(),
419 m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom());
420 QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height()));
421 QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()),
422 margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
426 if (m_tileHorizontal || m_tileVertical) {
428 qreal sx = m_targetRect.width()/(m_subSourceRect.width()*pm.width());
429 qreal sy = m_targetRect.height()/(m_subSourceRect.height()*pm.height());
430 painter->setTransform(QTransform::fromScale(sx, sy),
true);
431 painter->drawTiledPixmap(QRectF(m_targetRect.x()/sx, m_targetRect.y()/sy, m_targetRect.width()/sx, m_targetRect.height()/sy),
433 QPointF(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height()));
436 QRectF sr(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height(),
437 m_subSourceRect.width()*pm.width(), m_subSourceRect.height()*pm.height());
438 painter->drawPixmap(m_targetRect, pm, sr);