| Summary: | Gradient fill is slow | ||
|---|---|---|---|
| Product: | [Applications] krita | Reporter: | Robert Knight <robertknight> |
| Component: | General | Assignee: | Halla Rempt <halla> |
| Status: | RESOLVED FIXED | ||
| Severity: | wishlist | ||
| Priority: | NOR | ||
| Version First Reported In: | unspecified | ||
| Target Milestone: | --- | ||
| Platform: | unspecified | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
Robert Knight
2006-01-16 05:14:24 UTC
Not a bug, but a wish. SVN commit 508851 by rempt:
Speedup gradients a lot. This does not introduce colorspace problems because gradients
have always been defined in QColors. For 2.0, we might want to try our hand at L*a*b
gradients :-).
BUG:120223
M +1 -0 core/kis_gradient.h
M +26 -29 core/kis_gradient_painter.cc
M +0 -1 ui/kis_paintop_box.cc
--- trunk/koffice/krita/core/kis_gradient.h #508850:508851
@@ -243,6 +243,7 @@
virtual QImage generatePreview(int width, int height) const;
void colorAt(double t, QColor *color, Q_UINT8 *opacity) const;
+
KisGradientSegment *segmentAt(double t) const;
protected:
--- trunk/koffice/krita/core/kis_gradient_painter.cc #508850:508851
@@ -52,6 +52,8 @@
#include "kis_vec.h"
#include "kis_selection.h"
#include "kis_gradient_painter.h"
+#include "kis_meta_registry.h"
+#include "kis_colorspace_factory_registry.h"
namespace {
@@ -479,7 +481,6 @@
{
}
-// XXX: Use KisColor here instead of QColor
bool KisGradientPainter::paintGradient(const KisPoint& gradientVectorStart,
const KisPoint& gradientVectorEnd,
enumGradientShape shape,
@@ -534,12 +535,8 @@
}
Q_ASSERT(repeatStrategy != 0);
- KisPaintDeviceSP layer = new KisPaintDevice( m_device -> colorSpace(), "gradient layer");
- Q_CHECK_PTR(layer);
-
- KisPainter painter(layer);
-
- //If the device has a selection only iterate of that selection
+
+ //If the device has a selection only iterate over that selection
QRect r;
if( m_device -> hasSelection() ) {
r = m_device -> selection() -> selectedExactRect();
@@ -554,6 +551,9 @@
Q_INT32 endx = startx + width - 1;
Q_INT32 endy = starty + height - 1;
+ QImage layer (width, height, 32);
+ layer.setAlphaBuffer(true);
+
int pixelsProcessed = 0;
int lastProgressPercent = 0;
@@ -566,7 +566,6 @@
}
for (int y = starty; y <= endy; y++) {
- KisHLineIterator iter = layer -> createHLineIterator(startx, y, width, true);
for (int x = startx; x <= endx; x++) {
double t = shapeStrategy -> valueAt( x, y);
@@ -580,8 +579,10 @@
Q_UINT8 opacity;
m_gradient -> colorAt(t, &color, &opacity);
- layer -> colorSpace() -> fromQColor( color, opacity, iter.rawData());
-
+
+ layer.setPixel(x - startx, y - starty,
+ qRgba(color.red(), color.green(), color.blue(), opacity));
+
pixelsProcessed++;
int progressPercent = (pixelsProcessed * 100) / totalPixels;
@@ -594,8 +595,6 @@
break;
}
}
- ++iter;
-
if (m_cancelRequested) {
break;
}
@@ -605,18 +604,15 @@
if (!m_cancelRequested && antiAliasThreshold < 1 - DBL_EPSILON) {
emit notifyProgressStage(i18n("Anti-aliasing gradient..."), lastProgressPercent);
- KisColorSpace * cs = layer->colorSpace();
+ Q_UINT8 * layerPointer = layer.bits();
for (int y = starty; y <= endy; y++) {
- KisHLineIterator iter = layer -> createHLineIterator(startx, y, width, true);
for (int x = startx; x <= endx; x++) {
double maxDistance = 0;
- QColor thisPixel;
- Q_UINT8 thisPixelOpacity;
-
- cs->toQColor(iter.rawData(), &thisPixel, &thisPixelOpacity);
-
+ QColor thisPixel(layerPointer[2], layerPointer[1], layerPointer[0]);
+ Q_UINT8 thisPixelOpacity = layerPointer[3];
+
for (int yOffset = -1; yOffset < 2; yOffset++) {
for (int xOffset = -1; xOffset < 2; xOffset++) {
@@ -625,11 +621,12 @@
int sampleY = y + yOffset;
if (sampleX >= startx && sampleX <= endx && sampleY >= starty && sampleY <= endy) {
- QColor color;
- Q_UINT8 opacity;
-
- layer -> pixel(sampleX, sampleY, &color, &opacity);
-
+ uint x = sampleX - startx;
+ uint y = sampleY - starty;
+ Q_UINT8 * pixelPos = layer.bits() + (y * width * 4) + (x * 4);
+ QColor color(*(pixelPos +2), *(pixelPos + 1), *pixelPos);
+ Q_UINT8 opacity = *(pixelPos + 3);
+
double dRed = (color.red() * opacity - thisPixel.red() * thisPixelOpacity) / 65535.0;
double dGreen = (color.green() * opacity - thisPixel.green() * thisPixelOpacity) / 65535.0;
double dBlue = (color.blue() * opacity - thisPixel.blue() * thisPixelOpacity) / 65535.0;
@@ -686,9 +683,7 @@
int blue = totalBlue / (numSamples * numSamples);
int opacity = totalOpacity / (numSamples * numSamples);
- QColor color(red, green, blue);
-
- cs-> fromQColor( color, opacity, iter.rawData());
+ layer.setPixel(x - startx, y - starty, qRgba(red, green, blue, opacity));
}
pixelsProcessed++;
@@ -703,7 +698,7 @@
break;
}
}
- ++iter;
+ layerPointer += 4;
}
if (m_cancelRequested) {
@@ -713,7 +708,9 @@
}
if (!m_cancelRequested) {
- bltSelection(startx, starty, m_compositeOp, layer.data(), m_opacity, startx, starty, width, height);
+ KisPaintDeviceSP dev = new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temporary device for gradient");
+ dev->writeBytes(layer.bits(), startx, starty, width, height);
+ bltSelection(startx, starty, m_compositeOp, dev, m_opacity, startx, starty, width, height);
}
delete shapeStrategy;
--- trunk/koffice/krita/ui/kis_paintop_box.cc #508850:508851
@@ -234,7 +234,6 @@
}
const int index = m_paintops->findIndex(paintop);
- Q_ASSERT(index >= 0 && index < (int)settingsArray.count());
if (index >= 0 && index < (int)settingsArray.count())
return settingsArray[index];
else
|