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

The position of a path point within a path shape. More...

#include <KoPathShape.h>

+ Inheritance diagram for KoPathShape:

Classes

struct  PointSelectionChangeListener
 
class  Private
 

Public Member Functions

bool addSubpath (KoSubpath *subpath, int subpathIndex)
 Adds a subpath at the given index to the path.
 
KoPathPointarcTo (qreal rx, qreal ry, qreal startAngle, qreal sweepAngle)
 Add an arc.
 
bool autoFillMarkers () const
 
QRectF boundingRect () const override
 reimplemented
 
bool breakAfter (const KoPathPointIndex &pointIndex)
 Breaks the path after the point index.
 
void clear ()
 Removes all subpaths and their points from the path.
 
KoShapecloneShape () const override
 creates a deep copy of the shape or shape's subtree
 
void close ()
 Closes the current subpath.
 
void closeMerge ()
 Closes the current subpath.
 
KoPathPointIndex closeSubpath (const KoPathPointIndex &pointIndex)
 Close a open subpath.
 
int combine (KoPathShape *path)
 Combines two path shapes by appending the data of the specified path.
 
KoPathPointcurveTo (const QPointF &c, const QPointF &p)
 Adds a new quadratic Bezier curve segment.
 
KoPathPointcurveTo (const QPointF &c1, const QPointF &c2, const QPointF &p)
 Adds a new cubic Bezier curve segment.
 
Qt::FillRule fillRule () const
 Returns the fill rule for the path object.
 
bool hasMarkers () const
 
bool hitTest (const QPointF &position) const override
 reimplemented
 
bool insertPoint (KoPathPoint *point, const KoPathPointIndex &pointIndex)
 Inserts a new point into the given subpath at the specified position.
 
bool isClosedSubpath (int subpathIndex) const
 Checks if a subpath is closed.
 
bool join (int subpathIndex)
 Joins the given subpath with the following one.
 
 KoPathShape ()
 constructor
 
KoPathPointlineTo (const QPointF &p)
 Adds a new line segment.
 
void loadNodeTypes (const QString &nodeTypes)
 Loads node types.
 
KoMarkermarker (KoFlake::MarkerPosition pos) const
 
bool moveSubpath (int oldSubpathIndex, int newSubpathIndex)
 Moves the position of a subpath within a path.
 
KoPathPointmoveTo (const QPointF &p)
 Starts a new Subpath.
 
QString nodeTypes () const
 Saves the node types.
 
virtual QPointF normalize ()
 Normalizes the path data.
 
KoPathPointIndex openSubpath (const KoPathPointIndex &pointIndex)
 Opens a closed subpath.
 
QPainterPath outline () const override
 reimplemented
 
QRectF outlineRect () const override
 reimplemented
 
void paint (QPainter &painter) const override
 reimplemented
 
virtual void paintPoints (KisHandlePainterHelper &handlesHelper)
 
KoPathPointIndex pathPointIndex (const KoPathPoint *point) const
 Returns the path point index of a given path point.
 
virtual QString pathShapeId () const
 
QPainterPath pathStroke (const QPen &pen) const
 
KoPathPointpointByIndex (const KoPathPointIndex &pointIndex) const
 Returns the path point specified by a path point index.
 
int pointCount () const
 Returns the number of points in the path.
 
QList< KoPathPoint * > pointsAt (const QRectF &rect, const bool useControlPoints=false) const
 Returns the path points within the given rectangle.
 
void recommendPointSelectionChange (const QList< KoPathPointIndex > &newSelection)
 
KoPathPointremovePoint (const KoPathPointIndex &pointIndex)
 Removes a point from the path.
 
KoSubpathremoveSubpath (int subpathIndex)
 Removes subpath from the path.
 
bool reverseSubpath (int subpathIndex)
 Reverse subpath.
 
KoPathSegment segmentByIndex (const KoPathPointIndex &pointIndex) const
 Returns the segment specified by a path point index.
 
QList< KoPathSegmentsegmentsAt (const QRectF &rect) const
 Returns the list of path segments within the given rectangle.
 
bool separate (QList< KoPathShape * > &separatedPaths)
 Creates separate path shapes, one for each existing subpath.
 
void setAutoFillMarkers (bool value)
 
void setFillRule (Qt::FillRule fillRule)
 Sets the fill rule to be used for painting the background.
 
void setMarker (KoMarker *marker, KoFlake::MarkerPosition pos)
 
void setSize (const QSizeF &size) override
 
QSizeF size () const override
 reimplemented
 
int subpathCount () const
 Returns the number of subpaths in the path.
 
int subpathPointCount (int subpathIndex) const
 Returns the number of points in a subpath.
 
QString toString (const QTransform &matrix=QTransform()) const
 Returns a odf/svg string representation of the path data with the given matrix applied.
 
 ~KoPathShape () override
 
- Public Member Functions inherited from KoTosContainer
KoShapecreateTextShape (KoDocumentResourceManager *documentResources=0)
 
 KoTosContainer ()
 
virtual bool loadText (const QDomElement &element)
 
void paintComponent (QPainter &painter) const override
 Paint the component Implement this method to allow the shape to paint itself, just like the KoShape::paint() method does.
 
ResizeBehavior resizeBehavior () const
 
void setPlainText (const QString &text)
 
void setResizeBehavior (ResizeBehavior resizeBehavior)
 
void setRunThrough (short int runThrough) override
 
void setTextAlignment (Qt::Alignment alignment)
 
Qt::Alignment textAlignment () const
 
 ~KoTosContainer () override
 
- Public Member Functions inherited from KoShapeContainer
void addShape (KoShape *shape)
 
bool inheritsTransform (const KoShape *shape) const
 
bool isClipped (const KoShape *child) const
 
 KoShapeContainer (KoShapeContainerModel *model=0)
 
KoShapeContainerModelmodel () const
 
void paint (QPainter &painter) const override
 reimplemented
 
 Private (const Private &rhs, KoShapeContainer *q)
 
 Private (KoShapeContainer *q)
 
void removeShape (KoShape *shape)
 
void setClipped (const KoShape *child, bool clipping)
 
void setInheritsTransform (const KoShape *shape, bool inherit)
 
int shapeCount () const
 
ShapeInterfaceshapeInterface ()
 
QList< KoShape * > shapes () const
 
virtual void update () const
 
void update () const override
 reimplemented
 
 ~KoShapeContainer () override
 
virtual ~Private ()
 
- Public Member Functions inherited from KoShape
QRectF absoluteOutlineRect () const
 
QPointF absolutePosition (KoFlake::AnchorPosition anchor=KoFlake::Center) const
 
QTransform absoluteTransformation () const
 
bool addDependee (KoShape *shape)
 
QString additionalAttribute (const QString &name) const
 
void addShapeChangeListener (ShapeChangeListener *listener)
 
KoShapeAnchoranchor () const
 
void applyAbsoluteTransformation (const QTransform &matrix)
 
void applyTransformation (const QTransform &matrix)
 
virtual QSharedPointer< KoShapeBackgroundbackground () const
 
virtual ChildZOrderPolicy childZOrderPolicy ()
 
KoClipMaskclipMask () const
 Returns the currently set clip mask or 0 if there is no clip mask set.
 
KoClipPathclipPath () const
 Returns the currently set clip path or 0 if there is no clip path set.
 
KoShapecloneShapeAndBakeAbsoluteTransform () const
 creates a deep copy of the shape/shapes tree and bakes the absolute transform of this into the resulting shape.
 
void copySettings (const KoShape *shape)
 
QList< KoShape * > dependees () const
 Returns list of shapes depending on this shape.
 
QPointF documentToShape (const QPointF &point) const
 Transforms point from document coordinates to shape coordinates.
 
QRectF documentToShape (const QRectF &rect) const
 Transform rect from document coordinates to shape coordinates.
 
KoFilterEffectStackfilterEffectStack () const
 
bool hasAdditionalAttribute (const QString &name) const
 
bool hasCommonParent (const KoShape *shape) const
 
bool hasDependee (KoShape *shape) const
 Returns if the given shape is dependent on this shape.
 
virtual bool hasTransparency () const
 
QString hyperLink () const
 
bool inheritBackground () const
 inheritBackground shows if the shape inherits background from its parent
 
bool inheritPaintOrder () const
 inheritPaintOrder
 
bool inheritsTransformFromAny (const QList< KoShape * > ancestorsInQuestion) const
 inheritsTransformFromAny checks if the shape inherits transformation from any of the shapes listed in ancestorsInQuestion. The inheritance is checked in recursive way.
 
bool inheritStroke () const
 inheritStroke shows if the shape inherits the stroke from its parent
 
bool isContentProtected () const
 
bool isGeometryProtected () const
 
bool isPrintable () const
 
bool isSelectable () const
 
virtual bool isShapeEditable (bool recursive=true) const
 checks recursively if the shape or one of its parents is not visible or locked
 
bool isVisible (bool recursive=true) const
 
bool keepAspectRatio () const
 
 KoShape ()
 Constructor.
 
qreal minimumHeight () const
 
QString name () const
 
void notifyChanged ()
 
virtual void paintMarkers (QPainter &painter) const
 paintStroke paints the shape's markers
 
virtual QVector< PaintOrderpaintOrder () const
 paintOrder
 
virtual void paintStroke (QPainter &painter) const
 paintStroke paints the shape's stroked outline
 
KoShapeContainerparent () const
 
QPointF position () const
 Get the position of the shape in pt.
 
void removeAdditionalAttribute (const QString &name)
 
void removeAdditionalStyleAttribute (const char *name)
 
void removeDependee (KoShape *shape)
 
void removeShapeChangeListener (ShapeChangeListener *listener)
 
void rotate (qreal angle)
 Rotate the shape (relative)
 
qreal rotation () const
 
int runThrough () const
 
void scale (qreal sx, qreal sy)
 Scale the shape using the zero-point which is the top-left corner.
 
void setAbsolutePosition (const QPointF &newPosition, KoFlake::AnchorPosition anchor=KoFlake::Center)
 
void setAdditionalAttribute (const QString &name, const QString &value)
 
void setAdditionalStyleAttribute (const char *name, const QString &value)
 
void setAnchor (KoShapeAnchor *anchor)
 
virtual void setBackground (QSharedPointer< KoShapeBackground > background)
 
void setClipMask (KoClipMask *clipMask)
 Sets a new clip mask, removing the old one. The mask is owned by the shape.
 
void setClipPath (KoClipPath *clipPath)
 Sets a new clip path, removing the old one.
 
void setContentProtected (bool protect)
 
void setFilterEffectStack (KoFilterEffectStack *filterEffectStack)
 Sets the new filter effect stack, removing the old one.
 
void setGeometryProtected (bool on)
 
void setHyperLink (const QString &hyperLink)
 
void setInheritBackground (bool value)
 setInheritBackground marks a shape as inheriting the background from the parent shape. NOTE: The currently selected background is destroyed.
 
void setInheritPaintOrder (bool value)
 setInheritPaintOrder set inherit paint order.
 
void setInheritStroke (bool value)
 setInheritStroke marks a shape as inheriting the stroke from the parent shape. NOTE: The currently selected stroke is destroyed.
 
void setKeepAspectRatio (bool keepAspect)
 
void setMinimumHeight (qreal height)
 
void setName (const QString &name)
 
virtual void setPaintOrder (PaintOrder first, PaintOrder second)
 setPaintOrder set the paint order. As there's only three entries in any given paintorder, you only need to have the first and second entry to set it.
 
void setParent (KoShapeContainer *parent)
 
virtual void setPosition (const QPointF &position)
 Set the position of the shape in pt.
 
void setPrintable (bool on)
 
virtual void setResolution (qreal xRes, qreal yRes)
 
void setSelectable (bool selectable)
 
void setShadow (KoShapeShadow *shadow)
 Sets the new shadow, removing the old one.
 
void setShapeId (const QString &id)
 
virtual void setStroke (KoShapeStrokeModelSP stroke)
 
void setTextRunAroundContour (TextRunAroundContour contour)
 
void setTextRunAroundDistanceBottom (qreal distance)
 
void setTextRunAroundDistanceLeft (qreal distance)
 
void setTextRunAroundDistanceRight (qreal distance)
 
void setTextRunAroundDistanceTop (qreal distance)
 
void setTextRunAroundSide (TextRunAroundSide side, RunThroughLevel runThrough=Background)
 
void setTextRunAroundThreshold (qreal threshold)
 
void setToolDelegates (const QSet< KoShape * > &delegates)
 
void setTransformation (const QTransform &matrix)
 
void setTransparency (qreal transparency)
 
void setUserData (KoShapeUserData *userData)
 
void setVisible (bool on)
 
void setZIndex (qint16 zIndex)
 
KoShapeShadowshadow () const
 Returns the currently set shadow or 0 if there is no shadow set.
 
virtual QPainterPath shadowOutline () const
 
QString shapeId () const
 
QPointF shapeToDocument (const QPointF &point) const
 Transforms point from shape coordinates to document coordinates.
 
QRectF shapeToDocument (const QRectF &rect) const
 Transforms rect from shape coordinates to document coordinates.
 
void shear (qreal sx, qreal sy)
 Shear the shape The shape will be sheared using the zero-point which is the top-left corner.
 
virtual KoSnapData snapData () const
 Returns additional snap data the shape wants to have snapping to.
 
virtual KoShapeStrokeModelSP stroke () const
 
KoInsets strokeInsets () const
 
TextRunAroundContour textRunAroundContour () const
 
qreal textRunAroundDistanceBottom () const
 
qreal textRunAroundDistanceLeft () const
 
qreal textRunAroundDistanceRight () const
 
qreal textRunAroundDistanceTop () const
 
TextRunAroundSide textRunAroundSide () const
 
qreal textRunAroundThreshold () const
 
QSet< KoShape * > toolDelegates () const
 
QTransform transformation () const
 Returns the shapes local transformation matrix.
 
qreal transparency (bool recursive=false) const
 
virtual void updateAbsolute (const QRectF &rect) const
 
KoShapeUserDatauserData () const
 
virtual void waitUntilReady (bool asynchronous=true) const
 
qint16 zIndex () const
 
virtual ~KoShape ()
 Destructor.
 

Static Public Member Functions

static KoPathShapecreateShapeFromPainterPath (const QPainterPath &path)
 Creates path shape from given QPainterPath.
 
- Static Public Member Functions inherited from KoShape
static QRectF absoluteOutlineRect (const QList< KoShape * > &shapes)
 
static QRectF boundingRect (const QList< KoShape * > &shapes)
 
static bool compareShapeZIndex (KoShape *s1, KoShape *s2)
 
static KisHandlePainterHelper createHandlePainterHelperDocument (QPainter *painter, KoShape *shape, qreal handleRadius, int decorationThickness)
 
static KisHandlePainterHelper createHandlePainterHelperView (QPainter *painter, KoShape *shape, const KoViewConverter &converter, qreal handleRadius=0.0, int decorationThickness=1)
 
static QVector< PaintOrderdefaultPaintOrder ()
 default paint order as per SVG specification
 
static QList< KoShape * > linearizeSubtree (const QList< KoShape * > &shapes)
 
static QList< KoShape * > linearizeSubtreeSorted (const QList< KoShape * > &shapes)
 

Protected Member Functions

int arcToCurve (qreal rx, qreal ry, qreal startAngle, qreal sweepAngle, const QPointF &offset, QPointF *curvePoints) const
 Add an arc.
 
 KoPathShape (const KoPathShape &rhs)
 
void map (const QTransform &matrix)
 
void notifyPointsChanged ()
 
QTransform resizeMatrix (const QSizeF &newSize) const
 
KoSubpathListsubpaths ()
 XXX: refactor this using setter?
 
const KoSubpathListsubpaths () const
 
- Protected Member Functions inherited from KoTosContainer
 KoTosContainer (const KoTosContainer &rhs)
 
QRectF preferredTextRect () const
 
void setPreferredTextRect (const QRectF &rect)
 
void shapeChanged (ChangeType type, KoShape *shape=0) override
 
KoShapetextShape () const
 
- Protected Member Functions inherited from KoShapeContainer
 KoShapeContainer (const KoShapeContainer &rhs)
 
void setModel (KoShapeContainerModel *model)
 
void setModelInit (KoShapeContainerModel *model)
 
virtual void shapeCountChanged ()
 
- Protected Member Functions inherited from KoShape
 KoShape (const KoShape &rhs)
 
QList< ShapeChangeListener * > listeners () const
 
void setSizeImpl (const QSizeF &size) const
 
void shapeChangedPriv (KoShape::ChangeType type)
 
QTransform transform () const
 return the current matrix that contains the rotation/scale/position of this shape
 

Private Member Functions

void closeMergeSubpathPriv (KoSubpath *subpath)
 close-merges specified subpath
 
void closeSubpathPriv (KoSubpath *subpath)
 closes specified subpath
 
void updateLastPriv (KoPathPoint **lastPoint)
 

Private Attributes

QScopedPointer< Privated
 

Additional Inherited Members

- Public Types inherited from KoTosContainer
enum  ResizeBehavior { TextFollowsSize , FollowTextSize , IndependentSizes , TextFollowsPreferredTextRect }
 different kinds of resizing behavior to determine how to treat text overflow More...
 
- Public Types inherited from KoShape
enum  ChangeType {
  PositionChanged , RotationChanged , ScaleChanged , ShearChanged ,
  SizeChanged , GenericMatrixChange , KeepAspectRatioChange , ParentChanged ,
  Deleted , StrokeChanged , BackgroundChanged , ShadowChanged ,
  BorderChanged , ParameterChanged , ContentChanged , TextRunAroundChanged ,
  ChildChanged , ConnectionPointChanged , ClipPathChanged , ClipMaskChanged ,
  TransparencyChanged
}
 Used by shapeChanged() to select which change was made. More...
 
enum  ChildZOrderPolicy { ChildZDefault , ChildZParentChild = ChildZDefault , ChildZPassThrough }
 Used by compareShapeZIndex() to order shapes. More...
 
enum  PaintOrder { Fill , Stroke , Markers }
 
enum  RunThroughLevel { Background , Foreground }
 
enum  TextRunAroundContour { ContourBox , ContourFull , ContourOutside }
 The behavior text should do when intersecting this shape. More...
 
enum  TextRunAroundSide {
  BiggestRunAroundSide , LeftRunAroundSide , RightRunAroundSide , EnoughRunAroundSide ,
  BothRunAroundSide , NoRunAround , RunThrough
}
 The behavior text should do when intersecting this shape. More...
 
- Public Attributes inherited from KoShapeContainer
KoShapeContainerModelmodel
 
KoShapeContainer::ShapeInterface shapeInterface
 
- Static Public Attributes inherited from KoShape
static const qint16 maxZIndex = std::numeric_limits<qint16>::max()
 
static const qint16 minZIndex = std::numeric_limits<qint16>::min()
 

Detailed Description

The position of a path point within a path shape.

This is the base for all graphical objects.

All graphical objects are based on this object e.g. lines, rectangles, pies and so on.

The KoPathShape uses KoPathPoint's to describe the path of the shape.

Here a short example: 3 points connected by a curveTo's described by the following svg: M 100,200 C 100,100 250,100 250,200 C 250,200 400,300 400,200.

This will be stored in 3 KoPathPoint's as The first point contains in point 100,200 controlPoint2 100,100 The second point contains in point 250,200 controlPoint1 250,100 controlPoint2 250,300 The third point contains in point 400,300 controlPoint1 400,200

Not the segments are stored but the points. Out of the points the segments are generated. See the outline method. The reason for storing it like that is that it is the points that are modified by the user and not the segments.

Definition at line 62 of file KoPathShape.h.

Constructor & Destructor Documentation

◆ KoPathShape() [1/2]

KoPathShape::KoPathShape ( )

constructor

Definition at line 60 of file KoPathShape.cpp.

62 , d(new Private)
63{
64}
QScopedPointer< Private > d

◆ ~KoPathShape()

KoPathShape::~KoPathShape ( )
override

Definition at line 85 of file KoPathShape.cpp.

86{
87 clear();
88}
void clear()
Removes all subpaths and their points from the path.

References clear().

◆ KoPathShape() [2/2]

KoPathShape::KoPathShape ( const KoPathShape & rhs)
protected

constructor: to be used in cloneShape(), not in descendants!

Definition at line 66 of file KoPathShape.cpp.

67 : KoTosContainer(rhs)
68 , d(new Private(*rhs.d))
69{
70 // local data cannot be shared via QSharedData because
71 // every path point holds a pointer to the parent shape
73 Q_FOREACH (KoSubpath *subPath, rhs.d->subpaths) {
74 KoSubpath *clonedSubPath = new KoSubpath();
75
76 Q_FOREACH (KoPathPoint *point, *subPath) {
77 *clonedSubPath << new KoPathPoint(*point, this);
78 }
79
80 subpaths << clonedSubPath;
81 }
82 d->subpaths = subpaths;
83}
QList< KoPathPoint * > KoSubpath
a KoSubpath contains a path from a moveTo until a close or a new moveTo
Definition KoPathShape.h:31
A KoPathPoint represents a point in a path.
const KoSubpathList & subpaths() const

References d, and subpaths().

Member Function Documentation

◆ addSubpath()

bool KoPathShape::addSubpath ( KoSubpath * subpath,
int subpathIndex )

Adds a subpath at the given index to the path.

Parameters
subpaththe subpath to add
subpathIndexthe index at which the new subpath should be inserted
Returns
true on success, false otherwise e.g. subpathIndex out of bounds

Definition at line 937 of file KoPathShape.cpp.

938{
939 if (subpathIndex < 0 || subpathIndex > d->subpaths.size())
940 return false;
941
942 Q_FOREACH (KoPathPoint* point, *subpath) {
943 point->setParent(this);
944 }
945
946 d->subpaths.insert(subpathIndex, subpath);
948
949
950 return true;
951}
void setParent(KoPathShape *parent)
Sets the parent path shape.
void notifyPointsChanged()

References d, notifyPointsChanged(), and KoPathPoint::setParent().

◆ arcTo()

KoPathPoint * KoPathShape::arcTo ( qreal rx,
qreal ry,
qreal startAngle,
qreal sweepAngle )

Add an arc.

Adds an arc starting at the current point. The arc will be converted to bezier curves.

Parameters
rxx radius of the ellipse
ryy radius of the ellipse
startAnglethe angle where the arc will be started
sweepAnglethe length of the angle TODO add param to have angle of the ellipse
Returns
The newly created point

Definition at line 396 of file KoPathShape.cpp.

397{
398 if (d->subpaths.empty()) {
399 moveTo(QPointF(0, 0));
400 }
401
402 KoPathPoint * lastPoint = d->subpaths.last()->last();
403 if (lastPoint->properties() & KoPathPoint::CloseSubpath) {
404 lastPoint = d->subpaths.last()->first();
405 }
406 QPointF startpoint(lastPoint->point());
407
408 KoPathPoint * newEndPoint = lastPoint;
409
410 QPointF curvePoints[12];
411 int pointCnt = arcToCurve(rx, ry, startAngle, sweepAngle, startpoint, curvePoints);
412 for (int i = 0; i < pointCnt; i += 3) {
413 newEndPoint = curveTo(curvePoints[i], curvePoints[i+1], curvePoints[i+2]);
414 }
415 return newEndPoint;
416}
PointProperties properties
QPointF point
@ CloseSubpath
it closes a subpath (only applicable on StartSubpath and StopSubpath)
Definition KoPathPoint.h:40
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.
KoPathPoint * curveTo(const QPointF &c1, const QPointF &c2, const QPointF &p)
Adds a new cubic Bezier curve segment.

References arcToCurve(), KoPathPoint::CloseSubpath, curveTo(), d, moveTo(), KoPathPoint::point, and KoPathPoint::properties.

◆ arcToCurve()

int KoPathShape::arcToCurve ( qreal rx,
qreal ry,
qreal startAngle,
qreal sweepAngle,
const QPointF & offset,
QPointF * curvePoints ) const
protected

Add an arc.

Adds an arc starting at the current point. The arc will be converted to bezier curves.

Parameters
rxx radius of the ellipse
ryy radius of the ellipse
startAnglethe angle where the arc will be started
sweepAnglethe length of the angle TODO add param to have angle of the ellipse
offsetto the first point in the arc
curvePointsan array which take the curve points, pass a 'QPointF curvePoints[12]';
Returns
number of points created by the curve

Definition at line 418 of file KoPathShape.cpp.

419{
420 int pointCnt = 0;
421
422 // check Parameters
423 if (sweepAngle == 0.0)
424 return pointCnt;
425
426 sweepAngle = qBound(-360.0, sweepAngle, 360.0);
427
428 if (rx == 0 || ry == 0) {
429 //TODO
430 }
431
432 // split angles bigger than 90° so that it gives a good approximation to the circle
433 qreal parts = ceil(qAbs(sweepAngle / 90.0));
434
435 qreal sa_rad = startAngle * M_PI / 180.0;
436 qreal partangle = sweepAngle / parts;
437 qreal endangle = startAngle + partangle;
438 qreal se_rad = endangle * M_PI / 180.0;
439 qreal sinsa = sin(sa_rad);
440 qreal cossa = cos(sa_rad);
441 qreal kappa = 4.0 / 3.0 * tan((se_rad - sa_rad) / 4);
442
443 // startpoint is at the last point is the path but when it is closed
444 // it is at the first point
445 QPointF startpoint(offset);
446
447 //center berechnen
448 QPointF center(startpoint - QPointF(cossa * rx, -sinsa * ry));
449
450 //debugFlake <<"kappa" << kappa <<"parts" << parts;
451
452 for (int part = 0; part < parts; ++part) {
453 // start tangent
454 curvePoints[pointCnt++] = QPointF(startpoint - QPointF(sinsa * rx * kappa, cossa * ry * kappa));
455
456 qreal sinse = sin(se_rad);
457 qreal cosse = cos(se_rad);
458
459 // end point
460 QPointF endpoint(center + QPointF(cosse * rx, -sinse * ry));
461 // end tangent
462 curvePoints[pointCnt++] = QPointF(endpoint - QPointF(-sinse * rx * kappa, -cosse * ry * kappa));
463 curvePoints[pointCnt++] = endpoint;
464
465 // set the endpoint as next start point
466 startpoint = endpoint;
467 sinsa = sinse;
468 cossa = cosse;
469 endangle += partangle;
470 se_rad = endangle * M_PI / 180.0;
471 }
472
473 return pointCnt;
474}
quint64 part(quint64 n1, quint64 n2, int p)
#define M_PI
Definition kis_global.h:111

References M_PI, and part().

◆ autoFillMarkers()

bool KoPathShape::autoFillMarkers ( ) const

Definition at line 1330 of file KoPathShape.cpp.

1331{
1332 return d->autoFillMarkers;
1333}

References d.

◆ boundingRect()

QRectF KoPathShape::boundingRect ( ) const
overridevirtual

reimplemented

First we approximate the insets of the stroke by rendering a fat bezier curve with width set to the maximum inset of miters and markers. The are swept by this curve will be a good approximation of the real curve bounding rect.

NOTE: stroking the entire shape might be too expensive, so try to estimate the bounds using insets only...

Reimplemented from KoShape.

Definition at line 250 of file KoPathShape.cpp.

251{
252 const QTransform transform = absoluteTransformation();
253
259 qreal outlineSweepWidth = 0;
260
261 const QSharedPointer<KoShapeStroke> lineBorder = qSharedPointerDynamicCast<KoShapeStroke>(stroke());
262 if (lineBorder) {
263 outlineSweepWidth = lineBorder->lineWidth();
264 }
265
266 if (stroke()) {
267 KoInsets inset;
268 stroke()->strokeInsets(this, inset);
269 const qreal maxInset = std::max({inset.left, inset.top, inset.right, inset.bottom});
270
271 // insets extend outside the shape, but width extends both inside and outside,
272 // so we should multiply insets by 2.0
273 outlineSweepWidth = std::max({outlineSweepWidth,
274 2.0 * maxInset,
275 2.0 * stroke()->strokeMaxMarkersInset(this)});
276 }
277
278
279
282
283#if 0
284 QPen pen(Qt::black, outlineSweepWidth);
285
286 // select round joins and caps to ensure it sweeps exactly
287 // 'outlineSweepWidth' pixels in every possible
288 pen.setJoinStyle(Qt::RoundJoin);
289 pen.setCapStyle(Qt::RoundCap);
290 QRectF bb = transform.map(pathStroke(pen)).boundingRect();
291#endif
292
293 // add 10% extra update area around the doubled insets
294 QRectF bb = transform.mapRect(kisGrowRect(outline().boundingRect(), 1.1 * 0.5 * outlineSweepWidth));
295
296 if (shadow()) {
297 KoInsets insets;
298 shadow()->insets(insets);
299 bb.adjust(-insets.left, -insets.top, insets.right, insets.bottom);
300 }
301 if (filterEffectStack()) {
302 QRectF clipRect = filterEffectStack()->clipRectForBoundingRect(QRectF(QPointF(), size()));
303 bb |= transform.mapRect(clipRect);
304 }
305 return bb;
306}
QRectF clipRectForBoundingRect(const QRectF &boundingRect) const
Returns the clipping rectangle for the given bounding rect.
QSizeF size() const override
reimplemented
QPainterPath pathStroke(const QPen &pen) const
QPainterPath outline() const override
reimplemented
QRectF boundingRect() const override
reimplemented
void insets(KoInsets &insets) const
Fills the insets object with the space the shadow takes around a shape.
virtual KoShapeStrokeModelSP stroke() const
Definition KoShape.cpp:1067
QTransform absoluteTransformation() const
Definition KoShape.cpp:382
KoShapeShadow * shadow() const
Returns the currently set shadow or 0 if there is no shadow set.
Definition KoShape.cpp:1116
KoFilterEffectStack * filterEffectStack() const
Definition KoShape.cpp:1294
QTransform transform() const
return the current matrix that contains the rotation/scale/position of this shape
Definition KoShape.cpp:1145
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
qreal bottom
Bottom inset.
Definition KoInsets.h:50
qreal right
Right inset.
Definition KoInsets.h:52
qreal top
Top inset.
Definition KoInsets.h:49
qreal left
Left inset.
Definition KoInsets.h:51

References KoShape::absoluteTransformation(), KoInsets::bottom, boundingRect(), KoFilterEffectStack::clipRectForBoundingRect(), KoShape::filterEffectStack(), KoShapeShadow::insets(), kisGrowRect(), KoInsets::left, outline(), pathStroke(), KoInsets::right, KoShape::shadow(), size(), KoShape::stroke(), KoInsets::top, and KoShape::transform().

◆ breakAfter()

bool KoPathShape::breakAfter ( const KoPathPointIndex & pointIndex)

Breaks the path after the point index.

The new subpath will be behind the one that was broken. The segment between the given point and the one behind will be removed. If you want to split at one point insert first a copy of the point behind it. This does not work when the subpath is closed. Use openSubpath for this. It does not break at the last position of a subpath or if there is only one point in the subpath.

Parameters
pointIndexindex of the point after which the path should be broken
Returns
true if the subpath was broken, otherwise false

Definition at line 755 of file KoPathShape.cpp.

756{
757 KoSubpath *subpath = d->subPath(pointIndex.first);
758
759 if (!subpath || pointIndex.second < 0 || pointIndex.second > subpath->size() - 2
760 || isClosedSubpath(pointIndex.first))
761 return false;
762
763 KoSubpath * newSubpath = new KoSubpath;
764
765 int size = subpath->size();
766 for (int i = pointIndex.second + 1; i < size; ++i) {
767 newSubpath->append(subpath->takeAt(pointIndex.second + 1));
768 }
769 // now make the first point of the new subpath a starting node
770 newSubpath->first()->setProperty(KoPathPoint::StartSubpath);
771 // the last point of the old subpath is now an ending node
772 subpath->last()->setProperty(KoPathPoint::StopSubpath);
773
774 // insert the new subpath after the broken one
775 d->subpaths.insert(pointIndex.first + 1, newSubpath);
777
778 return true;
779}
@ StartSubpath
it starts a new subpath by a moveTo command
Definition KoPathPoint.h:38
@ StopSubpath
it stops a subpath (last point of subpath)
Definition KoPathPoint.h:39
bool isClosedSubpath(int subpathIndex) const
Checks if a subpath is closed.

References d, isClosedSubpath(), notifyPointsChanged(), size(), KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ clear()

void KoPathShape::clear ( )

Removes all subpaths and their points from the path.

Definition at line 95 of file KoPathShape.cpp.

96{
97 Q_FOREACH (KoSubpath *subpath, d->subpaths) {
98 Q_FOREACH (KoPathPoint *point, *subpath)
99 delete point;
100 delete subpath;
101 }
102 d->subpaths.clear();
103
105}

References d, and notifyPointsChanged().

◆ cloneShape()

KoShape * KoPathShape::cloneShape ( ) const
overridevirtual

creates a deep copy of the shape or shape's subtree

Returns
a cloned shape

Reimplemented from KoShape.

Reimplemented in RectangleShape, SpiralShape, and StarShape.

Definition at line 90 of file KoPathShape.cpp.

91{
92 return new KoPathShape(*this);
93}
KoPathShape()
constructor

References KoPathShape().

◆ close()

void KoPathShape::close ( )

Closes the current subpath.

Definition at line 476 of file KoPathShape.cpp.

477{
478 if (d->subpaths.empty()) {
479 return;
480 }
481 closeSubpathPriv(d->subpaths.last());
482}
void closeSubpathPriv(KoSubpath *subpath)
closes specified subpath

References closeSubpathPriv(), and d.

◆ closeMerge()

void KoPathShape::closeMerge ( )

Closes the current subpath.

It tries to merge the last and first point of the subpath to one point and then closes the subpath. If merging is not possible as the two point are to far from each other a close will be done. TODO define a maximum distance between the two points until this is working

Definition at line 484 of file KoPathShape.cpp.

485{
486 if (d->subpaths.empty()) {
487 return;
488 }
489 closeMergeSubpathPriv(d->subpaths.last());
490}
void closeMergeSubpathPriv(KoSubpath *subpath)
close-merges specified subpath

References closeMergeSubpathPriv(), and d.

◆ closeMergeSubpathPriv()

void KoPathShape::closeMergeSubpathPriv ( KoSubpath * subpath)
private

close-merges specified subpath

Definition at line 1025 of file KoPathShape.cpp.

1026{
1027 if (! subpath || subpath->size() < 2)
1028 return;
1029
1030 KoPathPoint * lastPoint = subpath->last();
1031 KoPathPoint * firstPoint = subpath->first();
1032
1033 // check if first and last points are coincident
1034 if (lastPoint->point() == firstPoint->point()) {
1035 // we are removing the current last point and
1036 // reuse its first control point if active
1039 if (lastPoint->activeControlPoint1())
1040 firstPoint->setControlPoint1(lastPoint->controlPoint1());
1041 // remove last point
1042 delete subpath->takeLast();
1043 // the new last point closes the subpath now
1044 lastPoint = subpath->last();
1047
1049 } else {
1050 closeSubpathPriv(subpath);
1051 }
1052}
void setControlPoint1(const QPointF &point)
Set the control point 1.
void setProperty(PointProperty property)
Sets a single property of a point.
QPointF controlPoint1
bool activeControlPoint1

References KoPathPoint::activeControlPoint1, KoPathPoint::CloseSubpath, closeSubpathPriv(), KoPathPoint::controlPoint1, notifyPointsChanged(), KoPathPoint::point, KoPathPoint::setControlPoint1(), KoPathPoint::setProperty(), KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ closeSubpath()

KoPathPointIndex KoPathShape::closeSubpath ( const KoPathPointIndex & pointIndex)

Close a open subpath.

The subpath is closed be inserting a segment between the start and end point, making the given point the new start point of the subpath.

Returns
the new position of the old first point in the subpath otherwise KoPathPointIndex( -1, -1 )

Definition at line 856 of file KoPathShape.cpp.

857{
858 KoSubpath *subpath = d->subPath(pointIndex.first);
859
860 if (!subpath || pointIndex.second < 0 || pointIndex.second >= subpath->size()
861 || isClosedSubpath(pointIndex.first))
862 return KoPathPointIndex(-1, -1);
863
864 KoPathPoint * oldStartPoint = subpath->first();
865 // the old starting node no longer starts the subpath
867 // the old end node no longer ends the subpath
868 subpath->last()->unsetProperty(KoPathPoint::StopSubpath);
869
870 // reorder the subpath
871 for (int i = 0; i < pointIndex.second; ++i) {
872 subpath->append(subpath->takeFirst());
873 }
874 subpath->first()->setProperty(KoPathPoint::StartSubpath);
875 subpath->last()->setProperty(KoPathPoint::StopSubpath);
876
877 closeSubpathPriv(subpath);
878
880
881 return pathPointIndex(oldStartPoint);
882}
QPair< int, int > KoPathPointIndex
Definition KoPathShape.h:28
void unsetProperty(PointProperty property)
Removes a property from the point.
KoPathPointIndex pathPointIndex(const KoPathPoint *point) const
Returns the path point index of a given path point.

References closeSubpathPriv(), d, isClosedSubpath(), notifyPointsChanged(), pathPointIndex(), KoPathPoint::StartSubpath, KoPathPoint::StopSubpath, and KoPathPoint::unsetProperty().

◆ closeSubpathPriv()

void KoPathShape::closeSubpathPriv ( KoSubpath * subpath)
private

closes specified subpath

Definition at line 1014 of file KoPathShape.cpp.

1015{
1016 if (! subpath)
1017 return;
1018
1019 subpath->last()->setProperty(KoPathPoint::CloseSubpath);
1020 subpath->first()->setProperty(KoPathPoint::CloseSubpath);
1021
1023}

References KoPathPoint::CloseSubpath, and notifyPointsChanged().

◆ combine()

int KoPathShape::combine ( KoPathShape * path)

Combines two path shapes by appending the data of the specified path.

Parameters
paththe path to combine with
Returns
index of the first segment inserted or -1 on failure

Definition at line 952 of file KoPathShape.cpp.

953{
954 int insertSegmentPosition = -1;
955 if (!path) return insertSegmentPosition;
956
957 QTransform pathMatrix = path->absoluteTransformation();
958 QTransform myMatrix = absoluteTransformation().inverted();
959
960 Q_FOREACH (KoSubpath* subpath, path->d->subpaths) {
961 KoSubpath *newSubpath = new KoSubpath();
962
963 Q_FOREACH (KoPathPoint* point, *subpath) {
964 KoPathPoint *newPoint = new KoPathPoint(*point, this);
965 newPoint->map(pathMatrix);
966 newPoint->map(myMatrix);
967 newSubpath->append(newPoint);
968 }
969 d->subpaths.append(newSubpath);
970
971 if (insertSegmentPosition < 0) {
972 insertSegmentPosition = d->subpaths.size() - 1;
973 }
974 }
975 normalize();
976
978 return insertSegmentPosition;
979}
void map(const QTransform &matrix)
apply matrix on the point
virtual QPointF normalize()
Normalizes the path data.

References KoShape::absoluteTransformation(), d, KoPathPoint::map(), normalize(), and notifyPointsChanged().

◆ createShapeFromPainterPath()

KoPathShape * KoPathShape::createShapeFromPainterPath ( const QPainterPath & path)
static

Creates path shape from given QPainterPath.

Definition at line 1247 of file KoPathShape.cpp.

1248{
1249 KoPathShape * shape = new KoPathShape();
1250
1251 int elementCount = path.elementCount();
1252 for (int i = 0; i < elementCount; i++) {
1253 QPainterPath::Element element = path.elementAt(i);
1254 switch (element.type) {
1255 case QPainterPath::MoveToElement:
1256 shape->moveTo(QPointF(element.x, element.y));
1257 break;
1258 case QPainterPath::LineToElement:
1259 shape->lineTo(QPointF(element.x, element.y));
1260 break;
1261 case QPainterPath::CurveToElement:
1262 shape->curveTo(QPointF(element.x, element.y),
1263 QPointF(path.elementAt(i + 1).x, path.elementAt(i + 1).y),
1264 QPointF(path.elementAt(i + 2).x, path.elementAt(i + 2).y));
1265 break;
1266 default:
1267 continue;
1268 }
1269 }
1270
1271 shape->setShapeId(KoPathShapeId);
1272
1273 //shape->normalize();
1274 return shape;
1275}
#define KoPathShapeId
Definition KoPathShape.h:20
The position of a path point within a path shape.
Definition KoPathShape.h:63
KoPathPoint * lineTo(const QPointF &p)
Adds a new line segment.
void setShapeId(const QString &id)
Definition KoShape.cpp:1062

References curveTo(), KoPathShape(), KoPathShapeId, lineTo(), moveTo(), and KoShape::setShapeId().

◆ curveTo() [1/2]

KoPathPoint * KoPathShape::curveTo ( const QPointF & c,
const QPointF & p )

Adds a new quadratic Bezier curve segment.

Adds a quadratic Bezier curve between the last point and the given point p, using the control point specified by c.

Parameters
ccontrol point
pthe endpoint of this curve segment
Returns
The newly created point

Definition at line 382 of file KoPathShape.cpp.

383{
384 if (d->subpaths.empty())
385 moveTo(QPointF(0, 0));
386
387 KoPathPoint * lastPoint = d->subpaths.last()->last();
388 updateLastPriv(&lastPoint);
389 lastPoint->setControlPoint2(c);
391 d->subpaths.last()->push_back(point);
393 return point;
394}
const Params2D p
void setControlPoint2(const QPointF &point)
Set the control point 2.
void updateLastPriv(KoPathPoint **lastPoint)

References d, moveTo(), notifyPointsChanged(), p, KoPathPoint::setControlPoint2(), KoPathPoint::StopSubpath, and updateLastPriv().

◆ curveTo() [2/2]

KoPathPoint * KoPathShape::curveTo ( const QPointF & c1,
const QPointF & c2,
const QPointF & p )

Adds a new cubic Bezier curve segment.

Adds a cubic Bezier curve between the last point and the given point p, using the control points specified by c1 and c2.

Parameters
c1control point1
c2control point2
pthe endpoint of this curve segment
Returns
The newly created point

Definition at line 367 of file KoPathShape.cpp.

368{
369 if (d->subpaths.empty()) {
370 moveTo(QPointF(0, 0));
371 }
372 KoPathPoint * lastPoint = d->subpaths.last()->last();
373 updateLastPriv(&lastPoint);
374 lastPoint->setControlPoint2(c1);
376 point->setControlPoint1(c2);
377 d->subpaths.last()->push_back(point);
379 return point;
380}

References d, moveTo(), notifyPointsChanged(), p, KoPathPoint::setControlPoint1(), KoPathPoint::setControlPoint2(), KoPathPoint::StopSubpath, and updateLastPriv().

◆ fillRule()

Qt::FillRule KoPathShape::fillRule ( ) const

Returns the fill rule for the path object.

Definition at line 1237 of file KoPathShape.cpp.

1238{
1239 return d->fillRule;
1240}

References d.

◆ hasMarkers()

bool KoPathShape::hasMarkers ( ) const

Definition at line 1325 of file KoPathShape.cpp.

1326{
1327 return !d->markersNew.isEmpty();
1328}

References d.

◆ hitTest()

bool KoPathShape::hitTest ( const QPointF & position) const
overridevirtual

reimplemented

Reimplemented from KoShape.

Definition at line 1277 of file KoPathShape.cpp.

1278{
1279 if (parent() && parent()->isClipped(this) && ! parent()->hitTest(position))
1280 return false;
1281
1282 QPointF point = absoluteTransformation().inverted().map(position);
1283 const QPainterPath outlinePath = outline();
1284 if (stroke()) {
1285 KoInsets insets;
1286 stroke()->strokeInsets(this, insets);
1287 QRectF roi(QPointF(-insets.left, -insets.top), QPointF(insets.right, insets.bottom));
1288
1289 roi.moveCenter(point);
1290 if (outlinePath.intersects(roi) || outlinePath.contains(roi))
1291 return true;
1292 } else {
1293 if (outlinePath.contains(point))
1294 return true;
1295 }
1296
1297 // if there is no shadow we can as well just leave
1298 if (! shadow())
1299 return false;
1300
1301 // the shadow has an offset to the shape, so we simply
1302 // check if the position minus the shadow offset hits the shape
1303 point = absoluteTransformation().inverted().map(position - shadow()->offset());
1304
1305 return outlinePath.contains(point);
1306}
bool hitTest(const QPointF &position) const override
reimplemented
bool isClipped(const KoShape *child) const
KoShapeContainer * parent
Definition KoShape_p.h:80
QPointF position() const
Get the position of the shape in pt.
Definition KoShape.cpp:825

References KoShape::absoluteTransformation(), KoInsets::bottom, hitTest(), KoShapeContainer::isClipped(), KoInsets::left, map(), outline(), KoShape::Private::parent, KoShape::position(), KoInsets::right, KoShape::shadow(), KoShape::stroke(), and KoInsets::top.

◆ insertPoint()

bool KoPathShape::insertPoint ( KoPathPoint * point,
const KoPathPointIndex & pointIndex )

Inserts a new point into the given subpath at the specified position.

This method keeps the subpath closed if it is closed, and open when it was open. So it can change the properties of the point inserted. You might need to update the point before/after to get the desired result e.g. when you insert the point into a curve.

Parameters
pointto insert
pointIndexindex at which the point should be inserted
Returns
true on success, false when pointIndex is out of bounds

Definition at line 673 of file KoPathShape.cpp.

674{
675 KoSubpath *subpath = d->subPath(pointIndex.first);
676
677 if (subpath == 0 || pointIndex.second < 0 || pointIndex.second > subpath->size())
678 return false;
679
680 KoPathPoint::PointProperties properties = point->properties();
681 properties &= ~KoPathPoint::StartSubpath;
682 properties &= ~KoPathPoint::StopSubpath;
683 properties &= ~KoPathPoint::CloseSubpath;
684 // check if new point starts subpath
685 if (pointIndex.second == 0) {
686 properties |= KoPathPoint::StartSubpath;
687 // subpath was closed
688 if (subpath->last()->properties() & KoPathPoint::CloseSubpath) {
689 // keep the path closed
690 properties |= KoPathPoint::CloseSubpath;
691 }
692 // old first point does not start the subpath anymore
693 subpath->first()->unsetProperty(KoPathPoint::StartSubpath);
694 }
695 // check if new point stops subpath
696 else if (pointIndex.second == subpath->size()) {
697 properties |= KoPathPoint::StopSubpath;
698 // subpath was closed
699 if (subpath->last()->properties() & KoPathPoint::CloseSubpath) {
700 // keep the path closed
701 properties = properties | KoPathPoint::CloseSubpath;
702 }
703 // old last point does not end subpath anymore
704 subpath->last()->unsetProperty(KoPathPoint::StopSubpath);
705 }
706
707 point->setProperties(properties);
708 point->setParent(this);
709 subpath->insert(pointIndex.second , point);
711
712 return true;
713}
void setProperties(PointProperties properties)
Set the properties of a point.

References KoPathPoint::CloseSubpath, d, notifyPointsChanged(), KoPathPoint::properties, KoPathPoint::setParent(), KoPathPoint::setProperties(), KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ isClosedSubpath()

bool KoPathShape::isClosedSubpath ( int subpathIndex) const

Checks if a subpath is closed.

Parameters
subpathIndexindex of the subpath to check
Returns
true when the subpath is closed, false otherwise

Definition at line 660 of file KoPathShape.cpp.

661{
662 KoSubpath *subpath = d->subPath(subpathIndex);
663
664 if (subpath == 0)
665 return false;
666
667 const bool firstClosed = subpath->first()->properties() & KoPathPoint::CloseSubpath;
668 const bool lastClosed = subpath->last()->properties() & KoPathPoint::CloseSubpath;
669
670 return firstClosed && lastClosed;
671}

References KoPathPoint::CloseSubpath, and d.

◆ join()

bool KoPathShape::join ( int subpathIndex)

Joins the given subpath with the following one.

Joins the given subpath with the following one by inserting a segment between the two subpaths. This does nothing if the specified subpath is the last subpath or one of both subpaths is closed.

Parameters
subpathIndexindex of the subpath being joined with the following subpath
Returns
true if the subpath was joined, otherwise false

Definition at line 781 of file KoPathShape.cpp.

782{
783 KoSubpath *subpath = d->subPath(subpathIndex);
784 KoSubpath *nextSubpath = d->subPath(subpathIndex + 1);
785
786 if (!subpath || !nextSubpath || isClosedSubpath(subpathIndex)
787 || isClosedSubpath(subpathIndex+1))
788 return false;
789
790 // the last point of the subpath does not end the subpath anymore
791 subpath->last()->unsetProperty(KoPathPoint::StopSubpath);
792 // the first point of the next subpath does not start a subpath anymore
793 nextSubpath->first()->unsetProperty(KoPathPoint::StartSubpath);
794
795 // append the second subpath to the first
796 Q_FOREACH (KoPathPoint * p, *nextSubpath)
797 subpath->append(p);
798
799 // remove the nextSubpath from path
800 d->subpaths.removeAt(subpathIndex + 1);
801
802 // delete it as it is no longer possible to use it
803 delete nextSubpath;
804
806
807 return true;
808}

References d, isClosedSubpath(), notifyPointsChanged(), p, KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ lineTo()

KoPathPoint * KoPathShape::lineTo ( const QPointF & p)

Adds a new line segment.

Adds a straight line between the last point and the given point p.

Returns
the newly created point

Definition at line 354 of file KoPathShape.cpp.

355{
356 if (d->subpaths.empty()) {
357 moveTo(QPointF(0, 0));
358 }
360 KoPathPoint * lastPoint = d->subpaths.last()->last();
361 updateLastPriv(&lastPoint);
362 d->subpaths.last()->push_back(point);
364 return point;
365}

References d, moveTo(), notifyPointsChanged(), p, KoPathPoint::StopSubpath, and updateLastPriv().

◆ loadNodeTypes()

void KoPathShape::loadNodeTypes ( const QString & nodeTypes)

Loads node types.

Definition at line 1211 of file KoPathShape.cpp.

1212{
1213 QString::const_iterator nIt(nodeTypes.constBegin());
1214 KoSubpathList::const_iterator pathIt(d->subpaths.constBegin());
1215 for (; pathIt != d->subpaths.constEnd(); ++pathIt) {
1216 KoSubpath::const_iterator it((*pathIt)->constBegin());
1217 for (; it != (*pathIt)->constEnd(); ++it, nIt++) {
1218 // be sure not to crash if there are not enough nodes in nodeTypes
1219 if (nIt == nodeTypes.constEnd()) {
1220 warnFlake << "not enough nodes in sodipodi:nodetypes";
1221 return;
1222 }
1223 // the first node is always of type 'c'
1224 if (it != (*pathIt)->constBegin()) {
1225 updateNodeType(*it, *nIt);
1226 }
1227
1228 if ((*it)->properties() & KoPathPoint::StopSubpath
1229 && (*it)->properties() & KoPathPoint::CloseSubpath) {
1230 ++nIt;
1231 updateNodeType((*pathIt)->first(), *nIt);
1232 }
1233 }
1234 }
1235}
#define warnFlake
Definition FlakeDebug.h:16
void updateNodeType(KoPathPoint *point, const QChar &nodeType)
QString nodeTypes() const
Saves the node types.

References KoPathPoint::CloseSubpath, d, nodeTypes(), KoPathPoint::StopSubpath, updateNodeType(), and warnFlake.

◆ map()

void KoPathShape::map ( const QTransform & matrix)
protected

Definition at line 1064 of file KoPathShape.cpp.

1065{
1066 return d->map(matrix);
1067}

References d.

◆ marker()

KoMarker * KoPathShape::marker ( KoFlake::MarkerPosition pos) const

Definition at line 1320 of file KoPathShape.cpp.

1321{
1322 return d->markersNew[pos].data();
1323}

References d.

◆ moveSubpath()

bool KoPathShape::moveSubpath ( int oldSubpathIndex,
int newSubpathIndex )

Moves the position of a subpath within a path.

Parameters
oldSubpathIndexold index of the subpath
newSubpathIndexnew index of the subpath
Returns
true if the subpath was moved, otherwise false e.g. if an index is out of bounds

Definition at line 810 of file KoPathShape.cpp.

811{
812 KoSubpath *subpath = d->subPath(oldSubpathIndex);
813
814 if (subpath == 0 || newSubpathIndex >= d->subpaths.size())
815 return false;
816
817 if (oldSubpathIndex == newSubpathIndex)
818 return true;
819
820 d->subpaths.removeAt(oldSubpathIndex);
821 d->subpaths.insert(newSubpathIndex, subpath);
822
824
825 return true;
826}

References d, and notifyPointsChanged().

◆ moveTo()

KoPathPoint * KoPathShape::moveTo ( const QPointF & p)

Starts a new Subpath.

Moves the pen to p and starts a new subpath.

Returns
the newly created point

Definition at line 344 of file KoPathShape.cpp.

345{
347 KoSubpath * path = new KoSubpath;
348 path->push_back(point);
349 d->subpaths.push_back(path);
351 return point;
352}

References d, notifyPointsChanged(), p, KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ nodeTypes()

QString KoPathShape::nodeTypes ( ) const

Saves the node types.

This is inspired by inkscape and uses the same mechanism as they do. This attribute contains of a string which has the node type of each point in it. The following node types exist:

c corner s smooth z symmetric

The first point of a path is always of the type c. If the path is closed the type of the first point is saved in the last element E.g. you have a closed path with 2 points in it. The first one (start/end of path) is symmetric and the second one is smooth that will result in the nodeType="czs" So if there is a closed sub path the nodeTypes contain one more entry then there are points. That is due to the first and the last point of a closed sub path get merged into one when they are on the same position.

Returns
The node types as string

Definition at line 1177 of file KoPathShape.cpp.

1178{
1179 QString types;
1180 KoSubpathList::const_iterator pathIt(d->subpaths.constBegin());
1181 for (; pathIt != d->subpaths.constEnd(); ++pathIt) {
1182 KoSubpath::const_iterator it((*pathIt)->constBegin());
1183 for (; it != (*pathIt)->constEnd(); ++it) {
1184 if (it == (*pathIt)->constBegin()) {
1185 types.append('c');
1186 }
1187 else {
1188 types.append(nodeType(*it));
1189 }
1190
1191 if ((*it)->properties() & KoPathPoint::StopSubpath
1192 && (*it)->properties() & KoPathPoint::CloseSubpath) {
1193 KoPathPoint * firstPoint = (*pathIt)->first();
1194 types.append(nodeType(firstPoint));
1195 }
1196 }
1197 }
1198 return types;
1199}
char nodeType(const KoPathPoint *point)

References KoPathPoint::CloseSubpath, d, nodeType(), and KoPathPoint::StopSubpath.

◆ normalize()

QPointF KoPathShape::normalize ( )
virtual

Normalizes the path data.

The path points are transformed so that the top-left corner of the bounding rect is at (0,0). This should be called after adding points to the path or changing positions of path points.

Returns
the offset by which the points are moved in shape coordinates.

Reimplemented in KoParameterShape, EllipseShape, EnhancedPathShape, SpiralShape, and KarbonCalligraphicShape.

Definition at line 492 of file KoPathShape.cpp.

493{
494 QPointF tl(outline().boundingRect().topLeft());
495 QTransform matrix;
496 matrix.translate(-tl.x(), -tl.y());
497 d->map(matrix);
498
499 // keep the top left point of the object
500 applyTransformation(matrix.inverted());
502 return tl;
503}
void applyTransformation(const QTransform &matrix)
Definition KoShape.cpp:410
void shapeChangedPriv(KoShape::ChangeType type)
Definition KoShape.cpp:132
@ ContentChanged
the content of the shape changed e.g. a new image inside a pixmap/text change inside a textshape
Definition KoShape.h:110

References KoShape::applyTransformation(), boundingRect(), KoShape::ContentChanged, d, outline(), and KoShape::shapeChangedPriv().

◆ notifyPointsChanged()

void KoPathShape::notifyPointsChanged ( )
protected

Definition at line 1350 of file KoPathShape.cpp.

1351{
1352 Q_FOREACH (KoShape::ShapeChangeListener *listener, listeners()) {
1353 PointSelectionChangeListener *pointListener = dynamic_cast<PointSelectionChangeListener*>(listener);
1354 if (pointListener) {
1355 pointListener->notifyPathPointsChanged(this);
1356 }
1357 }
1358}
QList< KoShape::ShapeChangeListener * > listeners
Definition KoShape_p.h:84

References KoShape::Private::listeners, and KoPathShape::PointSelectionChangeListener::notifyPathPointsChanged().

◆ openSubpath()

KoPathPointIndex KoPathShape::openSubpath ( const KoPathPointIndex & pointIndex)

Opens a closed subpath.

The subpath is opened by removing the segment before the given point, making the given point the new start point of the subpath.

Parameters
pointIndexthe index of the point at which to open the closed subpath
Returns
the new position of the old first point in the subpath otherwise KoPathPointIndex( -1, -1 )

Definition at line 828 of file KoPathShape.cpp.

829{
830 KoSubpath *subpath = d->subPath(pointIndex.first);
831
832 if (!subpath || pointIndex.second < 0 || pointIndex.second >= subpath->size()
833 || !isClosedSubpath(pointIndex.first))
834 return KoPathPointIndex(-1, -1);
835
836 KoPathPoint * oldStartPoint = subpath->first();
837 // the old starting node no longer starts the subpath
839 // the old end node no longer closes the subpath
840 subpath->last()->unsetProperty(KoPathPoint::StopSubpath);
841
842 // reorder the subpath
843 for (int i = 0; i < pointIndex.second; ++i) {
844 subpath->append(subpath->takeFirst());
845 }
846 // make the first point a start node
847 subpath->first()->setProperty(KoPathPoint::StartSubpath);
848 // make the last point an end node
849 subpath->last()->setProperty(KoPathPoint::StopSubpath);
850
852
853 return pathPointIndex(oldStartPoint);
854}

References d, isClosedSubpath(), notifyPointsChanged(), pathPointIndex(), KoPathPoint::StartSubpath, KoPathPoint::StopSubpath, and KoPathPoint::unsetProperty().

◆ outline()

QPainterPath KoPathShape::outline ( ) const
overridevirtual

reimplemented

Reimplemented from KoShape.

Definition at line 185 of file KoPathShape.cpp.

186{
187 QPainterPath path;
188 for (auto subpathIt = d->subpaths.constBegin(); subpathIt != d->subpaths.constEnd(); ++subpathIt) {
189 const KoSubpath * subpath = *subpathIt;
190 const KoPathPoint * lastPoint = subpath->constFirst();
191 bool activeCP = false;
192 for (auto pointIt = subpath->constBegin(); pointIt != subpath->constEnd(); ++pointIt) {
193 const KoPathPoint * currPoint = *pointIt;
194 KoPathPoint::PointProperties currProperties = currPoint->properties();
195 if (currPoint == subpath->constFirst()) {
196 if (currProperties & KoPathPoint::StartSubpath) {
197 Q_ASSERT(!qIsNaNPoint(currPoint->point()));
198 path.moveTo(currPoint->point());
199 }
200 } else if (activeCP && currPoint->activeControlPoint1()) {
201 Q_ASSERT(!qIsNaNPoint(lastPoint->controlPoint2()));
202 Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
203 Q_ASSERT(!qIsNaNPoint(currPoint->point()));
204 path.cubicTo(
205 lastPoint->controlPoint2(),
206 currPoint->controlPoint1(),
207 currPoint->point());
208 } else if (activeCP || currPoint->activeControlPoint1()) {
209 Q_ASSERT(!qIsNaNPoint(lastPoint->controlPoint2()));
210 Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
211 path.quadTo(
212 activeCP ? lastPoint->controlPoint2() : currPoint->controlPoint1(),
213 currPoint->point());
214 } else {
215 Q_ASSERT(!qIsNaNPoint(currPoint->point()));
216 path.lineTo(currPoint->point());
217 }
218 if (currProperties & KoPathPoint::CloseSubpath && currProperties & KoPathPoint::StopSubpath) {
219 // add curve when there is a curve on the way to the first point
220 KoPathPoint * firstPoint = subpath->first();
221 Q_ASSERT(!qIsNaNPoint(firstPoint->point()));
222 if (currPoint->activeControlPoint2() && firstPoint->activeControlPoint1()) {
223 path.cubicTo(
224 currPoint->controlPoint2(),
225 firstPoint->controlPoint1(),
226 firstPoint->point());
227 }
228 else if (currPoint->activeControlPoint2() || firstPoint->activeControlPoint1()) {
229 Q_ASSERT(!qIsNaNPoint(currPoint->point()));
230 Q_ASSERT(!qIsNaNPoint(currPoint->controlPoint1()));
231 path.quadTo(
232 currPoint->activeControlPoint2() ? currPoint->controlPoint2() : firstPoint->controlPoint1(),
233 firstPoint->point());
234 }
235 path.closeSubpath();
236 }
237
238 if (currPoint->activeControlPoint2()) {
239 activeCP = true;
240 } else {
241 activeCP = false;
242 }
243 lastPoint = currPoint;
244 }
245 }
246
247 return path;
248}
static bool qIsNaNPoint(const QPointF &p)
bool activeControlPoint2
QPointF controlPoint2

References KoPathPoint::activeControlPoint1, KoPathPoint::activeControlPoint2, KoPathPoint::CloseSubpath, KoPathPoint::controlPoint1, KoPathPoint::controlPoint2, d, KoPathPoint::point, KoPathPoint::properties, qIsNaNPoint(), KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ outlineRect()

QRectF KoPathShape::outlineRect ( ) const
overridevirtual

reimplemented

Reimplemented from KoShape.

Definition at line 180 of file KoPathShape.cpp.

181{
182 return outline().boundingRect();
183}

References outline().

◆ paint()

void KoPathShape::paint ( QPainter & painter) const
overridevirtual

reimplemented

Implements KoShape.

Definition at line 107 of file KoPathShape.cpp.

108{
109 KisQPainterStateSaver saver(&painter);
110 Q_UNUSED(saver);
111
112 QPainterPath path(outline());
113 path.setFillRule(d->fillRule);
114
115 if (background()) {
116 background()->paint(painter, path);
117 }
118 //d->paintDebug(painter);
119}
virtual QSharedPointer< KoShapeBackground > background() const
Definition KoShape.cpp:926

References KoShape::background(), d, and outline().

◆ paintPoints()

void KoPathShape::paintPoints ( KisHandlePainterHelper & handlesHelper)
virtual

Definition at line 169 of file KoPathShape.cpp.

170{
171 KoSubpathList::const_iterator pathIt(d->subpaths.constBegin());
172
173 for (; pathIt != d->subpaths.constEnd(); ++pathIt) {
174 KoSubpath::const_iterator it((*pathIt)->constBegin());
175 for (; it != (*pathIt)->constEnd(); ++it)
176 (*it)->paint(handlesHelper, KoPathPoint::Node);
177 }
178}
@ Node
the node point
Definition KoPathPoint.h:49

References d, and KoPathPoint::Node.

◆ pathPointIndex()

KoPathPointIndex KoPathShape::pathPointIndex ( const KoPathPoint * point) const

Returns the path point index of a given path point.

Parameters
pointthe point for which you want to get the index
Returns
path point index of the point if it exists otherwise KoPathPointIndex( -1, -1 )

Definition at line 589 of file KoPathShape.cpp.

590{
591 for (int subpathIndex = 0; subpathIndex < d->subpaths.size(); ++subpathIndex) {
592 KoSubpath * subpath = d->subpaths.at(subpathIndex);
593 for (int pointPos = 0; pointPos < subpath->size(); ++pointPos) {
594 if (subpath->at(pointPos) == point) {
595 return KoPathPointIndex(subpathIndex, pointPos);
596 }
597 }
598 }
599 return KoPathPointIndex(-1, -1);
600}

References d.

◆ pathShapeId()

QString KoPathShape::pathShapeId ( ) const
virtual

Returns the specific path shape id.

Path shape derived shapes have a different shape id which link them to their respective shape factories. In most cases they do not have a special tool for editing them. This function returns the specific shape id for finding the shape factory from KoShapeRegistry. The default KoPathShapeId is returned from KoShape::shapeId() so that the generic path editing tool gets activated when the shape is selected.

Returns
the specific shape id

Reimplemented in EllipseShape, RectangleShape, SpiralShape, StarShape, and KarbonCalligraphicShape.

Definition at line 1077 of file KoPathShape.cpp.

1078{
1079 return KoPathShapeId;
1080}

References KoPathShapeId.

◆ pathStroke()

QPainterPath KoPathShape::pathStroke ( const QPen & pen) const

Definition at line 1360 of file KoPathShape.cpp.

1361{
1362 if (d->subpaths.isEmpty()) {
1363 return QPainterPath();
1364 }
1365 QPainterPath pathOutline;
1366
1367 QPainterPathStroker stroker;
1368 stroker.setWidth(0);
1369 stroker.setJoinStyle(Qt::MiterJoin);
1370 stroker.setWidth(pen.widthF());
1371 stroker.setJoinStyle(pen.joinStyle());
1372 stroker.setMiterLimit(pen.miterLimit());
1373 stroker.setCapStyle(pen.capStyle());
1374 stroker.setDashOffset(pen.dashOffset());
1375 stroker.setDashPattern(pen.dashPattern());
1376
1377 QPainterPath path = stroker.createStroke(outline());
1378
1379 pathOutline.addPath(path);
1380 pathOutline.setFillRule(Qt::WindingFill);
1381
1382 return pathOutline;
1383}

References d, and outline().

◆ pointByIndex()

KoPathPoint * KoPathShape::pointByIndex ( const KoPathPointIndex & pointIndex) const

Returns the path point specified by a path point index.

Parameters
pointIndexindex of the point to get
Returns
KoPathPoint on success, 0 otherwise e.g. out of bounds

Definition at line 602 of file KoPathShape.cpp.

603{
604 KoSubpath *subpath = d->subPath(pointIndex.first);
605
606 if (subpath == 0 || pointIndex.second < 0 || pointIndex.second >= subpath->size())
607 return 0;
608
609 return subpath->at(pointIndex.second);
610}

References d.

◆ pointCount()

int KoPathShape::pointCount ( ) const

Returns the number of points in the path.

Returns
The number of points in the path

Definition at line 634 of file KoPathShape.cpp.

635{
636 int i = 0;
637 KoSubpathList::const_iterator pathIt(d->subpaths.constBegin());
638 for (; pathIt != d->subpaths.constEnd(); ++pathIt) {
639 i += (*pathIt)->size();
640 }
641
642 return i;
643}

References d.

◆ pointsAt()

QList< KoPathPoint * > KoPathShape::pointsAt ( const QRectF & rect,
const bool useControlPoints = false ) const

Returns the path points within the given rectangle.

Parameters
rectthe rectangle the requested points are in
useControlPointswhether to add control points to result or not
Returns
list of points within the rectangle

Definition at line 543 of file KoPathShape.cpp.

544{
545 QList<KoPathPoint*> result;
546
547 KoSubpathList::const_iterator pathIt(d->subpaths.constBegin());
548 for (; pathIt != d->subpaths.constEnd(); ++pathIt) {
549 KoSubpath::const_iterator it((*pathIt)->constBegin());
550 for (; it != (*pathIt)->constEnd(); ++it) {
551 if (r.contains((*it)->point()))
552 result.append(*it);
553 else if (useControlPoints) {
554 if ((*it)->activeControlPoint1() && r.contains((*it)->controlPoint1()))
555 result.append(*it);
556 else if ((*it)->activeControlPoint2() && r.contains((*it)->controlPoint2()))
557 result.append(*it);
558 }
559 }
560 }
561 return result;
562}

References d.

◆ recommendPointSelectionChange()

void KoPathShape::recommendPointSelectionChange ( const QList< KoPathPointIndex > & newSelection)

Definition at line 1340 of file KoPathShape.cpp.

1341{
1342 Q_FOREACH (KoShape::ShapeChangeListener *listener, listeners()) {
1343 PointSelectionChangeListener *pointListener = dynamic_cast<PointSelectionChangeListener*>(listener);
1344 if (pointListener) {
1345 pointListener->recommendPointSelectionChange(this, newSelection);
1346 }
1347 }
1348}

References KoShape::Private::listeners, and KoPathShape::PointSelectionChangeListener::recommendPointSelectionChange().

◆ removePoint()

KoPathPoint * KoPathShape::removePoint ( const KoPathPointIndex & pointIndex)

Removes a point from the path.

Note that the ownership of the point will pass to the caller.

Parameters
pointIndexindex of the point which should be removed
Returns
The removed point on success, otherwise 0

Definition at line 715 of file KoPathShape.cpp.

716{
717 KoSubpath *subpath = d->subPath(pointIndex.first);
718
719 if (subpath == 0 || pointIndex.second < 0 || pointIndex.second >= subpath->size())
720 return 0;
721
722 KoPathPoint * point = subpath->takeAt(pointIndex.second);
723 point->setParent(0);
724
725 //don't do anything (not even crash), if there was only one point
726 if (pointCount()==0) {
727 return point;
728 }
729 // check if we removed the first point
730 else if (pointIndex.second == 0) {
731 // first point removed, set new StartSubpath
732 subpath->first()->setProperty(KoPathPoint::StartSubpath);
733 // check if path was closed
734 if (subpath->last()->properties() & KoPathPoint::CloseSubpath) {
735 // keep path closed
736 subpath->first()->setProperty(KoPathPoint::CloseSubpath);
737 }
738 }
739 // check if we removed the last point
740 else if (pointIndex.second == subpath->size()) { // use size as point is already removed
741 // last point removed, set new StopSubpath
742 subpath->last()->setProperty(KoPathPoint::StopSubpath);
743 // check if path was closed
744 if (point->properties() & KoPathPoint::CloseSubpath) {
745 // keep path closed
746 subpath->last()->setProperty(KoPathPoint::CloseSubpath);
747 }
748 }
749
751
752 return point;
753}
int pointCount() const
Returns the number of points in the path.

References KoPathPoint::CloseSubpath, d, notifyPointsChanged(), pointCount(), KoPathPoint::properties, KoPathPoint::setParent(), KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ removeSubpath()

KoSubpath * KoPathShape::removeSubpath ( int subpathIndex)

Removes subpath from the path.

Parameters
subpathIndexthe index of the subpath to remove
Returns
the removed subpath on success, 0 otherwise.

Definition at line 921 of file KoPathShape.cpp.

922{
923 KoSubpath *subpath = d->subPath(subpathIndex);
924
925 if (subpath != 0) {
926 Q_FOREACH (KoPathPoint* point, *subpath) {
927 point->setParent(this);
928 }
929 d->subpaths.removeAt(subpathIndex);
930 }
931
933
934 return subpath;
935}

References d, notifyPointsChanged(), and KoPathPoint::setParent().

◆ resizeMatrix()

QTransform KoPathShape::resizeMatrix ( const QSizeF & newSize) const
protected

Get the resize matrix

This makes sure that also if the newSize isNull that there will be a very small size of 0.000001 pixels

Definition at line 323 of file KoPathShape.cpp.

324{
325 QSizeF oldSize = size();
326 if (oldSize.width() == 0.0) {
327 oldSize.setWidth(0.000001);
328 }
329 if (oldSize.height() == 0.0) {
330 oldSize.setHeight(0.000001);
331 }
332
333 QSizeF sizeNew(newSize);
334 if (sizeNew.width() == 0.0) {
335 sizeNew.setWidth(0.000001);
336 }
337 if (sizeNew.height() == 0.0) {
338 sizeNew.setHeight(0.000001);
339 }
340
341 return QTransform(sizeNew.width() / oldSize.width(), 0, 0, sizeNew.height() / oldSize.height(), 0, 0);
342}

References size().

◆ reverseSubpath()

bool KoPathShape::reverseSubpath ( int subpathIndex)

Reverse subpath.

The last point becomes the first point and the first one becomes the last one.

Parameters
subpathIndexthe index of the subpath to reverse

Definition at line 884 of file KoPathShape.cpp.

885{
886 KoSubpath *subpath = d->subPath(subpathIndex);
887
888 if (subpath == 0)
889 return false;
890
891 int size = subpath->size();
892 for (int i = 0; i < size; ++i) {
893 KoPathPoint *p = subpath->takeAt(i);
894 p->reverse();
895 subpath->prepend(p);
896 }
897
898 // adjust the position dependent properties
899 KoPathPoint *first = subpath->first();
900 KoPathPoint *last = subpath->last();
901
902 KoPathPoint::PointProperties firstProps = first->properties();
903 KoPathPoint::PointProperties lastProps = last->properties();
904
905 firstProps |= KoPathPoint::StartSubpath;
906 firstProps &= ~KoPathPoint::StopSubpath;
907 lastProps |= KoPathPoint::StopSubpath;
908 lastProps &= ~KoPathPoint::StartSubpath;
909 if (firstProps & KoPathPoint::CloseSubpath) {
910 firstProps |= KoPathPoint::CloseSubpath;
911 lastProps |= KoPathPoint::CloseSubpath;
912 }
913 first->setProperties(firstProps);
914 last->setProperties(lastProps);
915
917
918 return true;
919}

References KoPathPoint::CloseSubpath, d, notifyPointsChanged(), p, KoPathPoint::properties, KoPathPoint::setProperties(), size(), KoPathPoint::StartSubpath, and KoPathPoint::StopSubpath.

◆ segmentByIndex()

KoPathSegment KoPathShape::segmentByIndex ( const KoPathPointIndex & pointIndex) const

Returns the segment specified by a path point index.

A segment is defined by the point index of the first point in the segment. A segment contains the defined point and its following point. If the subpath is closed and the and the pointIndex point to the last point in the subpath, the following point is the first point in the subpath.

Parameters
pointIndexindex of the first point of the segment
Returns
Segment containing both points of the segment or KoPathSegment( 0, 0 ) on error e.g. out of bounds

Definition at line 612 of file KoPathShape.cpp.

613{
614 KoPathSegment segment(0, 0);
615
616 KoSubpath *subpath = d->subPath(pointIndex.first);
617
618 if (subpath != 0 && pointIndex.second >= 0 && pointIndex.second < subpath->size()) {
619 KoPathPoint * point = subpath->at(pointIndex.second);
620 int index = pointIndex.second;
621 // check if we have a (closing) segment starting from the last point
622 if ((index == subpath->size() - 1) && point->properties() & KoPathPoint::CloseSubpath)
623 index = 0;
624 else
625 ++index;
626
627 if (index < subpath->size()) {
628 segment = KoPathSegment(point, subpath->at(index));
629 }
630 }
631 return segment;
632}
A KoPathSegment consist of two neighboring KoPathPoints.

References KoPathPoint::CloseSubpath, d, KoPathPoint::properties, and size().

◆ segmentsAt()

QList< KoPathSegment > KoPathShape::segmentsAt ( const QRectF & rect) const

Returns the list of path segments within the given rectangle.

Parameters
rectthe rectangle the requested segments are in
Returns
list of segments within the rectangle

Definition at line 564 of file KoPathShape.cpp.

565{
566 QList<KoPathSegment> segments;
567 int subpathCount = d->subpaths.count();
568 for (int subpathIndex = 0; subpathIndex < subpathCount; ++subpathIndex) {
569 KoSubpath * subpath = d->subpaths[subpathIndex];
570 int pointCount = subpath->count();
571 bool subpathClosed = isClosedSubpath(subpathIndex);
572 for (int pointIndex = 0; pointIndex < pointCount; ++pointIndex) {
573 if (pointIndex == (pointCount - 1) && ! subpathClosed)
574 break;
575 KoPathSegment s(subpath->at(pointIndex), subpath->at((pointIndex + 1) % pointCount));
576 QRectF controlRect = s.controlPointRect();
577 if (! r.intersects(controlRect) && ! controlRect.contains(r))
578 continue;
579 QRectF bound = s.boundingRect();
580 if (! r.intersects(bound) && ! bound.contains(r))
581 continue;
582
583 segments.append(s);
584 }
585 }
586 return segments;
587}
int subpathCount() const
Returns the number of subpaths in the path.
QSharedDataPointer< SharedData > s
Definition KoShape.h:1138

References d, isClosedSubpath(), pointCount(), KoShape::s, and subpathCount().

◆ separate()

bool KoPathShape::separate ( QList< KoPathShape * > & separatedPaths)

Creates separate path shapes, one for each existing subpath.

Parameters
separatedPathsthe list which contains the separated path shapes
Returns
true if separating the path was successful, false otherwise

Definition at line 981 of file KoPathShape.cpp.

982{
983 if (! d->subpaths.size())
984 return false;
985
986 QTransform myMatrix = absoluteTransformation();
987
988 Q_FOREACH (KoSubpath* subpath, d->subpaths) {
989 KoPathShape *shape = new KoPathShape();
990
991 shape->setStroke(stroke());
992 shape->setBackground(background());
993 shape->setShapeId(shapeId());
994 shape->setZIndex(zIndex());
995
996 KoSubpath *newSubpath = new KoSubpath();
997
998 Q_FOREACH (KoPathPoint* point, *subpath) {
999 KoPathPoint *newPoint = new KoPathPoint(*point, shape);
1000 newPoint->map(myMatrix);
1001 newSubpath->append(newPoint);
1002 }
1003 shape->d->subpaths.append(newSubpath);
1004 shape->normalize();
1005
1006 // NOTE: shape cannot have any listeners yet, so no notification about
1007 // points modification is needed
1008
1009 separatedPaths.append(shape);
1010 }
1011 return true;
1012}
void setZIndex(qint16 zIndex)
Definition KoShape.cpp:954
QString shapeId() const
Definition KoShape.cpp:1057
virtual void setStroke(KoShapeStrokeModelSP stroke)
Definition KoShape.cpp:1081
virtual void setBackground(QSharedPointer< KoShapeBackground > background)
Definition KoShape.cpp:918
qint16 zIndex() const
Definition KoShape.cpp:600

References KoShape::absoluteTransformation(), KoShape::background(), d, KoPathShape(), KoPathPoint::map(), normalize(), KoShape::setBackground(), KoShape::setShapeId(), KoShape::setStroke(), KoShape::setZIndex(), KoShape::shapeId(), KoShape::stroke(), and KoShape::zIndex().

◆ setAutoFillMarkers()

void KoPathShape::setAutoFillMarkers ( bool value)

Definition at line 1335 of file KoPathShape.cpp.

1336{
1337 d->autoFillMarkers = value;
1338}
float value(const T *src, size_t ch)

References d, and value().

◆ setFillRule()

void KoPathShape::setFillRule ( Qt::FillRule fillRule)

Sets the fill rule to be used for painting the background.

Definition at line 1242 of file KoPathShape.cpp.

1243{
1244 d->fillRule = fillRule;
1245}
Qt::FillRule fillRule() const
Returns the fill rule for the path object.

References d, and fillRule().

◆ setMarker()

void KoPathShape::setMarker ( KoMarker * marker,
KoFlake::MarkerPosition pos )

Definition at line 1308 of file KoPathShape.cpp.

1309{
1310 if (!marker && d->markersNew.contains(pos)) {
1311 d->markersNew.remove(pos);
1312 } else {
1313 d->markersNew[pos] = marker;
1314 }
1315
1316 notifyChanged();
1318}
KoMarker * marker(KoFlake::MarkerPosition pos) const
@ StrokeChanged
the shapes stroke has changed
Definition KoShape.h:105
void notifyChanged()
Definition KoShape.cpp:698

References d, marker(), KoShape::notifyChanged(), KoShape::shapeChangedPriv(), and KoShape::StrokeChanged.

◆ setSize()

void KoPathShape::setSize ( const QSizeF & size)
overridevirtual

Resize the shape

This makes sure that the pathshape will not be resized to 0 if the new size is null as that makes it impossible to undo the change.

All functions that overwrite this function should also use the resizeMatrix function to get and use the same data in resizing.

See also
resizeMatrix()

Reimplemented from KoShape.

Reimplemented in SpiralShape, and StarShape.

Definition at line 315 of file KoPathShape.cpp.

316{
317 QTransform matrix(resizeMatrix(newSize));
318
319 KoShape::setSize(newSize);
320 d->map(matrix);
321}
QTransform resizeMatrix(const QSizeF &newSize) const
virtual void setSize(const QSizeF &size)
Resize the shape.
Definition KoShape.cpp:276

References d, resizeMatrix(), and KoShape::setSize().

◆ size()

QSizeF KoPathShape::size ( ) const
overridevirtual

reimplemented

Reimplemented from KoShape.

Definition at line 308 of file KoPathShape.cpp.

309{
310 // don't call boundingRect here as it uses absoluteTransformation
311 // which itself uses size() -> leads to infinite recursion
312 return outlineRect().size();
313}
QRectF outlineRect() const override
reimplemented

References outlineRect().

◆ subpathCount()

int KoPathShape::subpathCount ( ) const

Returns the number of subpaths in the path.

Returns
The number of subpaths in the path

Definition at line 645 of file KoPathShape.cpp.

646{
647 return d->subpaths.count();
648}

References d.

◆ subpathPointCount()

int KoPathShape::subpathPointCount ( int subpathIndex) const

Returns the number of points in a subpath.

Returns
The number of points in the subpath or -1 if subpath out of bounds

Definition at line 650 of file KoPathShape.cpp.

651{
652 KoSubpath *subpath = d->subPath(subpathIndex);
653
654 if (subpath == 0)
655 return -1;
656
657 return subpath->size();
658}

References d.

◆ subpaths() [1/2]

KoSubpathList & KoPathShape::subpaths ( )
protected

XXX: refactor this using setter?

Definition at line 1059 of file KoPathShape.cpp.

1060{
1061 return d->subpaths;
1062}

References d.

◆ subpaths() [2/2]

const KoSubpathList & KoPathShape::subpaths ( ) const
protected

Definition at line 1054 of file KoPathShape.cpp.

1055{
1056 return d->subpaths;
1057}

References d.

◆ toString()

QString KoPathShape::toString ( const QTransform & matrix = QTransform()) const

Returns a odf/svg string representation of the path data with the given matrix applied.

Definition at line 1082 of file KoPathShape.cpp.

1083{
1084 QString pathString;
1085
1086 // iterate over all subpaths
1087 KoSubpathList::const_iterator pathIt(d->subpaths.constBegin());
1088 for (; pathIt != d->subpaths.constEnd(); ++pathIt) {
1089 KoSubpath::const_iterator pointIt((*pathIt)->constBegin());
1090 // keep a pointer to the first point of the subpath
1091 KoPathPoint *firstPoint(*pointIt);
1092 // keep a pointer to the previous point of the subpath
1093 KoPathPoint *lastPoint = firstPoint;
1094 // keep track if the previous point has an active control point 2
1095 bool activeControlPoint2 = false;
1096
1097 // iterate over all points of the current subpath
1098 for (; pointIt != (*pathIt)->constEnd(); ++pointIt) {
1099 KoPathPoint *currPoint(*pointIt);
1100 if (!currPoint) {
1101 qWarning() << "Found a zero point in the shape's path!";
1102 continue;
1103 }
1104 // first point of subpath ?
1105 if (currPoint == firstPoint) {
1106 // are we starting a subpath ?
1107 if (currPoint->properties() & KoPathPoint::StartSubpath) {
1108 const QPointF p = matrix.map(currPoint->point());
1109 pathString += QString("M%1 %2").arg(p.x()).arg(p.y());
1110 }
1111 }
1112 // end point of curve segment ?
1113 else if (activeControlPoint2 || currPoint->activeControlPoint1()) {
1114 // check if we have a cubic or quadratic curve
1115 const bool isCubic = activeControlPoint2 && currPoint->activeControlPoint1();
1116 KoPathSegment cubicSeg = isCubic ? KoPathSegment(lastPoint, currPoint)
1117 : KoPathSegment(lastPoint, currPoint).toCubic();
1118 if (cubicSeg.first() && cubicSeg.second()) {
1119 const QPointF cp1 = matrix.map(cubicSeg.first()->controlPoint2());
1120 const QPointF cp2 = matrix.map(cubicSeg.second()->controlPoint1());
1121 const QPointF p = matrix.map(cubicSeg.second()->point());
1122 pathString += QString("C%1 %2 %3 %4 %5 %6")
1123 .arg(cp1.x()).arg(cp1.y())
1124 .arg(cp2.x()).arg(cp2.y())
1125 .arg(p.x()).arg(p.y());
1126 }
1127 }
1128 // end point of line segment!
1129 else {
1130 const QPointF p = matrix.map(currPoint->point());
1131 pathString += QString("L%1 %2").arg(p.x()).arg(p.y());
1132 }
1133 // last point closes subpath ?
1134 if (currPoint->properties() & KoPathPoint::StopSubpath
1135 && currPoint->properties() & KoPathPoint::CloseSubpath) {
1136 // add curve when there is a curve on the way to the first point
1137 if (currPoint->activeControlPoint2() || firstPoint->activeControlPoint1()) {
1138 // check if we have a cubic or quadratic curve
1139 const bool isCubic = currPoint->activeControlPoint2() && firstPoint->activeControlPoint1();
1140 KoPathSegment cubicSeg = isCubic ? KoPathSegment(currPoint, firstPoint)
1141 : KoPathSegment(currPoint, firstPoint).toCubic();
1142 if (cubicSeg.first() && cubicSeg.second()) {
1143 const QPointF cp1 = matrix.map(cubicSeg.first()->controlPoint2());
1144 const QPointF cp2 = matrix.map(cubicSeg.second()->controlPoint1());
1145
1146 const QPointF p = matrix.map(cubicSeg.second()->point());
1147 pathString += QString("C%1 %2 %3 %4 %5 %6")
1148 .arg(cp1.x()).arg(cp1.y())
1149 .arg(cp2.x()).arg(cp2.y())
1150 .arg(p.x()).arg(p.y());
1151 }
1152 }
1153 pathString += QString("Z");
1154 }
1155
1156 activeControlPoint2 = currPoint->activeControlPoint2();
1157 lastPoint = currPoint;
1158 }
1159 }
1160
1161 return pathString;
1162}
KoPathPoint * first
KoPathPoint * second

References KoPathPoint::activeControlPoint1, KoPathPoint::activeControlPoint2, KoPathPoint::CloseSubpath, KoPathPoint::controlPoint1, KoPathPoint::controlPoint2, d, KoPathSegment::first, p, KoPathPoint::point, KoPathPoint::properties, KoPathSegment::second, KoPathPoint::StartSubpath, KoPathPoint::StopSubpath, and KoPathSegment::toCubic().

◆ updateLastPriv()

void KoPathShape::updateLastPriv ( KoPathPoint ** lastPoint)
private

Definition at line 519 of file KoPathShape.cpp.

520{
521 // check if we are about to add a new point to a closed subpath
522 if ((*lastPoint)->properties() & KoPathPoint::StopSubpath
523 && (*lastPoint)->properties() & KoPathPoint::CloseSubpath) {
524 // get the first point of the subpath
525 KoPathPoint *subpathStart = d->subpaths.last()->first();
526 // clone the first point of the subpath...
527 KoPathPoint * newLastPoint = new KoPathPoint(*subpathStart, this);
528 // ... and make it a normal point
529 newLastPoint->setProperties(KoPathPoint::Normal);
530 // now start a new subpath with the cloned start point
531 KoSubpath *path = new KoSubpath;
532 path->push_back(newLastPoint);
533 d->subpaths.push_back(path);
534 *lastPoint = newLastPoint;
535 } else {
536 // the subpath was not closed so the formerly last point
537 // of the subpath is no end point anymore
539 }
540 (*lastPoint)->unsetProperty(KoPathPoint::CloseSubpath);
541}
@ Normal
it has no control points
Definition KoPathPoint.h:37

References KoPathPoint::CloseSubpath, d, KoPathPoint::Normal, KoPathPoint::setProperties(), KoPathPoint::StopSubpath, and KoPathPoint::unsetProperty().

Member Data Documentation

◆ d

QScopedPointer<Private> KoPathShape::d
private

Definition at line 524 of file KoPathShape.h.


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