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

#include <KoShapeMeshGradientHandles.h>

Classes

struct  Handle
 

Public Member Functions

QPointF getAttachedCorner (const Handle &bezierHandle) const
 get the attached corner node of the bezierHandle
 
QVector< QPainterPath > getConnectedPath (const Handle &handle) const
 
Handle getHandle (SvgMeshPosition position) const
 convenience method to get a handle by its position in the mesharray
 
QVector< Handlehandles () const
 get all nodes in the mesh, don't use this for drawing the path but use path()
 
 KoShapeMeshGradientHandles (KoFlake::FillVariant fillVariant, KoShape *shape)
 
KUndo2CommandmoveGradientHandle (const Handle &handle, const QPointF &newPos)
 
QPainterPath path () const
 

Private Member Functions

QTransform absoluteTransformation (KoFlake::CoordinateSystem system) const
 
QVector< HandlegetBezierHandles (const SvgMeshArray *mesharray, SvgMeshPatch::Type type, int row, int col) const
 
QVector< HandlegetHandles (const SvgMeshArray *mesharray, SvgMeshPatch::Type type, int row, int col) const
 get handles including the corner
 
const SvgMeshGradientgradient () const
 

Private Attributes

KoFlake::FillVariant m_fillVariant {KoFlake::Fill}
 
KoShapem_shape {0}
 

Detailed Description

Definition at line 18 of file KoShapeMeshGradientHandles.h.

Constructor & Destructor Documentation

◆ KoShapeMeshGradientHandles()

KoShapeMeshGradientHandles::KoShapeMeshGradientHandles ( KoFlake::FillVariant fillVariant,
KoShape * shape )

Definition at line 14 of file KoShapeMeshGradientHandles.cpp.

16 : m_fillVariant(fillVariant)
17 , m_shape(shape)
18{
19}

Member Function Documentation

◆ absoluteTransformation()

QTransform KoShapeMeshGradientHandles::absoluteTransformation ( KoFlake::CoordinateSystem system) const
private

Definition at line 205 of file KoShapeMeshGradientHandles.cpp.

206{
207 QTransform t;
208 if (system == KoFlake::UserSpaceOnUse) {
210 } else {
211 const QTransform gradientToUser = KisAlgebra2D::mapToRect(m_shape->outlineRect());
212 t = gradientToUser * m_shape->absoluteTransformation();
213 }
214 return t;
215}
virtual QRectF outlineRect() const
Definition KoShape.cpp:637
QTransform absoluteTransformation() const
Definition KoShape.cpp:382
QTransform mapToRect(const QRectF &rect)

References KoShape::absoluteTransformation(), m_shape, KisAlgebra2D::mapToRect(), KoShape::outlineRect(), and KoFlake::UserSpaceOnUse.

◆ getAttachedCorner()

QPointF KoShapeMeshGradientHandles::getAttachedCorner ( const Handle & bezierHandle) const

get the attached corner node of the bezierHandle

Definition at line 156 of file KoShapeMeshGradientHandles.cpp.

157{
158 KIS_ASSERT(bezierHandle.type == Handle::BezierHandle);
159
160 const SvgMeshArray *mesharray = gradient()->getMeshArray().data();
161 const SvgMeshPath path = mesharray->getPath(bezierHandle.getPosition());
162 const QTransform t = (gradient()->gradientUnits() == KoFlake::ObjectBoundingBox)
164 : QTransform();
165 if (bezierHandle.index == Handle::First) {
166 return t.map(path[bezierHandle.index - 1]);
167 } else {
168 return t.map(path[bezierHandle.index + 1]);
169 }
170}
std::array< QPointF, 4 > SvgMeshPath
const SvgMeshGradient * gradient() const
std::array< QPointF, 4 > getPath(const SvgMeshPatch::Type edge, const int row, const int col) const
Get the Path Points for a segment of the meshpatch.
const QScopedPointer< SvgMeshArray > & getMeshArray() const
KoFlake::CoordinateSystem gradientUnits() const
#define KIS_ASSERT(cond)
Definition kis_assert.h:33

References KoShapeMeshGradientHandles::Handle::BezierHandle, KoShapeMeshGradientHandles::Handle::First, SvgMeshGradient::getMeshArray(), SvgMeshArray::getPath(), KoShapeMeshGradientHandles::Handle::getPosition(), gradient(), SvgMeshGradient::gradientUnits(), KoShapeMeshGradientHandles::Handle::index, KIS_ASSERT, m_shape, KisAlgebra2D::mapToRect(), KoFlake::ObjectBoundingBox, KoShape::outlineRect(), and KoShapeMeshGradientHandles::Handle::type.

◆ getBezierHandles()

QVector< KoShapeMeshGradientHandles::Handle > KoShapeMeshGradientHandles::getBezierHandles ( const SvgMeshArray * mesharray,
SvgMeshPatch::Type type,
int row,
int col ) const
private

Definition at line 192 of file KoShapeMeshGradientHandles.cpp.

196{
197 QVector<Handle> buffer;
198 std::array<QPointF, 4> path = mesharray->getPath(type, row, col);
199 buffer << Handle(Handle::BezierHandle, path[1], row, col, type, Handle::First);
200 buffer << Handle(Handle::BezierHandle, path[2], row, col, type, Handle::Second);
201
202 return buffer;
203}

References KoShapeMeshGradientHandles::Handle::BezierHandle, KoShapeMeshGradientHandles::Handle::First, SvgMeshArray::getPath(), and KoShapeMeshGradientHandles::Handle::Second.

◆ getConnectedPath()

QVector< QPainterPath > KoShapeMeshGradientHandles::getConnectedPath ( const Handle & handle) const

Definition at line 122 of file KoShapeMeshGradientHandles.cpp.

123{
124 KIS_ASSERT(handle.type != Handle::None);
125
127
128 // TODO(sh_zam): Handle OBB and user mode in and only in SvgMeshPatch
129 const QTransform t = (gradient()->gradientUnits() == KoFlake::ObjectBoundingBox)
131 : QTransform();
132 const SvgMeshArray *mesharray = gradient()->getMeshArray().data();
133 QPainterPath painterPath;
134
135 if (handle.type == Handle::BezierHandle) {
136 SvgMeshPath path = mesharray->getPath(handle.getPosition());
137 std::transform(path.begin(), path.end(), path.begin(), [&t](QPointF &point) { return t.map(point); });
138 painterPath.moveTo(path[0]);
139 painterPath.cubicTo(path[1], path[2], path[3]);
140 result << painterPath;
141 } else {
142 QVector<SvgMeshPosition> positions = mesharray->getConnectedPaths(handle.getPosition());
143 for (const auto &position: positions) {
144 SvgMeshPath path = mesharray->getPath(position);
145 std::transform(path.begin(), path.end(), path.begin(), [&t](QPointF &point) { return t.map(point); });
146 painterPath = QPainterPath();
147 painterPath.moveTo(path[0]);
148 painterPath.cubicTo(path[1], path[2], path[3]);
149 result << painterPath;
150 }
151 }
152
153 return result;
154}
QVector< SvgMeshPosition > getConnectedPaths(const SvgMeshPosition &position) const
Return the paths connected to the corner. Can be thought of as edges connected to a vertex.

References KoShapeMeshGradientHandles::Handle::BezierHandle, SvgMeshArray::getConnectedPaths(), SvgMeshGradient::getMeshArray(), SvgMeshArray::getPath(), KoShapeMeshGradientHandles::Handle::getPosition(), gradient(), SvgMeshGradient::gradientUnits(), KIS_ASSERT, m_shape, KisAlgebra2D::mapToRect(), KoShapeMeshGradientHandles::Handle::None, KoFlake::ObjectBoundingBox, KoShape::outlineRect(), and KoShapeMeshGradientHandles::Handle::type.

◆ getHandle()

KoShapeMeshGradientHandles::Handle KoShapeMeshGradientHandles::getHandle ( SvgMeshPosition position) const

convenience method to get a handle by its position in the mesharray

Definition at line 63 of file KoShapeMeshGradientHandles.cpp.

64{
65 const SvgMeshGradient *g = gradient();
66 if (!g) return Handle();
67
68 Handle handle = getHandles(g->getMeshArray().data(), position.segmentType, position.row, position.col)[0];
69
70 QTransform t = absoluteTransformation(g->gradientUnits());
71 handle.pos = t.map(handle.pos);
72
73 return handle;
74}
QVector< Handle > getHandles(const SvgMeshArray *mesharray, SvgMeshPatch::Type type, int row, int col) const
get handles including the corner
QTransform absoluteTransformation(KoFlake::CoordinateSystem system) const
SvgMeshPatch::Type segmentType

References absoluteTransformation(), SvgMeshPosition::col, getHandles(), SvgMeshGradient::getMeshArray(), gradient(), SvgMeshGradient::gradientUnits(), KoShapeMeshGradientHandles::Handle::pos, SvgMeshPosition::row, and SvgMeshPosition::segmentType.

◆ getHandles()

QVector< KoShapeMeshGradientHandles::Handle > KoShapeMeshGradientHandles::getHandles ( const SvgMeshArray * mesharray,
SvgMeshPatch::Type type,
int row,
int col ) const
private

get handles including the corner

Definition at line 178 of file KoShapeMeshGradientHandles.cpp.

182{
183 QVector<Handle> buffer;
184 std::array<QPointF, 4> path = mesharray->getPath(type, row, col);
185 buffer << Handle(Handle::Corner, path[0], row, col, type);
186 buffer << Handle(Handle::BezierHandle, path[1], row, col, type, Handle::First);
187 buffer << Handle(Handle::BezierHandle, path[2], row, col, type, Handle::Second);
188
189 return buffer;
190}

References KoShapeMeshGradientHandles::Handle::BezierHandle, KoShapeMeshGradientHandles::Handle::Corner, KoShapeMeshGradientHandles::Handle::First, SvgMeshArray::getPath(), and KoShapeMeshGradientHandles::Handle::Second.

◆ gradient()

const SvgMeshGradient * KoShapeMeshGradientHandles::gradient ( ) const
private

Definition at line 172 of file KoShapeMeshGradientHandles.cpp.

173{
175 return wrapper.meshgradient();
176}

References m_fillVariant, m_shape, and KoShapeFillWrapper::meshgradient().

◆ handles()

QVector< KoShapeMeshGradientHandles::Handle > KoShapeMeshGradientHandles::handles ( ) const

get all nodes in the mesh, don't use this for drawing the path but use path()

Definition at line 21 of file KoShapeMeshGradientHandles.cpp.

22{
23 QVector<Handle> result;
24
25 const SvgMeshGradient *g = gradient();
26 if (!g) return result;
27
28 SvgMeshArray const *mesharray = g->getMeshArray().data();
29
30 for (int irow = 0; irow < mesharray->numRows(); ++irow) {
31 for (int icol = 0; icol < mesharray->numColumns(); ++icol) {
32 // add corners as well
33 result << getHandles(mesharray, SvgMeshPatch::Top, irow, icol);
34
35 result << getBezierHandles(mesharray, SvgMeshPatch::Left, irow, icol);
36
37 if (irow == mesharray->numRows() - 1) {
38 result << getHandles(mesharray, SvgMeshPatch::Left, irow, icol);
39
40 if (icol == mesharray->numColumns() - 1) {
41 result << getHandles(mesharray, SvgMeshPatch::Bottom, irow, icol);
42 } else {
43 result << getBezierHandles(mesharray, SvgMeshPatch::Bottom, irow, icol);
44 }
45 }
46
47 if (icol == mesharray->numColumns() - 1) {
48 result << getHandles(mesharray, SvgMeshPatch::Right, irow, icol);
49 }
50 }
51 }
52
53 // we get pointer events in points (pts, not logical), so we transform these now
54 // and then invert them while drawing handles (see SelectionDecorator).
55 QTransform t = absoluteTransformation(g->gradientUnits());
56 for (auto &handle: result) {
57 handle.pos = t.map(handle.pos);
58 }
59
60 return result;
61}
QVector< Handle > getBezierHandles(const SvgMeshArray *mesharray, SvgMeshPatch::Type type, int row, int col) const
int numRows() const
int numColumns() const

References absoluteTransformation(), SvgMeshPatch::Bottom, getBezierHandles(), getHandles(), SvgMeshGradient::getMeshArray(), gradient(), SvgMeshGradient::gradientUnits(), SvgMeshPatch::Left, SvgMeshArray::numColumns(), SvgMeshArray::numRows(), SvgMeshPatch::Right, and SvgMeshPatch::Top.

◆ moveGradientHandle()

KUndo2Command * KoShapeMeshGradientHandles::moveGradientHandle ( const Handle & handle,
const QPointF & newPos )

Definition at line 76 of file KoShapeMeshGradientHandles.cpp.

78{
80 QScopedPointer<SvgMeshGradient> newGradient(new SvgMeshGradient(*wrapper.meshgradient()));
81 SvgMeshArray *mesharray = newGradient->getMeshArray().data();
82 SvgMeshPatch *patch = newGradient->getMeshArray()->getPatch(handle.row, handle.col);
83 std::array<QPointF, 4> path = patch->getSegment(handle.segmentType);
84
85 QTransform t = absoluteTransformation(newGradient->gradientUnits()).inverted();
86
87 if (handle.type == Handle::BezierHandle) {
88 path[handle.index] = t.map(newPos);
89 mesharray->modifyHandle(SvgMeshPosition {handle.row, handle.col, handle.segmentType}, path);
90
91 } else if (handle.type == Handle::Corner) {
92 mesharray->modifyCorner(SvgMeshPosition {handle.row, handle.col, handle.segmentType}, t.map(newPos));
93 }
94
95 return wrapper.setMeshGradient(newGradient.data(), QTransform());
96}
void modifyCorner(const SvgMeshPosition &position, const QPointF &newPos)
void modifyHandle(const SvgMeshPosition &position, const std::array< QPointF, 4 > &newPath)
std::array< QPointF, 4 > getSegment(Type type) const
Get a segment of the path in the meshpatch.

References absoluteTransformation(), KoShapeMeshGradientHandles::Handle::BezierHandle, KoShapeMeshGradientHandles::Handle::col, KoShapeMeshGradientHandles::Handle::Corner, SvgMeshPatch::getSegment(), KoShapeMeshGradientHandles::Handle::index, m_fillVariant, m_shape, KoShapeFillWrapper::meshgradient(), SvgMeshArray::modifyCorner(), SvgMeshArray::modifyHandle(), path(), KoShapeMeshGradientHandles::Handle::row, KoShapeMeshGradientHandles::Handle::segmentType, KoShapeFillWrapper::setMeshGradient(), and KoShapeMeshGradientHandles::Handle::type.

◆ path()

QPainterPath KoShapeMeshGradientHandles::path ( ) const

Definition at line 98 of file KoShapeMeshGradientHandles.cpp.

99{
100 QPainterPath painterPath;
101
102 if (!gradient())
103 return painterPath;
104
105 QScopedPointer<SvgMeshGradient> g(new SvgMeshGradient(*gradient()));
106 if (g->gradientUnits() == KoFlake::ObjectBoundingBox) {
107 const QTransform gradientToUser = KisAlgebra2D::mapToRect(m_shape->outlineRect());
108 g->setTransform(gradientToUser);
109 }
110
111 SvgMeshArray *mesharray = g->getMeshArray().data();
112
113 for (int i = 0; i < mesharray->numRows(); ++i) {
114 for (int j = 0; j < mesharray->numColumns(); ++j) {
115 painterPath.addPath(mesharray->getPatch(i, j)->getPath());
116 }
117 }
118
119 return painterPath;
120}
SvgMeshPatch * getPatch(const int row, const int col) const
QPainterPath getPath() const
Get full (closed) meshpath.

References SvgMeshArray::getPatch(), SvgMeshPatch::getPath(), gradient(), m_shape, KisAlgebra2D::mapToRect(), SvgMeshArray::numColumns(), SvgMeshArray::numRows(), KoFlake::ObjectBoundingBox, and KoShape::outlineRect().

Member Data Documentation

◆ m_fillVariant

KoFlake::FillVariant KoShapeMeshGradientHandles::m_fillVariant {KoFlake::Fill}
private

Definition at line 88 of file KoShapeMeshGradientHandles.h.

◆ m_shape

KoShape* KoShapeMeshGradientHandles::m_shape {0}
private

Definition at line 89 of file KoShapeMeshGradientHandles.h.

89{0};

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