Krita Source Code Documentation
Loading...
Searching...
No Matches
CutThroughShapeStrategy Class Reference

#include <CutThroughShapeStrategy.h>

+ Inheritance diagram for CutThroughShapeStrategy:

Public Member Functions

KUndo2CommandcreateCommand () override
 
 CutThroughShapeStrategy (KoToolBase *tool, KoSelection *selection, const QList< KoShape * > &allShapes, QPointF startPoint, const GutterWidthsConfig &width)
 
void finishInteraction (Qt::KeyboardModifiers modifiers) override
 
void handleMouseMove (const QPointF &mouseLocation, Qt::KeyboardModifiers modifiers) override
 
void paint (QPainter &painter, const KoViewConverter &converter, const KoColorDisplayRendererInterface *displayRendererInterface) override
 
 ~CutThroughShapeStrategy () override
 
- Public Member Functions inherited from KoInteractionStrategy
virtual void cancelInteraction ()
 
 KoInteractionStrategy (KoToolBase *parent)
 constructor
 
KoToolBasetool () const
 
virtual ~KoInteractionStrategy ()
 Destructor.
 

Private Member Functions

qreal calculateLineAngle (QPointF start, QPointF end)
 
qreal gutterWidthInDocumentCoordinates (qreal lineAngle)
 
bool willShapeBeCutGeneral (KoShape *referenceShape, const QPainterPath &srcOutline, const QRectF &leftOppositeRect, const QRectF &rightOppositeRect, bool checkGapLineRect, const QRectF &gapLineRect)
 
bool willShapeBeCutPrecise (const QPainterPath &srcOutline, const QLineF gapLine, const QLineF &leftLine, const QLineF &rightLine, const QPolygonF &gapLinePolygon)
 

Private Attributes

QList< KoShape * > m_allShapes
 
QPointF m_endPoint = QPointF()
 
QRectF m_previousLineDirtyRect = QRectF()
 
QList< KoShape * > m_selectedShapes
 
QPointF m_startPoint = QPointF()
 
GutterWidthsConfig m_width
 

Additional Inherited Members

- Protected Member Functions inherited from KoInteractionStrategy
uint decorationThickness () const
 
uint grabSensitivity () const
 Convenience function to get the global grab sensitivity.
 
uint handleRadius () const
 Convenience function to get the global handle radius.
 
 KoInteractionStrategy (KoInteractionStrategyPrivate &)
 constructor
 
- Protected Attributes inherited from KoInteractionStrategy
KoInteractionStrategyPrivated_ptr
 

Detailed Description

Definition at line 23 of file CutThroughShapeStrategy.h.

Constructor & Destructor Documentation

◆ CutThroughShapeStrategy()

CutThroughShapeStrategy::CutThroughShapeStrategy ( KoToolBase * tool,
KoSelection * selection,
const QList< KoShape * > & allShapes,
QPointF startPoint,
const GutterWidthsConfig & width )

Definition at line 31 of file CutThroughShapeStrategy.cpp.

33 , m_startPoint(startPoint)
34 , m_endPoint(startPoint)
35 , m_width(width)
36{
38 m_allShapes = shapes;
39}
QList< KoShape * > m_selectedShapes
KoInteractionStrategy(KoToolBase *parent)
constructor
const QList< KoShape * > selectedEditableShapes() const

References m_allShapes, m_selectedShapes, and KoSelection::selectedEditableShapes().

◆ ~CutThroughShapeStrategy()

CutThroughShapeStrategy::~CutThroughShapeStrategy ( )
override

Definition at line 41 of file CutThroughShapeStrategy.cpp.

42{
43
44}

Member Function Documentation

◆ calculateLineAngle()

qreal CutThroughShapeStrategy::calculateLineAngle ( QPointF start,
QPointF end )
private

Definition at line 396 of file CutThroughShapeStrategy.cpp.

397{
398 QPointF vec = end - start;
399 qreal angleDegrees = KisAlgebra2D::wrapValue(kisRadiansToDegrees(std::atan2(vec.y(), vec.x())), 0.0, 360.0);
400 return angleDegrees;
401}
T kisRadiansToDegrees(T radians)
Definition kis_global.h:181
T wrapValue(T value, T wrapBounds)

References kisRadiansToDegrees(), and KisAlgebra2D::wrapValue().

◆ createCommand()

KUndo2Command * CutThroughShapeStrategy::createCommand ( )
overridevirtual

For interactions that are undo-able this method should be implemented to return such a command. Implementations should return 0 otherwise.

Returns
a command, or 0.

Implements KoInteractionStrategy.

Definition at line 46 of file CutThroughShapeStrategy.cpp.

47{
48 // TODO: undoing
49 return 0;
50}

◆ finishInteraction()

void CutThroughShapeStrategy::finishInteraction ( Qt::KeyboardModifiers modifiers)
overridevirtual

Override to make final changes to the data on the end of an interaction.

Implements KoInteractionStrategy.

Definition at line 145 of file CutThroughShapeStrategy.cpp.

146{
148
149
150 KisCanvas2 *kisCanvas = static_cast<KisCanvas2 *>(tool()->canvas());
152 const QTransform booleanWorkaroundTransform = KritaUtils::pathShapeBooleanSpaceWorkaround(kisCanvas->image());
153
154 QList<QPainterPath> srcOutlines;
155 QRectF outlineRect;
156
157 if (m_allShapes.length() == 0) {
158 qCritical() << "No shapes are available";
159 return;
160 }
161
162 Q_FOREACH (KoShape *shape, m_allShapes) {
163
164 QPainterPath outlineHere =
165 booleanWorkaroundTransform.map(
166 shape->absoluteTransformation().map(
167 shape->outline()));
168
169 srcOutlines << outlineHere;
170 outlineRect |= outlineHere.boundingRect();//booleanWorkaroundTransform.map(shape->absoluteOutlineRect()).boundingRect();
171 }
172
173 if (outlineRect.isEmpty()) {
174 //qCritical() << "The outline rect is empty";
175 return;
176 }
177
178 QRectF outlineRectBigger = kisGrowRect(outlineRect, 10);
179 QRect outlineRectBiggerInt = outlineRectBigger.toRect();
180
181 QLineF gapLine = QLineF(m_startPoint, m_endPoint);
182 qreal eps = 0.0000001;
183 if (gapLine.length() < eps) {
184 return;
185 }
186
188
189 QList<QLineF> gapLines = KisAlgebra2D::getParallelLines(gapLine, gutterWidth/2);
190
191 gapLine = booleanWorkaroundTransform.map(gapLine);
192 gapLines[0] = booleanWorkaroundTransform.map(gapLines[0]);
193 gapLines[1] = booleanWorkaroundTransform.map(gapLines[1]);
194
195 QLineF leftLine = gapLines[0];
196 QLineF rightLine = gapLines[1];
197
198 QLineF leftLineLong = leftLine;
199 QLineF rightLineLong = rightLine;
200
201
202
203 KisAlgebra2D::cropLineToRect(leftLineLong, outlineRectBiggerInt, true, true);
204 KisAlgebra2D::cropLineToRect(rightLineLong, outlineRectBiggerInt, true, true);
205
206 std::unique_ptr<KUndo2Command> cmd = std::unique_ptr<KUndo2Command>(new KUndo2Command(kundo2_i18n("Knife tool: cut through shapes")));
207
208
209 new KoKeepShapesSelectedCommand(m_selectedShapes, {}, kisCanvas->selectedShapesProxy(), false, cmd.get());
210
211
212 if (leftLine.length() == 0 || rightLine.length() == 0) {
213 KIS_SAFE_ASSERT_RECOVER_RETURN(gapLine.length() != 0 && gapLines[0].length() != 0 && gapLines[1].length() != 0 && "Original gap lines shouldn't be empty at this point");
214 // looks like *all* shapes need to be cut out
215
216 tool()->canvas()->shapeController()->removeShapes(m_allShapes, cmd.get());
217 tool()->canvas()->addCommand(cmd.release());
218 return;
219 }
220
221
222 QList<QPainterPath> paths = KisAlgebra2D::getPathsFromRectangleCutThrough(QRectF(outlineRectBiggerInt), leftLineLong, rightLineLong);
223 QPainterPath left = paths[0];
224 QPainterPath right = paths[1];
225
226 QList<QPainterPath> pathsOpposite = KisAlgebra2D::getPathsFromRectangleCutThrough(QRectF(outlineRectBiggerInt), rightLineLong, leftLineLong);
227 QPainterPath leftOpposite = pathsOpposite[0];
228 QPainterPath rightOpposite = pathsOpposite[1];
229
230 QList<KoShape*> newSelectedShapes;
231
232 QList<KoShape*> shapesToRemove;
233
234 QTransform booleanWorkaroundTransformInverted = booleanWorkaroundTransform.inverted();
235
236 QRectF gapLineLeftRect = KisAlgebra2D::createRectFromCorners(leftLine); // warning! can be empty for perfectly horizontal/vertical lines
237 QRectF gapLineRightRect = KisAlgebra2D::createRectFromCorners(rightLine);
238 QRectF gapLineRect = gapLineLeftRect | gapLineRightRect; // will not be empty if the gutterWidth > 0
239 bool checkGapLineRect = !gapLineRect.isEmpty();
240 QPolygonF gapLinePolygon = QPolygonF({leftLine.p1(), leftLine.p2(), rightLine.p2(), rightLine.p1(), leftLine.p1()});
241
242 int affectedShapes = 0;
243
244 for (int i = 0; i < srcOutlines.size(); i++) {
245
246 KoShape* referenceShape = m_allShapes[i];
247 bool wasSelected = m_selectedShapes.contains(referenceShape);
248
249 bool skipThisShape = !willShapeBeCutGeneral(referenceShape, srcOutlines[i], leftOpposite.boundingRect(), rightOpposite.boundingRect(), checkGapLineRect, gapLineRect);
250 skipThisShape = skipThisShape || !willShapeBeCutPrecise(srcOutlines[i], gapLine, leftLine, rightLine, gapLinePolygon);
251
252 if (skipThisShape) {
253 if (wasSelected) {
254 newSelectedShapes << referenceShape;
255 }
256 continue;
257 }
258
259 affectedShapes++;
260
261
262 QPainterPath leftPath = srcOutlines[i] & left;
263 QPainterPath rightPath = srcOutlines[i] & right;
264
265 QList<QPainterPath> bothSides;
266 bothSides << leftPath << rightPath;
267
268
269 Q_FOREACH(QPainterPath path, bothSides) {
270 if (path.isEmpty()) {
271 continue;
272 }
273
274 // comment copied from another place:
275 // there is a bug in Qt, sometimes it leaves the resulting
276 // outline open, so just close it explicitly.
277 path.closeSubpath();
278 // this is needed because Qt linearize curves; this allows for a
279 // "sane" linearization instead of a very blocky appearance
280 path = booleanWorkaroundTransformInverted.map(path);
281 std::unique_ptr<KoPathShape> shape = std::unique_ptr<KoPathShape>(KoPathShape::createShapeFromPainterPath(path));
282 shape->closeMerge();
283
284 if (shape->boundingRect().isEmpty()) {
285 continue;
286 }
287
288 shape->setBackground(referenceShape->background());
289 shape->setStroke(referenceShape->stroke());
290 shape->setZIndex(referenceShape->zIndex());
291
292 KoShapeContainer *parent = referenceShape->parent();
293
294 if (wasSelected) {
295 newSelectedShapes << shape.get();
296 }
297
298 tool()->canvas()->shapeController()->addShapeDirect(shape.release(), parent, cmd.get());
299
300 }
301
302 // that happens no matter if there was any non-empty shape
303 // because if there is none, maybe they just were underneath the gap
304 shapesToRemove << m_allShapes[i];
305
306 }
307
308 if (affectedShapes > 0) {
309 tool()->canvas()->shapeController()->removeShapes(shapesToRemove, cmd.get());
310 new KoKeepShapesSelectedCommand({}, newSelectedShapes, tool()->canvas()->selectedShapesProxy(), true, cmd.get());
311 tool()->canvas()->addCommand(cmd.release());
312 }
313
314
315
316}
bool willShapeBeCutGeneral(KoShape *referenceShape, const QPainterPath &srcOutline, const QRectF &leftOppositeRect, const QRectF &rightOppositeRect, bool checkGapLineRect, const QRectF &gapLineRect)
qreal calculateLineAngle(QPointF start, QPointF end)
bool willShapeBeCutPrecise(const QPainterPath &srcOutline, const QLineF gapLine, const QLineF &leftLine, const QLineF &rightLine, const QPolygonF &gapLinePolygon)
qreal gutterWidthInDocumentCoordinates(qreal lineAngle)
KisSelectedShapesProxy selectedShapesProxy
KisImageWSP image() const
QPointer< KoShapeController > shapeController
virtual void updateCanvas(const QRectF &rc)=0
virtual void addCommand(KUndo2Command *command)=0
virtual KoSelectedShapesProxy * selectedShapesProxy() const =0
selectedShapesProxy() is a special interface for keeping a persistent connections to selectionChanged...
static KoPathShape * createShapeFromPainterPath(const QPainterPath &path)
Creates path shape from given QPainterPath.
virtual QPainterPath outline() const
Definition KoShape.cpp:554
virtual KoShapeStrokeModelSP stroke() const
Definition KoShape.cpp:885
KoShapeContainer * parent() const
Definition KoShape.cpp:857
QTransform absoluteTransformation() const
Definition KoShape.cpp:330
virtual QSharedPointer< KoShapeBackground > background() const
Definition KoShape.cpp:754
qint16 zIndex() const
Definition KoShape.cpp:524
KoCanvasBase * canvas() const
Returns the canvas the tool is working on.
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
const qreal eps
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
KUndo2MagicString kundo2_i18n(const char *text)
QList< QPainterPath > getPathsFromRectangleCutThrough(const QRectF &rect, const QLineF &leftLine, const QLineF &rightLine)
getPathsFromRectangleCutThrough get paths defining both sides of a rectangle cut through using two (s...
void cropLineToRect(QLineF &line, const QRect rect, bool extendFirst, bool extendSecond)
Crop line to rect; if it doesn't intersect, just return an empty line (QLineF()).
QList< QLineF > getParallelLines(const QLineF &line, const qreal distance)
PointTypeTraits< Point >::rect_type createRectFromCorners(Point corner1, Point corner2)
ChildIterator< value_type, is_const > parent(const ChildIterator< value_type, is_const > &it)
Definition KisForest.h:327
QTransform pathShapeBooleanSpaceWorkaround(KisImageSP image)

References KoShape::absoluteTransformation(), KoCanvasBase::addCommand(), KoShape::background(), calculateLineAngle(), KoToolBase::canvas(), KisAlgebra2D::createRectFromCorners(), KoPathShape::createShapeFromPainterPath(), KisAlgebra2D::cropLineToRect(), eps, KisAlgebra2D::getParallelLines(), KisAlgebra2D::getPathsFromRectangleCutThrough(), gutterWidthInDocumentCoordinates(), KisCanvas2::image(), KIS_SAFE_ASSERT_RECOVER_RETURN, kisGrowRect(), kundo2_i18n(), m_allShapes, m_endPoint, m_previousLineDirtyRect, m_selectedShapes, m_startPoint, KoShape::outline(), KoShape::parent(), KritaUtils::pathShapeBooleanSpaceWorkaround(), KoCanvasBase::selectedShapesProxy(), KisCanvas2::selectedShapesProxy, KoCanvasBase::shapeController, KoShape::stroke(), KoInteractionStrategy::tool(), KoCanvasBase::updateCanvas(), willShapeBeCutGeneral(), willShapeBeCutPrecise(), and KoShape::zIndex().

◆ gutterWidthInDocumentCoordinates()

qreal CutThroughShapeStrategy::gutterWidthInDocumentCoordinates ( qreal lineAngle)
private

Definition at line 387 of file CutThroughShapeStrategy.cpp.

388{
389 KisCanvas2 *kisCanvas = static_cast<KisCanvas2 *>(tool()->canvas());
391 QLineF helperGapWidthLine = QLineF(QPointF(0, 0), QPointF(0, m_width.widthForAngleInPixels(lineAngle)));
392 QLineF helperGapWidthLineTransformed = kisCanvas->coordinatesConverter()->imageToDocument(helperGapWidthLine);
393 return helperGapWidthLineTransformed.length();
394}
qreal widthForAngleInPixels(qreal lineAngleDegrees)
KisCoordinatesConverter * coordinatesConverter
_Private::Traits< T >::Result imageToDocument(const T &obj) const
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129

References KoToolBase::canvas(), KisCanvas2::coordinatesConverter, KisCoordinatesConverter::imageToDocument(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, m_width, KoInteractionStrategy::tool(), and GutterWidthsConfig::widthForAngleInPixels().

◆ handleMouseMove()

void CutThroughShapeStrategy::handleMouseMove ( const QPointF & mouseLocation,
Qt::KeyboardModifiers modifiers )
overridevirtual

Extending classes should implement this method to update the selectedShapes based on the new mouse position.

Parameters
mouseLocationthe new location in pt
modifiersOR-ed set of keys pressed.

Implements KoInteractionStrategy.

Definition at line 74 of file CutThroughShapeStrategy.cpp.

75{
76 m_endPoint = snapEndPoint(m_startPoint, mouseLocation, modifiers);
77 QRectF dirtyRect;
80 dirtyRect = kisGrowRect(dirtyRect, gutterWidthInDocumentCoordinates(calculateLineAngle(m_startPoint, m_endPoint))); // twice as much as it should need to account for lines showing the effect
81
82 QRectF accumulatedWithPrevious = m_previousLineDirtyRect | dirtyRect;
83
84 tool()->canvas()->updateCanvas(accumulatedWithPrevious);
85 m_previousLineDirtyRect = dirtyRect;
86
87}
QPointF snapEndPoint(const QPointF &startPoint, const QPointF &mouseLocation, Qt::KeyboardModifiers modifiers)
void accumulateBounds(const Point &pt, Rect *bounds)

References KisAlgebra2D::accumulateBounds(), calculateLineAngle(), KoToolBase::canvas(), gutterWidthInDocumentCoordinates(), kisGrowRect(), m_endPoint, m_previousLineDirtyRect, m_startPoint, snapEndPoint(), KoInteractionStrategy::tool(), and KoCanvasBase::updateCanvas().

◆ paint()

void CutThroughShapeStrategy::paint ( QPainter & painter,
const KoViewConverter & converter,
const KoColorDisplayRendererInterface * displayRendererInterface )
overridevirtual

Reimplement this if the action needs to draw a "blob" on the canvas; that is, a transient decoration like a rubber band.

Reimplemented from KoInteractionStrategy.

Definition at line 318 of file CutThroughShapeStrategy.cpp.

319{
320 painter.save();
321
322 KoColor c;
323 c.fromQColor(Qt::darkGray);
324 QColor semitransparentGray = displayRendererInterface->convertColorToDisplayColorSpace(c);
325 semitransparentGray.setAlphaF(0.6);
326 QPen pen = QPen(QBrush(semitransparentGray), 2);
327 painter.setPen(pen);
328
329 painter.setRenderHint(QPainter::RenderHint::Antialiasing, true);
330
332
333 QLineF gutterCenterLine = QLineF(m_startPoint, m_endPoint);
334 gutterCenterLine = converter.documentToView().map(gutterCenterLine);
335 QLineF gutterWidthHelperLine = QLineF(QPointF(0, 0), QPointF(gutterWidth, 0));
336 gutterWidthHelperLine = converter.documentToView().map(gutterWidthHelperLine);
337
338 gutterWidth = gutterWidthHelperLine.length();
339
340 QList<QLineF> gutterLines = KisAlgebra2D::getParallelLines(gutterCenterLine, gutterWidth/2);
341
342 QLineF gutterLine1 = gutterLines.length() > 0 ? gutterLines[0] : gutterCenterLine;
343 QLineF gutterLine2 = gutterLines.length() > 1 ? gutterLines[1] : gutterCenterLine;
344
345
346 painter.drawLine(gutterLine1);
347 painter.drawLine(gutterLine2);
348
349 QRectF arcRect1 = QRectF(gutterCenterLine.p1() - QPointF(gutterWidth/2, gutterWidth/2), gutterCenterLine.p1() + QPointF(gutterWidth/2, gutterWidth/2));
350 QRectF arcRect2 = QRectF(gutterCenterLine.p2() - QPointF(gutterWidth/2, gutterWidth/2), gutterCenterLine.p2() + QPointF(gutterWidth/2, gutterWidth/2));
351
352 int qtAngleFactor = 16;
353 int qtHalfCircle = qtAngleFactor*180;
354
355 painter.drawArc(arcRect1, -qtAngleFactor*kisRadiansToDegrees(KisAlgebra2D::directionBetweenPoints(gutterCenterLine.p1(), gutterLine1.p1(), 0)), qtHalfCircle);
356 painter.drawArc(arcRect2, -qtAngleFactor*kisRadiansToDegrees(KisAlgebra2D::directionBetweenPoints(gutterCenterLine.p2(), gutterLine1.p2(), 0)), -qtHalfCircle);
357
358
359 int xLength = 3;
360 qreal xLengthEllipse = 2*qSqrt(2);
361
362 if (false) { // drawing X
363 painter.drawLine({QLineF(gutterCenterLine.p1() - QPointF(xLength, xLength), gutterCenterLine.p1() + QPointF(xLength, xLength))});
364 painter.drawLine({QLineF(gutterCenterLine.p2() - QPointF(xLength, xLength), gutterCenterLine.p2() + QPointF(xLength, xLength))});
365
366 painter.drawLine({QLineF(gutterCenterLine.p1() - QPointF(xLength, -xLength), gutterCenterLine.p1() + QPointF(xLength, -xLength))});
367 painter.drawLine({QLineF(gutterCenterLine.p2() - QPointF(xLength, -xLength), gutterCenterLine.p2() + QPointF(xLength, -xLength))});
368 }
369
370 // ellipse at the both ends of the gutter center line
371 painter.drawEllipse(gutterCenterLine.p1(), xLengthEllipse, xLengthEllipse);
372 painter.drawEllipse(gutterCenterLine.p2(), xLengthEllipse, xLengthEllipse);
373
374
375
376 pen.setWidth(1);
377 semitransparentGray.setAlphaF(0.2);
378 pen.setColor(semitransparentGray);
379
380 painter.setPen(pen);
381
382 painter.drawLine(gutterCenterLine);
383
384 painter.restore();
385}
virtual QColor convertColorToDisplayColorSpace(const KoColor color) const =0
convertColorToDisplayColorSpace
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
Definition KoColor.cpp:213
virtual QPointF documentToView(const QPointF &documentPoint) const
qreal directionBetweenPoints(const QPointF &p1, const QPointF &p2, qreal defaultAngle)

References calculateLineAngle(), KoColorDisplayRendererInterface::convertColorToDisplayColorSpace(), KisAlgebra2D::directionBetweenPoints(), KoViewConverter::documentToView(), KoColor::fromQColor(), KisAlgebra2D::getParallelLines(), gutterWidthInDocumentCoordinates(), kisRadiansToDegrees(), m_endPoint, and m_startPoint.

◆ willShapeBeCutGeneral()

bool CutThroughShapeStrategy::willShapeBeCutGeneral ( KoShape * referenceShape,
const QPainterPath & srcOutline,
const QRectF & leftOppositeRect,
const QRectF & rightOppositeRect,
bool checkGapLineRect,
const QRectF & gapLineRect )
private

Definition at line 90 of file CutThroughShapeStrategy.cpp.

91{
92 if (dynamic_cast<KoSvgTextShape*>(referenceShape)) {
93 // skip all text
94 return false;
95 }
96
97 if ((srcOutline.boundingRect() & leftOppositeRect).isEmpty()
98 || (srcOutline.boundingRect() & rightOppositeRect).isEmpty()) {
99 // there is nothing on one side
100 // everything is on the other, far away from the gap line
101 // it just makes it a bit faster when there is a whole lot of shapes
102
103 return false;
104 }
105
106 if (checkGapLineRect && (srcOutline.boundingRect() & gapLineRect).isEmpty()) {
107 // the gap lines can't cross the shape since their bounding rects don't cross it
108 return false;
109 }
110
111 return true;
112}

◆ willShapeBeCutPrecise()

bool CutThroughShapeStrategy::willShapeBeCutPrecise ( const QPainterPath & srcOutline,
const QLineF gapLine,
const QLineF & leftLine,
const QLineF & rightLine,
const QPolygonF & gapLinePolygon )
private

Definition at line 114 of file CutThroughShapeStrategy.cpp.

115{
116 bool containsGapLinePointStart = srcOutline.contains(gapLine.p1());
117 bool containsGapLinePointEnd = srcOutline.contains(gapLine.p2());
118
119 // if should skip if there is exactly one gap line point inside the shape
120 bool exactlyOneGapLinePointInside = (containsGapLinePointStart != containsGapLinePointEnd);
121 bool bothGapLinePointsInside = containsGapLinePointStart && containsGapLinePointEnd;
122
123 if (exactlyOneGapLinePointInside) {
124 return false;
125 }
126
127 bool crossesGapLine = KisAlgebra2D::getLineSegmentCrossingLineIndexes(leftLine, srcOutline).count() > 0
128 || KisAlgebra2D::getLineSegmentCrossingLineIndexes(rightLine, srcOutline).count() > 0;
129
130
131 bool containsPointWithinGap = false;
132 Q_FOREACH(QPointF p, srcOutline.toFillPolygon()) {
133 if (gapLinePolygon.containsPoint(p, Qt::WindingFill)) {
134 containsPointWithinGap = true;
135 break;
136 }
137 }
138
139 if (!bothGapLinePointsInside && !crossesGapLine && !containsPointWithinGap) {
140 return false;
141 }
142 return true;
143}
const Params2D p
QList< int > getLineSegmentCrossingLineIndexes(const QLineF &line, const QPainterPath &shape)

References KisAlgebra2D::getLineSegmentCrossingLineIndexes(), and p.

Member Data Documentation

◆ m_allShapes

QList<KoShape *> CutThroughShapeStrategy::m_allShapes
private

Definition at line 52 of file CutThroughShapeStrategy.h.

◆ m_endPoint

QPointF CutThroughShapeStrategy::m_endPoint = QPointF()
private

Definition at line 49 of file CutThroughShapeStrategy.h.

◆ m_previousLineDirtyRect

QRectF CutThroughShapeStrategy::m_previousLineDirtyRect = QRectF()
private

Definition at line 50 of file CutThroughShapeStrategy.h.

◆ m_selectedShapes

QList<KoShape *> CutThroughShapeStrategy::m_selectedShapes
private

Definition at line 51 of file CutThroughShapeStrategy.h.

◆ m_startPoint

QPointF CutThroughShapeStrategy::m_startPoint = QPointF()
private

Definition at line 48 of file CutThroughShapeStrategy.h.

◆ m_width

GutterWidthsConfig CutThroughShapeStrategy::m_width
private

Definition at line 53 of file CutThroughShapeStrategy.h.


The documentation for this class was generated from the following files: