File: kis_painter.h

package info (click to toggle)
calligra 1%3A2.8.5%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 397,516 kB
  • ctags: 185,064
  • sloc: cpp: 1,505,875; python: 45,987; ansic: 28,421; xml: 26,472; sh: 23,986; java: 18,214; objc: 3,965; makefile: 2,816; perl: 2,792; yacc: 2,601; lex: 1,410; sql: 903; ruby: 737; asm: 236; lisp: 121
file content (787 lines) | stat: -rw-r--r-- 29,905 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
/*
 *  Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
 *  Copyright (c) 2004 Clarence Dang <dang@kde.org>
 *  Copyright (c) 2008-2010 Lukáš Tvrdý <lukast.dev@gmail.com>
 *  Copyright (c) 2010 José Luis Vergara Toloza <pentalis@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef KIS_PAINTER_H_
#define KIS_PAINTER_H_

#include <math.h>

#include <QVector>

#include <KoColorSpaceConstants.h>
#include <KoColorConversionTransformation.h>

#include "kis_distance_information.h"
#include "kis_global.h"
#include "kis_types.h"
#include <krita_export.h>

class QPen;
class KUndo2Command;
class QRect;
class QRectF;
class QStringList;
class QBitArray;
class QPainterPath;

class KoAbstractGradient;
class KoUpdater;
class KoColor;
class KoCompositeOp;

class KisUndoAdapter;
class KisPostExecutionUndoAdapter;
class KisTransaction;
class KoPattern;
class KisFilterConfiguration;
class KisPaintInformation;
class KisPaintOp;
/**
 * KisPainter contains the graphics primitives necessary to draw on a
 * KisPaintDevice. This is the same kind of abstraction as used in Qt
 * itself, where you have QPainter and QPaintDevice.
 *
 * However, KisPainter works on a tiled image and supports different
 * color models, and that's a lot more complicated.
 *
 * KisPainter supports transactions that can group various paint operations
 * in one undoable step.
 *
 * For more complex operations, you might want to have a look at the subclasses
 * of KisPainter: KisConvolutionPainter, KisFillPainter and KisGradientPainter
 *
 * KisPainter sets a number of default values, like COMPOSITE_OVER for compositeop,
 * OPACITY_OPAQUE for opacity and no selection for selection.
 */
class KRITAIMAGE_EXPORT KisPainter
{


public:
    /// Construct painter without a device
    KisPainter();

    /// Construct a painter, and begin painting on the device
    KisPainter(KisPaintDeviceSP device);

    /// Construct a painter, and begin painting on the device. All actions will be masked by the given selection.
    KisPainter(KisPaintDeviceSP device, KisSelectionSP selection);
    virtual ~KisPainter();

public:
    /**
     * Start painting on the specified device. Not undoable.
     */
    void begin(KisPaintDeviceSP device);

    /**
     * Start painting on the specified paint device. All actions will be masked by the given selection.
     */
    void begin(KisPaintDeviceSP device, KisSelectionSP selection);

    /**
     * Finish painting on the current device
     */
    void end();

    /**
     * If set, the painter action is cancelable, if the action supports that.
     */
    void setProgress(KoUpdater * progressUpdater);

    /// Begin an undoable paint operation
    void beginTransaction(const QString& transactionName = QString());

    /// Return the transaction's text message
    QString transactionText();

    /// Cancel all the changes made by the painter
    void revertTransaction();

    /// Finish the undoable paint operation
    void endTransaction(KisUndoAdapter *undoAdapter);

    /**
     * Finish transaction and load it to a special adapter for strokes
     */
    void endTransaction(KisPostExecutionUndoAdapter *undoAdapter);

    /**
     * Finishes a transaction and returns a pointer to its undo command
     */
    KUndo2Command* endAndTakeTransaction();

    /**
     * Finish the transaction and delete it's undo information.
     * NOTE: Be careful, because all the previous transactions
     * will become non-undoable after execution of this method.
     */
    void deleteTransaction();

    /// continue a transaction started somewhere else
    void putTransaction(KisTransaction* transaction);

    /// take transaction out of the reach of KisPainter
    KisTransaction* takeTransaction();

    /// Returns the current paint device.
    const KisPaintDeviceSP device() const;
    KisPaintDeviceSP device();



    /**
     * Blast a region of srcWidth @param srcWidth and srcHeight @param srcHeight from @param
     * srcDev onto the current paint device. @param srcX and @param srcY set the x and y
     * positions of the origin top-left corner, @param dstX and @param dstY those of
     * the destination.
     * Any pixel read outside the limits of @param srcDev will return the
     * default pixel, this is a property of \ref KisPaintDevice.
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param srcX the source x-coordinate
     * @param srcY the source y-coordinate
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     */
    void bitBlt(qint32 dstX, qint32 dstY,
                const KisPaintDeviceSP srcDev,
                qint32 srcX, qint32 srcY,
                qint32 srcWidth, qint32 srcHeight);

    /**
     * Convenience method that uses QPoint and QRect.
     *
     * @param pos the destination coordinate, it replaces @param dstX and @param dstY.
     * @param srcDev the source device.
     * @param srcRect the rectangle describing the area to blast from @param srcDev into the current paint device.
     * @param srcRect replaces @param srcX, @param srcY, @param srcWidth and @param srcHeight.
     *
     */
    void bitBlt(const QPoint & pos, const KisPaintDeviceSP srcDev, const QRect & srcRect);

    /**
     * The same as @ref bitBlt() but reads data from oldData() part of the device
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param srcX the source x-coordinate
     * @param srcY the source y-coordinate
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     */
    void bitBltOldData(qint32 dstX, qint32 dstY,
                       const KisPaintDeviceSP srcDev,
                       qint32 srcX, qint32 srcY,
                       qint32 srcWidth, qint32 srcHeight);

    /**
     * Convenience method that uses QPoint and QRect.
     *
     * @param pos the destination coordinate, it replaces @param dstX and @param dstY.
     * @param srcDev the source device.
     * @param srcRect the rectangle describing the area to blast from @param srcDev into the current paint device.
     * @param srcRect replaces @param srcX, @param srcY, @param srcWidth and @param srcHeight.
     *
     */
    void bitBltOldData(const QPoint & pos, const KisPaintDeviceSP srcDev, const QRect & srcRect);

    /**
     * Blasts a @param selection of srcWidth @param srcWidth and srcHeight @param srcHeight
     * of @param srcDev on the current paint device. There is parameters
     * to control where the area begins in each distinct device, explained below.
     * @param selection can be used as a mask to shape @param srcDev to
     * something interesting in the same step it is rendered to the current
     * paint device. @param selection 's colorspace must be alpha8 (the
     * colorspace for selections/transparency), the rectangle formed by
     * @param selX, @param selY, @param srcWidth and @param srcHeight must not go
     * beyond its limits, and they must be different from zero.
     * @param selection and KisPainter's selection (the user selection) are
     * fused together through the composite operation COMPOSITE_MULT.
     * Any pixel read outside the limits of @param srcDev will return the
     * default pixel, this is a property of \ref KisPaintDevice.
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param selection the custom selection to apply on the source device
     * @param selX the selection x-coordinate
     * @param selY the selection y-coordinate
     * @param srcX the source x-coordinate
     * @param srcY the source y-coordinate
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     *
     */
    void bitBltWithFixedSelection(qint32 dstX, qint32 dstY,
                                  const KisPaintDeviceSP srcDev,
                                  const KisFixedPaintDeviceSP selection,
                                  qint32 selX, qint32 selY,
                                  qint32 srcX, qint32 srcY,
                                  qint32 srcWidth, qint32 srcHeight);

    /**
     * Convenience method that assumes @param selX, @param selY, @param srcX and @param srcY are
     * equal to 0. Best used when @param selection and the desired area of @param srcDev have exactly
     * the same dimensions and are specially made for each other.
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param selection the custom selection to apply on the source device
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     */
    void bitBltWithFixedSelection(qint32 dstX, qint32 dstY,
                                  const KisPaintDeviceSP srcDev,
                                  const KisFixedPaintDeviceSP selection,
                                  qint32 srcWidth, qint32 srcHeight);

    /**
     * Blast a region of srcWidth @param srcWidth and srcHeight @param srcHeight from @param srcDev onto the current
     * paint device. @param srcX and @param srcY set the x and y positions of the
     * origin top-left corner, @param dstX and @param dstY those of the destination.
     * @param srcDev is a \ref KisFixedPaintDevice: this means that @param srcDev must have the same
     * colorspace as the destination device.
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param srcX the source x-coordinate
     * @param srcY the source y-coordinate
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     */
    void bltFixed(qint32 dstX, qint32 dstY,
                  const KisFixedPaintDeviceSP srcDev,
                  qint32 srcX, qint32 srcY,
                  qint32 srcWidth, qint32 srcHeight);

    /**
     * Convenience method that uses QPoint and QRect.
     *
     * @param pos the destination coordinate, it replaces @param dstX and @param dstY.
     * @param srcDev the source device.
     * @param srcRect the rectangle describing the area to blast from @param srcDev into the current paint device.
     * @param srcRect replaces @param srcX, @param srcY, @param srcWidth and @param srcHeight.
     *
     */
    void bltFixed(const QPoint & pos, const KisFixedPaintDeviceSP srcDev, const QRect & srcRect);

    /**
     * Blasts a @param selection of srcWidth @param srcWidth and srcHeight @param srcHeight
     * of @param srcDev on the current paint device. There is parameters to control
     * the top-left corner of the area in each respective paint device (@param dstX,
     * @param dstY, @param srcX, @param srcY).
     * @param selection can be used as a mask to shape @param srcDev to something
     * interesting in the same step it is rendered to the current paint device.
     * @param srcDev is a \ref KisFixedPaintDevice: this means that @param srcDev
     * must have the same colorspace as the destination device.
     * @param selection 's colorspace must be alpha8 (the colorspace for
     * selections/transparency).
     * The rectangle formed by the respective top-left coordinates of each device
     * and @param srcWidth and @param srcHeight must not go beyond their limits, and
     * they must be different from zero.
     * @param selection and KisPainter's selection (the user selection) are
     * fused together through the composite operation COMPOSITE_MULT.
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param selection the selection stored in fixed device
     * @param selX the selection x-coordinate
     * @param selY the selection y-coordinate
     * @param srcX the source x-coordinate
     * @param srcY the source y-coordinate
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     */
    void bltFixedWithFixedSelection(qint32 dstX, qint32 dstY,
                                    const KisFixedPaintDeviceSP srcDev,
                                    const KisFixedPaintDeviceSP selection,
                                    qint32 selX, qint32 selY,
                                    qint32 srcX, qint32 srcY,
                                    quint32 srcWidth, quint32 srcHeight);

    /**
     * Convenience method that assumes @param selX, @param selY, @param srcX and @param srcY are
     * equal to 0. Best used when @param selection and @param srcDev have exactly the same
     * dimensions and are specially made for each other.
     *
     * @param dstX the destination x-coordinate
     * @param dstY the destination y-coordinate
     * @param srcDev the source device
     * @param selection the custom selection to apply on the source device
     * @param srcWidth the width of the region to be manipulated
     * @param srcHeight the height of the region to be manipulated
     */
    void bltFixedWithFixedSelection(qint32 dstX, qint32 dstY,
                                    const KisFixedPaintDeviceSP srcDev,
                                    const KisFixedPaintDeviceSP selection,
                                    quint32 srcWidth, quint32 srcHeight);

    /**
     * fills a region of width @param width and height @param height of the current
     * paint device with the color @param color. @param x and @param y set the x and y positions of the
     * origin top-left corner.
     *
     * @param x the destination x-coordinate
     * @param y the destination y-coordinate
     * @param width the width of the region to be manipulated
     * @param height the height of the region to be manipulated
     * @param color the color the area is filled with
     */
    void fill(qint32 x, qint32 y, qint32 width, qint32 height, const KoColor& color);

    /**
     * First you need to setup the painter with setMirrorInformation,
     * then these set of methods provide way to render the devices mirrored
     * according the axisCenter vertically or horizontally or both.
     *
     * @param rc rectangle area covered by dab
     * @param dab this device will be mirrored in-place, it means that it will be changed
     */
    void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab);
    void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab, KisFixedPaintDeviceSP mask);
    void renderMirrorMask(QRect rc, KisPaintDeviceSP dab);
    void renderMirrorMask(QRect rc, KisPaintDeviceSP dab, int sx, int sy, KisFixedPaintDeviceSP mask);

    /**
     * Convenience method for renderMirrorMask(), allows to choose whether
     * we need to preserve out dab or do the transformations in-place.
     *
     * @param rc rectangle area covered by dab
     * @param dab the device to render
     * @param preserveDab states whether a temporary device should be
     *                    created to do the transformations
     */
    void renderMirrorMaskSafe(QRect rc, KisFixedPaintDeviceSP dab, bool preserveDab);

    /**
     * Convenience method for renderMirrorMask(), allows to choose whether
     * we need to preserve our fixed mask or do the transformations in-place.
     *
     * @param rc rectangle area covered by dab
     * @param dab the device to render
     * @param mask mask to use for rendering
     * @param preserveMask states whether a temporary device should be
     *                    created to do the transformations
     */
    void renderMirrorMaskSafe(QRect rc, KisPaintDeviceSP dab, int sx, int sy, KisFixedPaintDeviceSP mask, bool preserveMask);

    /**
     * A complex method that re-renders a dab on an \p rc area.
     * The \p rc  area and all the dedicated mirroring areas are cleared
     * before the painting, so this method should be used by paintops
     * which do not update the canvas incrementally, but instead
     * regenerate some internal cache \p dab with the COMPOSITE_COPY op.
     *
     * \see KisExperimentPaintOp
     */
    void renderDabWithMirroringNonIncremental(QRect rc, KisPaintDeviceSP dab);

    /**
      * The methods in this class do not tell the paintdevice to update, but they calculate the
      * dirty area. This method returns this dirty area and resets it.
      */
    QVector<QRect> takeDirtyRegion();

    /**
     * Paint a line that connects the dots in points
     */
    void paintPolyline(const QVector <QPointF> &points,
                       int index = 0, int numPoints = -1);

    /**
     * Draw a line between pos1 and pos2 using the currently set brush and color.
     * If savedDist is less than zero, the brush is painted at pos1 before being
     * painted along the line using the spacing setting.
     * @return the drag distance, that is the remains of the distance between p1 and p2 not covered
     * because the currenlty set brush has a spacing greater than that distance.
     */
    void paintLine(const KisPaintInformation &pi1,
                   const KisPaintInformation &pi2,
                   KisDistanceInformation *curentDistance);

    /**
     * Draw a Bezier curve between pos1 and pos2 using control points 1 and 2.
     * If savedDist is less than zero, the brush is painted at pos1 before being
     * painted along the curve using the spacing setting.
     * @return the drag distance, that is the remains of the distance between p1 and p2 not covered
     * because the currenlty set brush has a spacing greater than that distance.
     */
    void paintBezierCurve(const KisPaintInformation &pi1,
                          const QPointF &control1,
                          const QPointF &control2,
                          const KisPaintInformation &pi2,
                          KisDistanceInformation *currentDistance);
    /**
     * Fill the given vector points with the points needed to draw the Bezier curve between
     * pos1 and pos2 using control points 1 and 2, excluding the final pos2.
     */
    void getBezierCurvePoints(const QPointF &pos1,
                              const QPointF &control1,
                              const QPointF &control2,
                              const QPointF &pos2,
                              vQPointF& points) const;

    /**
     * Paint a rectangle.
     * @param rect the rectangle to paint.
     */
    void paintRect(const QRectF &rect);

    /**
     * Paint a rectangle.
     *
     * @param x x coordinate of the top-left corner
     * @param y y coordinate of the top-left corner
     * @param w the rectangle width
     * @param h the rectangle height
     */
    void paintRect(const qreal x,
                   const qreal y,
                   const qreal w,
                   const qreal h);

    /**
     * Paint the ellipse that fills the given rectangle.
     *
     * @param rect the rectangle containing the ellipse to paint.
     */
    void paintEllipse(const QRectF &rect);

    /**
     * Paint the ellipse that fills the given rectangle.
     *
     * @param x x coordinate of the top-left corner
     * @param y y coordinate of the top-left corner
     * @param w the rectangle width
     * @param h the rectangle height
     */
    void paintEllipse(const qreal x,
                      const qreal y,
                      const qreal w,
                      const qreal h);

    /**
     * Paint the polygon with the points given in points. It automatically closes the polygon
     * by drawing the line from the last point to the first.
     */
    void paintPolygon(const vQPointF& points);

    /** Draw a spot at pos using the currently set paint op, brush and color */
    void paintAt(const KisPaintInformation &pos,
                 KisDistanceInformation *savedDist);

    /**
     * Stroke the given QPainterPath.
     */
    void paintPainterPath(const QPainterPath& path);

    /**
     * Fills the area enclosed by the given QPainterPath
     * Convenience method for fillPainterPath(path, rect)
     */
    void fillPainterPath(const QPainterPath& path);

    /**
     * Fills the portion of an area enclosed by the given QPainterPath
     *
     * \param rect the portion of the path to fill
     */
    void fillPainterPath(const QPainterPath& path, const QRect &requestedRect);

    /**
     * Draw the path using the Pen
     */
    void drawPainterPath(const QPainterPath& path, const QPen& pen);

    /**
     * paint an unstroked one-pixel wide line from specified start position to the
     * specified end position.
     *
     */
    void drawLine(const QPointF & start, const QPointF & end);

    /**
     * paint an unstroked line with thickness from specified start position to the
     * specified end position. Scanline algorithm is used.
     */
    void drawLine(const QPointF &start, const QPointF &end, qreal width, bool antialias);


    /**
     * paints an unstroked, aliased one-pixel line using the DDA algorithm from specified start position to the
     * specified end position.
     *
     */
    void drawDDALine(const QPointF & start, const QPointF & end);

    /**
     * Paint an unstroked, wobbly one-pixel wide line from the specified start to the specified
     * end position.
     *
     */
    void drawWobblyLine(const QPointF & start, const QPointF & end);

    /**
     * Paint an unstroked, anti-aliased one-pixel wide line from the specified start to the specified
     * end position using the Wu algorithm
     */
    void drawWuLine(const QPointF & start, const QPointF & end);

    /**
     * Paint an unstroked wide line from the specified start to the specified
     * end position with width varying from @param w1 at the start to @param w2 at
     * the end.
     *
     * XXX: the width should be set in doubles, not integers.
     */
    void drawThickLine(const QPointF & start, const QPointF & end, int startWidth, int endWidth);

    /**
     * Set the channelflags: a bit array where true means that the
     * channel corresponding in position with the bit will be read
     * by the operation, and false means that it will not be affected.
     *
     * An empty channelFlags parameter means that all channels are
     * affected.
     *
     * @param the bit array that masks the source channels; only
     * the channels where the corresponding bit is true will will be
     * composited onto the destination device.
     */
    void setChannelFlags(QBitArray channelFlags);

    /// @return the channel flags
    QBitArray channelFlags();

    /**
     * Set the paintop preset to use. If @param image is given,
     * the paintop will be created using this image as parameter.
     * Some paintops really want to know about the image they work
     * for, e.g. the duplicate paintop.
     */
    void setPaintOpPreset(KisPaintOpPresetSP preset, KisImageWSP image);

    /// Return the paintop preset
    KisPaintOpPresetSP preset() const;

    /**
     * Return the active paintop (which is created based on the specified preset and
     * will be deleted as soon as the KisPainter instance dies).
     */
    KisPaintOp* paintOp() const;

    void setMirrorInformation(const QPointF &axisCenter, bool mirrorHorizontaly, bool mirrorVerticaly);

    /**
     * copy the mirror information to other painter
     */
    void copyMirrorInformation(KisPainter * painter);

    /**
     * Returns whether the mirroring methods will do any
     * work when called
     */
    bool hasMirroring() const;

    /// Set the current pattern
    void setPattern(const KoPattern * pattern);

    /// Returns the currently set pattern
    const KoPattern * pattern() const;

    /**
     * Set the color that will be used to paint with, and convert it
     * to the color space of the current paint device.
     */
    void setPaintColor(const KoColor& color);

    /// Returns the color that will be used to paint with
    const KoColor &paintColor() const;

    /**
     * Set the current background color, and convert it
     * to the color space of the current paint device.
     */
    void setBackgroundColor(const KoColor& color);

    /// Returns the current background color
    const KoColor &backgroundColor() const;

    /// Set the current generator (a generator can be used to fill an area
    void setGenerator(const KisFilterConfiguration * generator);

    /// @return the current generator configuration
    const KisFilterConfiguration * generator() const;

    /// This enum contains the styles with which we can fill things like polygons and ellipses
    enum FillStyle {
        FillStyleNone,
        FillStyleForegroundColor,
        FillStyleBackgroundColor,
        FillStylePattern,
        FillStyleGradient,
        FillStyleStrokes,
        FillStyleGenerator
    };

    /// Set the current style with which to fill
    void setFillStyle(FillStyle fillStyle);

    /// Returns the current fill style
    FillStyle fillStyle() const;

    /// Set whether a polygon's filled area should be anti-aliased or not. The default is true.
    void setAntiAliasPolygonFill(bool antiAliasPolygonFill);

    /// Return whether a polygon's filled area should be anti-aliased or not
    bool antiAliasPolygonFill();

    /// The style of the brush stroke around polygons and so
    enum StrokeStyle {
        StrokeStyleNone,
        StrokeStyleBrush
    };

    /// Set the current brush stroke style
    void setStrokeStyle(StrokeStyle strokeStyle);

    /// Returns the current brush stroke style
    StrokeStyle strokeStyle() const;

    void setFlow(quint8 flow);

    quint8 flow() const;

    /**
     * Sets the opacity of the painting and recalculates the
     * mean opacity of the stroke. This mean value is used to
     * make ALPHA_DARKEN painting look correct
     */
    void setOpacityUpdateAverage(quint8 opacity);

    /// Set the opacity which is used in painting (like filling polygons)
    void setOpacity(quint8 opacity);

    /// Returns the opacity that is used in painting
    quint8 opacity() const;

    /// Set the composite op for this painter
    void setCompositeOp(const KoCompositeOp * op);
    const KoCompositeOp * compositeOp();

    /// Set the composite op for this painter by string.
    /// Note: the colorspace must be set previously!
    void setCompositeOp(const QString& op);

    /**
     * Add the r to the current dirty rect.
     */
    void addDirtyRect(const QRect & r);

    /**
     * Reset the selection to the given selection. All painter actions will be
     * masked by the specified selection.
     */
    void setSelection(KisSelectionSP selection);

    /**
     * @return the selection set on this painter.
     */
    KisSelectionSP selection();

    void setGradient(const KoAbstractGradient* gradient);
    const KoAbstractGradient* gradient() const;

    /**
    * Set the size of the tile in fillPainterPath, useful when optimizing the use of fillPainterPath
    * e.g. Spray paintop uses more small tiles, although selections uses bigger tiles. QImage::fill
    * is quite expensive so with smaller images you can save instructions
    * Default and maximum size is 256x256 image
    */
    void setMaskImageSize(qint32 width, qint32 height);

//    /**
//     * If the alpha channel is locked, the alpha values of the paint device we are painting on
//     * will not change.
//     */
//    void setLockAlpha(bool protect);
//    bool alphaLocked() const;

    /**
     * set the rendering intent in case pixels need to be converted before painting
     */
    void setRenderingIntent(KoColorConversionTransformation::Intent intent);

    /**
     * set the conversion flags in case pixels need to be converted before painting
     */
    void setColorConversionFlags(KoColorConversionTransformation::ConversionFlags conversionFlags);

protected:
    /// Initialize, set everything to '0' or defaults
    void init();

    /// Fill the polygon defined by points with the fillStyle
    void fillPolygon(const vQPointF& points, FillStyle fillStyle);

private:

    KisPainter(const KisPainter&);
    KisPainter& operator=(const KisPainter&);

    float frac(float value) {
        float tmp = 0;
        return modff(value , &tmp);
    }

    float invertFrac(float value) {
        float tmp = 0;
        return 1.0f - modff(value , &tmp);
    }

protected:
    KoUpdater * progressUpdater();

private:
    template <bool useOldSrcData>
        void bitBltImpl(qint32 dstX, qint32 dstY,
                        const KisPaintDeviceSP srcDev,
                        qint32 srcX, qint32 srcY,
                        qint32 srcWidth, qint32 srcHeight);

    inline void compositeOnePixel(quint8 *dst, const KoColor &color);

private:

    struct Private;
    Private* const d;
};


#endif // KIS_PAINTER_H_