diff options
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqpixmap.cpp')
| -rw-r--r-- | tqtinterface/qt4/src/kernel/tqpixmap.cpp | 1882 |
1 files changed, 1882 insertions, 0 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqpixmap.cpp b/tqtinterface/qt4/src/kernel/tqpixmap.cpp new file mode 100644 index 0000000..f47fb38 --- /dev/null +++ b/tqtinterface/qt4/src/kernel/tqpixmap.cpp @@ -0,0 +1,1882 @@ +/**************************************************************************** +** +** Implementation of TQPixmap class +** +** Created : 950301 +** +** 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. +** +**********************************************************************/ + +#include "tqpixmap.h" + +#include "tqbitmap.h" +#include "tqimage.h" +#include "tqwidget.h" +#include "tqpainter.h" +#include "tqdatastream.h" +#include "tqbuffer.h" +#include "tqobjectlist.h" +#include "tqapplication.h" +#include <private/tqinternal_p.h> +#include "tqmime.h" +#include "tqdragobject.h" +#include "tqfile.h" + +#ifdef USE_QT4 + +#include <Qt/qpaintengine.h> +#include "tqbitmap.h" + +#define VERIFY_TQPIXMAP_OBJECT_FUNCTION(x) \ +if (!dynamic_cast<const TQPixmap*>(static_cast<const QPixmap*>(this))) { \ + printf("[WARNING] An attempt was made to access the TQPixmap::tqmask method from an object not of type TQPixmap [possibly QPixmap]\n\r\tThis may indicate creation and subsequent [illegal] downcasting of a QPixmap object to a TQPixmap object within your application\n\r\tNo pixmap was returned\n\r"); \ + return x; \ +} + +TQPixmap::TQPixmap() : QPixmap(), tqt_tqbitmap_ptr(0) { +} + +TQPixmap::TQPixmap( const QImage& image ) : QPixmap( QPixmap::fromImage(image) ), tqt_tqbitmap_ptr(0) { +} + +// [FIXME] Set depth correctly (in Qt4 is that even possible/wise?) +TQPixmap::TQPixmap( int w, int h, int depth, Optimization o ) : QPixmap( w, h ), tqt_tqbitmap_ptr(0) { + TQ_UNUSED(o); + TQ_UNUSED(depth); +} + +// [FIXME] Set depth correctly (in Qt4 is that even possible/wise?) +TQPixmap::TQPixmap( const QSize &s, int depth, Optimization o ) : QPixmap( s ), tqt_tqbitmap_ptr(0) { + TQ_UNUSED(o); + TQ_UNUSED(depth); +} + +#ifndef TQT_NO_IMAGEIO +TQPixmap::TQPixmap( const QString& fileName, const char *format, TQPixmap::ColorMode mode ) : QPixmap( fileName, format ), tqt_tqbitmap_ptr(0) { + TQ_UNUSED(mode); +} + +TQPixmap::TQPixmap( const QString& fileName, const char *format, int conversion_flags ) : QPixmap( fileName, format, (Qt::ImageConversionFlags)conversion_flags), tqt_tqbitmap_ptr(0) { +} + +TQPixmap::TQPixmap( const char *xpm[] ) : QPixmap( xpm ), tqt_tqbitmap_ptr(0) { +} + +TQPixmap::TQPixmap( const QByteArray &data ) : QPixmap( data ), tqt_tqbitmap_ptr(0) { +} +#endif +TQPixmap::TQPixmap( const TQPixmap &p ) : QPixmap( p ), tqt_tqbitmap_ptr(0) { +} + +TQPixmap::TQPixmap( const QPixmap p ) : QPixmap( p ), tqt_tqbitmap_ptr(0) { +} + +TQPixmap::~TQPixmap() { + // HACK + // Make absolutely sure that this is a TQPixmap object! + VERIFY_TQPIXMAP_OBJECT_FUNCTION( ) +// printf("[WARNING] Memory leak likely at TQPixmap destruction [tqt_tqbitmap_ptr was %p]\n\r", (void*)tqt_tqbitmap_ptr); fflush(stdout); // [FIXME] [CRITICAL] [MEMORY LEAK] + if (tqt_tqbitmap_ptr) delete tqt_tqbitmap_ptr; +} + +bool TQPixmap::selfMask() const { + return false; +} + +bool TQPixmap::convertFromImage(const QImage &img, Qt::ImageConversionFlags flags) { + *this = fromImage(img, flags); + return true; +} + +bool TQPixmap::convertFromImage(const QImage &img, int flags) { + return QPixmap::convertFromImage(img, (Qt::ImageConversionFlag)flags); +} + +void TQPixmap::setOptimization( TQPixmap::Optimization ) { +} + +void TQPixmap::setDefaultOptimization( TQPixmap::Optimization ) { +} + +void TQPixmap::resize(const QSize s) { + resize_helper(s); +} + +void TQPixmap::resize(int width, int height) { + resize_helper(QSize(width, height)); +} + +void *TQPixmap::x11AppVisual( void ) { + return x11AppVisual(-1); +} + +void *TQPixmap::x11AppVisual( int screen ) { + return QX11Info::appVisual(screen); +} + +int TQPixmap::x11AppCells( void ) { + return x11AppCells(-1); +} + +int TQPixmap::x11AppCells( int screen ) { + return QX11Info::appCells(screen); +} + +int TQPixmap::x11AppDepth( void ) { + return x11AppDepth(-1); +} + +int TQPixmap::x11AppDepth( int screen ) { + return QX11Info::appDepth(screen); +} + +Display *TQPixmap::x11AppDisplay( void ) { + return QX11Info::display(); +} + +int TQPixmap::x11AppScreen( void ) { + return QX11Info::appScreen(); +} + +bool TQPixmap::x11AppDefaultVisual( void ) { + return x11AppDefaultVisual(-1); +} + +bool TQPixmap::x11AppDefaultVisual( int screen ) { + return QX11Info::appDefaultVisual(screen); +} + +TQt::HANDLE TQPixmap::x11AppColormap( void ) { + return x11AppColormap(-1); +} + +TQt::HANDLE TQPixmap::x11AppColormap( int screen ) { + return QX11Info::appColormap(screen); +} + +bool TQPixmap::x11AppDefaultColormap( void ) { + return x11AppDefaultColormap(-1); +} + +bool TQPixmap::x11AppDefaultColormap( int screen ) { + return QX11Info::appDefaultColormap(screen); +} + +TQt::HANDLE TQPixmap::x11AppRootWindow( void ) { + return x11AppRootWindow(-1); +} + +TQt::HANDLE TQPixmap::x11AppRootWindow( int screen ) { + return QX11Info::appRootWindow(screen); +} + +const TQBitmap *TQPixmap::tqmask() const { + // HACK + // Make absolutely sure that this is a TQPixmap object! + VERIFY_TQPIXMAP_OBJECT_FUNCTION(0) + + const QBitmap& ptrRef = mask(); + if (ptrRef.isNull() == true) { + return 0; + } + if (tqt_tqbitmap_ptr) { + delete tqt_tqbitmap_ptr; + } + tqt_tqbitmap_ptr = new TQBitmap(ptrRef); + return tqt_tqbitmap_ptr; +} + +void TQPixmap::resize_helper(const QSize s) +{ + int w = s.width(); + int h = s.height(); + + if (w < 1 || h < 1) { + *this = TQPixmap(); + return; + } + + if (size() == s) + return; + + TQPixmap pm(QSize(w, h)); + if (!isNull()) { + // Copy old pixmap + if (hasAlphaChannel()) + pm.fill(Qt::transparent); + QPainter p(&pm); + p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h)); + p.end(); + } + + // Mask too.... + if (!mask().isNull()) { + TQBitmap m = mask(); + if (m.size() != QSize(w,h)) { + TQBitmap pmr(QSize(w, h)); + pmr.fill(Qt::color0); + QPainter pr(&pmr); + pr.setBrush(Qt::color1); + pr.drawPixmap(0, 0, m, 0, 0, qMin(m.width(), w), qMin(m.height(), h)); + pr.end(); + pm.setMask(pmr); + } + else { + pm.setMask(m); + } + } + + // [FIXME] + // Note that the Xorg pixmap and/or gc (if any) is not created via the above process + // Therefore resize is more of a copy operation than a true resize + #warning TQPixmap::resize() partially implemented + + *this = pm; +} + +TQImage TQPixmap::convertToImage() const { + return TQImage(toImage()); +} + +TQPixmap::operator TQImage() const { + return TQImage(toImage()); +} + +TQPixmap TQPixmap::xForm(const QMatrix &matrix) const { + return TQPixmap(transformed(QTransform(matrix))); +} + +void copyBlt(QPixmap *dst, int dx, int dy, + const QPixmap *src, int sx, int sy, int sw, int sh) +{ + Q_ASSERT_X(dst, "::copyBlt", "Destination pixmap must be non-null"); + Q_ASSERT_X(src, "::copyBlt", "Source pixmap must be non-null"); + + if (src->hasAlphaChannel()) { + if (dst->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) { + QPainter p(dst); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawPixmap(dx, dy, *src, sx, sy, sw, sh); + } else { + QImage image = dst->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); + QPainter p(&image); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawPixmap(dx, dy, *src, sx, sy, sw, sh); + p.end(); + *dst = QPixmap::fromImage(image); + } + } else { + QPainter p(dst); + p.drawPixmap(dx, dy, *src, sx, sy, sw, sh); + } + +} + +extern const Q_GUI_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd); // Defined in tqpaintdevice_x11.cpp + +Display *TQPixmap::x11Display() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->display(); + return QX11Info::display(); +} + +int TQPixmap::x11Screen() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->screen(); + return QX11Info::appScreen(); +} + +void *TQPixmap::x11Visual() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->visual(); + return QX11Info::appVisual(); +} + +int TQPixmap::x11Depth() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->depth(); + return QX11Info::appDepth(); +} + +int TQPixmap::x11Cells() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->cells(); + return QX11Info::appCells(); +} + +Qt::HANDLE TQPixmap::x11Colormap() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->colormap(); + return QX11Info::appColormap(); +} + +bool TQPixmap::x11DefaultColormap() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->defaultColormap(); + return QX11Info::appDefaultColormap(); +} + +bool TQPixmap::x11DefaultVisual() const +{ + const QX11Info *info = qt_x11Info(this); + if (info) + return info->defaultVisual(); + return QX11Info::appDefaultVisual(); +} + +void TQPixmap::x11SetAppDpiX(int dpi, int screen) +{ + QX11Info::setAppDpiX(dpi, screen); +} + +void TQPixmap::x11SetAppDpiY(int dpi, int screen) +{ + QX11Info::setAppDpiY(dpi, screen); +} + +int TQPixmap::x11AppDpiX(int screen) +{ + return QX11Info::appDpiX(screen); +} + +int TQPixmap::x11AppDpiY(int screen) +{ + return QX11Info::appDpiY(screen); +} + +/*! Convenience function. Gets the data associated with the absolute + name \a abs_name from the default mime source factory and decodes it + to a pixmap. + + \sa TQMimeSourceFactory, TQImage::fromMimeSource(), TQImageDrag::decode() +*/ + +#ifndef TQT_NO_MIME +TQPixmap TQPixmap::fromMimeSource( const TQString &abs_name ) +{ + const TQMimeSource *m = TQT_TQMIMESOURCE_CONST(TQMimeSourceFactory::defaultFactory()->data( abs_name )); + if ( !m ) { + if ( TQFile::exists( abs_name ) ) + return TQPixmap( abs_name ); +#if defined(TQT_CHECK_STATE) + if ( !abs_name.isEmpty() ) + qWarning( "TQPixmap::fromMimeSource: Cannot find pixmap \"%s\" in the mime source factory", + abs_name.latin1() ); +#endif + return TQPixmap(); + } + TQPixmap pix; + TQImageDrag::decode( m, pix ); + return pix; +} +#endif + +#ifndef TQT_NO_IMAGE_HEURISTIC_MASK +TQBitmap TQPixmap::createHeuristicMask( bool clipTight ) const { + return TQBitmap(QPixmap::createHeuristicMask(clipTight)); +} +#endif + +#else // USE_QT4 + +/*! + \class TQPixmap tqpixmap.h + \brief The TQPixmap class is an off-screen, pixel-based paint tqdevice. + + \ingroup graphics + \ingroup images + \ingroup shared + \mainclass + + TQPixmap is one of the two classes TQt provides for dealing with + images; the other is TQImage. TQPixmap is designed and optimized + for drawing; TQImage is designed and optimized for I/O and for + direct pixel access/manipulation. There are (slow) functions to + convert between TQImage and TQPixmap: convertToImage() and + convertFromImage(). + + One common use of the TQPixmap class is to enable smooth updating + of widgets. Whenever something complex needs to be drawn, you can + use a pixmap to obtain flicker-free drawing, like this: + + \list 1 + \i Create a pixmap with the same size as the widget. + \i Fill the pixmap with the widget background color. + \i Paint the pixmap. + \i bitBlt() the pixmap contents onto the widget. + \endlist + + Pixel data in a pixmap is internal and is managed by the + underlying window system. Pixels can be accessed only through + TQPainter functions, through bitBlt(), and by converting the + TQPixmap to a TQImage. + + You can easily display a TQPixmap on the screen using + TQLabel::setPixmap(). For example, all the TQButton subclasses + support pixmap use. + + The TQPixmap class uses \link shclass.html copy-on-write\endlink, + so it is practical to pass TQPixmap objects by value. + + You can retrieve the width(), height(), depth() and size() of a + pixmap. The enclosing rectangle is given by rect(). Pixmaps can be + filled with fill() and resized with resize(). You can create and + set a tqmask with createHeuristicMask() and setMask(). Use + selfMask() to see if the pixmap is identical to its tqmask. + + In addition to loading a pixmap from file using load() you can + also loadFromData(). You can control optimization with + setOptimization() and obtain a transformed version of the pixmap + using xForm() + + Note regarding Windows 95 and 98: on Windows 9x the system crashes + if you create more than about 1000 pixmaps, independent of the + size of the pixmaps or installed RAM. Windows NT-systems (including + 2000, XP and following versions) do not have the same limitation, + but depending on the graphics equipment the system will fail to + allocate pixmap objects at some point (due to system running out of + GDI resources). + + TQt tries to work around the resource limitation. If you set the + pixmap optimization to \c TQPixmap::MemoryOptim and the width of + your pixmap is less than or equal to 128 pixels, TQt stores the + pixmap in a way that is very memory-efficient when there are many + pixmaps. + + If your application uses dozens or hundreds of pixmaps (for + example on tool bar buttons and in popup menus), and you plan to + run it on Windows 95 or Windows 98, we recommend using code like + this: + + \code + TQPixmap::setDefaultOptimization( TQPixmap::MemoryOptim ); + while ( ... ) { + // load tool bar pixmaps etc. + TQPixmap *pixmap = new TQPixmap(fileName); + } + TQPixmap::setDefaultOptimization( TQPixmap::NormalOptim ); + \endcode + + In general it is recommended to make as much use of TQPixmap's + implicit sharing and the TQPixmapCache as possible. + + \sa TQBitmap, TQImage, TQImageIO, \link shclass.html Shared Classes\endlink +*/ + +/*! + \enum TQPixmap::ColorMode + + This enum type defines the color modes that exist for converting + TQImage objects to TQPixmap. + + \value Auto Select \c Color or \c Mono on a case-by-case basis. + \value Color Always create colored pixmaps. + \value Mono Always create bitmaps. +*/ + +/*! + \enum TQPixmap::Optimization + + TQPixmap has the choice of optimizing for speed or memory in a few + places; the best choice varies from pixmap to pixmap but can + generally be derived heuristically. This enum type defines a + number of optimization modes that you can set for any pixmap to + tweak the speed/memory tradeoffs: + + \value DefaultOptim Whatever TQPixmap::defaultOptimization() + returns. A pixmap with this optimization will have whatever + the current default optimization is. If the default + optimization is changed using setDefaultOptimization(), then + this will not effect any pixmaps that have already been + created. + + \value NoOptim No optimization (currently the same as \c + MemoryOptim). + + \value MemoryOptim Optimize for minimal memory use on Windows + 9x and X11 systems. + + \value NormalOptim Optimize for typical usage. Often uses more + memory than \c MemoryOptim, and is often faster. + + \value BestOptim Optimize for pixmaps that are drawn very often + and where performance is critical. Generally uses more memory + than \c NormalOptim and may provide a little more speed. + + We recommend using \c DefaultOptim. + +*/ + + +TQPixmap::Optimization TQPixmap::defOptim = TQPixmap::NormalOptim; + + +/*! + \internal + Private constructor which takes the bitmap flag, the optimization.and a screen. +*/ + +TQPixmap::TQPixmap( int w, int h, int depth, bool bitmap, + Optimization optimization ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( w, h, depth, bitmap, optimization ); +} + + +/*! + Constructs a null pixmap. + + \sa isNull() +*/ + +TQPixmap::TQPixmap() + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( 0, 0, 0, FALSE, defOptim ); +} + +/*! + Constructs a pixmap from the TQImage \a image. + + \sa convertFromImage() +*/ + +TQPixmap::TQPixmap( const TQImage& image ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( 0, 0, 0, FALSE, defOptim ); + convertFromImage( image ); +} + +/*! + Constructs a pixmap with \a w width, \a h height and \a depth bits + per pixel. The pixmap is optimized in accordance with the \a + optimization value. + + The contents of the pixmap is uninitialized. + + The \a depth can be either 1 (monochrome) or the depth of the + current video mode. If \a depth is negative, then the hardware + depth of the current video mode will be used. + + If either \a w or \a h is zero, a null pixmap is constructed. + + \sa isNull() TQPixmap::Optimization +*/ + +TQPixmap::TQPixmap( int w, int h, int depth, Optimization optimization ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( w, h, depth, FALSE, optimization ); +} + +/*! + \overload TQPixmap::TQPixmap( const TQSize &size, int depth, Optimization optimization ) + + Constructs a pixmap of size \a size, \a depth bits per pixel, + optimized in accordance with the \a optimization value. +*/ + +TQPixmap::TQPixmap( const TQSize &size, int depth, Optimization optimization ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( size.width(), size.height(), depth, FALSE, optimization ); +} + +#ifndef TQT_NO_IMAGEIO +/*! + Constructs a pixmap from the file \a fileName. If the file does + not exist or is of an unknown format, the pixmap becomes a null + pixmap. + + The \a fileName, \a format and \a conversion_flags parameters are + passed on to load(). This means that the data in \a fileName is + not compiled into the binary. If \a fileName tqcontains a relative + path (e.g. the filename only) the relevant file must be found + relative to the runtime working directory. + + If the image needs to be modified to fit in a lower-resolution + result (e.g. converting from 32-bit to 8-bit), use the \a + conversion_flags to specify how you'd prefer this to happen. + + \sa TQt::ImageConversionFlags isNull(), load(), loadFromData(), save(), imageFormat() +*/ + +TQPixmap::TQPixmap( const TQString& fileName, const char *format, + int conversion_flags ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( 0, 0, 0, FALSE, defOptim ); + load( fileName, format, conversion_flags ); +} + +/*! + Constructs a pixmap from the file \a fileName. If the file does + not exist or is of an unknown format, the pixmap becomes a null + pixmap. + + The \a fileName, \a format and \a mode parameters are passed on to + load(). This means that the data in \a fileName is not compiled + into the binary. If \a fileName tqcontains a relative path (e.g. the + filename only) the relevant file must be found relative to the + runtime working directory. + + \sa TQPixmap::ColorMode isNull(), load(), loadFromData(), save(), imageFormat() +*/ + +TQPixmap::TQPixmap( const TQString& fileName, const char *format, ColorMode mode ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( 0, 0, 0, FALSE, defOptim ); + load( fileName, format, mode ); +} + +/*! + Constructs a pixmap from \a xpm, which must be a valid XPM image. + + Errors are silently ignored. + + Note that it's possible to squeeze the XPM variable a little bit + by using an unusual declaration: + + \code + static const char * const start_xpm[]={ + "16 15 8 1", + "a c #cec6bd", + .... + \endcode + + The extra \c const makes the entire definition read-only, which is + slightly more efficient (for example, when the code is in a shared + library) and ROMable when the application is to be stored in ROM. + + In order to use that sort of declaration you must cast the + variable back to \c{const char **} when you create the TQPixmap. +*/ + +TQPixmap::TQPixmap( const char *xpm[] ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( 0, 0, 0, FALSE, defOptim ); + TQImage image( xpm ); + if ( !image.isNull() ) + convertFromImage( image ); +} + +/*! + Constructs a pixmaps by loading from \a img_data. The data can be + in any image format supported by TQt. + + \sa loadFromData() +*/ + +TQPixmap::TQPixmap( const TQByteArray & img_data ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + init( 0, 0, 0, FALSE, defOptim ); + loadFromData( img_data ); +} +#endif //TQT_NO_IMAGEIO + +/*! + Constructs a pixmap that is a copy of \a pixmap. +*/ + +TQPixmap::TQPixmap( const TQPixmap &pixmap ) + : TQPaintDevice( TQInternal::Pixmap ) +{ + if ( pixmap.paintingActive() ) { // make a deep copy + data = 0; + operator=( pixmap.copy() ); + } else { + data = pixmap.data; + data->ref(); + devFlags = pixmap.devFlags; // copy TQPaintDevice flags +#if defined(TQ_WS_WIN) + hdc = pixmap.hdc; // copy Windows tqdevice context +#elif defined(TQ_WS_X11) + hd = pixmap.hd; // copy X11 drawable + rendhd = pixmap.rendhd; + copyX11Data( &pixmap ); // copy x11Data +#elif defined(TQ_WS_MAC) + hd = pixmap.hd; +#endif + } +} + + +/*! + Destroys the pixmap. +*/ + +TQPixmap::~TQPixmap() +{ + deref(); +} + +/*! Convenience function. Gets the data associated with the absolute + name \a abs_name from the default mime source factory and decodes it + to a pixmap. + + \sa TQMimeSourceFactory, TQImage::fromMimeSource(), TQImageDrag::decode() +*/ + +#ifndef TQT_NO_MIME +TQPixmap TQPixmap::fromMimeSource( const TQString &abs_name ) +{ + const TQMimeSource *m = TQMimeSourceFactory::defaultFactory()->data( abs_name ); + if ( !m ) { + if ( TQFile::exists( abs_name ) ) + return TQPixmap( abs_name ); +#if defined(TQT_CHECK_STATE) + if ( !abs_name.isEmpty() ) + qWarning( "TQPixmap::fromMimeSource: Cannot find pixmap \"%s\" in the mime source factory", + abs_name.latin1() ); +#endif + return TQPixmap(); + } + TQPixmap pix; + TQImageDrag::decode( m, pix ); + return pix; +} +#endif + +/*! + Returns a \link shclass.html deep copy\endlink of the pixmap using + the bitBlt() function to copy the pixels. + + \sa operator=() +*/ + +TQPixmap TQPixmap::copy( bool ignoreMask ) const +{ +#if defined(TQ_WS_X11) + int old = x11SetDefaultScreen( x11Screen() ); +#endif // TQ_WS_X11 + + TQPixmap pm( data->w, data->h, data->d, data->bitmap, data->optim ); + + if ( !pm.isNull() ) { // copy the bitmap +#if defined(TQ_WS_X11) + pm.cloneX11Data( this ); +#endif // TQ_WS_X11 + + if ( ignoreMask ) + bitBlt( &pm, 0, 0, this, 0, 0, data->w, data->h, TQt::CopyROP, TRUE ); + else + copyBlt( &pm, 0, 0, this, 0, 0, data->w, data->h ); + } + +#if defined(TQ_WS_X11) + x11SetDefaultScreen( old ); +#endif // TQ_WS_X11 + + return pm; +} + + +/*! + Assigns the pixmap \a pixmap to this pixmap and returns a + reference to this pixmap. +*/ + +TQPixmap &TQPixmap::operator=( const TQPixmap &pixmap ) +{ + if ( paintingActive() ) { +#if defined(TQT_CHECK_STATE) + qWarning("TQPixmap::operator=: Cannot assign to pixmap during painting"); +#endif + return *this; + } + pixmap.data->ref(); // avoid 'x = x' + deref(); + if ( pixmap.paintingActive() ) { // make a deep copy + init( pixmap.width(), pixmap.height(), pixmap.depth(), + pixmap.data->bitmap, pixmap.data->optim ); + data->uninit = FALSE; + if ( !isNull() ) + copyBlt( this, 0, 0, &pixmap, 0, 0, pixmap.width(), pixmap.height() ); + pixmap.data->deref(); + } else { + data = pixmap.data; + devFlags = pixmap.devFlags; // copy TQPaintDevice flags +#if defined(TQ_WS_WIN) + hdc = pixmap.hdc; +#elif defined(TQ_WS_X11) + hd = pixmap.hd; // copy TQPaintDevice drawable + rendhd = pixmap.rendhd; + copyX11Data( &pixmap ); // copy x11Data +#elif defined(TQ_WS_MACX) || defined(TQ_OS_MAC9) + hd = pixmap.hd; +#endif + } + return *this; +} + + +/*! + \overload + + Converts the image \a image to a pixmap that is assigned to this + pixmap. Returns a reference to the pixmap. + + \sa convertFromImage(). +*/ + +TQPixmap &TQPixmap::operator=( const TQImage &image ) +{ + convertFromImage( image ); + return *this; +} + + +/*! + \fn bool TQPixmap::isTQBitmap() const + + Returns TRUE if this is a TQBitmap; otherwise returns FALSE. +*/ + +/*! + \fn bool TQPixmap::isNull() const + + Returns TRUE if this is a null pixmap; otherwise returns FALSE. + + A null pixmap has zero width, zero height and no contents. You + cannot draw in a null pixmap or bitBlt() anything to it. + + Resizing an existing pixmap to (0, 0) makes a pixmap into a null + pixmap. + + \sa resize() +*/ + +/*! + \fn int TQPixmap::width() const + + Returns the width of the pixmap. + + \sa height(), size(), rect() +*/ + +/*! + \fn int TQPixmap::height() const + + Returns the height of the pixmap. + + \sa width(), size(), rect() +*/ + +/*! + \fn TQSize TQPixmap::size() const + + Returns the size of the pixmap. + + \sa width(), height(), rect() +*/ + +/*! + \fn TQRect TQPixmap::rect() const + + Returns the enclosing rectangle (0,0,width(),height()) of the pixmap. + + \sa width(), height(), size() +*/ + +/*! + \fn int TQPixmap::depth() const + + Returns the depth of the pixmap. + + The pixmap depth is also called bits per pixel (bpp) or bit planes + of a pixmap. A null pixmap has depth 0. + + \sa defaultDepth(), isNull(), TQImage::convertDepth() +*/ + + +/*! + \overload void TQPixmap::fill( const TQWidget *widget, const TQPoint &ofs ) + + Fills the pixmap with the \a widget's background color or pixmap. + If the background is empty, nothing is done. + + The \a ofs point is an offset in the widget. + + The point \a ofs is a point in the widget's coordinate system. The + pixmap's top-left pixel will be mapped to the point \a ofs in the + widget. This is significant if the widget has a background pixmap; + otherwise the pixmap will simply be filled with the background + color of the widget. + + Example: + \code + void CuteWidget::paintEvent( TQPaintEvent *e ) + { + TQRect ur = e->rect(); // rectangle to update + TQPixmap pix( ur.size() ); // Pixmap for double-buffering + pix.fill( this, ur.topLeft() ); // fill with widget background + + TQPainter p( &pix ); + p.translate( -ur.x(), -ur.y() ); // use widget coordinate system + // when drawing on pixmap + // ... draw on pixmap ... + + p.end(); + + bitBlt( this, ur.topLeft(), &pix ); + } + \endcode +*/ + +/*! + \overload void TQPixmap::fill( const TQWidget *widget, int xofs, int yofs ) + + Fills the pixmap with the \a widget's background color or pixmap. + If the background is empty, nothing is done. \a xofs, \a yofs is + an offset in the widget. +*/ + +void TQPixmap::fill( const TQWidget *widget, int xofs, int yofs ) +{ + const TQPixmap* bgpm = widget->backgroundPixmap(); + fill( widget->backgroundColor() ); + if ( bgpm ) { + if ( !bgpm->isNull() ) { + TQPoint ofs = widget->backgroundOffset(); + xofs += ofs.x(); + yofs += ofs.y(); + + TQPainter p; + p.begin( this ); + p.setPen( NoPen ); + p.drawTiledPixmap( 0, 0, width(), height(), *widget->backgroundPixmap(), xofs, yofs ); + p.end(); + } + } +} + + +/*! + \overload void TQPixmap::resize( const TQSize &size ) + + Resizes the pixmap to size \a size. +*/ + +/*! + Resizes the pixmap to \a w width and \a h height. If either \a w + or \a h is 0, the pixmap becomes a null pixmap. + + If both \a w and \a h are greater than 0, a valid pixmap is + created. New pixels will be uninitialized (random) if the pixmap + is expanded. +*/ + +void TQPixmap::resize( int w, int h ) +{ + if ( w < 1 || h < 1 ) { // becomes null + TQPixmap pm( 0, 0, 0, data->bitmap, data->optim ); + *this = pm; + return; + } + int d; + if ( depth() > 0 ) + d = depth(); + else + d = isTQBitmap() ? 1 : -1; + // Create new pixmap + TQPixmap pm( w, h, d, data->bitmap, data->optim ); +#ifdef TQ_WS_X11 + pm.x11SetScreen( x11Screen() ); +#endif // TQ_WS_X11 + if ( !data->uninit && !isNull() ) // has existing pixmap + bitBlt( &pm, 0, 0, this, 0, 0, // copy old pixmap + TQMIN(width(), w), + TQMIN(height(),h), CopyROP, TRUE ); +#if defined(TQ_WS_MAC) + if(data->alphapm) { + data->alphapm->resize(w, h); + } else +#elif defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE) + if (data->alphapm) + qWarning("TQPixmap::resize: TODO: resize alpha data"); + else +#endif // TQ_WS_X11 + if ( data->tqmask ) { // resize tqmask as well + if ( data->selfmask ) { // preserve self-tqmask + pm.setMask( *((TQBitmap*)&pm) ); + } else { // independent tqmask + TQBitmap m = *data->tqmask; + m.resize( w, h ); + pm.setMask( m ); + } + } + *this = pm; +} + + +/*! + \fn const TQBitmap *TQPixmap::tqmask() const + + Returns the tqmask bitmap, or 0 if no tqmask has been set. + + \sa setMask(), TQBitmap, hasAlpha() +*/ + +/*! + Sets a tqmask bitmap. + + The \a newtqmask bitmap defines the clip tqmask for this pixmap. Every + pixel in \a newtqmask corresponds to a pixel in this pixmap. Pixel + value 1 means opaque and pixel value 0 means transtqparent. The tqmask + must have the same size as this pixmap. + + \warning Setting the tqmask on a pixmap will cause any alpha channel + data to be cleared. For example: + \code + TQPixmap alpha( "image-with-alpha.png" ); + TQPixmap alphacopy = alpha; + alphacopy.setMask( *alphacopy.tqmask() ); + \endcode + Now, alpha and alphacopy are visually different. + + Setting a \link isNull() null\endlink tqmask resets the tqmask. + + \sa tqmask(), createHeuristicMask(), TQBitmap +*/ + +void TQPixmap::setMask( const TQBitmap &newtqmask ) +{ + const TQPixmap *tmp = &newtqmask; // dec cxx bug + if ( (data == tmp->data) || + ( newtqmask.handle() && newtqmask.handle() == handle() ) ) { + TQPixmap m = tmp->copy( TRUE ); + setMask( *((TQBitmap*)&m) ); + data->selfmask = TRUE; // tqmask == pixmap + return; + } + + if ( newtqmask.isNull() ) { // reset the tqmask + if (data->tqmask) { + detach(); + data->selfmask = FALSE; + + delete data->tqmask; + data->tqmask = 0; + } + return; + } + + detach(); + data->selfmask = FALSE; + + if ( newtqmask.width() != width() || newtqmask.height() != height() ) { +#if defined(TQT_CHECK_RANGE) + qWarning( "TQPixmap::setMask: The pixmap and the tqmask must have " + "the same size" ); +#endif + return; + } +#if defined(TQ_WS_MAC) || (defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)) + // when setting the tqmask, we get rid of the alpha channel completely + delete data->alphapm; + data->alphapm = 0; +#endif // TQ_WS_X11 && !TQT_NO_XFTFREETYPE + + delete data->tqmask; + TQBitmap* newmaskcopy; + if ( newtqmask.tqmask() ) + newmaskcopy = (TQBitmap*)new TQPixmap( tmp->copy( TRUE ) ); + else + newmaskcopy = new TQBitmap( newtqmask ); +#ifdef TQ_WS_X11 + newmaskcopy->x11SetScreen( x11Screen() ); +#endif + data->tqmask = newmaskcopy; +} + + +/*! + \fn bool TQPixmap::selfMask() const + + Returns TRUE if the pixmap's tqmask is identical to the pixmap + itself; otherwise returns FALSE. + + \sa tqmask() +*/ + +#ifndef TQT_NO_IMAGE_HEURISTIC_MASK +/*! + Creates and returns a heuristic tqmask for this pixmap. It works by + selecting a color from one of the corners and then chipping away + pixels of that color, starting at all the edges. + + The tqmask may not be perfect but it should be reasonable, so you + can do things such as the following: + \code + pm->setMask( pm->createHeuristicMask() ); + \endcode + + This function is slow because it involves transformation to a + TQImage, non-trivial computations and a transformation back to a + TQBitmap. + + If \a clipTight is TRUE the tqmask is just large enough to cover the + pixels; otherwise, the tqmask is larger than the data pixels. + + \sa TQImage::createHeuristicMask() +*/ + +TQBitmap TQPixmap::createHeuristicMask( bool clipTight ) const +{ + TQBitmap m; + m.convertFromImage( convertToImage().createHeuristicMask(clipTight) ); + return m; +} +#endif +#ifndef TQT_NO_IMAGEIO +/*! + Returns a string that specifies the image format of the file \a + fileName, or 0 if the file cannot be read or if the format cannot + be recognized. + + The TQImageIO documentation lists the supported image formats. + + \sa load(), save() +*/ + +const char* TQPixmap::imageFormat( const TQString &fileName ) +{ + return TQImageIO::imageFormat(fileName); +} + +/*! + Loads a pixmap from the file \a fileName at runtime. Returns TRUE + if successful; otherwise returns FALSE. + + If \a format is specified, the loader attempts to read the pixmap + using the specified format. If \a format is not specified + (default), the loader reads a few bytes from the header to guess + the file's format. + + See the convertFromImage() documentation for a description of the + \a conversion_flags argument. + + The TQImageIO documentation lists the supported image formats and + explains how to add extra formats. + + \sa loadFromData(), save(), imageFormat(), TQImage::load(), + TQImageIO +*/ + +bool TQPixmap::load( const TQString &fileName, const char *format, + int conversion_flags ) +{ + TQImageIO io( fileName, format ); + bool result = io.read(); + if ( result ) { + detach(); // ###hanord: Why detach here, convertFromImage does it + result = convertFromImage( io.image(), conversion_flags ); + } + return result; +} + +/*! + \overload + + Loads a pixmap from the file \a fileName at runtime. + + If \a format is specified, the loader attempts to read the pixmap + using the specified format. If \a format is not specified + (default), the loader reads a few bytes from the header to guess + the file's format. + + The \a mode is used to specify the color mode of the pixmap. + + \sa TQPixmap::ColorMode +*/ + +bool TQPixmap::load( const TQString &fileName, const char *format, + ColorMode mode ) +{ + int conversion_flags = 0; + switch (mode) { + case Color: + conversion_flags |= ColorOnly; + break; + case Mono: + conversion_flags |= MonoOnly; + break; + default: + break;// Nothing. + } + return load( fileName, format, conversion_flags ); +} +#endif //TQT_NO_IMAGEIO + +/*! + \overload + + Converts \a image and sets this pixmap using color mode \a mode. + Returns TRUE if successful; otherwise returns FALSE. + + \sa TQPixmap::ColorMode +*/ + +bool TQPixmap::convertFromImage( const TQImage &image, ColorMode mode ) +{ + if ( image.isNull() ) { + // convert null image to null pixmap + *this = TQPixmap(); + return TRUE; + } + + int conversion_flags = 0; + switch (mode) { + case Color: + conversion_flags |= ColorOnly; + break; + case Mono: + conversion_flags |= MonoOnly; + break; + default: + break;// Nothing. + } + return convertFromImage( image, conversion_flags ); +} + +#ifndef TQT_NO_IMAGEIO +/*! + Loads a pixmap from the binary data in \a buf (\a len bytes). + Returns TRUE if successful; otherwise returns FALSE. + + If \a format is specified, the loader attempts to read the pixmap + using the specified format. If \a format is not specified + (default), the loader reads a few bytes from the header to guess + the file's format. + + See the convertFromImage() documentation for a description of the + \a conversion_flags argument. + + The TQImageIO documentation lists the supported image formats and + explains how to add extra formats. + + \sa load(), save(), imageFormat(), TQImage::loadFromData(), + TQImageIO +*/ + +bool TQPixmap::loadFromData( const uchar *buf, uint len, const char *format, + int conversion_flags ) +{ + TQByteArray a; + a.setRawData( (char *)buf, len ); + TQBuffer b( a ); + b.open( IO_ReadOnly ); + TQImageIO io( &b, format ); + bool result = io.read(); + b.close(); + a.resetRawData( (char *)buf, len ); + if ( result ) { + detach(); + result = convertFromImage( io.image(), conversion_flags ); + } + return result; +} + +/*! + \overload + + Loads a pixmap from the binary data in \a buf (\a len bytes) using + color mode \a mode. Returns TRUE if successful; otherwise returns + FALSE. + + If \a format is specified, the loader attempts to read the pixmap + using the specified format. If \a format is not specified + (default), the loader reads a few bytes from the header to guess + the file's format. + + \sa TQPixmap::ColorMode +*/ + +bool TQPixmap::loadFromData( const uchar *buf, uint len, const char *format, + ColorMode mode ) +{ + int conversion_flags = 0; + switch (mode) { + case Color: + conversion_flags |= ColorOnly; + break; + case Mono: + conversion_flags |= MonoOnly; + break; + default: + break;// Nothing. + } + return loadFromData( buf, len, format, conversion_flags ); +} + +/*! + \overload +*/ + +bool TQPixmap::loadFromData( const TQByteArray &buf, const char *format, + int conversion_flags ) +{ + return loadFromData( (const uchar *)(buf.data()), buf.size(), + format, conversion_flags ); +} + + +/*! + Saves the pixmap to the file \a fileName using the image file + format \a format and a quality factor \a quality. \a quality must + be in the range [0,100] or -1. Specify 0 to obtain small + compressed files, 100 for large uncompressed files, and -1 to use + the default settings. Returns TRUE if successful; otherwise + returns FALSE. + + \sa load(), loadFromData(), imageFormat(), TQImage::save(), + TQImageIO +*/ + +bool TQPixmap::save( const TQString &fileName, const char *format, int quality ) const +{ + if ( isNull() ) + return FALSE; // nothing to save + TQImageIO io( fileName, format ); + return doImageIO( &io, quality ); +} + +/*! + \overload + + This function writes a TQPixmap to the TQIODevice, \a tqdevice. This + can be used, for example, to save a pixmap directly into a + TQByteArray: + \code + TQPixmap pixmap; + TQByteArray ba; + TQBuffer buffer( ba ); + buffer.open( IO_WriteOnly ); + pixmap.save( &buffer, "PNG" ); // writes pixmap into ba in PNG format + \endcode +*/ + +bool TQPixmap::save( TQIODevice* tqdevice, const char* format, int quality ) const +{ + if ( isNull() ) + return FALSE; // nothing to save + TQImageIO io( tqdevice, format ); + return doImageIO( &io, quality ); +} + +/*! \internal +*/ + +bool TQPixmap::doImageIO( TQImageIO* io, int quality ) const +{ + if ( !io ) + return FALSE; + io->setImage( convertToImage() ); +#if defined(TQT_CHECK_RANGE) + if ( quality > 100 || quality < -1 ) + qWarning( "TQPixmap::save: quality out of range [-1,100]" ); +#endif + if ( quality >= 0 ) + io->setQuality( TQMIN(quality,100) ); + return io->write(); +} + +#endif //TQT_NO_IMAGEIO + +/*! + \fn int TQPixmap::serialNumber() const + + Returns a number that uniquely identifies the contents of this + TQPixmap object. This means that multiple TQPixmap objects can have + the same serial number as long as they refer to the same contents. + + An example of where this is useful is for caching TQPixmaps. + + \sa TQPixmapCache +*/ + + +/*! + Returns the default pixmap optimization setting. + + \sa setDefaultOptimization(), setOptimization(), optimization() +*/ + +TQPixmap::Optimization TQPixmap::defaultOptimization() +{ + return defOptim; +} + +/*! + Sets the default pixmap optimization. + + All \e new pixmaps that are created will use this default + optimization. You may also set optimization for individual pixmaps + using the setOptimization() function. + + The initial default \a optimization setting is \c TQPixmap::Normal. + + \sa defaultOptimization(), setOptimization(), optimization() +*/ + +void TQPixmap::setDefaultOptimization( Optimization optimization ) +{ + if ( optimization != DefaultOptim ) + defOptim = optimization; +} + + +// helper for next function. +static TQPixmap grabChildWidgets( TQWidget * w ) +{ + TQPixmap res( w->width(), w->height() ); + if ( res.isNull() && w->width() ) + return res; + res.fill( w, TQPoint( 0, 0 ) ); + TQPaintDevice *oldRedirect = TQPainter::redirect( w ); + TQPainter::redirect( w, &res ); + bool dblbfr = TQSharedDoubleBuffer::isDisabled(); + TQSharedDoubleBuffer::setDisabled( TRUE ); + TQPaintEvent e( w->rect(), FALSE ); + TQApplication::sendEvent( w, &e ); + TQSharedDoubleBuffer::setDisabled( dblbfr ); + TQPainter::redirect( w, oldRedirect ); + + if ( !w->childrenListObject().isEmpty() ) { + TQPainter p( &res ); + TQObjectListIt it( w->childrenListObject() ); + TQObject * child; + while( (child=it.current()) != 0 ) { + ++it; + if ( child->isWidgetType() && + !((TQWidget *)child)->isHidden() && + !((TQWidget *)child)->isTopLevel() && + ((TQWidget *)child)->tqgeometry().intersects( w->rect() ) ) { + // those conditions aren't quite right, it's possible + // to have a grandchild completely outside its + // grandtqparent, but partially inside its tqparent. no + // point in optimizing for that. + + // make sure to evaluate pos() first - who knows what + // the paint event(s) inside grabChildWidgets() will do. + TQPoint childpos = ((TQWidget *)child)->pos(); + TQPixmap cpm = grabChildWidgets( (TQWidget *)child ); + if ( cpm.isNull() ) { + // Some child pixmap failed - abort and reset + res.resize( 0, 0 ); + break; + } + p.drawPixmap( childpos, cpm); + } + } + } + return res; +} + + +/*! + Creates a pixmap and paints \a widget in it. + + If the \a widget has any tqchildren, then they are also painted in + the appropriate positions. + + If you specify \a x, \a y, \a w or \a h, only the rectangle you + specify is painted. The defaults are 0, 0 (top-left corner) and + -1,-1 (which means the entire widget). + + (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.) + + If \a widget is 0, or if the rectangle defined by \a x, \a y, the + modified \a w and the modified \a h does not overlap the \a + {widget}->rect(), this function will return a null TQPixmap. + + This function actually asks \a widget to paint itself (and its + tqchildren to paint themselves). TQPixmap::grabWindow() grabs pixels + off the screen, which is a bit faster and picks up \e exactly + what's on-screen. This function works by calling paintEvent() with + painter redirection turned on. If there are overlaying windows, + grabWindow() will see them, but not this function. + + If there is overlap, it returns a pixmap of the size you want, + containing a rendering of \a widget. If the rectangle you ask for + is a superset of \a widget, the areas outside \a widget are + covered with the widget's background. + + If an error occurs when trying to grab the widget, such as the + size of the widget being too large to fit in memory, an isNull() + pixmap is returned. + + \sa grabWindow() TQPainter::redirect() TQWidget::paintEvent() +*/ + +TQPixmap TQPixmap::grabWidget( TQWidget * widget, int x, int y, int w, int h ) +{ + TQPixmap res; + if ( !widget ) + return res; + + if ( w < 0 ) + w = widget->width() - x; + if ( h < 0 ) + h = widget->height() - y; + + TQRect wr( x, y, w, h ); + if ( wr == widget->rect() ) + return grabChildWidgets( widget ); + if ( !wr.intersects( widget->rect() ) ) + return res; + + res.resize( w, h ); + if( res.isNull() ) + return res; + res.fill( widget, TQPoint( w,h ) ); + TQPixmap tmp( grabChildWidgets( widget ) ); + if( tmp.isNull() ) + return tmp; + ::bitBlt( &res, 0, 0, &tmp, x, y, w, h ); + return res; +} + +/*! + Returns the actual matrix used for transforming a pixmap with \a w + width and \a h height and matrix \a matrix. + + When transforming a pixmap with xForm(), the transformation matrix + is internally adjusted to compensate for unwanted translation, + i.e. xForm() returns the smallest pixmap containing all + transformed points of the original pixmap. + + This function returns the modified matrix, which maps points + correctly from the original pixmap into the new pixmap. + + \sa xForm(), TQWMatrix +*/ +#ifndef TQT_NO_PIXMAP_TRANSFORMATION +TQWMatrix TQPixmap::trueMatrix( const TQWMatrix &matrix, int w, int h ) +{ + const double dt = (double)0.; + double x1,y1, x2,y2, x3,y3, x4,y4; // get corners + double xx = (double)w; + double yy = (double)h; + + TQWMatrix mat( matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), 0., 0. ); + + mat.map( dt, dt, &x1, &y1 ); + mat.map( xx, dt, &x2, &y2 ); + mat.map( xx, yy, &x3, &y3 ); + mat.map( dt, yy, &x4, &y4 ); + + double ymin = y1; // lowest y value + if ( y2 < ymin ) ymin = y2; + if ( y3 < ymin ) ymin = y3; + if ( y4 < ymin ) ymin = y4; + double xmin = x1; // lowest x value + if ( x2 < xmin ) xmin = x2; + if ( x3 < xmin ) xmin = x3; + if ( x4 < xmin ) xmin = x4; + + double ymax = y1; // lowest y value + if ( y2 > ymax ) ymax = y2; + if ( y3 > ymax ) ymax = y3; + if ( y4 > ymax ) ymax = y4; + double xmax = x1; // lowest x value + if ( x2 > xmax ) xmax = x2; + if ( x3 > xmax ) xmax = x3; + if ( x4 > xmax ) xmax = x4; + + if ( xmax-xmin > 1.0 ) + xmin -= xmin/(xmax-xmin); + if ( ymax-ymin > 1.0 ) + ymin -= ymin/(ymax-ymin); + + mat.setMatrix( matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), -xmin, -ymin ); + return mat; +} +#endif // TQT_NO_WMATRIX + + + + + +/***************************************************************************** + TQPixmap stream functions + *****************************************************************************/ +#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO) +/*! + \relates TQPixmap + + Writes the pixmap \a pixmap to the stream \a s as a PNG image. + + Note that writing the stream to a file will not produce a valid image file. + + \sa TQPixmap::save() + \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQPixmap &pixmap ) +{ + s << pixmap.convertToImage(); + return s; +} + +/*! + \relates TQPixmap + + Reads a pixmap from the stream \a s into the pixmap \a pixmap. + + \sa TQPixmap::load() + \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQPixmap &pixmap ) +{ + TQImage img; + s >> img; + pixmap.convertFromImage( img ); + return s; +} + +#endif //TQT_NO_DATASTREAM + + + + +/***************************************************************************** + TQPixmap (and TQImage) helper functions + *****************************************************************************/ +/* + This internal function tqcontains the common (i.e. platform independent) code + to do a transformation of pixel data. It is used by TQPixmap::xForm() and by + TQImage::xForm(). + + \a trueMat is the true transformation matrix (see TQPixmap::trueMatrix()) and + \a xoffset is an offset to the matrix. + + \a msbfirst specifies for 1bpp images, if the MSB or LSB comes first and \a + depth specifies the colordepth of the data. + + \a dptr is a pointer to the destination data, \a dbpl specifies the bits per + line for the destination data, \a p_inc is the offset that we advance for + every scanline and \a dHeight is the height of the destination image. + + \a sprt is the pointer to the source data, \a sbpl specifies the bits per + line of the source data, \a sWidth and \a sHeight are the width and height of + the source data. +*/ +#ifndef TQT_NO_PIXMAP_TRANSFORMATION +#undef IWX_MSB +#define IWX_MSB(b) if ( trigx < maxws && trigy < maxhs ) { \ + if ( *(sptr+sbpl*(trigy>>16)+(trigx>>19)) & \ + (1 << (7-((trigx>>16)&7))) ) \ + *dptr |= b; \ + } \ + trigx += m11; \ + trigy += m12; + // END OF MACRO +#undef IWX_LSB +#define IWX_LSB(b) if ( trigx < maxws && trigy < maxhs ) { \ + if ( *(sptr+sbpl*(trigy>>16)+(trigx>>19)) & \ + (1 << ((trigx>>16)&7)) ) \ + *dptr |= b; \ + } \ + trigx += m11; \ + trigy += m12; + // END OF MACRO +#undef IWX_PIX +#define IWX_PIX(b) if ( trigx < maxws && trigy < maxhs ) { \ + if ( (*(sptr+sbpl*(trigy>>16)+(trigx>>19)) & \ + (1 << (7-((trigx>>16)&7)))) == 0 ) \ + *dptr &= ~b; \ + } \ + trigx += m11; \ + trigy += m12; + // END OF MACRO +bool qt_xForm_helper( const TQWMatrix &trueMat, int xoffset, + int type, int depth, + uchar *dptr, int dbpl, int p_inc, int dHeight, + uchar *sptr, int sbpl, int sWidth, int sHeight + ) +{ + int m11 = int(trueMat.m11()*65536.0 + 1.); + int m12 = int(trueMat.m12()*65536.0 + 1.); + int m21 = int(trueMat.m21()*65536.0 + 1.); + int m22 = int(trueMat.m22()*65536.0 + 1.); + int dx = tqRound(trueMat.dx() *65536.0); + int dy = tqRound(trueMat.dy() *65536.0); + + int m21ydx = dx + (xoffset<<16); + int m22ydy = dy; + uint trigx; + uint trigy; + uint maxws = sWidth<<16; + uint maxhs = sHeight<<16; + + for ( int y=0; y<dHeight; y++ ) { // for each target scanline + trigx = m21ydx; + trigy = m22ydy; + uchar *maxp = dptr + dbpl; + if ( depth != 1 ) { + switch ( depth ) { + case 8: // 8 bpp transform + while ( dptr < maxp ) { + if ( trigx < maxws && trigy < maxhs ) + *dptr = *(sptr+sbpl*(trigy>>16)+(trigx>>16)); + trigx += m11; + trigy += m12; + dptr++; + } + break; + + case 16: // 16 bpp transform + while ( dptr < maxp ) { + if ( trigx < maxws && trigy < maxhs ) + *((ushort*)dptr) = *((ushort *)(sptr+sbpl*(trigy>>16) + + ((trigx>>16)<<1))); + trigx += m11; + trigy += m12; + dptr++; + dptr++; + } + break; + + case 24: { // 24 bpp transform + uchar *p2; + while ( dptr < maxp ) { + if ( trigx < maxws && trigy < maxhs ) { + p2 = sptr+sbpl*(trigy>>16) + ((trigx>>16)*3); + dptr[0] = p2[0]; + dptr[1] = p2[1]; + dptr[2] = p2[2]; + } + trigx += m11; + trigy += m12; + dptr += 3; + } + } + break; + + case 32: // 32 bpp transform + while ( dptr < maxp ) { + if ( trigx < maxws && trigy < maxhs ) + *((uint*)dptr) = *((uint *)(sptr+sbpl*(trigy>>16) + + ((trigx>>16)<<2))); + trigx += m11; + trigy += m12; + dptr += 4; + } + break; + + default: { + return FALSE; + } + } + } else { + switch ( type ) { + case TQT_XFORM_TYPE_MSBFIRST: + while ( dptr < maxp ) { + IWX_MSB(128); + IWX_MSB(64); + IWX_MSB(32); + IWX_MSB(16); + IWX_MSB(8); + IWX_MSB(4); + IWX_MSB(2); + IWX_MSB(1); + dptr++; + } + break; + case TQT_XFORM_TYPE_LSBFIRST: + while ( dptr < maxp ) { + IWX_LSB(1); + IWX_LSB(2); + IWX_LSB(4); + IWX_LSB(8); + IWX_LSB(16); + IWX_LSB(32); + IWX_LSB(64); + IWX_LSB(128); + dptr++; + } + break; +# if defined(TQ_WS_WIN) + case TQT_XFORM_TYPE_WINDOWSPIXMAP: + while ( dptr < maxp ) { + IWX_PIX(128); + IWX_PIX(64); + IWX_PIX(32); + IWX_PIX(16); + IWX_PIX(8); + IWX_PIX(4); + IWX_PIX(2); + IWX_PIX(1); + dptr++; + } + break; +# endif + } + } + m21ydx += m21; + m22ydy += m22; + dptr += p_inc; + } + return TRUE; +} +#undef IWX_MSB +#undef IWX_LSB +#undef IWX_PIX +#endif // TQT_NO_PIXMAP_TRANSFORMATION + +#endif // USE_QT4 |
