Commit 9dbde0d0 authored by Mathias Wein's avatar Mathias Wein

Implement optimized renderBackground() for elliptical selector shape

Uses a simple integer radius check to skip pixels outside the mask.
Also do antialiased outline rendering here instead of redoing
on every cursor movement.
parent 0cb1e86e
......@@ -23,6 +23,7 @@
#include <QPainterPath>
#include <QRect>
#include <QVector>
#include <QVector4D>
#include <QVBoxLayout>
#include <QList>
#include <QPolygon>
......@@ -66,6 +67,8 @@ QSize KisVisualEllipticalSelectorShape::sizeHint() const
void KisVisualEllipticalSelectorShape::setBorderWidth(int width)
{
m_barWidth = width;
forceImageUpdate();
update();
}
QRect KisVisualEllipticalSelectorShape::getSpaceForSquare(QRect geom)
......@@ -178,18 +181,51 @@ QRegion KisVisualEllipticalSelectorShape::getMaskMap()
return mask;
}
void KisVisualEllipticalSelectorShape::drawCursor()
QImage KisVisualEllipticalSelectorShape::renderBackground(const QVector4D &channelValues, quint32 pixelSize) const
{
//qDebug() << this << "KisVisualEllipticalSelectorShape::drawCursor: image needs update" << imagesNeedUpdate();
QPointF cursorPoint = convertShapeCoordinateToWidgetCoordinate(getCursorPosition());
QImage fullSelector = getImageMap();
QColor col = getColorFromConverter(getCurrentColor());
QPainter painter;
painter.begin(&fullSelector);
painter.setRenderHint(QPainter::Antialiasing);
QRect innerRect(m_barWidth, m_barWidth, width()-(m_barWidth*2), height()-(m_barWidth*2));
const KisVisualColorSelector *selector = qobject_cast<KisVisualColorSelector*>(parent());
Q_ASSERT(selector);
// optimization assumes widget is (close to) square, but should still render correctly as ellipse
int rMaxSquare = qRound(qMax(width(), height()) * 0.5f + 0.5f);
rMaxSquare *= rMaxSquare;
int rMinSquare = 0;
if (getDimensions() == Dimensions::onedimensional)
{
rMinSquare = qMax(0, qRound(qMin(width(), height()) * 0.5f - m_barWidth));
rMinSquare *= rMinSquare;
}
int cx = width()/2;
int cy = height()/2;
painter.save();
// Fill a buffer with the right kocolors
quint32 imageSize = width() * height() * pixelSize;
QScopedArrayPointer<quint8> raw(new quint8[imageSize] {});
quint8 *dataPtr = raw.data();
bool is2D = (getDimensions() == Dimensions::twodimensional);
QVector4D coordinates = channelValues;
QVector<int> channels = getChannels();
for (int y = 0; y < height(); y++) {
int dy = y - cy;
for (int x=0; x < width(); x++) {
int dx = x - cx;
int radSquare = dx*dx + dy*dy;
if (radSquare >= rMinSquare && radSquare < rMaxSquare)
{
QPointF newcoordinate = convertWidgetCoordinateToShapeCoordinate(QPoint(x, y));
coordinates[channels.at(0)] = newcoordinate.x();
if (is2D){
coordinates[channels.at(1)] = newcoordinate.y();
}
KoColor c = selector->convertShapeCoordsToKoColor(coordinates);
memcpy(dataPtr, c.data(), pixelSize);
}
dataPtr += pixelSize;
}
}
QImage image = convertImageMap(raw.data(), imageSize);
// cleanup edges by erasing with antialiased circles
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing);
painter.setCompositionMode(QPainter::CompositionMode_Clear);
QPen pen;
pen.setWidth(5);
......@@ -197,11 +233,23 @@ void KisVisualEllipticalSelectorShape::drawCursor()
painter.drawEllipse(QRect(0,0,width(),height()));
if (getDimensions()==KisVisualColorSelectorShape::onedimensional) {
QRect innerRect(m_barWidth, m_barWidth, width()-(m_barWidth*2), height()-(m_barWidth*2));
painter.setBrush(Qt::SolidPattern);
painter.drawEllipse(innerRect);
}
painter.restore();
return image;
}
void KisVisualEllipticalSelectorShape::drawCursor()
{
//qDebug() << this << "KisVisualEllipticalSelectorShape::drawCursor: image needs update" << imagesNeedUpdate();
QPointF cursorPoint = convertShapeCoordinateToWidgetCoordinate(getCursorPosition());
QImage fullSelector = getImageMap();
QColor col = getColorFromConverter(getCurrentColor());
QPainter painter;
painter.begin(&fullSelector);
painter.setRenderHint(QPainter::Antialiasing);
QRect innerRect(m_barWidth, m_barWidth, width()-(m_barWidth*2), height()-(m_barWidth*2));
QBrush fill;
fill.setStyle(Qt::SolidPattern);
......
......@@ -56,6 +56,8 @@ public:
QRect getSpaceForCircle(QRect geom) override;
QRect getSpaceForTriangle(QRect geom) override;
protected:
virtual QImage renderBackground(const QVector4D &channelValues, quint32 pixelSize) const override;
private:
QPointF convertShapeCoordinateToWidgetCoordinate(QPointF coordinate) const override;
QPointF convertWidgetCoordinateToShapeCoordinate(QPoint coordinate) const override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment