Search code examples
performanceqttextmarqueepixmap

How to shift pixels of a pixmap efficient in Qt4


I have implemented a marquee text widget using Qt4. I painted the text content onto a pixmap first. And then paint a portion of this pixmap onto a paint device by calling painter.drawTiledPixmap(offsetX, offsetY, myPixmap)

My Imagination is that, Qt will fill the whole marquee text rectangle with the content from myPixmap.

Is there a ever faster way, to shift all existing content to left by 1px and than fill the newly exposed 1px wide and N-px high area with the content from myPixmap?


Solution

  • Well. This is a trick I used to do with slower hardware back in the old days. Basically, the image buffer is allocated twice as wide as needed with 1 extra line at the beginning. Build the image to the left of the buffer. Then draw the image repeatedly with the buffer advancing 1 pixel at a time in the buffer.

    int w = 200;
    int h = 100;
    int rowBytes = w * sizeof(QRgb) * 2; // line buffer is twice as the width
    QByteArray buffer(rowBytes * (h + 1), 0xFF); // 1 more line than the height
    uchar * p = (uchar*)buffer.data() + rowBytes; // start drawing the image content at 2nd line
    QImage image(p, w, h, rowBytes, QImage::Format_RGB32); // 1st line is used as the padding at the start of scroll
    image.fill(qRgb(255, 0, 0)); // well. do something to the image
    
    p = image.bits() - rowBytes / 2; //  start scrolling at the middle of the 1st (blank) line
    for(int i=0;i<w;++i, p+=sizeof(QRgb)) {
        QImage  scroll(p, w, h, rowBytes, QImage::Format_RGB32); // scrool 1 pixel at a time
        scroll.save(QString("%1.png").arg(i));
    }
    

    I am not sure this will be any faster than just change the offset of the image and draw it strait. The hardware today is really powerful which renders a lot of old tricks useless. But it's fun to play obscure tricks. :)