summaryrefslogtreecommitdiffstats
path: root/chalk/core/kis_brush.h
blob: 5ee21881b2b162f9edda405512458943a4ebb9e9 (plain)
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
/*
 *  Copyright (c) 1999 Matthias Elter  <me@kde.org>
 *  Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
 *  Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
 *
 *  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_BRUSH_
#define KIS_BRUSH_

#include <tqcstring.h>
#include <tqstring.h>
#include <tqsize.h>
#include <tqimage.h>
#include <tqvaluevector.h>

#include <kio/job.h>

#include "kis_resource.h"
#include "kis_types.h"
#include "kis_point.h"
#include "kis_alpha_mask.h"
#include "koffice_export.h"
#include "kis_boundary.h"
#include "kis_paintop.h"

class TQPoint;
class TQPixmap;
class KisBoundary;
class KisColorSpace;
class TQIODevice;

enum enumBrushType {
    INVALID,
    MASK,
    IMAGE,
    PIPE_MASK,
    PIPE_IMAGE,
    AIRBRUSH
};

class KRITACORE_EXPORT KisBrush : public KisResource {
    typedef KisResource super;
    Q_OBJECT
  

public:
    /// Construct brush to load filename later as brush
    KisBrush(const TQString& filename);
    /// Load brush from the specified data, at position dataPos, and set the filename
    KisBrush(const TQString& filename,
         const TQByteArray & data,
         TQ_UINT32 & dataPos);
    /// Load brush from the specified paint device, in the specified region
    KisBrush(KisPaintDevice* image, int x, int y, int w, int h);
    /// Load brush as a copy from the specified TQImage (handy when you need to copy a brush!)
    KisBrush(const TQImage& image, const TQString& name = TQString(""));

    virtual ~KisBrush();

    virtual bool load();
    /// synchronous, doesn't emit any signal (none defined!)
    virtual bool save();
    virtual TQImage img();
    virtual bool saveToDevice(TQIODevice* dev) const;

    /**
       @return a mask computed from the grey-level values of the
       pixels in the brush.
    */
    virtual KisAlphaMaskSP mask(const KisPaintInformation& info,
                                double subPixelX = 0, double subPixelY = 0) const;
    // XXX: return non-tiled simple buffer
    virtual KisPaintDeviceSP image(KisColorSpace * colorSpace, const KisPaintInformation& info,
                             double subPixelX = 0, double subPixelY = 0) const;

    void setHotSpot(KisPoint);
    KisPoint hotSpot(const KisPaintInformation& info = KisPaintInformation()) const;

    void setSpacing(double s) { m_spacing = s; }
    double spacing() const { return m_spacing; }
    double xSpacing(double pressure = PRESSURE_DEFAULT) const;
    double ySpacing(double pressure = PRESSURE_DEFAULT) const;

    // Dimensions in pixels of the mask/image at a given pressure.
    TQ_INT32 maskWidth(const KisPaintInformation& info) const;
    TQ_INT32 maskHeight(const KisPaintInformation& info) const;

    virtual void setUseColorAsMask(bool useColorAsMask) { m_useColorAsMask = useColorAsMask; }
    virtual bool useColorAsMask() const { return m_useColorAsMask; }
    virtual bool hasColor() const;

    virtual void makeMaskImage();
    TQ_INT32 width() const;
    TQ_INT32 height() const;

    virtual enumBrushType brushType() const;

    //TQImage outline(double pressure = PRESSURE_DEFAULT);
    virtual KisBoundary boundary();

    /**
     * Returns true if this brush can return something useful for the info. This is used
     * by Pipe Brushes that can't paint sometimes
     **/
    virtual bool canPaintFor(const KisPaintInformation& /*info*/) { return true; }

    virtual KisBrush* clone() const;

protected:
    void setWidth(TQ_INT32 w);
    void setHeight(TQ_INT32 h);
    void setImage(const TQImage& img);
    void setBrushType(enumBrushType type) { m_brushType = type; };
    static double scaleForPressure(double pressure);

private:
    class ScaledBrush {
    public:
        ScaledBrush();
        ScaledBrush(KisAlphaMaskSP scaledMask, const TQImage& scaledImage, double scale, double xScale, double yScale);

        double scale() const { return m_scale; }
        double xScale() const { return m_xScale; }
        double yScale() const { return m_yScale; }
        KisAlphaMaskSP mask() const { return m_mask; }
        TQImage image() const { return m_image; }

    private:
        KisAlphaMaskSP m_mask;
        TQImage m_image;
        double m_scale;
        double m_xScale;
        double m_yScale;
    };


    bool init();
    bool initFromPaintDev(KisPaintDevice* image, int x, int y, int w, int h);
    void createScaledBrushes() const;

    KisAlphaMaskSP scaleMask(const ScaledBrush *srcBrush, double scale, double subPixelX, double subPixelY) const;
    TQImage scaleImage(const ScaledBrush *srcBrush, double scale, double subPixelX, double subPixelY) const;

    static TQImage scaleImage(const TQImage& srcImage, int width, int height);
    static TQImage interpolate(const TQImage& image1, const TQImage& image2, double t);

    static KisAlphaMaskSP scaleSinglePixelMask(double scale, TQ_UINT8 maskValue, double subPixelX, double subPixelY);
    static TQImage scaleSinglePixelImage(double scale, TQRgb pixel, double subPixelX, double subPixelY);

    // Find the scaled brush(es) nearest to the given scale.
    void findScaledBrushes(double scale, const ScaledBrush **aboveBrush, const ScaledBrush **belowBrush) const;

    // Initialize our boundary
    void generateBoundary();

    TQByteArray m_data;
    bool m_ownData;
    KisPoint m_hotSpot;
    double m_spacing;
    bool m_useColorAsMask;
    bool m_hasColor;
    TQImage m_img;
    mutable TQValueVector<ScaledBrush> m_scaledBrushes;

    TQ_INT32 m_width;
    TQ_INT32 m_height;

    TQ_UINT32 m_header_size;  /*  header_size = sizeof (BrushHeader) + brush name  */
    TQ_UINT32 m_version;      /*  brush file version #  */
    TQ_UINT32 m_bytes;        /*  depth of brush in bytes */
    TQ_UINT32 m_magic_number; /*  GIMP brush magic number  */

    enumBrushType m_brushType;

    KisBoundary* m_boundary;

};
#endif // KIS_BRUSH_