File indexing completed on 2024-12-22 04:13:00

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_TOOL_FREEHAND_HELPER_H
0008 #define __KIS_TOOL_FREEHAND_HELPER_H
0009 
0010 #include <QObject>
0011 #include <QVector>
0012 
0013 #include "kis_types.h"
0014 #include "kritaui_export.h"
0015 #include <brushengine/kis_paint_information.h>
0016 #include "kis_default_bounds.h"
0017 #include <brushengine/kis_paintop_settings.h>
0018 #include "kis_smoothing_options.h"
0019 #include "kundo2magicstring.h"
0020 
0021 
0022 class KoPointerEvent;
0023 class KoCanvasResourceProvider;
0024 class KisPaintingInformationBuilder;
0025 class KisStrokesFacade;
0026 class KisPostExecutionUndoAdapter;
0027 class KisPaintOp;
0028 class KisFreehandStrokeInfo;
0029 
0030 
0031 class KRITAUI_EXPORT KisToolFreehandHelper : public QObject
0032 {
0033     Q_OBJECT
0034 
0035 public:
0036 
0037     KisToolFreehandHelper(KisPaintingInformationBuilder *infoBuilder,
0038                           KoCanvasResourceProvider *resourceManager,
0039                           const KUndo2MagicString &transactionText = KUndo2MagicString(),
0040                           KisSmoothingOptions *smoothingOptions = 0);
0041     ~KisToolFreehandHelper() override;
0042 
0043     void setSmoothness(KisSmoothingOptionsSP smoothingOptions);
0044     KisSmoothingOptionsSP smoothingOptions() const;
0045 
0046     bool isRunning() const;
0047 
0048     void cursorMoved(const QPointF &cursorPos);
0049 
0050     /**
0051      * @param event The event
0052      * @param pixelCoords The position of the KoPointerEvent, in pixel coordinates.
0053      * @param resourceManager The canvas resource manager
0054      * @param image The image
0055      * @param currentNode The current node
0056      * @param strokesFacade The strokes facade
0057      * @param overrideNode The override node
0058      * @param bounds The bounds
0059      */
0060     void initPaint(KoPointerEvent *event,
0061                    const QPointF &pixelCoords,
0062                    KisImageWSP image,
0063                    KisNodeSP currentNode,
0064                    KisStrokesFacade *strokesFacade,
0065                    KisNodeSP overrideNode = 0,
0066                    KisDefaultBoundsBaseSP bounds = 0);
0067     void paintEvent(KoPointerEvent *event);
0068     void endPaint();
0069 
0070     KisOptimizedBrushOutline paintOpOutline(const QPointF &savedCursorPos,
0071                                             const KoPointerEvent *event,
0072                                             const KisPaintOpSettingsSP globalSettings,
0073                                             KisPaintOpSettings::OutlineMode mode) const;
0074 
0075 Q_SIGNALS:
0076     /**
0077      * The signal is emitted when the outline should be updated
0078      * explicitly by the tool. Used by Stabilizer option, because it
0079      * paints on internal timer events instead of the on every paint()
0080      * event
0081      */
0082     void requestExplicitUpdateOutline();
0083 
0084 protected:
0085     void cancelPaint();
0086     int elapsedStrokeTime() const;
0087 
0088     void initPaintImpl(qreal startAngle,
0089                        const KisPaintInformation &pi,
0090                        KoCanvasResourceProvider *resourceManager,
0091                        KisImageWSP image,
0092                        KisNodeSP node,
0093                        KisStrokesFacade *strokesFacade,
0094                        KisNodeSP overrideNode = 0,
0095                        KisDefaultBoundsBaseSP bounds = 0);
0096 
0097     KoCanvasResourceProvider *resourceManager() const;
0098 
0099 protected:
0100 
0101     virtual void createPainters(QVector<KisFreehandStrokeInfo*> &strokeInfos,
0102                                 const KisDistanceInformation &startDist);
0103 
0104     // lo-level methods for painting primitives
0105 
0106     void paintAt(int strokeInfoId, const KisPaintInformation &pi);
0107 
0108     void paintLine(int strokeInfoId,
0109                    const KisPaintInformation &pi1,
0110                    const KisPaintInformation &pi2);
0111 
0112     void paintBezierCurve(int strokeInfoId,
0113                           const KisPaintInformation &pi1,
0114                           const QPointF &control1,
0115                           const QPointF &control2,
0116                           const KisPaintInformation &pi2);
0117 
0118     // hi-level methods for painting primitives
0119 
0120     virtual void paintAt(const KisPaintInformation &pi);
0121 
0122     virtual void paintLine(const KisPaintInformation &pi1,
0123                            const KisPaintInformation &pi2);
0124 
0125     virtual void paintBezierCurve(const KisPaintInformation &pi1,
0126                                   const QPointF &control1,
0127                                   const QPointF &control2,
0128                                   const KisPaintInformation &pi2);
0129 
0130 private:
0131     void paint(KisPaintInformation &info);
0132     void paintBezierSegment(KisPaintInformation pi1, KisPaintInformation pi2,
0133                                                    QPointF tangent1, QPointF tangent2);
0134 
0135     void stabilizerStart(KisPaintInformation firstPaintInfo);
0136     void stabilizerEnd();
0137     KisPaintInformation getStabilizedPaintInfo(const QQueue<KisPaintInformation> &queue,
0138                                                const KisPaintInformation &lastPaintInfo);
0139     int computeAirbrushTimerInterval() const;
0140 
0141     qreal currentZoom() const;
0142     qreal currentPhysicalZoom() const;
0143 
0144 private Q_SLOTS:
0145     void finishStroke();
0146     void doAirbrushing();
0147     void stabilizerPollAndPaint();
0148     void slotSmoothingTypeChanged();
0149 
0150 private:
0151     struct Private;
0152     Private * const m_d;
0153 };
0154 
0155 #endif /* __KIS_TOOL_FREEHAND_HELPER_H */