summaryrefslogtreecommitdiffstats
path: root/chalk/core/kis_imagepipe_brush.h
blob: 075071b944aa5baff89a4e5978502fb581d1c088 (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
/*
 *  Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
 *  Copyright (c) 2005 Bart Coppens <kde@bartcoppens.be>
 *
 *  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_IMAGEPIPE_BRUSH_
#define KIS_IMAGEPIPE_BRUSH_

#include <tqptrlist.h>
#include <tqvaluelist.h>
#include <tqvaluevector.h>
#include <tqmap.h>
#include <tqstring.h>

#include <tdeio/job.h>

#include "kis_resource.h"
#include "kis_brush.h"
#include "kis_global.h"

class TQCString;
class TQImage;
class TQPoint;
class TQSize;

/**
 * The parasite info that gets loaded from the terribly documented gimp pipe brush parasite.
 * We only store data we actually use.
 * BC: How it seems the dimension stuff interacts with rank, selectionMode and the actual
 * selection of a brush to be drawn. So apparantly you can have at most 4 'dimensions'.
 * Each dimension has a number of brushes, the rank. Each dimension has an associated selection
 * mode and placement mode (which we don't use). The selection mode says us in which way
 * which of the brushes or brush sets will be selected. In the case of a 1-dimensional pipe
 * brush it is easy.
 * However, when there are more dimensions it is a bit harder. You can according to the gimp
 * source maximally use 4 dimensions. When you want to select a brush, you first go to the
 * first dimension. Say it has a rank of 2. The code chooses one of the 2 according to the
 * selection mode. Say we choose 2. Then the currentBrush will skip over all the brushes
 * from the first element in dimension 1. Then in dimension we pick again from the choices
 * we have in dimension 2. We again add the appropriate amount to currentBrush. And so on,
 * until we have reached dimension dim. Or at least, that is how it looks like, we'll know
 * for sure when we can test it better with >1 dim brushes and Angular selectionMode.
 **/
class KisPipeBrushParasite {
public:
    /// Set some default values
    KisPipeBrushParasite() : ncells(0), dim(0), needsMovement(false) {
        for (int i = 0; i < MaxDim; i++) {
            rank[i] = index[i] = brushesCount[i] = 0;
            selection[i] = Constant;
        }
    }
    /// Initializes the brushesCount helper
    void setBrushesCount();
    /// Load the parasite from the source string
    KisPipeBrushParasite(const TQString& source);
    /**
     * Saves a GIMP-compatible representation of this parasite to the device. Also writes the
     * number of brushes (== ncells) (no trailing '\n') */
    bool saveToDevice(TQIODevice* dev) const;

    /** Velocity won't be supported, atm Angular and Tilt aren't either, but have chances of implementation */
    enum SelectionMode {
        Constant, Incremental, Angular, Velocity, Random, Pressure, TiltX, TiltY
    };
    enum Placement { DefaultPlacement, ConstantPlacement, RandomPlacement };
    static int const MaxDim = 4;
    //TQ_INT32 step;
    TQ_INT32 ncells;
    TQ_INT32 dim;
    // Apparantly only used for editing a pipe brush, which we won't at the moment
    // TQ_INT32 cols, rows;
    // TQ_INT32 cellwidth, cellheight;
    // Aparantly the gimp doesn't use this anymore? Anyway it is a bit weird to
    // paint at someplace else than where your cursor displays it will...
    //Placement placement;
    TQ_INT32 rank[MaxDim];
    SelectionMode selection[MaxDim];
    /// The total count of brushes in each dimension (helper)
    TQ_INT32 brushesCount[MaxDim];
    /// The current index in each dimension, so that the selection modes know where to start
    TQ_INT32 index[MaxDim];
    /// If true, the brush won't be painted when there is no motion
    bool needsMovement;
};


class KisImagePipeBrush : public KisBrush {
    typedef KisBrush super;
    Q_OBJECT
  

public:
    KisImagePipeBrush(const TQString& filename);
    /**
     * Specialized constructor that makes a new pipe brush from a sequence of samesize
     * devices. The fact that it's a vector of a vector, is to support multidimensional
     * brushes (not yet supported!) */
    KisImagePipeBrush(const TQString& name, int w, int h,
                      TQValueVector< TQValueVector<KisPaintDevice*> > devices,
                      TQValueVector<KisPipeBrushParasite::SelectionMode> modes);
    virtual ~KisImagePipeBrush();

    virtual bool load();
    virtual bool save();
    /// Will call KisBrush's saveToDevice as well
    virtual bool saveToDevice(TQIODevice* dev) const;

    /**
      @return the next image in the pipe.
      */
    virtual TQImage img();

    /**
       @return the next mask in the pipe.
    */
    virtual KisAlphaMaskSP mask(const KisPaintInformation& info,
                                double subPixelX = 0, double subPixelY = 0) const;
    virtual KisPaintDeviceSP image(KisColorSpace * colorSpace, const KisPaintInformation& info,
                             double subPixelX = 0, double subPixelY = 0) const;

    virtual bool useColorAsMask() const;
    virtual void setUseColorAsMask(bool useColorAsMask);
    virtual bool hasColor() const;

    virtual enumBrushType brushType() const;
    
    virtual KisBoundary boundary();
    
    KisPipeBrushParasite const& parasite() const { return m_parasite; }
    
    virtual bool canPaintFor(const KisPaintInformation& info);

    virtual void makeMaskImage();

    virtual KisImagePipeBrush* clone() const;

private:
    bool init();
    void setParasiteString(const TQString& parasite);
    void selectNextBrush(const KisPaintInformation& info) const;

    TQString m_name;
    TQString m_parasiteString; // Contains instructions on how to use the brush
    mutable KisPipeBrushParasite m_parasite;
    TQ_UINT32 m_numOfBrushes;
    mutable TQ_UINT32 m_currentBrush;

    TQByteArray m_data;
    mutable TQPtrList<KisBrush> m_brushes;

    enumBrushType m_brushType;
    
};

#endif // KIS_IMAGEPIPE_BRUSH_