1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the painting module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
// Uncomment the next line to enable the MIT Shared Memory extension
31
// WARNING: This has some problems:
33
// 1. Consumes a 800x600 pixmap
34
// 2. Qt does not handle the ShmCompletion message, so you will
35
// get strange effects if you xForm() repeatedly.
39
#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
43
#include "qplatformdefs.h"
45
#include "qiodevice.h"
46
#include "qpixmap_p.h"
48
#include "qcolormap.h"
51
#include "qapplication.h"
52
#include <private/qpaintengine_x11_p.h>
53
#include <private/qt_x11_p.h>
54
#include "qx11info_x11.h"
55
#include <private/qdrawhelper_p.h>
60
#if defined(Q_CC_MIPS)
61
# define for if(0){}else for
65
// image->data does not belong to X11, so we must free it ourselves.
67
inline static void qSafeXDestroyImage(XImage *x)
76
QBitmap QPixmapData::mask_to_bitmap() const
81
GC gc = XCreateGC(X11->display, bm.data->hd, 0, 0);
82
XCopyArea(X11->display, x11_mask, bm.data->hd, gc, 0, 0, bm.data->w, bm.data->h, 0, 0);
83
XFreeGC(X11->display, gc);
87
Qt::HANDLE QPixmapData::bitmap_to_mask(const QBitmap &bitmap, int screen)
92
bm.x11SetScreen(screen);
94
Pixmap mask = XCreatePixmap(X11->display, RootWindow(X11->display, screen),
95
bm.data->w, bm.data->h, 1);
96
GC gc = XCreateGC(X11->display, mask, 0, 0);
97
XCopyArea(X11->display, bm.data->hd, mask, gc, 0, 0, bm.data->w, bm.data->h, 0, 0);
98
XFreeGC(X11->display, gc);
103
/*****************************************************************************
104
MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
105
*****************************************************************************/
107
#if defined(QT_MITSHM)
109
static bool xshminit = false;
110
static XShmSegmentInfo xshminfo;
111
static XImage *xshmimg = 0;
112
static Pixmap xshmpm = 0;
114
static void qt_cleanup_mitshm()
118
Display *dpy = QX11Info::appDisplay();
120
XFreePixmap(dpy, xshmpm);
123
XShmDetach(dpy, &xshminfo); xshmimg->data = 0;
124
qSafeXDestroyImage(xshmimg); xshmimg = 0;
125
shmdt(xshminfo.shmaddr);
126
shmctl(xshminfo.shmid, IPC_RMID, 0);
129
static bool qt_create_mitshm_buffer(const QPaintDevice* dev, int w, int h)
131
static int major, minor;
132
static Bool pixmaps_ok;
133
Display *dpy = dev->data->xinfo->display();
134
int dd = dev->x11Depth();
135
Visual *vis = (Visual*)dev->x11Visual();
140
if (!XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok))
141
return false; // MIT Shm not supported
142
qAddPostRoutine(qt_cleanup_mitshm);
146
xshmimg = XShmCreateImage(dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h);
151
xshminfo.shmid = shmget(IPC_PRIVATE,
152
xshmimg->bytes_per_line * xshmimg->height,
154
ok = xshminfo.shmid != -1;
156
xshmimg->data = (char*)shmat(xshminfo.shmid, 0, 0);
157
xshminfo.shmaddr = xshmimg->data;
158
ok = (xshminfo.shmaddr != (char*)-1);
160
xshminfo.readOnly = false;
162
ok = XShmAttach(dpy, &xshminfo);
164
qSafeXDestroyImage(xshmimg);
166
if (xshminfo.shmaddr)
167
shmdt(xshminfo.shmaddr);
168
if (xshminfo.shmid != -1)
169
shmctl(xshminfo.shmid, IPC_RMID, 0);
173
xshmpm = XShmCreatePixmap(dpy, DefaultRootWindow(dpy), xshmimg->data,
174
&xshminfo, w, h, dd);
181
// If extern, need a dummy.
183
// static bool qt_create_mitshm_buffer(QPaintDevice*, int, int)
191
/*****************************************************************************
193
*****************************************************************************/
195
extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
197
// Returns position of highest bit set or -1 if none
198
static int highest_bit(uint v)
201
uint b = (uint)1 << 31;
202
for (i=31; ((b & v) == 0) && i>=0; i--)
207
// Returns position of lowest set bit in 'v' as an integer (0-31), or -1
208
static int lowest_bit(uint v)
213
for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1);
214
return i==32 ? -1 : i;
217
// Counts the number of bits set in 'v'
218
static uint n_bits(uint v)
228
static uint *red_scale_table = 0;
229
static uint *green_scale_table = 0;
230
static uint *blue_scale_table = 0;
232
static void cleanup_scale_tables()
234
delete[] red_scale_table;
235
delete[] green_scale_table;
236
delete[] blue_scale_table;
240
Could do smart bitshifting, but the "obvious" algorithm only works for
241
nBits >= 4. This is more robust.
243
static void build_scale_table(uint **table, uint nBits)
246
qWarning("build_scale_table: internal error, nBits = %i", nBits);
250
static bool firstTable = true;
252
qAddPostRoutine(cleanup_scale_tables);
255
*table = new uint[256];
257
int maxVal = (1 << nBits) - 1;
258
int valShift = 8 - nBits;
260
for(i = 0 ; i < maxVal + 1 ; i++)
261
(*table)[i << valShift] = i*255/maxVal;
264
static int defaultScreen = -1;
266
/*****************************************************************************
267
QPixmap member functions
268
*****************************************************************************/
270
static int qt_pixmap_serial = 0;
271
int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
275
Initializes the pixmap data.
277
void QPixmap::init(int w, int h, Type type)
279
if (qApp->type() == QApplication::Tty) {
280
qWarning("QPixmap: Cannot create a QPixmap when no GUI "
284
data = new QPixmapData;
285
memset(data, 0, sizeof(QPixmapData));
289
data->ser_no = ++qt_pixmap_serial;
293
if (defaultScreen >= 0 && defaultScreen != data->xinfo.screen()) {
294
QX11InfoData* xd = data->xinfo.getX11Data(true);
295
xd->screen = defaultScreen;
296
xd->depth = QX11Info::appDepth(xd->screen);
297
xd->cells = QX11Info::appCells(xd->screen);
298
xd->colormap = QX11Info::appColormap(xd->screen);
299
xd->defaultColormap = QX11Info::appDefaultColormap(xd->screen);
300
xd->visual = (Visual *)QX11Info::appVisual(xd->screen);
301
xd->defaultVisual = QX11Info::appDefaultVisual(xd->screen);
302
data->xinfo.setX11Data(xd);
305
int dd = ((X11->use_xrender) ? 32 : data->xinfo.depth());
307
if (qt_x11_preferred_pixmap_depth)
308
dd = qt_x11_preferred_pixmap_depth;
310
bool make_null = w == 0 || h == 0; // create null pixmap
311
data->d = (type == PixmapType) ? dd : 1;
312
if (make_null || w < 0 || h < 0 || data->d == 0) {
316
qWarning("QPixmap: Invalid pixmap parameters");
321
data->hd = (Qt::HANDLE)XCreatePixmap(data->xinfo.display(),
322
RootWindow(data->xinfo.display(),
323
data->xinfo.screen()),
326
#ifndef QT_NO_XRENDER
327
if (X11->use_xrender) {
328
if (qt_x11_preferred_pixmap_depth)
329
data->picture = XRenderCreatePicture(X11->display, data->hd,
330
XRenderFindVisualFormat(X11->display, (Visual *) data->xinfo.visual()), 0, 0);
332
data->picture = XRenderCreatePicture(X11->display, data->hd,
333
XRenderFindStandardFormat(X11->display, data->d == 1
334
? PictStandardA1 : PictStandardARGB32), 0, 0);
336
#endif // QT_NO_XRENDER
339
QPixmapData::~QPixmapData()
344
XFreePixmap(X11->display, x11_mask);
349
#ifndef QT_NO_XRENDER
351
XRenderFreePicture(X11->display, picture);
354
#endif // QT_NO_XRENDER
357
XFreePixmap(xinfo.display(), hd2);
360
XFreePixmap(xinfo.display(), hd);
368
This is a special-purpose function that detaches the pixmap from
371
A pixmap is automatically detached by Qt whenever its contents are
372
about to change. This is done in all QPixmap member functions that
373
modify the pixmap (fill(), resize(), convertFromImage(), load(),
374
etc.), and in QPainter::begin() on a pixmap.
376
It is possible to modify a pixmap without letting Qt know. You can
377
first obtain the system-dependent handle() and then call
378
system-specific functions (for instance, BitBlt under Windows)
379
that modify the pixmap contents. In such cases, you can call
380
detach() to cut the pixmap loose from other pixmaps that share
383
detach() returns immediately if there is just a single reference
384
or if the pixmap has not been initialized yet.
387
void QPixmap::detach()
389
if (data->count != 1)
391
data->uninit = FALSE;
393
// reset the cache data
395
XFreePixmap(data->xinfo.display(), data->hd2);
398
data->ser_no = ++qt_pixmap_serial;
403
Returns the default pixmap depth, i.e. the depth a pixmap gets if
409
int QPixmap::defaultDepth()
411
return X11->use_xrender ? 32 : QX11Info::appDepth();
415
Fills the pixmap with the color \a fillColor.
418
void QPixmap::fill(const QColor &fillColor)
422
if (fillColor.alpha() != 255) {
423
// ################ inefficient
424
QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
425
im.fill(PREMUL(fillColor.rgba()));
426
*this = QPixmap::fromImage(im);
431
GC gc = XCreateGC(data->xinfo.display(), data->hd, 0, 0);
433
XSetForeground(data->xinfo.display(), gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
434
} else if (X11->use_xrender) {
435
XSetForeground(data->xinfo.display(), gc, fillColor.rgba());
437
XSetForeground(data->xinfo.display(), gc,
438
QColormap::instance(data->xinfo.screen()).pixel(fillColor));
440
XFillRectangle(data->xinfo.display(), data->hd, gc, 0, 0, width(), height());
441
XFreeGC(data->xinfo.display(), gc);
445
Returns the alpha channel of the pixmap. If the pixmap doesn't have an
446
alpha channel a null pixmap is returned.
448
\sa hasAlphaChannel() setAlphaChannel()
450
QPixmap QPixmap::alphaChannel() const
452
if (!hasAlphaChannel())
454
QImage im(toImage());
455
return fromImage(im.alphaChannel(), Qt::OrderedDither);
459
Sets the alpha channel of this pixmap to \a alpha. If the pixmap
460
already contains an alpha channel, it is merged with \a alpha.
462
void QPixmap::setAlphaChannel(const QPixmap &alpha)
467
if (width() != alpha.width() && height() != alpha.height()) {
468
qWarning("QPixmap::setAlphaChannel: The pixmap and the alpha channel pixmap must have the same size");
471
QImage im(toImage());
472
im.setAlphaChannel(alpha.toImage());
473
*this = fromImage(im, Qt::OrderedDither | Qt::OrderedAlphaDither);
478
\fn QBitmap QPixmap::mask() const
480
Returns the mask, or a null bitmap if no mask has been set.
482
\sa setMask(), QBitmap, hasAlpha()
484
QBitmap QPixmap::mask() const
487
#ifndef QT_NO_XRENDER
488
if (X11->use_xrender) {
489
// #### slow - there must be a better way..
490
mask = QBitmap::fromImage(toImage().createAlphaMask());
496
mask = data->mask_to_bitmap();
505
The \a newmask bitmap defines the clip mask for this pixmap. Every
506
pixel in \a newmask corresponds to a pixel in this pixmap. Pixel
507
value 1 means opaque and pixel value 0 means transparent. The mask
508
must have the same size as this pixmap.
510
\warning Setting the mask on a pixmap will cause any alpha channel
511
data to be cleared. For example:
512
\quotefromfile snippets/image/image.cpp
516
Now, alpha and alphacopy are visually different.
518
Setting a \link isNull() null\endlink mask resets the mask.
520
\sa mask(), createHeuristicMask(), QBitmap
522
void QPixmap::setMask(const QBitmap &newmask)
524
if (data == newmask.data)
525
// trying to selfmask
528
if (newmask.isNull()) { // clear mask
529
#ifndef QT_NO_XRENDER
530
if (X11->use_xrender) {
532
if (data->type == QPixmap::BitmapType)
533
pixmap = QBitmap(data->w, data->h);
535
pixmap = QPixmap(data->w, data->h);
536
pixmap.fill(Qt::black);
537
XRenderComposite(X11->display, PictOpOver,
539
pixmap.data->picture, 0, 0, 0, 0, 0, 0, data->w, data->h);
543
if (data->x11_mask) {
544
XFreePixmap(X11->display, data->x11_mask);
550
if (newmask.width() != width() || newmask.height() != height()) {
551
qWarning("QPixmap::setMask: The pixmap and the mask must have the same size");
557
#ifndef QT_NO_XRENDER
558
if (X11->use_xrender) {
559
XRenderComposite(X11->display, PictOpSrc,
560
data->picture, newmask.x11PictureHandle(),
561
data->picture, 0, 0, 0, 0, 0, 0, data->w, data->h);
566
vals.function = GXand;
567
GC gc = XCreateGC(X11->display, data->hd, GCFunction, &vals);
568
XCopyArea(X11->display, newmask.handle(), data->hd, gc, 0, 0, width(), height(), 0, 0);
569
XFreeGC(X11->display, gc);
572
XFreePixmap(X11->display, data->x11_mask);
573
data->x11_mask = QPixmapData::bitmap_to_mask(newmask, data->xinfo.screen());
581
int QPixmap::metric(PaintDeviceMetric m) const
586
else if (m == PdmHeight) {
589
Display *dpy = data->xinfo.display();
590
int scr = data->xinfo.screen();
593
case PdmPhysicalDpiX:
594
val = QX11Info::appDpiX(scr);
597
case PdmPhysicalDpiY:
598
val = QX11Info::appDpiY(scr);
601
val = (DisplayWidthMM(dpy,scr)*width())/
602
DisplayWidth(dpy,scr);
605
val = (DisplayHeightMM(dpy,scr)*height())/
606
DisplayHeight(dpy,scr);
616
qWarning("QPixmap::metric: Invalid metric command");
623
Converts the pixmap to a QImage. Returns a null image if it fails.
625
If the pixmap has 1-bit depth, the returned image will also be 1
626
bit deep. If the pixmap has 2- to 8-bit depth, the returned image
627
has 8-bit depth. If the pixmap has greater than 8-bit depth, the
628
returned image has 32-bit depth.
630
Note that for the moment, alpha masks on monochrome images are
633
\sa convertFromImage()
636
QImage QPixmap::toImage() const
639
return QImage(); // null image
644
Visual *visual = (Visual *) data->xinfo.visual();
645
bool trucol = (visual->c_class >= TrueColor) && d > 8;
647
QImage::Format format = QImage::Format_Mono;
648
if (d > 1 && d <= 8) {
650
format = QImage::Format_Indexed8;
652
// we could run into the situation where d == 8 AND trucol is true, which can
653
// cause problems when converting to and from images. in this case, always treat
654
// the depth as 32...
655
if (d > 8 || trucol) {
657
format = QImage::Format_RGB32;
660
XImage *xi = XGetImage(data->xinfo.display(), data->hd, 0, 0, w, h, AllPlanes,
661
(d == 1) ? XYPixmap : ZPixmap);
667
if (X11->use_xrender && data->d == 32) {
668
QImage image(data->w, data->h, QImage::Format_ARGB32_Premultiplied);
669
memcpy(image.bits(), xi->data, xi->bytes_per_line * xi->height);
671
// throw away image data
672
qSafeXDestroyImage(xi);
677
if (d == 1 && xi->bitmap_bit_order == LSBFirst)
678
format = QImage::Format_MonoLSB;
679
if (data->x11_mask && format == QImage::Format_RGB32)
680
format = QImage::Format_ARGB32;
682
QImage image(w, h, format);
683
if (image.isNull()) // could not create image
687
if (data->x11_mask) {
688
alpha = mask().toImage();
690
bool ale = alpha.format() == QImage::Format_MonoLSB;
692
if (trucol) { // truecolor
693
const uint red_mask = (uint)visual->red_mask;
694
const uint green_mask = (uint)visual->green_mask;
695
const uint blue_mask = (uint)visual->blue_mask;
696
const int red_shift = highest_bit(red_mask) - 7;
697
const int green_shift = highest_bit(green_mask) - 7;
698
const int blue_shift = highest_bit(blue_mask) - 7;
700
const uint red_bits = n_bits(red_mask);
701
const uint green_bits = n_bits(green_mask);
702
const uint blue_bits = n_bits(blue_mask);
704
static uint red_table_bits = 0;
705
static uint green_table_bits = 0;
706
static uint blue_table_bits = 0;
708
if (red_bits < 8 && red_table_bits != red_bits) {
709
build_scale_table(&red_scale_table, red_bits);
710
red_table_bits = red_bits;
712
if (blue_bits < 8 && blue_table_bits != blue_bits) {
713
build_scale_table(&blue_scale_table, blue_bits);
714
blue_table_bits = blue_bits;
716
if (green_bits < 8 && green_table_bits != green_bits) {
717
build_scale_table(&green_scale_table, green_bits);
718
green_table_bits = green_bits;
726
int bppc = xi->bits_per_pixel;
728
if (bppc > 8 && xi->byte_order == LSBFirst)
731
for (int y = 0; y < h; y++) {
732
uchar* asrc = data->x11_mask ? alpha.scanLine(y) : 0;
733
dst = (QRgb *)image.scanLine(y);
734
src = (uchar *)xi->data + xi->bytes_per_line*y;
735
for (int x = 0; x < w; x++) {
740
case 16: // 16 bit MSB
741
pixel = src[1] | (uint)src[0] << 8;
744
case 17: // 16 bit LSB
745
pixel = src[0] | (uint)src[1] << 8;
748
case 24: // 24 bit MSB
749
pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
752
case 25: // 24 bit LSB
753
pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
756
case 32: // 32 bit MSB
757
pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
760
case 33: // 32 bit LSB
761
pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
764
default: // should not really happen
767
pixel = 0; // eliminate compiler warning
768
qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
771
r = (pixel & red_mask) >> red_shift;
773
r = (pixel & red_mask) << -red_shift;
775
g = (pixel & green_mask) >> green_shift;
777
g = (pixel & green_mask) << -green_shift;
779
b = (pixel & blue_mask) >> blue_shift;
781
b = (pixel & blue_mask) << -blue_shift;
784
r = red_scale_table[r];
786
g = green_scale_table[g];
788
b = blue_scale_table[b];
790
if (data->x11_mask) {
792
*dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
794
*dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
797
*dst++ = qRgb(r, g, b);
801
} else if (xi->bits_per_pixel == d) { // compatible depth
802
char *xidata = xi->data; // copy each scanline
803
int bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
804
for (int y=0; y<h; y++) {
805
memcpy(image.scanLine(y), xidata, bpl);
806
xidata += xi->bytes_per_line;
809
/* Typically 2 or 4 bits display depth */
810
qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
815
if (d == 1) { // bitmap
816
image.setNumColors(2);
817
image.setColor(0, qRgb(255,255,255));
818
image.setColor(1, qRgb(0,0,0));
819
} else if (!trucol) { // pixmap with colormap
822
uchar use[256]; // pixel-in-use table
823
uchar pix[256]; // pixel translation table
827
bpl = image.bytesPerLine();
829
if (data->x11_mask) { // which pixels are used?
830
for (int i = 0; i < h; i++) {
831
uchar* asrc = alpha.scanLine(i);
832
p = image.scanLine(i);
834
for (int x = 0; x < w; x++) {
835
if (asrc[x >> 3] & (1 << (x & 7)))
840
for (int x = 0; x < w; x++) {
841
if (asrc[x >> 3] & (0x80 >> (x & 7)))
848
for (int i = 0; i < h; i++) {
849
p = image.scanLine(i);
856
for (int i = 0; i < 256; i++) { // build translation table
860
for (int i = 0; i < h; i++) { // translate pixels
861
p = image.scanLine(i);
868
if (data->x11_mask) {
872
image.setNumColors(ncols); // create color table
873
image.setColor(trans, 0x00000000);
875
image.setNumColors(ncols); // create color table
876
// oh dear... no spare "transparent" pixel.
877
// use first pixel in image (as good as any).
878
trans = image.scanLine(0)[0];
880
for (int i = 0; i < h; i++) {
881
uchar* asrc = alpha.scanLine(i);
882
p = image.scanLine(i);
884
for (int x = 0; x < w; x++) {
885
if (!(asrc[x >> 3] & (1 << (x & 7))))
890
for (int x = 0; x < w; x++) {
891
if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
898
image.setNumColors(ncols); // create color table
900
QVector<QColor> colors = QColormap::instance(data->xinfo.screen()).colormap();
902
for (int i=0; i<colors.size(); i++) { // translate pixels
904
image.setColor(j++, 0xff000000 | colors.at(i).rgb());
908
qSafeXDestroyImage(xi);
915
Converts image \a img and sets this pixmap. Returns true if
916
successful; otherwise returns false.
918
The \a flags argument is a bitwise-OR of the
919
\l{Qt::ImageConversionFlags}. Passing 0 for \a flags sets all the
922
If the image is a monochrome image, it is converted to a 32-bit pixmap and
923
then filled with the colors in the color table. If this is too expensive an
924
operation, you can use QBitmap::fromImage() instead.
926
\sa toImage(), isQBitmap(), QImage::convertDepth(),
927
defaultDepth(), QImage::hasAlphaBuffer()
930
QPixmap QPixmap::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
934
qWarning("QPixmap::convertFromImage: Cannot convert a null image");
939
const int w = image.width();
940
const int h = image.height();
941
int d = image.depth();
942
const int dd = ((X11->use_xrender) ? 32 : pixmap.data->xinfo.depth());
943
bool force_mono = (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly);
945
// must be monochrome
949
image = image.convertToFormat(QImage::Format_MonoLSB, flags);
952
} else { // can be both
954
if (d > 8 && dd <= 8) { // convert to 8 bit
955
if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
956
flags = (flags & ~Qt::DitherMode_Mask)
959
} else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
960
conv8 = (d == 1); // native depth wanted
962
if (image.numColors() == 2) {
963
QRgb c0 = image.color(0); // Auto: convert to best
964
QRgb c1 = image.color(1);
965
conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
967
// eg. 1-color monochrome images (they do exist).
972
image = image.convertToFormat(QImage::Format_Indexed8, flags);
978
QImage im = image.convertToFormat(QImage::Format_RGB32, flags);
979
return fromImage(im);
982
Display *dpy = pixmap.data->xinfo.display();
983
Visual *visual = (Visual *) pixmap.data->xinfo.visual();
985
bool trucol = (visual->c_class >= TrueColor);
986
int nbytes = image.numBytes();
989
#ifndef QT_NO_XRENDER
990
if (X11->use_xrender) {
991
const QImage &cimage = image;
998
(Qt::HANDLE)XCreatePixmap(pixmap.data->xinfo.display(),
999
RootWindow(pixmap.data->xinfo.display(), pixmap.data->xinfo.screen()),
1000
w, h, pixmap.data->d);
1002
pixmap.data->picture = XRenderCreatePicture(X11->display, pixmap.data->hd,
1003
XRenderFindStandardFormat(X11->display, PictStandardARGB32), 0, 0);
1005
xi = XCreateImage(dpy, visual, pixmap.data->d, ZPixmap, 0, 0, w, h, 32, 0);
1007
newbits = (uchar *)malloc(xi->bytes_per_line*h);
1008
Q_CHECK_PTR(newbits);
1009
xi->data = (char *)newbits;
1011
switch(cimage.format()) {
1012
case QImage::Format_Indexed8: {
1013
QVector<QRgb> colorTable = cimage.colorTable();
1014
uint *xidata = (uint *)xi->data;
1015
for (int y = 0; y < h; ++y) {
1016
const uchar *p = cimage.scanLine(y);
1017
for (int x = 0; x < w; ++x) {
1018
const QRgb rgb = colorTable[p[x]];
1019
const int a = qAlpha(rgb);
1023
// RENDER expects premultiplied alpha
1024
*xidata = qRgba(qt_div_255(qRed(rgb) * a),
1025
qt_div_255(qGreen(rgb) * a),
1026
qt_div_255(qBlue(rgb) * a),
1033
case QImage::Format_RGB32: {
1034
uint *xidata = (uint *)xi->data;
1035
for (int y = 0; y < h; ++y) {
1036
const QRgb *p = (const QRgb *) cimage.scanLine(y);
1037
for (int x = 0; x < w; ++x)
1038
*xidata++ = p[x] | 0xff000000;
1042
case QImage::Format_ARGB32: {
1043
uint *xidata = (uint *)xi->data;
1044
for (int y = 0; y < h; ++y) {
1045
const QRgb *p = (const QRgb *) cimage.scanLine(y);
1046
for (int x = 0; x < w; ++x) {
1047
const QRgb rgb = p[x];
1048
const int a = qAlpha(rgb);
1052
// RENDER expects premultiplied alpha
1053
*xidata = qRgba(qt_div_255(qRed(rgb) * a),
1054
qt_div_255(qGreen(rgb) * a),
1055
qt_div_255(qBlue(rgb) * a),
1062
case QImage::Format_ARGB32_Premultiplied: {
1063
uint *xidata = (uint *)xi->data;
1064
for (int y = 0; y < h; ++y) {
1065
const QRgb *p = (const QRgb *) cimage.scanLine(y);
1066
memcpy(xidata, p, w*sizeof(QRgb));
1075
if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
1076
uint *xidata = (uint *)xi->data;
1077
uint *xiend = xidata + w*h;
1078
while (xidata < xiend) {
1079
*xidata = (*xidata >> 24)
1080
| ((*xidata >> 8) & 0xff00)
1081
| ((*xidata << 8) & 0xff0000)
1087
GC gc = XCreateGC(dpy, pixmap.data->hd, 0, 0);
1088
XPutImage(dpy, pixmap.data->hd, gc, xi, 0, 0, 0, 0, w, h);
1091
qSafeXDestroyImage(xi);
1095
#endif // QT_NO_XRENDER
1097
if (trucol) { // truecolor display
1098
if (image.format() == QImage::Format_ARGB32_Premultiplied)
1099
image = image.convertToFormat(QImage::Format_ARGB32);
1101
const QImage &cimage = image;
1102
QRgb pix[256]; // pixel translation table
1103
const bool d8 = (d == 8);
1104
const uint red_mask = (uint)visual->red_mask;
1105
const uint green_mask = (uint)visual->green_mask;
1106
const uint blue_mask = (uint)visual->blue_mask;
1107
const int red_shift = highest_bit(red_mask) - 7;
1108
const int green_shift = highest_bit(green_mask) - 7;
1109
const int blue_shift = highest_bit(blue_mask) - 7;
1110
const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
1111
const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
1112
const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
1114
if (d8) { // setup pixel translation
1115
QVector<QRgb> ctable = cimage.colorTable();
1116
for (int i=0; i < cimage.numColors(); i++) {
1117
int r = qRed (ctable[i]);
1118
int g = qGreen(ctable[i]);
1119
int b = qBlue (ctable[i]);
1120
r = red_shift > 0 ? r << red_shift : r >> -red_shift;
1121
g = green_shift > 0 ? g << green_shift : g >> -green_shift;
1122
b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
1123
pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
1124
| ~(blue_mask | green_mask | red_mask);
1128
xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
1130
newbits = (uchar *)malloc(xi->bytes_per_line*h);
1131
Q_CHECK_PTR(newbits);
1132
if (!newbits) // no memory
1134
int bppc = xi->bits_per_pixel;
1136
bool contig_bits = n_bits(red_mask) == rbits &&
1137
n_bits(green_mask) == gbits &&
1138
n_bits(blue_mask) == bbits;
1141
(flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
1142
(flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
1145
// Can do it? (Contiguous bits?)
1148
static bool init=false;
1149
static int D[16][16];
1150
if (dither_tc && !init) {
1151
// I also contributed this code to XV - WWA.
1153
The dither matrix, D, is obtained with this formula:
1159
D2*n = [4*Dn 4*Dn+2*Un]
1160
[4*Dn+3*Un 4*Dn+1*Un]
1171
/* Expand using recursive definition given above */
1172
for (n=2; n<16; n*=2) {
1173
for (i=0; i<n; i++) {
1174
for (j=0; j<n; j++) {
1176
D[i+n][j]=D[i][j]+2;
1177
D[i][j+n]=D[i][j]+3;
1178
D[i+n][j+n]=D[i][j]+1;
1186
BPP16_565, BPP16_555,
1187
BPP16_MSB, BPP16_LSB,
1189
BPP24_MSB, BPP24_LSB,
1191
BPP32_MSB, BPP32_LSB
1194
bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
1196
if(bppc == 8) // 8 bit
1198
else if(bppc == 16) { // 16 bit MSB/LSB
1199
if(red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
1201
else if(red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
1204
mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
1205
} else if(bppc == 24) { // 24 bit MSB/LSB
1206
if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
1209
mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
1210
} else if(bppc == 32) { // 32 bit MSB/LSB
1211
if(red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
1214
mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
1216
qFatal("Logic error 3");
1220
if (d8) pixel = pix[*src++]; \
1222
int r = qRed (*p); \
1223
int g = qGreen(*p); \
1224
int b = qBlue (*p++); \
1226
? r << red_shift : r >> -red_shift; \
1227
g = green_shift > 0 \
1228
? g << green_shift : g >> -green_shift; \
1229
b = blue_shift > 0 \
1230
? b << blue_shift : b >> -blue_shift; \
1231
pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
1232
| ~(blue_mask | green_mask | red_mask); \
1235
#define GET_PIXEL_DITHER_TC \
1236
int r = qRed (*p); \
1237
int g = qGreen(*p); \
1238
int b = qBlue (*p++); \
1239
const int thres = D[x%16][y%16]; \
1240
if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
1242
r += (1<<(8-rbits)); \
1243
if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
1245
g += (1<<(8-gbits)); \
1246
if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
1248
b += (1<<(8-bbits)); \
1250
? r << red_shift : r >> -red_shift; \
1251
g = green_shift > 0 \
1252
? g << green_shift : g >> -green_shift; \
1253
b = blue_shift > 0 \
1254
? b << blue_shift : b >> -blue_shift; \
1255
uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
1257
// again, optimized case
1258
// can't be optimized that much :(
1259
#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
1260
rbits,gbits,bbits) \
1261
const int thres = D[x%16][y%16]; \
1262
int r = qRed (*p); \
1263
if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
1265
r += (1<<(8-rbits)); \
1266
int g = qGreen(*p); \
1267
if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
1269
g += (1<<(8-gbits)); \
1270
int b = qBlue (*p++); \
1271
if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
1273
b += (1<<(8-bbits)); \
1274
uint pixel = ((r red_shift) & red_mask) \
1275
| ((g green_shift) & green_mask) \
1276
| ((b blue_shift) & blue_mask);
1278
#define CYCLE(body) \
1279
for (int y=0; y<h; y++) { \
1280
const uchar* src = cimage.scanLine(y); \
1281
uchar* dst = newbits + xi->bytes_per_line*y; \
1282
const QRgb* p = (const QRgb *)src; \
1290
quint16* dst16 = (quint16*)dst;
1291
for (int x=0; x<w; x++) {
1292
GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
1299
quint16* dst16 = (quint16*)dst;
1300
for (int x=0; x<w; x++) {
1301
GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
1306
case BPP16_MSB: // 16 bit MSB
1308
for (int x=0; x<w; x++) {
1310
*dst++ = (pixel >> 8);
1315
case BPP16_LSB: // 16 bit LSB
1317
for (int x=0; x<w; x++) {
1320
*dst++ = pixel >> 8;
1325
qFatal("Logic error");
1332
for (int x=0; x<w; x++)
1333
*dst++ = pix[*src++];
1338
quint16* dst16 = (quint16*)dst;
1339
for (int x = 0; x < w; x++) {
1340
*dst16++ = ((*p >> 8) & 0xf800)
1341
| ((*p >> 5) & 0x7e0)
1342
| ((*p >> 3) & 0x1f);
1349
quint16* dst16 = (quint16*)dst;
1350
for (int x=0; x<w; x++) {
1351
*dst16++ = ((*p >> 9) & 0x7c00)
1352
| ((*p >> 6) & 0x3e0)
1353
| ((*p >> 3) & 0x1f);
1358
case BPP16_MSB: // 16 bit MSB
1360
for (int x=0; x<w; x++) {
1362
*dst++ = (pixel >> 8);
1367
case BPP16_LSB: // 16 bit LSB
1369
for (int x=0; x<w; x++) {
1372
*dst++ = pixel >> 8;
1376
case BPP24_888: // 24 bit MSB
1378
for (int x=0; x<w; x++) {
1380
*dst++ = qGreen(*p);
1381
*dst++ = qBlue (*p++);
1385
case BPP24_MSB: // 24 bit MSB
1387
for (int x=0; x<w; x++) {
1389
*dst++ = pixel >> 16;
1390
*dst++ = pixel >> 8;
1395
case BPP24_LSB: // 24 bit LSB
1397
for (int x=0; x<w; x++) {
1400
*dst++ = pixel >> 8;
1401
*dst++ = pixel >> 16;
1407
memcpy(dst, p, w * 4);
1410
case BPP32_MSB: // 32 bit MSB
1412
for (int x=0; x<w; x++) {
1414
*dst++ = pixel >> 24;
1415
*dst++ = pixel >> 16;
1416
*dst++ = pixel >> 8;
1421
case BPP32_LSB: // 32 bit LSB
1423
for (int x=0; x<w; x++) {
1426
*dst++ = pixel >> 8;
1427
*dst++ = pixel >> 16;
1428
*dst++ = pixel >> 24;
1433
qFatal("Logic error 2");
1436
xi->data = (char *)newbits;
1439
if (d == 8 && !trucol) { // 8 bit pixmap
1440
int pop[256]; // pixel popularity
1442
if (image.numColors() == 0)
1443
image.setNumColors(1);
1445
const QImage &cimage = image;
1446
memset(pop, 0, sizeof(int)*256); // reset popularity array
1447
for (int i = 0; i < h; i++) { // for each scanline...
1448
const uchar* p = cimage.scanLine(i);
1449
const uchar *end = p + w;
1450
while (p < end) // compute popularity
1454
newbits = (uchar *)malloc(nbytes); // copy image into newbits
1455
Q_CHECK_PTR(newbits);
1456
if (!newbits) // no memory
1459
memcpy(p, cimage.bits(), nbytes); // copy image data into newbits
1462
* The code below picks the most important colors. It is based on the
1463
* diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
1466
struct PIX { // pixel sort element
1467
uchar r,g,b,n; // color + pad
1468
int use; // popularity
1469
int index; // index in colormap
1473
for (int i=0; i< cimage.numColors(); i++) { // compute number of colors
1477
for (int i = cimage.numColors(); i < 256; i++) // ignore out-of-range pixels
1480
// works since we make sure above to have at least
1481
// one color in the image
1485
PIX pixarr[256]; // pixel array
1486
PIX pixarr_sorted[256]; // pixel array (sorted)
1487
memset(pixarr, 0, ncols*sizeof(PIX));
1488
PIX *px = &pixarr[0];
1492
QVector<QRgb> ctable = cimage.colorTable();
1493
for (int i = 0; i < 256; i++) { // init pixel array
1495
px->r = qRed (ctable[i]);
1496
px->g = qGreen(ctable[i]);
1497
px->b = qBlue (ctable[i]);
1500
if (pop[i] > maxpop) { // select most popular entry
1505
px->mindist = 1000000;
1510
pixarr_sorted[0] = pixarr[maxpix];
1511
pixarr[maxpix].use = 0;
1513
for (int i = 1; i < ncols; i++) { // sort pixels
1514
int minpix = -1, mindist = -1;
1515
px = &pixarr_sorted[i-1];
1520
if ((i & 1) || i<10) { // sort on max distance
1521
for (int j=0; j<ncols; j++) {
1524
dist = (px->r - r)*(px->r - r) +
1525
(px->g - g)*(px->g - g) +
1526
(px->b - b)*(px->b - b);
1527
if (px->mindist > dist)
1529
if (px->mindist > mindist) {
1530
mindist = px->mindist;
1535
} else { // sort on max popularity
1536
for (int j=0; j<ncols; j++) {
1539
dist = (px->r - r)*(px->r - r) +
1540
(px->g - g)*(px->g - g) +
1541
(px->b - b)*(px->b - b);
1542
if (px->mindist > dist)
1544
if (px->use > mindist) {
1551
pixarr_sorted[i] = pixarr[minpix];
1552
pixarr[minpix].use = 0;
1555
QColormap cmap = QColormap::instance(pixmap.data->xinfo.screen());
1556
uint pix[256]; // pixel translation table
1557
px = &pixarr_sorted[0];
1558
for (int i = 0; i < ncols; i++) { // allocate colors
1559
QColor c(px->r, px->g, px->b);
1560
pix[px->index] = cmap.pixel(c);
1565
for (int i = 0; i < nbytes; i++) { // translate pixels
1571
if (!xi) { // X image not created
1572
xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
1573
if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp
1575
int p2inc = xi->bytes_per_line/sizeof(ushort);
1576
ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
1577
Q_CHECK_PTR(newerbits);
1578
if (!newerbits) // no memory
1581
for (int y = 0; y < h; y++) { // OOPS: Do right byte order!!
1582
p2 = newerbits + p2inc*y;
1583
for (int x = 0; x < w; x++)
1587
newbits = (uchar *)newerbits;
1588
} else if (xi->bits_per_pixel != 8) {
1589
qWarning("QPixmap::convertFromImage: Display not supported "
1590
"(bpp=%d)", xi->bits_per_pixel);
1592
xi->data = (char *)newbits;
1595
pixmap.data->hd = (Qt::HANDLE)XCreatePixmap(pixmap.data->xinfo.display(),
1596
RootWindow(pixmap.data->xinfo.display(), pixmap.data->xinfo.screen()),
1599
GC gc = XCreateGC(dpy, pixmap.data->hd, 0, 0);
1600
XPutImage(dpy, pixmap.data->hd, gc, xi, 0, 0, 0, 0, w, h);
1603
qSafeXDestroyImage(xi);
1606
pixmap.data->d = dd;
1608
if (image.hasAlphaChannel()) {
1609
QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
1618
Grabs the contents of the window \a window and makes a pixmap out
1619
of it. Returns the pixmap.
1621
The arguments (\a{x}, \a{y}) specify the offset in the window,
1622
whereas (\a{w}, \a{h}) specify the width and height of the area to
1625
If \a w is negative, the function copies everything to the right
1626
border of the window. If \a h is negative, the function copies
1627
everything to the bottom of the window.
1629
Note that grabWindow() grabs pixels from the screen, not from the
1630
window. If there is another window partially or entirely over the
1631
one you grab, you get pixels from the overlying window, too.
1633
Note also that the mouse cursor is generally not grabbed.
1635
The reason we use a window identifier and not a QWidget is to
1636
enable grabbing of windows that are not part of the application,
1637
window system frames, and so on.
1639
\warning Grabbing an area outside the screen is not safe in
1640
general. This depends on the underlying window system.
1642
\warning X11 only: If \a window is not the same depth as the root
1643
window and another window partially or entirely obscures the one
1644
you grab, you will \e not get pixels from the overlying window.
1645
The contests of the obscured areas in the pixmap are undefined and
1651
QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
1653
if (w == 0 || h == 0)
1656
Display *dpy = X11->display;
1657
XWindowAttributes window_attr;
1658
if (! XGetWindowAttributes(dpy, window, &window_attr))
1662
w = window_attr.width - x;
1664
h = window_attr.height - y;
1666
// determine the screen
1668
for (scr = 0; scr < ScreenCount(dpy); ++scr) {
1669
if (window_attr.root == RootWindow(dpy, scr)) // found it
1672
if (scr >= ScreenCount(dpy)) // sanity check
1676
// get the depth of the root window
1677
XWindowAttributes root_attr;
1678
if (! XGetWindowAttributes(dpy, window_attr.root, &root_attr))
1681
if (window_attr.depth == root_attr.depth) {
1682
// if the depth of the specified window and the root window are the
1683
// same, grab pixels from the root window (so that we get the any
1684
// overlapping windows and window manager frames)
1686
// map x and y to the root window
1688
if (! XTranslateCoordinates(dpy, window, window_attr.root, x, y,
1692
window = window_attr.root;
1693
window_attr = root_attr;
1697
pm.data->uninit = false;
1698
pm.x11SetScreen(scr);
1700
#ifndef QT_NO_XRENDER
1701
if (X11->use_xrender) {
1702
XRenderPictFormat *format = XRenderFindVisualFormat(dpy, window_attr.visual);
1703
XRenderPictureAttributes pattr;
1704
pattr.subwindow_mode = IncludeInferiors;
1705
Picture src_pict = XRenderCreatePicture(dpy, window, format, CPSubwindowMode, &pattr);
1706
Picture dst_pict = pm.x11PictureHandle();
1707
XRenderComposite(dpy, PictOpSrc, src_pict, 0, dst_pict, x, y, x, y, 0, 0, w, h);
1708
XRenderFreePicture(dpy, src_pict);
1712
GC gc = XCreateGC(dpy, pm.handle(), 0, 0);
1713
XSetSubwindowMode(dpy, gc, IncludeInferiors);
1714
XCopyArea(dpy, window, pm.handle(), gc, x, y, w, h, 0, 0);
1722
Returns a copy of the pixmap that is transformed using \a matrix.
1723
The original pixmap is not changed.
1725
The transformation \a matrix is internally adjusted to compensate
1726
for unwanted translation, i.e. transformed() returns the smallest image
1727
that contains all the transformed points of the original image.
1729
\a mode specifies whether the transformation should be smooth or
1732
This function is slow because it involves transformation to a
1733
QImage, non-trivial computations and a transformation back to a
1736
\sa trueMatrix(), QMatrix, QPainter::setWorldMatrix() QImage::transformed()
1739
QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const
1742
int h = 0; // size of target pixmap
1743
int ws, hs; // size of source pixmap
1744
uchar *dptr; // data in target pixmap
1745
int dbpl, dbytes; // bytes per line/bytes total
1746
uchar *sptr; // data in original pixmap
1747
int sbpl; // bytes per line in original
1748
int bpp; // bits per pixel
1749
bool depth1 = depth() == 1;
1750
Display *dpy = data->xinfo.display();
1752
if (isNull()) // this is a null pixmap
1758
QMatrix mat(matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), 0., 0.);
1759
bool complex_xform = false;
1761
if (mat.m12() == 0.0F && mat.m21() == 0.0F) {
1762
if (mat.m11() == 1.0F && mat.m22() == 1.0F) // identity matrix
1764
h = int(qAbs(mat.m22()) * hs + 0.9999);
1765
w = int(qAbs(mat.m11()) * ws + 0.9999);
1768
} else { // rotation or shearing
1769
QPolygonF a(QRectF(0, 0, ws+1, hs+1));
1771
QRectF r = a.boundingRect().normalized();
1772
w = int(r.width() + 0.9999);
1773
h = int(r.height() + 0.9999);
1774
complex_xform = true;
1776
mat = trueMatrix(mat, ws, hs); // true matrix
1780
mat = mat.inverted(&invertible); // invert matrix
1782
if (h == 0 || w == 0 || !invertible)
1785
if (mode == Qt::SmoothTransformation) {
1786
QImage image = toImage();
1787
return QPixmap::fromImage(image.transformed(matrix, mode));
1790
#if defined(QT_MITSHM)
1791
static bool try_once = true;
1795
qt_create_mitshm_buffer(this, 800, 600);
1798
bool use_mitshm = xshmimg && !depth1 &&
1799
xshmimg->width >= w && xshmimg->height >= h;
1801
XImage *xi = XGetImage(data->xinfo.display(), handle(), 0, 0, ws, hs, AllPlanes,
1802
depth1 ? XYPixmap : ZPixmap);
1807
sbpl = xi->bytes_per_line;
1808
sptr = (uchar *)xi->data;
1809
bpp = xi->bits_per_pixel;
1814
dbpl = ((w*bpp+31)/32)*4;
1817
#if defined(QT_MITSHM)
1819
dptr = (uchar *)xshmimg->data;
1820
uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
1821
for (int y=0; y<h; y++)
1822
memset(dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl);
1825
dptr = (uchar *)malloc(dbytes); // create buffer for bits
1827
if (depth1) // fill with zeros
1828
memset(dptr, 0, dbytes);
1829
else if (bpp == 8) // fill with background color
1830
memset(dptr, WhitePixel(data->xinfo.display(), data->xinfo.screen()), dbytes);
1832
memset(dptr, 0, dbytes);
1833
#if defined(QT_MITSHM)
1837
// #define QT_DEBUG_XIMAGE
1838
#if defined(QT_DEBUG_XIMAGE)
1839
qDebug("----IMAGE--INFO--------------");
1840
qDebug("width............. %d", xi->width);
1841
qDebug("height............ %d", xi->height);
1842
qDebug("xoffset........... %d", xi->xoffset);
1843
qDebug("format............ %d", xi->format);
1844
qDebug("byte order........ %d", xi->byte_order);
1845
qDebug("bitmap unit....... %d", xi->bitmap_unit);
1846
qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
1847
qDebug("depth............. %d", xi->depth);
1848
qDebug("bytes per line.... %d", xi->bytes_per_line);
1849
qDebug("bits per pixel.... %d", xi->bits_per_pixel);
1853
if (xi->bitmap_bit_order == MSBFirst)
1854
type = QT_XFORM_TYPE_MSBFIRST;
1856
type = QT_XFORM_TYPE_LSBFIRST;
1860
p_inc = dbpl - xbpl;
1863
p_inc = dbpl - xbpl;
1864
#if defined(QT_MITSHM)
1866
p_inc = xshmimg->bytes_per_line - xbpl;
1870
if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
1871
qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
1876
qSafeXDestroyImage(xi);
1878
if (depth1) { // mono bitmap
1879
QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
1880
BitmapBitOrder(X11->display) == MSBFirst
1881
? QImage::Format_Mono
1882
: QImage::Format_MonoLSB);
1885
} else { // color pixmap
1887
pm.data->uninit = false;
1888
pm.x11SetScreen(data->xinfo.screen());
1889
GC gc = XCreateGC(pm.data->xinfo.display(), pm.handle(), 0, 0);
1890
#if defined(QT_MITSHM)
1892
XCopyArea(dpy, xshmpm, pm.handle(), gc, 0, 0, w, h, 0, 0);
1896
xi = XCreateImage(dpy, (Visual *) pm.data->xinfo.visual(), pm.data->d,
1897
ZPixmap, 0, (char *)dptr, w, h, 32, 0);
1898
XPutImage(dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
1899
qSafeXDestroyImage(xi);
1901
XFreeGC(data->xinfo.display(), gc);
1903
if (!X11->use_xrender) {
1904
if (data->x11_mask) { // xform mask, too
1905
pm.setMask(data->mask_to_bitmap().transformed(matrix));
1906
} else if (complex_xform) { // need a mask!
1907
QBitmap mask(data->w, data->h);
1908
mask.fill(Qt::color1);
1909
pm.setMask(mask.transformed(matrix));
1920
int QPixmap::x11SetDefaultScreen(int screen)
1922
int old = defaultScreen;
1923
defaultScreen = screen;
1930
void QPixmap::x11SetScreen(int screen)
1933
screen = QX11Info::appScreen();
1935
if (screen == data->xinfo.screen())
1936
return; // nothing to do
1939
QX11InfoData* xd = data->xinfo.getX11Data(true);
1940
xd->screen = screen;
1941
xd->depth = QX11Info::appDepth(screen);
1942
xd->cells = QX11Info::appCells(screen);
1943
xd->colormap = QX11Info::appColormap(screen);
1944
xd->defaultColormap = QX11Info::appDefaultColormap(screen);
1945
xd->visual = (Visual *)QX11Info::appVisual(screen);
1946
xd->defaultVisual = QX11Info::appDefaultVisual(screen);
1947
data->xinfo.setX11Data(xd);
1951
qDebug("QPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", data, data->xinfo.screen(), screen, width(), height());
1954
QImage img = toImage();
1955
QX11InfoData* xd = data->xinfo.getX11Data(true);
1956
xd->screen = screen;
1957
xd->depth = QX11Info::appDepth(screen);
1958
xd->cells = QX11Info::appCells(screen);
1959
xd->colormap = QX11Info::appColormap(screen);
1960
xd->defaultColormap = QX11Info::appDefaultColormap(screen);
1961
xd->visual = (Visual *)QX11Info::appVisual(screen);
1962
xd->defaultVisual = QX11Info::appDefaultVisual(screen);
1963
data->xinfo.setX11Data(xd);
1964
(*this) = fromImage(img);
1968
Returns true this pixmap has an alpha channel or a mask.
1970
\sa hasAlphaChannel() mask()
1972
bool QPixmap::hasAlpha() const
1974
return X11->use_xrender || data->x11_mask;
1978
Returns true if the pixmap has an alpha channel; otherwise it
1981
\sa hasAlpha() mask()
1983
bool QPixmap::hasAlphaChannel() const
1985
return X11->use_xrender || data->x11_mask;
1989
Returns a pointer to a QX11Info object. This pointer is owned by
1990
QPixmap and should not be deleted.
1992
const QX11Info &QPixmap::x11Info() const
1997
QPaintEngine *QPixmap::paintEngine() const
1999
if (!data->paintEngine)
2000
data->paintEngine = new QX11PaintEngine();
2001
return data->paintEngine;
2005
Returns the X11 Picture handle of the pixmap for XRender
2006
support. Use of this function is not portable. This function will
2007
return 0 if XRender support is not compiled into Qt, if the
2008
XRender extension is not supported on the X11 display, or if the
2009
handle could not be created.
2012
Qt::HANDLE QPixmap::x11PictureHandle() const
2014
#ifndef QT_NO_XRENDER
2015
return data->picture;
2018
#endif // QT_NO_XRENDER
2021
Qt::HANDLE QPixmapData::x11ConvertToDefaultDepth()
2023
#ifndef QT_NO_XRENDER
2024
if (d == xinfo.depth())
2027
hd2 = XCreatePixmap(xinfo.display(), hd, w, h, xinfo.depth());
2028
XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
2029
(Visual*) xinfo.visual());
2030
Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
2031
XRenderComposite(xinfo.display(), PictOpSrc, picture,
2032
XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
2033
XRenderFreePicture(xinfo.display(), pic);