2
votes

How do I get a list of points/coordinates that the drawLine() function affects? For example if I have

QLineF line(10.0, 80.0, 90.0, 20.0);
QPainter(this);
painter.drawLine(line);

I want to get the list of QPoint coordinates that the drawLine() will draw. I'm aware of Bresenham's line algorithm, however I need this to work in a more general case where I can set different QPen and QBrush:

painter.setPen(QPen(myColor, myWidth, Qt::SolidLine, Qt::RoundCap));

I also need it to be consistent with other programs that might draw lines with same end points and parameters, but without Qt, so I want to end up with the same result, and without off-by-one differences.

Note: This is different from this question, because I need ALL pixels that are going to be affected by the drawing function, not just the vertices of polygon/path.

Update: I think it is possible to subclass QImage or QPainterDevice and QPaintEngine to catch all "setPixel()" operations. Could anyone prove otherwise or confirm and maybe even write a short code to do that?

2

2 Answers

2
votes

Not sure of your performance requirements but you could render the line off screen then look at the image to see what pixels were painted. Here's an example that prints the pixels painted between a 3 pixel line on a 400x400 image from 190,190 to 210,210.

When you work with QImage, be sure to use the scanLine() function for performance reasons.

#include <QCoreApplication>
#include <QImage>
#include <QPainter>
#include <QDebug>

int main(int argc, char *argv[])
{
    QImage image(400,400,QImage::Format_ARGB32);
    QPainter painter;
    painter.begin(&image);
    painter.fillRect(0,0,400,400,QBrush(Qt::white));
    QBrush brush(Qt::black);
    QPen pen(brush, 3.0);
    painter.setPen(pen);
    painter.drawLine(190,190,210,210);
    painter.end();

    for (int i=0;i<image.height();i++) {
        const uchar *scanLine = image.scanLine(i);
        for (int j=0;j<image.width()*4;j+=4) {
            if ( scanLine[j] == 0 ) {
                qDebug() << "pixel" << i << j/4 << scanLine[j];
            }
        }
    }

    return (0);
}
0
votes

The exact pixels covered will not necessarily even be consistent within a Qt program. It will be different if you turn on anti-aliasing on the QPainter, it will be different if you draw to a QGLWidget, and it might be different depending on which platform the program is running on, because Qt has different QPaintEngine implementations which do not necessarily produce exactly the same output.

In short, what you're asking for just isn't possible. You can only ever find the pixels covered by a particular paint operation, and you can only do that by taking the approach suggested by mzelina.