1 /*
2   quickdecorationsdrawer.cpp
3 
4   This file is part of GammaRay, the Qt application inspection and
5   manipulation tool.
6 
7   Copyright (C) 2010-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
8   Author: Filipe Azevedo <filipe.azevedo@kdab.com>
9 
10   Licensees holding valid commercial KDAB GammaRay licenses may use this file in
11   accordance with GammaRay Commercial License Agreement provided with the Software.
12 
13   Contact info@kdab.com if any conditions of this licensing are not clear to you.
14 
15   This program is free software; you can redistribute it and/or modify
16   it under the terms of the GNU General Public License as published by
17   the Free Software Foundation, either version 2 of the License, or
18   (at your option) any later version.
19 
20   This program is distributed in the hope that it will be useful,
21   but WITHOUT ANY WARRANTY; without even the implied warranty of
22   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23   GNU General Public License for more details.
24 
25   You should have received a copy of the GNU General Public License
26   along with this program.  If not, see <http://www.gnu.org/licenses/>.
27 */
28 
29 #include "quickdecorationsdrawer.h"
30 
31 #include <compat/qasconst.h>
32 
33 #include <QDebug>
34 #include <QPainter>
35 #include <QVector2D>
36 
37 #ifndef GL_BGRA
38 #define GL_BGRA GL_BGRA_EXT
39 #endif
40 
41 using namespace GammaRay;
42 
QuickDecorationsDrawer(QuickDecorationsDrawer::Type type,QPainter & painter,const QuickDecorationsBaseRenderInfo & renderInfo)43 QuickDecorationsDrawer::QuickDecorationsDrawer(QuickDecorationsDrawer::Type type,
44                                                QPainter &painter,
45                                                const QuickDecorationsBaseRenderInfo &renderInfo)
46     : m_type(type)
47     , m_renderInfo(&renderInfo)
48     , m_painter(&painter)
49 {
50     Q_ASSERT(m_painter);
51     Q_ASSERT(m_renderInfo);
52 }
53 
render()54 void QuickDecorationsDrawer::render()
55 {
56     // Draw the grid if needed
57     drawGrid();
58 
59     switch (m_type) {
60     case QuickDecorationsDrawer::Decorations: {
61         drawDecorations();
62         break;
63     }
64 
65     case QuickDecorationsDrawer::Traces: {
66         drawTraces();
67         break;
68     }
69     }
70 }
71 
drawDecorations()72 void QuickDecorationsDrawer::drawDecorations()
73 {
74     QuickItemGeometry itemGeometry(this->itemGeometry());
75 
76     if (!itemGeometry.isValid())
77         return;
78 
79     const qreal &zoom(m_renderInfo->zoom);
80     DrawTextInfoList texts;
81 
82     itemGeometry.scaleTo(zoom);
83 
84     m_painter->save();
85 
86     // bounding box
87     if (itemGeometry.boundingRect.isValid()) {
88         m_painter->setPen(m_renderInfo->settings.boundingRectColor);
89         m_painter->setBrush(m_renderInfo->settings.boundingRectBrush);
90         m_painter->drawRect(itemGeometry.boundingRect);
91     }
92 
93     // original geometry
94     if (itemGeometry.itemRect.isValid() && itemGeometry.itemRect != itemGeometry.boundingRect) {
95         m_painter->setPen(m_renderInfo->settings.geometryRectColor);
96         m_painter->setBrush(m_renderInfo->settings.geometryRectBrush);
97         m_painter->drawRect(itemGeometry.itemRect);
98     }
99 
100     // children rect
101     if (itemGeometry.childrenRect.isValid() && itemGeometry.itemRect != itemGeometry.boundingRect &&
102             itemGeometry.transform.isIdentity()) {
103         // If this item is transformed the children rect will be painted wrongly,
104         // so for now skip painting it.
105         m_painter->setPen(m_renderInfo->settings.childrenRectColor);
106         m_painter->setBrush(m_renderInfo->settings.childrenRectBrush);
107         m_painter->drawRect(itemGeometry.childrenRect);
108     }
109 
110     // transform origin
111     if (itemGeometry.itemRect != itemGeometry.boundingRect) {
112         m_painter->setPen(m_renderInfo->settings.transformOriginColor);
113         m_painter->drawEllipse(itemGeometry.transformOriginPoint, 2.5, 2.5);
114         m_painter->drawLine(itemGeometry.transformOriginPoint - QPointF(0, 6),
115                           itemGeometry.transformOriginPoint + QPointF(0, 6));
116         m_painter->drawLine(itemGeometry.transformOriginPoint - QPointF(6, 0),
117                           itemGeometry.transformOriginPoint + QPointF(6, 0));
118     }
119 
120     // x and y values
121     m_painter->setPen(m_renderInfo->settings.coordinatesColor);
122     if (!itemGeometry.left &&
123             !itemGeometry.horizontalCenter &&
124             !itemGeometry.right &&
125             itemGeometry.x != 0) {
126         QPointF parentEnd = (QPointF(itemGeometry.itemRect.x() - itemGeometry.x,
127                                      itemGeometry.itemRect.y()));
128         QPointF itemEnd = itemGeometry.itemRect.topLeft();
129         drawArrow(parentEnd, itemEnd);
130         texts << DrawTextInfo(m_painter->pen(),
131                               QRectF(parentEnd.x(), parentEnd.y() + 10, itemEnd.x() - parentEnd.x(), 50),
132                               QStringLiteral("x: %1px").arg(itemGeometry.x / zoom),
133                               Qt::AlignHCenter | Qt::TextDontClip);
134     }
135     if (!itemGeometry.top &&
136             !itemGeometry.verticalCenter &&
137             !itemGeometry.bottom &&
138             !itemGeometry.baseline &&
139             itemGeometry.y != 0) {
140         QPointF parentEnd = (QPointF(itemGeometry.itemRect.x(),
141                                      itemGeometry.itemRect.y() - itemGeometry.y));
142         QPointF itemEnd = itemGeometry.itemRect.topLeft();
143         drawArrow(parentEnd, itemEnd);
144         texts << DrawTextInfo(m_painter->pen(),
145                               QRectF(parentEnd.x() + 10, parentEnd.y(), 100, itemEnd.y() - parentEnd.y()),
146                               QStringLiteral("y: %1px").arg(itemGeometry.y / zoom),
147                               Qt::AlignVCenter | Qt::TextDontClip);
148     }
149 
150     // anchors
151     m_painter->setPen(m_renderInfo->settings.marginsColor);
152 
153     if (itemGeometry.left) {
154         drawHorizontalAnchor(itemGeometry, itemGeometry.itemRect.left(),
155                              itemGeometry.leftMargin);
156         texts << drawHorizontalAnchorLabel(itemGeometry,
157                                            itemGeometry.itemRect.left(),
158                                            itemGeometry.leftMargin,
159                                            QStringLiteral("%1px").arg(itemGeometry.leftMargin / zoom),
160                                            Qt::AlignBottom | Qt::AlignHCenter);
161     }
162 
163     if (itemGeometry.horizontalCenter) {
164         drawHorizontalAnchor(itemGeometry,
165                              (itemGeometry.itemRect.left() + itemGeometry.itemRect.right()) / 2,
166                              itemGeometry.horizontalCenterOffset);
167         texts << drawHorizontalAnchorLabel(itemGeometry,
168                                            (itemGeometry.itemRect.left() + itemGeometry.itemRect.right()) / 2,
169                                            itemGeometry.horizontalCenterOffset,
170                                            QStringLiteral("offset: %1px").arg(itemGeometry.horizontalCenterOffset / zoom),
171                                            Qt::AlignBottom | Qt::AlignHCenter);
172     }
173 
174     if (itemGeometry.right) {
175         drawHorizontalAnchor(itemGeometry,
176                              itemGeometry.itemRect.right(),
177                              -itemGeometry.rightMargin);
178         texts << drawHorizontalAnchorLabel(itemGeometry,
179                                            itemGeometry.itemRect.right(),
180                                            -itemGeometry.rightMargin,
181                                            QStringLiteral("%1px").arg(itemGeometry.rightMargin / zoom),
182                                            Qt::AlignTop | Qt::AlignHCenter);
183     }
184 
185     if (itemGeometry.top) {
186         drawVerticalAnchor(itemGeometry,
187                            itemGeometry.itemRect.top(),
188                            itemGeometry.topMargin);
189         texts << drawVerticalAnchorLabel(itemGeometry,
190                                          itemGeometry.itemRect.top(),
191                                          itemGeometry.topMargin,
192                                          QStringLiteral("%1px").arg(itemGeometry.topMargin / zoom),
193                                          Qt::AlignVCenter | Qt::AlignRight);
194     }
195 
196     if (itemGeometry.verticalCenter) {
197         drawVerticalAnchor(itemGeometry,
198                            (itemGeometry.itemRect.top() + itemGeometry.itemRect.bottom()) / 2,
199                            itemGeometry.verticalCenterOffset);
200         texts << drawVerticalAnchorLabel(itemGeometry,
201                                          (itemGeometry.itemRect.top() + itemGeometry.itemRect.bottom()) / 2,
202                                          itemGeometry.verticalCenterOffset,
203                                          QStringLiteral("offset: %1px").arg(itemGeometry.verticalCenterOffset / zoom),
204                                          Qt::AlignVCenter | Qt::AlignRight);
205     }
206 
207     if (itemGeometry.bottom) {
208         drawVerticalAnchor(itemGeometry,
209                            itemGeometry.itemRect.bottom(),
210                            -itemGeometry.bottomMargin);
211         texts << drawVerticalAnchorLabel(itemGeometry,
212                                          itemGeometry.itemRect.bottom(),
213                                          -itemGeometry.bottomMargin,
214                                          QStringLiteral("%1px").arg(itemGeometry.bottomMargin / zoom),
215                                          Qt::AlignVCenter | Qt::AlignLeft);
216     }
217 
218     if (itemGeometry.baseline) {
219         drawVerticalAnchor(itemGeometry,
220                            itemGeometry.itemRect.top(),
221                            itemGeometry.baselineOffset);
222         texts << drawVerticalAnchorLabel(itemGeometry,
223                                          itemGeometry.itemRect.top(), itemGeometry.baselineOffset,
224                                          QStringLiteral("offset: %1px").arg(itemGeometry.baselineOffset / zoom),
225                                          Qt::AlignVCenter | Qt::AlignLeft);
226     }
227 
228     // padding
229     m_painter->setPen(m_renderInfo->settings.paddingColor);
230 
231     if (!qIsNaN(itemGeometry.leftPadding)) {
232         drawHorizontalAnchor(itemGeometry,
233                              itemGeometry.itemRect.left(),
234                              -itemGeometry.leftPadding);
235         texts << drawHorizontalAnchorLabel(itemGeometry,
236                                            itemGeometry.itemRect.left(),
237                                            -itemGeometry.leftPadding,
238                                            QStringLiteral("%1px").arg(itemGeometry.leftPadding / zoom),
239                                            Qt::AlignTop | Qt::AlignHCenter);
240     }
241 
242     if (!qIsNaN(itemGeometry.rightPadding)) {
243         drawHorizontalAnchor(itemGeometry,
244                              itemGeometry.itemRect.right(),
245                              itemGeometry.rightPadding);
246         texts << drawHorizontalAnchorLabel(itemGeometry,
247                                            itemGeometry.itemRect.right(),
248                                            itemGeometry.rightPadding,
249                                            QStringLiteral("%1px").arg(itemGeometry.rightPadding / zoom),
250                                            Qt::AlignBottom | Qt::AlignHCenter);
251     }
252 
253     if (!qIsNaN(itemGeometry.topPadding)) {
254         drawVerticalAnchor(itemGeometry,
255                            itemGeometry.itemRect.top(),
256                            -itemGeometry.topPadding);
257         texts << drawVerticalAnchorLabel(itemGeometry,
258                                          itemGeometry.itemRect.top(),
259                                          -itemGeometry.topPadding,
260                                          QStringLiteral("%1px").arg(itemGeometry.topPadding / zoom),
261                                          Qt::AlignVCenter | Qt::AlignLeft);
262     }
263 
264     if (!qIsNaN(itemGeometry.bottomPadding)) {
265         drawVerticalAnchor(itemGeometry,
266                            itemGeometry.itemRect.bottom(),
267                            itemGeometry.bottomPadding);
268         texts << drawVerticalAnchorLabel(itemGeometry,
269                                          itemGeometry.itemRect.bottom(),
270                                          itemGeometry.bottomPadding,
271                                          QStringLiteral("%1px").arg(itemGeometry.bottomPadding / zoom),
272                                          Qt::AlignVCenter | Qt::AlignRight);
273     }
274 
275     // Finally draw texts over the traced rectangles and lines
276     // This make sure texts are always readable
277     for (const auto &t : qAsConst(texts)) {
278         if (t.label.isEmpty())
279             continue;
280 
281         m_painter->setPen(t.pen);
282         m_painter->drawText(t.rect, t.align, t.label);
283     }
284 
285     m_painter->restore();
286 }
287 
drawTraces()288 void QuickDecorationsDrawer::drawTraces()
289 {
290     const QVector<QuickItemGeometry> itemsGeometry(this->itemsGeometry());
291 
292     if (itemsGeometry.isEmpty())
293         return;
294 
295     m_painter->save();
296 
297     for (auto itemGeometry : itemsGeometry) {
298         itemGeometry.scaleTo(m_renderInfo->zoom);
299 
300         // bounding box
301         m_painter->setPen(itemGeometry.traceColor);
302         m_painter->setBrush(itemGeometry.traceColor.lighter());
303         m_painter->drawRect(itemGeometry.boundingRect);
304 
305         // bounding class box
306         m_painter->setPen(QColor(60, 60, 60, 70));
307         m_painter->setBrush(m_painter->pen().color());
308 
309         const int margin = m_painter->fontMetrics().width(QLatin1Char('X')) / 2;
310         const QRectF classRect =
311             itemGeometry.boundingRect.adjusted(
312                 0, 0, 0,
313                 -(itemGeometry.boundingRect.height() - (m_painter->fontMetrics().height() * 1.6)));
314         m_painter->drawRect(classRect);
315 
316         // type name label
317         m_painter->setPen(QColor(250, 250, 250, 120));
318         m_painter->drawText(classRect.adjusted(margin, margin, -margin, -margin),
319                           Qt::AlignVCenter | Qt::AlignLeft | Qt::TextDontClip,
320                           itemGeometry.traceTypeName);
321 
322         // draw bounding box corners
323         m_painter->setPen(QPen(QColor(30, 30, 30), 3));
324         m_painter->setBrush(m_painter->pen().color());
325         const QVector<QPointF> points = QVector<QPointF>()
326                 << itemGeometry.boundingRect.topLeft()
327                 << itemGeometry.boundingRect.topRight()
328                 << itemGeometry.boundingRect.bottomRight()
329                 << itemGeometry.boundingRect.bottomLeft();
330         m_painter->drawPoints(points);
331 
332         // name label
333         m_painter->setPen(QColor(250, 250, 250, 120));
334         m_painter->drawText(itemGeometry.boundingRect.adjusted(margin, margin, -margin, -margin),
335                           Qt::AlignVCenter | Qt::AlignLeft | Qt::TextDontClip,
336                           itemGeometry.traceName);
337     }
338 
339     m_painter->restore();
340 }
341 
itemGeometry() const342 QuickItemGeometry QuickDecorationsDrawer::itemGeometry() const
343 {
344     switch (m_type) {
345     case QuickDecorationsDrawer::Decorations:
346         return static_cast<const QuickDecorationsRenderInfo *>(m_renderInfo)->itemGeometry;
347     case QuickDecorationsDrawer::Traces:
348         break;
349     }
350 
351     return QuickItemGeometry();
352 }
353 
itemsGeometry() const354 QVector<QuickItemGeometry> QuickDecorationsDrawer::itemsGeometry() const
355 {
356     switch (m_type) {
357     case QuickDecorationsDrawer::Decorations:
358         break;
359     case QuickDecorationsDrawer::Traces:
360         return static_cast<const QuickDecorationsTracesInfo *>(m_renderInfo)->itemsGeometry;
361     }
362 
363     return QVector<QuickItemGeometry>();
364 }
365 
drawGrid()366 void QuickDecorationsDrawer::drawGrid()
367 {
368     const QRectF &viewRect(m_renderInfo->viewRect);
369     const QPointF &gridOffset(m_renderInfo->settings.gridOffset);
370     const QSizeF &gridCellSize(m_renderInfo->settings.gridCellSize);
371 
372     if (!m_renderInfo->settings.gridEnabled || gridCellSize.isEmpty())
373         return;
374 
375     m_painter->save();
376     m_painter->setPen(m_renderInfo->settings.gridColor);
377 
378     QVector<QLineF> lines;
379     lines.reserve((viewRect.width() / gridCellSize.width()) +
380                   (viewRect.height() / gridCellSize.height()));
381 
382     for (qreal x = viewRect.left() + gridOffset.x(); x < viewRect.right(); x += gridCellSize.width()) {
383         if (x < viewRect.left())
384             continue;
385 
386         lines << QLineF(QPointF(x, viewRect.top()) * m_renderInfo->zoom,
387                         QPointF(x, viewRect.bottom()) * m_renderInfo->zoom);
388     }
389 
390     for (qreal y = viewRect.top() + gridOffset.y(); y < viewRect.bottom(); y += gridCellSize.height()) {
391         if (y < viewRect.top())
392             continue;
393 
394         lines << QLineF(QPointF(viewRect.left(), y) * m_renderInfo->zoom,
395                         QPointF(viewRect.right(), y) * m_renderInfo->zoom);
396     }
397 
398     m_painter->drawLines(lines);
399     m_painter->restore();
400 }
401 
drawArrow(const QPointF & first,const QPointF & second)402 void QuickDecorationsDrawer::drawArrow(const QPointF &first, const QPointF &second)
403 {
404     m_painter->drawLine(first, second);
405     QPointF vector(second - first);
406     QMatrix m;
407     m.rotate(30);
408     QVector2D v1 = QVector2D(m.map(vector)).normalized() * 10;
409     m.rotate(-60);
410     QVector2D v2 = QVector2D(m.map(vector)).normalized() * 10;
411     m_painter->drawLine(first, first + v1.toPointF());
412     m_painter->drawLine(first, first + v2.toPointF());
413     m_painter->drawLine(second, second - v1.toPointF());
414     m_painter->drawLine(second, second - v2.toPointF());
415 }
416 
drawAnchor(const QuickItemGeometry & itemGeometry,Qt::Orientation orientation,qreal ownAnchorLine,qreal offset)417 void QuickDecorationsDrawer::drawAnchor(const QuickItemGeometry &itemGeometry, Qt::Orientation orientation, qreal ownAnchorLine, qreal offset)
418 {
419     const QRectF &viewRect(m_renderInfo->viewRect);
420     const qreal &zoom(m_renderInfo->zoom);
421 
422     m_painter->save();
423 
424     const qreal foreignAnchorLine = ownAnchorLine - offset;
425 
426     // Arrow
427     if (offset) {
428         if (orientation == Qt::Horizontal) {
429             drawArrow(QPointF(foreignAnchorLine,
430                               (itemGeometry.itemRect.top() + itemGeometry.itemRect.bottom()) / 2),
431                       QPointF(ownAnchorLine,
432                               (itemGeometry.itemRect.top() + itemGeometry.itemRect.bottom()) / 2));
433         } else {
434             drawArrow(QPointF((itemGeometry.itemRect.left() + itemGeometry.itemRect.right()) / 2,
435                               foreignAnchorLine),
436                       QPointF((itemGeometry.itemRect.left() + itemGeometry.itemRect.right()) / 2,
437                               ownAnchorLine));
438         }
439     }
440 
441     // Own Anchor line
442     QPen pen(m_painter->pen());
443     pen.setWidth(2);
444     m_painter->setPen(pen);
445     if (orientation == Qt::Horizontal) {
446         m_painter->drawLine(ownAnchorLine,
447                     itemGeometry.itemRect.top(), ownAnchorLine,
448                     itemGeometry.itemRect.bottom());
449     } else {
450         m_painter->drawLine(
451                     itemGeometry.itemRect.left(), ownAnchorLine,
452                     itemGeometry.itemRect.right(), ownAnchorLine);
453     }
454 
455     // Foreign Anchor line
456     pen.setStyle(Qt::DotLine);
457     m_painter->setPen(pen);
458     if (orientation == Qt::Horizontal) {
459         m_painter->drawLine(foreignAnchorLine, 0, foreignAnchorLine, viewRect.height() * zoom);
460     } else {
461         m_painter->drawLine(0, foreignAnchorLine, viewRect.width() * zoom, foreignAnchorLine);
462     }
463 
464     m_painter->restore();
465 }
466 
drawVerticalAnchor(const QuickItemGeometry & itemGeometry,qreal ownAnchorLine,qreal offset)467 void QuickDecorationsDrawer::drawVerticalAnchor(const QuickItemGeometry &itemGeometry,
468                                                 qreal ownAnchorLine, qreal offset)
469 {
470     drawAnchor(itemGeometry, Qt::Vertical, ownAnchorLine, offset);
471 }
472 
drawHorizontalAnchor(const QuickItemGeometry & itemGeometry,qreal ownAnchorLine,qreal offset)473 void QuickDecorationsDrawer::drawHorizontalAnchor(const QuickItemGeometry &itemGeometry,
474                                                   qreal ownAnchorLine, qreal offset)
475 {
476     drawAnchor(itemGeometry, Qt::Horizontal, ownAnchorLine, offset);
477 }
478 
drawAnchorLabel(const QuickItemGeometry & itemGeometry,Qt::Orientation orientation,qreal ownAnchorLine,qreal offset,const QString & label,Qt::Alignment align)479 QuickDecorationsDrawer::DrawTextInfo QuickDecorationsDrawer::drawAnchorLabel(const QuickItemGeometry &itemGeometry,
480                                                          Qt::Orientation orientation, qreal ownAnchorLine, qreal offset, const QString &label, Qt::Alignment align)
481 {
482     if (align.testFlag(Qt::AlignCenter)) {
483         qWarning("%s: You can not use Qt::AlignCenter!", Q_FUNC_INFO);
484         return QuickDecorationsDrawer::DrawTextInfo();
485     }
486 
487     if (align.testFlag(Qt::AlignJustify)) {
488         qWarning("%s: You can not use Qt::AlignJustify!", Q_FUNC_INFO);
489         return QuickDecorationsDrawer::DrawTextInfo();
490     }
491 
492     if (align.testFlag(Qt::AlignBaseline)) {
493         qWarning("%s: You can not use Qt::AlignBaseline!", Q_FUNC_INFO);
494         return QuickDecorationsDrawer::DrawTextInfo();
495     }
496 
497     if (offset) {
498         const qreal foreignAnchorLine = ownAnchorLine - offset;
499         const int margin = 10;
500 
501         if (orientation == Qt::Horizontal) {
502             QRectF rect(m_painter->fontMetrics().boundingRect(label));
503 
504             QPointF center(foreignAnchorLine + ((ownAnchorLine - foreignAnchorLine) / 2),
505                            itemGeometry.itemRect.center().y());
506 
507             if (align.testFlag(Qt::AlignLeft)) {
508                 rect.moveRight(center.x());
509 
510                 if (align.testFlag(Qt::AlignVCenter)) {
511                     rect.moveRight(foreignAnchorLine - margin);
512                 }
513             } else if (align.testFlag(Qt::AlignRight)) {
514                 rect.moveLeft(center.x());
515 
516                 if (align.testFlag(Qt::AlignVCenter)) {
517                     rect.moveLeft(foreignAnchorLine + offset + margin);
518                 }
519             } else if (align.testFlag(Qt::AlignHCenter)) {
520                 rect.moveCenter(QPointF(center.x(), rect.center().y()));
521             }
522 
523             if (align.testFlag(Qt::AlignTop)) {
524                 rect.moveBottom(center.y() - margin);
525             } else if (align.testFlag(Qt::AlignBottom)) {
526                 rect.moveTop(center.y() + margin);
527             } else if (align.testFlag(Qt::AlignVCenter)) {
528                 rect.moveCenter(QPointF(rect.center().x(), center.y()));
529             }
530 
531             return QuickDecorationsDrawer::DrawTextInfo(
532                         m_painter->pen(),
533                         rect,
534                         label
535                         );
536         } else {
537             QRectF rect(m_painter->fontMetrics().boundingRect(label));
538 
539             QPointF center(itemGeometry.itemRect.center().x(),
540                            foreignAnchorLine + ((ownAnchorLine - foreignAnchorLine) / 2));
541 
542             if (align.testFlag(Qt::AlignLeft)) {
543                 rect.moveRight(center.x() - margin);
544             } else if (align.testFlag(Qt::AlignRight)) {
545                 rect.moveLeft(center.x() + margin);
546             } else if (align.testFlag(Qt::AlignHCenter)) {
547                 rect.moveCenter(QPointF(center.x(), rect.center().y()));
548             }
549 
550             if (align.testFlag(Qt::AlignTop)) {
551                 rect.moveBottom(center.y());
552             } else if (align.testFlag(Qt::AlignBottom)) {
553                 rect.moveTop(center.y());
554             } else if (align.testFlag(Qt::AlignVCenter)) {
555                 rect.moveCenter(QPointF(rect.center().x(), center.y()));
556             }
557 
558             return QuickDecorationsDrawer::DrawTextInfo(
559                         m_painter->pen(),
560                         rect,
561                         label
562                         );
563         }
564     }
565 
566     return QuickDecorationsDrawer::DrawTextInfo();
567 }
568 
drawHorizontalAnchorLabel(const QuickItemGeometry & itemGeometry,qreal ownAnchorLine,qreal offset,const QString & label,Qt::Alignment align)569 QuickDecorationsDrawer::DrawTextInfo QuickDecorationsDrawer::drawHorizontalAnchorLabel(const QuickItemGeometry &itemGeometry,
570                                                                    qreal ownAnchorLine, qreal offset, const QString &label, Qt::Alignment align)
571 {
572     return drawAnchorLabel(itemGeometry, Qt::Horizontal, ownAnchorLine, offset, label, align);
573 }
574 
drawVerticalAnchorLabel(const QuickItemGeometry & itemGeometry,qreal ownAnchorLine,qreal offset,const QString & label,Qt::Alignment align)575 QuickDecorationsDrawer::DrawTextInfo QuickDecorationsDrawer::drawVerticalAnchorLabel(const QuickItemGeometry &itemGeometry,
576                                                                  qreal ownAnchorLine, qreal offset, const QString &label, Qt::Alignment align)
577 {
578     return drawAnchorLabel(itemGeometry, Qt::Vertical, ownAnchorLine, offset, label, align);
579 }
580 
operator <<(QDataStream & stream,const GammaRay::QuickDecorationsSettings & settings)581 QDataStream &GammaRay::operator<<(QDataStream &stream, const GammaRay::QuickDecorationsSettings &settings)
582 {
583     stream
584             << settings.boundingRectColor
585             << settings.boundingRectBrush
586             << settings.geometryRectColor
587             << settings.geometryRectBrush
588             << settings.childrenRectColor
589             << settings.childrenRectBrush
590             << settings.transformOriginColor
591             << settings.coordinatesColor
592             << settings.marginsColor
593             << settings.paddingColor
594             << settings.gridOffset
595             << settings.gridCellSize
596             << settings.gridColor
597             << settings.componentsTraces
598             << settings.gridEnabled
599     ;
600 
601     return stream;
602 }
603 
operator >>(QDataStream & stream,GammaRay::QuickDecorationsSettings & settings)604 QDataStream &GammaRay::operator>>(QDataStream &stream, GammaRay::QuickDecorationsSettings &settings)
605 {
606     stream
607             >> settings.boundingRectColor
608             >> settings.boundingRectBrush
609             >> settings.geometryRectColor
610             >> settings.geometryRectBrush
611             >> settings.childrenRectColor
612             >> settings.childrenRectBrush
613             >> settings.transformOriginColor
614             >> settings.coordinatesColor
615             >> settings.marginsColor
616             >> settings.paddingColor
617             >> settings.gridOffset
618             >> settings.gridCellSize
619             >> settings.gridColor
620             >> settings.componentsTraces
621             >> settings.gridEnabled
622     ;
623 
624     return stream;
625 }
626