21void qDrawBorderPixmap(QPainter *painter,
const QRect &targetRect,
const QMargins &targetMarginsIn,
22 const QPixmap &pixmap,
const QRect &sourceRect,
const QMargins &sourceMarginsIn,
23 const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
25 QPainter::PixmapFragment d;
32 QMargins sourceMargins = normalizedMargins(sourceMarginsIn);
33 QMargins targetMargins = normalizedMargins(targetMarginsIn);
35 const qreal sourceDpr = pixmap.devicePixelRatio();
36 sourceMargins *= sourceDpr;
39 const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
40 const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
41 const int sourceCenterBottom = sourceRect.bottom() - sourceMargins.bottom() + 1;
42 const int sourceCenterRight = sourceRect.right() - sourceMargins.right() + 1;
43 const int sourceCenterWidth = sourceCenterRight - sourceCenterLeft;
44 const int sourceCenterHeight = sourceCenterBottom - sourceCenterTop;
46 const int targetCenterTop = targetRect.top() + targetMargins.top();
47 const int targetCenterLeft = targetRect.left() + targetMargins.left();
48 const int targetCenterBottom = targetRect.bottom() - targetMargins.bottom() + 1;
49 const int targetCenterRight = targetRect.right() - targetMargins.right() + 1;
50 const int targetCenterWidth = targetCenterRight - targetCenterLeft;
51 const int targetCenterHeight = targetCenterBottom - targetCenterTop;
53 QVarLengthArray<qreal, 16> xTarget;
54 QVarLengthArray<qreal, 16> yTarget;
58 if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
59 columns = qMax(3, 2 + qCeil((targetCenterWidth * sourceDpr) / qreal(sourceCenterWidth)));
60 if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
61 rows = qMax(3, 2 + qCeil((targetCenterHeight * sourceDpr) / qreal(sourceCenterHeight)));
63 xTarget.resize(columns + 1);
64 yTarget.resize(rows + 1);
66 xTarget[0] = targetRect.left();
67 xTarget[1] = targetCenterLeft;
68 xTarget[columns - 1] = targetCenterRight;
69 xTarget[columns] = targetRect.left() + targetRect.width();
71 yTarget[0] = targetRect.top();
72 yTarget[1] = targetCenterTop;
73 yTarget[rows - 1] = targetCenterBottom;
74 yTarget[rows] = targetRect.top() + targetRect.height();
76 qreal dx = targetCenterWidth;
77 qreal dy = targetCenterHeight;
79 switch (rules.horizontal) {
81 dx = targetCenterWidth;
84 dx = sourceCenterWidth / sourceDpr;
87 dx = targetCenterWidth / qreal(columns - 2);
91 for (
int i = 2; i < columns - 1; ++i)
92 xTarget[i] = xTarget[i - 1] + dx;
94 switch (rules.vertical) {
96 dy = targetCenterHeight;
99 dy = sourceCenterHeight / sourceDpr;
102 dy = targetCenterHeight / qreal(rows - 2);
106 for (
int i = 2; i < rows - 1; ++i)
107 yTarget[i] = yTarget[i - 1] + dy;
110 if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) {
111 d.x = (0.5 * (xTarget[1] + xTarget[0]));
112 d.y = (0.5 * (yTarget[1] + yTarget[0]));
113 d.sourceLeft = sourceRect.left();
114 d.sourceTop = sourceRect.top();
115 d.width = sourceMargins.left();
116 d.height = sourceMargins.top();
117 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
118 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
120 opaqueData.append(d);
122 translucentData.append(d);
124 if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) {
125 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
126 d.y = (0.5 * (yTarget[1] + yTarget[0]));
127 d.sourceLeft = sourceCenterRight;
128 d.sourceTop = sourceRect.top();
129 d.width = sourceMargins.right();
130 d.height = sourceMargins.top();
131 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
132 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
134 opaqueData.append(d);
136 translucentData.append(d);
138 if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) {
139 d.x = (0.5 * (xTarget[1] + xTarget[0]));
140 d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1]));
141 d.sourceLeft = sourceRect.left();
142 d.sourceTop = sourceCenterBottom;
143 d.width = sourceMargins.left();
144 d.height = sourceMargins.bottom();
145 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
146 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
148 opaqueData.append(d);
150 translucentData.append(d);
152 if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) {
153 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
154 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
155 d.sourceLeft = sourceCenterRight;
156 d.sourceTop = sourceCenterBottom;
157 d.width = sourceMargins.right();
158 d.height = sourceMargins.bottom();
159 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
160 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
162 opaqueData.append(d);
164 translucentData.append(d);
168 if (targetCenterWidth > 0 && sourceCenterWidth > 0) {
169 if (targetMargins.top() > 0 && sourceMargins.top() > 0) {
171 d.sourceLeft = sourceCenterLeft;
172 d.sourceTop = sourceRect.top();
173 d.width = sourceCenterWidth;
174 d.height = sourceMargins.top();
175 d.y = (0.5 * (yTarget[1] + yTarget[0]));
176 d.scaleX = dx / d.width;
177 d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height;
178 for (
int i = 1; i < columns - 1; ++i) {
179 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
182 if (rules.horizontal == Qt::RepeatTile)
183 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
185 if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) {
187 d.sourceLeft = sourceCenterLeft;
188 d.sourceTop = sourceCenterBottom;
189 d.width = sourceCenterWidth;
190 d.height = sourceMargins.bottom();
191 d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1]));
192 d.scaleX = dx / d.width;
193 d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height;
194 for (
int i = 1; i < columns - 1; ++i) {
195 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
198 if (rules.horizontal == Qt::RepeatTile)
199 data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX);
204 if (targetCenterHeight > 0 && sourceCenterHeight > 0) {
205 if (targetMargins.left() > 0 && sourceMargins.left() > 0) {
207 d.sourceLeft = sourceRect.left();
208 d.sourceTop = sourceCenterTop;
209 d.width = sourceMargins.left();
210 d.height = sourceCenterHeight;
211 d.x = (0.5 * (xTarget[1] + xTarget[0]));
212 d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width;
213 d.scaleY = dy / d.height;
214 for (
int i = 1; i < rows - 1; ++i) {
215 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
218 if (rules.vertical == Qt::RepeatTile)
219 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
221 if (targetMargins.right() > 0 && sourceMargins.right() > 0) {
223 d.sourceLeft = sourceCenterRight;
224 d.sourceTop = sourceCenterTop;
225 d.width = sourceMargins.right();
226 d.height = sourceCenterHeight;
227 d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1]));
228 d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width;
229 d.scaleY = dy / d.height;
230 for (
int i = 1; i < rows - 1; ++i) {
231 d.y = (0.5 * (yTarget[i + 1] + yTarget[i]));
234 if (rules.vertical == Qt::RepeatTile)
235 data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY);
240 if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) {
242 d.sourceLeft = sourceCenterLeft;
243 d.sourceTop = sourceCenterTop;
244 d.width = sourceCenterWidth;
245 d.height = sourceCenterHeight;
246 d.scaleX = dx / d.width;
247 d.scaleY = dy / d.height;
249 qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX;
250 qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY;
252 for (
int j = 1; j < rows - 1; ++j) {
253 d.y = (0.5 * (yTarget[j + 1] + yTarget[j]));
254 for (
int i = 1; i < columns - 1; ++i) {
255 d.x = (0.5 * (xTarget[i + 1] + xTarget[i]));
258 if (rules.horizontal == Qt::RepeatTile)
259 data[data.size() - 1].width = repeatWidth;
261 if (rules.vertical == Qt::RepeatTile) {
262 for (
int i = 1; i < columns - 1; ++i)
263 data[data.size() - i].height = repeatHeight;
267 if (opaqueData.size())
268 painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint);
269 if (translucentData.size())
270 painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap);
408 painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
410 painter->setRenderHint(QPainter::Antialiasing,
false);
412 updateCachedMirroredPixmap();
413 const QPixmap &pm = m_mirrorHorizontally || m_mirrorVertically || m_textureIsLayer ? m_cachedMirroredPixmap : pixmap();
415 if (m_innerTargetRect != m_targetRect) {
417 QMargins margins(m_innerTargetRect.left() - m_targetRect.left(), m_innerTargetRect.top() - m_targetRect.top(),
418 m_targetRect.right() - m_innerTargetRect.right(), m_targetRect.bottom() - m_innerTargetRect.bottom());
419 QSGSoftwareHelpers::QTileRules tilerules(getTileRule(m_subSourceRect.width()), getTileRule(m_subSourceRect.height()));
420 QSGSoftwareHelpers::qDrawBorderPixmap(painter, m_targetRect.toRect(), margins, pm, QRect(0, 0, pm.width(), pm.height()),
421 margins, tilerules, QSGSoftwareHelpers::QDrawBorderPixmap::DrawingHints{});
425 if (m_tileHorizontal || m_tileVertical) {
427 qreal sx = m_targetRect.width()/(m_subSourceRect.width()*pm.width());
428 qreal sy = m_targetRect.height()/(m_subSourceRect.height()*pm.height());
429 painter->setTransform(QTransform::fromScale(sx, sy),
true);
430 painter->drawTiledPixmap(QRectF(m_targetRect.x()/sx, m_targetRect.y()/sy, m_targetRect.width()/sx, m_targetRect.height()/sy),
432 QPointF(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height()));
435 QRectF sr(m_subSourceRect.left()*pm.width(), m_subSourceRect.top()*pm.height(),
436 m_subSourceRect.width()*pm.width(), m_subSourceRect.height()*pm.height());
437 painter->drawPixmap(m_targetRect, pm, sr);