File indexing completed on 2024-05-12 15:58:35
0001 /* 0002 * SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2004 Clarence Dang <dang@kde.org> 0004 * SPDX-FileCopyrightText: 2008-2010 Lukáš Tvrdý <lukast.dev@gmail.com> 0005 * SPDX-FileCopyrightText: 2010 José Luis Vergara Toloza <pentalis@gmail.com> 0006 * 0007 * SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #ifndef KIS_PAINTER_H_ 0011 #define KIS_PAINTER_H_ 0012 0013 #include <math.h> 0014 0015 #include <QVector> 0016 0017 #include <KoColorSpaceConstants.h> 0018 #include <KoColorConversionTransformation.h> 0019 #include <KoPattern.h> 0020 #include <KoAbstractGradient.h> 0021 0022 #include "kundo2magicstring.h" 0023 #include "kis_types.h" 0024 #include <kis_filter_configuration.h> 0025 #include <kritaimage_export.h> 0026 0027 0028 class QPen; 0029 class KUndo2Command; 0030 class QRect; 0031 class QRectF; 0032 class QBitArray; 0033 class QPainterPath; 0034 0035 class KoUpdater; 0036 class KoColor; 0037 class KoCompositeOp; 0038 0039 class KisUndoAdapter; 0040 class KisPostExecutionUndoAdapter; 0041 class KisTransaction; 0042 class KisPaintInformation; 0043 class KisPaintOp; 0044 class KisDistanceInformation; 0045 struct KisRenderedDab; 0046 class KisRunnableStrokeJobsInterface; 0047 0048 /** 0049 * KisPainter contains the graphics primitives necessary to draw on a 0050 * KisPaintDevice. This is the same kind of abstraction as used in Qt 0051 * itself, where you have QPainter and QPaintDevice. 0052 * 0053 * However, KisPainter works on a tiled image and supports different 0054 * color models, and that's a lot more complicated. 0055 * 0056 * KisPainter supports transactions that can group various paint operations 0057 * in one undoable step. 0058 * 0059 * For more complex operations, you might want to have a look at the subclasses 0060 * of KisPainter: KisConvolutionPainter, KisFillPainter and KisGradientPainter 0061 * 0062 * KisPainter sets a number of default values, like COMPOSITE_OVER for compositeop, 0063 * OPACITY_OPAQUE for opacity and no selection for selection. 0064 */ 0065 class KRITAIMAGE_EXPORT KisPainter 0066 { 0067 0068 0069 public: 0070 /// Construct painter without a device 0071 KisPainter(); 0072 0073 /// Construct a painter, and begin painting on the device 0074 KisPainter(KisPaintDeviceSP device); 0075 0076 /// Construct a painter, and begin painting on the device. All actions will be masked by the given selection. 0077 KisPainter(KisPaintDeviceSP device, KisSelectionSP selection); 0078 virtual ~KisPainter(); 0079 0080 public: 0081 static void copyAreaOptimized(const QPoint &dstPt, 0082 KisPaintDeviceSP src, 0083 KisPaintDeviceSP dst, 0084 const QRect &originalSrcRect); 0085 0086 static void copyAreaOptimizedOldData(const QPoint &dstPt, 0087 KisPaintDeviceSP src, 0088 KisPaintDeviceSP dst, 0089 const QRect &originalSrcRect); 0090 0091 static void copyAreaOptimized(const QPoint &dstPt, 0092 KisPaintDeviceSP src, 0093 KisPaintDeviceSP dst, 0094 const QRect &originalSrcRect, 0095 KisSelectionSP selection); 0096 0097 static KisPaintDeviceSP convertToAlphaAsAlpha(KisPaintDeviceSP src); 0098 static KisPaintDeviceSP convertToAlphaAsGray(KisPaintDeviceSP src); 0099 0100 /** 0101 * creates a paint device with only alpha values from src 0102 */ 0103 static KisPaintDeviceSP convertToAlphaAsPureAlpha(KisPaintDeviceSP src); 0104 0105 static bool checkDeviceHasTransparency(KisPaintDeviceSP dev); 0106 0107 /** 0108 * Start painting on the specified device. Not undoable. 0109 */ 0110 void begin(KisPaintDeviceSP device); 0111 0112 /** 0113 * Start painting on the specified paint device. All actions will be masked by the given selection. 0114 */ 0115 void begin(KisPaintDeviceSP device, KisSelectionSP selection); 0116 0117 /** 0118 * Finish painting on the current device 0119 */ 0120 void end(); 0121 0122 /** 0123 * If set, the painter action is cancelable, if the action supports that. 0124 */ 0125 void setProgress(KoUpdater * progressUpdater); 0126 0127 /// Begin an undoable paint operation 0128 void beginTransaction(const KUndo2MagicString& transactionName = KUndo2MagicString(),int timedID = -1); 0129 0130 /// Cancel all the changes made by the painter 0131 void revertTransaction(); 0132 0133 /// Finish the undoable paint operation 0134 void endTransaction(KisUndoAdapter *undoAdapter); 0135 0136 /** 0137 * Finish transaction and load it to a special adapter for strokes 0138 */ 0139 void endTransaction(KisPostExecutionUndoAdapter *undoAdapter); 0140 0141 /** 0142 * Finishes a transaction and returns a pointer to its undo command 0143 */ 0144 KUndo2Command* endAndTakeTransaction(); 0145 0146 /** 0147 * Finish the transaction and delete it's undo information. 0148 * NOTE: Be careful, because all the previous transactions 0149 * will become non-undoable after execution of this method. 0150 */ 0151 void deleteTransaction(); 0152 0153 /// continue a transaction started somewhere else 0154 void putTransaction(KisTransaction* transaction); 0155 0156 /// take transaction out of the reach of KisPainter 0157 KisTransaction* takeTransaction(); 0158 0159 /// Returns the current paint device. 0160 const KisPaintDeviceSP device() const; 0161 KisPaintDeviceSP device(); 0162 0163 0164 0165 /** 0166 * Blast a region of srcWidth @param srcWidth and srcHeight @param srcHeight from @param 0167 * srcDev onto the current paint device. @param srcX and @param srcY set the x and y 0168 * positions of the origin top-left corner, @param dstX and @param dstY those of 0169 * the destination. 0170 * Any pixel read outside the limits of @param srcDev will return the 0171 * default pixel, this is a property of \ref KisPaintDevice. 0172 * 0173 * @param dstX the destination x-coordinate 0174 * @param dstY the destination y-coordinate 0175 * @param srcDev the source device 0176 * @param srcX the source x-coordinate 0177 * @param srcY the source y-coordinate 0178 * @param srcWidth the width of the region to be manipulated 0179 * @param srcHeight the height of the region to be manipulated 0180 */ 0181 void bitBlt(qint32 dstX, qint32 dstY, 0182 const KisPaintDeviceSP srcDev, 0183 qint32 srcX, qint32 srcY, 0184 qint32 srcWidth, qint32 srcHeight); 0185 0186 /** 0187 * Convenience method that uses QPoint and QRect. 0188 * 0189 * @param pos the destination coordinate, it replaces @p dstX and @p dstY. 0190 * @param srcDev the source device. 0191 * @param srcRect the rectangle describing the area to blast from @p srcDev into the current paint device. 0192 * @p srcRect replaces @p srcX, @p srcY, @p srcWidth and @p srcHeight. 0193 * 0194 */ 0195 void bitBlt(const QPoint & pos, const KisPaintDeviceSP srcDev, const QRect & srcRect); 0196 0197 /** 0198 * The same as @ref bitBlt() but reads data from oldData() part of the device 0199 * 0200 * @param dstX the destination x-coordinate 0201 * @param dstY the destination y-coordinate 0202 * @param srcDev the source device 0203 * @param srcX the source x-coordinate 0204 * @param srcY the source y-coordinate 0205 * @param srcWidth the width of the region to be manipulated 0206 * @param srcHeight the height of the region to be manipulated 0207 */ 0208 void bitBltOldData(qint32 dstX, qint32 dstY, 0209 const KisPaintDeviceSP srcDev, 0210 qint32 srcX, qint32 srcY, 0211 qint32 srcWidth, qint32 srcHeight); 0212 0213 /** 0214 * Convenience method that uses QPoint and QRect. 0215 * 0216 * @param pos the destination coordinate, it replaces @p dstX and @p dstY. 0217 * @param srcDev the source device. 0218 * @param srcRect the rectangle describing the area to blast from @param srcDev into the current paint device. 0219 * @p srcRect replaces @p srcX, @p srcY, @p srcWidth and @p srcHeight. 0220 * 0221 */ 0222 void bitBltOldData(const QPoint & pos, const KisPaintDeviceSP srcDev, const QRect & srcRect); 0223 0224 /** 0225 * Blasts a @param selection of srcWidth @param srcWidth and srcHeight @param srcHeight 0226 * of @param srcDev on the current paint device. There is parameters 0227 * to control where the area begins in each distinct device, explained below. 0228 * @param selection can be used as a mask to shape @param srcDev to 0229 * something interesting in the same step it is rendered to the current 0230 * paint device. @param selection 's colorspace must be alpha8 (the 0231 * colorspace for selections/transparency), the rectangle formed by 0232 * @param selX, @param selY, @param srcWidth and @param srcHeight must not go 0233 * beyond its limits, and they must be different from zero. 0234 * @param selection and KisPainter's selection (the user selection) are 0235 * fused together through the composite operation COMPOSITE_MULT. 0236 * Any pixel read outside the limits of @param srcDev will return the 0237 * default pixel, this is a property of \ref KisPaintDevice. 0238 * 0239 * @param dstX the destination x-coordinate 0240 * @param dstY the destination y-coordinate 0241 * @param srcDev the source device 0242 * @param selection the custom selection to apply on the source device 0243 * @param selX the selection x-coordinate 0244 * @param selY the selection y-coordinate 0245 * @param srcX the source x-coordinate 0246 * @param srcY the source y-coordinate 0247 * @param srcWidth the width of the region to be manipulated 0248 * @param srcHeight the height of the region to be manipulated 0249 * 0250 */ 0251 void bitBltWithFixedSelection(qint32 dstX, qint32 dstY, 0252 const KisPaintDeviceSP srcDev, 0253 const KisFixedPaintDeviceSP selection, 0254 qint32 selX, qint32 selY, 0255 qint32 srcX, qint32 srcY, 0256 qint32 srcWidth, qint32 srcHeight); 0257 0258 /** 0259 * Convenience method that assumes @p selX, @p selY, @p srcX and @p srcY are 0260 * equal to 0. Best used when @p selection and the desired area of @p srcDev have exactly 0261 * the same dimensions and are specially made for each other. 0262 * 0263 * @param dstX the destination x-coordinate 0264 * @param dstY the destination y-coordinate 0265 * @param srcDev the source device 0266 * @param selection the custom selection to apply on the source device 0267 * @param srcWidth the width of the region to be manipulated 0268 * @param srcHeight the height of the region to be manipulated 0269 */ 0270 void bitBltWithFixedSelection(qint32 dstX, qint32 dstY, 0271 const KisPaintDeviceSP srcDev, 0272 const KisFixedPaintDeviceSP selection, 0273 qint32 srcWidth, qint32 srcHeight); 0274 0275 /** 0276 * Blast a region of srcWidth @p srcWidth and srcHeight @p srcHeight from @p srcDev onto the current 0277 * paint device. @p srcX and @p srcY set the x and y positions of the 0278 * origin top-left corner, @p dstX and @p dstY those of the destination. 0279 * @p srcDev is a @ref KisFixedPaintDevice : this means that @p srcDev must have the same 0280 * colorspace as the destination device. 0281 * 0282 * @param dstX the destination x-coordinate 0283 * @param dstY the destination y-coordinate 0284 * @param srcDev the source device 0285 * @param srcX the source x-coordinate 0286 * @param srcY the source y-coordinate 0287 * @param srcWidth the width of the region to be manipulated 0288 * @param srcHeight the height of the region to be manipulated 0289 */ 0290 void bltFixed(qint32 dstX, qint32 dstY, 0291 const KisFixedPaintDeviceSP srcDev, 0292 qint32 srcX, qint32 srcY, 0293 qint32 srcWidth, qint32 srcHeight); 0294 0295 0296 /** 0297 * Render the area \p rc from \p srcDevices on the destination device. 0298 * If \p rc doesn't cross the device's rect, then the device is not 0299 * rendered at all. 0300 */ 0301 void bltFixed(const QRect &rc, const QList<KisRenderedDab> allSrcDevices); 0302 0303 /** 0304 * Convenience method that uses QPoint and QRect. 0305 * 0306 * @param pos the destination coordinate, it replaces @p dstX and @p dstY. 0307 * @param srcDev the source device. 0308 * @param srcRect the rectangle describing the area to blast from @p srcDev into the current paint device. 0309 * @param srcRect replaces @p srcX, @p srcY, @p srcWidth and @p srcHeight. 0310 * 0311 */ 0312 void bltFixed(const QPoint & pos, const KisFixedPaintDeviceSP srcDev, const QRect & srcRect); 0313 0314 /** 0315 * Blasts a @p selection of srcWidth @p srcWidth and srcHeight @p srcHeight 0316 * of @p srcDev on the current paint device. There is parameters to control 0317 * the top-left corner of the area in each respective paint device (@p dstX, 0318 * @p dstY, @p srcX, @p srcY). 0319 * @p selection can be used as a mask to shape @p srcDev to something 0320 * interesting in the same step it is rendered to the current paint device. 0321 * @p srcDev is a @ref KisFixedPaintDevice : this means that @p srcDev 0322 * must have the same colorspace as the destination device. 0323 * @p selection 's colorspace must be alpha8 (the colorspace for 0324 * selections/transparency). 0325 * The rectangle formed by the respective top-left coordinates of each device 0326 * and @p srcWidth and @p srcHeight must not go beyond their limits, and 0327 * they must be different from zero. 0328 * @p selection and KisPainter's selection (the user selection) are 0329 * fused together through the composite operation COMPOSITE_MULT. 0330 * 0331 * @param dstX the destination x-coordinate 0332 * @param dstY the destination y-coordinate 0333 * @param srcDev the source device 0334 * @param selection the selection stored in fixed device 0335 * @param selX the selection x-coordinate 0336 * @param selY the selection y-coordinate 0337 * @param srcX the source x-coordinate 0338 * @param srcY the source y-coordinate 0339 * @param srcWidth the width of the region to be manipulated 0340 * @param srcHeight the height of the region to be manipulated 0341 */ 0342 void bltFixedWithFixedSelection(qint32 dstX, qint32 dstY, 0343 const KisFixedPaintDeviceSP srcDev, 0344 const KisFixedPaintDeviceSP selection, 0345 qint32 selX, qint32 selY, 0346 qint32 srcX, qint32 srcY, 0347 quint32 srcWidth, quint32 srcHeight); 0348 0349 /** 0350 * Convenience method that assumes @p selX, @p selY, @p srcX and @p srcY are 0351 * equal to 0. Best used when @p selection and @p srcDev have exactly the same 0352 * dimensions and are specially made for each other. 0353 * 0354 * @param dstX the destination x-coordinate 0355 * @param dstY the destination y-coordinate 0356 * @param srcDev the source device 0357 * @param selection the custom selection to apply on the source device 0358 * @param srcWidth the width of the region to be manipulated 0359 * @param srcHeight the height of the region to be manipulated 0360 */ 0361 void bltFixedWithFixedSelection(qint32 dstX, qint32 dstY, 0362 const KisFixedPaintDeviceSP srcDev, 0363 const KisFixedPaintDeviceSP selection, 0364 quint32 srcWidth, quint32 srcHeight); 0365 0366 /** 0367 * fills a region of width @p width and height @p height of the current 0368 * paint device with the color @p color. @p x and @p y set the x and y positions of the 0369 * origin top-left corner. 0370 * 0371 * @param x the destination x-coordinate 0372 * @param y the destination y-coordinate 0373 * @param width the width of the region to be manipulated 0374 * @param height the height of the region to be manipulated 0375 * @param color the color the area is filled with 0376 */ 0377 void fill(qint32 x, qint32 y, qint32 width, qint32 height, const KoColor& color); 0378 0379 /** 0380 * First you need to setup the painter with setMirrorInformation, 0381 * then these set of methods provide way to render the devices mirrored 0382 * according the axesCenter vertically or horizontally or both. 0383 * 0384 * @param rc rectangle area covered by dab 0385 * @param dab this device will be mirrored in-place, it means that it will be changed 0386 */ 0387 void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab); 0388 void renderMirrorMask(QRect rc, KisFixedPaintDeviceSP dab, KisFixedPaintDeviceSP mask); 0389 void renderMirrorMask(QRect rc, KisPaintDeviceSP dab); 0390 void renderMirrorMask(QRect rc, KisPaintDeviceSP dab, int sx, int sy, KisFixedPaintDeviceSP mask); 0391 0392 /** 0393 * Convenience method for renderMirrorMask(), allows to choose whether 0394 * we need to preserve out dab or do the transformations in-place. 0395 * 0396 * @param rc rectangle area covered by dab 0397 * @param dab the device to render 0398 * @param mask mask to use for rendering 0399 * @param preserveDab states whether a temporary device should be 0400 * created to do the transformations 0401 */ 0402 void renderMirrorMaskSafe(QRect rc, KisFixedPaintDeviceSP dab, bool preserveDab); 0403 void renderMirrorMaskSafe(QRect rc, KisFixedPaintDeviceSP dab, KisFixedPaintDeviceSP mask, bool preserveDab); 0404 0405 /** 0406 * Convenience method for renderMirrorMask(), allows to choose whether 0407 * we need to preserve our fixed mask or do the transformations in-place. 0408 * 0409 * @param rc rectangular area covered by dab 0410 * @param dab the device to render 0411 * @param sx x coordinate of the top left corner of the area 0412 * @param sy y coordinate of the top left corner of the area 0413 * @param mask mask to use for rendering 0414 * @param preserveMask states whether a temporary device should be 0415 * created to do the transformations 0416 */ 0417 void renderMirrorMaskSafe(QRect rc, KisPaintDeviceSP dab, int sx, int sy, KisFixedPaintDeviceSP mask, bool preserveMask); 0418 0419 /** 0420 * A complex method that re-renders a dab on an \p rc area. 0421 * The \p rc area and all the dedicated mirroring areas are cleared 0422 * before the painting, so this method should be used by paintops 0423 * which do not update the canvas incrementally, but instead 0424 * regenerate some internal cache \p dab with the COMPOSITE_COPY op. 0425 * 0426 * \see KisExperimentPaintOp 0427 */ 0428 void renderDabWithMirroringNonIncremental(QRect rc, KisPaintDeviceSP dab); 0429 0430 /** 0431 * @return true if the painter has some rects marked as dirty 0432 * @see takeDirtyRegion(), addDirtyRect() 0433 */ 0434 bool hasDirtyRegion() const; 0435 0436 /** 0437 * The methods in this class do not tell the paintdevice to update, but they calculate the 0438 * dirty area. This method returns this dirty area and resets it. 0439 */ 0440 QVector<QRect> takeDirtyRegion(); 0441 0442 /** 0443 * Paint a line that connects the dots in points 0444 */ 0445 void paintPolyline(const QVector <QPointF> &points, 0446 int index = 0, int numPoints = -1); 0447 0448 /** 0449 * Draw a line between pos1 and pos2 using the currently set brush and color. 0450 * If savedDist is less than zero, the brush is painted at pos1 before being 0451 * painted along the line using the spacing setting. 0452 * @return the drag distance, that is the remains of the distance between p1 and p2 not covered 0453 * because the currently set brush has a spacing greater than that distance. 0454 */ 0455 void paintLine(const KisPaintInformation &pi1, 0456 const KisPaintInformation &pi2, 0457 KisDistanceInformation *currentDistance); 0458 0459 /** 0460 * Draw a Bezier curve between @p pi1 and @p pi2 using control points @p control1 and @p control2. 0461 * If savedDist is less than zero, the brush is painted at pos1 before being 0462 * painted along the curve using the spacing setting. 0463 * @return the drag distance, that is the remains of the distance between @p pi1 and @p pi2 not covered 0464 * because the currently set brush has a spacing greater than that distance. 0465 */ 0466 void paintBezierCurve(const KisPaintInformation &pi1, 0467 const QPointF &control1, 0468 const QPointF &control2, 0469 const KisPaintInformation &pi2, 0470 KisDistanceInformation *currentDistance); 0471 /** 0472 * Fill the given vector points with the points needed to draw the Bezier curve between 0473 * @p pos1 and @p pos2 using control points @p control1 and @p control2, excluding the final pos2. 0474 */ 0475 void getBezierCurvePoints(const QPointF &pos1, 0476 const QPointF &control1, 0477 const QPointF &control2, 0478 const QPointF &pos2, 0479 vQPointF& points) const; 0480 0481 /** 0482 * Paint a rectangle. 0483 * @param rect the rectangle to paint. 0484 */ 0485 void paintRect(const QRectF &rect); 0486 0487 /** 0488 * Paint a rectangle. 0489 * 0490 * @param x x coordinate of the top-left corner 0491 * @param y y coordinate of the top-left corner 0492 * @param w the rectangle width 0493 * @param h the rectangle height 0494 */ 0495 void paintRect(const qreal x, 0496 const qreal y, 0497 const qreal w, 0498 const qreal h); 0499 0500 /** 0501 * Paint the ellipse that fills the given rectangle. 0502 * 0503 * @param rect the rectangle containing the ellipse to paint. 0504 */ 0505 void paintEllipse(const QRectF &rect); 0506 0507 /** 0508 * Paint the ellipse that fills the given rectangle. 0509 * 0510 * @param x x coordinate of the top-left corner 0511 * @param y y coordinate of the top-left corner 0512 * @param w the rectangle width 0513 * @param h the rectangle height 0514 */ 0515 void paintEllipse(const qreal x, 0516 const qreal y, 0517 const qreal w, 0518 const qreal h); 0519 0520 /** 0521 * Paint the polygon with the points given in points. It automatically closes the polygon 0522 * by drawing the line from the last point to the first. 0523 */ 0524 void paintPolygon(const vQPointF& points); 0525 0526 /** Draw a spot at pos using the currently set paint op, brush and color */ 0527 void paintAt(const KisPaintInformation &pos, 0528 KisDistanceInformation *savedDist); 0529 0530 /** 0531 * Stroke the given QPainterPath. 0532 */ 0533 void paintPainterPath(const QPainterPath& path); 0534 0535 /** 0536 * Fills the area enclosed by the given QPainterPath 0537 * Convenience method for fillPainterPath(path, rect) 0538 */ 0539 void fillPainterPath(const QPainterPath& path); 0540 0541 /** 0542 * Fills the portion of an area enclosed by the given QPainterPath 0543 * 0544 * \param path the portion of the path to fill 0545 * \param requestedRect the rectangle containing the area 0546 */ 0547 void fillPainterPath(const QPainterPath& path, const QRect &requestedRect); 0548 0549 /** 0550 * Draw the path using the Pen 0551 * 0552 * if \p requestedRect is null, the entire path is painted 0553 */ 0554 void drawPainterPath(const QPainterPath& path, const QPen& pen, const QRect &requestedRect); 0555 0556 // convenience overload 0557 void drawPainterPath(const QPainterPath& path, const QPen& pen); 0558 0559 /** 0560 * paint an unstroked one-pixel wide line from specified start position to the 0561 * specified end position. 0562 * 0563 */ 0564 void drawLine(const QPointF & start, const QPointF & end); 0565 0566 /** 0567 * paint an unstroked line with thickness from specified start position to the 0568 * specified end position. Scanline algorithm is used. 0569 */ 0570 void drawLine(const QPointF &start, const QPointF &end, qreal width, bool antialias); 0571 0572 0573 /** 0574 * paints an unstroked, aliased one-pixel line using the DDA algorithm from specified start position to the 0575 * specified end position. 0576 * 0577 */ 0578 void drawDDALine(const QPointF & start, const QPointF & end); 0579 0580 /** 0581 * Paint an unstroked, wobbly one-pixel wide line from the specified start to the specified 0582 * end position. 0583 * 0584 */ 0585 void drawWobblyLine(const QPointF & start, const QPointF & end); 0586 0587 /** 0588 * Paint an unstroked, anti-aliased one-pixel wide line from the specified start to the specified 0589 * end position using the Wu algorithm 0590 */ 0591 void drawWuLine(const QPointF & start, const QPointF & end); 0592 0593 /** 0594 * Paint an unstroked wide line from the specified start to the specified 0595 * end position with width varying from @p start at the start to @p end at 0596 * the end. 0597 * 0598 * XXX: the width should be set in doubles, not integers. 0599 */ 0600 void drawThickLine(const QPointF & start, const QPointF & end, int startWidth, int endWidth); 0601 0602 /** 0603 * Set the channelflags: a bit array where true means that the 0604 * channel corresponding in position with the bit will be read 0605 * by the operation, and false means that it will not be affected. 0606 * 0607 * An empty channelFlags parameter means that all channels are 0608 * affected. 0609 * 0610 * @param channelFlags the bit array that masks the source channels; only 0611 * the channels where the corresponding bit is true will will be 0612 * composited onto the destination device. 0613 */ 0614 void setChannelFlags(QBitArray channelFlags); 0615 0616 /// @return the channel flags 0617 QBitArray channelFlags(); 0618 0619 /** 0620 * Set the paintop preset to use. If @p image is given, 0621 * the paintop will be created using this image as parameter. 0622 * Some paintops really want to know about the image they work 0623 * for, e.g. the clone paintop. 0624 */ 0625 void setPaintOpPreset(KisPaintOpPresetSP preset, KisNodeSP node, KisImageSP image); 0626 0627 /// Return the paintop preset 0628 KisPaintOpPresetSP preset() const; 0629 0630 /** 0631 * Return the active paintop (which is created based on the specified preset and 0632 * will be deleted as soon as the KisPainter instance dies). 0633 */ 0634 KisPaintOp* paintOp() const; 0635 0636 void setMirrorInformation(const QPointF &axesCenter, bool mirrorHorizontally, bool mirrorVertically); 0637 0638 void copyMirrorInformationFrom(const KisPainter *other); 0639 0640 /** 0641 * Returns whether the mirroring methods will do any 0642 * work when called 0643 */ 0644 bool hasMirroring() const; 0645 0646 /** 0647 * Indicates if horizontal mirroring mode is activated 0648 */ 0649 bool hasHorizontalMirroring() const; 0650 0651 /** 0652 * Indicates if vertical mirroring mode is activated 0653 */ 0654 bool hasVerticalMirroring() const; 0655 0656 /** 0657 * Mirror \p rc in the requested \p direction around the center point defined 0658 * in the painter. 0659 */ 0660 void mirrorRect(Qt::Orientation direction, QRect *rc) const; 0661 0662 /** 0663 * Mirror \p dab in the requested direction around the center point defined 0664 * in the painter. The dab's offset is adjusted automatically. 0665 */ 0666 void mirrorDab(Qt::Orientation direction, KisRenderedDab *dab, bool skipMirrorPixels = false) const; 0667 0668 /** 0669 * Calculate the list of the mirrored rects that will be painted on the 0670 * the canvas when calling renderMirrorMask() at al 0671 */ 0672 const QVector<QRect> calculateAllMirroredRects(const QRect &rc); 0673 0674 /** 0675 * Calculate the list of the mirrored points according to the current 0676 * mirroring configuration. 0677 */ 0678 const QVector<QPointF> calculateAllMirroredPoints(const QPointF &pos); 0679 0680 /** 0681 * Calculate the list of the mirrored point pairs according to the current 0682 * mirroring configuration. 0683 */ 0684 const QVector<QPair<QPointF, QPointF>> calculateAllMirroredPoints(const QPair<QPointF, QPointF> &pair); 0685 0686 /// Set the current pattern 0687 void setPattern(const KoPatternSP pattern); 0688 0689 /// Returns the currently set pattern 0690 const KoPatternSP pattern() const; 0691 0692 /** 0693 * Set the color that will be used to paint with, and convert it 0694 * to the color space of the current paint device. 0695 */ 0696 void setPaintColor(const KoColor& color); 0697 0698 /// Returns the color that will be used to paint with 0699 const KoColor &paintColor() const; 0700 0701 /** 0702 * Set the current background color, and convert it 0703 * to the color space of the current paint device. 0704 */ 0705 void setBackgroundColor(const KoColor& color); 0706 0707 /// Returns the current background color 0708 const KoColor &backgroundColor() const; 0709 0710 /// Set the current generator (a generator can be used to fill an area 0711 void setGenerator(KisFilterConfigurationSP generator); 0712 0713 /// @return the current generator configuration 0714 const KisFilterConfigurationSP generator() const; 0715 0716 /// This enum contains the styles with which we can fill things like polygons and ellipses 0717 enum FillStyle { 0718 FillStyleNone, 0719 FillStyleForegroundColor, 0720 FillStyleBackgroundColor, 0721 FillStylePattern, 0722 FillStyleGenerator 0723 }; 0724 0725 /// Set the current style with which to fill 0726 void setFillStyle(FillStyle fillStyle); 0727 0728 /// Returns the current fill style 0729 FillStyle fillStyle() const; 0730 0731 /// Set the transform on the pattern. 0732 void setPatternTransform(QTransform transform); 0733 0734 /// get the current transform on the pattern. 0735 QTransform patternTransform(); 0736 0737 /// Set whether a polygon's filled area should be anti-aliased or not. The default is true. 0738 void setAntiAliasPolygonFill(bool antiAliasPolygonFill); 0739 0740 /// Return whether a polygon's filled area should be anti-aliased or not 0741 bool antiAliasPolygonFill(); 0742 0743 /// The style of the brush stroke around polygons and so 0744 enum StrokeStyle { 0745 StrokeStyleNone, 0746 StrokeStyleBrush 0747 }; 0748 0749 /// Set the current brush stroke style 0750 void setStrokeStyle(StrokeStyle strokeStyle); 0751 0752 /// Returns the current brush stroke style 0753 StrokeStyle strokeStyle() const; 0754 0755 void setFlow(quint8 flow); 0756 0757 quint8 flow() const; 0758 0759 /** 0760 * Sets the opacity of the painting and recalculates the 0761 * mean opacity of the stroke. This mean value is used to 0762 * make ALPHA_DARKEN painting look correct 0763 */ 0764 void setOpacityUpdateAverage(quint8 opacity); 0765 0766 /** 0767 * Sets average opacity, that is used to make ALPHA_DARKEN painting look correct 0768 */ 0769 void setAverageOpacity(qreal averageOpacity); 0770 0771 /** 0772 * Calculate average opacity value after painting a single dab with \p opacity 0773 */ 0774 static qreal blendAverageOpacity(qreal opacity, qreal averageOpacity); 0775 0776 /// Set the opacity which is used in painting (like filling polygons) 0777 void setOpacity(quint8 opacity); 0778 0779 /// Returns the opacity that is used in painting 0780 quint8 opacity() const; 0781 0782 /** 0783 * Set the composite op ID for this painter 0784 * Only kept for convenience, it will just call ::setCompositeOpId(QString) with op->Id(). 0785 */ 0786 void setCompositeOpId(const KoCompositeOp * op); 0787 0788 /// Returns the current composite op Id 0789 QString compositeOpId(); 0790 0791 /// Set the composite op for this painter by string. 0792 void setCompositeOpId(const QString& op); 0793 0794 /** 0795 * Add \p r to the current set of dirty rects 0796 */ 0797 void addDirtyRect(const QRect &r); 0798 0799 /** 0800 * Add \p rects to the current set of dirty rects 0801 */ 0802 void addDirtyRects(const QVector<QRect> &rects); 0803 0804 /** 0805 * Reset the selection to the given selection. All painter actions will be 0806 * masked by the specified selection. 0807 */ 0808 void setSelection(KisSelectionSP selection); 0809 0810 /** 0811 * @return the selection set on this painter. 0812 */ 0813 KisSelectionSP selection(); 0814 0815 void setGradient(const KoAbstractGradientSP gradient); 0816 const KoAbstractGradientSP gradient() const; 0817 0818 /** 0819 * Set the size of the tile in fillPainterPath, useful when optimizing the use of fillPainterPath 0820 * e.g. Spray paintop uses more small tiles, although selections uses bigger tiles. QImage::fill 0821 * is quite expensive so with smaller images you can save instructions 0822 * Default and maximum size is 256x256 image 0823 */ 0824 void setMaskImageSize(qint32 width, qint32 height); 0825 0826 // /** 0827 // * If the alpha channel is locked, the alpha values of the paint device we are painting on 0828 // * will not change. 0829 // */ 0830 // void setLockAlpha(bool protect); 0831 // bool alphaLocked() const; 0832 0833 /** 0834 * set the rendering intent in case pixels need to be converted before painting 0835 */ 0836 void setRenderingIntent(KoColorConversionTransformation::Intent intent); 0837 0838 /** 0839 * set the conversion flags in case pixels need to be converted before painting 0840 */ 0841 void setColorConversionFlags(KoColorConversionTransformation::ConversionFlags conversionFlags); 0842 0843 /** 0844 * Set interface for running asynchronous jobs by paintops. 0845 * 0846 * NOTE: the painter does *not* own the interface device. It is the responsibility 0847 * of the caller to ensure that the interface object is alive during the lifetime 0848 * of the painter. 0849 */ 0850 void setRunnableStrokeJobsInterface(KisRunnableStrokeJobsInterface *interface); 0851 0852 /** 0853 * Get the interface for running asynchronous jobs. It is used by paintops mostly. 0854 */ 0855 KisRunnableStrokeJobsInterface* runnableStrokeJobsInterface() const; 0856 0857 protected: 0858 /// Initialize, set everything to '0' or defaults 0859 void init(); 0860 0861 /// Fill the polygon defined by points with the fillStyle 0862 void fillPolygon(const vQPointF& points, FillStyle fillStyle); 0863 0864 private: 0865 0866 KisPainter(const KisPainter&); 0867 KisPainter& operator=(const KisPainter&); 0868 0869 float frac(float value) { 0870 float tmp = 0; 0871 return modff(value , &tmp); 0872 } 0873 0874 float invertFrac(float value) { 0875 float tmp = 0; 0876 return 1.0f - modff(value , &tmp); 0877 } 0878 0879 protected: 0880 KoUpdater * progressUpdater(); 0881 0882 private: 0883 template <bool useOldSrcData> 0884 void bitBltImpl(qint32 dstX, qint32 dstY, 0885 const KisPaintDeviceSP srcDev, 0886 qint32 srcX, qint32 srcY, 0887 qint32 srcWidth, qint32 srcHeight); 0888 0889 inline void compositeOnePixel(quint8 *dst, const KoColor &color); 0890 0891 private: 0892 0893 struct Private; 0894 Private* const d; 0895 }; 0896 0897 0898 #endif // KIS_PAINTER_H_ 0899