Krita Source Code Documentation
Loading...
Searching...
No Matches
KoShapeQtQuickLabel.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
7#include <KoShape.h>
8#include <SvgParser.h>
9#include <KoColorBackground.h>
11#include <QQuickWindow>
12#include <KoShapeGroupCommand.h>
14#include <KoShapePainter.h>
15#include <kis_assert.h>
16
18
20
21 }
22
24 shapePainter.reset();
25 qDeleteAll(shapes);
26 }
27
29 QScopedPointer<KoShapePainter> shapePainter;
30 QString svgData;
31
32 QColor fgColor = Qt::black;
33 bool fullColor = false;
35 Qt::Alignment alignment = Qt::AlignHCenter | Qt::AlignVCenter;
36
38
39 int leftPadding = 0;
40 int rightPadding = 0;
41 int topPadding = 0;
43
44 QRectF adjustBBoxToScaling(const QRectF &bbox, const QRectF &widgetBounds) {
45 const double newWidth = widgetBounds.width() - (leftPadding + rightPadding);
46 const double newHeight = widgetBounds.height() - (topPadding + bottomPadding);
47
48 QRectF newBox = bbox;
50 const double docWidth = bbox.width();
51 const double docHeight = bbox.width() * (newHeight / newWidth);
52 double docY = bbox.top();
53 if (alignment.testFlag(Qt::AlignBottom)) {
54 docY = bbox.bottom() - docHeight;
55 } else if (alignment.testFlag(Qt::AlignVCenter)) {
56 docY = (bbox.bottom()*0.5) - (docHeight*0.5);
57 }
58 newBox = QRectF(bbox.left(), docY, docWidth, docHeight);
60 const double docWidth = bbox.height() * (newWidth / newHeight);
61 const double docHeight = bbox.height();
62 double docX = bbox.left();
63 if (alignment.testFlag(Qt::AlignRight)) {
64 docX = bbox.right() - docWidth;
65 } else if (alignment.testFlag(Qt::AlignHCenter)) {
66 docX = (bbox.right()*0.5) - (docWidth*0.5);
67 }
68 newBox = QRectF(docX, bbox.top(), docWidth, docHeight);
69 }
70 const double newTop = (topPadding/newHeight) * newBox.height();
71 const double newBottom = (bottomPadding/newHeight) * newBox.height();
72 const double newLeft = (leftPadding/newWidth) * newBox.width();
73 const double newRight = (rightPadding/newWidth) * newBox.width();
74 return newBox.adjusted(-newLeft, -newTop, newRight, newBottom);
75 }
76
77 QRectF addPaddingToBounds(QRectF bounds) {
79 }
80
81};
82
84 : QQuickPaintedItem(parent)
85 , d(new Private())
86{
87 setAntialiasing(true);
88 setOpaquePainting(true);
89
90 connect(this, SIGNAL(minimumRectChanged()), this, SLOT(callUpdateIfComplete()));
91}
92
96
97void KoShapeQtQuickLabel::paint(QPainter *painter)
98{
99 if (!d->shapePainter) return;
100 if (!painter->isActive()) return;
101
102 const QRectF bbox = d->documentRect.isValid()? d->documentRect: d->shapePainter->contentRect();
103 const QRectF bounds = QRectF(0, 0, width(), height());
104
105 if (d->shapes.isEmpty()) {
106 return;
107 }
108
109 d->shapePainter->paint(*painter,
110 bounds.toAlignedRect(),
111 d->adjustBBoxToScaling(bbox, bounds));
112
113}
114
116{
117 return d->svgData;
118}
119
120void KoShapeQtQuickLabel::setSvgData(const QString &newSvgData)
121{
122 if (d->svgData == newSvgData)
123 return;
124 d->svgData = newSvgData;
125
126 QDomDocument doc = SvgParser::createDocumentFromSvg(d->svgData);
127 KoDocumentResourceManager resourceManager;
128 SvgParser p(&resourceManager);
129 QRectF bb = QRectF( 0, 0, 200, 200);
130 QSizeF sz = bb.size();
131 p.setResolution(bb, 72);
132 p.setFillStrokeInheritByDefault(true);
133
134 QList<KoShape*> shapes = p.parseSvg(doc.documentElement(), &sz);
135
136 // TODO: Evaluate if this can't be faster.
137 d->shapePainter.reset(new KoShapePainter());
138
139 if (!d->shapes.isEmpty()) {
140 qDeleteAll(d->shapes);
141 }
142
143 d->shapes = shapes;
144 d->shapePainter->setShapes(d->shapes);
145
146 updateShapes();
147
148 emit svgDataChanged();
149 emit minimumRectChanged();
150}
151
153{
154 return d->fgColor;
155}
156
157void KoShapeQtQuickLabel::setForegroundColor(const QColor &newForegroundColor)
158{
159 if (d->fgColor == newForegroundColor)
160 return;
161
162 d->fgColor = newForegroundColor;
163 updateShapes();
165}
166
168{
169 return (d->leftPadding + d->rightPadding + d->topPadding + d->bottomPadding) / 4;
170}
171
173{
174 const int currentPadding = (d->leftPadding + d->rightPadding + d->topPadding + d->bottomPadding) / 4;
175 if (currentPadding == newPadding)
176 return;
177 d->leftPadding = newPadding;
178 d->rightPadding = newPadding;
179 d->topPadding = newPadding;
180 d->bottomPadding = newPadding;
181
182 emit paddingChanged();
183 emit minimumRectChanged();
184}
185
187{
188 return d->fullColor;
189}
190
192{
193 if (d->fullColor == newFullColor)
194 return;
195 d->fullColor = newFullColor;
196
197 emit fullColorChanged();
198}
199
201{
202 return d->scalingType;
203}
204
206{
207 if (d->scalingType == type) return;
208 d->scalingType = type;
209 emit scalingTypeChanged();
210}
211
213{
214 return d->alignment;
215}
216
217void KoShapeQtQuickLabel::setAlignment(const Qt::Alignment align)
218{
219 if (d->alignment == align) return;
220 d->alignment = align;
221 emit alignmentChanged();
222}
223
225{
226 QQuickPaintedItem::componentComplete();
227 updateShapes();
228 setOpaquePainting(fillColor().alpha() == 255);
229}
230
232{
233 if (!d->fullColor) {
235 for (int i = 0; i < d->shapes.size(); i++) {
236 d->shapes.at(i)->setBackground(bg);
237 }
238 }
240}
241
243{
244 if (isComponentComplete()) {
245 update(boundingRect().toAlignedRect());
246 }
247}
248
250{
251 return d->documentRect;
252}
253
255{
256 if (d->documentRect == rect) return;
257 d->documentRect = rect;
258 emit documentRectChanged();
259 emit minimumRectChanged();
260}
261
263{
264 const QRectF bounds = d->documentRect.isValid()? d->documentRect: d->shapePainter? d->shapePainter->contentRect(): QRectF();
265 return d->addPaddingToBounds(bounds);
266}
const Params2D p
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
A simple solid color shape background.
@ FitWidth
Scale document view to document width. Use alignment to position top or bottom on the document.
@ Fit
Default koshapepainter behaviour, fit whole document into widget bounds.
@ FitHeight
Scale document view to document height. Use alignment to position left or right on the document.
void setPadding(int newPadding)
KoShapeQtQuickLabel(QQuickItem *parent=nullptr)
void foregroundColorChanged()
void setForegroundColor(const QColor &newForegroundColor)
void paint(QPainter *painter) override
void setSvgData(const QString &newSvgData)
void setAlignment(const Qt::Alignment align)
void setFullColor(bool newFullColor)
void setScalingType(const ScalingType type)
const QScopedPointer< Private > d
void componentComplete() override
void setDocumentRect(const QRectF &rect)
static QDomDocument createDocumentFromSvg(QIODevice *device, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0)
#define bounds(x, a, b)
KoShapeQtQuickLabel::ScalingType scalingType
QRectF adjustBBoxToScaling(const QRectF &bbox, const QRectF &widgetBounds)
QScopedPointer< KoShapePainter > shapePainter
QRectF addPaddingToBounds(QRectF bounds)