summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp2494
1 files changed, 0 insertions, 2494 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp b/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
deleted file mode 100644
index 1caf3a3..0000000
--- a/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
+++ /dev/null
@@ -1,2494 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQPixmap class for X11
-**
-** Created : 940501
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the kernel module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-// NOT REVISED
-
-#include "tqplatformdefs.h"
-
-#include "tqplatformdefs.h"
-
-#include "tqbitmap.h"
-#include "tqpaintdevicemetrics.h"
-#include "tqimage.h"
-#include "tqwmatrix.h"
-#include "tqapplication.h"
-#include "tqt_x11_p.h"
-
-#include <stdlib.h>
-
-#if defined(TQ_CC_MIPS)
-# define for if(0){}else for
-#endif
-
-#ifdef USE_QT4
-
-/*!
- Returns the window system handle of the paint tqdevice, for
- low-level access. Using this function is not portable.
-
- The HANDLE type varies with platform; see \c tqpaintdevice.h and
- \c tqwindowdefs.h for details.
-
- \sa x11Display()
-*/
-TQt::HANDLE TQPixmap::handle() const
-{
- return QPixmap::handle();
-}
-
-/*!
- Returns the window system handle of the paint tqdevice for XRender
- support. Use of this function is not portable. This function will
- return 0 if XRender support is not compiled into TQt, if the
- XRender extension is not supported on the X11 display, or if the
- handle could not be created.
-*/
-TQt::HANDLE TQPixmap::x11RenderHandle() const
-{
-// #ifndef TQT_NO_XFTFREETYPE
-// return rendhd ? XftDrawPicture( (XftDraw *) rendhd ) : 0;
-// #else
-// return 0;
-// #endif // TQT_NO_XFTFREETYPE
-
- // [FIXME]
- printf("[WARNING] TQPixmap::x11RenderHandle() const unimplemented\n\r");
- return 0;
-}
-
-#else // USE_QT4
-
-/*!
- \class TQPixmap::TQPixmapData
- \brief The TQPixmap::TQPixmapData class is an internal class.
- \internal
-*/
-
-
-// For thread-safety:
-// image->data does not belong to X11, so we must free it ourselves.
-
-inline static void qSafeXDestroyImage( XImage *x )
-{
- if ( x->data ) {
- free( x->data );
- x->data = 0;
- }
- XDestroyImage( x );
-}
-
-
-/*****************************************************************************
- MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
- *****************************************************************************/
-
-#if defined(TQT_MITSHM_XFORM)
-
-static bool xshminit = FALSE;
-static XShmSegmentInfo xshminfo;
-static XImage *xshmimg = 0;
-static Pixmap xshmpm = 0;
-
-static void qt_cleanup_mitshm()
-{
- if ( xshmimg == 0 )
- return;
- Display *dpy = TQPaintDevice::x11AppDisplay();
- if ( xshmpm ) {
- XFreePixmap( dpy, xshmpm );
- xshmpm = 0;
- }
- XShmDetach( dpy, &xshminfo ); xshmimg->data = 0;
- qSafeXDestroyImage( xshmimg ); xshmimg = 0;
- shmdt( xshminfo.shmaddr );
- shmctl( xshminfo.shmid, IPC_RMID, 0 );
-}
-
-
-static bool qt_create_mitshm_buffer( const TQPaintDevice* dev, int w, int h )
-{
- static int major, minor;
- static Bool pixmaps_ok;
- Display *dpy = dev->x11Display();
- int dd = dev->x11Depth();
- Visual *vis = (Visual*)dev->x11Visual();
-
- if ( xshminit ) {
- qt_cleanup_mitshm();
- } else {
- if ( !XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok) )
- return FALSE; // MIT Shm not supported
- qAddPostRoutine( qt_cleanup_mitshm );
- xshminit = TRUE;
- }
-
- xshmimg = XShmCreateImage( dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h );
- if ( !xshmimg )
- return FALSE;
-
- bool ok;
- xshminfo.shmid = shmget( IPC_PRIVATE,
- xshmimg->bytes_per_line * xshmimg->height,
- IPC_CREAT | 0777 );
- ok = xshminfo.shmid != -1;
- if ( ok ) {
- xshmimg->data = (char*)shmat( xshminfo.shmid, 0, 0 );
- xshminfo.shmaddr = xshmimg->data;
- ok = ( xshminfo.shmaddr != (char*)-1 );
- }
- xshminfo.readOnly = FALSE;
- if ( ok )
- ok = XShmAttach( dpy, &xshminfo );
- if ( !ok ) {
- qSafeXDestroyImage( xshmimg );
- xshmimg = 0;
- if ( xshminfo.shmaddr )
- shmdt( xshminfo.shmaddr );
- if ( xshminfo.shmid != -1 )
- shmctl( xshminfo.shmid, IPC_RMID, 0 );
- return FALSE;
- }
- if ( pixmaps_ok )
- xshmpm = XShmCreatePixmap( dpy, DefaultRootWindow(dpy), xshmimg->data,
- &xshminfo, w, h, dd );
-
- return TRUE;
-}
-
-#else
-
-// If extern, need a dummy.
-//
-// static bool qt_create_mitshm_buffer( TQPaintDevice*, int, int )
-// {
-// return FALSE;
-// }
-
-#endif // TQT_MITSHM_XFORM
-
-#ifdef TQT_MITSHM_CONVERSIONS
-
-static bool qt_mitshm_error = false;
-static int qt_mitshm_errorhandler( Display*, XErrorEvent* )
-{
- qt_mitshm_error = true;
- return 0;
-}
-
-static XImage* qt_XShmCreateImage( Display* dpy, Visual* visual, unsigned int depth,
- int format, int /*offset*/, char* /*data*/, unsigned int width, unsigned int height,
- int /*bitmap_pad*/, int /*bytes_per_line*/, XShmSegmentInfo* shminfo )
-{
- if( width * height * depth < 100*100*32 )
- return NULL;
- static int shm_inited = -1;
- if( shm_inited == -1 ) {
- if( XShmQueryExtension( dpy ))
- shm_inited = 1;
- else
- shm_inited = 0;
- }
- if( shm_inited == 0 )
- return NULL;
- XImage* xi = XShmCreateImage( dpy, visual, depth, format, NULL, shminfo, width,
- height );
- if( xi == NULL )
- return NULL;
- shminfo->shmid = shmget( IPC_PRIVATE, xi->bytes_per_line * xi->height,
- IPC_CREAT|0600);
- if( shminfo->shmid < 0 ) {
- XDestroyImage( xi );
- return NULL;
- }
- shminfo->readOnly = False;
- shminfo->shmaddr = (char*)shmat( shminfo->shmid, 0, 0 );
- if( shminfo->shmaddr == (char*)-1 ) {
- XDestroyImage( xi );
- shmctl( shminfo->shmid, IPC_RMID, 0 );
- return NULL;
- }
- xi->data = shminfo->shmaddr;
-#ifndef TQT_MITSHM_RMID_IGNORES_REFCOUNT
- // mark as deleted to automatically free the memory in case
- // of a crash (but this doesn't work e.g. on Solaris)
- shmctl( shminfo->shmid, IPC_RMID, 0 );
-#endif
- if( shm_inited == 1 ) { // first time
- XErrorHandler old_h = XSetErrorHandler( qt_mitshm_errorhandler );
- XShmAttach( dpy, shminfo );
- shm_inited = 2;
- XSync( dpy, False );
- XSetErrorHandler( old_h );
- if( qt_mitshm_error ) { // oops ... perhaps we are remote?
- shm_inited = 0;
- XDestroyImage( xi );
- shmdt( shminfo->shmaddr );
-#ifdef TQT_MITSHM_RMID_IGNORES_REFCOUNT
- shmctl( shminfo->shmid, IPC_RMID, 0 );
-#endif
- return NULL;
- }
- } else
- XShmAttach( dpy, shminfo );
- return xi;
-}
-
-static void qt_XShmDestroyImage( XImage* xi, XShmSegmentInfo* shminfo )
-{
- XShmDetach( TQPaintDevice::x11AppDisplay(), shminfo );
- XDestroyImage( xi );
- shmdt( shminfo->shmaddr );
-#ifdef TQT_MITSHM_RMID_IGNORES_REFCOUNT
- shmctl( shminfo->shmid, IPC_RMID, 0 );
-#endif
-}
-
-static XImage* qt_XShmGetImage( const TQPixmap* pix, int format,
- XShmSegmentInfo* shminfo )
-{
- XImage* xi = qt_XShmCreateImage( pix->x11Display(), (Visual*)pix->x11Visual(),
- pix->depth(), format, 0, 0, pix->width(), pix->height(), 32, 0, shminfo );
- if( xi == NULL )
- return NULL;
- if( XShmGetImage( pix->x11Display(), pix->handle(), xi, 0, 0, AllPlanes ) == False ) {
- qt_XShmDestroyImage( xi, shminfo );
- return NULL;
- }
- return xi;
-}
-
-#endif // TQT_MITSHM_CONVERSIONS
-
-/*****************************************************************************
- Internal functions
- *****************************************************************************/
-
-extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
-
-static uchar *flip_bits( const uchar *bits, int len )
-{
- register const uchar *p = bits;
- const uchar *end = p + len;
- uchar *newdata = new uchar[len];
- uchar *b = newdata;
- const uchar *f = qt_get_bitflip_array();
- while ( p < end )
- *b++ = f[*p++];
- return newdata;
-}
-
-// Returns position of highest bit set or -1 if none
-static int highest_bit( uint v )
-{
- int i;
- uint b = (uint)1 << 31;
- for ( i=31; ((b & v) == 0) && i>=0; i-- )
- b >>= 1;
- return i;
-}
-
-// Returns position of lowest set bit in 'v' as an integer (0-31), or -1
-static int lowest_bit( uint v )
-{
- int i;
- ulong lb;
- lb = 1;
- for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1);
- return i==32 ? -1 : i;
-}
-
-// Counts the number of bits set in 'v'
-static uint n_bits( uint v )
-{
- int i = 0;
- while ( v ) {
- v = v & (v - 1);
- i++;
- }
- return i;
-}
-
-static uint *red_scale_table = 0;
-static uint *green_scale_table = 0;
-static uint *blue_scale_table = 0;
-
-static void cleanup_scale_tables()
-{
- delete[] red_scale_table;
- delete[] green_scale_table;
- delete[] blue_scale_table;
-}
-
-/*
- Could do smart bitshifting, but the "obvious" algorithm only works for
- nBits >= 4. This is more robust.
-*/
-static void build_scale_table( uint **table, uint nBits )
-{
- if ( nBits > 7 ) {
-#if defined(TQT_CHECK_RANGE)
- qWarning( "build_scale_table: internal error, nBits = %i", nBits );
-#endif
- return;
- }
- if (!*table) {
- static bool firstTable = TRUE;
- if ( firstTable ) {
- qAddPostRoutine( cleanup_scale_tables );
- firstTable = FALSE;
- }
- *table = new uint[256];
- }
- int maxVal = (1 << nBits) - 1;
- int valShift = 8 - nBits;
- int i;
- for( i = 0 ; i < maxVal + 1 ; i++ )
- (*table)[i << valShift] = i*255/maxVal;
-}
-
-static int defaultScreen = -1;
-
-extern bool qt_use_xrender; // defined in qapplication_x11.cpp
-extern bool qt_has_xft; // defined in qfont_x11.cpp
-
-#ifndef TQT_NO_XFTFREETYPE
-#ifndef TQT_XFT2
-// Xft1 doesn't have XftDrawCreateAlpha, so we fake it in qtaddons_x11.cpp
-extern "C" XftDraw *XftDrawCreateAlpha( Display *, TQt::HANDLE, int );
-#endif // TQT_XFT2
-#endif // TQT_NO_XFTFREETYPE
-
-/*****************************************************************************
- TQPixmap member functions
- *****************************************************************************/
-
-/*!
- \internal
- Initializes the pixmap data.
-*/
-
-void TQPixmap::init( int w, int h, int d, bool bitmap, Optimization optim )
-{
-#if defined(TQT_CHECK_STATE)
- if ( tqApp->type() == TQApplication::Tty ) {
- qWarning( "TQPixmap: Cannot create a TQPixmap when no GUI "
- "is being used" );
- }
-#endif
-
- static int serial = 0;
-
- if ( defaultScreen >= 0 && defaultScreen != x11Screen() ) {
- TQPaintDeviceX11Data* xd = getX11Data( TRUE );
- xd->x_screen = defaultScreen;
- xd->x_depth = TQPaintDevice::x11AppDepth( xd->x_screen );
- xd->x_cells = TQPaintDevice::x11AppCells( xd->x_screen );
- xd->x_colormap = TQPaintDevice::x11AppColormap( xd->x_screen );
- xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( xd->x_screen );
- xd->x_visual = TQPaintDevice::x11AppVisual( xd->x_screen );
- xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( xd->x_screen );
- setX11Data( xd );
- }
-
- int dd = x11Depth();
-
- if ( d != -1 )
- dd = d;
-
- if ( optim == DefaultOptim ) // use default optimization
- optim = defOptim;
-
- data = new TQPixmapData;
- TQ_CHECK_PTR( data );
-
- memset( data, 0, sizeof(TQPixmapData) );
- data->count = 1;
- data->uninit = TRUE;
- data->bitmap = bitmap;
- data->ser_no = ++serial;
- data->optim = optim;
-
- bool make_null = w == 0 || h == 0; // create null pixmap
- if ( d == 1 ) // monocrome pixmap
- data->d = 1;
- else if ( d < 0 || d == dd ) // def depth pixmap
- data->d = dd;
- if ( make_null || w < 0 || h < 0 || data->d == 0 ) {
- hd = 0;
- rendhd = 0;
-#if defined(TQT_CHECK_RANGE)
- if ( !make_null )
- qWarning( "TQPixmap: Invalid pixmap parameters" );
-#endif
- return;
- }
- data->w = w;
- data->h = h;
- hd = (HANDLE)XCreatePixmap( x11Display(), RootWindow(x11Display(), x11Screen() ),
- w, h, data->d );
-
-#ifndef TQT_NO_XFTFREETYPE
- if ( qt_has_xft ) {
- if ( data->d == 1 ) {
- rendhd = (HANDLE) XftDrawCreateBitmap( x11Display(), hd );
- } else {
- rendhd = (HANDLE) XftDrawCreate( x11Display(), hd,
- (Visual *) x11Visual(),
- x11Colormap() );
- }
- }
-#endif // TQT_NO_XFTFREETYPE
-
-}
-
-
-void TQPixmap::deref()
-{
- if ( data && data->deref() ) { // last reference lost
- delete data->mask;
- delete data->alphapm;
- if ( data->ximage )
- qSafeXDestroyImage( (XImage*)data->ximage );
- if ( data->maskgc )
- XFreeGC( x11Display(), (GC)data->maskgc );
- if ( tqApp && hd) {
-
-#ifndef TQT_NO_XFTFREETYPE
- if (rendhd) {
- XftDrawDestroy( (XftDraw *) rendhd );
- rendhd = 0;
- }
-#endif // TQT_NO_XFTFREETYPE
-
- XFreePixmap( x11Display(), hd );
- hd = 0;
- }
- delete data;
- }
-}
-
-
-/*!
- Constructs a monochrome pixmap, with width \a w and height \a h,
- that is initialized with the data in \a bits. The \a isXbitmap
- indicates whether the data is an X bitmap and defaults to FALSE.
- This constructor is protected and used by the TQBitmap class.
-*/
-
-TQPixmap::TQPixmap( int w, int h, const uchar *bits, bool isXbitmap)
- : TQPaintDevice( TQInternal::Pixmap )
-{ // for bitmaps only
- init( 0, 0, 0, FALSE, defOptim );
- if ( w <= 0 || h <= 0 ) // create null pixmap
- return;
-
- data->uninit = FALSE;
- data->w = w;
- data->h = h;
- data->d = 1;
- uchar *flipped_bits;
- if ( isXbitmap ) {
- flipped_bits = 0;
- } else { // not X bitmap -> flip bits
- flipped_bits = flip_bits( bits, ((w+7)/8)*h );
- bits = flipped_bits;
- }
- hd = (HANDLE)XCreateBitmapFromData( x11Display(),
- RootWindow(x11Display(), x11Screen() ),
- (char *)bits, w, h );
-
-#ifndef TQT_NO_XFTFREETYPE
- if ( qt_has_xft )
- rendhd = (HANDLE) XftDrawCreateBitmap (x11Display (), hd);
-#endif // TQT_NO_XFTFREETYPE
-
- if ( flipped_bits ) // Avoid purify complaint
- delete [] flipped_bits;
-}
-
-
-/*!
- This is a special-purpose function that detaches the pixmap from
- shared pixmap data.
-
- A pixmap is automatically detached by TQt whenever its contents is
- about to change. This is done in all TQPixmap member functions
- that modify the pixmap (fill(), resize(), convertFromImage(),
- load(), etc.), in bitBlt() for the destination pixmap and in
- TQPainter::begin() on a pixmap.
-
- It is possible to modify a pixmap without letting TQt know. You can
- first obtain the system-dependent handle() and then call
- system-specific functions (for instance, BitBlt under Windows)
- that modify the pixmap contents. In such cases, you can call
- detach() to cut the pixmap loose from other pixmaps that share
- data with this one.
-
- detach() returns immediately if there is just a single reference
- or if the pixmap has not been initialized yet.
-*/
-
-void TQPixmap::detach()
-{
- if ( data->count != 1 )
- *this = copy();
- data->uninit = FALSE;
-
- // reset cached data
- if ( data->ximage ) {
- qSafeXDestroyImage( (XImage*)data->ximage );
- data->ximage = 0;
- }
- if ( data->maskgc ) {
- XFreeGC( x11Display(), (GC)data->maskgc );
- data->maskgc = 0;
- }
-}
-
-
-/*!
- Returns the default pixmap depth, i.e. the depth a pixmap gets if
- -1 is specified.
-
- \sa depth()
-*/
-
-int TQPixmap::defaultDepth()
-{
- return x11AppDepth();
-}
-
-
-/*!
- \fn TQPixmap::Optimization TQPixmap::optimization() const
-
- Returns the optimization setting for this pixmap.
-
- The default optimization setting is \c TQPixmap::NormalOptim. You
- can change this setting in two ways:
- \list
- \i Call setDefaultOptimization() to set the default optimization
- for all new pixmaps.
- \i Call setOptimization() to set the optimization for individual
- pixmaps.
- \endlist
-
- \sa setOptimization(), setDefaultOptimization(), defaultOptimization()
-*/
-
-/*!
- Sets pixmap drawing optimization for this pixmap.
-
- The \a optimization setting affects pixmap operations, in
- particular drawing of transparent pixmaps (bitBlt() a pixmap with
- a mask set) and pixmap transformations (the xForm() function).
-
- Pixmap optimization involves keeping intermediate results in a
- cache buffer and using the cache to speed up bitBlt() and xForm().
- The cost is more memory consumption, up to twice as much as an
- unoptimized pixmap.
-
- Use the setDefaultOptimization() to change the default
- optimization for all new pixmaps.
-
- \sa optimization(), setDefaultOptimization(), defaultOptimization()
-*/
-
-void TQPixmap::setOptimization( Optimization optimization )
-{
- if ( optimization == data->optim )
- return;
- detach();
- data->optim = optimization == DefaultOptim ?
- defOptim : optimization;
- if ( data->optim == MemoryOptim && data->ximage ) {
- qSafeXDestroyImage( (XImage*)data->ximage );
- data->ximage = 0;
- }
-}
-
-
-/*!
- Fills the pixmap with the color \a fillColor.
-*/
-
-void TQPixmap::fill( const TQColor &fillColor )
-{
- if ( isNull() )
- return;
- detach(); // detach other references
- GC gc = qt_xget_temp_gc( x11Screen(), depth()==1 );
- XSetForeground( x11Display(), gc, fillColor.pixel(x11Screen()) );
- XFillRectangle( x11Display(), hd, gc, 0, 0, width(), height() );
-}
-
-
-/*!
- Internal implementation of the virtual TQPaintDevice::metric() function.
-
- Use the TQPaintDeviceMetrics class instead.
-
- \a m is the metric to get.
-*/
-
-int TQPixmap::metric( int m ) const
-{
- int val;
- if ( m == TQPaintDeviceMetrics::PdmWidth )
- val = width();
- else if ( m == TQPaintDeviceMetrics::PdmHeight ) {
- val = height();
- } else {
- Display *dpy = x11Display();
- int scr = x11Screen();
- switch ( m ) {
- case TQPaintDeviceMetrics::PdmDpiX:
- case TQPaintDeviceMetrics::PdmPhysicalDpiX:
- val = TQPaintDevice::x11AppDpiX( scr );
- break;
- case TQPaintDeviceMetrics::PdmDpiY:
- case TQPaintDeviceMetrics::PdmPhysicalDpiY:
- val = TQPaintDevice::x11AppDpiY( scr );
- break;
- case TQPaintDeviceMetrics::PdmWidthMM:
- val = (DisplayWidthMM(dpy,scr)*width())/
- DisplayWidth(dpy,scr);
- break;
- case TQPaintDeviceMetrics::PdmHeightMM:
- val = (DisplayHeightMM(dpy,scr)*height())/
- DisplayHeight(dpy,scr);
- break;
- case TQPaintDeviceMetrics::PdmNumColors:
- val = 1 << depth();
- break;
- case TQPaintDeviceMetrics::PdmDepth:
- val = depth();
- break;
- default:
- val = 0;
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPixmap::metric: Invalid metric command" );
-#endif
- }
- }
- return val;
-}
-
-/*!
- Converts the pixmap to a TQImage. Returns a null image if it fails.
-
- If the pixmap has 1-bit depth, the returned image will also be 1
- bit deep. If the pixmap has 2- to 8-bit depth, the returned image
- has 8-bit depth. If the pixmap has greater than 8-bit depth, the
- returned image has 32-bit depth.
-
- Note that for the moment, alpha masks on monochrome images are
- ignored.
-
- \sa convertFromImage()
-*/
-
-TQImage TQPixmap::convertToImage() const
-{
- TQImage image;
- if ( isNull() )
- return image; // null image
-
- int w = width();
- int h = height();
- int d = depth();
- bool mono = d == 1;
- Visual *visual = (Visual *)x11Visual();
- bool trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor) && !mono && d > 8;
-
- if ( d > 1 && d <= 8 ) // set to nearest valid depth
- d = 8; // 2..8 ==> 8
- // we could run into the situation where d == 8 AND trucol is true, which can
- // cause problems when converting to and from images. in this case, always treat
- // the depth as 32... from Klaus Schmidinger and qt-bugs/arc-15/31333.
- if ( d > 8 || trucol )
- d = 32; // > 8 ==> 32
-
- XImage *xi = (XImage *)data->ximage; // any cached ximage?
-#ifdef TQT_MITSHM_CONVERSIONS
- bool mitshm_ximage = false;
- XShmSegmentInfo shminfo;
-#endif
- if ( !xi ) { // fetch data from X server
-#ifdef TQT_MITSHM_CONVERSIONS
- xi = qt_XShmGetImage( this, mono ? XYPixmap : ZPixmap, &shminfo );
- if( xi ) {
- mitshm_ximage = true;
- } else
-#endif
- xi = XGetImage( x11Display(), hd, 0, 0, w, h, AllPlanes,
- mono ? XYPixmap : ZPixmap );
- }
- TQ_CHECK_PTR( xi );
- if (!xi)
- return image; // null image
-
- TQImage::Endian bitOrder = TQImage::IgnoreEndian;
- if ( mono ) {
- bitOrder = xi->bitmap_bit_order == LSBFirst ?
- TQImage::LittleEndian : TQImage::BigEndian;
- }
- image.create( w, h, d, 0, bitOrder );
- if ( image.isNull() ) { // could not create image
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage )
- qt_XShmDestroyImage( xi, &shminfo );
- else
-#endif
- qSafeXDestroyImage( xi );
- return image;
- }
-
- const TQPixmap* msk = mask();
- const TQPixmap *alf = data->alphapm;
-
- TQImage alpha;
- if (alf) {
- XImage* axi;
-#ifdef TQT_MITSHM_CONVERSIONS
- bool mitshm_aximage = false;
- XShmSegmentInfo ashminfo;
- axi = qt_XShmGetImage( alf, ZPixmap, &ashminfo );
- if( axi ) {
- mitshm_aximage = true;
- } else
-#endif
- axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
-
- if (axi) {
- image.setAlphaBuffer( TRUE );
- alpha.create(w, h, 8);
-
- // copy each scanline
- char *src = axi->data;
- int bpl = TQMIN(alpha.bytesPerLine(), axi->bytes_per_line);
- for (int y = 0; y < h; y++ ) {
- memcpy( alpha.scanLine(y), src, bpl );
- src += axi->bytes_per_line;
- }
-
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_aximage )
- qt_XShmDestroyImage( axi, &ashminfo );
- else
-#endif
- qSafeXDestroyImage( axi );
- }
- } else if (msk) {
- image.setAlphaBuffer( TRUE );
- alpha = msk->convertToImage();
- }
- bool ale = alpha.bitOrder() == TQImage::LittleEndian;
-
- if ( trucol ) { // truecolor
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit( red_mask ) - 7;
- const int green_shift = highest_bit( green_mask ) - 7;
- const int blue_shift = highest_bit( blue_mask ) - 7;
-
- const uint red_bits = n_bits( red_mask );
- const uint green_bits = n_bits( green_mask );
- const uint blue_bits = n_bits( blue_mask );
-
- static uint red_table_bits = 0;
- static uint green_table_bits = 0;
- static uint blue_table_bits = 0;
-
- if ( red_bits < 8 && red_table_bits != red_bits) {
- build_scale_table( &red_scale_table, red_bits );
- red_table_bits = red_bits;
- }
- if ( blue_bits < 8 && blue_table_bits != blue_bits) {
- build_scale_table( &blue_scale_table, blue_bits );
- blue_table_bits = blue_bits;
- }
- if ( green_bits < 8 && green_table_bits != green_bits) {
- build_scale_table( &green_scale_table, green_bits );
- green_table_bits = green_bits;
- }
-
- int r, g, b;
-
- TQRgb *dst;
- uchar *src;
- uint pixel;
- int bppc = xi->bits_per_pixel;
-
- if ( bppc > 8 && xi->byte_order == LSBFirst )
- bppc++;
-
- for ( int y=0; y<h; y++ ) {
- uchar* asrc = alf || msk ? alpha.scanLine( y ) : 0;
- dst = (TQRgb *)image.scanLine( y );
- src = (uchar *)xi->data + xi->bytes_per_line*y;
- for ( int x=0; x<w; x++ ) {
- switch ( bppc ) {
- case 8:
- pixel = *src++;
- break;
- case 16: // 16 bit MSB
- pixel = src[1] | (ushort)src[0] << 8;
- src += 2;
- break;
- case 17: // 16 bit LSB
- pixel = src[0] | (ushort)src[1] << 8;
- src += 2;
- break;
- case 24: // 24 bit MSB
- pixel = src[2] | (ushort)src[1] << 8 |
- (uint)src[0] << 16;
- src += 3;
- break;
- case 25: // 24 bit LSB
- pixel = src[0] | (ushort)src[1] << 8 |
- (uint)src[2] << 16;
- src += 3;
- break;
- case 32: // 32 bit MSB
- pixel = src[3] | (ushort)src[2] << 8 |
- (uint)src[1] << 16 | (uint)src[0] << 24;
- src += 4;
- break;
- case 33: // 32 bit LSB
- pixel = src[0] | (ushort)src[1] << 8 |
- (uint)src[2] << 16 | (uint)src[3] << 24;
- src += 4;
- break;
- default: // should not really happen
- x = w; // leave loop
- y = h;
- pixel = 0; // eliminate compiler warning
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPixmap::convertToImage: Invalid depth %d",
- bppc );
-#endif
- }
- if ( red_shift > 0 )
- r = (pixel & red_mask) >> red_shift;
- else
- r = (pixel & red_mask) << -red_shift;
- if ( green_shift > 0 )
- g = (pixel & green_mask) >> green_shift;
- else
- g = (pixel & green_mask) << -green_shift;
- if ( blue_shift > 0 )
- b = (pixel & blue_mask) >> blue_shift;
- else
- b = (pixel & blue_mask) << -blue_shift;
-
- if ( red_bits < 8 )
- r = red_scale_table[r];
- if ( green_bits < 8 )
- g = green_scale_table[g];
- if ( blue_bits < 8 )
- b = blue_scale_table[b];
-
- if (alf) {
- *dst++ = tqRgba(r, g, b, asrc[x]);
- } else if (msk) {
- if ( ale ) {
- *dst++ = (asrc[x >> 3] & (1 << (x & 7)))
- ? tqRgba(r, g, b, 0xff) : tqRgba(r, g, b, 0x00);
- } else {
- *dst++ = (asrc[x >> 3] & (1 << (7 -(x & 7))))
- ? tqRgba(r, g, b, 0xff) : tqRgba(r, g, b, 0x00);
- }
- } else {
- *dst++ = tqRgb(r, g, b);
- }
- }
- }
- } else if ( xi->bits_per_pixel == d ) { // compatible depth
- char *xidata = xi->data; // copy each scanline
- int bpl = TQMIN(image.bytesPerLine(),xi->bytes_per_line);
- for ( int y=0; y<h; y++ ) {
- memcpy( image.scanLine(y), xidata, bpl );
- xidata += xi->bytes_per_line;
- }
- } else {
- /* Typically 2 or 4 bits display depth */
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPixmap::convertToImage: Display not supported (bpp=%d)",
- xi->bits_per_pixel );
-#endif
- image.reset();
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage )
- qt_XShmDestroyImage( xi, &shminfo );
- else
-#endif
- qSafeXDestroyImage( xi );
- return image;
- }
-
- if ( mono ) { // bitmap
- image.setNumColors( 2 );
- image.setColor( 0, tqRgb(255,255,255) );
- image.setColor( 1, tqRgb(0,0,0) );
- } else if ( !trucol ) { // pixmap with colormap
- register uchar *p;
- uchar *end;
- uchar use[256]; // pixel-in-use table
- uchar pix[256]; // pixel translation table
- int ncols, i, bpl;
- memset( use, 0, 256 );
- memset( pix, 0, 256 );
- bpl = image.bytesPerLine();
-
- if (msk) { // which pixels are used?
- for ( i=0; i<h; i++ ) {
- uchar* asrc = alpha.scanLine( i );
- p = image.scanLine( i );
- for ( int x = 0; x < w; x++ ) {
- if ( ale ) {
- if (asrc[x >> 3] & (1 << (x & 7)))
- use[*p] = 1;
- } else {
- if (asrc[x >> 3] & (1 << (7 -(x & 7))))
- use[*p] = 1;
- }
- ++p;
- }
- }
- } else {
- for ( i=0; i<h; i++ ) {
- p = image.scanLine( i );
- end = p + bpl;
- while ( p < end )
- use[*p++] = 1;
- }
- }
- ncols = 0;
- for ( i=0; i<256; i++ ) { // build translation table
- if ( use[i] )
- pix[i] = ncols++;
- }
- for ( i=0; i<h; i++ ) { // translate pixels
- p = image.scanLine( i );
- end = p + bpl;
- while ( p < end ) {
- *p = pix[*p];
- p++;
- }
- }
-
- Colormap cmap = x11Colormap();
- int ncells = x11Cells();
- XColor *carr = new XColor[ncells];
- for ( i=0; i<ncells; i++ )
- carr[i].pixel = i;
- // Get default colormap
- XQueryColors( x11Display(), cmap, carr, ncells );
-
- if (msk) {
- int trans;
- if (ncols < 256) {
- trans = ncols++;
- image.setNumColors( ncols ); // create color table
- image.setColor( trans, 0x00000000 );
- } else {
- image.setNumColors( ncols ); // create color table
- // oh dear... no spare "transparent" pixel.
- // use first pixel in image (as good as any).
- trans = image.scanLine( i )[0];
- }
- for ( i=0; i<h; i++ ) {
- uchar* asrc = alpha.scanLine( i );
- p = image.scanLine( i );
- for ( int x = 0; x < w; x++ ) {
- if ( ale ) {
- if (!(asrc[x >> 3] & (1 << (x & 7))))
- *p = trans;
- } else {
- if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
- *p = trans;
- }
- ++p;
- }
- }
- } else {
- image.setNumColors( ncols ); // create color table
- }
- int j = 0;
- for ( i=0; i<256; i++ ) { // translate pixels
- if ( use[i] ) {
- image.setColor( j++,
- ( msk ? 0xff000000 : 0 )
- | tqRgb( (carr[i].red >> 8) & 255,
- (carr[i].green >> 8) & 255,
- (carr[i].blue >> 8) & 255 ) );
- }
- }
-
- delete [] carr;
- }
- if ( data->optim != BestOptim ) { // throw away image data
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage )
- qt_XShmDestroyImage( xi, &shminfo );
- else
-#endif
- qSafeXDestroyImage( xi );
- ((TQPixmap*)this)->data->ximage = 0;
- } else { // keep ximage data
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage ) { // copy the XImage?
- qt_XShmDestroyImage( xi, &shminfo );
- xi = 0;
- }
-#endif
- ((TQPixmap*)this)->data->ximage = xi;
- }
-
- return image;
-}
-
-
-/*!
- Converts image \a img and sets this pixmap. Returns TRUE if
- successful; otherwise returns FALSE.
-
- The \a conversion_flags argument is a bitwise-OR of the
- \l{TQt::ImageConversionFlags}. Passing 0 for \a conversion_flags
- sets all the default options.
-
- Note that even though a TQPixmap with depth 1 behaves much like a
- TQBitmap, isTQBitmap() returns FALSE.
-
- If a pixmap with depth 1 is painted with color0 and color1 and
- converted to an image, the pixels painted with color0 will produce
- pixel index 0 in the image and those painted with color1 will
- produce pixel index 1.
-
- \sa convertToImage(), isTQBitmap(), TQImage::convertDepth(),
- defaultDepth(), TQImage::hasAlphaBuffer()
-*/
-
-bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
-{
- if ( img.isNull() ) {
-#if defined(TQT_CHECK_NULL)
- qWarning( "TQPixmap::convertFromImage: Cannot convert a null image" );
-#endif
- return FALSE;
- }
- detach(); // detach other references
- TQImage image = img;
- const uint w = image.width();
- const uint h = image.height();
- int d = image.depth();
- const int dd = x11Depth();
- bool force_mono = (dd == 1 || isTQBitmap() ||
- (conversion_flags & ColorMode_Mask)==MonoOnly );
-
- if ( w >= 32768 || h >= 32768 )
- return FALSE;
-
- // get rid of the mask
- delete data->mask;
- data->mask = 0;
-
- // get rid of alpha pixmap
- delete data->alphapm;
- data->alphapm = 0;
-
- // must be monochrome
- if ( force_mono ) {
- if ( d != 1 ) {
- // dither
- image = image.convertDepth( 1, conversion_flags );
- d = 1;
- }
- } else { // can be both
- bool conv8 = FALSE;
- if ( d > 8 && dd <= 8 ) { // convert to 8 bit
- if ( (conversion_flags & DitherMode_Mask) == AutoDither )
- conversion_flags = (conversion_flags & ~DitherMode_Mask)
- | PreferDither;
- conv8 = TRUE;
- } else if ( (conversion_flags & ColorMode_Mask) == ColorOnly ) {
- conv8 = d == 1; // native depth wanted
- } else if ( d == 1 ) {
- if ( image.numColors() == 2 ) {
- TQRgb c0 = image.color(0); // Auto: convert to best
- TQRgb c1 = image.color(1);
- conv8 = TQMIN(c0,c1) != tqRgb(0,0,0) || TQMAX(c0,c1) != tqRgb(255,255,255);
- } else {
- // eg. 1-color monochrome images (they do exist).
- conv8 = TRUE;
- }
- }
- if ( conv8 ) {
- image = image.convertDepth( 8, conversion_flags );
- d = 8;
- }
- }
-
- if ( d == 1 ) { // 1 bit pixmap (bitmap)
- if ( hd ) { // delete old X pixmap
-
-#ifndef TQT_NO_XFTFREETYPE
- if (rendhd) {
- XftDrawDestroy( (XftDraw *) rendhd );
- rendhd = 0;
- }
-#endif // TQT_NO_XFTFREETYPE
-
- XFreePixmap( x11Display(), hd );
- }
-
- // make sure image.color(0) == color0 (white) and image.color(1) == color1 (black)
- if (image.color(0) == TQt::black.rgb() && image.color(1) == TQt::white.rgb()) {
- image.invertPixels();
- image.setColor(0, TQt::white.rgb());
- image.setColor(1, TQt::black.rgb());
- }
-
- char *bits;
- uchar *tmp_bits;
- int bpl = (w+7)/8;
- int ibpl = image.bytesPerLine();
- if ( image.bitOrder() == TQImage::BigEndian || bpl != ibpl ) {
- tmp_bits = new uchar[bpl*h];
- TQ_CHECK_PTR( tmp_bits );
- bits = (char *)tmp_bits;
- uchar *p, *b, *end;
- uint y, count;
- if ( image.bitOrder() == TQImage::BigEndian ) {
- const uchar *f = qt_get_bitflip_array();
- b = tmp_bits;
- for ( y=0; y<h; y++ ) {
- p = image.scanLine( y );
- end = p + bpl;
- count = bpl;
- while ( count > 4 ) {
- *b++ = f[*p++];
- *b++ = f[*p++];
- *b++ = f[*p++];
- *b++ = f[*p++];
- count -= 4;
- }
- while ( p < end )
- *b++ = f[*p++];
- }
- } else { // just copy
- b = tmp_bits;
- p = image.scanLine( 0 );
- for ( y=0; y<h; y++ ) {
- memcpy( b, p, bpl );
- b += bpl;
- p += ibpl;
- }
- }
- } else {
- bits = (char *)image.bits();
- tmp_bits = 0;
- }
- hd = (HANDLE)XCreateBitmapFromData( x11Display(),
- RootWindow(x11Display(), x11Screen() ),
- bits, w, h );
-
-#ifndef TQT_NO_XFTFREETYPE
- if ( qt_has_xft )
- rendhd = (HANDLE) XftDrawCreateBitmap( x11Display(), hd );
-#endif // TQT_NO_XFTFREETYPE
-
- if ( tmp_bits ) // Avoid purify complaint
- delete [] tmp_bits;
- data->w = w; data->h = h; data->d = 1;
-
- if ( image.hasAlphaBuffer() ) {
- TQBitmap m;
- m = image.createAlphaMask( conversion_flags );
- setMask( m );
- }
- return TRUE;
- }
-
- Display *dpy = x11Display();
- Visual *visual = (Visual *)x11Visual();
- XImage *xi = 0;
- bool trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor);
- int nbytes = image.numBytes();
- uchar *newbits= 0;
- int newbits_size = 0;
-#ifdef TQT_MITSHM_CONVERSIONS
- bool mitshm_ximage = false;
- XShmSegmentInfo shminfo;
-#endif
-
- if ( trucol ) { // truecolor display
- TQRgb pix[256]; // pixel translation table
- const bool d8 = d == 8;
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit( red_mask ) - 7;
- const int green_shift = highest_bit( green_mask ) - 7;
- const int blue_shift = highest_bit( blue_mask ) - 7;
- const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
- const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
- const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
-
- if ( d8 ) { // setup pixel translation
- TQRgb *ctable = image.colorTable();
- for ( int i=0; i<image.numColors(); i++ ) {
- int r = tqRed (ctable[i]);
- int g = tqGreen(ctable[i]);
- int b = tqBlue (ctable[i]);
- r = red_shift > 0 ? r << red_shift : r >> -red_shift;
- g = green_shift > 0 ? g << green_shift : g >> -green_shift;
- b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
- pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
- | ~(blue_mask | green_mask | red_mask);
- }
- }
-
-#ifdef TQT_MITSHM_CONVERSIONS
- xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
- if( xi != NULL ) {
- mitshm_ximage = true;
- newbits = (uchar*)xi->data;
- }
- else
-#endif
- xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
- if (!xi)
- return false;
- if( newbits == NULL )
- newbits = (uchar *)malloc( xi->bytes_per_line*h );
- TQ_CHECK_PTR( newbits );
- if ( !newbits ) // no memory
- return FALSE;
- int bppc = xi->bits_per_pixel;
-
- bool contig_bits = n_bits(red_mask) == rbits &&
- n_bits(green_mask) == gbits &&
- n_bits(blue_mask) == bbits;
- bool dither_tc =
- // Want it?
- (conversion_flags & Dither_Mask) != ThresholdDither &&
- (conversion_flags & DitherMode_Mask) != AvoidDither &&
- // Need it?
- bppc < 24 && !d8 &&
- // Can do it? (Contiguous bits?)
- contig_bits;
-
- static bool init=FALSE;
- static int D[16][16];
- if ( dither_tc && !init ) {
- // I also contributed this code to XV - WWA.
- /*
- The dither matrix, D, is obtained with this formula:
-
- D2 = [ 0 2 ]
- [ 3 1 ]
-
-
- D2*n = [ 4*Dn 4*Dn+2*Un ]
- [ 4*Dn+3*Un 4*Dn+1*Un ]
- */
- int n,i,j;
- init=1;
-
- /* Set D2 */
- D[0][0]=0;
- D[1][0]=2;
- D[0][1]=3;
- D[1][1]=1;
-
- /* Expand using recursive definition given above */
- for (n=2; n<16; n*=2) {
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- D[i][j]*=4;
- D[i+n][j]=D[i][j]+2;
- D[i][j+n]=D[i][j]+3;
- D[i+n][j+n]=D[i][j]+1;
- }
- }
- }
- init=TRUE;
- }
-
- enum { BPP8,
- BPP16_8_3_M3, BPP16_7_2_M3, BPP16_MSB, BPP16_LSB,
- BPP24_MSB, BPP24_LSB,
- BPP32_16_8_0, BPP32_MSB, BPP32_LSB
- } mode = BPP8;
-
- if ( bppc > 8 && xi->byte_order == LSBFirst )
- bppc++;
-
- int wordsize;
- bool bigendian;
- qSysInfo( &wordsize, &bigendian );
- bool same_msb_lsb = ( xi->byte_order == MSBFirst ) == ( bigendian );
-
- if( bppc == 8 ) // 8 bit
- mode = BPP8;
- else if( bppc == 16 || bppc == 17 ) { // 16 bit MSB/LSB
- if( red_shift == 8 && green_shift == 3 && blue_shift == -3
- && !d8 && same_msb_lsb )
- mode = BPP16_8_3_M3;
- else if( red_shift == 7 && green_shift == 2 && blue_shift == -3
- && !d8 && same_msb_lsb )
- mode = BPP16_7_2_M3;
- else
- mode = bppc == 17 ? BPP16_LSB : BPP16_MSB;
- } else if( bppc == 24 || bppc == 25 ) { // 24 bit MSB/LSB
- mode = bppc == 25 ? BPP24_LSB : BPP24_MSB;
- } else if( bppc == 32 || bppc == 33 ) { // 32 bit MSB/LSB
- if( red_shift == 16 && green_shift == 8 && blue_shift == 0
- && !d8 && same_msb_lsb )
- mode = BPP32_16_8_0;
- else
- mode = bppc == 33 ? BPP32_LSB : BPP32_MSB;
- } else
- qFatal("Logic error 3");
-
-#define GET_PIXEL \
- int pixel; \
- if ( d8 ) pixel = pix[*src++]; \
- else { \
- int r = tqRed ( *p ); \
- int g = tqGreen( *p ); \
- int b = tqBlue ( *p++ ); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
- | ~(blue_mask | green_mask | red_mask); \
- }
-
-// optimized case - no d8 case, shift only once instead of twice, mask only once instead of twice,
-// use direct values instead of variables, and use only one statement
-// (*p >> 16), (*p >> 8 ) and (*p) are tqRed(),tqGreen() and tqBlue() without masking
-// shifts have to be passed including the shift operator (e.g. '>>3'), because of the direction
-#define GET_PIXEL_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask) \
- int pixel = ((( *p >> 16 ) red_shift ) & red_mask ) \
- | ((( *p >> 8 ) green_shift ) & green_mask ) \
- | ((( *p ) blue_shift ) & blue_mask ); \
- ++p;
-
-
-#define GET_PIXEL_DITHER_TC \
- int r = tqRed ( *p ); \
- int g = tqGreen( *p ); \
- int b = tqBlue ( *p++ ); \
- const int thres = D[x%16][y%16]; \
- if ( r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- if ( g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- if ( b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- int pixel = (b & blue_mask)|(g & green_mask) | (r & red_mask);
-
-// again, optimized case
-// can't be optimized that much :(
-#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
- rbits,gbits,bbits) \
- const int thres = D[x%16][y%16]; \
- int r = tqRed ( *p ); \
- if ( r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- int g = tqGreen( *p ); \
- if ( g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- int b = tqBlue ( *p++ ); \
- if ( b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- int pixel = (( r red_shift ) & red_mask ) \
- | (( g green_shift ) & green_mask ) \
- | (( b blue_shift ) & blue_mask );
-
-#define CYCLE(body) \
- for ( uint y=0; y<h; y++ ) { \
- uchar* src = image.scanLine( y ); \
- uchar* dst = newbits + xi->bytes_per_line*y; \
- TQRgb* p = (TQRgb *)src; \
- body \
- }
-
- if ( dither_tc ) {
- switch ( mode ) {
- case BPP16_8_3_M3:
- CYCLE(
- TQ_INT16* dst16 = (TQ_INT16*)dst;
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_7_2_M3:
- CYCLE(
- TQ_INT16* dst16 = (TQ_INT16*)dst;
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f)
- *dst16++ = pixel;
- }
- )
- break;
- default:
- qFatal("Logic error");
- }
- } else {
- switch ( mode ) {
- case BPP8: // 8 bit
- CYCLE(
- Q_UNUSED(p);
- for ( uint x=0; x<w; x++ ) {
- int pixel = pix[*src++];
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_8_3_M3:
- CYCLE(
- TQ_INT16* dst16 = (TQ_INT16*)dst;
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_7_2_M3:
- CYCLE(
- TQ_INT16* dst16 = (TQ_INT16*)dst;
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL_DITHER_TC
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL_DITHER_TC
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- case BPP24_MSB: // 24 bit MSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case 33: // 32 bit LSB
- case BPP24_LSB: // 24 bit LSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- }
- )
- break;
- case BPP32_16_8_0:
- CYCLE(
- memcpy( dst, p, w * 4 );
- )
- break;
- case BPP32_MSB: // 32 bit MSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel >> 24;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP32_LSB: // 32 bit LSB
- CYCLE(
- for ( uint x=0; x<w; x++ ) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 24;
- }
- )
- break;
- default:
- qFatal("Logic error 2");
- }
- }
- xi->data = (char *)newbits;
- }
-
- if ( d == 8 && !trucol ) { // 8 bit pixmap
- int pop[256]; // pixel popularity
-
- if ( image.numColors() == 0 )
- image.setNumColors( 1 );
-
- memset( pop, 0, sizeof(int)*256 ); // reset popularity array
- uint i;
- for ( i=0; i<h; i++ ) { // for each scanline...
- uchar* p = image.scanLine( i );
- uchar *end = p + w;
- while ( p < end ) // compute popularity
- pop[*p++]++;
- }
-
- newbits = (uchar *)malloc( nbytes ); // copy image into newbits
- newbits_size = nbytes;
- TQ_CHECK_PTR( newbits );
- if ( !newbits ) // no memory
- return FALSE;
- uchar* p = newbits;
- memcpy( p, image.bits(), nbytes ); // copy image data into newbits
-
- /*
- * The code below picks the most important colors. It is based on the
- * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
- */
-
- struct PIX { // pixel sort element
- uchar r,g,b,n; // color + pad
- int use; // popularity
- int index; // index in colormap
- int mindist;
- };
- int ncols = 0;
- for ( i=0; i< (uint) image.numColors(); i++ ) { // compute number of colors
- if ( pop[i] > 0 )
- ncols++;
- }
- for ( i=image.numColors(); i<256; i++ ) // ignore out-of-range pixels
- pop[i] = 0;
-
- // works since we make sure above to have at least
- // one color in the image
- if ( ncols == 0 )
- ncols = 1;
-
- PIX pixarr[256]; // pixel array
- PIX pixarr_sorted[256]; // pixel array (sorted)
- memset( pixarr, 0, ncols*sizeof(PIX) );
- PIX *px = &pixarr[0];
- int maxpop = 0;
- int maxpix = 0;
- TQ_CHECK_PTR( pixarr );
- uint j = 0;
- TQRgb* ctable = image.colorTable();
- for ( i=0; i<256; i++ ) { // init pixel array
- if ( pop[i] > 0 ) {
- px->r = tqRed ( ctable[i] );
- px->g = tqGreen( ctable[i] );
- px->b = tqBlue ( ctable[i] );
- px->n = 0;
- px->use = pop[i];
- if ( pop[i] > maxpop ) { // select most popular entry
- maxpop = pop[i];
- maxpix = j;
- }
- px->index = i;
- px->mindist = 1000000;
- px++;
- j++;
- }
- }
- pixarr_sorted[0] = pixarr[maxpix];
- pixarr[maxpix].use = 0;
-
- for ( i=1; i< (uint) ncols; i++ ) { // sort pixels
- int minpix = -1, mindist = -1;
- px = &pixarr_sorted[i-1];
- int r = px->r;
- int g = px->g;
- int b = px->b;
- int dist;
- if ( (i & 1) || i<10 ) { // sort on max distance
- for ( int j=0; j<ncols; j++ ) {
- px = &pixarr[j];
- if ( px->use ) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if ( px->mindist > dist )
- px->mindist = dist;
- if ( px->mindist > mindist ) {
- mindist = px->mindist;
- minpix = j;
- }
- }
- }
- } else { // sort on max popularity
- for ( int j=0; j<ncols; j++ ) {
- px = &pixarr[j];
- if ( px->use ) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if ( px->mindist > dist )
- px->mindist = dist;
- if ( px->use > mindist ) {
- mindist = px->use;
- minpix = j;
- }
- }
- }
- }
- pixarr_sorted[i] = pixarr[minpix];
- pixarr[minpix].use = 0;
- }
-
- uint pix[256]; // pixel translation table
- px = &pixarr_sorted[0];
- for ( i=0; i< (uint) ncols; i++ ) { // allocate colors
- TQColor c( px->r, px->g, px->b );
- pix[px->index] = c.pixel(x11Screen());
- px++;
- }
-
- p = newbits;
- for ( i=0; i< (uint) nbytes; i++ ) { // translate pixels
- *p = pix[*p];
- p++;
- }
- }
-
- if ( !xi ) {
-#ifdef TQT_MITSHM_CONVERSIONS
- xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
- if( xi != NULL )
- mitshm_ximage = true;
- else
-#endif // X image not created
- xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
- if ( xi->bits_per_pixel == 16 ) { // convert 8 bpp ==> 16 bpp
- ushort *p2;
- int p2inc = xi->bytes_per_line/sizeof(ushort);
- ushort *newerbits = (ushort *)malloc( xi->bytes_per_line * h );
- newbits_size = xi->bytes_per_line * h;
- TQ_CHECK_PTR( newerbits );
- if ( !newerbits ) // no memory
- return FALSE;
- uchar* p = newbits;
- for ( uint y=0; y<h; y++ ) { // OOPS: Do right byte order!!
- p2 = newerbits + p2inc*y;
- for ( uint x=0; x<w; x++ )
- *p2++ = *p++;
- }
- free( newbits );
- newbits = (uchar *)newerbits;
- } else if ( xi->bits_per_pixel != 8 ) {
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPixmap::convertFromImage: Display not supported "
- "(bpp=%d)", xi->bits_per_pixel );
-#endif
- }
-#ifdef TQT_MITSHM_CONVERSIONS
- if( newbits_size > 0 && mitshm_ximage ) { // need to copy to shared memory
- memcpy( xi->data, newbits, newbits_size );
- free( newbits );
- newbits = (uchar*)xi->data;
- }
- else
-#endif
- xi->data = (char *)newbits;
- }
-
- if ( hd && (width() != (int)w || height() != (int)h || this->depth() != dd) ) {
-
-#ifndef TQT_NO_XFTFREETYPE
- if (rendhd) {
- XftDrawDestroy( (XftDraw *) rendhd );
- rendhd = 0;
- }
-#endif // TQT_NO_XFTFREETYPE
-
- XFreePixmap( dpy, hd ); // don't reuse old pixmap
- hd = 0;
- }
- if ( !hd ) { // create new pixmap
- hd = (HANDLE)XCreatePixmap( x11Display(),
- RootWindow(x11Display(), x11Screen() ),
- w, h, dd );
-
-#ifndef TQT_NO_XFTFREETYPE
- if ( qt_has_xft ) {
- if ( data->d == 1 ) {
- rendhd = (HANDLE) XftDrawCreateBitmap( x11Display (), hd );
- } else {
- rendhd = (HANDLE) XftDrawCreate( x11Display (), hd,
- (Visual *) x11Visual(), x11Colormap() );
- }
- }
-#endif // TQT_NO_XFTFREETYPE
-
- }
-
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage )
- XShmPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE ),
- xi, 0, 0, 0, 0, w, h, False );
- else
-#endif
- XPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE ),
- xi, 0, 0, 0, 0, w, h );
-
- data->w = w;
- data->h = h;
- data->d = dd;
-
- XImage* axi = NULL;
-#ifdef TQT_MITSHM_CONVERSIONS
- bool mitshm_aximage = false;
- XShmSegmentInfo ashminfo;
-#endif
- if ( image.hasAlphaBuffer() ) {
- TQBitmap m;
- m = image.createAlphaMask( conversion_flags );
- setMask( m );
-
-#ifndef TQT_NO_XFTFREETYPE
- // does this image have an alphamap (and not just a 1bpp mask)?
- bool alphamap = image.depth() == 32;
- if (image.depth() == 8) {
- const TQRgb * const rgb = image.colorTable();
- for (int i = 0, count = image.numColors(); i < count; ++i) {
- const int alpha = tqAlpha(rgb[i]);
- if (alpha != 0 && alpha != 0xff) {
- alphamap = TRUE;
- break;
- }
- }
- }
-
- if (qt_use_xrender && qt_has_xft && alphamap) {
- data->alphapm = new TQPixmap; // create a null pixmap
-
- // setup pixmap data
- data->alphapm->data->w = w;
- data->alphapm->data->h = h;
- data->alphapm->data->d = 8;
-
- // create 8bpp pixmap and render picture
- data->alphapm->hd =
- XCreatePixmap(x11Display(), RootWindow(x11Display(), x11Screen()),
- w, h, 8);
-
- data->alphapm->rendhd =
- (HANDLE) XftDrawCreateAlpha( x11Display(), data->alphapm->hd, 8 );
-
-#ifdef TQT_MITSHM_CONVERSIONS
- axi = qt_XShmCreateImage( x11Display(), (Visual*)x11Visual(),
- 8, ZPixmap, 0, 0, w, h, 8, 0, &ashminfo );
- if( axi != NULL )
- mitshm_aximage = true;
- else
-#endif
- axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
- 8, ZPixmap, 0, 0, w, h, 8, 0);
-
- if (axi) {
- if( axi->data==NULL ) {
- // the data is deleted by qSafeXDestroyImage
- axi->data = (char *) malloc(h * axi->bytes_per_line);
- TQ_CHECK_PTR( axi->data );
- }
- char *aptr = axi->data;
-
- if (image.depth() == 32) {
- const int *iptr = (const int *) image.bits();
- if( axi->bytes_per_line == (int)w ) {
- int max = w * h;
- while (max--)
- *aptr++ = *iptr++ >> 24; // squirt
- } else {
- for (uint i = 0; i < h; ++i ) {
- for (uint j = 0; j < w; ++j )
- *aptr++ = *iptr++ >> 24; // squirt
- aptr += ( axi->bytes_per_line - w );
- }
- }
- } else if (image.depth() == 8) {
- const TQRgb * const rgb = image.colorTable();
- for (uint y = 0; y < h; ++y) {
- const uchar *iptr = image.scanLine(y);
- for (uint x = 0; x < w; ++x)
- *aptr++ = tqAlpha(rgb[*iptr++]);
- aptr += ( axi->bytes_per_line - w );
- }
- }
-
- GC gc = XCreateGC(x11Display(), data->alphapm->hd, 0, 0);
- #ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_aximage )
- XShmPutImage( dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h, False );
- else
-#endif
- XPutImage(dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h);
- XFreeGC(x11Display(), gc);
- }
- }
-#endif // TQT_NO_XFTFREETYPE
- }
-
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage || mitshm_aximage )
- XSync( x11Display(), False ); // wait until processed
-#endif
-
- if ( data->optim != BestOptim ) { // throw away image
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage )
- qt_XShmDestroyImage( xi, &shminfo );
- else
-#endif
- qSafeXDestroyImage( xi );
- data->ximage = 0;
- } else { // keep ximage that we created
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_ximage ) { // copy the XImage?
- qt_XShmDestroyImage( xi, &shminfo );
- xi = 0;
- }
-#endif
- data->ximage = xi;
- }
- if( axi ) {
-#ifdef TQT_MITSHM_CONVERSIONS
- if( mitshm_aximage )
- qt_XShmDestroyImage( axi, &ashminfo );
- else
-#endif
- qSafeXDestroyImage(axi);
- }
- return TRUE;
-}
-
-
-/*!
- Grabs the contents of the window \a window and makes a pixmap out
- of it. Returns the pixmap.
-
- The arguments \a (x, y) specify the offset in the window, whereas
- \a (w, h) specify the width and height of the area to be copied.
-
- If \a w is negative, the function copies everything to the right
- border of the window. If \a h is negative, the function copies
- everything to the bottom of the window.
-
- Note that grabWindow() grabs pixels from the screen, not from the
- window. If there is another window partially or entirely over the
- one you grab, you get pixels from the overlying window, too.
-
- Note also that the mouse cursor is generally not grabbed.
-
- The reason we use a window identifier and not a TQWidget is to
- enable grabbing of windows that are not part of the application,
- window system frames, and so on.
-
- \warning Grabbing an area outside the screen is not safe in
- general. This depends on the underlying window system.
-
- \warning X11 only: If \a window is not the same depth as the root
- window and another window partially or entirely obscures the one
- you grab, you will \e not get pixels from the overlying window.
- The contests of the obscured areas in the pixmap are undefined and
- uninitialized.
-
- \sa grabWidget()
-*/
-
-TQPixmap TQPixmap::grabWindow( WId window, int x, int y, int w, int h )
-{
- if ( w == 0 || h == 0 )
- return TQPixmap();
-
- Display *dpy = x11AppDisplay();
- XWindowAttributes window_attr;
- if ( ! XGetWindowAttributes( dpy, window, &window_attr ) )
- return TQPixmap();
-
- if ( w < 0 )
- w = window_attr.width - x;
- if ( h < 0 )
- h = window_attr.height - y;
-
- // determine the screen
- int scr;
- for ( scr = 0; scr < ScreenCount( dpy ); ++scr ) {
- if ( window_attr.root == RootWindow( dpy, scr ) ) // found it
- break;
- }
- if ( scr >= ScreenCount( dpy ) ) // sanity check
- return TQPixmap();
-
-
- // get the depth of the root window
- XWindowAttributes root_attr;
- if ( ! XGetWindowAttributes( dpy, window_attr.root, &root_attr ) )
- return TQPixmap();
-
- if ( window_attr.depth == root_attr.depth ) {
- // if the depth of the specified window and the root window are the
- // same, grab pixels from the root window (so that we get the any
- // overlapping windows and window manager frames)
-
- // map x and y to the root window
- WId unused;
- if ( ! XTranslateCoordinates( dpy, window, window_attr.root, x, y,
- &x, &y, &unused ) )
- return TQPixmap();
-
- window = window_attr.root;
- }
-
- TQPixmap pm( w, h );
- pm.data->uninit = FALSE;
- pm.x11SetScreen( scr );
-
- GC gc = qt_xget_temp_gc( scr, FALSE );
- XSetSubwindowMode( dpy, gc, IncludeInferiors );
- XCopyArea( dpy, window, pm.handle(), gc, x, y, w, h, 0, 0 );
- XSetSubwindowMode( dpy, gc, ClipByChildren );
-
- return pm;
-}
-
-/*!
- Returns a copy of the pixmap that is transformed using \a matrix.
- The original pixmap is not changed.
-
- The transformation \a matrix is internally adjusted to compensate
- for unwanted translation, i.e. xForm() returns the smallest image
- that contains all the transformed points of the original image.
-
- This function is slow because it involves transformation to a
- TQImage, non-trivial computations and a transformation back to a
- TQPixmap.
-
- \sa trueMatrix(), TQWMatrix, TQPainter::setWorldMatrix() TQImage::xForm()
-*/
-
-TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
-{
- uint w = 0;
- uint h = 0; // size of target pixmap
- uint ws, hs; // size of source pixmap
- uchar *dptr; // data in target pixmap
- uint dbpl, dbytes; // bytes per line/bytes total
- uchar *sptr; // data in original pixmap
- int sbpl; // bytes per line in original
- int bpp; // bits per pixel
- bool depth1 = depth() == 1;
- Display *dpy = x11Display();
-
- if ( isNull() ) // this is a null pixmap
- return copy();
-
- ws = width();
- hs = height();
-
- TQWMatrix mat( matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), 0., 0. );
-
- double scaledWidth;
- double scaledHeight;
-
- if ( matrix.m12() == 0.0F && matrix.m21() == 0.0F ) {
- if ( matrix.m11() == 1.0F && matrix.m22() == 1.0F )
- return *this; // identity matrix
- scaledHeight = matrix.m22()*hs;
- scaledWidth = matrix.m11()*ws;
- h = TQABS( tqRound( scaledHeight ) );
- w = TQABS( tqRound( scaledWidth ) );
- } else { // rotation or shearing
- TQPointArray a( TQRect(0,0,ws+1,hs+1) );
- a = mat.map( a );
- TQRect r = a.boundingRect().normalize();
- w = r.width()-1;
- h = r.height()-1;
- scaledWidth = w;
- scaledHeight = h;
- }
-
- mat = trueMatrix( mat, ws, hs ); // true matrix
-
-
- bool invertible;
- mat = mat.invert( &invertible ); // invert matrix
-
- if ( h == 0 || w == 0 || !invertible
- || TQABS(scaledWidth) >= 32768 || TQABS(scaledHeight) >= 32768 ) { // error, return null pixmap
- TQPixmap pm;
- pm.data->bitmap = data->bitmap;
- return pm;
- }
-
-#if defined(TQT_MITSHM_XFORM)
- static bool try_once = TRUE;
- if (try_once) {
- try_once = FALSE;
- if ( !xshminit )
- qt_create_mitshm_buffer( this, 800, 600 );
- }
-
- bool use_mitshm = xshmimg && !depth1 &&
- xshmimg->width >= w && xshmimg->height >= h;
-#endif
- XImage *xi = (XImage*)data->ximage; // any cached ximage?
- if ( !xi )
- xi = XGetImage( x11Display(), handle(), 0, 0, ws, hs, AllPlanes,
- depth1 ? XYPixmap : ZPixmap );
-
- if ( !xi ) { // error, return null pixmap
- TQPixmap pm;
- pm.data->bitmap = data->bitmap;
- pm.data->alphapm = data->alphapm;
- return pm;
- }
-
- sbpl = xi->bytes_per_line;
- sptr = (uchar *)xi->data;
- bpp = xi->bits_per_pixel;
-
- if ( depth1 )
- dbpl = (w+7)/8;
- else
- dbpl = ((w*bpp+31)/32)*4;
- dbytes = dbpl*h;
-
-#if defined(TQT_MITSHM_XFORM)
- if ( use_mitshm ) {
- dptr = (uchar *)xshmimg->data;
- uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
- for ( int y=0; y<h; y++ )
- memset( dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl );
- } else {
-#endif
- dptr = (uchar *)malloc( dbytes ); // create buffer for bits
- TQ_CHECK_PTR( dptr );
- if ( depth1 ) // fill with zeros
- memset( dptr, 0, dbytes );
- else if ( bpp == 8 ) // fill with background color
- memset( dptr, TQt::white.pixel( x11Screen() ), dbytes );
- else
- memset( dptr, 0xff, dbytes );
-#if defined(TQT_MITSHM_XFORM)
- }
-#endif
-
- // #define TQT_DEBUG_XIMAGE
-#if defined(TQT_DEBUG_XIMAGE)
- qDebug( "----IMAGE--INFO--------------" );
- qDebug( "width............. %d", xi->width );
- qDebug( "height............ %d", xi->height );
- qDebug( "xoffset........... %d", xi->xoffset );
- qDebug( "format............ %d", xi->format );
- qDebug( "byte order........ %d", xi->byte_order );
- qDebug( "bitmap unit....... %d", xi->bitmap_unit );
- qDebug( "bitmap bit order.. %d", xi->bitmap_bit_order );
- qDebug( "depth............. %d", xi->depth );
- qDebug( "bytes per line.... %d", xi->bytes_per_line );
- qDebug( "bits per pixel.... %d", xi->bits_per_pixel );
-#endif
-
- int type;
- if ( xi->bitmap_bit_order == MSBFirst )
- type = TQT_XFORM_TYPE_MSBFIRST;
- else
- type = TQT_XFORM_TYPE_LSBFIRST;
- int xbpl, p_inc;
- if ( depth1 ) {
- xbpl = (w+7)/8;
- p_inc = dbpl - xbpl;
- } else {
- xbpl = (w*bpp)/8;
- p_inc = dbpl - xbpl;
-#if defined(TQT_MITSHM_XFORM)
- if ( use_mitshm )
- p_inc = xshmimg->bytes_per_line - xbpl;
-#endif
- }
-
- if ( !qt_xForm_helper( mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs ) ){
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPixmap::xForm: display not supported (bpp=%d)",bpp);
-#endif
- TQPixmap pm;
- return pm;
- }
-
- if ( data->optim == NoOptim ) { // throw away ximage
- qSafeXDestroyImage( xi );
- data->ximage = 0;
- } else { // keep ximage that we fetched
- data->ximage = xi;
- }
-
- if ( depth1 ) { // mono bitmap
- TQPixmap pm( w, h, dptr, TQImage::systemBitOrder() != TQImage::BigEndian );
- pm.data->bitmap = data->bitmap;
- free( dptr );
- if ( data->mask ) {
- if ( data->selfmask ) // pixmap == mask
- pm.setMask( *((TQBitmap*)(&pm)) );
- else
- pm.setMask( data->mask->xForm(matrix) );
- }
- return pm;
- } else { // color pixmap
- GC gc = qt_xget_readonly_gc( x11Screen(), FALSE );
- TQPixmap pm( w, h );
- pm.data->uninit = FALSE;
- pm.x11SetScreen( x11Screen() );
-#if defined(TQT_MITSHM_XFORM)
- if ( use_mitshm ) {
- XCopyArea( dpy, xshmpm, pm.handle(), gc, 0, 0, w, h, 0, 0 );
- } else {
-#endif
- xi = XCreateImage( dpy, (Visual *)x11Visual(), x11Depth(),
- ZPixmap, 0, (char *)dptr, w, h, 32, 0 );
- XPutImage( dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
- qSafeXDestroyImage( xi );
-#if defined(TQT_MITSHM_XFORM)
- }
-#endif
-
- if ( data->mask ) // xform mask, too
- pm.setMask( data->mask->xForm(matrix) );
-
-#ifndef TQT_NO_XFTFREETYPE
- if ( qt_use_xrender && qt_has_xft && data->alphapm ) { // xform the alpha channel
- XImage *axi = 0;
- if ((axi = XGetImage(x11Display(), data->alphapm->handle(),
- 0, 0, ws, hs, AllPlanes, ZPixmap))) {
- sbpl = axi->bytes_per_line;
- sptr = (uchar *) axi->data;
- bpp = axi->bits_per_pixel;
- dbytes = dbpl * h;
- dptr = (uchar *) malloc(dbytes);
- TQ_CHECK_PTR( dptr );
- memset(dptr, 0, dbytes);
- if ( axi->bitmap_bit_order == MSBFirst )
- type = TQT_XFORM_TYPE_MSBFIRST;
- else
- type = TQT_XFORM_TYPE_LSBFIRST;
-
- if (qt_xForm_helper( mat, axi->xoffset, type, bpp, dptr, w,
- 0, h, sptr, sbpl, ws, hs )) {
- delete pm.data->alphapm;
- pm.data->alphapm = new TQPixmap; // create a null pixmap
-
- // setup pixmap data
- pm.data->alphapm->data->w = w;
- pm.data->alphapm->data->h = h;
- pm.data->alphapm->data->d = 8;
-
- // create 8bpp pixmap and render picture
- pm.data->alphapm->hd =
- XCreatePixmap(x11Display(),
- RootWindow(x11Display(), x11Screen()),
- w, h, 8);
-
- pm.data->alphapm->rendhd =
- (HANDLE) XftDrawCreateAlpha( x11Display(),
- pm.data->alphapm->hd, 8 );
-
- XImage *axi2 = XCreateImage(x11Display(), (Visual *) x11Visual(),
- 8, ZPixmap, 0, (char *)dptr, w, h, 8, 0);
-
- if (axi2) {
- // the data is deleted by qSafeXDestroyImage
- GC gc = XCreateGC(x11Display(), pm.data->alphapm->hd, 0, 0);
- XPutImage(dpy, pm.data->alphapm->hd, gc, axi2, 0, 0, 0, 0, w, h);
- XFreeGC(x11Display(), gc);
- qSafeXDestroyImage(axi2);
- }
- }
- qSafeXDestroyImage(axi);
- }
- }
-#endif // TQT_NO_XFTFREETYPE
-
- return pm;
- }
-}
-
-
-/*!
- \internal
-*/
-int TQPixmap::x11SetDefaultScreen( int screen )
-{
- int old = defaultScreen;
- defaultScreen = screen;
- return old;
-}
-
-/*!
- \internal
-*/
-void TQPixmap::x11SetScreen( int screen )
-{
- if ( screen < 0 )
- screen = x11AppScreen();
-
- if ( screen == x11Screen() )
- return; // nothing to do
-
- if ( isNull() ) {
- TQPaintDeviceX11Data* xd = getX11Data( TRUE );
- xd->x_screen = screen;
- xd->x_depth = TQPaintDevice::x11AppDepth( screen );
- xd->x_cells = TQPaintDevice::x11AppCells( screen );
- xd->x_colormap = TQPaintDevice::x11AppColormap( screen );
- xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( screen );
- xd->x_visual = TQPaintDevice::x11AppVisual( screen );
- xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( screen );
- setX11Data( xd );
- return;
- }
-#if 0
- qDebug("TQPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", data, x11Screen(), screen, width(), height() );
-#endif
-
- TQImage img = convertToImage();
- resize(0,0);
- TQPaintDeviceX11Data* xd = getX11Data( TRUE );
- xd->x_screen = screen;
- xd->x_depth = TQPaintDevice::x11AppDepth( screen );
- xd->x_cells = TQPaintDevice::x11AppCells( screen );
- xd->x_colormap = TQPaintDevice::x11AppColormap( screen );
- xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( screen );
- xd->x_visual = TQPaintDevice::x11AppVisual( screen );
- xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( screen );
- setX11Data( xd );
- convertFromImage( img );
-}
-
-/*!
- Returns TRUE this pixmap has an alpha channel or a mask.
-
- \sa hasAlphaChannel() mask()
-*/
-bool TQPixmap::hasAlpha() const
-{
- return data->alphapm || data->mask;
-}
-
-/*!
- Returns TRUE if the pixmap has an alpha channel; otherwise it
- returns FALSE.
-
- NOTE: If the pixmap has a mask but not alpha channel, this
- function returns FALSE.
-
- \sa hasAlpha() mask()
-*/
-bool TQPixmap::hasAlphaChannel() const
-{
- return data->alphapm != 0;
-}
-
-/*!
- \relates TQPixmap
-
- Copies a block of pixels from \a src to \a dst. The alpha channel
- and mask data (if any) is also copied from \a src. NOTE: \a src
- is \e not alpha blended or masked when copied to \a dst. Use
- bitBlt() or TQPainter::drawPixmap() to perform alpha blending or
- masked drawing.
-
- \a sx, \a sy is the top-left pixel in \a src (0, 0 by default), \a
- dx, \a dy is the top-left position in \a dst and \a sw, \sh is the
- size of the copied block (all of \a src by default).
-
- If \a src, \a dst, \a sw or \a sh is 0 (zero), copyBlt() does
- nothing. If \a sw or \a sh is negative, copyBlt() copies starting
- at \a sx (and respectively, \a sy) and ending at the right edge
- (and respectively, the bottom edge) of \a src.
-
- copyBlt() does nothing if \a src and \a dst have different depths.
-*/
-TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy,
- const TQPixmap *src, int sx, int sy, int sw, int sh )
-{
- if ( ! dst || ! src || sw == 0 || sh == 0 || dst->depth() != src->depth() ) {
-#ifdef TQT_CHECK_NULL
- TQ_ASSERT( dst != 0 );
- TQ_ASSERT( src != 0 );
-#endif
- return;
- }
-
- // copy pixel data
- bitBlt( dst, dx, dy, src, sx, sy, sw, sh, TQt::CopyROP, TRUE );
-
- // copy mask data
- if ( src->data->mask ) {
- if ( ! dst->data->mask ) {
- dst->data->mask = new TQBitmap( dst->width(), dst->height() );
-
- // new masks are fully opaque by default
- dst->data->mask->fill( TQt::color1 );
- }
-
- bitBlt( dst->data->mask, dx, dy,
- src->data->mask, sx, sy, sw, sh, TQt::CopyROP, TRUE );
- }
-
-#ifndef TQT_NO_XFTFREETYPE
- // copy alpha data
- extern bool qt_use_xrender; // from qapplication_x11.cpp
- if ( ! qt_use_xrender || ! src->data->alphapm )
- return;
-
- if ( sw < 0 )
- sw = src->width() - sx;
- else
- sw = TQMIN( src->width()-sx, sw );
- sw = TQMIN( dst->width()-dx, sw );
-
- if ( sh < 0 )
- sh = src->height() - sy ;
- else
- sh = TQMIN( src->height()-sy, sh );
- sh = TQMIN( dst->height()-dy, sh );
-
- if ( sw <= 0 || sh <= 0 )
- return;
-
- // create an alpha pixmap for dst if it doesn't exist
- bool do_init = FALSE;
- if ( ! dst->data->alphapm ) {
- dst->data->alphapm = new TQPixmap;
-
- // setup pixmap d
- dst->data->alphapm->data->w = dst->width();
- dst->data->alphapm->data->h = dst->height();
- dst->data->alphapm->data->d = 8;
-
- // create 8bpp pixmap and render picture
- dst->data->alphapm->hd =
- XCreatePixmap(dst->x11Display(),
- RootWindow(dst->x11Display(), dst->x11Screen()),
- dst->width(), dst->height(), 8);
-
- // new alpha pixmaps should be fully opaque by default
- do_init = TRUE;
-
- dst->data->alphapm->rendhd =
- (TQt::HANDLE) XftDrawCreateAlpha( dst->x11Display(),
- dst->data->alphapm->hd, 8 );
- }
-
- GC gc = XCreateGC(dst->x11Display(), dst->data->alphapm->hd, 0, 0);
-
- if ( do_init ) {
- // the alphapm was just created, make it fully opaque
- XSetForeground( dst->x11Display(), gc, 255 );
- XSetBackground( dst->x11Display(), gc, 255 );
- XFillRectangle( dst->x11Display(), dst->data->alphapm->hd, gc,
- 0, 0, dst->data->alphapm->data->w,
- dst->data->alphapm->data->h );
- }
-
- XCopyArea(dst->x11Display(), src->data->alphapm->hd, dst->data->alphapm->hd, gc,
- sx, sy, sw, sh, dx, dy);
- XFreeGC(dst->x11Display(), gc);
-#endif // TQT_NO_XFTFREETYPE
-}
-
-#endif // USE_QT4