33 handles.push_back(QPointF(100, 50));
34 handles.push_back(QPointF(100, 50));
35 handles.push_back(QPointF(0, 50));
37 QSizeF
size(100, 100);
45 m_startAngle(rhs.m_startAngle),
46 m_endAngle(rhs.m_endAngle),
47 m_kindAngle(rhs.m_kindAngle),
48 m_center(rhs.m_center),
75 matrix.translate(-offset.x(), -offset.y());
89 angle = (diff.y() < 0 ? 270 : 90) *
M_PI / 180.0;
92 angle = atan(diff.y() / diff.x());
117 kindHandlePositions.push_back(
m_center);
122 for (
int i = 0; i < kindHandlePositions.size(); ++i) {
123 QPointF pointDiff(
p - kindHandlePositions[i]);
124 if (i == 0 || qAbs(pointDiff.x()) + qAbs(pointDiff.y()) < qAbs(diff.x()) + qAbs(diff.y())) {
129 handles[handleId] = kindHandlePositions[handlePos];
144 QPointF startpoint(
handles()[0]);
146 QPointF curvePoints[12];
149 const bool sameAngles =
distance > 359.9;
153 int curvePointCount = 1 + pointCnt / 3;
154 int requiredPointCount = curvePointCount;
156 requiredPointCount++;
157 }
else if (
m_type ==
Arc && sameAngles) {
159 requiredPointCount--;
167 points[0]->setPoint(startpoint);
168 points[0]->removeControlPoint1();
170 for (
int i = 1; i < curvePointCount; ++i) {
171 points[i - 1]->setControlPoint2(curvePoints[curveIndex++]);
172 points[i]->setControlPoint1(curvePoints[curveIndex++]);
173 points[i]->setPoint(curvePoints[curveIndex++]);
174 points[i]->removeControlPoint2();
178 points[requiredPointCount - 1]->setPoint(
m_center);
179 points[requiredPointCount - 1]->removeControlPoint1();
180 points[requiredPointCount - 1]->removeControlPoint2();
181 }
else if (
m_type ==
Arc && sameAngles) {
182 points[curvePointCount - 1]->setControlPoint2(curvePoints[curveIndex]);
183 points[0]->setControlPoint1(curvePoints[++curveIndex]);
186 for (
int i = 0; i < requiredPointCount; ++i) {
210 int currentPointCount =
subpaths()[0]->count();
211 if (currentPointCount > requiredPointCount) {
212 for (
int i = 0; i < currentPointCount - requiredPointCount; ++i) {
216 }
else if (requiredPointCount > currentPointCount) {
217 for (
int i = 0; i < requiredPointCount - currentPointCount; ++i) {
264 qreal sAngle = a2 - a1;
267 sAngle = 2 *
M_PI + sAngle;
270 if (qAbs(a1 - a2) < 0.05 /
M_PI) {
327 const bool isCircle =
size.width() ==
size.height();
328 context.
shapeWriter().startElement(isCircle ?
"circle" :
"ellipse");
350 context.
shapeWriter().addAttribute(
"sodipodi:type",
"arc");
366 context.
shapeWriter().addAttribute(
"sodipodi:arc-type",
"chord");
369 context.
shapeWriter().addAttribute(
"sodipodi:open",
"true");
385 qreal rx = 0, ry = 0;
392 const QString extendedNamespace =
393 element.attribute(
"sodipodi:type") ==
"arc" ?
"sodipodi" :
394 element.attribute(
"krita:type") ==
"arc" ?
"krita" :
"";
396 if (element.tagName() ==
"ellipse") {
401 }
else if (element.tagName() ==
"circle") {
406 }
else if (element.tagName() ==
"path" && !extendedNamespace.isEmpty()) {
414 const QString kritaArcType =
415 element.attribute(
"sodipodi:arc-type", element.attribute(
"krita:arcType"));
417 if (kritaArcType.isEmpty()) {
418 if (element.attribute(
"sodipodi:open",
"false") ==
"false") {
421 }
else if (kritaArcType ==
"pie") {
423 }
else if (kritaArcType ==
"chord") {
430 setSize(QSizeF(2 * rx, 2 * ry));
432 if (rx == 0.0 || ry == 0.0) {
436 if (start != 0 || start != end) {
qreal distance(const QPointF &p1, const QPointF &p2)
QList< KoPathPoint * > KoSubpath
a KoSubpath contains a path from a moveTo until a close or a new moveTo
void setType(EllipseType type)
void updatePath(const QSizeF &size) override
Update the path of the parameter shape.
qreal startAngle() const
Returns the actual ellipse start angle in degree.
QPointF normalize() override
Normalizes the path data.
void updateAngleHandles()
void setStartAngle(qreal angle)
qreal endAngle() const
Returns the actual ellipse end angle in degree.
void setEndAngle(qreal angle)
QString pathShapeId() const override
reimplemented
void moveHandleAction(int handleId, const QPointF &point, Qt::KeyboardModifiers modifiers=Qt::NoModifier) override
Updates the internal state of a KoParameterShape.
EllipseType type() const
Returns the actual ellipse type.
bool loadSvg(const QDomElement &element, SvgLoadingContext &context) override
reimplemented from SvgShape
void setSize(const QSizeF &newSize) override
Resize the shape.
void createPoints(int requiredPointCount)
KoShape * cloneShape() const override
creates a deep copy of the shape or shape's subtree
bool saveSvg(SvgSavingContext &context) override
reimplemented from SvgShape
EllipseType
the possible ellipse types
QPointF normalize() override
Normalizes the path data.
QList< QPointF > handles
the handles that the user can grab and change
void setSize(const QSizeF &size) override
reimplemented from KoShape
void setHandles(const QList< QPointF > &handles)
bool isParametricShape() const
Check if object is a parametric shape.
A KoPathPoint represents a point in a path.
@ StartSubpath
it starts a new subpath by a moveTo command
@ CloseSubpath
it closes a subpath (only applicable on StartSubpath and StopSubpath)
@ StopSubpath
it stops a subpath (last point of subpath)
const KoSubpathList & subpaths() const
QTransform resizeMatrix(const QSizeF &newSize) const
QSizeF size() const override
reimplemented
void notifyPointsChanged()
int arcToCurve(qreal rx, qreal ry, qreal startAngle, qreal sweepAngle, const QPointF &offset, QPointF *curvePoints) const
Add an arc.
QString toString(const QTransform &matrix=QTransform()) const
Returns a odf/svg string representation of the path data with the given matrix applied.
void clear()
Removes all subpaths and their points from the path.
QTransform transformation() const
Returns the shapes local transformation matrix.
virtual void setPosition(const QPointF &position)
Set the position of the shape in pt.
Contains data used for loading svg.
SvgGraphicsContext * currentGC() const
Returns the current graphics context.
KoSvgTextProperties resolvedProperties() const
These are the text properties, completely resolved, ensuring that everything is inherited and the siz...
Context for saving svg files.
QTransform userSpaceTransform() const
Returns the transformation used to transform into user space.
QScopedPointer< KoXmlWriter > shapeWriter
QString getID(const KoShape *obj)
Returns the unique id for the given shape.
static void saveSvgStyle(KoShape *shape, SvgSavingContext &context)
Saves the style of the specified shape.
static void saveMetadata(const KoShape *shape, SvgSavingContext &context)
static qreal parseUnitX(SvgGraphicsContext *gc, const KoSvgTextProperties &resolved, const QString &unit)
parses a length attribute in x-direction
static const char * parseNumber(const char *ptr, qreal &number)
parses the number into parameter number
static qreal parseUnitXY(SvgGraphicsContext *gc, const KoSvgTextProperties &resolved, const QString &unit)
parses a length attribute in xy-direction
static void writeTransformAttributeLazy(const QString &name, const QTransform &transform, KoXmlWriter &shapeWriter)
Writes a transform as an attribute name iff the transform is not empty.
static qreal parseUnitY(SvgGraphicsContext *gc, const KoSvgTextProperties &resolved, const QString &unit)
parses a length attribute in y-direction
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
T kisRadiansToDegrees(T radians)
std::enable_if< std::is_floating_point< T >::value, T >::type normalizeAngleDegrees(T a)
T kisDegreesToRadians(T degrees)
std::enable_if< std::is_floating_point< T >::value, T >::type normalizeAngle(T a)