26#include "tqfontinfo.h"
27#include "tqfontmetrics.h"
35#include <tqpointarray.h>
44#include "kis_debug_areas.h"
47#include "kis_paint_device.h"
48#include "kis_painter.h"
49#include "kis_pattern.h"
51#include "kis_colorspace.h"
52#include "kis_transaction.h"
55#include "kis_selection.h"
56#include "kis_fill_painter.h"
57#include "kis_iterators_pixel.h"
58#include "kis_iterator.h"
60#include "kis_selection.h"
68 m_width = m_height = -1;
69 m_sampleMerged = false;
70 m_careForSelection = false;
76 m_width = m_height = -1;
77 m_sampleMerged = false;
78 m_careForSelection = false;
92 TQ_UINT8 * data = kc2. data();
93 m_device->colorSpace()->setAlpha(data, opacity, 1);
95 m_device->fill(x1, y1, w, h, data);
104 if (!m_device) return;
107 KisPaintDeviceSP patternLayer = pattern->image(m_device->colorSpace());
120 sh = TQMIN((y1 + h) - y, pattern->height() - sy);
131 sw = TQMIN((x1 + w) - x, pattern->width() - sx);
133 bitBlt(x, y, m_compositeOp, patternLayer.data(), m_opacity, sx, sy, sw, sh);
146 genericFillStart(startX, startY);
149 KisPaintDeviceSP filled = new KisPaintDevice(m_device->colorSpace(), "filled");
150 TQ_CHECK_PTR(filled);
152 painter. fillRect(0, 0, m_width, m_height, m_paintColor);
155 genericFillEnd(filled);
159 genericFillStart(startX, startY);
162 KisPaintDeviceSP filled = new KisPaintDevice(m_device->colorSpace(), "filled");
163 TQ_CHECK_PTR(filled);
165 painter. fillRect(0, 0, m_width, m_height, m_pattern);
168 genericFillEnd(filled);
171void KisFillPainter::genericFillStart( int startX, int startY) {
172 m_cancelRequested = false;
174 if (m_width < 0 || m_height < 0) {
175 if (m_device->image()) {
176 m_width = m_device->image()->width();
177 m_height = m_device->image()->height();
179 m_width = m_height = 500;
183 m_size = m_width * m_height;
189void KisFillPainter::genericFillEnd(KisPaintDeviceSP filled) {
190 if (m_cancelRequested) {
191 m_width = m_height = -1;
195 TQRect rc = m_selection->selectedRect();
197 bltSelection(rc.x(), rc.y(), m_compositeOp, filled, m_selection, m_opacity,
198 rc.x(), rc.y(), rc.width(), rc.height());
200 emit notifyProgressDone();
202 m_width = m_height = -1;
206 FillSegment( int x, int y) : x(x), y(y) {}
212typedef enum { None = 0, Added = 1, Checked = 2 } Status;
215 if (m_width < 0 || m_height < 0) {
216 if (m_device->hasSelection() && m_careForSelection) {
218 TQRect rc = m_device->selection()->selectedRect();
219 m_width = rc.width() - (startX - rc.x());
220 m_height = rc.height() - (startY - rc.y());
222 } else if (m_device->image()) {
224 m_width = m_device->image()->width();
225 m_height = m_device->image()->height();
228 m_width = m_height = 500;
233 if (startX < 0 || startY < 0 || startX >= m_width || startY >= m_height)
236 KisPaintDeviceSP sourceDevice = 0;
239 if (m_sampleMerged) {
240 if (!m_device->image()) {
243 sourceDevice = m_device->image()->mergedImage();
245 sourceDevice = m_device;
248 m_size = m_width * m_height;
254 TQ_UINT8* source = new TQ_UINT8[sourceDevice->pixelSize()];
257 memcpy(source, pixelIt.rawData(), sourceDevice->pixelSize());
259 std::stack<FillSegment*> stack;
261 stack.push( new FillSegment(startX, startY));
263 Status* map = new Status[m_size];
265 memset(map, None, m_size * sizeof(Status));
267 int progressPercent = 0; int pixelsDone = 0; int currentPercent = 0;
268 emit notifyProgressStage(i18n( "Making fill outline..."), 0);
270 bool hasSelection = m_careForSelection && sourceDevice->hasSelection();
271 KisSelectionSP srcSel = 0;
273 srcSel = sourceDevice->selection();
275 while(!stack.empty()) {
276 FillSegment* segment = stack.top();
278 if (map[m_width * segment->y + segment->x] == Checked) {
282 map[m_width * segment->y + segment->x] = Checked;
289 pixelIt = sourceDevice->createHLineIterator(0, y, m_width, false);
291 TQ_UINT8 diff = devColorSpace-> difference(source, pixelIt.rawData());
293 if (diff >= m_threshold
294 || (hasSelection && srcSel->selected(pixelIt.x(), pixelIt.y()) == MIN_SELECTED)) {
303 colorSpace-> fromTQColor(TQt::white, MAX_SELECTED - diff, selIt.rawData());
305 colorSpace-> fromTQColor(TQt::white, MAX_SELECTED, selIt.rawData());
307 if (y > 0 && (map[m_width * (y - 1) + x] == None)) {
308 map[m_width * (y - 1) + x] = Added;
309 stack.push( new FillSegment(x, y-1));
311 if (y < (m_height - 1) && (map[m_width * (y + 1) + x] == None)) {
312 map[m_width * (y + 1) + x] = Added;
313 stack.push( new FillSegment(x, y+1));
325 while(!stop && x >= 0 && (map[m_width * y + x] != Checked) ) {
326 map[m_width * y + x] = Checked;
327 diff = devColorSpace-> difference(source, pixelIt.rawData());
328 if (diff >= m_threshold
329 || (hasSelection && srcSel->selected(pixelIt.x(), pixelIt.y()) == MIN_SELECTED)) {
335 colorSpace-> fromTQColor(TQt::white, MAX_SELECTED - diff, selIt.rawData());
337 colorSpace-> fromTQColor(TQt::white, MAX_SELECTED, selIt.rawData());
339 if (y > 0 && (map[m_width * (y - 1) + x] == None)) {
340 map[m_width * (y - 1) + x] = Added;
341 stack.push( new FillSegment(x, y-1));
343 if (y < (m_height - 1) && (map[m_width * (y + 1) + x] == None)) {
344 map[m_width * (y + 1) + x] = Added;
345 stack.push( new FillSegment(x, y+1));
356 if (map[m_width * y + x] == Checked)
360 pixelIt = sourceDevice->createHLineIterator(x, y, m_width, false);
361 selIt = selection->createHLineIterator(x, y, m_width, true);
364 while(!stop && x < m_width && (map[m_width * y + x] != Checked) ) {
365 diff = devColorSpace-> difference(source, pixelIt.rawData());
366 map[m_width * y + x] = Checked;
368 if (diff >= m_threshold
369 || (hasSelection && srcSel->selected(pixelIt.x(), pixelIt.y()) == MIN_SELECTED) ) {
375 colorSpace-> fromTQColor(TQt::white, MAX_SELECTED - diff, selIt.rawData());
377 colorSpace-> fromTQColor(TQt::white, MAX_SELECTED, selIt.rawData());
379 if (y > 0 && (map[m_width * (y - 1) + x] == None)) {
380 map[m_width * (y - 1) + x] = Added;
381 stack.push( new FillSegment(x, y-1));
383 if (y < (m_height - 1) && (map[m_width * (y + 1) + x] == None)) {
384 map[m_width * (y + 1) + x] = Added;
385 stack.push( new FillSegment(x, y+1));
394 progressPercent = (pixelsDone * 100) / m_size;
395 if (progressPercent > currentPercent) {
396 emit notifyProgress(progressPercent);
397 currentPercent = progressPercent;
A colorspace is the definition of a certain color model in Chalk.
virtual void fromTQColor(const TQColor &c, TQ_UINT8 *dst, KisProfile *profile=0)=0 The fromTQColor methods take a given color defined as an RGB TQColor and fills a byte array with the ...
virtual TQ_UINT8 difference(const TQ_UINT8 *src1, const TQ_UINT8 *src2)=0 Get the difference between 2 colors, normalized in the range (0,255).
A KisColor describes a color in a certain colorspace.
void convertTo(KisColorSpace *cs) Convert this KisColor to the specified colorspace.
TQ_UINT8 * data() const For easy memcpy'ing etc.
void fillPattern(int startX, int startY) Fills the enclosed area around the point with the set pattern.
KisFillPainter() Construct an empty painter.
KisSelectionSP createFloodSelection(int startX, int startY) Returns a selection mask for the floodfill starting at the specified position.
void fillRect(TQ_INT32 x, TQ_INT32 y, TQ_INT32 w, TQ_INT32 h, const KisColor &c) Fill a rectangle with a certain color.
The pixel iterators are high level iterarators.
A paint device contains the actual pixel data and offers methods to read and write pixels.
TQRect addDirtyRect(TQRect r) Add the r to the current dirty rect, and return the dirtyRect after adding r to it.
KisPattern * pattern() const Returns the currently set pattern.
KCommand * end() Finish painting on the current device.
KisPaintDeviceSP device() const Returns the current paint device.
TQ_UINT8 opacity() const Returns the opacity that is used in painting.
void bitBlt(TQ_INT32 dx, TQ_INT32 dy, const KisCompositeOp &op, KisPaintDeviceSP src, TQ_INT32 sx, TQ_INT32 sy, TQ_INT32 sw, TQ_INT32 sh) Blast the specified region from src onto the current paint device.
KisColor fillColor() const Returns the current fill color.
void bltSelection(TQ_INT32 dx, TQ_INT32 dy, const KisCompositeOp &op, KisPaintDeviceSP src, KisSelectionSP selMask, TQ_UINT8 opacity, TQ_INT32 sx, TQ_INT32 sy, TQ_INT32 sw, TQ_INT32 sh) A version of bitBlt that renders using an external selection mask, ignoring the src device's own sele...
KisSelection contains a byte-map representation of a layer, where the value of a byte signifies wheth...
|