1 /* This file is part of the KDE project
2    Copyright (C) 2008 Fela Winkelmolen <fela.kde@gmail.com>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18 */
19 
20 #ifndef KARBONCALLIGRAPHICSHAPE_H
21 #define KARBONCALLIGRAPHICSHAPE_H
22 
23 #include <KoParameterShape.h>
24 
25 #define KarbonCalligraphicShapeId "KarbonCalligraphicShape"
26 
27 class KarbonCalligraphicPoint
28 {
29 public:
KarbonCalligraphicPoint(const QPointF & point,qreal angle,qreal width)30     KarbonCalligraphicPoint(const QPointF &point, qreal angle, qreal width)
31             : m_point(point), m_angle(angle), m_width(width) {}
32 
point()33     QPointF point() const {
34         return m_point;
35     }
angle()36     qreal angle() const {
37         return m_angle;
38     }
width()39     qreal width() const {
40         return m_width;
41     }
42 
setPoint(const QPointF & point)43     void setPoint(const QPointF &point) {
44         m_point = point;
45     }
setAngle(qreal angle)46     void setAngle(qreal angle) {
47         m_angle = angle;
48     }
49 
50 private:
51     QPointF m_point; // in shape coordinates
52     qreal m_angle;
53     qreal m_width;
54 };
55 
56 /*class KarbonCalligraphicShape::Point
57 {
58 public:
59     KoPainterPath(KoPathPoint *point) : m_prev(point), m_next(0) {}
60 
61     // calculates the effective point
62     QPointF point() {
63         if (m_next = 0)
64             return m_prev.point();
65 
66         // m_next != 0
67         qDebug() << "not implemented yet!!!!";
68         return QPointF();
69     }
70 
71 private:
72     KoPainterPath m_prev;
73     KoPainterPath m_next;
74     qreal m_percentage;
75 };*/
76 
77 // the indexes of the path will be similar to:
78 //        7--6--5--4   <- pointCount() / 2
79 // start  |        |   end    ==> (direction of the stroke)
80 //        0--1--2--3
81 class KarbonCalligraphicShape : public KoParameterShape
82 {
83 public:
84     explicit KarbonCalligraphicShape(qreal caps = 0.0);
85     ~KarbonCalligraphicShape() override;
86 
87     void appendPoint(const QPointF &p1, qreal angle, qreal width);
88     void appendPointToPath(const KarbonCalligraphicPoint &p);
89 
90     // returns the bounding rect of whan needs to be repainted
91     // after new points are added
92     const QRectF lastPieceBoundingRect();
93 
94     void setSize(const QSizeF &newSize) override;
95     //virtual QPointF normalize();
96 
97     QPointF normalize() override;
98 
99     void simplifyPath();
100 
101     void simplifyGuidePath();
102 
103     // reimplemented
104     QString pathShapeId() const override;
105 
106 protected:
107     // reimplemented
108     void moveHandleAction(int handleId,
109                           const QPointF & point,
110                           Qt::KeyboardModifiers modifiers = Qt::NoModifier) override;
111 
112     // reimplemented
113     void updatePath(const QSizeF &size) override;
114 
115 private:
116     // auxiliary function that actually inserts the points
117     // without doing any additional checks
118     // the points should be given in canvas coordinates
119     void appendPointsToPathAux(const QPointF &p1, const QPointF &p2);
120 
121     // function to detect a flip, given the points being inserted
122     bool flipDetected(const QPointF &p1, const QPointF &p2);
123 
124     void smoothLastPoints();
125     void smoothPoint(const int index);
126 
127     // determine whether the points given are in counterclockwise order or not
128     // returns +1 if they are, -1 if they are given in clockwise order
129     // and 0 if they form a degenerate triangle
130     static int ccw(const QPointF &p1, const QPointF &p2, const QPointF &p3);
131 
132     //
133     void addCap(int index1, int index2, int pointIndex, bool inverted = false);
134 
135     // the actual data then determines it's shape (guide path + data for points)
136     QList<KarbonCalligraphicPoint *> m_points;
137     bool m_lastWasFlip;
138     qreal m_caps;
139 };
140 
141 #endif // KARBONCALLIGRAPHICSHAPE_H
142 
143