2
* Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
3
* Copyright (c) 2004 Clarence Dang <dang@kde.org>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
#ifndef KIS_PAINTER_H_
21
#define KIS_PAINTER_H_
25
#include <KoColorSpaceConstants.h>
27
#include "kis_distance_information.h"
28
#include "kis_global.h"
29
#include "kis_types.h"
30
#include <krita_export.h>
40
class KoAbstractGradient;
47
class KisFilterConfiguration;
48
class KisPaintInformation;
51
* KisPainter contains the graphics primitives necessary to draw on a
52
* KisPaintDevice. This is the same kind of abstraction as used in Qt
53
* itself, where you have QPainter and QPaintDevice.
55
* However, KisPainter works on a tiled image and supports different
56
* color models, and that's a lot more complicated.
58
* KisPainter supports transactions that can group various paint operations
59
* in one undoable step.
61
* For more complex operations, you might want to have a look at the subclasses
62
* of KisPainter: KisConvolutionPainter, KisFillPainter and KisGradientPainter
64
* KisPainter sets a number of default values, like COMPOSITE_OVER for compositeop,
65
* OPACITY_OPAQUE for opacity and no selection for selection.
67
class KRITAIMAGE_EXPORT KisPainter
72
/// Construct painter without a device
75
/// Construct a painter, and begin painting on the device
76
KisPainter(KisPaintDeviceSP device);
78
/// Construct a painter, and begin painting on the device. All actions will be masked by the given selection.
79
KisPainter(KisPaintDeviceSP device, KisSelectionSP selection);
80
virtual ~KisPainter();
84
* Start painting on the specified device. Not undoable.
86
void begin(KisPaintDeviceSP device);
89
* Start painting on the specified paint device. All actions will be masked by the given selection.
91
void begin(KisPaintDeviceSP device, KisSelectionSP selection);
94
* Finish painting on the current device
99
* If set, the painter action is cancelable, if the action supports that.
101
void setProgress(KoUpdater * progressUpdater);
103
/// Begin an undoable paint operation
104
void beginTransaction(const QString& customName = "");
106
/// Finish the undoable paint operation
107
QUndoCommand *endTransaction();
109
/// begin a transaction with the given command
110
void beginTransaction(KisTransaction* command);
112
/// Returns the current paint device.
113
const KisPaintDeviceSP device() const;
114
KisPaintDeviceSP device();
117
* Blast the specified region from src onto the current paint device.
118
* @param dx the destination x-coordinate
119
* @param dy the destination y-coordinate
120
* @param op a pointer to the composite op use to blast the pixels from src on dst
121
* @param src the source device
122
* @param sx the source x-coordinate
123
* @param sy the source y-coordinate
124
* @param sw the width of the region
125
* @param sh the height of the region
127
void bitBlt(qint32 dx, qint32 dy,
128
const KisPaintDeviceSP src,
129
qint32 sx, qint32 sy,
130
qint32 sw, qint32 sh);
133
* Blast the specific region from src to the current paint device using a \ref KisFixedPaintDevice
134
* @param selection the selection will be used between (0,0) and (sw-1,sh-1).
136
void bitBlt(qint32 dx, qint32 dy,
137
const KisPaintDeviceSP srcdev,
138
const KisFixedPaintDeviceSP selection,
139
qint32 sx, qint32 sy,
140
qint32 sw, qint32 sh);
143
* Convenience method that uses QPoint and QRect
145
void bitBlt(const QPoint & pos, const KisPaintDeviceSP src, const QRect & srcRect);
148
* Blast the specified region from src onto the current paint device. Src is a
149
* fixed-size paint device: this means that src must have the same colorspace as
150
* the destination device.
152
* @param dx the destination x-coordinate
153
* @param dy the destination y-coordinate
154
* @param op a pointer to the composite op use to blast the pixels from src on dst
155
* @param src the source device
156
* @param sx the source x-coordinate
157
* @param sy the source y-coordinate
158
* @param sw the width of the region
159
* @param sh the height of the region
161
void bltFixed(qint32 dx, qint32 dy,
162
const KisFixedPaintDeviceSP src,
163
qint32 sx, qint32 sy,
164
qint32 sw, qint32 sh);
167
* Convenience method that uses QPoint and QRect
169
void bltFixed(const QPoint & pos, const KisFixedPaintDeviceSP src, const QRect & srcRect);
172
* Transfer the specified region from src onto the current paint device with selection.
173
* Src is a * fixed-size paint device: this means that src must have the same colorspace as
174
* the destination device. Selection is also fixed-size paint device and it's colorspace has
175
* to be alpha8. Assert if there is wrong colorspace for selection
177
* @param dx the destination x-coordinate
178
* @param dy the destination y-coordinate
179
* @param op a pointer to the composite op use to blast the pixels from src on dst
180
* @param src the source device
181
* @param selection the selection stored in fixed device
182
* @param sx the source x-coordinate
183
* @param sy the source y-coordinate
184
* @param sw the width of the region
185
* @param sh the height of the region
187
void bltFixed(qint32 dx, qint32 dy,
188
const KisFixedPaintDeviceSP srcDev,
189
const KisFixedPaintDeviceSP selection,
190
qint32 sx, qint32 sy,
191
qint32 sw, qint32 sh);
197
* The methods below are 'higher' level than the above methods. They need brushes, colors
198
* etc. set before they can be called. The methods do not directly tell the image to
199
* update, but you can call dirtyRegion() to get the region that needs to be notified by your
202
* Call will RESET the dirtyRegion!
204
QRegion dirtyRegion();
207
* Paint a line that connects the dots in points
209
void paintPolyline(const QVector <QPointF> &points,
210
int index = 0, int numPoints = -1);
213
* Draw a line between pos1 and pos2 using the currently set brush and color.
214
* If savedDist is less than zero, the brush is painted at pos1 before being
215
* painted along the line using the spacing setting.
216
* @return the drag distance, that is the remains of the distance between p1 and p2 not covered
217
* because the currenlty set brush has a spacing greater than that distance.
219
KisDistanceInformation paintLine(const KisPaintInformation &pi1,
220
const KisPaintInformation &pi2,
221
const KisDistanceInformation& savedDist = KisDistanceInformation());
224
* Draw a Bezier curve between pos1 and pos2 using control points 1 and 2.
225
* If savedDist is less than zero, the brush is painted at pos1 before being
226
* painted along the curve using the spacing setting.
227
* @return the drag distance, that is the remains of the distance between p1 and p2 not covered
228
* because the currenlty set brush has a spacing greater than that distance.
230
KisDistanceInformation paintBezierCurve(const KisPaintInformation &pi1,
231
const QPointF &control1,
232
const QPointF &control2,
233
const KisPaintInformation &pi2,
234
const KisDistanceInformation& savedDist = KisDistanceInformation());
236
* Fill the given vector points with the points needed to draw the Bezier curve between
237
* pos1 and pos2 using control points 1 and 2, excluding the final pos2.
239
void getBezierCurvePoints(const QPointF &pos1,
240
const QPointF &control1,
241
const QPointF &control2,
243
vQPointF& points) const;
247
* @param rect the rectangle to paint.
249
void paintRect(const QRectF &rect);
254
* @param x x coordinate of the top-left corner
255
* @param y y coordinate of the top-left corner
256
* @param w the rectangle width
257
* @param h the rectangle height
259
void paintRect(const double x,
265
* Paint the ellipse that fills the given rectangle.
267
* @param rect the rectangle containing the ellipse to paint.
269
void paintEllipse(const QRectF &rect);
272
* Paint the ellipse that fills the given rectangle.
274
* @param x x coordinate of the top-left corner
275
* @param y y coordinate of the top-left corner
276
* @param w the rectangle width
277
* @param h the rectangle height
279
void paintEllipse(const double x,
285
* Paint the polygon with the points given in points. It automatically closes the polygon
286
* by drawing the line from the last point to the first.
288
void paintPolygon(const vQPointF& points);
290
/** Draw a spot at pos using the currently set paint op, brush and color */
291
double paintAt(const KisPaintInformation &pos);
294
* Stroke the given QPainterPath.
296
void paintPainterPath(const QPainterPath& path);
299
* Fills the area enclosed by the given QPainterPath
301
void fillPainterPath(const QPainterPath& path);
304
* paint an unstroked one-pixel wide line from specified start position to the
305
* specified end position.
307
* XXX: this method really should work with subpixel precision for start and end position
308
* XXX: this method does not use the composite op
310
void drawLine(const QPointF & start, const QPointF & end);
313
* paints an unstroked one-pixel line using the DDA algorithm from specified start position to the
314
* specified end position.
316
* XXX: this method really should work with subpixel precision for start and end position
317
* XXX: this method does not use the composite op
319
void drawDDALine(const QPointF & start, const QPointF & end);
322
* Paint an unstroked, wobbly one-pixel wide line from the specified start to the specified
325
* XXX: this method really should work with subpixel precision for start and end position
326
* XXX: this method does not use the composite op
328
void drawWobblyLine(const QPointF & start, const QPointF & end);
331
* Paint an unstroked, one-pixel wide line from the specified start to the specified
332
* end position using the Wu algorithm
334
* XXX: this method does not use the composite op
336
void drawWuLine(const QPointF & start, const QPointF & end);
339
* Paint an unstroked wide line from the specified start to the specified
340
* end position with width varying from @param w1 at the start to @param w2 at
343
* XXX: the width should be set in doubles, not integers.
344
* XXX: this method really should work with subpixel precision for start and end position
345
* XXX: this method does not use the composite op
347
void drawThickLine(const QPointF & start, const QPointF & end, int startWidth, int endWidth);
350
* Set the channelflags: a bit array where true means that the
351
* channel corresponding in position with the bit will be read
352
* by the operation, and false means that it will not be affected.
354
* An empty channelFlags parameter means that all channels are
357
* @param the bit array that masks the source channels; only
358
* the channels where the corresponding bit is true will will be
359
* composited onto the destination device.
361
void setChannelFlags(QBitArray channelFlags);
363
/// @return the channel flags
364
QBitArray channelFlags();
367
* Set the paintop preset to use. If @param image is given,
368
* the paintop will be created using this image as parameter.
369
* Some paintops really want to know about the image they work
370
* for, e.g. the duplicate paintop.
372
void setPaintOpPreset(KisPaintOpPresetSP preset, KisImageWSP image);
374
/// Return the paintop preset
375
KisPaintOpPresetSP preset() const;
378
* Return the active paintop (which is created based on the specified preset and
379
* will be deleted as soon as the KisPainter instance dies).
381
KisPaintOp* paintOp() const;
383
/// Set the current pattern
384
void setPattern(const KisPattern * pattern);
386
/// Returns the currently set pattern
387
const KisPattern * pattern() const;
390
* Set the color that will be used to paint with, and convert it
391
* to the color space of the current paint device.
393
void setPaintColor(const KoColor& color);
395
/// Returns the color that will be used to paint with
396
const KoColor &paintColor() const;
399
* Set the current background color, and convert it
400
* to the color space of the current paint device.
402
void setBackgroundColor(const KoColor& color);
404
/// Returns the current background color
405
const KoColor &backgroundColor() const;
407
/// Set the current fill color
408
void setFillColor(const KoColor& color);
410
/// Returns the current fill color
411
const KoColor &fillColor() const;
413
/// Set the current generator (a generator can be used to fill an area
414
void setGenerator(const KisFilterConfiguration * generator);
416
/// @return the current generator configuration
417
const KisFilterConfiguration * generator() const;
419
/// This enum contains the styles with which we can fill things like polygons and ellipses
422
FillStyleForegroundColor,
423
FillStyleBackgroundColor,
430
/// Set the current style with which to fill
431
void setFillStyle(FillStyle fillStyle);
433
/// Returns the current fill style
434
FillStyle fillStyle() const;
436
/// Set whether a polygon's filled area should be anti-aliased or not. The default is true.
437
void setAntiAliasPolygonFill(bool antiAliasPolygonFill);
439
/// Return whether a polygon's filled area should be anti-aliased or not
440
bool antiAliasPolygonFill();
442
/// The style of the brush stroke around polygons and so
448
/// Set the current brush stroke style
449
void setStrokeStyle(StrokeStyle strokeStyle);
451
/// Returns the current brush stroke style
452
StrokeStyle strokeStyle() const;
454
/// Set the opacity which is used in painting (like filling polygons)
455
void setOpacity(quint8 opacity);
457
/// Returns the opacity that is used in painting
458
quint8 opacity() const;
460
/// Sets the bounds of the painter area; if not set, the painter
461
/// will happily paint where you ask it, making the paint device
462
/// larger as it goes
463
void setBounds(const QRect & bounds);
466
/// Set the composite op for this painter
467
void setCompositeOp(const KoCompositeOp * op);
468
const KoCompositeOp * compositeOp();
470
/// Set the composite op for this painter by string.
471
/// Note: the colorspace must be set previously!
472
void setCompositeOp(const QString& op);
475
* Add the r to the current dirty rect, and return the dirtyRegion after adding r to it.
477
QRegion addDirtyRect(const QRect & r);
480
* Reset the selection to the given selection. All painter actions will be
481
* masked by the specified selection.
483
void setSelection(KisSelectionSP selection);
486
* @return the selection set on this painter.
488
KisSelectionSP selection();
490
void setGradient(const KoAbstractGradient* gradient);
491
const KoAbstractGradient* gradient();
494
* Set the size of the tile in fillPainterPath, useful when optimizing the use of fillPainterPath
495
* e.g. Spray paintop uses more small tiles, although selections uses bigger tiles. QImage::fill
496
* is quite expensive so with smaller images you can save instructions
497
* Default and maximum size is 256x256 image
499
void setMaskImageSize(qint32 width, qint32 height);
502
* If the alpha channel is locked, the alpha values of the paint device we are painting on
505
void setLockAlpha(bool protect);
506
bool alphaLocked() const;
509
/// Initialize, set everything to '0' or defaults
512
/// Fill the polygon defined by points with the fillStyle
513
void fillPolygon(const vQPointF& points, FillStyle fillStyle);
517
KisPainter(const KisPainter&);
518
KisPainter& operator=(const KisPainter&);
520
float frac(float value) {
522
return modff(value , &tmp);
525
float invertFrac(float value) {
527
return 1.0f - modff(value , &tmp);
531
KoUpdater * progressUpdater();
540
#endif // KIS_PAINTER_H_