3 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 1. Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 // Stateless painter with sane semantics that works on kpImage's i.e. it
42 // works on document - not view - data. If you find that you need state,
43 // you should probably move it into kpPainter to avoid the overhead of
44 // passing around this state (e.g. color, line width) and for reuse.
46 // kpPainter is to kpImage as QPainter is to QPixmap.
48 // This encapsulates the set of functionality used by all of KolourPaint's
49 // document drawing functions and nothing more, permitting rewriting of
50 // the image library. Currently uses QPainter/kpPixmapFX as the image library.
53 struct kpPainterPrivate
;
58 // Returns whether the given points are cardinally adjacent (i.e. one point
59 // is exactly 1 pixel north, east, south or west of the other). Equal
60 // points are not cardinally adjacent.
61 static bool pointsAreCardinallyAdjacent (const QPoint
&p
, const QPoint
&q
);
63 // Returns a list of points representing a straight line from <startPoint>
64 // to <endPoint> inclusive, using Bresenham's line algorithm. Each point
65 // is created only with the specified <probability>.
67 // If <cardinalAdjacency> is set, a modified Bresenham's algorithm will add
68 // an extra point between every pair of originally strictly-diagonally-adjacent
69 // points, such that these points become cardinally adjacent. However, these
70 // extra points are also created only with the specified <probability>.
72 // For instance, <cardinalAdjacency> must be set if a diagonal line is to
73 // drawn at each of the returned points, otherwise things won't look right:
82 // 'A' is the previous Bresenham point. 'B' is the new point. See how if
83 // diagonal lines are drawn at A and B, there is a gap between the lines.
84 // Setting <cardinalAdjacency> will solve this problem, since it will add
87 // ASSUMPTION: <probability> is between 0.0 and 1.0 inclusive.
88 static QList
<QPoint
> interpolatePoints (const QPoint
&startPoint
,
89 const QPoint
&endPoint
,
90 bool cardinalAdjacency
= false,
91 double probability
= 1.0);
93 // Draws a line from (x1,y1) to (x2,y2) onto <image>, with <color>
94 // and <penWidth>. The corners are rounded and centred at those
95 // coordinates so if <width> > 1, the line is likely to extend past
96 // a rectangle with those corners.
97 static void drawLine (kpImage
*image
,
98 int x1
, int y1
, int x2
, int y2
,
99 const kpColor
&color
, int penWidth
);
100 static void drawPolyline (kpImage
*image
,
101 const QPolygon
&points
,
102 const kpColor
&color
, int penWidth
);
103 // <isFinal> = shape completed else drawing but haven't finalised.
104 // If not <isFinal>, the edge that would form the closure, if the
105 // shape were finalised now, is highlighted specially. Unfortunately,
106 // the argument is currently ignored.
109 static void drawPolygon (kpImage
*image
,
110 const QPolygon
&points
,
111 const kpColor
&fcolor
, int penWidth
,
112 const kpColor
&bcolor
= kpColor::Invalid
,
113 bool isFinal
= true);
115 static void drawCurve (kpImage
*image
,
116 const QPoint
&startPoint
,
117 const QPoint
&controlPointP
, const QPoint
&controlPointQ
,
118 const QPoint
&endPoint
,
119 const kpColor
&color
, int penWidth
);
121 static void fillRect (kpImage
*image
,
122 int x
, int y
, int width
, int height
,
123 const kpColor
&color
);
125 // Draws a rectangle / rounded rectangle / ellipse with top-left at
126 // (x, y) with width <width> and height <height>. Unlike QPainter,
127 // this rectangle will really fit inside <width>x<height> and won't
128 // be one pixel higher or wider etc.
130 // <width> and <height> must be >= 0.
132 // <fcolor> must not be invalid. However, <bcolor> may be invalid
133 // to signify an unfilled rectangle / rounded rectangle /ellipse.
134 static void drawRect (kpImage
*image
,
135 int x
, int y
, int width
, int height
,
136 const kpColor
&fcolor
, int penWidth
= 1,
137 const kpColor
&bcolor
= kpColor::Invalid
);
138 static void drawRoundedRect (kpImage
*image
,
139 int x
, int y
, int width
, int height
,
140 const kpColor
&fcolor
, int penWidth
= 1,
141 const kpColor
&bcolor
= kpColor::Invalid
);
142 static void drawEllipse (kpImage
*image
,
143 int x
, int y
, int width
, int height
,
144 const kpColor
&fcolor
, int penWidth
= 1,
145 const kpColor
&bcolor
= kpColor::Invalid
);
147 // Replaces all pixels of <colorToReplace> on the line
148 // from (x1,y1) to (x2,y2) of <image>, with a pen of <color> with
149 // dimensions <penWidth>x<penHeight>.
151 // The corners are centred at those coordinates so if <penWidth> > 1 or
152 // <penHeight> > 1, the line is likely to extend past a rectangle with
155 // Returns the dirty rectangle.
156 static QRect
washLine (kpImage
*image
,
157 int x1
, int y1
, int x2
, int y2
,
158 const kpColor
&color
, int penWidth
, int penHeight
,
159 const kpColor
&colorToReplace
,
160 int processedColorSimilarity
);
162 static QRect
washRect (kpImage
*image
,
163 int x
, int y
, int width
, int height
,
164 const kpColor
&color
,
165 const kpColor
&colorToReplace
,
166 int processedColorSimilarity
);
168 // For each point in <points>, sprays a random pattern of 10 dots of <color>,
169 // each within a circle of diameter <spraycanSize>, onto <image>.
171 // ASSUMPTION: spraycanSize > 0.
172 // TODO: I think this diameter is 1 or 2 off.
173 static void sprayPoints (kpImage
*image
,
174 const QList
<QPoint
> &points
,
175 const kpColor
&color
,
180 #endif // KP_PAINTER_H