30#include <QPainterPath>
37 return qIsNaN(
p.x()) || qIsNaN(
p.y());
41 : fillRule(Qt::OddEvenFill)
42 , autoFillMarkers(false)
47 : fillRule(rhs.fillRule)
48 , markersNew(rhs.markersNew)
49 , autoFillMarkers(rhs.autoFillMarkers)
55 return QRectF(
p.x() - radius,
p.y() - radius, 2*radius, 2*radius);
72 Q_FOREACH (
KoSubpath *subPath, rhs.
d->subpaths) {
112 path.setFillRule(
d->fillRule);
124 KoSubpathList::const_iterator pathIt(
subpaths.constBegin());
127 QPen pen(Qt::black, 0);
130 for (; pathIt !=
subpaths.constEnd(); ++pathIt) {
131 KoSubpath::const_iterator it((*pathIt)->constBegin());
132 for (; it != (*pathIt)->constEnd(); ++it) {
135 QRectF r(point->
point(), QSizeF(5, 5));
136 r.translate(-2.5, -2.5);
137 QPen pen(Qt::black, 0);
143 QBrush b(Qt::yellow);
146 QBrush b(Qt::darkYellow);
149 painter.drawEllipse(r);
158 KoSubpathList::const_iterator pathIt(
subpaths.constBegin());
159 for (; pathIt !=
subpaths.constEnd(); ++pathIt) {
160 KoSubpath::const_iterator it((*pathIt)->constBegin());
161 for (; it != (*pathIt)->constEnd(); ++it) {
162 debugFlake <<
"p:" << (*pathIt) <<
"," << *it <<
"," << (*it)->point() <<
"," << (*it)->properties();
170 KoSubpathList::const_iterator pathIt(
d->subpaths.constBegin());
172 for (; pathIt !=
d->subpaths.constEnd(); ++pathIt) {
173 KoSubpath::const_iterator it((*pathIt)->constBegin());
174 for (; it != (*pathIt)->constEnd(); ++it)
181 return outline().boundingRect();
187 for (
auto subpathIt =
d->subpaths.constBegin(); subpathIt !=
d->subpaths.constEnd(); ++subpathIt) {
189 const KoPathPoint * lastPoint = subpath->constFirst();
190 bool activeCP =
false;
191 for (
auto pointIt = subpath->constBegin(); pointIt != subpath->constEnd(); ++pointIt) {
193 KoPathPoint::PointProperties currProperties = currPoint->
properties();
194 if (currPoint == subpath->constFirst()) {
197 path.moveTo(currPoint->
point());
215 path.lineTo(currPoint->
point());
225 firstPoint->
point());
232 firstPoint->
point());
242 lastPoint = currPoint;
258 qreal outlineSweepWidth = 0;
262 outlineSweepWidth = lineBorder->lineWidth();
267 stroke()->strokeInsets(
this, inset);
272 outlineSweepWidth = std::max({outlineSweepWidth,
274 2.0 *
stroke()->strokeMaxMarkersInset(
this)});
283 QPen pen(Qt::black, outlineSweepWidth);
287 pen.setJoinStyle(Qt::RoundJoin);
288 pen.setCapStyle(Qt::RoundCap);
313 QSizeF oldSize =
size();
314 if (oldSize.width() == 0.0) {
315 oldSize.setWidth(0.000001);
317 if (oldSize.height() == 0.0) {
318 oldSize.setHeight(0.000001);
321 QSizeF sizeNew(newSize);
322 if (sizeNew.width() == 0.0) {
323 sizeNew.setWidth(0.000001);
325 if (sizeNew.height() == 0.0) {
326 sizeNew.setHeight(0.000001);
329 return QTransform(sizeNew.width() / oldSize.width(), 0, 0, sizeNew.height() / oldSize.height(), 0, 0);
336 path->push_back(point);
337 d->subpaths.push_back(path);
344 if (
d->subpaths.empty()) {
350 d->subpaths.last()->push_back(point);
357 if (
d->subpaths.empty()) {
365 d->subpaths.last()->push_back(point);
372 if (
d->subpaths.empty())
379 d->subpaths.last()->push_back(point);
386 if (
d->subpaths.empty()) {
392 lastPoint =
d->subpaths.last()->first();
394 QPointF startpoint(lastPoint->
point());
398 QPointF curvePoints[12];
399 int pointCnt =
arcToCurve(rx, ry, startAngle, sweepAngle, startpoint, curvePoints);
400 for (
int i = 0; i < pointCnt; i += 3) {
401 newEndPoint =
curveTo(curvePoints[i], curvePoints[i+1], curvePoints[i+2]);
406int KoPathShape::arcToCurve(qreal rx, qreal ry, qreal startAngle, qreal sweepAngle,
const QPointF & offset, QPointF * curvePoints)
const
411 if (sweepAngle == 0.0)
414 sweepAngle = qBound(-360.0, sweepAngle, 360.0);
416 if (rx == 0 || ry == 0) {
421 qreal parts = ceil(qAbs(sweepAngle / 90.0));
423 qreal sa_rad = startAngle *
M_PI / 180.0;
424 qreal partangle = sweepAngle / parts;
425 qreal endangle = startAngle + partangle;
426 qreal se_rad = endangle *
M_PI / 180.0;
427 qreal sinsa = sin(sa_rad);
428 qreal cossa = cos(sa_rad);
429 qreal kappa = 4.0 / 3.0 * tan((se_rad - sa_rad) / 4);
433 QPointF startpoint(offset);
436 QPointF center(startpoint - QPointF(cossa * rx, -sinsa * ry));
442 curvePoints[pointCnt++] = QPointF(startpoint - QPointF(sinsa * rx * kappa, cossa * ry * kappa));
444 qreal sinse = sin(se_rad);
445 qreal cosse = cos(se_rad);
448 QPointF endpoint(center + QPointF(cosse * rx, -sinse * ry));
450 curvePoints[pointCnt++] = QPointF(endpoint - QPointF(-sinse * rx * kappa, -cosse * ry * kappa));
451 curvePoints[pointCnt++] = endpoint;
454 startpoint = endpoint;
457 endangle += partangle;
458 se_rad = endangle *
M_PI / 180.0;
466 if (
d->subpaths.empty()) {
474 if (
d->subpaths.empty()) {
484 matrix.translate(-tl.x(), -tl.y());
495 KoSubpathList::const_iterator pathIt(
subpaths.constBegin());
496 for (; pathIt !=
subpaths.constEnd(); ++pathIt) {
497 KoSubpath::const_iterator it((*pathIt)->constBegin());
498 for (; it != (*pathIt)->constEnd(); ++it) {
513 KoPathPoint *subpathStart =
d->subpaths.last()->first();
520 path->push_back(newLastPoint);
521 d->subpaths.push_back(path);
522 *lastPoint = newLastPoint;
535 KoSubpathList::const_iterator pathIt(
d->subpaths.constBegin());
536 for (; pathIt !=
d->subpaths.constEnd(); ++pathIt) {
537 KoSubpath::const_iterator it((*pathIt)->constBegin());
538 for (; it != (*pathIt)->constEnd(); ++it) {
539 if (r.contains((*it)->point()))
541 else if (useControlPoints) {
542 if ((*it)->activeControlPoint1() && r.contains((*it)->controlPoint1()))
544 else if ((*it)->activeControlPoint2() && r.contains((*it)->controlPoint2()))
556 for (
int subpathIndex = 0; subpathIndex <
subpathCount; ++subpathIndex) {
557 KoSubpath * subpath =
d->subpaths[subpathIndex];
560 for (
int pointIndex = 0; pointIndex <
pointCount; ++pointIndex) {
561 if (pointIndex == (
pointCount - 1) && ! subpathClosed)
564 QRectF controlRect =
s.controlPointRect();
565 if (! r.intersects(controlRect) && ! controlRect.contains(r))
567 QRectF bound =
s.boundingRect();
568 if (! r.intersects(bound) && ! bound.contains(r))
579 for (
int subpathIndex = 0; subpathIndex <
d->subpaths.size(); ++subpathIndex) {
580 KoSubpath * subpath =
d->subpaths.at(subpathIndex);
581 for (
int pointPos = 0; pointPos < subpath->size(); ++pointPos) {
582 if (subpath->at(pointPos) == point) {
592 KoSubpath *subpath =
d->subPath(pointIndex.first);
594 if (subpath == 0 || pointIndex.second < 0 || pointIndex.second >= subpath->size())
597 return subpath->at(pointIndex.second);
604 KoSubpath *subpath =
d->subPath(pointIndex.first);
606 if (subpath != 0 && pointIndex.second >= 0 && pointIndex.second < subpath->size()) {
607 KoPathPoint * point = subpath->at(pointIndex.second);
608 int index = pointIndex.second;
615 if (index < subpath->
size()) {
625 KoSubpathList::const_iterator pathIt(
d->subpaths.constBegin());
626 for (; pathIt !=
d->subpaths.constEnd(); ++pathIt) {
627 i += (*pathIt)->size();
635 return d->subpaths.count();
640 KoSubpath *subpath =
d->subPath(subpathIndex);
645 return subpath->size();
650 KoSubpath *subpath =
d->subPath(subpathIndex);
658 return firstClosed && lastClosed;
663 KoSubpath *subpath =
d->subPath(pointIndex.first);
665 if (subpath == 0 || pointIndex.second < 0 || pointIndex.second > subpath->size())
668 KoPathPoint::PointProperties properties = point->
properties();
673 if (pointIndex.second == 0) {
684 else if (pointIndex.second == subpath->size()) {
697 subpath->insert(pointIndex.second , point);
705 KoSubpath *subpath =
d->subPath(pointIndex.first);
707 if (subpath == 0 || pointIndex.second < 0 || pointIndex.second >= subpath->size())
710 KoPathPoint * point = subpath->takeAt(pointIndex.second);
718 else if (pointIndex.second == 0) {
728 else if (pointIndex.second == subpath->size()) {
745 KoSubpath *subpath =
d->subPath(pointIndex.first);
747 if (!subpath || pointIndex.second < 0 || pointIndex.second > subpath->size() - 2
753 int size = subpath->size();
754 for (
int i = pointIndex.second + 1; i <
size; ++i) {
755 newSubpath->append(subpath->takeAt(pointIndex.second + 1));
763 d->subpaths.insert(pointIndex.first + 1, newSubpath);
771 KoSubpath *subpath =
d->subPath(subpathIndex);
772 KoSubpath *nextSubpath =
d->subPath(subpathIndex + 1);
788 d->subpaths.removeAt(subpathIndex + 1);
800 KoSubpath *subpath =
d->subPath(oldSubpathIndex);
802 if (subpath == 0 || newSubpathIndex >=
d->subpaths.size())
805 if (oldSubpathIndex == newSubpathIndex)
808 d->subpaths.removeAt(oldSubpathIndex);
809 d->subpaths.insert(newSubpathIndex, subpath);
818 KoSubpath *subpath =
d->subPath(pointIndex.first);
820 if (!subpath || pointIndex.second < 0 || pointIndex.second >= subpath->size()
831 for (
int i = 0; i < pointIndex.second; ++i) {
832 subpath->append(subpath->takeFirst());
846 KoSubpath *subpath =
d->subPath(pointIndex.first);
848 if (!subpath || pointIndex.second < 0 || pointIndex.second >= subpath->size()
859 for (
int i = 0; i < pointIndex.second; ++i) {
860 subpath->append(subpath->takeFirst());
874 KoSubpath *subpath =
d->subPath(subpathIndex);
879 int size = subpath->size();
880 for (
int i = 0; i <
size; ++i) {
890 KoPathPoint::PointProperties firstProps = first->
properties();
891 KoPathPoint::PointProperties lastProps = last->
properties();
911 KoSubpath *subpath =
d->subPath(subpathIndex);
917 d->subpaths.removeAt(subpathIndex);
927 if (subpathIndex < 0 || subpathIndex >
d->subpaths.size())
934 d->subpaths.insert(subpathIndex, subpath);
942 int insertSegmentPosition = -1;
943 if (!path)
return insertSegmentPosition;
945 QTransform pathMatrix = path->absoluteTransformation();
948 Q_FOREACH (
KoSubpath* subpath, path->d->subpaths) {
953 newPoint->
map(pathMatrix);
954 newPoint->
map(myMatrix);
955 newSubpath->append(newPoint);
957 d->subpaths.append(newSubpath);
959 if (insertSegmentPosition < 0) {
960 insertSegmentPosition =
d->subpaths.size() - 1;
966 return insertSegmentPosition;
971 if (!
d->subpaths.size())
988 newPoint->
map(myMatrix);
989 newSubpath->append(newPoint);
991 shape->
d->subpaths.append(newSubpath);
997 separatedPaths.append(shape);
1015 if (! subpath || subpath->size() < 2)
1022 if (lastPoint->
point() == firstPoint->
point()) {
1030 delete subpath->takeLast();
1032 lastPoint = subpath->last();
1054 return d->map(matrix);
1059 if (subpathIndex < 0 || subpathIndex >=
subpaths.size())
1075 KoSubpathList::const_iterator pathIt(
d->subpaths.constBegin());
1076 for (; pathIt !=
d->subpaths.constEnd(); ++pathIt) {
1077 KoSubpath::const_iterator pointIt((*pathIt)->constBegin());
1083 bool activeControlPoint2 =
false;
1086 for (; pointIt != (*pathIt)->constEnd(); ++pointIt) {
1089 qWarning() <<
"Found a zero point in the shape's path!";
1093 if (currPoint == firstPoint) {
1096 const QPointF
p = matrix.map(currPoint->
point());
1097 pathString += QString(
"M%1 %2").arg(
p.x()).arg(
p.y());
1109 const QPointF
p = matrix.map(cubicSeg.
second()->
point());
1110 pathString += QString(
"C%1 %2 %3 %4 %5 %6")
1111 .arg(cp1.x()).arg(cp1.y())
1112 .arg(cp2.x()).arg(cp2.y())
1113 .arg(
p.x()).arg(
p.y());
1118 const QPointF
p = matrix.map(currPoint->
point());
1119 pathString += QString(
"L%1 %2").arg(
p.x()).arg(
p.y());
1134 const QPointF
p = matrix.map(cubicSeg.
second()->
point());
1135 pathString += QString(
"C%1 %2 %3 %4 %5 %6")
1136 .arg(cp1.x()).arg(cp1.y())
1137 .arg(cp2.x()).arg(cp2.y())
1138 .arg(
p.x()).arg(
p.y());
1141 pathString += QString(
"Z");
1145 lastPoint = currPoint;
1168 KoSubpathList::const_iterator pathIt(
d->subpaths.constBegin());
1169 for (; pathIt !=
d->subpaths.constEnd(); ++pathIt) {
1170 KoSubpath::const_iterator it((*pathIt)->constBegin());
1171 for (; it != (*pathIt)->constEnd(); ++it) {
1172 if (it == (*pathIt)->constBegin()) {
1182 types.append(
nodeType(firstPoint));
1201 QString::const_iterator nIt(
nodeTypes.constBegin());
1202 KoSubpathList::const_iterator pathIt(
d->subpaths.constBegin());
1203 for (; pathIt !=
d->subpaths.constEnd(); ++pathIt) {
1204 KoSubpath::const_iterator it((*pathIt)->constBegin());
1205 for (; it != (*pathIt)->constEnd(); ++it, nIt++) {
1208 warnFlake <<
"not enough nodes in sodipodi:nodetypes";
1212 if (it != (*pathIt)->constBegin()) {
1239 int elementCount = path.elementCount();
1240 for (
int i = 0; i < elementCount; i++) {
1241 QPainterPath::Element element = path.elementAt(i);
1242 switch (element.type) {
1243 case QPainterPath::MoveToElement:
1244 shape->
moveTo(QPointF(element.x, element.y));
1246 case QPainterPath::LineToElement:
1247 shape->
lineTo(QPointF(element.x, element.y));
1249 case QPainterPath::CurveToElement:
1250 shape->
curveTo(QPointF(element.x, element.y),
1251 QPointF(path.elementAt(i + 1).x, path.elementAt(i + 1).y),
1252 QPointF(path.elementAt(i + 2).x, path.elementAt(i + 2).y));
1271 const QPainterPath outlinePath =
outline();
1274 stroke()->strokeInsets(
this, insets);
1275 QRectF roi(QPointF(-insets.
left, -insets.
top), QPointF(insets.
right, insets.
bottom));
1277 roi.moveCenter(point);
1278 if (outlinePath.intersects(roi) || outlinePath.contains(roi))
1281 if (outlinePath.contains(point))
1290 if (!
marker &&
d->markersNew.contains(pos)) {
1291 d->markersNew.remove(pos);
1302 return d->markersNew[pos].data();
1307 return !
d->markersNew.isEmpty();
1312 return d->autoFillMarkers;
1317 d->autoFillMarkers =
value;
1330 qreal minDistance = std::numeric_limits<qreal>::max();
1336 const qreal nearestPointParam =
s.nearestPoint(
p);
1337 const QPointF nearestPoint =
s.pointAt(nearestPointParam);
1356 if (pointListener) {
1366 if (pointListener) {
1374 if (
d->subpaths.isEmpty()) {
1375 return QPainterPath();
1377 QPainterPath pathOutline;
1379 QPainterPathStroker stroker;
1380 stroker.setWidth(0);
1381 stroker.setJoinStyle(Qt::MiterJoin);
1382 stroker.setWidth(pen.widthF());
1383 stroker.setJoinStyle(pen.joinStyle());
1384 stroker.setMiterLimit(pen.miterLimit());
1385 stroker.setCapStyle(pen.capStyle());
1386 stroker.setDashOffset(pen.dashOffset());
1387 stroker.setDashPattern(pen.dashPattern());
1389 QPainterPath path = stroker.createStroke(
outline());
1391 pathOutline.addPath(path);
1392 pathOutline.setFillRule(Qt::WindingFill);
float value(const T *src, size_t ch)
quint64 part(quint64 n1, quint64 n2, int p)
qreal distance(const QPointF &p1, const QPointF &p2)
static bool qIsNaNPoint(const QPointF &p)
static bool qIsNaNPoint(const QPointF &p)
char nodeType(const KoPathPoint *point)
void updateNodeType(KoPathPoint *point, const QChar &nodeType)
QList< KoPathPoint * > KoSubpath
a KoSubpath contains a path from a moveTo until a close or a new moveTo
QPair< int, int > KoPathPointIndex
The KisHandlePainterHelper class is a special helper for painting handles around objects....
A KoPathPoint represents a point in a path.
PointProperties properties
void setProperties(PointProperties properties)
Set the properties of a point.
void setControlPoint1(const QPointF &point)
Set the control point 1.
void setProperty(PointProperty property)
Sets a single property of a point.
void setControlPoint2(const QPointF &point)
Set the control point 2.
void map(const QTransform &matrix)
apply matrix on the point
@ IsSmooth
it is smooth, both control points on a line through the point
@ StartSubpath
it starts a new subpath by a moveTo command
@ Normal
it has no control points
@ IsSymmetric
it is symmetric, like smooth but control points have same distance to point
@ CloseSubpath
it closes a subpath (only applicable on StartSubpath and StopSubpath)
@ StopSubpath
it stops a subpath (last point of subpath)
void unsetProperty(PointProperty property)
Removes a property from the point.
void setParent(KoPathShape *parent)
Sets the parent path shape.
A KoPathSegment consist of two neighboring KoPathPoints.
KoPathSegment toCubic() const
Returns cubic bezier curve segment of this segment.
void debugPath() const
print debug information about a the points of the path
void paintDebug(QPainter &painter)
void map(const QTransform &matrix)
QRectF handleRect(const QPointF &p, qreal radius) const
KoSubpath * subPath(int subpathIndex) const
Returns subpath at given index.
The position of a path point within a path shape.
const KoSubpathList & subpaths() const
bool autoFillMarkers() const
QTransform resizeMatrix(const QSizeF &newSize) const
bool breakAfter(const KoPathPointIndex &pointIndex)
Breaks the path after the point index.
int subpathPointCount(int subpathIndex) const
Returns the number of points in a subpath.
bool isClosedSubpath(int subpathIndex) const
Checks if a subpath is closed.
void map(const QTransform &matrix)
virtual QString pathShapeId() const
KoMarker * marker(KoFlake::MarkerPosition pos) const
bool reverseSubpath(int subpathIndex)
Reverse subpath.
KoPathSegment segmentAtPoint(const QPointF &point, const QRectF &grabRoi) const
KoPathPoint * lineTo(const QPointF &p)
Adds a new line segment.
bool hitTest(const QPointF &position) const override
reimplemented
void setAutoFillMarkers(bool value)
void recommendPointSelectionChange(const QList< KoPathPointIndex > &newSelection)
KoSubpath * removeSubpath(int subpathIndex)
Removes subpath from the path.
virtual QPointF normalize()
Normalizes the path data.
QSizeF size() const override
reimplemented
void close()
Closes the current subpath.
void notifyPointsChanged()
bool addSubpath(KoSubpath *subpath, int subpathIndex)
Adds a subpath at the given index to the path.
void setSize(const QSizeF &size) override
QRectF outlineRect() const override
reimplemented
QPainterPath pathStroke(const QPen &pen) const
Qt::FillRule fillRule() const
Returns the fill rule for the path object.
void closeMerge()
Closes the current subpath.
void setFillRule(Qt::FillRule fillRule)
Sets the fill rule to be used for painting the background.
KoPathPoint * moveTo(const QPointF &p)
Starts a new Subpath.
int arcToCurve(qreal rx, qreal ry, qreal startAngle, qreal sweepAngle, const QPointF &offset, QPointF *curvePoints) const
Add an arc.
int pointCount() const
Returns the number of points in the path.
bool moveSubpath(int oldSubpathIndex, int newSubpathIndex)
Moves the position of a subpath within a path.
void closeSubpathPriv(KoSubpath *subpath)
closes specified subpath
bool join(int subpathIndex)
Joins the given subpath with the following one.
QList< KoPathPoint * > pointsAt(const QRectF &rect, const bool useControlPoints=false) const
Returns the path points within the given rectangle.
void setMarker(KoMarker *marker, KoFlake::MarkerPosition pos)
bool separate(QList< KoPathShape * > &separatedPaths)
Creates separate path shapes, one for each existing subpath.
void updateLastPriv(KoPathPoint **lastPoint)
QList< KoPathSegment > segmentsAt(const QRectF &rect) const
Returns the list of path segments within the given rectangle.
void paint(QPainter &painter) const override
reimplemented
KoShape * cloneShape() const override
creates a deep copy of the shape or shape's subtree
KoPathPointIndex closeSubpath(const KoPathPointIndex &pointIndex)
Close a open subpath.
KoPathPoint * arcTo(qreal rx, qreal ry, qreal startAngle, qreal sweepAngle)
Add an arc.
KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex)
Opens a closed subpath.
QString toString(const QTransform &matrix=QTransform()) const
Returns a odf/svg string representation of the path data with the given matrix applied.
QPainterPath outline() const override
reimplemented
KoPathPoint * curveTo(const QPointF &c1, const QPointF &c2, const QPointF &p)
Adds a new cubic Bezier curve segment.
QString nodeTypes() const
Saves the node types.
QRectF boundingRect() const override
reimplemented
KoPathPoint * removePoint(const KoPathPointIndex &pointIndex)
Removes a point from the path.
int subpathCount() const
Returns the number of subpaths in the path.
static KoPathShape * createShapeFromPainterPath(const QPainterPath &path)
Creates path shape from given QPainterPath.
KoPathSegment segmentByIndex(const KoPathPointIndex &pointIndex) const
Returns the segment specified by a path point index.
virtual void paintPoints(KisHandlePainterHelper &handlesHelper)
KoPathPointIndex pathPointIndex(const KoPathPoint *point) const
Returns the path point index of a given path point.
void loadNodeTypes(const QString &nodeTypes)
Loads node types.
KoPathPoint * pointByIndex(const KoPathPointIndex &pointIndex) const
Returns the path point specified by a path point index.
QScopedPointer< Private > d
void closeMergeSubpathPriv(KoSubpath *subpath)
close-merges specified subpath
void clear()
Removes all subpaths and their points from the path.
bool insertPoint(KoPathPoint *point, const KoPathPointIndex &pointIndex)
Inserts a new point into the given subpath at the specified position.
int combine(KoPathShape *path)
Combines two path shapes by appending the data of the specified path.
void setZIndex(qint16 zIndex)
virtual KoShapeStrokeModelSP stroke() const
QPointF documentToShape(const QPointF &point) const
Transforms point from document coordinates to shape coordinates.
QList< ShapeChangeListener * > listeners() const
void applyTransformation(const QTransform &matrix)
KoShapeContainer * parent() const
void shapeChangedPriv(KoShape::ChangeType type)
virtual void setStroke(KoShapeStrokeModelSP stroke)
QTransform absoluteTransformation() const
virtual void setBackground(QSharedPointer< KoShapeBackground > background)
ChangeType
Used by shapeChanged() to select which change was made.
@ StrokeChanged
the shapes stroke has changed
@ ContentChanged
the content of the shape changed e.g. a new image inside a pixmap/text change inside a textshape
virtual QSharedPointer< KoShapeBackground > background() const
QSharedDataPointer< SharedData > s
void setShapeId(const QString &id)
QTransform transform() const
return the current matrix that contains the rotation/scale/position of this shape
virtual void setSize(const QSizeF &size)
Resize the shape.
QPointF position() const
Get the position of the shape in pt.
qreal kisDistance(const QPointF &pt1, const QPointF &pt2)
T kisGrowRect(const T &rect, U offset)
auto maxDimension(Size size) -> decltype(size.width())
qreal bottom
Bottom inset.
virtual void recommendPointSelectionChange(KoPathShape *shape, const QList< KoPathPointIndex > &newSelection)=0
virtual void notifyPathPointsChanged(KoPathShape *shape)=0
void notifyShapeChanged(ChangeType type, KoShape *shape) override