Warning, file /office/calligra/libs/flake/KoPathShape.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2006, 2011 Thorsten Zachmann <zachmann@kde.org> 0003 Copyright (C) 2007,2009 Thomas Zander <zander@kde.org> 0004 Copyright (C) 2006-2008 Jan Hambrecht <jaham@gmx.net> 0005 Copyright (C) 2011 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com> 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #ifndef KOPATHSHAPE_H 0024 #define KOPATHSHAPE_H 0025 0026 #include "flake_export.h" 0027 0028 #include <QMetaType> 0029 #include <QTransform> 0030 0031 #include "KoTosContainer.h" 0032 #include "KoMarkerData.h" 0033 0034 #define KoPathShapeId "KoPathShape" 0035 0036 class KoPathSegment; 0037 class KoPathPoint; 0038 class KoPathShapePrivate; 0039 class KoMarker; 0040 0041 typedef QPair<int, int> KoPathPointIndex; 0042 0043 /// a KoSubpath contains a path from a moveTo until a close or a new moveTo 0044 typedef QList<KoPathPoint *> KoSubpath; 0045 typedef QList<KoSubpath *> KoSubpathList; 0046 /// The position of a path point within a path shape 0047 /** 0048 * @brief This is the base for all graphical objects. 0049 * 0050 * All graphical objects are based on this object e.g. lines, rectangulars, pies 0051 * and so on. 0052 * 0053 * The KoPathShape uses KoPathPoint's to describe the path of the shape. 0054 * 0055 * Here a short example: 0056 * 3 points connected by a curveTo's described by the following svg: 0057 * M 100,200 C 100,100 250,100 250,200 C 250,200 400,300 400,200. 0058 * 0059 * This will be stored in 3 KoPathPoint's as 0060 * The first point contains in 0061 * point 100,200 0062 * controlPoint2 100,100 0063 * The second point contains in 0064 * point 250,200 0065 * controlPoint1 250,100 0066 * controlPoint2 250,300 0067 * The third point contains in 0068 * point 400,300 0069 * controlPoint1 400,200 0070 * 0071 * Not the segments are stored but the points. Out of the points the segments are 0072 * generated. See the outline method. The reason for storing it like that is that 0073 * it is the points that are modified by the user and not the segments. 0074 */ 0075 class FLAKE_EXPORT KoPathShape : public KoTosContainer 0076 { 0077 public: 0078 /** 0079 * @brief constructor 0080 */ 0081 KoPathShape(); 0082 0083 /** 0084 * @brief 0085 */ 0086 ~KoPathShape() override; 0087 0088 /// reimplemented 0089 void paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintContext) override; 0090 virtual void paintPoints(QPainter &painter, const KoViewConverter &converter, int handleRadius); 0091 /// reimplemented 0092 QPainterPath outline() const override; 0093 /// reimplemented 0094 QRectF boundingRect() const override; 0095 /// reimplemented 0096 QSizeF size() const override; 0097 0098 QPainterPath pathStroke(const QPen &pen) const; 0099 /** 0100 * Resize the shape 0101 * 0102 * This makes sure that the pathshape will not be resized to 0 if the new size 0103 * is null as that makes it impossible to undo the change. 0104 * 0105 * All functions that overwrite this function should also use the resizeMatrix 0106 * function to get and use the same data in resizing. 0107 * 0108 * @see resizeMatrix() 0109 */ 0110 void setSize(const QSizeF &size) override; 0111 /// reimplemented 0112 bool hitTest(const QPointF &position) const override; 0113 0114 // reimplemented 0115 void saveOdf(KoShapeSavingContext &context) const override; 0116 // reimplemented 0117 bool loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) override; 0118 0119 // basically the same as loadOdf but adapted to the contour cases 0120 // tag needs to be either contour-polygon or contour-path from another shape 0121 bool loadContourOdf(const KoXmlElement & element, KoShapeLoadingContext &context, const QSizeF &scaleFactor); 0122 0123 /** basically the equivalent saveOdf but adapted to the contour cases 0124 * @param context saving context 0125 * @param originalSize the original size of the unscaled image. 0126 */ 0127 void saveContourOdf(KoShapeSavingContext &context, const QSizeF &originalSize) const; 0128 0129 /// Removes all subpaths and their points from the path 0130 void clear(); 0131 /** 0132 * @brief Starts a new Subpath 0133 * 0134 * Moves the pen to p and starts a new subpath. 0135 * 0136 * @return the newly created point 0137 */ 0138 KoPathPoint *moveTo(const QPointF &p); 0139 0140 /** 0141 * @brief Adds a new line segment 0142 * 0143 * Adds a straight line between the last point and the given point p. 0144 * 0145 * @return the newly created point 0146 */ 0147 KoPathPoint *lineTo(const QPointF &p); 0148 0149 /** 0150 * @brief Adds a new cubic Bezier curve segment. 0151 * 0152 * Adds a cubic Bezier curve between the last point and the given point p, 0153 * using the control points specified by c1 and c2. 0154 * 0155 * @param c1 control point1 0156 * @param c2 control point2 0157 * @param p the endpoint of this curve segment 0158 * 0159 * @return The newly created point 0160 */ 0161 KoPathPoint *curveTo(const QPointF &c1, const QPointF &c2, const QPointF &p); 0162 0163 /** 0164 * @brief Adds a new quadratic Bezier curve segment. 0165 * 0166 * Adds a quadratic Bezier curve between the last point and the given point p, 0167 * using the control point specified by c. 0168 * 0169 * @param c control point 0170 * @param p the endpoint of this curve segment 0171 * 0172 * @return The newly created point 0173 */ 0174 KoPathPoint *curveTo(const QPointF &c, const QPointF &p); 0175 0176 /** 0177 * @brief Add an arc. 0178 * 0179 * Adds an arc starting at the current point. The arc will be converted to bezier curves. 0180 * 0181 * @param rx x radius of the ellipse 0182 * @param ry y radius of the ellipse 0183 * @param startAngle the angle where the arc will be started 0184 * @param sweepAngle the length of the angle 0185 * TODO add param to have angle of the ellipse 0186 * 0187 * @return The newly created point 0188 */ 0189 KoPathPoint *arcTo(qreal rx, qreal ry, qreal startAngle, qreal sweepAngle); 0190 0191 0192 /** 0193 * @brief Closes the current subpath 0194 */ 0195 void close(); 0196 0197 /** 0198 * @brief Closes the current subpath 0199 * 0200 * It tries to merge the last and first point of the subpath 0201 * to one point and then closes the subpath. If merging is not 0202 * possible as the two point are to far from each other a close 0203 * will be done. 0204 * TODO define a maximum distance between the two points until this is working 0205 */ 0206 void closeMerge(); 0207 0208 /** 0209 * @brief Normalizes the path data. 0210 * 0211 * The path points are transformed so that the top-left corner 0212 * of the bounding rect is at (0,0). 0213 * This should be called after adding points to the path or changing 0214 * positions of path points. 0215 * @return the offset by which the points are moved in shape coordinates. 0216 */ 0217 virtual QPointF normalize(); 0218 0219 /** 0220 * @brief Returns the path points within the given rectangle. 0221 * @param rect the rectangle the requested points are in 0222 * @return list of points within the rectangle 0223 */ 0224 QList<KoPathPoint*> pointsAt(const QRectF &rect) const; 0225 0226 /** 0227 * @brief Returns the list of path segments within the given rectangle. 0228 * @param rect the rectangle the requested segments are in 0229 * @return list of segments within the rectangle 0230 */ 0231 QList<KoPathSegment> segmentsAt(const QRectF &rect) const; 0232 0233 /** 0234 * @brief Returns the path point index of a given path point 0235 * 0236 * @param point the point for which you want to get the index 0237 * @return path point index of the point if it exists 0238 * otherwise KoPathPointIndex( -1, -1 ) 0239 */ 0240 KoPathPointIndex pathPointIndex(const KoPathPoint *point) const; 0241 0242 /** 0243 * @brief Returns the path point specified by a path point index 0244 * 0245 * @param pointIndex index of the point to get 0246 * 0247 * @return KoPathPoint on success, 0 otherwise e.g. out of bounds 0248 */ 0249 KoPathPoint *pointByIndex(const KoPathPointIndex &pointIndex) const; 0250 0251 /** 0252 * @brief Returns the segment specified by a path point index 0253 * 0254 * A semgent is defined by the point index of the first point in the segment. 0255 * A segment contains the defined point and its following point. If the subpath is 0256 * closed and the and the pointIndex point to the last point in the subpath, the 0257 * following point is the first point in the subpath. 0258 * 0259 * @param pointIndex index of the first point of the segment 0260 * 0261 * @return Segment containing both points of the segment or KoPathSegment( 0, 0 ) on error e.g. out of bounds 0262 */ 0263 KoPathSegment segmentByIndex(const KoPathPointIndex &pointIndex) const; 0264 0265 /** 0266 * @brief Returns the number of points in the path 0267 * 0268 * @return The number of points in the path 0269 */ 0270 int pointCount() const; 0271 0272 /** 0273 * @brief Returns the number of subpaths in the path 0274 * 0275 * @return The number of subpaths in the path 0276 */ 0277 int subpathCount() const; 0278 0279 /** 0280 * @brief Returns the number of points in a subpath 0281 * 0282 * @return The number of points in the subpath or -1 if subpath out of bounds 0283 */ 0284 int subpathPointCount(int subpathIndex) const; 0285 0286 /** 0287 * @brief Checks if a subpath is closed 0288 * 0289 * @param subpathIndex index of the subpath to check 0290 * 0291 * @return true when the subpath is closed, false otherwise 0292 */ 0293 bool isClosedSubpath(int subpathIndex) const; 0294 0295 /** 0296 * @brief Inserts a new point into the given subpath at the specified position 0297 * 0298 * This method keeps the subpath closed if it is closed, and open when it was 0299 * open. So it can change the properties of the point inserted. 0300 * You might need to update the point before/after to get the desired result 0301 * e.g. when you insert the point into a curve. 0302 * 0303 * @param point to insert 0304 * @param pointIndex index at which the point should be inserted 0305 * 0306 * @return true on success, 0307 * false when pointIndex is out of bounds 0308 */ 0309 bool insertPoint(KoPathPoint *point, const KoPathPointIndex &pointIndex); 0310 0311 /** 0312 * @brief Removes a point from the path. 0313 * 0314 * Note that the ownership of the point will pass to the caller. 0315 * 0316 * @param pointIndex index of the point which should be removed 0317 * 0318 * @return The removed point on success, 0319 * otherwise 0 0320 */ 0321 KoPathPoint *removePoint(const KoPathPointIndex &pointIndex); 0322 0323 /** 0324 * @brief Breaks the path after the point index 0325 * 0326 * The new subpath will be behind the one that was broken. The segment between 0327 * the given point and the one behind will be removed. If you want to split at 0328 * one point insert first a copy of the point behind it. 0329 * This does not work when the subpath is closed. Use openSubpath for this. 0330 * It does not break at the last position of a subpath or if there is only one 0331 * point in the subpath. 0332 * 0333 * @param pointIndex index of the point after which the path should be broken 0334 * 0335 * @return true if the subpath was broken, otherwise false 0336 */ 0337 bool breakAfter(const KoPathPointIndex &pointIndex); 0338 0339 /** 0340 * @brief Joins the given subpath with the following one 0341 * 0342 * Joins the given subpath with the following one by inserting a segment between 0343 * the two subpaths. 0344 * This does nothing if the specified subpath is the last subpath 0345 * or one of both subpaths is closed. 0346 * 0347 * @param subpathIndex index of the subpath being joined with the following subpath 0348 * 0349 * @return true if the subpath was joined, otherwise false 0350 */ 0351 bool join(int subpathIndex); 0352 0353 /** 0354 * @brief Moves the position of a subpath within a path 0355 * 0356 * @param oldSubpathIndex old index of the subpath 0357 * @param newSubpathIndex new index of the subpath 0358 * 0359 * @return true if the subpath was moved, otherwise false e.g. if an index is out of bounds 0360 */ 0361 bool moveSubpath(int oldSubpathIndex, int newSubpathIndex); 0362 0363 /** 0364 * @brief Opens a closed subpath 0365 * 0366 * The subpath is opened by removing the segment before the given point, making 0367 * the given point the new start point of the subpath. 0368 * 0369 * @param pointIndex the index of the point at which to open the closed subpath 0370 * @return the new position of the old first point in the subpath 0371 * otherwise KoPathPointIndex( -1, -1 ) 0372 */ 0373 KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex); 0374 0375 /** 0376 * @brief Close a open subpath 0377 * 0378 * The subpath is closed be inserting a segment between the start and end point, making 0379 * the given point the new start point of the subpath. 0380 * 0381 * @return the new position of the old first point in the subpath 0382 * otherwise KoPathPointIndex( -1, -1 ) 0383 */ 0384 KoPathPointIndex closeSubpath(const KoPathPointIndex &pointIndex); 0385 0386 /** 0387 * @brief Reverse subpath 0388 * 0389 * The last point becomes the first point and the first one becomes the last one. 0390 * 0391 * @param subpathIndex the index of the subpath to reverse 0392 */ 0393 bool reverseSubpath(int subpathIndex); 0394 0395 /** 0396 * @brief Removes subpath from the path 0397 * @param subpathIndex the index of the subpath to remove 0398 * @return the removed subpath on succes, 0 otherwise. 0399 */ 0400 KoSubpath *removeSubpath(int subpathIndex); 0401 0402 /** 0403 * @brief Adds a subpath at the given index to the path 0404 * @param subpath the subpath to add 0405 * @param subpathIndex the index at which the new subpath should be inserted 0406 * @return true on success, false otherwise e.g. subpathIndex out of bounds 0407 */ 0408 bool addSubpath(KoSubpath *subpath, int subpathIndex); 0409 0410 /** 0411 * @brief Combines two path shapes by appending the data of the specified path. 0412 * @param path the path to combine with 0413 * @return true if combining was successful, else false 0414 */ 0415 bool combine(KoPathShape *path); 0416 0417 /** 0418 * @brief Creates separate path shapes, one for each existing subpath. 0419 * @param separatedPaths the list which contains the separated path shapes 0420 * @return true if separating the path was successful, false otherwise 0421 */ 0422 bool separate(QList<KoPathShape*> &separatedPaths); 0423 0424 /** 0425 * Returns the specific path shape id. 0426 * 0427 * Path shape derived shapes have a different shape id which link them 0428 * to their respective shape factories. In most cases they do not have 0429 * a special tool for editing them. 0430 * This function returns the specific shape id for finding the shape 0431 * factory from KoShapeRegistry. The default KoPathShapeId is returned 0432 * from KoShape::shapeId() so that the generic path editing tool gets 0433 * activated when the shape is selected. 0434 * 0435 * @return the specific shape id 0436 */ 0437 virtual QString pathShapeId() const; 0438 0439 /// Returns a odf/svg string representation of the path data with the given matrix applied. 0440 QString toString(const QTransform &matrix = QTransform()) const; 0441 0442 /// Returns the fill rule for the path object 0443 Qt::FillRule fillRule() const; 0444 0445 /// Sets the fill rule to be used for painting the background 0446 void setFillRule(Qt::FillRule fillRule); 0447 0448 /// Creates path shape from given QPainterPath 0449 static KoPathShape *createShapeFromPainterPath(const QPainterPath &path); 0450 0451 /// Returns the viewbox from the given xml element. 0452 static QRect loadOdfViewbox(const KoXmlElement &element); 0453 0454 /// Marker setter 0455 void setMarker(const KoMarkerData &markerData); 0456 0457 /// Marker setter 0458 void setMarker(KoMarker *marker, KoMarkerData::MarkerPosition position); 0459 0460 /// returns the list of all the markers of the path 0461 KoMarker *marker(KoMarkerData::MarkerPosition position) const; 0462 0463 KoMarkerData markerData(KoMarkerData::MarkerPosition position) const; 0464 0465 protected: 0466 /// constructor \internal 0467 KoPathShape(KoPathShapePrivate &); 0468 0469 /// reimplemented 0470 QString saveStyle(KoGenStyle &style, KoShapeSavingContext &context) const override; 0471 /// reimplemented 0472 void loadStyle(const KoXmlElement &element, KoShapeLoadingContext &context) override; 0473 0474 /** 0475 * @brief Add an arc. 0476 * 0477 * Adds an arc starting at the current point. The arc will be converted to bezier curves. 0478 * @param rx x radius of the ellipse 0479 * @param ry y radius of the ellipse 0480 * @param startAngle the angle where the arc will be started 0481 * @param sweepAngle the length of the angle 0482 * TODO add param to have angle of the ellipse 0483 * @param offset to the first point in the arc 0484 * @param curvePoints a array which take the cuve points, pass a 'QPointF curvePoins[12]'; 0485 * 0486 * @return number of points created by the curve 0487 */ 0488 int arcToCurve(qreal rx, qreal ry, qreal startAngle, qreal sweepAngle, const QPointF &offset, QPointF *curvePoints) const; 0489 0490 /** 0491 * Get the resize matrix 0492 * 0493 * This makes sure that also if the newSize isNull that there will be a 0494 * very small size of 0.000001 pixels 0495 */ 0496 QTransform resizeMatrix( const QSizeF &newSize ) const; 0497 0498 KoSubpathList m_subpaths; 0499 0500 private: 0501 Q_DECLARE_PRIVATE(KoPathShape) 0502 }; 0503 0504 Q_DECLARE_METATYPE(KoPathShape*) 0505 0506 #endif /* KOPATHSHAPE_H */