kdeui: KPixmap from QPixmap constructor optimization

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-11-09 01:40:39 +02:00
parent b9169a25a5
commit 28ae883aeb

View file

@ -86,12 +86,48 @@ KPixmap::KPixmap(const QPixmap &pixmap)
d->handle = XNone;
return;
}
// TODO: optimize
QPixmap tempPix = QPixmap::fromX11Pixmap(d->handle, QPixmap::ExplicitlyShared);
tempPix.fill(Qt::transparent);
QPainter p(&tempPix);
p.drawPixmap(QPoint(0, 0), pixmap);
p.end();
// this is sub-optimal but pixmaps are usually small (e.g. 32x32)
QImage qimage = pixmap.toImage();
if (qimage.depth() != 32) {
qimage = qimage.convertToFormat(QImage::Format_ARGB32);
}
// qimage.save("/tmp/kpixmap.kat", "KAT");
XImage* x11image = XCreateImage(
QX11Info::display(), (Visual*)QX11Info::appVisual(),
qimage.depth(),
ZPixmap,
0, NULL, // offset and data
qimage.width(), qimage.height(),
32,
0 // bytes per line
);
if (Q_UNLIKELY(!x11image)) {
kWarning(240) << "Could not create image";
XFreePixmap(QX11Info::display(), d->handle);
d->handle = XNone;
return;
}
x11image->data = static_cast<char*>(::malloc(size_t(x11image->bytes_per_line) * x11image->height));
if (Q_UNLIKELY(!x11image->data)) {
kWarning(240) << "Could not allocate image data";
XDestroyImage(x11image);
XFreePixmap(QX11Info::display(), d->handle);
d->handle = XNone;
return;
}
for (int h = 0; h < qimage.height(); h++) {
for (int w = 0; w < qimage.width(); w++) {
const QRgb qpixel = qimage.pixel(w, h);
XPutPixel(x11image, w, h, qpixel);
}
}
GC x11gc = XCreateGC(QX11Info::display(), d->handle, 0, 0);
XPutImage(QX11Info::display(), d->handle, x11gc, x11image, 0, 0, 0, 0, x11image->width, x11image->height);
XFreeGC(QX11Info::display(), x11gc);
XDestroyImage(x11image);
d->size = pixmap.size();
}
}
@ -172,12 +208,11 @@ QImage KPixmap::toImage() const
kWarning(240) << "Could not get image";
return QImage();
}
// this is sub-optimal but pixmaps are usually small (e.g. 32x32)
QImage qimage(d->size, QImage::Format_ARGB32);
for (int h = 0; h < x11image->height; h++) {
for (int w = 0; w < x11image->width; w++) {
const uint xpixel = XGetPixel(x11image, w, h);
qimage.setPixel(w, h, xpixel);
const uint x11pixel = XGetPixel(x11image, w, h);
qimage.setPixel(w, h, x11pixel);
}
}
// qimage.save("/tmp/kpixmap.kat", "KAT");