From 1e9fa8e06de5da7fcc268e9cccb2d6b21c5f53a3 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Sat, 20 Jul 2024 20:15:52 +0900 Subject: Rename graphics class nt* related files to equivalent tq* (part 2) Signed-off-by: Michele Calgaro --- src/kernel/ntqaccessible.h | 2 +- src/kernel/ntqapplication.h | 2 +- src/kernel/ntqcursor.h | 2 +- src/kernel/ntqevent.h | 2 +- src/kernel/ntqpalette.h | 183 --- src/kernel/ntqpen.h | 102 -- src/kernel/ntqpicture.h | 127 -- src/kernel/ntqpixmap.h | 340 ----- src/kernel/ntqpixmapcache.h | 63 - src/kernel/ntqpngio.h | 107 -- src/kernel/ntqpoint.h | 219 --- src/kernel/ntqpointarray.h | 118 -- src/kernel/ntqprinter.h | 284 ---- src/kernel/ntqrect.h | 276 ---- src/kernel/ntqregion.h | 172 --- src/kernel/ntqsimplerichtext.h | 2 +- src/kernel/ntqt.h | 26 +- src/kernel/ntqwmatrix.h | 129 -- src/kernel/qapplication_x11.cpp | 2 +- src/kernel/qdrawutil.cpp | 2 +- src/kernel/qinternal.cpp | 2 +- src/kernel/qinternal_p.h | 2 +- src/kernel/qpalette.cpp | 1200 ---------------- src/kernel/qpicture.cpp | 1229 ----------------- src/kernel/qpixmap.cpp | 1510 -------------------- src/kernel/qpixmap_x11.cpp | 2482 --------------------------------- src/kernel/qpixmapcache.cpp | 336 ----- src/kernel/qpngio.cpp | 1351 ------------------ src/kernel/qpoint.cpp | 443 ------ src/kernel/qpointarray.cpp | 1109 --------------- src/kernel/qpolygonscanner.cpp | 2 +- src/kernel/qprinter.cpp | 1028 -------------- src/kernel/qprinter_p.h | 62 - src/kernel/qprinter_unix.cpp | 668 --------- src/kernel/qpsprinter_p.h | 4 +- src/kernel/qrect.cpp | 960 ------------- src/kernel/qregion.cpp | 383 ------ src/kernel/qregion_x11.cpp | 2896 --------------------------------------- src/kernel/qrichtext_p.h | 4 +- src/kernel/qscriptengine.cpp | 2 +- src/kernel/qt_gfx.pri | 4 +- src/kernel/qt_kernel.pri | 60 +- src/kernel/qt_pch.h | 2 +- src/kernel/qvariant.cpp | 14 +- src/kernel/qwmatrix.cpp | 1036 -------------- src/kernel/tqbitmap.h | 2 +- src/kernel/tqclipboard.cpp | 2 +- src/kernel/tqdragobject.cpp | 2 +- src/kernel/tqfontmetrics.h | 2 +- src/kernel/tqiconset.h | 2 +- src/kernel/tqimage.cpp | 4 +- src/kernel/tqimage.h | 2 +- src/kernel/tqmovie.cpp | 2 +- src/kernel/tqmovie.h | 2 +- src/kernel/tqpaintdevice.h | 2 +- src/kernel/tqpainter.cpp | 2 +- src/kernel/tqpainter.h | 8 +- src/kernel/tqpainter_x11.cpp | 6 +- src/kernel/tqpalette.cpp | 1200 ++++++++++++++++ src/kernel/tqpalette.h | 183 +++ src/kernel/tqpen.h | 102 ++ src/kernel/tqpicture.cpp | 1229 +++++++++++++++++ src/kernel/tqpicture.h | 127 ++ src/kernel/tqpixmap.cpp | 1510 ++++++++++++++++++++ src/kernel/tqpixmap.h | 340 +++++ src/kernel/tqpixmap_x11.cpp | 2482 +++++++++++++++++++++++++++++++++ src/kernel/tqpixmapcache.cpp | 336 +++++ src/kernel/tqpixmapcache.h | 63 + src/kernel/tqpngio.cpp | 1351 ++++++++++++++++++ src/kernel/tqpngio.h | 107 ++ src/kernel/tqpoint.cpp | 443 ++++++ src/kernel/tqpoint.h | 219 +++ src/kernel/tqpointarray.cpp | 1109 +++++++++++++++ src/kernel/tqpointarray.h | 118 ++ src/kernel/tqprinter.cpp | 1028 ++++++++++++++ src/kernel/tqprinter.h | 284 ++++ src/kernel/tqprinter_p.h | 62 + src/kernel/tqprinter_unix.cpp | 668 +++++++++ src/kernel/tqrect.cpp | 960 +++++++++++++ src/kernel/tqrect.h | 276 ++++ src/kernel/tqregion.cpp | 383 ++++++ src/kernel/tqregion.h | 172 +++ src/kernel/tqregion_x11.cpp | 2896 +++++++++++++++++++++++++++++++++++++++ src/kernel/tqsize.h | 2 +- src/kernel/tqstyle.cpp | 2 +- src/kernel/tqstyle.h | 2 +- src/kernel/tqtextlayout_p.h | 2 +- src/kernel/tqwidget.cpp | 2 +- src/kernel/tqwidget.h | 2 +- src/kernel/tqwmatrix.cpp | 1036 ++++++++++++++ src/kernel/tqwmatrix.h | 129 ++ 91 files changed, 18906 insertions(+), 18906 deletions(-) delete mode 100644 src/kernel/ntqpalette.h delete mode 100644 src/kernel/ntqpen.h delete mode 100644 src/kernel/ntqpicture.h delete mode 100644 src/kernel/ntqpixmap.h delete mode 100644 src/kernel/ntqpixmapcache.h delete mode 100644 src/kernel/ntqpngio.h delete mode 100644 src/kernel/ntqpoint.h delete mode 100644 src/kernel/ntqpointarray.h delete mode 100644 src/kernel/ntqprinter.h delete mode 100644 src/kernel/ntqrect.h delete mode 100644 src/kernel/ntqregion.h delete mode 100644 src/kernel/ntqwmatrix.h delete mode 100644 src/kernel/qpalette.cpp delete mode 100644 src/kernel/qpicture.cpp delete mode 100644 src/kernel/qpixmap.cpp delete mode 100644 src/kernel/qpixmap_x11.cpp delete mode 100644 src/kernel/qpixmapcache.cpp delete mode 100644 src/kernel/qpngio.cpp delete mode 100644 src/kernel/qpoint.cpp delete mode 100644 src/kernel/qpointarray.cpp delete mode 100644 src/kernel/qprinter.cpp delete mode 100644 src/kernel/qprinter_p.h delete mode 100644 src/kernel/qprinter_unix.cpp delete mode 100644 src/kernel/qrect.cpp delete mode 100644 src/kernel/qregion.cpp delete mode 100644 src/kernel/qregion_x11.cpp delete mode 100644 src/kernel/qwmatrix.cpp create mode 100644 src/kernel/tqpalette.cpp create mode 100644 src/kernel/tqpalette.h create mode 100644 src/kernel/tqpen.h create mode 100644 src/kernel/tqpicture.cpp create mode 100644 src/kernel/tqpicture.h create mode 100644 src/kernel/tqpixmap.cpp create mode 100644 src/kernel/tqpixmap.h create mode 100644 src/kernel/tqpixmap_x11.cpp create mode 100644 src/kernel/tqpixmapcache.cpp create mode 100644 src/kernel/tqpixmapcache.h create mode 100644 src/kernel/tqpngio.cpp create mode 100644 src/kernel/tqpngio.h create mode 100644 src/kernel/tqpoint.cpp create mode 100644 src/kernel/tqpoint.h create mode 100644 src/kernel/tqpointarray.cpp create mode 100644 src/kernel/tqpointarray.h create mode 100644 src/kernel/tqprinter.cpp create mode 100644 src/kernel/tqprinter.h create mode 100644 src/kernel/tqprinter_p.h create mode 100644 src/kernel/tqprinter_unix.cpp create mode 100644 src/kernel/tqrect.cpp create mode 100644 src/kernel/tqrect.h create mode 100644 src/kernel/tqregion.cpp create mode 100644 src/kernel/tqregion.h create mode 100644 src/kernel/tqregion_x11.cpp create mode 100644 src/kernel/tqwmatrix.cpp create mode 100644 src/kernel/tqwmatrix.h (limited to 'src/kernel') diff --git a/src/kernel/ntqaccessible.h b/src/kernel/ntqaccessible.h index 2d0302a9d..4ea410f4c 100644 --- a/src/kernel/ntqaccessible.h +++ b/src/kernel/ntqaccessible.h @@ -42,7 +42,7 @@ #ifndef QT_H #include "tqobject.h" #include -#include "ntqrect.h" +#include "tqrect.h" #include "ntqguardedptr.h" #include "tqmemarray.h" #endif // QT_H diff --git a/src/kernel/ntqapplication.h b/src/kernel/ntqapplication.h index 3568ad454..fc4448089 100644 --- a/src/kernel/ntqapplication.h +++ b/src/kernel/ntqapplication.h @@ -44,7 +44,7 @@ #ifndef QT_H #include "ntqdesktopwidget.h" #include "tqasciidict.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "ntqtranslator.h" #include "tqstrlist.h" #include "tqstringlist.h" diff --git a/src/kernel/ntqcursor.h b/src/kernel/ntqcursor.h index 1e9b183fb..aeb36d2f0 100644 --- a/src/kernel/ntqcursor.h +++ b/src/kernel/ntqcursor.h @@ -42,7 +42,7 @@ #define TQCURSOR_H #ifndef QT_H -#include "ntqpoint.h" +#include "tqpoint.h" #include "ntqshared.h" #endif // QT_H diff --git a/src/kernel/ntqevent.h b/src/kernel/ntqevent.h index 769244360..f05fc2c94 100644 --- a/src/kernel/ntqevent.h +++ b/src/kernel/ntqevent.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "ntqwindowdefs.h" -#include "ntqregion.h" +#include "tqregion.h" #include "ntqnamespace.h" #include "tqmime.h" #include "tqpair.h" diff --git a/src/kernel/ntqpalette.h b/src/kernel/ntqpalette.h deleted file mode 100644 index 9f0ca13f0..000000000 --- a/src/kernel/ntqpalette.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Definition of TQColorGroup and TQPalette classes -** -** Created : 950323 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPALETTE_H -#define TQPALETTE_H - -#ifndef QT_H -#include "ntqwindowdefs.h" -#include "tqcolor.h" -#include "ntqshared.h" -#include "tqbrush.h" // TQColor->TQBrush conversion -#endif // QT_H - -#ifndef TQT_NO_PALETTE - -class TQColorGroupPrivate; - -class TQ_EXPORT TQColorGroup -{ -public: - TQColorGroup(); - TQColorGroup( const TQColor &foreground, const TQColor &button, - const TQColor &light, const TQColor &dark, const TQColor &mid, - const TQColor &text, const TQColor &base ); - TQColorGroup( const TQBrush &foreground, const TQBrush &button, - const TQBrush &light, const TQBrush &dark, const TQBrush &mid, - const TQBrush &text, const TQBrush &bright_text, - const TQBrush &base, const TQBrush &background); - TQColorGroup( const TQColorGroup & ); - - ~TQColorGroup(); - - TQColorGroup& operator =(const TQColorGroup&); - - // Do not change the order, the serialization format depends on it - enum ColorRole { Foreground, Button, Light, Midlight, Dark, Mid, - Text, BrightText, ButtonText, Base, Background, Shadow, - Highlight, HighlightedText, Link, LinkVisited, - NColorRoles }; - - const TQColor &color( ColorRole ) const; - const TQBrush &brush( ColorRole ) const; - void setColor( ColorRole, const TQColor & ); - void setBrush( ColorRole, const TQBrush & ); - - const TQColor &foreground() const { return br[Foreground].color(); } - const TQColor &button() const { return br[Button].color(); } - const TQColor &light() const { return br[Light].color(); } - const TQColor &dark() const { return br[Dark].color(); } - const TQColor &mid() const { return br[Mid].color(); } - const TQColor &text() const { return br[Text].color(); } - const TQColor &base() const { return br[Base].color(); } - const TQColor &background() const { return br[Background].color(); } - - const TQColor &midlight() const { return br[Midlight].color(); } - const TQColor &brightText() const { return br[BrightText].color(); } - const TQColor &buttonText() const { return br[ButtonText].color(); } - const TQColor &shadow() const { return br[Shadow].color(); } - const TQColor &highlight() const { return br[Highlight].color(); } - const TQColor &highlightedText() const{return br[HighlightedText].color(); } - const TQColor &link() const { return br[Link].color(); } - const TQColor &linkVisited() const { return br[LinkVisited].color(); } - - bool operator==( const TQColorGroup &g ) const; - bool operator!=( const TQColorGroup &g ) const - { return !(operator==(g)); } - -private: - TQBrush *br; - TQColorGroupPrivate * d; - - friend class TQPalette; -}; - - -class TQ_EXPORT TQPalette -{ -public: - TQPalette(); - TQPalette( const TQColor &button ); - TQPalette( const TQColor &button, const TQColor &background ); - TQPalette( const TQColorGroup &active, const TQColorGroup &disabled, - const TQColorGroup &inactive ); - TQPalette( const TQPalette & ); - ~TQPalette(); - TQPalette &operator=( const TQPalette & ); - - enum ColorGroup { Disabled, Active, Inactive, NColorGroups }; - - const TQColor &color( ColorGroup, TQColorGroup::ColorRole ) const; - const TQBrush &brush( ColorGroup, TQColorGroup::ColorRole ) const; - void setColor( ColorGroup, TQColorGroup::ColorRole, const TQColor & ); - void setBrush( ColorGroup, TQColorGroup::ColorRole, const TQBrush & ); - - void setColor( TQColorGroup::ColorRole, const TQColor & ); - void setBrush( TQColorGroup::ColorRole, const TQBrush & ); - - TQPalette copy() const; - - const TQColorGroup &active() const { return data->active; } - const TQColorGroup &disabled() const { return data->disabled; } - const TQColorGroup &inactive() const { return data->inactive; } - - void setActive( const TQColorGroup & ); - void setDisabled( const TQColorGroup & ); - void setInactive( const TQColorGroup & ); - - bool operator==( const TQPalette &p ) const; - bool operator!=( const TQPalette &p ) const - { return !(operator==(p)); } - bool isCopyOf( const TQPalette & ); - - int serialNumber() const { return data->ser_no; } - - - static TQColorGroup::ColorRole foregroundRoleFromMode( TQt::BackgroundMode mode ); - static TQColorGroup::ColorRole backgroundRoleFromMode( TQt::BackgroundMode mode); - -private: - void detach(); - const TQBrush &directBrush( ColorGroup, TQColorGroup::ColorRole ) const; - void directSetBrush( ColorGroup, TQColorGroup::ColorRole, const TQBrush& ); - - struct TQPalData : public TQShared { - TQColorGroup disabled; - TQColorGroup active; - int ser_no; - TQColorGroup inactive; - } *data; -}; - - -/***************************************************************************** - TQColorGroup/TQPalette stream functions - *****************************************************************************/ - -#ifndef TQT_NO_DATASTREAM -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQColorGroup & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQColorGroup & ); - -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPalette & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPalette & ); -#endif // TQT_NO_DATASTREAM - -#endif // TQT_NO_PALETTE -#endif // TQPALETTE_H diff --git a/src/kernel/ntqpen.h b/src/kernel/ntqpen.h deleted file mode 100644 index 3a0a0f8d0..000000000 --- a/src/kernel/ntqpen.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Definition of TQPen class -** -** Created : 940112 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPEN_H -#define TQPEN_H - -#ifndef QT_H -#include "tqcolor.h" -#include "ntqshared.h" -#endif // QT_H - - -class TQ_EXPORT TQPen: public TQt -{ -public: - TQPen(); - TQPen( PenStyle ); - TQPen( const TQColor &color, uint width=0, PenStyle style=SolidLine ); - TQPen( const TQColor &cl, uint w, PenStyle s, PenCapStyle c, PenJoinStyle j); - TQPen( const TQPen & ); - ~TQPen(); - TQPen &operator=( const TQPen & ); - - PenStyle style() const { return data->style; } - void setStyle( PenStyle ); - uint width() const { return data->width; } - void setWidth( uint ); - const TQColor &color() const { return data->color; } - void setColor( const TQColor & ); - PenCapStyle capStyle() const; - void setCapStyle( PenCapStyle ); - PenJoinStyle joinStyle() const; - void setJoinStyle( PenJoinStyle ); - - bool operator==( const TQPen &p ) const; - bool operator!=( const TQPen &p ) const - { return !(operator==(p)); } - -private: - friend class TQPainter; -#ifdef TQ_WS_WIN - friend class TQFontEngineWin; -#endif - - TQPen copy() const; - void detach(); - void init( const TQColor &, uint, uint ); - struct TQPenData : public TQShared { // pen data - PenStyle style; - uint width; - TQColor color; - TQ_UINT16 linest; - } *data; -}; - - -/***************************************************************************** - TQPen stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPen & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPen & ); -#endif - -#endif // TQPEN_H diff --git a/src/kernel/ntqpicture.h b/src/kernel/ntqpicture.h deleted file mode 100644 index 28512b61f..000000000 --- a/src/kernel/ntqpicture.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Definition of TQPicture class -** -** Created : 940729 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPICTURE_H -#define TQPICTURE_H - -#ifndef QT_H -#include "tqpaintdevice.h" -#include "tqbuffer.h" -#endif // QT_H - -#ifndef TQT_NO_PICTURE - -class TQ_EXPORT TQPicture : public TQPaintDevice // picture class -{ -public: - TQPicture( int formatVersion = -1 ); - TQPicture( const TQPicture & ); - ~TQPicture(); - - bool isNull() const; - - uint size() const; - const char* data() const; - virtual void setData( const char* data, uint size ); - - bool play( TQPainter * ); - - bool load( TQIODevice *dev, const char *format = 0 ); - bool load( const TQString &fileName, const char *format = 0 ); - bool save( TQIODevice *dev, const char *format = 0 ); - bool save( const TQString &fileName, const char *format = 0 ); - - TQRect boundingRect() const; - void setBoundingRect( const TQRect &r ); - - TQPicture& operator= (const TQPicture&); - - friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPicture & ); - friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPicture & ); - -protected: - bool cmd( int, TQPainter *, TQPDevCmdParam * ); - int metric( int ) const; - void detach(); - TQPicture copy() const; - -private: - bool exec( TQPainter *, TQDataStream &, int ); - - struct TQPicturePrivate : public TQShared { - bool cmd( int, TQPainter *, TQPDevCmdParam * ); - bool checkFormat(); - void resetFormat(); - - TQBuffer pictb; - int trecs; - bool formatOk; - int formatMajor; - int formatMinor; - TQRect brect; - } *d; -}; - - -inline bool TQPicture::isNull() const -{ - return d->pictb.buffer().isNull(); -} - -inline uint TQPicture::size() const -{ - return d->pictb.buffer().size(); -} - -inline const char* TQPicture::data() const -{ - return d->pictb.buffer().data(); -} - -/***************************************************************************** - TQPicture stream functions - *****************************************************************************/ - -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPicture & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPicture & ); - -#endif // TQT_NO_PICTURE - -#endif // TQPICTURE_H diff --git a/src/kernel/ntqpixmap.h b/src/kernel/ntqpixmap.h deleted file mode 100644 index 70609d4a7..000000000 --- a/src/kernel/ntqpixmap.h +++ /dev/null @@ -1,340 +0,0 @@ -/**************************************************************************** -** -** Definition of TQPixmap class -** -** Created : 940501 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPIXMAP_H -#define TQPIXMAP_H - -#ifndef QT_H -#include "tqpaintdevice.h" -#include "tqcolor.h" // char*->TQColor conversion -#include "tqstring.h" // char*->TQString conversion -#include "ntqnamespace.h" -#endif // QT_H - -class TQPixmapPrivate; - -#if defined(TQ_WS_WIN) -// Internal pixmap memory optimization class for Windows 9x -class TQMultiCellPixmap; -#endif - - -class TQ_EXPORT TQPixmap : public TQPaintDevice, public TQt -{ -public: - enum ColorMode { Auto, Color, Mono }; - enum Optimization { DefaultOptim, NoOptim, MemoryOptim=NoOptim, - NormalOptim, BestOptim }; - - TQPixmap(); - TQPixmap( const TQImage& image ); - TQPixmap( int w, int h, int depth = -1, Optimization = DefaultOptim ); - TQPixmap( const TQSize &, int depth = -1, Optimization = DefaultOptim ); -#ifndef TQT_NO_IMAGEIO - TQPixmap( const TQString& fileName, const char *format=0, - ColorMode mode=Auto ); - TQPixmap( const TQString& fileName, const char *format, - int conversion_flags ); - TQPixmap( const char *xpm[] ); // ### in 4.0, 'const char * const xpm[]'? - TQPixmap( const TQByteArray &data ); -#endif - TQPixmap( const TQPixmap & ); - ~TQPixmap(); - - TQPixmap &operator=( const TQPixmap & ); - TQPixmap &operator=( const TQImage & ); - - bool isNull() const; - - int width() const { return data->w; } - int height() const { return data->h; } - TQSize size() const { return TQSize(data->w,data->h); } - TQRect rect() const { return TQRect(0,0,data->w,data->h); } - int depth() const { return data->d; } - static int defaultDepth(); - - void fill( const TQColor &fillColor = TQt::white ); - void fill( const TQWidget *, int xofs, int yofs ); - void fill( const TQWidget *, const TQPoint &ofs ); - void resize( int width, int height ); - void resize( const TQSize & ); - - const TQBitmap *mask() const; - void setMask( const TQBitmap & ); - bool selfMask() const; - bool hasAlpha() const; - bool hasAlphaChannel() const; -#ifndef TQT_NO_IMAGE_HEURISTIC_MASK - TQBitmap createHeuristicMask( bool clipTight = TRUE ) const; -#endif -#ifndef TQT_NO_MIME - static TQPixmap fromMimeSource( const TQString& abs_name ); -#endif - static TQPixmap grabWindow( WId, int x=0, int y=0, int w=-1, int h=-1 ); - static TQPixmap grabWidget( TQWidget * widget, - int x=0, int y=0, int w=-1, int h=-1 ); - -#ifndef TQT_NO_PIXMAP_TRANSFORMATION - TQPixmap xForm( const TQWMatrix & ) const; - static TQWMatrix trueMatrix( const TQWMatrix &, int w, int h ); -#endif - - TQImage convertToImage() const; - bool convertFromImage( const TQImage &, ColorMode mode=Auto ); - bool convertFromImage( const TQImage &, int conversion_flags ); -#ifndef TQT_NO_IMAGEIO - static const char* imageFormat( const TQString &fileName ); - bool load( const TQString& fileName, const char *format=0, - ColorMode mode=Auto ); - bool load( const TQString& fileName, const char *format, - int conversion_flags ); - bool loadFromData( const uchar *buf, uint len, - const char* format=0, - ColorMode mode=Auto ); - bool loadFromData( const uchar *buf, uint len, - const char* format, - int conversion_flags ); - bool loadFromData( const TQByteArray &data, - const char* format=0, - int conversion_flags=0 ); - bool save( const TQString& fileName, const char* format, int quality = -1 ) const; - bool save( TQIODevice* device, const char* format, int quality = -1 ) const; -#endif - -#if defined(TQ_WS_WIN) - HBITMAP hbm() const; -#endif - - int serialNumber() const; - - Optimization optimization() const; - void setOptimization( Optimization ); - static Optimization defaultOptimization(); - static void setDefaultOptimization( Optimization ); - - virtual void detach(); - - bool isTQBitmap() const; - -#if defined(TQ_WS_WIN) - // These functions are internal and used by Windows 9x only - bool isMultiCellPixmap() const; - HDC multiCellHandle() const; - HBITMAP multiCellBitmap() const; - int multiCellOffset() const; - int allocCell(); - void freeCell( bool = FALSE ); -#endif - -#if defined(TQ_WS_X11) - static int x11SetDefaultScreen( int screen ); - void x11SetScreen( int screen ); -#endif - -#ifndef Q_QDOC - TQ_DUMMY_COMPARISON_OPERATOR(TQPixmap) -#endif - -protected: - TQPixmap( int w, int h, const uchar *data, bool isXbitmap ); - int metric( int ) const; - -#if defined(TQ_WS_WIN) - struct TQMCPI { // mem optim for win9x - TQMultiCellPixmap *mcp; - int offset; - }; -#endif - - struct TQPixmapData : public TQShared { // internal pixmap data - TQCOORD w, h; - short d; - uint uninit : 1; - uint bitmap : 1; - uint selfmask : 1; -#if defined(TQ_WS_WIN) - uint mcp : 1; -#endif - int ser_no; - TQBitmap *mask; -#if defined(TQ_WS_WIN) - TQPixmap *maskpm; - union { - HBITMAP hbm; // if mcp == FALSE - TQMCPI *mcpi; // if mcp == TRUE - } hbm_or_mcpi; - uchar *realAlphaBits; -#ifdef Q_OS_TEMP - uchar* ppvBits; // Pointer to DIBSection bits -#endif -#elif defined(TQ_WS_X11) - void *ximage; - void *maskgc; - TQPixmap *alphapm; -#elif defined(TQ_WS_MAC) - ColorTable *clut; - TQPixmap *alphapm; -#endif - Optimization optim; -#if defined(TQ_WS_WIN) - HBITMAP old_hbm; -#endif - } *data; -private: -#ifndef TQT_NO_IMAGEIO - bool doImageIO( TQImageIO* io, int quality ) const; -#endif - TQPixmap( int w, int h, int depth, bool, Optimization ); - void init( int, int, int, bool, Optimization ); - void deref(); - TQPixmap copy( bool ignoreMask = FALSE ) const; -#if defined(TQ_WS_WIN) - void initAlphaPixmap( uchar *bytes, int length, struct tagBITMAPINFO *bmi ); - void convertToAlphaPixmap( bool initAlpha=TRUE ); - static void bitBltAlphaPixmap( TQPixmap *dst, int dx, int dy, - const TQPixmap *src, int sx, int sy, - int sw, int sh, bool useDstAlpha ); -#endif - static Optimization defOptim; - friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int, - const TQPaintDevice *, - int, int, int, int, RasterOp, bool ); - friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int, - const TQImage* src, - int, int, int, int, int conversion_flags ); - friend TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy, - const TQPixmap *src, int sx, int sy, - int sw, int sh ); - -#if defined(TQ_WS_MAC) - friend void unclippedScaledBitBlt(TQPaintDevice *, int, int, int, int, - const TQPaintDevice *, int, int, int, int, - TQt::RasterOp, bool, bool); -#endif - - friend class TQBitmap; - friend class TQPaintDevice; - friend class TQPainter; - friend class TQGLWidget; -}; - - -inline bool TQPixmap::isNull() const -{ - return data->w == 0; -} - -inline void TQPixmap::fill( const TQWidget *w, const TQPoint &ofs ) -{ - fill( w, ofs.x(), ofs.y() ); -} - -inline void TQPixmap::resize( const TQSize &s ) -{ - resize( s.width(), s.height() ); -} - -inline const TQBitmap *TQPixmap::mask() const -{ - return data->mask; -} - -inline bool TQPixmap::selfMask() const -{ - return data->selfmask; -} - -#if defined(TQ_WS_WIN) -inline HBITMAP TQPixmap::hbm() const -{ - return data->mcp ? 0 : data->hbm_or_mcpi.hbm; -} -#endif - -inline int TQPixmap::serialNumber() const -{ - return data->ser_no; -} - -inline TQPixmap::Optimization TQPixmap::optimization() const -{ - return data->optim; -} - -inline bool TQPixmap::isTQBitmap() const -{ - return data->bitmap; -} - -#if defined(TQ_WS_WIN) -inline bool TQPixmap::isMultiCellPixmap() const -{ - return data->mcp; -} -#endif - - -/***************************************************************************** - TQPixmap stream functions - *****************************************************************************/ - -#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO) -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPixmap & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPixmap & ); -#endif - -/***************************************************************************** - TQPixmap (and TQImage) helper functions - *****************************************************************************/ - -#ifndef TQT_NO_PIXMAP_TRANSFORMATION -# define QT_XFORM_TYPE_MSBFIRST 0 -# define QT_XFORM_TYPE_LSBFIRST 1 -# if defined(TQ_WS_WIN) -# define QT_XFORM_TYPE_WINDOWSPIXMAP 2 -# endif -bool qt_xForm_helper( const TQWMatrix&, int, int, int, uchar*, int, int, int, uchar*, int, int, int ); -#endif - -TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy, - const TQPixmap *src, int sx = 0, int sy = 0, - int sw = -1, int sh = -1 ); - -#endif // TQPIXMAP_H diff --git a/src/kernel/ntqpixmapcache.h b/src/kernel/ntqpixmapcache.h deleted file mode 100644 index 2f2d1372d..000000000 --- a/src/kernel/ntqpixmapcache.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Definition of TQPixmapCache class -** -** Created : 950501 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPIXMAPCACHE_H -#define TQPIXMAPCACHE_H - -#ifndef QT_H -#include "ntqpixmap.h" -#endif // QT_H - - -class TQ_EXPORT TQPixmapCache // global pixmap cache -{ -public: - static int cacheLimit(); - static void setCacheLimit( int ); - static TQPixmap *find( const TQString &key ); - static bool find( const TQString &key, TQPixmap& ); - static bool insert( const TQString &key, TQPixmap * ); - static bool insert( const TQString &key, const TQPixmap& ); - static void remove( const TQString &key ); - static void clear(); -}; - - -#endif // TQPIXMAPCACHE_H diff --git a/src/kernel/ntqpngio.h b/src/kernel/ntqpngio.h deleted file mode 100644 index 42c85c653..000000000 --- a/src/kernel/ntqpngio.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Definition of PNG TQImage IOHandler -** -** Created : 970521 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPNGIO_H -#define TQPNGIO_H - -#ifndef QT_H -#include "tqimage.h" -#endif // QT_H - -#ifndef TQT_NO_IMAGEIO_PNG - -void qInitPngIO(); - -class TQIODevice; - -#ifndef Q_PNGEXPORT -#if !defined(QT_PLUGIN) -#define Q_PNGEXPORT TQ_EXPORT -#else -#define Q_PNGEXPORT -#endif -#endif - -class Q_PNGEXPORT TQPNGImageWriter { -public: - TQPNGImageWriter(TQIODevice*); - ~TQPNGImageWriter(); - - enum DisposalMethod { Unspecified, NoDisposal, RestoreBackground, RestoreImage }; - void setDisposalMethod(DisposalMethod); - void setLooping(int loops=0); // 0 == infinity - void setFrameDelay(int msecs); - void setGamma(float); - - bool writeImage(const TQImage& img, int x, int y); - bool writeImage(const TQImage& img, int quality, int x, int y); - bool writeImage(const TQImage& img) - { return writeImage(img, 0, 0); } - bool writeImage(const TQImage& img, int quality) - { return writeImage(img, quality, 0, 0); } - - TQIODevice* device() { return dev; } - -private: - TQIODevice* dev; - int frames_written; - DisposalMethod disposal; - int looping; - int ms_delay; - float gamma; -}; - -class Q_PNGEXPORT TQPNGImagePacker : public TQPNGImageWriter { -public: - TQPNGImagePacker(TQIODevice*, int depth, int convflags); - - void setPixelAlignment(int x); - bool packImage(const TQImage& img); - -private: - TQImage previous; - int depth; - int convflags; - int alignx; -}; - -#endif // TQT_NO_IMAGEIO_PNG - -#endif // TQPNGIO_H diff --git a/src/kernel/ntqpoint.h b/src/kernel/ntqpoint.h deleted file mode 100644 index c38e379b2..000000000 --- a/src/kernel/ntqpoint.h +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Definition of TQPoint class -** -** Created : 931028 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPOINT_H -#define TQPOINT_H - -#ifndef QT_H -#include "ntqwindowdefs.h" -#endif // QT_H - - -class TQ_EXPORT TQPoint -{ -public: - TQPoint(); - TQPoint( int xpos, int ypos ); - - bool isNull() const; - - int x() const; - int y() const; - void setX( int x ); - void setY( int y ); - - int manhattanLength() const; - - TQCOORD &rx(); - TQCOORD &ry(); - - TQPoint &operator+=( const TQPoint &p ); - TQPoint &operator-=( const TQPoint &p ); - TQPoint &operator*=( int c ); - TQPoint &operator*=( double c ); - TQPoint &operator/=( int c ); - TQPoint &operator/=( double c ); - - friend inline bool operator==( const TQPoint &, const TQPoint & ); - friend inline bool operator!=( const TQPoint &, const TQPoint & ); - friend inline const TQPoint operator+( const TQPoint &, const TQPoint & ); - friend inline const TQPoint operator-( const TQPoint &, const TQPoint & ); - friend inline const TQPoint operator*( const TQPoint &, int ); - friend inline const TQPoint operator*( int, const TQPoint & ); - friend inline const TQPoint operator*( const TQPoint &, double ); - friend inline const TQPoint operator*( double, const TQPoint & ); - friend inline const TQPoint operator-( const TQPoint & ); - friend inline const TQPoint operator/( const TQPoint &, int ); - friend inline const TQPoint operator/( const TQPoint &, double ); - -private: - static void warningDivByZero(); - -#if defined(Q_OS_MAC) - TQCOORD yp; - TQCOORD xp; -#else - TQCOORD xp; - TQCOORD yp; -#endif -}; - - -/***************************************************************************** - TQPoint stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPoint & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPoint & ); -#endif - -/***************************************************************************** - TQPoint inline functions - *****************************************************************************/ - -inline TQPoint::TQPoint() -{ xp=0; yp=0; } - -inline TQPoint::TQPoint( int xpos, int ypos ) -{ xp=(TQCOORD)xpos; yp=(TQCOORD)ypos; } - -inline bool TQPoint::isNull() const -{ return xp == 0 && yp == 0; } - -inline int TQPoint::x() const -{ return xp; } - -inline int TQPoint::y() const -{ return yp; } - -inline void TQPoint::setX( int x ) -{ xp = (TQCOORD)x; } - -inline void TQPoint::setY( int y ) -{ yp = (TQCOORD)y; } - -inline TQCOORD &TQPoint::rx() -{ return xp; } - -inline TQCOORD &TQPoint::ry() -{ return yp; } - -inline TQPoint &TQPoint::operator+=( const TQPoint &p ) -{ xp+=p.xp; yp+=p.yp; return *this; } - -inline TQPoint &TQPoint::operator-=( const TQPoint &p ) -{ xp-=p.xp; yp-=p.yp; return *this; } - -inline TQPoint &TQPoint::operator*=( int c ) -{ xp*=(TQCOORD)c; yp*=(TQCOORD)c; return *this; } - -inline TQPoint &TQPoint::operator*=( double c ) -{ xp=(TQCOORD)(xp*c); yp=(TQCOORD)(yp*c); return *this; } - -inline bool operator==( const TQPoint &p1, const TQPoint &p2 ) -{ return p1.xp == p2.xp && p1.yp == p2.yp; } - -inline bool operator!=( const TQPoint &p1, const TQPoint &p2 ) -{ return p1.xp != p2.xp || p1.yp != p2.yp; } - -inline const TQPoint operator+( const TQPoint &p1, const TQPoint &p2 ) -{ return TQPoint(p1.xp+p2.xp, p1.yp+p2.yp); } - -inline const TQPoint operator-( const TQPoint &p1, const TQPoint &p2 ) -{ return TQPoint(p1.xp-p2.xp, p1.yp-p2.yp); } - -inline const TQPoint operator*( const TQPoint &p, int c ) -{ return TQPoint(p.xp*c, p.yp*c); } - -inline const TQPoint operator*( int c, const TQPoint &p ) -{ return TQPoint(p.xp*c, p.yp*c); } - -inline const TQPoint operator*( const TQPoint &p, double c ) -{ return TQPoint((TQCOORD)(p.xp*c), (TQCOORD)(p.yp*c)); } - -inline const TQPoint operator*( double c, const TQPoint &p ) -{ return TQPoint((TQCOORD)(p.xp*c), (TQCOORD)(p.yp*c)); } - -inline const TQPoint operator-( const TQPoint &p ) -{ return TQPoint(-p.xp, -p.yp); } - -inline TQPoint &TQPoint::operator/=( int c ) -{ -#if defined(QT_CHECK_MATH) - if ( c == 0 ) - warningDivByZero(); -#endif - xp/=(TQCOORD)c; - yp/=(TQCOORD)c; - return *this; -} - -inline TQPoint &TQPoint::operator/=( double c ) -{ -#if defined(QT_CHECK_MATH) - if ( c == 0.0 ) - warningDivByZero(); -#endif - xp=(TQCOORD)(xp/c); - yp=(TQCOORD)(yp/c); - return *this; -} - -inline const TQPoint operator/( const TQPoint &p, int c ) -{ -#if defined(QT_CHECK_MATH) - if ( c == 0 ) - TQPoint::warningDivByZero(); -#endif - return TQPoint(p.xp/c, p.yp/c); -} - -inline const TQPoint operator/( const TQPoint &p, double c ) -{ -#if defined(QT_CHECK_MATH) - if ( c == 0.0 ) - TQPoint::warningDivByZero(); -#endif - return TQPoint((TQCOORD)(p.xp/c), (TQCOORD)(p.yp/c)); -} - -#define Q_DEFINED_QPOINT -#include "ntqwinexport.h" -#endif // TQPOINT_H diff --git a/src/kernel/ntqpointarray.h b/src/kernel/ntqpointarray.h deleted file mode 100644 index 515935ac7..000000000 --- a/src/kernel/ntqpointarray.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Definition of TQPointArray class -** -** Created : 940213 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPOINTARRAY_H -#define TQPOINTARRAY_H - -#ifndef QT_H -#include "tqmemarray.h" -#include "ntqpoint.h" -#endif // QT_H - - -#if defined(Q_TEMPLATEDLL) -//Q_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray; -#endif - -class TQ_EXPORT TQPointArray : public TQMemArray -{ -public: - TQPointArray() {} - ~TQPointArray() {} - TQPointArray( int size ) : TQMemArray( size ) {} - TQPointArray( const TQPointArray &a ) : TQMemArray( a ) {} - TQPointArray( const TQRect &r, bool closed=FALSE ); - TQPointArray( int nPoints, const TQCOORD *points ); - - TQPointArray &operator=( const TQPointArray &a ) - { return (TQPointArray&)assign( a ); } - - TQPointArray copy() const - { TQPointArray tmp; return *((TQPointArray*)&tmp.duplicate(*this)); } - - void translate( int dx, int dy ); - TQRect boundingRect() const; - - void point( uint i, int *x, int *y ) const; - TQPoint point( uint i ) const; - void setPoint( uint i, int x, int y ); - void setPoint( uint i, const TQPoint &p ); - bool setPoints( int nPoints, const TQCOORD *points ); - bool setPoints( int nPoints, int firstx, int firsty, ... ); - bool putPoints( int index, int nPoints, const TQCOORD *points ); - bool putPoints( int index, int nPoints, int firstx, int firsty, ... ); - bool putPoints( int index, int nPoints, - const TQPointArray & from, int fromIndex=0 ); - - void makeArc( int x, int y, int w, int h, int a1, int a2 ); - void makeEllipse( int x, int y, int w, int h ); - void makeArc( int x, int y, int w, int h, int a1, int a2, - const TQWMatrix& ); -#ifndef TQT_NO_BEZIER - TQPointArray cubicBezier() const; -#endif - void* shortPoints( int index = 0, int nPoints = -1 ) const; - static void cleanBuffers(); - -protected: - static uint splen; - static void* sp; -}; - - -/***************************************************************************** - TQPointArray stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPointArray & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPointArray & ); -#endif - -/***************************************************************************** - Misc. TQPointArray functions - *****************************************************************************/ - -inline void TQPointArray::setPoint( uint i, const TQPoint &p ) -{ - setPoint( i, p.x(), p.y() ); -} - - -#endif // TQPOINTARRAY_H diff --git a/src/kernel/ntqprinter.h b/src/kernel/ntqprinter.h deleted file mode 100644 index de561901a..000000000 --- a/src/kernel/ntqprinter.h +++ /dev/null @@ -1,284 +0,0 @@ -/********************************************************************** -** -** Definition of TQPrinter class -** -** Created : 940927 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPRINTER_H -#define TQPRINTER_H - -#ifndef QT_H -#include "tqpaintdevice.h" -#include "tqstring.h" -#include "tqstringlist.h" -#endif // QT_H - -#ifndef TQT_NO_PRINTER - -#if defined(B0) -#undef B0 // Terminal hang-up. We assume that you do not want that. -#endif - -class TQPrinterPrivate; - -class TQ_EXPORT TQPrinter : public TQPaintDevice -{ -public: - enum PrinterMode { ScreenResolution, PrinterResolution, HighResolution, Compatible }; - - TQPrinter( PrinterMode mode = ScreenResolution ); - ~TQPrinter(); - - enum Orientation { Portrait, Landscape }; - - enum PageSize { A4, B5, Letter, Legal, Executive, - A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1, - B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E, - DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom }; - - enum PageOrder { FirstPageFirst, LastPageFirst }; - - enum ColorMode { GrayScale, Color }; - - enum PaperSource { OnlyOne, Lower, Middle, Manual, Envelope, - EnvelopeManual, Auto, Tractor, SmallFormat, - LargeFormat, LargeCapacity, Cassette, FormSource }; - - enum PrintRange { AllPages, - Selection, - PageRange }; - - enum PrinterOption { PrintToFile, - PrintSelection, - PrintPageRange }; - - TQString printerName() const; - virtual void setPrinterName( const TQString &); - bool outputToFile() const; - virtual void setOutputToFile( bool ); - TQString outputFileName()const; - virtual void setOutputFileName( const TQString &); - - TQString printProgram() const; - virtual void setPrintProgram( const TQString &); - - TQString printerSelectionOption() const; - virtual void setPrinterSelectionOption( const TQString & ); - - TQString docName() const; - virtual void setDocName( const TQString &); - TQString creator() const; - virtual void setCreator( const TQString &); - - Orientation orientation() const; - virtual void setOrientation( Orientation ); - PageSize pageSize() const; - virtual void setPageSize( PageSize ); -#ifdef TQ_WS_WIN - void setWinPageSize( short winPageSize ); - short winPageSize() const; -#endif -#ifdef TQ_WS_MAC - bool printSetup(); - bool pageSetup(); -#endif - virtual void setPageOrder( PageOrder ); - PageOrder pageOrder() const; - - void setResolution( int ); - int resolution() const; - - virtual void setColorMode( ColorMode ); - ColorMode colorMode() const; - - virtual void setFullPage( bool ); - bool fullPage() const; - TQSize margins() const; - void setMargins( uint top, uint left, uint bottom, uint right ); - void margins( uint *top, uint *left, uint *bottom, uint *right ) const; - - int fromPage() const; - int toPage() const; - virtual void setFromTo( int fromPage, int toPage ); - int minPage() const; - int maxPage() const; - virtual void setMinMax( int minPage, int maxPage ); - int numCopies() const; - virtual void setNumCopies( int ); - - bool collateCopiesEnabled() const; - void setCollateCopiesEnabled(bool ); - - bool collateCopies() const; - void setCollateCopies( bool ); - - PrintRange printRange() const; - void setPrintRange( PrintRange range ); - - bool newPage(); - bool abort(); - bool aborted() const; - - bool setup( TQWidget *parent = 0 ); - - PaperSource paperSource() const; - virtual void setPaperSource( PaperSource ); - - void setOptionEnabled( PrinterOption, bool enable ); - bool isOptionEnabled( PrinterOption ); - -protected: - bool cmd( int, TQPainter *, TQPDevCmdParam * ); - int metric( int ) const; - -#if defined(TQ_WS_WIN) - virtual void setActive(); - virtual void setIdle(); -#endif - -private: -#if defined(TQ_WS_X11) - TQPaintDevice *pdrv; - int pid; -#endif -#if defined(TQ_WS_MAC) - friend class TQPrinterPrivate; - PMPageFormat pformat; - PMPrintSettings psettings; - PMPrintSession psession; - bool prepare(PMPrintSettings *); - bool prepare(PMPageFormat *); - void interpret(PMPrintSettings *); - void interpret(PMPageFormat *); -#endif -#if defined(TQ_WS_WIN) - void readPdlg( void* ); - void readPdlgA( void* ); - void writeDevmode( TQt::HANDLE ); - void writeDevmodeA( TQt::HANDLE ); - void reinit(); - - bool viewOffsetDone; - TQPainter* painter; - TQt::HANDLE hdevmode; - TQt::HANDLE hdevnames; -#endif - - int state; - TQString printer_name; - TQString option_string; - TQString output_filename; - bool output_file; - TQString print_prog; - TQString doc_name; - TQString creator_name; - - PageSize page_size; - PaperSource paper_source; - PageOrder page_order; - ColorMode color_mode; - Orientation orient; - uint to_edge : 1; - uint appcolcopies : 1; - uint usercolcopies : 1; - uint res_set : 1; - short from_pg, to_pg; - short min_pg, max_pg; - short ncopies; - int res; - TQPrinterPrivate *d; - -private: // Disabled copy constructor and operator= -#if defined(TQ_DISABLE_COPY) - TQPrinter( const TQPrinter & ); - TQPrinter &operator=( const TQPrinter & ); -#endif -}; - - -inline TQString TQPrinter::printerName() const -{ return printer_name; } - -inline bool TQPrinter::outputToFile() const -{ return output_file; } - -inline TQString TQPrinter::outputFileName() const -{ return output_filename; } - -inline TQString TQPrinter::printProgram() const -{ return print_prog; } - -inline TQString TQPrinter::docName() const -{ return doc_name; } - -inline TQString TQPrinter::creator() const -{ return creator_name; } - -inline TQPrinter::PageSize TQPrinter::pageSize() const -{ return page_size; } - -inline TQPrinter::Orientation TQPrinter::orientation() const -{ return orient; } - -inline int TQPrinter::fromPage() const -{ return from_pg; } - -inline int TQPrinter::toPage() const -{ return to_pg; } - -inline int TQPrinter::minPage() const -{ return min_pg; } - -inline int TQPrinter::maxPage() const -{ return max_pg; } - -inline int TQPrinter::numCopies() const -{ return ncopies; } - -inline bool TQPrinter::collateCopiesEnabled() const -{ return appcolcopies; } - -inline void TQPrinter::setCollateCopiesEnabled(bool v) -{ appcolcopies = v; } - -inline bool TQPrinter::collateCopies() const -{ return usercolcopies; } - - -#endif // TQT_NO_PRINTER - -#endif // TQPRINTER_H diff --git a/src/kernel/ntqrect.h b/src/kernel/ntqrect.h deleted file mode 100644 index d7dd2886b..000000000 --- a/src/kernel/ntqrect.h +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************** -** -** Definition of TQRect class -** -** Created : 931028 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQRECT_H -#define TQRECT_H - -#ifndef QT_H -#include "tqsize.h" -#endif // QT_H - -#if defined(topLeft) -#error "Macro definition of topLeft conflicts with TQRect" -// don't just silently undo people's defines: #undef topLeft -#endif - -class TQ_EXPORT TQRect // rectangle class -{ -public: - TQRect() { x1 = y1 = 0; x2 = y2 = -1; } - TQRect( const TQPoint &topleft, const TQPoint &bottomright ); - TQRect( const TQPoint &topleft, const TQSize &size ); - TQRect( int left, int top, int width, int height ); - - bool isNull() const; - bool isEmpty() const; - bool isValid() const; - TQRect normalize() const; - - int left() const; - int top() const; - int right() const; - int bottom() const; - - TQCOORD &rLeft(); - TQCOORD &rTop(); - TQCOORD &rRight(); - TQCOORD &rBottom(); - - int x() const; - int y() const; - void setLeft( int pos ); - void setTop( int pos ); - void setRight( int pos ); - void setBottom( int pos ); - void setX( int x ); - void setY( int y ); - - void setTopLeft( const TQPoint &p ); - void setBottomRight( const TQPoint &p ); - void setTopRight( const TQPoint &p ); - void setBottomLeft( const TQPoint &p ); - - TQPoint topLeft() const; - TQPoint bottomRight() const; - TQPoint topRight() const; - TQPoint bottomLeft() const; - TQPoint center() const; - - void rect( int *x, int *y, int *w, int *h ) const; - void coords( int *x1, int *y1, int *x2, int *y2 ) const; - - void moveLeft( int pos ); - void moveTop( int pos ); - void moveRight( int pos ); - void moveBottom( int pos ); - void moveTopLeft( const TQPoint &p ); - void moveBottomRight( const TQPoint &p ); - void moveTopRight( const TQPoint &p ); - void moveBottomLeft( const TQPoint &p ); - void moveCenter( const TQPoint &p ); - void moveBy( int dx, int dy ); - - void setRect( int x, int y, int w, int h ); - void setCoords( int x1, int y1, int x2, int y2 ); - void addCoords( int x1, int y1, int x2, int y2 ); - - TQSize size() const; - int width() const; - int height() const; - void setWidth( int w ); - void setHeight( int h ); - void setSize( const TQSize &s ); - - TQRect operator|(const TQRect &r) const; - TQRect operator&(const TQRect &r) const; - TQRect& operator|=(const TQRect &r); - TQRect& operator&=(const TQRect &r); - - bool contains( const TQPoint &p, bool proper=FALSE ) const; - bool contains( int x, int y ) const; // inline methods, _don't_ merge these - bool contains( int x, int y, bool proper ) const; - bool contains( const TQRect &r, bool proper=FALSE ) const; - TQRect unite( const TQRect &r ) const; - TQRect intersect( const TQRect &r ) const; - bool intersects( const TQRect &r ) const; - - friend TQ_EXPORT bool operator==( const TQRect &, const TQRect & ); - friend TQ_EXPORT bool operator!=( const TQRect &, const TQRect & ); - -private: -#if defined(TQ_WS_X11) || defined(Q_OS_TEMP) - friend void qt_setCoords( TQRect *r, int xp1, int yp1, int xp2, int yp2 ); -#endif -#if defined(Q_OS_MAC) - TQCOORD y1; - TQCOORD x1; - TQCOORD y2; - TQCOORD x2; -#else - TQCOORD x1; - TQCOORD y1; - TQCOORD x2; - TQCOORD y2; -#endif -}; - -TQ_EXPORT bool operator==( const TQRect &, const TQRect & ); -TQ_EXPORT bool operator!=( const TQRect &, const TQRect & ); - - -/***************************************************************************** - TQRect stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRect & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRect & ); -#endif - -/***************************************************************************** - TQRect inline member functions - *****************************************************************************/ - -inline TQRect::TQRect( int left, int top, int width, int height ) -{ - x1 = (TQCOORD)left; - y1 = (TQCOORD)top; - x2 = (TQCOORD)(left+width-1); - y2 = (TQCOORD)(top+height-1); -} - -inline bool TQRect::isNull() const -{ return x2 == x1-1 && y2 == y1-1; } - -inline bool TQRect::isEmpty() const -{ return x1 > x2 || y1 > y2; } - -inline bool TQRect::isValid() const -{ return x1 <= x2 && y1 <= y2; } - -inline int TQRect::left() const -{ return x1; } - -inline int TQRect::top() const -{ return y1; } - -inline int TQRect::right() const -{ return x2; } - -inline int TQRect::bottom() const -{ return y2; } - -inline TQCOORD &TQRect::rLeft() -{ return x1; } - -inline TQCOORD & TQRect::rTop() -{ return y1; } - -inline TQCOORD & TQRect::rRight() -{ return x2; } - -inline TQCOORD & TQRect::rBottom() -{ return y2; } - -inline int TQRect::x() const -{ return x1; } - -inline int TQRect::y() const -{ return y1; } - -inline void TQRect::setLeft( int pos ) -{ x1 = (TQCOORD)pos; } - -inline void TQRect::setTop( int pos ) -{ y1 = (TQCOORD)pos; } - -inline void TQRect::setRight( int pos ) -{ x2 = (TQCOORD)pos; } - -inline void TQRect::setBottom( int pos ) -{ y2 = (TQCOORD)pos; } - -inline void TQRect::setX( int x ) -{ x1 = (TQCOORD)x; } - -inline void TQRect::setY( int y ) -{ y1 = (TQCOORD)y; } - -inline TQPoint TQRect::topLeft() const -{ return TQPoint(x1, y1); } - -inline TQPoint TQRect::bottomRight() const -{ return TQPoint(x2, y2); } - -inline TQPoint TQRect::topRight() const -{ return TQPoint(x2, y1); } - -inline TQPoint TQRect::bottomLeft() const -{ return TQPoint(x1, y2); } - -inline TQPoint TQRect::center() const -{ return TQPoint((x1+x2)/2, (y1+y2)/2); } - -inline int TQRect::width() const -{ return x2 - x1 + 1; } - -inline int TQRect::height() const -{ return y2 - y1 + 1; } - -inline TQSize TQRect::size() const -{ return TQSize(x2-x1+1, y2-y1+1); } - -inline bool TQRect::contains( int x, int y, bool proper ) const -{ - if ( proper ) - return x > x1 && x < x2 && - y > y1 && y < y2; - else - return x >= x1 && x <= x2 && - y >= y1 && y <= y2; -} - -inline bool TQRect::contains( int x, int y ) const -{ - return x >= x1 && x <= x2 && - y >= y1 && y <= y2; -} -#define Q_DEFINED_QRECT -#include "ntqwinexport.h" -#endif // TQRECT_H diff --git a/src/kernel/ntqregion.h b/src/kernel/ntqregion.h deleted file mode 100644 index 8ab8966af..000000000 --- a/src/kernel/ntqregion.h +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** Definition of TQRegion class -** -** Created : 940514 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQREGION_H -#define TQREGION_H - -#ifndef QT_H -#include "ntqshared.h" -#include "ntqrect.h" -#endif // QT_H - -#ifdef TQ_WS_X11 -struct TQRegionPrivate; -#endif - -class TQ_EXPORT TQRegion -{ -public: - enum RegionType { Rectangle, Ellipse }; - - TQRegion(); - TQRegion( int x, int y, int w, int h, RegionType = Rectangle ); - TQRegion( const TQRect &, RegionType = Rectangle ); - TQRegion( const TQPointArray &, bool winding=FALSE ); - TQRegion( const TQRegion & ); - TQRegion( const TQBitmap & ); - ~TQRegion(); - TQRegion &operator=( const TQRegion & ); - - bool isNull() const; - bool isEmpty() const; - - bool contains( const TQPoint &p ) const; - bool contains( const TQRect &r ) const; - - void translate( int dx, int dy ); - - TQRegion unite( const TQRegion & ) const; - TQRegion intersect( const TQRegion &) const; - TQRegion subtract( const TQRegion & ) const; - TQRegion eor( const TQRegion & ) const; - - TQRect boundingRect() const; - TQMemArray rects() const; - void setRects( const TQRect *, int ); - - const TQRegion operator|( const TQRegion & ) const; - const TQRegion operator+( const TQRegion & ) const; - const TQRegion operator&( const TQRegion & ) const; - const TQRegion operator-( const TQRegion & ) const; - const TQRegion operator^( const TQRegion & ) const; - TQRegion& operator|=( const TQRegion & ); - TQRegion& operator+=( const TQRegion & ); - TQRegion& operator&=( const TQRegion & ); - TQRegion& operator-=( const TQRegion & ); - TQRegion& operator^=( const TQRegion & ); - - bool operator==( const TQRegion & ) const; - bool operator!=( const TQRegion &r ) const - { return !(operator==(r)); } - -#if defined(TQ_WS_WIN) - HRGN handle() const { return data->rgn; } -#elif defined(TQ_WS_X11) - Region handle() const { if(!data->rgn) updateX11Region(); return data->rgn; } -#elif defined(TQ_WS_MAC) - RgnHandle handle(bool require_rgn=FALSE) const; -#endif - -#ifndef TQT_NO_DATASTREAM - friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRegion & ); - friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRegion & ); -#endif -private: - TQRegion( bool ); - TQRegion copy() const; - void detach(); -#if defined(TQ_WS_WIN) - TQRegion winCombine( const TQRegion &, int ) const; -#endif -#if defined(TQ_WS_X11) - void updateX11Region() const; - void *clipRectangles( int &num ) const; - friend void *qt_getClipRects( const TQRegion &, int & ); -#endif - void exec( const TQByteArray &, int ver = 0 ); - struct TQRegionData : public TQShared { -#if defined(TQ_WS_WIN) - HRGN rgn; -#elif defined(TQ_WS_X11) - Region rgn; - void *xrectangles; - TQRegionPrivate *region; -#elif defined(TQ_WS_MAC) - uint is_rect:1; - TQRect rect; - RgnHandle rgn; -#endif - bool is_null; - } *data; -#if defined(TQ_WS_MAC) - friend struct qt_mac_rgn_data_cache; - friend TQRegionData *qt_mac_get_rgn_data(); - friend void qt_mac_free_rgn_data(TQRegionData *); - void rectifyRegion(); -#elif defined(TQ_WS_WIN) - friend class TQETWidget; -#endif - -}; - - -#define TQRGN_SETRECT 1 // region stream commands -#define TQRGN_SETELLIPSE 2 // (these are internal) -#define TQRGN_SETPTARRAY_ALT 3 -#define TQRGN_SETPTARRAY_WIND 4 -#define TQRGN_TRANSLATE 5 -#define TQRGN_OR 6 -#define TQRGN_AND 7 -#define TQRGN_SUB 8 -#define TQRGN_XOR 9 -#define TQRGN_RECTS 10 - - -/***************************************************************************** - TQRegion stream functions - *****************************************************************************/ - -#ifndef TQT_NO_DATASTREAM -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRegion & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRegion & ); -#endif - - -#endif // TQREGION_H diff --git a/src/kernel/ntqsimplerichtext.h b/src/kernel/ntqsimplerichtext.h index 0f19a3971..8d3d9ad8b 100644 --- a/src/kernel/ntqsimplerichtext.h +++ b/src/kernel/ntqsimplerichtext.h @@ -44,7 +44,7 @@ #ifndef QT_H #include "ntqnamespace.h" #include "tqstring.h" -#include "ntqregion.h" +#include "tqregion.h" #endif // QT_H #ifndef TQT_NO_RICHTEXT diff --git a/src/kernel/ntqt.h b/src/kernel/ntqt.h index ae3c2820d..51eb62b33 100644 --- a/src/kernel/ntqt.h +++ b/src/kernel/ntqt.h @@ -34,16 +34,16 @@ #include "tqfont.h" #include "tqdatastream.h" #include "tqpair.h" -#include "ntqpoint.h" +#include "tqpoint.h" #include #include "tqtextstream.h" #include "tqfontinfo.h" #include "tqsizepolicy.h" #include "ntqtl.h" #include "tqsize.h" -#include "ntqrect.h" +#include "tqrect.h" #include "tqbitarray.h" -#include "ntqregion.h" +#include "tqregion.h" #include "tqsql.h" #include "tqstrlist.h" #include "tqvaluelist.h" @@ -62,11 +62,11 @@ #include "tqobject.h" #include #include "tqbrush.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "tqwidget.h" #include "tqjpunicode.h" #include "tqtextcodec.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include #include "tqiconset.h" #include "ntqbutton.h" @@ -88,7 +88,7 @@ #include #include "ntqgcache.h" #include -#include +#include #include #include #include "ntqgplugin.h" @@ -111,7 +111,7 @@ #include #include "tqintdict.h" #include "ntqmotifstyle.h" -#include "ntqpicture.h" +#include "tqpicture.h" #include #include #include @@ -146,21 +146,21 @@ #include #include #include -#include "ntqpointarray.h" +#include "tqpointarray.h" #include "tqmenudata.h" #include -#include "ntqpen.h" +#include "tqpen.h" #include "tqdragobject.h" #include -#include +#include #include -#include +#include #include #include #include #include "tqpopupmenu.h" #include -#include +#include #include #include "ntqprogressbar.h" #include @@ -189,7 +189,7 @@ #include #include #include -#include "ntqwmatrix.h" +#include "tqwmatrix.h" #include #include #include diff --git a/src/kernel/ntqwmatrix.h b/src/kernel/ntqwmatrix.h deleted file mode 100644 index 1a7153b79..000000000 --- a/src/kernel/ntqwmatrix.h +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Definition of TQWMatrix class -** -** Created : 941020 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQWMATRIX_H -#define TQWMATRIX_H - -#ifndef QT_H -#include "ntqwindowdefs.h" -#include "ntqpointarray.h" -#include "ntqrect.h" -#include "ntqregion.h" -#endif // QT_H - -#ifndef TQT_NO_WMATRIX - - -class TQ_EXPORT TQWMatrix // 2D transform matrix -{ -public: - TQWMatrix(); - TQWMatrix( double m11, double m12, double m21, double m22, - double dx, double dy ); - - void setMatrix( double m11, double m12, double m21, double m22, - double dx, double dy ); - - double m11() const { return _m11; } - double m12() const { return _m12; } - double m21() const { return _m21; } - double m22() const { return _m22; } - double dx() const { return _dx; } - double dy() const { return _dy; } - - void map( int x, int y, int *tx, int *ty ) const; - void map( double x, double y, double *tx, double *ty ) const; - TQRect mapRect( const TQRect & ) const; - - TQPoint map( const TQPoint &p ) const { return operator *( p ); } - TQRect map( const TQRect &r ) const { return mapRect ( r ); } - TQPointArray map( const TQPointArray &a ) const { return operator * ( a ); } - TQRegion map( const TQRegion &r ) const { return operator *( r ); } - TQRegion mapToRegion( const TQRect &r ) const { return operator *( r ); } - TQPointArray mapToPolygon( const TQRect &r ) const; - - void reset(); - bool isIdentity() const; - - TQWMatrix &translate( double dx, double dy ); - TQWMatrix &scale( double sx, double sy ); - TQWMatrix &shear( double sh, double sv ); - TQWMatrix &rotate( double a ); - - bool isInvertible() const { return (_m11*_m22 - _m12*_m21) != 0; } - double det() const { return _m11*_m22 - _m12*_m21; } - - TQWMatrix invert( bool * = 0 ) const; - - bool operator==( const TQWMatrix & ) const; - bool operator!=( const TQWMatrix & ) const; - TQWMatrix &operator*=( const TQWMatrix & ); - - /* we use matrix multiplication semantics here */ - TQPoint operator * (const TQPoint & ) const; - TQRegion operator * (const TQRect & ) const; - TQRegion operator * (const TQRegion & ) const; - TQPointArray operator * ( const TQPointArray &a ) const; - - enum TransformationMode { - Points, Areas - }; - static void setTransformationMode( TQWMatrix::TransformationMode m ); - static TransformationMode transformationMode(); -private: - double _m11, _m12; - double _m21, _m22; - double _dx, _dy; -}; - -TQ_EXPORT TQWMatrix operator*( const TQWMatrix &, const TQWMatrix & ); - - -/***************************************************************************** - TQWMatrix stream functions - *****************************************************************************/ - -TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQWMatrix & ); -TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQWMatrix & ); - - -#endif // TQT_NO_WMATRIX - -#endif // TQWMATRIX_H diff --git a/src/kernel/qapplication_x11.cpp b/src/kernel/qapplication_x11.cpp index 3c6e43185..fbe329e98 100644 --- a/src/kernel/qapplication_x11.cpp +++ b/src/kernel/qapplication_x11.cpp @@ -72,7 +72,7 @@ #include "tqwidgetintdict.h" #include "tqbitarray.h" #include "tqpainter.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "tqdatetime.h" #include "tqtextcodec.h" #include "tqdatastream.h" diff --git a/src/kernel/qdrawutil.cpp b/src/kernel/qdrawutil.cpp index 7e571418f..8abb9216f 100644 --- a/src/kernel/qdrawutil.cpp +++ b/src/kernel/qdrawutil.cpp @@ -41,7 +41,7 @@ #include "ntqdrawutil.h" #ifndef TQT_NO_DRAWUTIL #include "tqbitmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "ntqapplication.h" #include "tqpainter.h" diff --git a/src/kernel/qinternal.cpp b/src/kernel/qinternal.cpp index a714333d9..82afee051 100644 --- a/src/kernel/qinternal.cpp +++ b/src/kernel/qinternal.cpp @@ -40,7 +40,7 @@ #include "private/qinternal_p.h" #include "tqwidget.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqpainter.h" #include "ntqcleanuphandler.h" diff --git a/src/kernel/qinternal_p.h b/src/kernel/qinternal_p.h index 1ced79556..8992497e6 100644 --- a/src/kernel/qinternal_p.h +++ b/src/kernel/qinternal_p.h @@ -54,7 +54,7 @@ // #ifndef QT_H #include "ntqnamespace.h" -#include "ntqrect.h" +#include "tqrect.h" #include "tqptrlist.h" #include "tqcstring.h" #include "tqiodevice.h" diff --git a/src/kernel/qpalette.cpp b/src/kernel/qpalette.cpp deleted file mode 100644 index 43009fe7b..000000000 --- a/src/kernel/qpalette.cpp +++ /dev/null @@ -1,1200 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQColorGroup and TQPalette classes -** -** Created : 950323 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpalette.h" - -#ifndef TQT_NO_PALETTE -#include "tqdatastream.h" -#include "ntqcleanuphandler.h" - -/***************************************************************************** - TQColorGroup member functions - *****************************************************************************/ - -/*! - \class TQColorGroup ntqpalette.h - \brief The TQColorGroup class contains a group of widget colors. - - \ingroup appearance - \ingroup graphics - \ingroup images - - A color group contains a group of colors used by widgets for - drawing themselves. We recommend that widgets use color group - roles such as "foreground" and "base" rather than literal colors - like "red" or "turquoise". The color roles are enumerated and - defined in the \l ColorRole documentation. - - The most common use of TQColorGroup is like this: - - \code - TQPainter p; - ... - p.setPen( colorGroup().foreground() ); - p.drawLine( ... ) - \endcode - - It is also possible to modify color groups or create new color - groups from scratch. - - The color group class can be created using three different - constructors or by modifying one supplied by TQt. The default - constructor creates an all-black color group, which can then be - modified using set functions; there's also a constructor for - specifying all the color group colors. And there is also a copy - constructor. - - We strongly recommend using a system-supplied color group and - modifying that as necessary. - - You modify a color group by calling the access functions - setColor() and setBrush(), depending on whether you want a pure - color or a pixmap pattern. - - There are also corresponding color() and brush() getters, and a - commonly used convenience function to get each ColorRole: - background(), foreground(), base(), etc. - - \sa TQColor TQPalette TQWidget::colorGroup() -*/ - - -/*! - \enum TQColorGroup::ColorRole - - The ColorRole enum defines the different symbolic color roles used - in current GUIs. - - The central roles are: - - \value Background general background color. - - \value Foreground general foreground color. - - \value Base used as background color for text entry widgets, for example; - usually white or another light color. - - \value Text the foreground color used with \c Base. Usually this - is the same as the \c Foreground, in which case it must provide good - contrast with \c Background and \c Base. - - \value Button general button background color in which buttons need a - background different from \c Background, as in the Macintosh style. - - \value ButtonText a foreground color used with the \c Button color. - - There are some color roles used mostly for 3D bevel and shadow - effects: - - \value Light lighter than \c Button color. - - \value Midlight between \c Button and \c Light. - - \value Dark darker than \c Button. - - \value Mid between \c Button and \c Dark. - - \value Shadow a very dark color. - By default, the shadow color is \c TQt::black. - - All of these are normally derived from \c Background and used in - ways that depend on that relationship. For example, buttons depend - on it to make the bevels look attractive, and Motif scroll bars - depend on \c Mid to be slightly different from \c Background. - - Selected (marked) items have two roles: - - \value Highlight a color to indicate a selected item or the - current item. By default, the highlight color is \c TQt::darkBlue. - - \value HighlightedText a text color that contrasts with \c Highlight. - By default, the highlighted text color is \c TQt::white. - - Finally, there is a special role for text that needs to be - drawn where \c Text or \c Foreground would give poor contrast, - such as on pressed push buttons: - - \value BrightText a text color that is very different from \c - Foreground and contrasts well with e.g. \c Dark. - - \value Link a text color used for unvisited hyperlinks. - By default, the link color is \c TQt::blue. - - \value LinkVisited a text color used for already visited hyperlinks. - By default, the linkvisited color is \c TQt::magenta. - - \value NColorRoles Internal. - - Note that text colors can be used for things other than just - words; text colors are \e usually used for text, but it's quite - common to use the text color roles for lines, icons, etc. - - This image shows most of the color roles in use: - \img palette.png Color Roles -*/ - - -class TQColorGroupPrivate : public TQShared -{ -public: - TQBrush br[TQColorGroup::NColorRoles]; - TQColorGroupPrivate* detach() { - if ( count > 1 ) { - deref(); - TQColorGroupPrivate* d = new TQColorGroupPrivate; - for (int i=0; ibr[i] = br[i]; - return d; - } - return this; - } -}; - -/*! - Constructs a color group with all colors set to black. -*/ - -TQColorGroup::TQColorGroup() -{ - static TQColorGroupPrivate* defColorGroupData = 0; - if ( !defColorGroupData ) { - static TQSharedCleanupHandler defColorGroupCleanup; - defColorGroupData = new TQColorGroupPrivate; - defColorGroupCleanup.set( &defColorGroupData ); - } - d = defColorGroupData; - br = d->br; - d->ref(); -} - -/*! - Constructs a color group that is an independent copy of \a other. -*/ -TQColorGroup::TQColorGroup( const TQColorGroup& other ) -{ - d = other.d; - d->ref(); - br = d->br; -} - -/*! - Copies the colors of \a other to this color group. -*/ -TQColorGroup& TQColorGroup::operator =(const TQColorGroup& other) -{ - if ( d != other.d ) { - if ( d->deref() ) - delete d; - d = other.d; - br = d->br; - d->ref(); - } - return *this; -} - -static TQColor qt_mix_colors( TQColor a, TQColor b) -{ - return TQColor( (a.red() + b.red()) / 2, (a.green() + b.green()) / 2, (a.blue() + b.blue()) / 2 ); -} - - -/*! - Constructs a color group. You can pass either brushes, pixmaps or - plain colors for \a foreground, \a button, \a light, \a dark, \a - mid, \a text, \a bright_text, \a base and \a background. - - \sa TQBrush -*/ - TQColorGroup::TQColorGroup( const TQBrush &foreground, const TQBrush &button, - const TQBrush &light, const TQBrush &dark, - const TQBrush &mid, const TQBrush &text, - const TQBrush &bright_text, const TQBrush &base, - const TQBrush &background) -{ - d = new TQColorGroupPrivate; - br = d->br; - br[Foreground] = foreground; - br[Button] = button; - br[Light] = light; - br[Dark] = dark; - br[Mid] = mid; - br[Text] = text; - br[BrightText] = bright_text; - br[ButtonText] = text; - br[Base] = base; - br[Background] = background; - br[Midlight] = qt_mix_colors( br[Button].color(), br[Light].color() ); - br[Shadow] = TQt::black; - br[Highlight] = TQt::darkBlue; - br[HighlightedText] = TQt::white; - br[Link] = TQt::blue; - br[LinkVisited] = TQt::magenta; -} - - -/*!\obsolete - - Constructs a color group with the specified colors. The button - color will be set to the background color. -*/ - -TQColorGroup::TQColorGroup( const TQColor &foreground, const TQColor &background, - const TQColor &light, const TQColor &dark, - const TQColor &mid, - const TQColor &text, const TQColor &base ) -{ - d = new TQColorGroupPrivate; - br = d->br; - br[Foreground] = TQBrush(foreground); - br[Button] = TQBrush(background); - br[Light] = TQBrush(light); - br[Dark] = TQBrush(dark); - br[Mid] = TQBrush(mid); - br[Text] = TQBrush(text); - br[BrightText] = br[Light]; - br[ButtonText] = br[Text]; - br[Base] = TQBrush(base); - br[Background] = TQBrush(background); - br[Midlight] = qt_mix_colors( br[Button].color(), br[Light].color() ); - br[Shadow] = TQt::black; - br[Highlight] = TQt::darkBlue; - br[HighlightedText] = TQt::white; - br[Link] = TQt::blue; - br[LinkVisited] = TQt::magenta; -} - -/*! - Destroys the color group. -*/ - -TQColorGroup::~TQColorGroup() -{ - if ( d->deref() ) - delete d; -} - -/*! - Returns the color that has been set for color role \a r. - - \sa brush() ColorRole - */ -const TQColor &TQColorGroup::color( ColorRole r ) const -{ - return br[r].color(); -} - -/*! - Returns the brush that has been set for color role \a r. - - \sa color() setBrush() ColorRole -*/ -const TQBrush &TQColorGroup::brush( ColorRole r ) const -{ - return br[r]; -} - -/*! - Sets the brush used for color role \a r to a solid color \a c. - - \sa brush() setColor() ColorRole -*/ -void TQColorGroup::setColor( ColorRole r, const TQColor &c ) -{ - setBrush( r, TQBrush(c) ); -} - -/*! - Sets the brush used for color role \a r to \a b. - - \sa brush() setColor() ColorRole -*/ -void TQColorGroup::setBrush( ColorRole r, const TQBrush &b ) -{ - d = d->detach(); - br = d->br; - br[r] = b; -} - - -/*! - \fn const TQColor & TQColorGroup::foreground() const - - Returns the foreground color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::button() const - - Returns the button color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::light() const - - Returns the light color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor& TQColorGroup::midlight() const - - Returns the midlight color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::dark() const - - Returns the dark color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::mid() const - - Returns the mid color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::text() const - - Returns the text foreground color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::brightText() const - - Returns the bright text foreground color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::buttonText() const - - Returns the button text foreground color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::base() const - - Returns the base color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::background() const - - Returns the background color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::shadow() const - - Returns the shadow color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::highlight() const - - Returns the highlight color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::highlightedText() const - - Returns the highlighted text color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::link() const - - Returns the unvisited link text color of the color group. - - \sa ColorRole -*/ - -/*! - \fn const TQColor & TQColorGroup::linkVisited() const - - Returns the visited link text color of the color group. - - \sa ColorRole -*/ - -/*! - \fn bool TQColorGroup::operator!=( const TQColorGroup &g ) const - - Returns TRUE if this color group is different from \a g; otherwise - returns FALSE. - - \sa operator!=() -*/ - -/*! - Returns TRUE if this color group is equal to \a g; otherwise - returns FALSE. - - \sa operator==() -*/ - -bool TQColorGroup::operator==( const TQColorGroup &g ) const -{ - if ( d == g.d ) - return TRUE; - for( int r = 0 ; r < NColorRoles ; r++ ) - if ( br[r] != g.br[r] ) - return FALSE; - return TRUE; -} - - -/***************************************************************************** - TQPalette member functions - *****************************************************************************/ - -/*! - \class TQPalette ntqpalette.h - - \brief The TQPalette class contains color groups for each widget state. - - \ingroup appearance - \ingroup shared - \ingroup graphics - \ingroup images - \mainclass - - A palette consists of three color groups: \e active, \e disabled, - and \e inactive. All widgets contain a palette, and all widgets in - TQt use their palette to draw themselves. This makes the user - interface easily configurable and easier to keep consistent. - - If you create a new widget we strongly recommend that you use the - colors in the palette rather than hard-coding specific colors. - - The color groups: - \list - \i The active() group is used for the window that has keyboard focus. - \i The inactive() group is used for other windows. - \i The disabled() group is used for widgets (not windows) that are - disabled for some reason. - \endlist - - Both active and inactive windows can contain disabled widgets. - (Disabled widgets are often called \e inaccessible or \e{grayed - out}.) - - In Motif style, active() and inactive() look the same. In Windows - 2000 style and Macintosh Platinum style, the two styles look - slightly different. - - There are setActive(), setInactive(), and setDisabled() functions - to modify the palette. - - Colors and brushes can be set for particular roles in any of a - palette's color groups with setColor() and setBrush(). - - You can copy a palette using the copy constructor and test to see - if two palettes are \e identical using isCopyOf(). - - \sa TQApplication::setPalette(), TQWidget::setPalette(), TQColorGroup, TQColor -*/ - -/*! - \enum TQPalette::ColorGroup - - \value Disabled - \value Active - \value Inactive - \value NColorGroups -*/ - -static int palette_count = 1; - -/*! - Constructs a palette that consists of color groups with only black - colors. -*/ - -TQPalette::TQPalette() -{ - static TQPalData *defPalData = 0; - if ( !defPalData ) { // create common palette data - defPalData = new TQPalData; // for the default palette - static TQSharedCleanupHandler defPalCleanup; - defPalCleanup.set( &defPalData ); - defPalData->ser_no = palette_count++; - } - data = defPalData; - data->ref(); -} - -/*!\obsolete - Constructs a palette from the \a button color. The other colors are - automatically calculated, based on this color. Background will be - the button color as well. -*/ - -TQPalette::TQPalette( const TQColor &button ) -{ - data = new TQPalData; - TQ_CHECK_PTR( data ); - data->ser_no = palette_count++; - TQColor bg = button, btn = button, fg, base, disfg; - int h, s, v; - bg.hsv( &h, &s, &v ); - if ( v > 128 ) { // light background - fg = TQt::black; - base = TQt::white; - disfg = TQt::darkGray; - } else { // dark background - fg = TQt::white; - base = TQt::black; - disfg = TQt::darkGray; - } - data->active = TQColorGroup( fg, btn, btn.light(150), btn.dark(), - btn.dark(150), fg, TQt::white, base, bg ); - data->disabled = TQColorGroup( disfg, btn, btn.light(150), btn.dark(), - btn.dark(150), disfg, TQt::white, base, bg ); - data->inactive = data->active; -} - -/*! - Constructs a palette from a \a button color and a \a background. - The other colors are automatically calculated, based on these - colors. -*/ - -TQPalette::TQPalette( const TQColor &button, const TQColor &background ) -{ - data = new TQPalData; - TQ_CHECK_PTR( data ); - data->ser_no = palette_count++; - TQColor bg = background, btn = button, fg, base, disfg; - int h, s, v; - bg.hsv( &h, &s, &v ); - if ( v > 128 ) { // light background - fg = TQt::black; - base = TQt::white; - disfg = TQt::darkGray; - } else { // dark background - fg = TQt::white; - base = TQt::black; - disfg = TQt::darkGray; - } - data->active = TQColorGroup( fg, btn, btn.light(150), btn.dark(), - btn.dark(150), fg, TQt::white, base, bg ); - data->disabled = TQColorGroup( disfg, btn, btn.light(150), btn.dark(), - btn.dark(150), disfg, TQt::white, base, bg ); - data->inactive = data->active; -} - -/*! - Constructs a palette that consists of the three color groups \a - active, \a disabled and \a inactive. See the \link #details - Detailed Description\endlink for definitions of the color groups - and \l TQColorGroup::ColorRole for definitions of each color role - in the three groups. - - \sa TQColorGroup TQColorGroup::ColorRole TQPalette -*/ - -TQPalette::TQPalette( const TQColorGroup &active, const TQColorGroup &disabled, - const TQColorGroup &inactive ) -{ - data = new TQPalData; - TQ_CHECK_PTR( data ); - data->ser_no = palette_count++; - data->active = active; - data->disabled = disabled; - data->inactive = inactive; -} - -/*! - Constructs a copy of \a p. - - This constructor is fast (it uses copy-on-write). -*/ - -TQPalette::TQPalette( const TQPalette &p ) -{ - data = p.data; - data->ref(); -} - -/*! - Destroys the palette. -*/ - -TQPalette::~TQPalette() -{ - if ( data->deref() ) - delete data; -} - -/*! - Assigns \a p to this palette and returns a reference to this - palette. - - This is fast (it uses copy-on-write). - - \sa copy() -*/ - -TQPalette &TQPalette::operator=( const TQPalette &p ) -{ - p.data->ref(); - if ( data->deref() ) - delete data; - data = p.data; - return *this; -} - - -/*! - Returns the color in color group \a gr, used for color role \a r. - - \sa brush() setColor() TQColorGroup::ColorRole -*/ -const TQColor &TQPalette::color( ColorGroup gr, TQColorGroup::ColorRole r ) const -{ - return directBrush( gr, r ).color(); -} - -/*! - Returns the brush in color group \a gr, used for color role \a r. - - \sa color() setBrush() TQColorGroup::ColorRole -*/ -const TQBrush &TQPalette::brush( ColorGroup gr, TQColorGroup::ColorRole r ) const -{ - return directBrush( gr, r ); -} - -/*! - Sets the brush in color group \a gr, used for color role \a r, to - the solid color \a c. - - \sa setBrush() color() TQColorGroup::ColorRole -*/ -void TQPalette::setColor( ColorGroup gr, TQColorGroup::ColorRole r, - const TQColor &c) -{ - setBrush( gr, r, TQBrush(c) ); -} - -/*! - Sets the brush in color group \a gr, used for color role \a r, to - \a b. - - \sa brush() setColor() TQColorGroup::ColorRole -*/ -void TQPalette::setBrush( ColorGroup gr, TQColorGroup::ColorRole r, - const TQBrush &b) -{ - detach(); - data->ser_no = palette_count++; - directSetBrush( gr, r, b); -} - -/*! - \overload - - Sets the brush color used for color role \a r to color \a c in all - three color groups. - - \sa color() setBrush() TQColorGroup::ColorRole -*/ -void TQPalette::setColor( TQColorGroup::ColorRole r, const TQColor &c ) -{ - setBrush( r, TQBrush(c) ); -} - -/*! - \overload - - Sets the brush in for color role \a r in all three color groups to - \a b. - - \sa brush() setColor() TQColorGroup::ColorRole active() inactive() disabled() -*/ -void TQPalette::setBrush( TQColorGroup::ColorRole r, const TQBrush &b ) -{ - detach(); - data->ser_no = palette_count++; - directSetBrush( Active, r, b ); - directSetBrush( Disabled, r, b ); - directSetBrush( Inactive, r, b ); -} - - -/*! - Returns a deep copy of this palette. - - \warning This is slower than the copy constructor and assignment - operator and offers no benefits. -*/ - -TQPalette TQPalette::copy() const -{ - TQPalette p( data->active, data->disabled, data->inactive ); - return p; -} - - -/*! - Detaches this palette from any other TQPalette objects with which - it might implicitly share TQColorGroup objects. In essence, does - the copying part of copy-on-write. - - Calling this should generally not be necessary; TQPalette calls it - itself when necessary. -*/ - -void TQPalette::detach() -{ - if ( data->count != 1 ) - *this = copy(); -} - -/*! - \fn const TQColorGroup & TQPalette::disabled() const - - Returns the disabled color group of this palette. - - \sa TQColorGroup, setDisabled(), active(), inactive() -*/ - -/*! - Sets the \c Disabled color group to \a g. - - \sa disabled() setActive() setInactive() -*/ - -void TQPalette::setDisabled( const TQColorGroup &g ) -{ - detach(); - data->ser_no = palette_count++; - data->disabled = g; -} - -/*! - \fn const TQColorGroup & TQPalette::active() const - - Returns the active color group of this palette. - - \sa TQColorGroup, setActive(), inactive(), disabled() -*/ - -/*! - Sets the \c Active color group to \a g. - - \sa active() setDisabled() setInactive() TQColorGroup -*/ - -void TQPalette::setActive( const TQColorGroup &g ) -{ - detach(); - data->ser_no = palette_count++; - data->active = g; -} - -/*! - \fn const TQColorGroup & TQPalette::inactive() const - - Returns the inactive color group of this palette. - - \sa TQColorGroup, setInactive(), active(), disabled() -*/ - -/*! - Sets the \c Inactive color group to \a g. - - \sa active() setDisabled() setActive() TQColorGroup -*/ - -void TQPalette::setInactive( const TQColorGroup &g ) -{ - detach(); - data->ser_no = palette_count++; - data->inactive = g; -} - - -/*! - \fn bool TQPalette::operator!=( const TQPalette &p ) const - - Returns TRUE (slowly) if this palette is different from \a p; - otherwise returns FALSE (usually quickly). -*/ - -/*! - Returns TRUE (usually quickly) if this palette is equal to \a p; - otherwise returns FALSE (slowly). -*/ - -bool TQPalette::operator==( const TQPalette &p ) const -{ - return data->active == p.data->active && - data->disabled == p.data->disabled && - data->inactive == p.data->inactive; -} - - -/*! - \fn int TQPalette::serialNumber() const - - Returns a number that uniquely identifies this TQPalette object. - The serial number is intended for caching. Its value may not be - used for anything other than equality testing. - - Note that TQPalette uses copy-on-write, and the serial number - changes during the lazy copy operation (detach()), not during a - shallow copy (copy constructor or assignment). - - \sa TQPixmap TQPixmapCache TQCache -*/ - - -/***************************************************************************** - TQColorGroup/TQPalette stream functions - *****************************************************************************/ - -#ifndef TQT_NO_DATASTREAM -/*! - \relates TQColorGroup - - Writes color group, \a g to the stream \a s. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQColorGroup &g ) -{ - if ( s.version() == 1 ) { - // TQt 1.x - s << g.foreground() - << g.background() - << g.light() - << g.dark() - << g.mid() - << g.text() - << g.base(); - } else { - int max = TQColorGroup::NColorRoles; - if ( s.version() <= 3) // TQt 2.x - max = 14; - - for( int r = 0 ; r < max ; r++ ) - s << g.brush( (TQColorGroup::ColorRole)r); - } - return s; -} - -/*! - \related TQColorGroup - - Reads a color group from the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator>>( TQDataStream &s, TQColorGroup &g ) -{ - if ( s.version() == 1 ) { - // TQt 1.x - TQColor fg, bg, light, dark, mid, text, base; - s >> fg >> bg >> light >> dark >> mid >> text >> base; - TQPalette p( bg ); - TQColorGroup n( p.active() ); - n.setColor( TQColorGroup::Foreground, fg ); - n.setColor( TQColorGroup::Light, light ); - n.setColor( TQColorGroup::Dark, dark ); - n.setColor( TQColorGroup::Mid, mid ); - n.setColor( TQColorGroup::Text, text ); - n.setColor( TQColorGroup::Base, base ); - g = n; - } else { - int max = TQColorGroup::NColorRoles; - if (s.version() <= 3) // TQt 2.x - max = 14; - - TQBrush tmp; - for( int r = 0 ; r < max; r++ ) { - s >> tmp; - g.setBrush( (TQColorGroup::ColorRole)r, tmp); - } - } - return s; -} - - -/*! - \relates TQPalette - - Writes the palette, \a p to the stream \a s and returns a - reference to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQPalette &p ) -{ - return s << p.active() - << p.disabled() - << p.inactive(); -} - - -static void readV1ColorGroup( TQDataStream &s, TQColorGroup &g, - TQPalette::ColorGroup r ) -{ - TQColor fg, bg, light, dark, mid, text, base; - s >> fg >> bg >> light >> dark >> mid >> text >> base; - TQPalette p( bg ); - TQColorGroup n; - switch ( r ) { - case TQPalette::Disabled: - n = p.disabled(); - break; - case TQPalette::Inactive: - n = p.inactive(); - break; - default: - n = p.active(); - break; - } - n.setColor( TQColorGroup::Foreground, fg ); - n.setColor( TQColorGroup::Light, light ); - n.setColor( TQColorGroup::Dark, dark ); - n.setColor( TQColorGroup::Mid, mid ); - n.setColor( TQColorGroup::Text, text ); - n.setColor( TQColorGroup::Base, base ); - g = n; -} - - -/*! - \relates TQPalette - - Reads a palette from the stream, \a s into the palette \a p, and - returns a reference to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator>>( TQDataStream &s, TQPalette &p ) -{ - TQColorGroup active, disabled, inactive; - if ( s.version() == 1 ) { - readV1ColorGroup( s, active, TQPalette::Active ); - readV1ColorGroup( s, disabled, TQPalette::Disabled ); - readV1ColorGroup( s, inactive, TQPalette::Inactive ); - } else { - s >> active >> disabled >> inactive; - } - TQPalette newpal( active, disabled, inactive ); - p = newpal; - return s; -} -#endif //TQT_NO_DATASTREAM - -/*! - Returns TRUE if this palette and \a p are copies of each other, - i.e. one of them was created as a copy of the other and neither - was subsequently modified; otherwise returns FALSE. This is much - stricter than equality. - - \sa operator=() operator==() -*/ - -bool TQPalette::isCopyOf( const TQPalette & p ) -{ - return data && data == p.data; -} - -const TQBrush &TQPalette::directBrush( ColorGroup gr, TQColorGroup::ColorRole r ) const -{ - if ( (uint)gr > (uint)TQPalette::NColorGroups ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPalette::directBrush: colorGroup(%i) out of range", gr ); -#endif - return data->active.br[TQColorGroup::Foreground]; - } - if ( (uint)r >= (uint)TQColorGroup::NColorRoles ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPalette::directBrush: colorRole(%i) out of range", r ); -#endif - return data->active.br[TQColorGroup::Foreground]; - } - switch( gr ) { - case Active: - return data->active.br[r]; - //break; - case Disabled: - return data->disabled.br[r]; - //break; - case Inactive: - return data->inactive.br[r]; - //break; - default: - break; - } -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPalette::directBrush: colorGroup(%i) internal error", gr ); -#endif - return data->active.br[TQColorGroup::Foreground]; // Satisfy compiler -} - -void TQPalette::directSetBrush( ColorGroup gr, TQColorGroup::ColorRole r, const TQBrush& b) -{ - if ( (uint)gr > (uint)TQPalette::NColorGroups ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPalette::directBrush: colorGroup(%i) out of range", gr ); -#endif - return; - } - if ( (uint)r >= (uint)TQColorGroup::NColorRoles ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPalette::directBrush: colorRole(%i) out of range", r ); -#endif - return; - } - switch( gr ) { - case Active: - data->active.setBrush(r,b); - break; - case Disabled: - data->disabled.setBrush(r,b); - break; - case Inactive: - data->inactive.setBrush(r,b); - break; - default: -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPalette::directBrush: colorGroup(%i) internal error", gr ); -#endif - break; - } -} - - -/*!\internal*/ -TQColorGroup::ColorRole TQPalette::foregroundRoleFromMode( TQt::BackgroundMode mode ) -{ - switch (mode) { - case TQt::PaletteButton: - return TQColorGroup::ButtonText; - case TQt::PaletteBase: - return TQColorGroup::Text; - case TQt::PaletteDark: - case TQt::PaletteShadow: - return TQColorGroup::Light; - case TQt::PaletteHighlight: - return TQColorGroup::HighlightedText; - case TQt::PaletteBackground: - default: - return TQColorGroup::Foreground; - } -} - -/*!\internal*/ -TQColorGroup::ColorRole TQPalette::backgroundRoleFromMode( TQt::BackgroundMode mode) -{ - switch (mode) { - case TQt::PaletteForeground: - return TQColorGroup::Foreground; - case TQt::PaletteButton: - return TQColorGroup::Button; - case TQt::PaletteLight: - return TQColorGroup::Light; - case TQt::PaletteMidlight: - return TQColorGroup::Midlight; - case TQt::PaletteDark: - return TQColorGroup::Dark; - case TQt::PaletteMid: - return TQColorGroup::Mid; - case TQt::PaletteText: - return TQColorGroup::Text; - case TQt::PaletteBrightText: - return TQColorGroup::BrightText; - case TQt::PaletteButtonText: - return TQColorGroup::ButtonText; - case TQt::PaletteBase: - return TQColorGroup::Base; - case TQt::PaletteShadow: - return TQColorGroup::Shadow; - case TQt::PaletteHighlight: - return TQColorGroup::Highlight; - case TQt::PaletteHighlightedText: - return TQColorGroup::HighlightedText; - case TQt::PaletteLink: - return TQColorGroup::Link; - case TQt::PaletteLinkVisited: - return TQColorGroup::LinkVisited; - case TQt::PaletteBackground: - default: - return TQColorGroup::Background; - } -} - -#endif // TQT_NO_PALETTE diff --git a/src/kernel/qpicture.cpp b/src/kernel/qpicture.cpp deleted file mode 100644 index 35dd8439a..000000000 --- a/src/kernel/qpicture.cpp +++ /dev/null @@ -1,1229 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPicture class -** -** Created : 940802 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpicture.h" - -#ifndef TQT_NO_PICTURE - -#include "tqpainter.h" -#include "ntqpixmap.h" -#include "tqimage.h" -#include "tqfile.h" -#include "tqdatastream.h" -#include "tqpaintdevicemetrics.h" - -#ifndef TQT_NO_SVG -#include "private/qsvgdevice_p.h" -#endif - -/*! - \class TQPicture ntqpicture.h - \brief The TQPicture class is a paint device that records and - replays TQPainter commands. - - \ingroup graphics - \ingroup images - \ingroup shared - - A picture serializes painter commands to an IO device in a - platform-independent format. For example, a picture created under - Windows can be read on a Sun SPARC. - - Pictures are called meta-files on some platforms. - - TQt pictures use a proprietary binary format. Unlike native picture - (meta-file) formats on many window systems, TQt pictures have no - limitations regarding their contents. Everything that can be - painted can also be stored in a picture, e.g. fonts, pixmaps, - regions, transformed graphics, etc. - - TQPicture is an \link shclass.html implicitly shared\endlink class. - - Example of how to record a picture: - \code - TQPicture pic; - TQPainter p; - p.begin( &pic ); // paint in picture - p.drawEllipse( 10,20, 80,70 ); // draw an ellipse - p.end(); // painting done - pic.save( "drawing.pic" ); // save picture - \endcode - - Example of how to replay a picture: - \code - TQPicture pic; - pic.load( "drawing.pic" ); // load picture - TQPainter p; - p.begin( &myWidget ); // paint in myWidget - p.drawPicture( pic ); // draw the picture - p.end(); // painting done - \endcode - - Pictures can also be drawn using play(). Some basic data about a - picture is available, for example, size(), isNull() and - boundingRect(). - -*/ - - -static const char *mfhdr_tag = "TQPIC"; // header tag -static const TQ_UINT16 mfhdr_maj = 5; // major version # -static const TQ_UINT16 mfhdr_min = 0; // minor version # - - -/*! - Constructs an empty picture. - - The \a formatVersion parameter may be used to \e create a TQPicture - that can be read by applications that are compiled with earlier - versions of TQt. - \list - \i \a formatVersion == 1 is binary compatible with TQt 1.x and later. - \i \a formatVersion == 2 is binary compatible with TQt 2.0.x and later. - \i \a formatVersion == 3 is binary compatible with TQt 2.1.x and later. - \i \a formatVersion == 4 is binary compatible with TQt 3.0.x and later. - \i \a formatVersion == 5 is binary compatible with TQt 3.1. - \endlist - - Note that the default formatVersion is -1 which signifies the - current release, i.e. for TQt 3.1 a formatVersion of 5 is the same - as the default formatVersion of -1. - - Reading pictures generated by earlier versions of TQt is supported - and needs no special coding; the format is automatically detected. -*/ - -TQPicture::TQPicture( int formatVersion ) - : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ) - // set device type -{ - d = new TQPicturePrivate; - -#if defined(QT_CHECK_RANGE) - if ( formatVersion == 0 ) - tqWarning( "TQPicture: invalid format version 0" ); -#endif - - // still accept the 0 default from before TQt 3.0. - if ( formatVersion > 0 && formatVersion != (int)mfhdr_maj ) { - d->formatMajor = formatVersion; - d->formatMinor = 0; - d->formatOk = FALSE; - } - else { - d->resetFormat(); - } -} - -/*! - Constructs a \link shclass.html shallow copy\endlink of \a pic. -*/ - -TQPicture::TQPicture( const TQPicture &pic ) - : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ) -{ - d = pic.d; - d->ref(); -} - -/*! - Destroys the picture. -*/ -TQPicture::~TQPicture() -{ - if ( d->deref() ) - delete d; -} - - -/*! - \fn bool TQPicture::isNull() const - - Returns TRUE if the picture contains no data; otherwise returns - FALSE. -*/ - -/*! - \fn uint TQPicture::size() const - - Returns the size of the picture data. - - \sa data() -*/ - -/*! - \fn const char* TQPicture::data() const - - Returns a pointer to the picture data. The pointer is only valid - until the next non-const function is called on this picture. The - returned pointer is 0 if the picture contains no data. - - \sa size(), isNull() -*/ - -/*! - Sets the picture data directly from \a data and \a size. This - function copies the input data. - - \sa data(), size() -*/ - -void TQPicture::setData( const char* data, uint size ) -{ - detach(); - TQByteArray a( size ); - memcpy( a.data(), data, size ); - d->pictb.setBuffer( a ); // set byte array in buffer - d->resetFormat(); // we'll have to check -} - - -/*! - Loads a picture from the file specified by \a fileName and returns - TRUE if successful; otherwise returns FALSE. - - By default, the file will be interpreted as being in the native - TQPicture format. Specifying the \a format string is optional and - is only needed for importing picture data stored in a different - format. - - Currently, the only external format supported is the \link - http://www.w3.org/Graphics/SVG/ W3C SVG \endlink format which - requires the \link xml.html TQt XML module \endlink. The - corresponding \a format string is "svg". - - \sa save() -*/ - -bool TQPicture::load( const TQString &fileName, const char *format ) -{ - TQFile f( fileName ); - if ( !f.open(IO_ReadOnly) ) - return FALSE; - return load( &f, format ); -} - -/*! - \overload - - \a dev is the device to use for loading. -*/ - -bool TQPicture::load( TQIODevice *dev, const char *format ) -{ -#ifndef TQT_NO_SVG - if ( qstrcmp( format, "svg" ) == 0 ) { - TQSvgDevice svg; - if ( !svg.load( dev ) ) - return FALSE; - TQPainter p( this ); - bool b = svg.play( &p ); - d->brect = svg.boundingRect(); - return b; - } -#endif - if ( format ) { - tqWarning( "TQPicture::load: No such picture format: %s", format ); - return FALSE; - } - - detach(); - TQByteArray a = dev->readAll(); - d->pictb.setBuffer( a ); // set byte array in buffer - return d->checkFormat(); -} - -/*! - Saves a picture to the file specified by \a fileName and returns - TRUE if successful; otherwise returns FALSE. - - Specifying the file \a format string is optional. It's not - recommended unless you intend to export the picture data for - use by a third party reader. By default the data will be saved in - the native TQPicture file format. - - Currently, the only external format supported is the \link - http://www.w3.org/Graphics/SVG/ W3C SVG \endlink format which - requires the \link xml.html TQt XML module \endlink. The - corresponding \a format string is "svg". - - \sa load() -*/ - -bool TQPicture::save( const TQString &fileName, const char *format ) -{ - if ( paintingActive() ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPicture::save: still being painted on. " - "Call TQPainter::end() first" ); -#endif - return FALSE; - } - -#ifndef TQT_NO_SVG - // identical to TQIODevice* code below but the file name - // makes a difference when it comes to saving pixmaps - if ( tqstricmp( format, "svg" ) == 0 ) { - TQSvgDevice svg; - TQPainter p( &svg ); - if ( !play( &p ) ) - return FALSE; - svg.setBoundingRect( boundingRect() ); - return svg.save( fileName ); - } -#endif - - TQFile f( fileName ); - if ( !f.open(IO_WriteOnly) ) - return FALSE; - return save( &f, format ); -} - -/*! - \overload - - \a dev is the device to use for saving. -*/ - -bool TQPicture::save( TQIODevice *dev, const char *format ) -{ - if ( paintingActive() ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPicture::save: still being painted on. " - "Call TQPainter::end() first" ); -#endif - return FALSE; - } - -#ifndef TQT_NO_SVG - if ( tqstricmp( format, "svg" ) == 0 ) { - TQSvgDevice svg; - TQPainter p( &svg ); - if ( !play( &p ) ) - return FALSE; - svg.setBoundingRect( boundingRect() ); - return svg.save( dev ); - } -#endif - if ( format ) { - tqWarning( "TQPicture::save: No such picture format: %s", format ); - return FALSE; - } - - dev->writeBlock( d->pictb.buffer().data(), d->pictb.buffer().size() ); - return TRUE; -} - -/*! - Returns the picture's bounding rectangle or an invalid rectangle - if the picture contains no data. -*/ - -TQRect TQPicture::boundingRect() const -{ - if ( !d->formatOk ) - d->checkFormat(); - return d->brect; -} - -/*! - Sets the picture's bounding rectangle to \a r. The automatically - calculated value is overriden. -*/ - -void TQPicture::setBoundingRect( const TQRect &r ) -{ - if ( !d->formatOk ) - d->checkFormat(); - d->brect = r; -} - -/*! - Replays the picture using \a painter, and returns TRUE if - successful; otherwise returns FALSE. - - This function does exactly the same as TQPainter::drawPicture() - with (x, y) = (0, 0). -*/ - -bool TQPicture::play( TQPainter *painter ) -{ - if ( d->pictb.size() == 0 ) // nothing recorded - return TRUE; - - if ( !d->formatOk && !d->checkFormat() ) - return FALSE; - - d->pictb.open( IO_ReadOnly ); // open buffer device - TQDataStream s; - s.setDevice( &d->pictb ); // attach data stream to buffer - s.device()->at( 10 ); // go directly to the data - s.setVersion( d->formatMajor == 4 ? 3 : d->formatMajor ); - - TQ_UINT8 c, clen; - TQ_UINT32 nrecords; - s >> c >> clen; - Q_ASSERT( c == PdcBegin ); - // bounding rect was introduced in ver 4. Read in checkFormat(). - if ( d->formatMajor >= 4 ) { - TQ_INT32 dummy; - s >> dummy >> dummy >> dummy >> dummy; - } - s >> nrecords; - if ( !exec( painter, s, nrecords ) ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPicture::play: Format error" ); -#endif - d->pictb.close(); - return FALSE; - } - d->pictb.close(); - return TRUE; // no end-command -} - - -/*! - \internal - Iterates over the internal picture data and draws the picture using - \a painter. -*/ - -bool TQPicture::exec( TQPainter *painter, TQDataStream &s, int nrecords ) -{ -#if defined(QT_DEBUG) - int strm_pos; -#endif - TQ_UINT8 c; // command id - TQ_UINT8 tiny_len; // 8-bit length descriptor - TQ_INT32 len; // 32-bit length descriptor - TQ_INT16 i_16, i1_16, i2_16; // parameters... - TQ_INT8 i_8; - TQ_UINT32 ul; - TQCString str1; - TQString str; - TQPoint p, p1, p2; - TQRect r; - TQPointArray a; - TQColor color; - TQFont font; - TQPen pen; - TQBrush brush; - TQRegion rgn; -#ifndef TQT_NO_TRANSFORMATIONS - TQWMatrix matrix; -#endif - - while ( nrecords-- && !s.eof() ) { - s >> c; // read cmd - s >> tiny_len; // read param length - if ( tiny_len == 255 ) // longer than 254 bytes - s >> len; - else - len = tiny_len; -#if defined(QT_DEBUG) - strm_pos = s.device()->at(); -#endif - switch ( c ) { // exec cmd - case PdcNOP: - break; - case PdcDrawPoint: - s >> p; - painter->drawPoint( p ); - break; - case PdcMoveTo: - s >> p; - painter->moveTo( p ); - break; - case PdcLineTo: - s >> p; - painter->lineTo( p ); - break; - case PdcDrawLine: - s >> p1 >> p2; - painter->drawLine( p1, p2 ); - break; - case PdcDrawRect: - s >> r; - painter->drawRect( r ); - break; - case PdcDrawRoundRect: - s >> r >> i1_16 >> i2_16; - painter->drawRoundRect( r, i1_16, i2_16 ); - break; - case PdcDrawEllipse: - s >> r; - painter->drawEllipse( r ); - break; - case PdcDrawArc: - s >> r >> i1_16 >> i2_16; - painter->drawArc( r, i1_16, i2_16 ); - break; - case PdcDrawPie: - s >> r >> i1_16 >> i2_16; - painter->drawPie( r, i1_16, i2_16 ); - break; - case PdcDrawChord: - s >> r >> i1_16 >> i2_16; - painter->drawChord( r, i1_16, i2_16 ); - break; - case PdcDrawLineSegments: - s >> a; - painter->drawLineSegments( a ); - break; - case PdcDrawPolyline: - s >> a; - painter->drawPolyline( a ); - break; - case PdcDrawPolygon: - s >> a >> i_8; - painter->drawPolygon( a, i_8 ); - break; - case PdcDrawCubicBezier: - s >> a; -#ifndef TQT_NO_BEZIER - painter->drawCubicBezier( a ); -#endif - break; - case PdcDrawText: - s >> p >> str1; - painter->drawText( p, str1 ); - break; - case PdcDrawTextFormatted: - s >> r >> i_16 >> str1; - painter->drawText( r, i_16, str1 ); - break; - case PdcDrawText2: - s >> p >> str; - painter->drawText( p, str ); - break; - case PdcDrawText2Formatted: - s >> r >> i_16 >> str; - painter->drawText( r, i_16, str ); - break; - case PdcDrawPixmap: { - TQPixmap pixmap; - if ( d->formatMajor < 4 ) { - s >> p >> pixmap; - painter->drawPixmap( p, pixmap ); - } else { - s >> r >> pixmap; - painter->drawPixmap( r, pixmap ); - } - } - break; - case PdcDrawImage: { - TQImage image; - if ( d->formatMajor < 4 ) { - s >> p >> image; - painter->drawImage( p, image ); - } else { - s >> r >> image; - painter->drawImage( r, image ); - } - } - break; - case PdcBegin: - s >> ul; // number of records - if ( !exec( painter, s, ul ) ) - return FALSE; - break; - case PdcEnd: - if ( nrecords == 0 ) - return TRUE; - break; - case PdcSave: - painter->save(); - break; - case PdcRestore: - painter->restore(); - break; - case PdcSetBkColor: - s >> color; - painter->setBackgroundColor( color ); - break; - case PdcSetBkMode: - s >> i_8; - painter->setBackgroundMode( (TQt::BGMode)i_8 ); - break; - case PdcSetROP: - s >> i_8; - painter->setRasterOp( (TQt::RasterOp)i_8 ); - break; - case PdcSetBrushOrigin: - s >> p; - painter->setBrushOrigin( p ); - break; - case PdcSetFont: - s >> font; - painter->setFont( font ); - break; - case PdcSetPen: - s >> pen; - painter->setPen( pen ); - break; - case PdcSetBrush: - s >> brush; - painter->setBrush( brush ); - break; - case PdcSetTabStops: - s >> i_16; - painter->setTabStops( i_16 ); - break; - case PdcSetTabArray: - s >> i_16; - if ( i_16 == 0 ) { - painter->setTabArray( 0 ); - } else { - int *ta = new int[i_16]; - TQ_CHECK_PTR( ta ); - for ( int i=0; i> i1_16; - ta[i] = i1_16; - } - painter->setTabArray( ta ); - delete [] ta; - } - break; - case PdcSetVXform: - s >> i_8; -#ifndef TQT_NO_TRANSFORMATIONS - painter->setViewXForm( i_8 ); -#endif - break; - case PdcSetWindow: - s >> r; -#ifndef TQT_NO_TRANSFORMATIONS - painter->setWindow( r ); -#endif - break; - case PdcSetViewport: - s >> r; -#ifndef TQT_NO_TRANSFORMATIONS - painter->setViewport( r ); -#endif - break; - case PdcSetWXform: - s >> i_8; -#ifndef TQT_NO_TRANSFORMATIONS - painter->setWorldXForm( i_8 ); -#endif - break; - case PdcSetWMatrix: -#ifndef TQT_NO_TRANSFORMATIONS // #### fix me! - s >> matrix >> i_8; - painter->setWorldMatrix( matrix, i_8 ); -#endif - break; -#ifndef TQT_NO_TRANSFORMATIONS - case PdcSaveWMatrix: - painter->saveWorldMatrix(); - break; - case PdcRestoreWMatrix: - painter->restoreWorldMatrix(); - break; -#endif - case PdcSetClip: - s >> i_8; - painter->setClipping( i_8 ); - break; - case PdcSetClipRegion: - s >> rgn >> i_8; - painter->setClipRegion( rgn, (TQPainter::CoordinateMode)i_8 ); - break; - default: -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPicture::play: Invalid command %d", c ); -#endif - if ( len ) // skip unknown command - s.device()->at( s.device()->at()+len ); - } -#if defined(QT_DEBUG) - //tqDebug( "device->at(): %i, strm_pos: %i len: %i", s.device()->at(), strm_pos, len ); - Q_ASSERT( TQ_INT32(s.device()->at() - strm_pos) == len ); -#endif - } - return FALSE; -} - - -/*! - \internal - Records painter commands and stores them in the pictb buffer. -*/ - -bool TQPicture::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) -{ - detach(); - return d->cmd( c, pt, p ); -} - -/*! - \internal - Implementation of the function forwarded above to the internal data struct. -*/ - -bool TQPicture::TQPicturePrivate::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) -{ - TQDataStream s; - s.setDevice( &pictb ); - // when moving up to 4 the TQDataStream version remained at 3 - s.setVersion( formatMajor != 4 ? formatMajor : 3 ); - if ( c == PdcBegin ) { // begin; write header - TQByteArray empty( 0 ); - pictb.setBuffer( empty ); // reset byte array in buffer - pictb.open( IO_WriteOnly ); - s.writeRawBytes( mfhdr_tag, 4 ); - s << (TQ_UINT16)0 << (TQ_UINT16)formatMajor << (TQ_UINT16)formatMinor; - s << (TQ_UINT8)c << (TQ_UINT8)sizeof(TQ_INT32); - brect = TQRect(); - if ( formatMajor >= 4 ) { - s << (TQ_INT32)brect.left() << (TQ_INT32)brect.top() - << (TQ_INT32)brect.width() << (TQ_INT32)brect.height(); - } - trecs = 0; - s << (TQ_UINT32)trecs; // total number of records - formatOk = FALSE; - return TRUE; - } else if ( c == PdcEnd ) { // end; calc checksum and close - trecs++; - s << (TQ_UINT8)c << (TQ_UINT8)0; - TQByteArray buf = pictb.buffer(); - int cs_start = sizeof(TQ_UINT32); // pos of checksum word - int data_start = cs_start + sizeof(TQ_UINT16); - int brect_start = data_start + 2*sizeof(TQ_INT16) + 2*sizeof(TQ_UINT8); - int pos = pictb.at(); - pictb.at( brect_start ); - if ( formatMajor >= 4 ) { // bounding rectangle - s << (TQ_INT32)brect.left() << (TQ_INT32)brect.top() - << (TQ_INT32)brect.width() << (TQ_INT32)brect.height(); - } - s << (TQ_UINT32)trecs; // write number of records - pictb.at( cs_start ); - TQ_UINT16 cs = (TQ_UINT16)tqChecksum( buf.data()+data_start, pos-data_start ); - s << cs; // write checksum - pictb.close(); - return TRUE; - } - trecs++; - s << (TQ_UINT8)c; // write cmd to stream - s << (TQ_UINT8)0; // write dummy length info - int pos = (int)pictb.at(); // save position - TQRect br; // bounding rect addition - bool corr = FALSE; // correction for pen width - - switch ( c ) { - case PdcDrawPoint: - case PdcMoveTo: - case PdcLineTo: - case PdcSetBrushOrigin: - s << *p[0].point; - br = TQRect( *p[0].point, TQSize( 1, 1 ) ); - corr = TRUE; - break; - case PdcDrawLine: - s << *p[0].point << *p[1].point; - br = TQRect( *p[0].point, *p[1].point ).normalize(); - corr = TRUE; - break; - case PdcDrawRect: - case PdcDrawEllipse: - s << *p[0].rect; - br = *p[0].rect; - corr = TRUE; - break; - case PdcDrawRoundRect: - case PdcDrawArc: - case PdcDrawPie: - case PdcDrawChord: - s << *p[0].rect << (TQ_INT16)p[1].ival << (TQ_INT16)p[2].ival; - br = *p[0].rect; - corr = TRUE; - break; - case PdcDrawLineSegments: - case PdcDrawPolyline: - s << *p[0].ptarr; - br = p[0].ptarr->boundingRect(); - corr = TRUE; - break; -#ifndef TQT_NO_BEZIER - case PdcDrawCubicBezier: - s << *p[0].ptarr; - br = p[0].ptarr->cubicBezier().boundingRect(); - corr = TRUE; - break; -#endif - case PdcDrawPolygon: - s << *p[0].ptarr << (TQ_INT8)p[1].ival; - br = p[0].ptarr->boundingRect(); - corr = TRUE; - break; - case PdcDrawText2: - if ( formatMajor == 1 ) { - pictb.at( pos - 2 ); - s << (TQ_UINT8)PdcDrawText << (TQ_UINT8)0; - TQCString str1( (*p[1].str).latin1() ); - s << *p[0].point << str1; - } - else { - s << *p[0].point << *p[1].str; - } - br = pt->fontMetrics().boundingRect( *p[1].str ); - br.moveBy( p[0].point->x(), p[0].point->y() ); - break; - case PdcDrawText2Formatted: - if ( formatMajor == 1 ) { - pictb.at( pos - 2 ); - s << (TQ_UINT8)PdcDrawTextFormatted << (TQ_UINT8)0; - TQCString str1( (*p[2].str).latin1() ); - s << *p[0].rect << (TQ_INT16)p[1].ival << str1; - } - else { - s << *p[0].rect << (TQ_INT16)p[1].ival << *p[2].str; - } - br = *p[0].rect; - break; - case PdcDrawPixmap: - if ( formatMajor < 4 ) { - s << *p[0].point; - s << *p[1].pixmap; - br = TQRect( *p[0].point, p[1].pixmap->size() ); - } else { - s << *p[0].rect; - s << *p[1].pixmap; - br = *p[0].rect; - } - break; - case PdcDrawImage: - if ( formatMajor < 4 ) { - TQPoint pt( p[0].point->x(), p[0].point->y() ); - s << pt; - s << *p[1].image; - br = TQRect( *p[0].point, p[1].image->size() ); - } else { - s << *p[0].rect; - s << *p[1].image; - br = *p[0].rect; - } - break; - case PdcSave: - case PdcRestore: - break; - case PdcSetBkColor: - s << *p[0].color; - break; - case PdcSetBkMode: - case PdcSetROP: - s << (TQ_INT8)p[0].ival; - break; - case PdcSetFont: { - TQFont fnt = *p[0].font; - if (fnt.pointSize() > 0) - // we have to store pixels to get correct replay. - // the resolution is 72 dpi, so points == pixels - fnt.setPixelSize(TQFontInfo(fnt).pixelSize()); - s << fnt; - } - break; - case PdcSetPen: - s << *p[0].pen; - break; - case PdcSetBrush: - s << *p[0].brush; - break; - case PdcSetTabStops: - s << (TQ_INT16)p[0].ival; - break; - case PdcSetTabArray: - s << (TQ_INT16)p[0].ival; - if ( p[0].ival ) { - int *ta = p[1].ivec; - for ( int i=0; ipen().width() / 2; - br.setCoords( br.left() - w2, br.top() - w2, - br.right() + w2, br.bottom() + w2 ); - } -#ifndef TQT_NO_TRANSFORMATIONS - br = pt->worldMatrix().map( br ); -#endif - if ( pt->hasClipping() ) { - TQRect cr = pt->clipRegion().boundingRect(); - br &= cr; - } - if ( br.isValid() ) - brect |= br; // merge with existing rect - } - - return TRUE; -} - - -/*! - Internal implementation of the virtual TQPaintDevice::metric() - function. - - Use the TQPaintDeviceMetrics class instead. - - A picture has the following hard-coded values: dpi=72, - numcolors=16777216 and depth=24. - - \a m is the metric to get. -*/ - -int TQPicture::metric( int m ) const -{ - int val; - switch ( m ) { - // ### hard coded dpi and color depth values ! - case TQPaintDeviceMetrics::PdmWidth: - val = d->brect.width(); - break; - case TQPaintDeviceMetrics::PdmHeight: - val = d->brect.height(); - break; - case TQPaintDeviceMetrics::PdmWidthMM: - val = int(25.4/72.0*d->brect.width()); - break; - case TQPaintDeviceMetrics::PdmHeightMM: - val = int(25.4/72.0*d->brect.height()); - break; - case TQPaintDeviceMetrics::PdmDpiX: - case TQPaintDeviceMetrics::PdmPhysicalDpiX: - val = 72; - break; - case TQPaintDeviceMetrics::PdmDpiY: - case TQPaintDeviceMetrics::PdmPhysicalDpiY: - val = 72; - break; - case TQPaintDeviceMetrics::PdmNumColors: - val = 16777216; - break; - case TQPaintDeviceMetrics::PdmDepth: - val = 24; - break; - default: - val = 0; -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPicture::metric: Invalid metric command" ); -#endif - } - return val; -} - -/*! - Detaches from shared picture data and makes sure that this picture - is the only one referring to the data. - - If multiple pictures share common data, this picture makes a copy - of the data and detaches itself from the sharing mechanism. - Nothing is done if there is just a single reference. -*/ - -void TQPicture::detach() -{ - if ( d->count != 1 ) - *this = copy(); -} - -/*! - Returns a \link shclass.html deep copy\endlink of the picture. -*/ - -TQPicture TQPicture::copy() const -{ - TQPicture p; - TQByteArray a( size() ); - memcpy( a.data(), data(), size() ); - p.d->pictb.setBuffer( a ); // set byte array in buffer - if ( d->pictb.isOpen() ) { // copy buffer state - p.d->pictb.open( d->pictb.mode() ); - p.d->pictb.at( d->pictb.at() ); - } - p.d->trecs = d->trecs; - p.d->formatOk = d->formatOk; - p.d->formatMinor = d->formatMajor; - p.d->brect = boundingRect(); - return p; -} - -/***************************************************************************** - TQPainter member functions - *****************************************************************************/ - -/*! - Replays the picture \a pic translated by (\a x, \a y). - - This function does exactly the same as TQPicture::play() when - called with (\a x, \a y) = (0, 0). -*/ - -void TQPainter::drawPicture( int x, int y, const TQPicture &pic ) -{ - save(); - translate( x, y ); - ((TQPicture*)&pic)->play( (TQPainter*)this ); - restore(); -} - -/*! - \overload void TQPainter::drawPicture( const TQPoint &p, const TQPicture &pic ) - - Draws picture \a pic at point \a p. -*/ - -void TQPainter::drawPicture( const TQPoint &p, const TQPicture &pic ) -{ - drawPicture( p.x(), p.y(), pic ); -} - -/*! - \obsolete - - Use one of the other TQPainter::drawPicture() functions with a (0, 0) - offset instead. -*/ - -void TQPainter::drawPicture( const TQPicture &pic ) -{ - drawPicture( 0, 0, pic ); -} - -/*! - Assigns a \link shclass.html shallow copy\endlink of \a p to this - picture and returns a reference to this picture. -*/ - -TQPicture& TQPicture::operator= (const TQPicture& p) -{ - p.d->ref(); // avoid 'x = x' - if ( d->deref() ) - delete d; - d = p.d; - return *this; -} - - -/*! - \internal - - Sets formatOk to FALSE and resets the format version numbers to default -*/ - -void TQPicture::TQPicturePrivate::resetFormat() -{ - formatOk = FALSE; - formatMajor = mfhdr_maj; - formatMinor = mfhdr_min; -} - -/*! - \internal - - Checks data integrity and format version number. Set formatOk to TRUE - on success, to FALSE otherwise. Returns the resulting formatOk value. -*/ - -bool TQPicture::TQPicturePrivate::checkFormat() -{ - resetFormat(); - - // can't check anything in an empty buffer - if ( pictb.size() == 0 ) - return FALSE; - - pictb.open( IO_ReadOnly ); // open buffer device - TQDataStream s; - s.setDevice( &pictb ); // attach data stream to buffer - - char mf_id[4]; // picture header tag - s.readRawBytes( mf_id, 4 ); // read actual tag - if ( memcmp(mf_id, mfhdr_tag, 4) != 0 ) { // wrong header id -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPicture::checkFormat: Incorrect header" ); -#endif - pictb.close(); - return FALSE; - } - - int cs_start = sizeof(TQ_UINT32); // pos of checksum word - int data_start = cs_start + sizeof(TQ_UINT16); - TQ_UINT16 cs,ccs; - TQByteArray buf = pictb.buffer(); // pointer to data - s >> cs; // read checksum - ccs = tqChecksum( buf.data() + data_start, buf.size() - data_start ); - if ( ccs != cs ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPicture::checkFormat: Invalid checksum %x, %x expected", - ccs, cs ); -#endif - pictb.close(); - return FALSE; - } - - TQ_UINT16 major, minor; - s >> major >> minor; // read version number - if ( major > mfhdr_maj ) { // new, incompatible version -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPicture::checkFormat: Incompatible version %d.%d", - major, minor); -#endif - pictb.close(); - return FALSE; - } - s.setVersion( major != 4 ? major : 3 ); - - TQ_UINT8 c, clen; - s >> c >> clen; - if ( c == PdcBegin ) { - if ( !( major >= 1 && major <= 3 )) { - TQ_INT32 l, t, w, h; - s >> l >> t >> w >> h; - brect = TQRect( l, t, w, h ); - } - } else { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPicture::checkFormat: Format error" ); -#endif - pictb.close(); - return FALSE; - } - pictb.close(); - - formatOk = TRUE; // picture seems to be ok - formatMajor = major; - formatMinor = minor; - return TRUE; -} - -/***************************************************************************** - TQPicture stream functions - *****************************************************************************/ - -/*! - \relates TQPicture - - Writes picture \a r to the stream \a s and returns a reference to - the stream. -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQPicture &r ) -{ - TQ_UINT32 size = r.d->pictb.buffer().size(); - s << size; - // null picture ? - if ( size == 0 ) - return s; - // just write the whole buffer to the stream - return s.writeRawBytes ( r.d->pictb.buffer().data(), - r.d->pictb.buffer().size() ); -} - -/*! - \relates TQPicture - - Reads a picture from the stream \a s into picture \a r and returns - a reference to the stream. -*/ - -TQDataStream &operator>>( TQDataStream &s, TQPicture &r ) -{ - TQDataStream sr; - - // "init"; this code is similar to the beginning of TQPicture::cmd() - sr.setDevice( &r.d->pictb ); - sr.setVersion( r.d->formatMajor ); - TQ_UINT32 len; - s >> len; - TQByteArray data( len ); - if ( len > 0 ) - s.readRawBytes( data.data(), len ); - - r.d->pictb.setBuffer( data ); - r.d->resetFormat(); - - return s; -} - -#endif // TQT_NO_PICTURE - diff --git a/src/kernel/qpixmap.cpp b/src/kernel/qpixmap.cpp deleted file mode 100644 index 148b06da6..000000000 --- a/src/kernel/qpixmap.cpp +++ /dev/null @@ -1,1510 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPixmap class -** -** Created : 950301 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpixmap.h" - -#include "tqbitmap.h" -#include "tqimage.h" -#include "tqwidget.h" -#include "tqpainter.h" -#include "tqdatastream.h" -#include "tqbuffer.h" -#include "tqobjectlist.h" -#include "ntqapplication.h" -#include -#include "tqmime.h" -#include "tqdragobject.h" -#include "tqfile.h" - -/*! - \class TQPixmap ntqpixmap.h - \brief The TQPixmap class is an off-screen, pixel-based paint device. - - \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 mask with createHeuristicMask() and setMask(). Use - selfMask() to see if the pixmap is identical to its mask. - - 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 contains 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 contains 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 device 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(QT_CHECK_STATE) - if ( !abs_name.isEmpty() ) - tqWarning( "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(QT_CHECK_STATE) - tqWarning("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(Q_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) - tqWarning("TQPixmap::resize: TODO: resize alpha data"); - else -#endif // TQ_WS_X11 - if ( data->mask ) { // resize mask as well - if ( data->selfmask ) { // preserve self-mask - pm.setMask( *((TQBitmap*)&pm) ); - } else { // independent mask - TQBitmap m = *data->mask; - m.resize( w, h ); - pm.setMask( m ); - } - } - *this = pm; -} - - -/*! - \fn const TQBitmap *TQPixmap::mask() const - - Returns the mask bitmap, or 0 if no mask has been set. - - \sa setMask(), TQBitmap, hasAlpha() -*/ - -/*! - Sets a mask bitmap. - - The \a newmask bitmap defines the clip mask for this pixmap. Every - pixel in \a newmask corresponds to a pixel in this pixmap. Pixel - value 1 means opaque and pixel value 0 means transparent. The mask - must have the same size as this pixmap. - - \warning Setting the mask 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.mask() ); - \endcode - Now, alpha and alphacopy are visually different. - - Setting a \link isNull() null\endlink mask resets the mask. - - \sa mask(), createHeuristicMask(), TQBitmap -*/ - -void TQPixmap::setMask( const TQBitmap &newmask ) -{ - const TQPixmap *tmp = &newmask; // dec cxx bug - if ( (data == tmp->data) || - ( newmask.handle() && newmask.handle() == handle() ) ) { - TQPixmap m = tmp->copy( TRUE ); - setMask( *((TQBitmap*)&m) ); - data->selfmask = TRUE; // mask == pixmap - return; - } - - if ( newmask.isNull() ) { // reset the mask - if (data->mask) { - detach(); - data->selfmask = FALSE; - - delete data->mask; - data->mask = 0; - } - return; - } - - detach(); - data->selfmask = FALSE; - - if ( newmask.width() != width() || newmask.height() != height() ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPixmap::setMask: The pixmap and the mask must have " - "the same size" ); -#endif - return; - } -#if defined(TQ_WS_MAC) || (defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)) - // when setting the mask, we get rid of the alpha channel completely - delete data->alphapm; - data->alphapm = 0; -#endif // TQ_WS_X11 && !TQT_NO_XFTFREETYPE - - delete data->mask; - TQBitmap* newmaskcopy; - if ( newmask.mask() ) - newmaskcopy = (TQBitmap*)new TQPixmap( tmp->copy( TRUE ) ); - else - newmaskcopy = new TQBitmap( newmask ); -#ifdef TQ_WS_X11 - newmaskcopy->x11SetScreen( x11Screen() ); -#endif - data->mask = newmaskcopy; -} - - -/*! - \fn bool TQPixmap::selfMask() const - - Returns TRUE if the pixmap's mask is identical to the pixmap - itself; otherwise returns FALSE. - - \sa mask() -*/ - -#ifndef TQT_NO_IMAGE_HEURISTIC_MASK -/*! - Creates and returns a heuristic mask 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 mask 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 mask is just large enough to cover the - pixels; otherwise, the mask 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 device. 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* device, const char* format, int quality ) const -{ - if ( isNull() ) - return FALSE; // nothing to save - TQImageIO io( device, format ); - return doImageIO( &io, quality ); -} - -/*! \internal -*/ - -bool TQPixmap::doImageIO( TQImageIO* io, int quality ) const -{ - if ( !io ) - return FALSE; - io->setImage( convertToImage() ); -#if defined(QT_CHECK_RANGE) - if ( quality > 100 || quality < -1 ) - tqWarning( "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 ); - - const TQObjectList * children = w->children(); - if ( children ) { - TQPainter p( &res ); - TQObjectListIt it( *children ); - TQObject * child; - while( (child=it.current()) != 0 ) { - ++it; - if ( child->isWidgetType() && - !((TQWidget *)child)->isHidden() && - !((TQWidget *)child)->isTopLevel() && - ((TQWidget *)child)->geometry().intersects( w->rect() ) ) { - // those conditions aren't quite right, it's possible - // to have a grandchild completely outside its - // grandparent, but partially inside its parent. 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 children, 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 - children 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 contains 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>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 QT_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 QT_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 QT_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 diff --git a/src/kernel/qpixmap_x11.cpp b/src/kernel/qpixmap_x11.cpp deleted file mode 100644 index 1b5be8410..000000000 --- a/src/kernel/qpixmap_x11.cpp +++ /dev/null @@ -1,2482 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPixmap class for X11 -** -** Created : 940501 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "qplatformdefs.h" - -#if defined(Q_OS_WIN32) && defined(QT_MITSHM) -#undef QT_MITSHM -#endif - -#ifdef QT_MITSHM - -// Use the MIT Shared Memory extension for pixmap<->image conversions -#define QT_MITSHM_CONVERSIONS - -// Uncomment the next line to enable the MIT Shared Memory extension -// for TQPixmap::xForm() -// -// WARNING: This has some problems: -// -// 1. Consumes a 800x600 pixmap -// 2. TQt does not handle the ShmCompletion message, so you will -// get strange effects if you xForm() repeatedly. -// -// #define QT_MITSHM_XFORM - -#else -#undef QT_MITSHM_CONVERSIONS -#undef QT_MITSHM_XFORM -#endif - -#include "tqbitmap.h" -#include "tqpaintdevicemetrics.h" -#include "tqimage.h" -#include "ntqwmatrix.h" -#include "ntqapplication.h" -#include "qt_x11_p.h" - -#include - -#if defined(Q_CC_MIPS) -# define for if(0){}else for -#endif - - -/*! - \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(QT_MITSHM_XFORM) - -static bool xshminit = FALSE; -static XShmSegmentInfo xshminfo; -static XImage *xshmimg = 0; -static Pixmap xshmpm = 0; - -static void tqt_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 ) { - tqt_cleanup_mitshm(); - } else { - if ( !XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok) ) - return FALSE; // MIT Shm not supported - tqAddPostRoutine( tqt_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 // QT_MITSHM_XFORM - -#ifdef QT_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 QT_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 QT_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 QT_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 // QT_MITSHM_CONVERSIONS - -/***************************************************************************** - Internal functions - *****************************************************************************/ - -extern const uchar *qt_get_bitflip_array(); // defined in tqimage.cpp - -static uchar *flip_bits( const uchar *bits, int len ) -{ - 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(QT_CHECK_RANGE) - tqWarning( "build_scale_table: internal error, nBits = %i", nBits ); -#endif - return; - } - if (!*table) { - static bool firstTable = TRUE; - if ( firstTable ) { - tqAddPostRoutine( 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 tqt_use_xrender; // defined in qapplication_x11.cpp -extern bool tqt_has_xft; // defined in tqfont_x11.cpp - -#ifndef TQT_NO_XFTFREETYPE -#ifndef QT_XFT2 -// Xft1 doesn't have XftDrawCreateAlpha, so we fake it in qtaddons_x11.cpp -extern "C" XftDraw *XftDrawCreateAlpha( Display *, TQt::HANDLE, int ); -#endif // QT_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(QT_CHECK_STATE) - if ( tqApp->type() == TQApplication::Tty ) { - tqWarning( "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(QT_CHECK_RANGE) - if ( !make_null ) - tqWarning( "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 ( tqt_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 ( tqt_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 = tqt_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(QT_CHECK_RANGE) - tqWarning( "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 QT_MITSHM_CONVERSIONS - bool mitshm_ximage = false; - XShmSegmentInfo shminfo; -#endif - if ( !xi ) { // fetch data from X server -#ifdef QT_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 QT_MITSHM_CONVERSIONS - if( mitshm_ximage ) - qt_XShmDestroyImage( xi, &shminfo ); - else -#endif - qSafeXDestroyImage( xi ); - ((TQPixmap*)this)->data->ximage = 0; - return image; - } - - const TQPixmap* msk = mask(); - const TQPixmap *alf = data->alphapm; - - TQImage alpha; - if (alf) { - XImage* axi; -#ifdef QT_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 QT_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; ydata + xi->bytes_per_line*y; - for ( int x=0; x 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; ybytes_per_line; - } - } else { - /* Typically 2 or 4 bits display depth */ -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPixmap::convertToImage: Display not supported (bpp=%d)", - xi->bits_per_pixel ); -#endif - image.reset(); -#ifdef QT_MITSHM_CONVERSIONS - if( mitshm_ximage ) - qt_XShmDestroyImage( xi, &shminfo ); - else -#endif - qSafeXDestroyImage( xi ); - ((TQPixmap*)this)->data->ximage = 0; - 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 - 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> 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> 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 QT_MITSHM_CONVERSIONS - if( mitshm_ximage ) - qt_XShmDestroyImage( xi, &shminfo ); - else -#endif - qSafeXDestroyImage( xi ); - ((TQPixmap*)this)->data->ximage = 0; - } else { // keep ximage data -#ifdef QT_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(QT_CHECK_NULL) - tqWarning( "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 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; yw = 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; -#ifdef QT_MITSHM_CONVERSIONS - int newbits_size = 0; - 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 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 QT_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 8 && xi->byte_order == LSBFirst ) - bppc++; - - int wordsize; - bool bigendian; - tqSysInfo( &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 - tqFatal("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< thres) \ - r += (1<<(8-rbits)); \ - if ( g <= (255-(1<<(8-gbits))) && ((g< thres) \ - g += (1<<(8-gbits)); \ - if ( b <= (255-(1<<(8-bbits))) && ((b< 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 = (r & red_mask)|(g & green_mask) | (b & blue_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< thres) \ - r += (1<<(8-rbits)); \ - int g = tqGreen( *p ); \ - if ( g <= (255-(1<<(8-gbits))) && ((g< thres) \ - g += (1<<(8-gbits)); \ - int b = tqBlue ( *p++ ); \ - if ( b <= (255-(1<<(8-bbits))) && ((b< 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; ybytes_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>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>3,0x7c00,0x3e0,0x1f,5,5,5) - *dst16++ = pixel; - } - ) - break; - case BPP16_MSB: // 16 bit MSB - CYCLE( - for ( uint x=0; x> 8); - *dst++ = pixel; - } - ) - break; - case BPP16_LSB: // 16 bit LSB - CYCLE( - for ( uint x=0; x> 8; - } - ) - break; - default: - tqFatal("Logic error"); - } - } else { - switch ( mode ) { - case BPP8: // 8 bit - CYCLE( - Q_UNUSED(p); - for ( uint x=0; x>3,0xf800,0x7e0,0x1f) - *dst16++ = pixel; - } - ) - break; - case BPP16_7_2_M3: - CYCLE( - TQ_INT16* dst16 = (TQ_INT16*)dst; - for ( uint x=0; x>3,0x7c00,0x3e0,0x1f) - *dst16++ = pixel; - } - ) - break; - case BPP16_MSB: // 16 bit MSB - CYCLE( - for ( uint x=0; x> 8); - *dst++ = pixel; - } - ) - break; - case BPP16_LSB: // 16 bit LSB - CYCLE( - for ( uint x=0; x> 8; - } - ) - break; - case BPP24_MSB: // 24 bit MSB - CYCLE( - for ( uint x=0; x> 16; - *dst++ = pixel >> 8; - *dst++ = pixel; - } - ) - break; - case BPP24_LSB: // 24 bit LSB - CYCLE( - for ( uint x=0; x> 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> 24; - *dst++ = pixel >> 16; - *dst++ = pixel >> 8; - *dst++ = pixel; - } - ) - break; - case BPP32_LSB: // 32 bit LSB - CYCLE( - for ( uint x=0; x> 8; - *dst++ = pixel >> 16; - *dst++ = pixel >> 24; - } - ) - break; - default: - tqFatal("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 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; juse ) { - 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; juse ) { - 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 ) { // X image not created -#ifdef QT_MITSHM_CONVERSIONS - xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo ); - if( xi != NULL ) - mitshm_ximage = true; - else -#endif - 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 ); -#ifdef QT_MITSHM_CONVERSIONS - newbits_size = xi->bytes_per_line * h; -#endif - TQ_CHECK_PTR( newerbits ); - if ( !newerbits ) // no memory - return FALSE; - uchar* p = newbits; - for ( uint y=0; ybits_per_pixel != 8 ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPixmap::convertFromImage: Display not supported " - "(bpp=%d)", xi->bits_per_pixel ); -#endif - } -#ifdef QT_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 ( tqt_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 QT_MITSHM_CONVERSIONS - if( mitshm_ximage ) - XShmPutImage( dpy, hd, tqt_xget_readonly_gc( x11Screen(), FALSE ), - xi, 0, 0, 0, 0, w, h, False ); - else -#endif - XPutImage( dpy, hd, tqt_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 QT_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 (tqt_use_xrender && tqt_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 QT_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 QT_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 QT_MITSHM_CONVERSIONS - if( mitshm_ximage || mitshm_aximage ) - XSync( x11Display(), False ); // wait until processed -#endif - - if ( data->optim != BestOptim ) { // throw away image -#ifdef QT_MITSHM_CONVERSIONS - if( mitshm_ximage ) - qt_XShmDestroyImage( xi, &shminfo ); - else -#endif - qSafeXDestroyImage( xi ); - data->ximage = 0; - } else { // keep ximage that we created -#ifdef QT_MITSHM_CONVERSIONS - if( mitshm_ximage ) { // copy the XImage? - qt_XShmDestroyImage( xi, &shminfo ); - xi = 0; - } -#endif - data->ximage = xi; - } - if( axi ) { -#ifdef QT_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 = tqt_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(QT_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(QT_MITSHM_XFORM) - if ( use_mitshm ) { - dptr = (uchar *)xshmimg->data; - uchar fillbyte = bpp == 8 ? white.pixel() : 0xff; - for ( int y=0; ybytes_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(QT_MITSHM_XFORM) - } -#endif - - // #define QT_DEBUG_XIMAGE -#if defined(QT_DEBUG_XIMAGE) - tqDebug( "----IMAGE--INFO--------------" ); - tqDebug( "width............. %d", xi->width ); - tqDebug( "height............ %d", xi->height ); - tqDebug( "xoffset........... %d", xi->xoffset ); - tqDebug( "format............ %d", xi->format ); - tqDebug( "byte order........ %d", xi->byte_order ); - tqDebug( "bitmap unit....... %d", xi->bitmap_unit ); - tqDebug( "bitmap bit order.. %d", xi->bitmap_bit_order ); - tqDebug( "depth............. %d", xi->depth ); - tqDebug( "bytes per line.... %d", xi->bytes_per_line ); - tqDebug( "bits per pixel.... %d", xi->bits_per_pixel ); -#endif - - int type; - if ( xi->bitmap_bit_order == MSBFirst ) - type = QT_XFORM_TYPE_MSBFIRST; - else - type = QT_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(QT_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(QT_CHECK_RANGE) - tqWarning( "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 = tqt_xget_readonly_gc( x11Screen(), FALSE ); - TQPixmap pm( w, h ); - pm.data->uninit = FALSE; - pm.x11SetScreen( x11Screen() ); -#if defined(QT_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(QT_MITSHM_XFORM) - } -#endif - - if ( data->mask ) // xform mask, too - pm.setMask( data->mask->xForm(matrix) ); - -#ifndef TQT_NO_XFTFREETYPE - if ( tqt_use_xrender && tqt_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 = QT_XFORM_TYPE_MSBFIRST; - else - type = QT_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 - tqDebug("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 QT_CHECK_NULL - Q_ASSERT( dst != 0 ); - Q_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 tqt_use_xrender; // from qapplication_x11.cpp - if ( ! tqt_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 -} diff --git a/src/kernel/qpixmapcache.cpp b/src/kernel/qpixmapcache.cpp deleted file mode 100644 index 9eb09466c..000000000 --- a/src/kernel/qpixmapcache.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPixmapCache class -** -** Created : 950504 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpixmapcache.h" -#include "tqcache.h" -#include "tqobject.h" -#include "ntqcleanuphandler.h" - - -// REVISED: paul -/*! - \class TQPixmapCache ntqpixmapcache.h - - \brief The TQPixmapCache class provides an application-global cache for - pixmaps. - - \ingroup environment - \ingroup graphics - \ingroup images - - This class is a tool for optimized drawing with TQPixmap. You can - use it to store temporary pixmaps that are expensive to generate - without using more storage space than cacheLimit(). Use insert() - to insert pixmaps, find() to find them and clear() to empty the - cache. - - For example, TQRadioButton has a non-trivial visual representation - so we don't want to regenerate a pixmap whenever a radio button is - displayed or changes state. In the function - TQRadioButton::drawButton(), we do not draw the radio button - directly. Instead, we first check the global pixmap cache for a - pixmap with the key "$qt_radio_nnn_", where \c nnn is a numerical - value that specifies the the radio button state. If a pixmap is - found, we bitBlt() it onto the widget and return. Otherwise, we - create a new pixmap, draw the radio button in the pixmap, and - finally insert the pixmap in the global pixmap cache, using the - key above. The bitBlt() is ten times faster than drawing the - radio button. All radio buttons in the program share the cached - pixmap since TQPixmapCache is application-global. - - TQPixmapCache contains no member data, only static functions to - access the global pixmap cache. It creates an internal TQCache for - caching the pixmaps. - - The cache associates a pixmap with a string (key). If two pixmaps - are inserted into the cache using equal keys, then the last pixmap - will hide the first pixmap. The TQDict and TQCache classes do - exactly the same. - - The cache becomes full when the total size of all pixmaps in the - cache exceeds cacheLimit(). The initial cache limit is 1024 KByte - (1 MByte); it is changed with setCacheLimit(). A pixmap takes - roughly width*height*depth/8 bytes of memory. - - See the \l TQCache documentation for more details about the cache - mechanism. -*/ - - -static const int cache_size = 149; // size of internal hash array -#ifdef TQ_WS_MAC9 -static int cache_limit = 256; // 256 KB cache limit -#else -static int cache_limit = 1024; // 1024 KB cache limit -#endif - -class TQPMCache: public TQObject, public TQCache -{ -public: - TQPMCache(): - TQObject( 0, "global pixmap cache" ), - TQCache( cache_limit * 1024, cache_size ), - id( 0 ), ps( 0 ), t( FALSE ) - { - setAutoDelete( TRUE ); - } - ~TQPMCache() {} - void timerEvent( TQTimerEvent * ); - bool insert( const TQString& k, const TQPixmap *d, int c, int p = 0 ); -private: - int id; - int ps; - bool t; -}; - - -/* - This is supposed to cut the cache size down by about 80-90% in a - minute once the application becomes idle, to let any inserted pixmap - remain in the cache for some time before it becomes a candidate for - cleaning-up, and to not cut down the size of the cache while the - cache is in active use. - - When the last pixmap has been deleted from the cache, kill the - timer so TQt won't keep the CPU from going into sleep mode. -*/ - -void TQPMCache::timerEvent( TQTimerEvent * ) -{ - int mc = maxCost(); - bool nt = totalCost() == ps; - setMaxCost( nt ? totalCost() * 3 / 4 : totalCost() -1 ); - setMaxCost( mc ); - ps = totalCost(); - - if ( !count() ) { - killTimer( id ); - id = 0; - } else if ( nt != t ) { - killTimer( id ); - id = startTimer( nt ? 10000 : 30000 ); - t = nt; - } -} - -bool TQPMCache::insert( const TQString& k, const TQPixmap *d, int c, int p ) -{ - bool r = TQCache::insert( k, d, c, p ); - if ( r && !id ) { - id = startTimer( 30000 ); - t = FALSE; - } - return r; -} - -static TQPMCache *pm_cache = 0; // global pixmap cache - -static TQSingleCleanupHandler qpm_cleanup_cache; - -/*! - Returns the pixmap associated with the \a key in the cache, or - null if there is no such pixmap. - - \warning If valid, you should copy the pixmap immediately (this is - fast). Subsequent insertions into the cache could cause the - pointer to become invalid. For this reason, we recommend you use - find(const TQString&, TQPixmap&) instead. - - Example: - \code - TQPixmap* pp; - TQPixmap p; - if ( (pp=TQPixmapCache::find("my_big_image", pm)) ) { - p = *pp; - } else { - p.load("bigimage.png"); - TQPixmapCache::insert("my_big_image", new TQPixmap(p)); - } - painter->drawPixmap(0, 0, p); - \endcode -*/ - -TQPixmap *TQPixmapCache::find( const TQString &key ) -{ - return pm_cache ? pm_cache->find(key) : 0; -} - - -/*! - \overload - - Looks for a cached pixmap associated with the \a key in the cache. - If a pixmap is found, the function sets \a pm to that pixmap and - returns TRUE; otherwise leaves \a pm alone and returns FALSE. - - Example: - \code - TQPixmap p; - if ( !TQPixmapCache::find("my_big_image", pm) ) { - pm.load("bigimage.png"); - TQPixmapCache::insert("my_big_image", pm); - } - painter->drawPixmap(0, 0, p); - \endcode -*/ - -bool TQPixmapCache::find( const TQString &key, TQPixmap& pm ) -{ - TQPixmap* p = pm_cache ? pm_cache->find(key) : 0; - if ( p ) pm = *p; - return !!p; -} - - -/*! - \obsolete - Inserts the pixmap \a pm associated with \a key into the cache. - Returns TRUE if successful, or FALSE if the pixmap is too big for the cache. - - - Note: \a pm must be allocated on the heap (using \c new). - - If this function returns FALSE, you must delete \a pm yourself. - - If this function returns TRUE, do not use \a pm afterwards or - keep references to it because any other insertions into the cache, - whether from anywhere in the application or within TQt itself, could cause - the pixmap to be discarded from the cache and the pointer to - become invalid. - - Due to these dangers, we strongly recommend that you use - insert(const TQString&, const TQPixmap&) instead. - -*/ - -bool TQPixmapCache::insert( const TQString &key, TQPixmap *pm ) -{ - if ( !pm_cache ) { // create pixmap cache - pm_cache = new TQPMCache; - TQ_CHECK_PTR( pm_cache ); - qpm_cleanup_cache.set( &pm_cache ); - } - return pm_cache->insert( key, pm, pm->width()*pm->height()*pm->depth()/8 ); -} - -/*! - Inserts a copy of the pixmap \a pm associated with the \a key into - the cache. - - All pixmaps inserted by the TQt library have a key starting with - "$qt", so your own pixmap keys should never begin "$qt". - - When a pixmap is inserted and the cache is about to exceed its - limit, it removes pixmaps until there is enough room for the - pixmap to be inserted. - - The oldest pixmaps (least recently accessed in the cache) are - deleted when more space is needed. - - \sa setCacheLimit(). -*/ - -bool TQPixmapCache::insert( const TQString &key, const TQPixmap& pm ) -{ - if ( !pm_cache ) { // create pixmap cache - pm_cache = new TQPMCache; - TQ_CHECK_PTR( pm_cache ); - qpm_cleanup_cache.set( &pm_cache ); - } - TQPixmap *p = new TQPixmap(pm); - bool rt = pm_cache->insert( key, p, p->width()*p->height()*p->depth()/8 ); - if ( !rt ) - delete p; - - return rt; -} - -/*! - Returns the cache limit (in kilobytes). - - The default setting is 1024 kilobytes. - - \sa setCacheLimit(). -*/ - -int TQPixmapCache::cacheLimit() -{ - return cache_limit; -} - -/*! - Sets the cache limit to \a n kilobytes. - - The default setting is 1024 kilobytes. - - \sa cacheLimit() -*/ - -void TQPixmapCache::setCacheLimit( int n ) -{ -#ifdef TQ_WS_MAC9 - if(n > 256) - tqWarning("TQPixmapCache::setCacheLimit: Setting cache limits high is harmfull to mac9's health"); -#endif - cache_limit = n; - if ( pm_cache ) - pm_cache->setMaxCost( 1024*cache_limit ); -} - - -/*! - Removes the pixmap associated with \a key from the cache. -*/ -void TQPixmapCache::remove( const TQString &key ) -{ - if ( pm_cache ) - pm_cache->remove( key ); -} - - -/*! - Removes all pixmaps from the cache. -*/ - -void TQPixmapCache::clear() -{ - if ( pm_cache ) - pm_cache->clear(); -} diff --git a/src/kernel/qpngio.cpp b/src/kernel/qpngio.cpp deleted file mode 100644 index c2db400ac..000000000 --- a/src/kernel/qpngio.cpp +++ /dev/null @@ -1,1351 +0,0 @@ -/**************************************************************************** -** -** Implementation of PNG TQImage IOHandler -** -** Created : 970521 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpngio.h" - -#ifndef TQT_NO_IMAGEIO_PNG - -#include "ntqasyncimageio.h" -#include "tqiodevice.h" - -#include -#if PNG_LIBPNG_VER>=10500 -#include -#endif /* LIBPNG 1.5 */ - - -#ifdef Q_OS_TEMP -#define CALLBACK_CALL_TYPE __cdecl -#else -#define CALLBACK_CALL_TYPE -#endif - - -/* - All PNG files load to the minimal TQImage equivalent. - - All TQImage formats output to reasonably efficient PNG equivalents. - Never to grayscale. -*/ - -#if defined(Q_C_CALLBACKS) -extern "C" { -#endif - -static -void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) -{ - TQImageIO* iio = (TQImageIO*)png_get_io_ptr(png_ptr); - TQIODevice* in = iio->ioDevice(); - - while (length) { - int nr = in->readBlock((char*)data, length); - if (nr <= 0) { - png_error(png_ptr, "Read Error"); - return; - } - length -= nr; - } -} - - -static -void CALLBACK_CALL_TYPE qpiw_write_fn( png_structp png_ptr, png_bytep data, png_size_t length ) -{ - TQPNGImageWriter* qpiw = (TQPNGImageWriter*)png_get_io_ptr( png_ptr ); - TQIODevice* out = qpiw->device(); - - uint nr = out->writeBlock( (char*)data, length ); - if ( nr != length ) { - png_error( png_ptr, "Write Error" ); - return; - } -} - - -static -void CALLBACK_CALL_TYPE qpiw_flush_fn( png_structp png_ptr ) -{ - TQPNGImageWriter* qpiw = (TQPNGImageWriter*)png_get_io_ptr( png_ptr ); - TQIODevice* out = qpiw->device(); - - out->flush(); -} - -#if defined(Q_C_CALLBACKS) -} -#endif - -static -void setup_qt( TQImage& image, png_structp png_ptr, png_infop info_ptr, float screen_gamma=0.0 ) -{ - if ( screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) ) { - double file_gamma; - png_get_gAMA(png_ptr, info_ptr, &file_gamma); - png_set_gamma( png_ptr, screen_gamma, file_gamma ); - } - - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - -#if PNG_LIBPNG_VER>=10500 - png_colorp info_ptr_palette = NULL; - int info_ptr_num_palette = 0; - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { - png_get_PLTE(png_ptr, info_ptr, &info_ptr_palette, &info_ptr_num_palette); - } - - png_bytep info_ptr_trans_alpha = NULL; - int info_ptr_num_trans = 0; - png_color_16p info_ptr_trans_color = NULL; - - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_get_tRNS(png_ptr, info_ptr, &info_ptr_trans_alpha, &info_ptr_num_trans, &info_ptr_trans_color); - } -#endif /* LIBPNG 1.5 */ - - if ( color_type == PNG_COLOR_TYPE_GRAY ) { - // Black & White or 8-bit grayscale -#if PNG_LIBPNG_VER>=10500 - if ( bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1 ) { -#else /* LIBPNG 1.5 */ - if ( bit_depth == 1 && info_ptr->channels == 1 ) { -#endif /* LIBPNG 1.5 */ - png_set_invert_mono( png_ptr ); - png_read_update_info( png_ptr, info_ptr ); - if (!image.create( width, height, 1, 2, TQImage::BigEndian )) - return; - image.setColor( 1, tqRgb(0,0,0) ); - image.setColor( 0, tqRgb(255,255,255) ); - } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_set_expand(png_ptr); - png_set_strip_16(png_ptr); - png_set_gray_to_rgb(png_ptr); - - if (!image.create(width, height, 32)) - return; - image.setAlphaBuffer(TRUE); - - if (TQImage::systemByteOrder() == TQImage::BigEndian) - png_set_swap_alpha(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - } else { - if ( bit_depth == 16 ) - png_set_strip_16(png_ptr); - else if ( bit_depth < 8 ) - png_set_packing(png_ptr); - int ncols = bit_depth < 8 ? 1 << bit_depth : 256; - png_read_update_info(png_ptr, info_ptr); - if (!image.create(width, height, 8, ncols)) - return; - for (int i=0; i=10500 - const int g = info_ptr_trans_color->gray; -#elif PNG_LIBPNG_VER>=10400 - const int g = info_ptr->trans_color.gray; -#else - const int g = info_ptr->trans_values.gray; -#endif - if (g < ncols) { - image.setAlphaBuffer(TRUE); - image.setColor(g, image.color(g) & TQT_RGB_MASK); - } - } - } - } else if ( color_type == PNG_COLOR_TYPE_PALETTE - && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE) -#if PNG_LIBPNG_VER>=10500 - && info_ptr_num_palette <= 256 ) -#else /* LIBPNG 1.5 */ - && info_ptr->num_palette <= 256 ) -#endif /* LIBPNG 1.5 */ - { - // 1-bit and 8-bit color - if ( bit_depth != 1 ) - png_set_packing( png_ptr ); - png_read_update_info( png_ptr, info_ptr ); - png_get_IHDR(png_ptr, info_ptr, - &width, &height, &bit_depth, &color_type, 0, 0, 0); -#if PNG_LIBPNG_VER>=10500 - if (!image.create(width, height, bit_depth, info_ptr_num_palette, -#else /* LIBPNG 1.5 */ - if (!image.create(width, height, bit_depth, info_ptr->num_palette, -#endif /* LIBPNG 1.5 */ - TQImage::BigEndian)) - return; - int i = 0; - if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) { - image.setAlphaBuffer( TRUE ); - -#if PNG_LIBPNG_VER>=10500 - while ( i < info_ptr_num_trans ) { - image.setColor(i, tqRgba( - info_ptr_palette[i].red, - info_ptr_palette[i].green, - info_ptr_palette[i].blue, -#else /* LIBPNG 1.5 */ - while ( i < info_ptr->num_trans ) { - image.setColor(i, tqRgba( - info_ptr->palette[i].red, - info_ptr->palette[i].green, - info_ptr->palette[i].blue, -#endif /* LIBPNG 1.5 */ -#if PNG_LIBPNG_VER>=10500 - info_ptr_trans_alpha[i] -#elif PNG_LIBPNG_VER>=10400 - info_ptr->trans_alpha[i] -#else - info_ptr->trans[i] -#endif - ) - ); - i++; - } - } -#if PNG_LIBPNG_VER>=10500 - while ( i < info_ptr_num_palette ) { - image.setColor(i, tqRgba( - info_ptr_palette[i].red, - info_ptr_palette[i].green, - info_ptr_palette[i].blue, -#else /* LIBPNG 1.5 */ - while ( i < info_ptr->num_palette ) { - image.setColor(i, tqRgba( - info_ptr->palette[i].red, - info_ptr->palette[i].green, - info_ptr->palette[i].blue, -#endif /* LIBPNG 1.5 */ - 0xff - ) - ); - i++; - } - } else { - // 32-bit - if ( bit_depth == 16 ) - png_set_strip_16(png_ptr); - - png_set_expand(png_ptr); - - if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) - png_set_gray_to_rgb(png_ptr); - - if (!image.create(width, height, 32)) - return; - - // Only add filler if no alpha, or we can get 5 channel data. - if (!(color_type & PNG_COLOR_MASK_ALPHA) - && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - png_set_filler(png_ptr, 0xff, - TQImage::systemByteOrder() == TQImage::BigEndian ? - PNG_FILLER_BEFORE : PNG_FILLER_AFTER); - // We want 4 bytes, but it isn't an alpha channel - } else { - image.setAlphaBuffer(TRUE); - } - - if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { - png_set_swap_alpha(png_ptr); - } - - png_read_update_info(png_ptr, info_ptr); - } - - // TQt==ARGB==Big(ARGB)==Little(BGRA) - if ( TQImage::systemByteOrder() == TQImage::LittleEndian ) { - png_set_bgr(png_ptr); - } -} - - -#if defined(Q_C_CALLBACKS) -extern "C" { -#endif -static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const_charp message) -{ - tqWarning("libpng warning: %s", message); -} - -#if defined(Q_C_CALLBACKS) -} -#endif - - -static -void read_png_image(TQImageIO* iio) -{ - png_structp png_ptr; - png_infop info_ptr; - png_infop end_info; - png_bytep* row_pointers; - - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0); - if (!png_ptr) { - iio->setStatus(-1); - return; - } - - png_set_error_fn(png_ptr, 0, 0, qt_png_warning); - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, 0, 0); - iio->setStatus(-2); - return; - } - - end_info = png_create_info_struct(png_ptr); - if (!end_info) { - png_destroy_read_struct(&png_ptr, &info_ptr, 0); - iio->setStatus(-3); - return; - } - -#if PNG_LIBPNG_VER>=10500 - if (setjmp(png_jmpbuf(png_ptr))) { -#else /* LIBPNG 1.5 */ - if (setjmp(png_ptr->jmpbuf)) { -#endif /* LIBPNG 1.5 */ - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - iio->setStatus(-4); - return; - } - - png_set_read_fn(png_ptr, (void*)iio, iod_read_fn); - png_read_info(png_ptr, info_ptr); - - TQImage image; - setup_qt(image, png_ptr, info_ptr, iio->gamma()); - if (image.isNull()) { - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - iio->setStatus(-5); - return; - } - - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - - uchar** jt = image.jumpTable(); - row_pointers=new png_bytep[height]; - - for (uint y=0; y=10400 - (info_ptr->trans_color.red << 8 >> bit_depth)&0xff, - (info_ptr->trans_color.green << 8 >> bit_depth)&0xff, - (info_ptr->trans_color.blue << 8 >> bit_depth)&0xff); -#else - (info_ptr->trans_values.red << 8 >> bit_depth)&0xff, - (info_ptr->trans_values.green << 8 >> bit_depth)&0xff, - (info_ptr->trans_values.blue << 8 >> bit_depth)&0xff); -#endif - for (uint y=0; ywidth; x++) { - if (((uint**)jt)[y][x] == trans) { - ((uint**)jt)[y][x] &= 0x00FFFFFF; - } else { - } - } - } - } -#endif - - image.setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr)); - image.setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr)); - -#ifndef TQT_NO_IMAGE_TEXT - png_textp text_ptr; - int num_text=0; - png_get_text(png_ptr,info_ptr,&text_ptr,&num_text); - while (num_text--) { - image.setText(text_ptr->key,0,text_ptr->text); - text_ptr++; - } -#endif - - delete [] row_pointers; - - if ( image.hasAlphaBuffer() ) { - // Many PNG files lie (eg. from PhotoShop). Fortunately this loop will - // usually be quick to find those that tell the truth. - TQRgb* c; - int n; - if (image.depth()==32) { - c = (TQRgb*)image.bits(); - n = image.bytesPerLine() * image.height() / 4; - } else { - c = image.colorTable(); - n = image.numColors(); - } - while ( n-- && tqAlpha(*c++)==0xff ) - ; - if ( n<0 ) // LIAR! - image.setAlphaBuffer(FALSE); - } - - iio->setImage(image); - - png_read_end(png_ptr, end_info); - png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); - - iio->setStatus(0); -} - -TQPNGImageWriter::TQPNGImageWriter(TQIODevice* iod) : - dev(iod), - frames_written(0), - disposal(Unspecified), - looping(-1), - ms_delay(-1), - gamma(0.0) -{ -} - -TQPNGImageWriter::~TQPNGImageWriter() -{ -} - -void TQPNGImageWriter::setDisposalMethod(DisposalMethod dm) -{ - disposal = dm; -} - -void TQPNGImageWriter::setLooping(int loops) -{ - looping = loops; -} - -void TQPNGImageWriter::setFrameDelay(int msecs) -{ - ms_delay = msecs; -} - -void TQPNGImageWriter::setGamma(float g) -{ - gamma = g; -} - - -#ifndef TQT_NO_IMAGE_TEXT -static void set_text(const TQImage& image, png_structp png_ptr, png_infop info_ptr, bool short_not_long) -{ - TQValueList keys = image.textList(); - if ( keys.count() ) { - png_textp text_ptr = new png_text[keys.count()]; - int i=0; - for (TQValueList::Iterator it=keys.begin(); - it != keys.end(); ++it) - { - TQString t = image.text(*it); - if ( (t.length() <= 200) == short_not_long ) { - if ( t.length() < 40 ) - text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE; - else - text_ptr[i].compression = PNG_TEXT_COMPRESSION_zTXt; - text_ptr[i].key = (png_charp)(*it).key.data(); - text_ptr[i].text = (png_charp)t.latin1(); - //text_ptr[i].text = tqstrdup(t.latin1()); - i++; - } - } - png_set_text(png_ptr, info_ptr, text_ptr, i); - //for (int j=0; j=10500 - if (setjmp(png_jmpbuf(png_ptr))) { -#else /* LIBPNG 1.5 */ - if (setjmp(png_ptr->jmpbuf)) { -#endif /* LIBPNG 1.5 */ - png_destroy_write_struct(&png_ptr, &info_ptr); - return FALSE; - } - - int quality = quality_in; - if (quality >= 0) { - if (quality > 9) { -#if defined(QT_CHECK_RANGE) - tqWarning( "PNG: Quality %d out of range", quality ); -#endif - quality = 9; - } - png_set_compression_level(png_ptr, quality); - } - - if (gamma != 0.0) { - png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); - } - - png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); - - png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), - image.depth() == 1 ? 1 : 8 /* per channel */, - image.depth() == 32 - ? image.hasAlphaBuffer() - ? PNG_COLOR_TYPE_RGB_ALPHA - : PNG_COLOR_TYPE_RGB - : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); - -#if PNG_LIBPNG_VER>=10500 - png_color_8 sig_bit; - sig_bit.red = 8; - sig_bit.green = 8; - sig_bit.blue = 8; - png_set_sBIT(png_ptr, info_ptr, &sig_bit); -#else /* LIBPNG 1.5 */ - //png_set_sBIT(png_ptr, info_ptr, 8); - info_ptr->sig_bit.red = 8; - info_ptr->sig_bit.green = 8; - info_ptr->sig_bit.blue = 8; -#endif /* LIBPNG 1.5 */ - - if (image.depth() == 1 && image.bitOrder() == TQImage::LittleEndian) - png_set_packswap(png_ptr); - - png_colorp palette = 0; - png_bytep copy_trans = 0; - if (image.numColors()) { - // Paletted - int num_palette = image.numColors(); - palette = new png_color[num_palette]; - png_set_PLTE(png_ptr, info_ptr, palette, num_palette); - int* trans = new int[num_palette]; - int num_trans = 0; -#if PNG_LIBPNG_VER>=10500 - png_colorp info_ptr_palette = NULL; - int tmp; - png_get_PLTE(png_ptr, info_ptr, &info_ptr_palette, &tmp); -#endif /* LIBPNG 1.5 */ - for (int i=0; i=10500 - info_ptr_palette[i].red = tqRed(rgb); - info_ptr_palette[i].green = tqGreen(rgb); - info_ptr_palette[i].blue = tqBlue(rgb); -#else /* LIBPNG 1.5 */ - info_ptr->palette[i].red = tqRed(rgb); - info_ptr->palette[i].green = tqGreen(rgb); - info_ptr->palette[i].blue = tqBlue(rgb); -#endif /* LIBPNG 1.5 */ - if (image.hasAlphaBuffer()) { - trans[i] = rgb >> 24; - if (trans[i] < 255) { - num_trans = i+1; - } - } - } -#if PNG_LIBPNG_VER>=10500 - png_set_PLTE(png_ptr, info_ptr, info_ptr_palette, num_palette); -#endif /* LIBPNG 1.5 */ - if (num_trans) { - copy_trans = new png_byte[num_trans]; - for (int i=0; i=10500 - png_color_8p sig_bit; - png_get_sBIT(png_ptr, info_ptr, &sig_bit); - sig_bit->alpha = 8; - png_set_sBIT(png_ptr, info_ptr, sig_bit); -#else /* LIBPNG 1.5 */ - info_ptr->sig_bit.alpha = 8; -#endif /* LIBPNG 1.5 */ - } - - // Swap ARGB to RGBA (normal PNG format) before saving on - // BigEndian machines - if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { - png_set_swap_alpha(png_ptr); - } - - // TQt==ARGB==Big(ARGB)==Little(BGRA) - if ( TQImage::systemByteOrder() == TQImage::LittleEndian ) { - png_set_bgr(png_ptr); - } - - if (off_x || off_y) { - png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL); - } - - if ( frames_written > 0 ) - png_set_sig_bytes(png_ptr, 8); - - if ( image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0 ) { - png_set_pHYs(png_ptr, info_ptr, - image.dotsPerMeterX(), image.dotsPerMeterY(), - PNG_RESOLUTION_METER); - } - -#ifndef TQT_NO_IMAGE_TEXT - // Write short texts early. - set_text(image,png_ptr,info_ptr,TRUE); -#endif - - png_write_info(png_ptr, info_ptr); - -#ifndef TQT_NO_IMAGE_TEXT - // Write long texts later. - set_text(image,png_ptr,info_ptr,FALSE); -#endif - - if ( image.depth() != 1 ) - png_set_packing(png_ptr); - - if ( image.depth() == 32 && !image.hasAlphaBuffer() ) - png_set_filler(png_ptr, 0, - TQImage::systemByteOrder() == TQImage::BigEndian ? - PNG_FILLER_BEFORE : PNG_FILLER_AFTER); - - if ( looping >= 0 && frames_written == 0 ) { - uchar data[13] = "NETSCAPE2.0"; - // 0123456789aBC - data[0xB] = looping%0x100; - data[0xC] = looping/0x100; - png_write_chunk(png_ptr, (png_byte*)"gIFx", data, 13); - } - if ( ms_delay >= 0 || disposal!=Unspecified ) { - uchar data[4]; - data[0] = disposal; - data[1] = 0; - data[2] = (ms_delay/10)/0x100; // hundredths - data[3] = (ms_delay/10)%0x100; - png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); - } - - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - - uchar** jt = image.jumpTable(); - row_pointers=new png_bytep[height]; - uint y; - for (y=0; yioDevice()); - int quality = iio->quality(); - if ( quality >= 0 ) { - quality = TQMIN( quality, 100 ); - quality = (100-quality) * 9 / 91; // map [0,100] -> [9,0] - } - writer.setGamma(iio->gamma()); - bool ok = writer.writeImage( iio->image(), quality ); - iio->setStatus( ok ? 0 : -1 ); -} - -/*! - \class TQPNGImagePacker ntqpngio.h - \brief The TQPNGImagePacker class creates well-compressed PNG animations. - - \ingroup images - \ingroup graphics - - By using transparency, TQPNGImagePacker allows you to build a PNG - image from a sequence of TQImages. - - Images are added using packImage(). -*/ - - -/*! - Creates an image packer that writes PNG data to IO device \a iod - using a \a storage_depth bit encoding (use 8 or 32, depending on - the desired quality and compression requirements). - - 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 - conversionflags to specify how you'd prefer this to happen. - - \sa TQt::ImageConversionFlags -*/ -TQPNGImagePacker::TQPNGImagePacker(TQIODevice* iod, int storage_depth, - int conversionflags) : - TQPNGImageWriter(iod), - depth(storage_depth), - convflags(conversionflags), - alignx(1) -{ -} - -/*! - Aligns pixel differences to \a x pixels. For example, using 8 can - improve playback on certain hardware. Normally the default of - 1-pixel alignment (i.e. no alignment) gives better compression and - performance. -*/ -void TQPNGImagePacker::setPixelAlignment(int x) -{ - alignx = x; -} - -/*! - Adds the image \a img to the PNG animation, analyzing the - differences between this and the previous image to improve - compression. -*/ -bool TQPNGImagePacker::packImage(const TQImage& img) -{ - TQImage image = img.convertDepth(32); - if ( previous.isNull() ) { - // First image - writeImage(image.convertDepth(depth,convflags)); - } else { - bool done; - int minx, maxx, miny, maxy; - int w = image.width(); - int h = image.height(); - - TQRgb** jt = (TQRgb**)image.jumpTable(); - TQRgb** pjt = (TQRgb**)previous.jumpTable(); - - // Find left edge of change - done = FALSE; - for (minx = 0; minx < w && !done; minx++) { - for (int ty = 0; ty < h; ty++) { - if ( jt[ty][minx] != pjt[ty][minx] ) { - done = TRUE; - break; - } - } - } - minx--; - - // Find right edge of change - done = FALSE; - for (maxx = w-1; maxx >= 0 && !done; maxx--) { - for (int ty = 0; ty < h; ty++) { - if ( jt[ty][maxx] != pjt[ty][maxx] ) { - done = TRUE; - break; - } - } - } - maxx++; - - // Find top edge of change - done = FALSE; - for (miny = 0; miny < h && !done; miny++) { - for (int tx = 0; tx < w; tx++) { - if ( jt[miny][tx] != pjt[miny][tx] ) { - done = TRUE; - break; - } - } - } - miny--; - - // Find right edge of change - done = FALSE; - for (maxy = h-1; maxy >= 0 && !done; maxy--) { - for (int tx = 0; tx < w; tx++) { - if ( jt[maxy][tx] != pjt[maxy][tx] ) { - done = TRUE; - break; - } - } - } - maxy++; - - if ( minx > maxx ) minx=maxx=0; - if ( miny > maxy ) miny=maxy=0; - - if ( alignx > 1 ) { - minx -= minx % alignx; - maxx = maxx - maxx % alignx + alignx - 1; - } - - int dw = maxx-minx+1; - int dh = maxy-miny+1; - - TQImage diff(dw, dh, 32); - - diff.setAlphaBuffer(TRUE); - int x, y; - if ( alignx < 1 ) - alignx = 1; - for (y = 0; y < dh; y++) { - TQRgb* li = (TQRgb*)image.scanLine(y+miny)+minx; - TQRgb* lp = (TQRgb*)previous.scanLine(y+miny)+minx; - TQRgb* ld = (TQRgb*)diff.scanLine(y); - if ( alignx ) { - for (x = 0; x < dw; x+=alignx) { - int i; - for (i=0; iinfo(png_ptr,info); -} - -static void -CALLBACK_CALL_TYPE row_callback(png_structp png_ptr, png_bytep new_row, - png_uint_32 row_num, int pass) -{ - TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr); - that->row(png_ptr,new_row,row_num,pass); -} - -static void -CALLBACK_CALL_TYPE end_callback(png_structp png_ptr, png_infop info) -{ - TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr); - that->end(png_ptr,info); -} - -#if 0 -#ifdef PNG_USER_CHUNKS_SUPPORTED -static int -CALLBACK_CALL_TYPE user_chunk_callback(png_structp png_ptr, - png_unknown_chunkp chunk) -{ - TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr); - return that->user_chunk(png_ptr,chunk->data,chunk->size); -} -#endif -#endif - -#if defined(Q_C_CALLBACKS) -} -#endif - - -/*! - Constructs a TQPNGFormat object. -*/ -TQPNGFormat::TQPNGFormat() -{ - state = MovieStart; - first_frame = 1; - base_offx = 0; - base_offy = 0; - png_ptr = 0; - info_ptr = 0; -} - - -/*! - Destroys a TQPNGFormat object. -*/ -TQPNGFormat::~TQPNGFormat() -{ - if ( png_ptr ) - png_destroy_read_struct(&png_ptr, &info_ptr, 0); -} - - -/*! - This function decodes some data into image changes. - - Returns the number of bytes consumed. -*/ -int TQPNGFormat::decode(TQImage& img, TQImageConsumer* cons, - const uchar* buffer, int length) -{ - consumer = cons; - image = &img; - - if ( state != Inside ) { - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if (!png_ptr) { - info_ptr = 0; - image = 0; - return -1; - } - - png_set_error_fn(png_ptr, 0, 0, qt_png_warning); - png_set_compression_level(png_ptr, 9); - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, &info_ptr, 0); - image = 0; - return -1; - } - -#if PNG_LIBPNG_VER>=10500 - if (setjmp(png_jmpbuf(png_ptr))) { -#else /* LIBPNG 1.5 */ - if (setjmp((png_ptr)->jmpbuf)) { -#endif /* LIBPNG 1.5 */ - png_destroy_read_struct(&png_ptr, &info_ptr, 0); - image = 0; - return -1; - } - - png_set_progressive_read_fn(png_ptr, (void *)this, - info_callback, row_callback, end_callback); - -#ifdef PNG_USER_CHUNKS_SUPPORTED - // Can't do this yet. libpng has a crash bug with unknown (user) chunks. - // Warwick has sent them a patch. - // png_set_read_user_chunk_fn(png_ptr, 0, user_chunk_callback); - // png_set_keep_unknown_chunks(png_ptr, 2/*HANDLE_CHUNK_IF_SAFE*/, 0, 0); -#endif - - if ( state != MovieStart && *buffer != 0211 ) { - // Good, no signature - the preferred way to concat PNG images. - // Skip them. - png_set_sig_bytes(png_ptr, 8); - } - - state = Inside; - } - - if ( !png_ptr ) return 0; - -#if PNG_LIBPNG_VER>=10500 - if (setjmp(png_jmpbuf(png_ptr))) { -#else /* LIBPNG 1.5 */ - if (setjmp(png_ptr->jmpbuf)) { -#endif /* LIBPNG 1.5 */ - png_destroy_read_struct(&png_ptr, &info_ptr, 0); - image = 0; - state = MovieStart; - return -1; - } - unused_data = 0; - png_process_data(png_ptr, info_ptr, (png_bytep)buffer, length); - int l = length - unused_data; - - // TODO: send incremental stuff to consumer (optional) - - if ( state != Inside ) { - if ( png_ptr ) - png_destroy_read_struct(&png_ptr, &info_ptr, 0); - } - - image = 0; - return l; -} - -void TQPNGFormat::info(png_structp png, png_infop) -{ - png_set_interlace_handling(png); - setup_qt(*image, png, info_ptr); -} - -void TQPNGFormat::row(png_structp png, png_bytep new_row, - png_uint_32 row_num, int) -{ - uchar* old_row = image->scanLine(row_num); - png_progressive_combine_row(png, old_row, new_row); -} - - -void TQPNGFormat::end(png_structp png, png_infop info) -{ - int offx = png_get_x_offset_pixels(png,info) - base_offx; - int offy = png_get_y_offset_pixels(png,info) - base_offy; - if ( first_frame ) { - base_offx = offx; - base_offy = offy; - first_frame = 0; - } - image->setOffset(TQPoint(offx,offy)); - image->setDotsPerMeterX(png_get_x_pixels_per_meter(png,info)); - image->setDotsPerMeterY(png_get_y_pixels_per_meter(png,info)); -#ifndef TQT_NO_IMAGE_TEXT - png_textp text_ptr; - int num_text=0; - png_get_text(png,info,&text_ptr,&num_text); - while (num_text--) { - image->setText(text_ptr->key,0,text_ptr->text); - text_ptr++; - } -#endif - TQRect r(0,0,image->width(),image->height()); - consumer->frameDone(TQPoint(offx,offy),r); - consumer->end(); - state = FrameStart; -#if PNG_LIBPNG_VER>=10500 - unused_data = png_process_data_pause(png, 0); -#else /* LIBPNG 1.5 */ - unused_data = (int)png->buffer_size; // Since libpng doesn't tell us -#endif /* LIBPNG 1.5 */ -} - -#ifdef PNG_USER_CHUNKS_SUPPORTED - -/* -#ifndef TQT_NO_IMAGE_TEXT -static bool skip(png_uint_32& max, png_bytep& data) -{ - while (*data) { - if ( !max ) return FALSE; - max--; - data++; - } - if ( !max ) return FALSE; - max--; - data++; // skip to after NUL - return TRUE; -} -#endif -*/ - -int TQPNGFormat::user_chunk(png_structp png, - png_bytep data, png_uint_32 length) -{ -#if 0 // NOT SUPPORTED: experimental PNG animation. - // tqDebug("Got %ld-byte %s chunk", length, png->chunk_name); - if ( 0==qstrcmp((char*)png->chunk_name, "gIFg") - && length == 4 ) { - - //TQPNGImageWriter::DisposalMethod disposal = - // (TQPNGImageWriter::DisposalMethod)data[0]; - // ### TODO: use the disposal method - int ms_delay = ((data[2] << 8) | data[3])*10; - consumer->setFramePeriod(ms_delay); - return 1; - } else if ( 0==qstrcmp((char*)png->chunk_name, "gIFx") - && length == 13 ) { - if ( tqstrncmp((char*)data,"NETSCAPE2.0",11)==0 ) { - int looping = (data[0xC]<<8)|data[0xB]; - consumer->setLooping(looping); - return 1; - } - } -#else - Q_UNUSED( png ) - Q_UNUSED( data ) - Q_UNUSED( length ) -#endif - -#ifndef TQT_NO_IMAGE_TEXT - /* - - libpng now supports this chunk. - - - if ( 0==qstrcmp((char*)png->chunk_name, "iTXt") && length>=6 ) { - const char* keyword = (const char*)data; - if ( !skip(length,data) ) return 0; - if ( length >= 4 ) { - char compression_flag = *data++; - char compression_method = *data++; - if ( compression_flag == compression_method ) { - // fool the compiler into thinking they're used - } - const char* lang = (const char*)data; - if ( !skip(length,data) ) return 0; - // const char* keyword_utf8 = (const char*)data; - if ( !skip(length,data) ) return 0; - const char* text_utf8 = (const char*)data; - if ( !skip(length,data) ) return 0; - TQString text = TQString::fromUtf8(text_utf8); - image->setText(keyword,lang[0] ? lang : 0,text); - return 1; - } - } - */ -#endif - - return 0; -} -#endif - - -static TQPNGFormatType* globalPngFormatTypeObject = 0; - -#endif // TQT_NO_ASYNC_IMAGE_IO - -static bool done = FALSE; -void qCleanupPngIO() -{ -#ifndef TQT_NO_ASYNC_IMAGE_IO - if ( globalPngFormatTypeObject ) { - delete globalPngFormatTypeObject; - globalPngFormatTypeObject = 0; - } -#endif - done = FALSE; -} - -void qInitPngIO() -{ - if ( !done ) { - done = TRUE; - TQImageIO::defineIOHandler( "PNG", "^.PNG\r", 0, read_png_image, - write_png_image); -#ifndef TQT_NO_ASYNC_IMAGE_IO - globalPngFormatTypeObject = new TQPNGFormatType; -#endif - tqAddPostRoutine( qCleanupPngIO ); - } -} - -void qt_zlib_compression_hack() -{ - compress(0,0,0,0); - uncompress(0,0,0,0); -} - -#endif // TQT_NO_IMAGEIO_PNG diff --git a/src/kernel/qpoint.cpp b/src/kernel/qpoint.cpp deleted file mode 100644 index e3f620f9e..000000000 --- a/src/kernel/qpoint.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPoint class -** -** Created : 931028 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpoint.h" -#include "tqdatastream.h" - - -/*! - \class TQPoint ntqpoint.h - \brief The TQPoint class defines a point in the plane. - - \ingroup images - \ingroup graphics - \mainclass - - A point is specified by an x coordinate and a y coordinate. - - The coordinate type is \c TQCOORD (a 32-bit integer). The minimum - value of \c TQCOORD is \c TQCOORD_MIN (-2147483648) and the maximum - value is \c TQCOORD_MAX (2147483647). - - The coordinates are accessed by the functions x() and y(); they - can be set by setX() and setY() or by the reference functions rx() - and ry(). - - Given a point \e p, the following statements are all equivalent: - \code - p.setX( p.x() + 1 ); - p += TQPoint( 1, 0 ); - p.rx()++; - \endcode - - A TQPoint can also be used as a vector. Addition and subtraction - of TQPoints are defined as for vectors (each component is added - separately). You can divide or multiply a TQPoint by an \c int or a - \c double. The function manhattanLength() gives an inexpensive - approximation of the length of the TQPoint interpreted as a vector. - - Example: - \code - //TQPoint oldPos is defined somewhere else - MyWidget::mouseMoveEvent( TQMouseEvent *e ) - { - TQPoint vector = e->pos() - oldPos; - if ( vector.manhattanLength() > 3 ) - ... //mouse has moved more than 3 pixels since oldPos - } - \endcode - - TQPoints can be compared for equality or inequality, and they can - be written to and read from a TQStream. - - \sa TQPointArray TQSize, TQRect -*/ - - -/***************************************************************************** - TQPoint member functions - *****************************************************************************/ - -/*! - \fn TQPoint::TQPoint() - - Constructs a point with coordinates (0, 0) (isNull() returns TRUE). -*/ - -/*! - \fn TQPoint::TQPoint( int xpos, int ypos ) - - Constructs a point with x value \a xpos and y value \a ypos. -*/ - -/*! - \fn bool TQPoint::isNull() const - - Returns TRUE if both the x value and the y value are 0; otherwise - returns FALSE. -*/ - -/*! - \fn int TQPoint::x() const - - Returns the x coordinate of the point. - - \sa setX() y() -*/ - -/*! - \fn int TQPoint::y() const - - Returns the y coordinate of the point. - - \sa setY() x() -*/ - -/*! - \fn void TQPoint::setX( int x ) - - Sets the x coordinate of the point to \a x. - - \sa x() setY() -*/ - -/*! - \fn void TQPoint::setY( int y ) - - Sets the y coordinate of the point to \a y. - - \sa y() setX() -*/ - - -/*! - \fn TQCOORD &TQPoint::rx() - - Returns a reference to the x coordinate of the point. - - Using a reference makes it possible to directly manipulate x. - - Example: - \code - TQPoint p( 1, 2 ); - p.rx()--; // p becomes (0, 2) - \endcode - - \sa ry() -*/ - -/*! - \fn TQCOORD &TQPoint::ry() - - Returns a reference to the y coordinate of the point. - - Using a reference makes it possible to directly manipulate y. - - Example: - \code - TQPoint p( 1, 2 ); - p.ry()++; // p becomes (1, 3) - \endcode - - \sa rx() -*/ - - -/*! - \fn TQPoint &TQPoint::operator+=( const TQPoint &p ) - - Adds point \a p to this point and returns a reference to this - point. - - Example: - \code - TQPoint p( 3, 7 ); - TQPoint q( -1, 4 ); - p += q; // p becomes (2,11) - \endcode -*/ - -/*! - \fn TQPoint &TQPoint::operator-=( const TQPoint &p ) - - Subtracts point \a p from this point and returns a reference to - this point. - - Example: - \code - TQPoint p( 3, 7 ); - TQPoint q( -1, 4 ); - p -= q; // p becomes (4,3) - \endcode -*/ - -/*! - \fn TQPoint &TQPoint::operator*=( int c ) - - Multiplies this point's x and y by \a c, and returns a reference - to this point. - - Example: - \code - TQPoint p( -1, 4 ); - p *= 2; // p becomes (-2,8) - \endcode -*/ - -/*! - \overload TQPoint &TQPoint::operator*=( double c ) - - Multiplies this point's x and y by \a c, and returns a reference - to this point. - - Example: - \code - TQPoint p( -1, 4 ); - p *= 2.5; // p becomes (-3,10) - \endcode - - Note that the result is truncated because points are held as - integers. -*/ - - -/*! - \fn bool operator==( const TQPoint &p1, const TQPoint &p2 ) - - \relates TQPoint - - Returns TRUE if \a p1 and \a p2 are equal; otherwise returns FALSE. -*/ - -/*! - \fn bool operator!=( const TQPoint &p1, const TQPoint &p2 ) - - \relates TQPoint - - Returns TRUE if \a p1 and \a p2 are not equal; otherwise returns FALSE. -*/ - -/*! - \fn const TQPoint operator+( const TQPoint &p1, const TQPoint &p2 ) - - \relates TQPoint - - Returns the sum of \a p1 and \a p2; each component is added separately. -*/ - -/*! - \fn const TQPoint operator-( const TQPoint &p1, const TQPoint &p2 ) - - \relates TQPoint - - Returns \a p2 subtracted from \a p1; each component is subtracted - separately. -*/ - -/*! - \fn const TQPoint operator*( const TQPoint &p, int c ) - - \relates TQPoint - - Returns the TQPoint formed by multiplying both components of \a p - by \a c. -*/ - -/*! - \overload const TQPoint operator*( int c, const TQPoint &p ) - - \relates TQPoint - - Returns the TQPoint formed by multiplying both components of \a p - by \a c. -*/ - -/*! - \overload const TQPoint operator*( const TQPoint &p, double c ) - - \relates TQPoint - - Returns the TQPoint formed by multiplying both components of \a p - by \a c. - - Note that the result is truncated because points are held as - integers. -*/ - -/*! - \overload const TQPoint operator*( double c, const TQPoint &p ) - - \relates TQPoint - - Returns the TQPoint formed by multiplying both components of \a p - by \a c. - - Note that the result is truncated because points are held as - integers. -*/ - -/*! - \overload const TQPoint operator-( const TQPoint &p ) - - \relates TQPoint - - Returns the TQPoint formed by changing the sign of both components - of \a p, equivalent to \c{TQPoint(0,0) - p}. -*/ - -/*! - \fn TQPoint &TQPoint::operator/=( int c ) - - Divides both x and y by \a c, and returns a reference to this - point. - - Example: - \code - TQPoint p( -2, 8 ); - p /= 2; // p becomes (-1,4) - \endcode -*/ - -/*! - \overload TQPoint &TQPoint::operator/=( double c ) - - Divides both x and y by \a c, and returns a reference to this - point. - - Example: - \code - TQPoint p( -3, 10 ); - p /= 2.5; // p becomes (-1,4) - \endcode - - Note that the result is truncated because points are held as - integers. -*/ - -/*! - \fn const TQPoint operator/( const TQPoint &p, int c ) - - \relates TQPoint - - Returns the TQPoint formed by dividing both components of \a p by - \a c. -*/ - -/*! - \overload const TQPoint operator/( const TQPoint &p, double c ) - - \relates TQPoint - - Returns the TQPoint formed by dividing both components of \a p - by \a c. - - Note that the result is truncated because points are held as - integers. -*/ - - -void TQPoint::warningDivByZero() -{ -#if defined(QT_CHECK_MATH) - tqWarning( "TQPoint: Division by zero error" ); -#endif -} - - -/***************************************************************************** - TQPoint stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -/*! - \relates TQPoint - - Writes point \a p to the stream \a s and returns a reference to - the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQPoint &p ) -{ - if ( s.version() == 1 ) - s << (TQ_INT16)p.x() << (TQ_INT16)p.y(); - else - s << (TQ_INT32)p.x() << (TQ_INT32)p.y(); - return s; -} - -/*! - \relates TQPoint - - Reads a TQPoint from the stream \a s into point \a p and returns a - reference to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator>>( TQDataStream &s, TQPoint &p ) -{ - if ( s.version() == 1 ) { - TQ_INT16 x, y; - s >> x; p.rx() = x; - s >> y; p.ry() = y; - } - else { - TQ_INT32 x, y; - s >> x; p.rx() = x; - s >> y; p.ry() = y; - } - return s; -} -#endif // TQT_NO_DATASTREAM -/*! - Returns the sum of the absolute values of x() and y(), - traditionally known as the "Manhattan length" of the vector from - the origin to the point. The tradition arises because such - distances apply to travelers who can only travel on a rectangular - grid, like the streets of Manhattan. - - This is a useful, and quick to calculate, approximation to the - true length: sqrt(pow(x(),2)+pow(y(),2)). -*/ -int TQPoint::manhattanLength() const -{ - return TQABS(x())+TQABS(y()); -} diff --git a/src/kernel/qpointarray.cpp b/src/kernel/qpointarray.cpp deleted file mode 100644 index ccba1122e..000000000 --- a/src/kernel/qpointarray.cpp +++ /dev/null @@ -1,1109 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPointArray class -** -** Created : 940213 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqpointarray.h" -#include "ntqrect.h" -#include "tqdatastream.h" -#include "ntqwmatrix.h" -#include - -const double Q_PI = 3.14159265358979323846; // pi // one more useful comment - - -/*! - \class TQPointArray ntqpointarray.h - \brief The TQPointArray class provides an array of points. - - \ingroup images - \ingroup graphics - \ingroup shared - - A TQPointArray is an array of TQPoint objects. In addition to the - functions provided by TQMemArray, TQPointArray provides some - point-specific functions. - - For convenient reading and writing of the point data use - setPoints(), putPoints(), point(), and setPoint(). - - For geometry operations use boundingRect() and translate(). There - is also the TQWMatrix::map() function for more general - transformations of TQPointArrays. You can also create arcs and - ellipses with makeArc() and makeEllipse(). - - Among others, TQPointArray is used by TQPainter::drawLineSegments(), - TQPainter::drawPolyline(), TQPainter::drawPolygon() and - TQPainter::drawCubicBezier(). - - Note that because this class is a TQMemArray, copying an array and - modifying the copy modifies the original as well, i.e. a shallow - copy. If you need a deep copy use copy() or detach(), for example: - - \code - void drawGiraffe( const TQPointArray & r, TQPainter * p ) - { - TQPointArray tmp = r; - tmp.detach(); - // some code that modifies tmp - p->drawPoints( tmp ); - } - \endcode - - If you forget the tmp.detach(), the const array will be modified. - - \sa TQPainter TQWMatrix TQMemArray -*/ - - -/***************************************************************************** - TQPointArray member functions - *****************************************************************************/ - -/*! - \fn TQPointArray::TQPointArray() - - Constructs a null point array. - - \sa isNull() -*/ - -/*! - \fn TQPointArray::TQPointArray( int size ) - - Constructs a point array with room for \a size points. Makes a - null array if \a size == 0. - - \sa resize(), isNull() -*/ - -/*! - \fn TQPointArray::TQPointArray( const TQPointArray &a ) - - Constructs a shallow copy of the point array \a a. - - \sa copy() detach() -*/ - -/*! - Constructs a point array from the rectangle \a r. - - If \a closed is FALSE, then the point array just contains the - following four points in the listed order: r.topLeft(), - r.topRight(), r.bottomRight() and r.bottomLeft(). - - If \a closed is TRUE, then a fifth point is set to r.topLeft(). -*/ - -TQPointArray::TQPointArray( const TQRect &r, bool closed ) -{ - setPoints( 4, r.left(), r.top(), - r.right(), r.top(), - r.right(), r.bottom(), - r.left(), r.bottom() ); - if ( closed ) { - resize( 5 ); - setPoint( 4, r.left(), r.top() ); - } -} - -/*! - \internal - Constructs a point array with \a nPoints points, taken from the - \a points array. - - Equivalent to setPoints(nPoints, points). -*/ - -TQPointArray::TQPointArray( int nPoints, const TQCOORD *points ) -{ - setPoints( nPoints, points ); -} - - -/*! - \fn TQPointArray::~TQPointArray() - - Destroys the point array. -*/ - - -/*! - \fn TQPointArray &TQPointArray::operator=( const TQPointArray &a ) - - Assigns a shallow copy of \a a to this point array and returns a - reference to this point array. - - Equivalent to assign(a). - - \sa copy() detach() -*/ - -/*! - \fn TQPointArray TQPointArray::copy() const - - Creates a deep copy of the array. - - \sa detach() -*/ - - - -/*! - Translates all points in the array by \a (dx, dy). -*/ - -void TQPointArray::translate( int dx, int dy ) -{ - TQPoint *p = data(); - int i = size(); - TQPoint pt( dx, dy ); - while ( i-- ) { - *p += pt; - p++; - } -} - - -/*! - Reads the coordinates of the point at position \a index within the - array and writes them into \a *x and \a *y. -*/ - -void TQPointArray::point( uint index, int *x, int *y ) const -{ - TQPoint p = TQMemArray::at( index ); - if ( x ) - *x = (int)p.x(); - if ( y ) - *y = (int)p.y(); -} - -/*! - \overload - - Returns the point at position \a index within the array. -*/ - -TQPoint TQPointArray::point( uint index ) const -{ // #### index out of bounds - return TQMemArray::at( index ); -} - -/*! - \fn void TQPointArray::setPoint( uint i, const TQPoint &p ) - - \overload - - Sets the point at array index \a i to \a p. -*/ - -/*! - Sets the point at position \a index in the array to \a (x, y). -*/ - -void TQPointArray::setPoint( uint index, int x, int y ) -{ // #### index out of bounds - TQMemArray::at( index ) = TQPoint( x, y ); -} - -/*! - \internal - Resizes the array to \a nPoints and sets the points in the array to - the values taken from \a points. - - Returns TRUE if successful, or FALSE if the array could not be - resized (normally due to lack of memory). - - The example code creates an array with two points (1,2) and (3,4): - \code - static TQCOORD points[] = { 1,2, 3,4 }; - TQPointArray a; - a.setPoints( 2, points ); - \endcode - - \sa resize(), putPoints() -*/ - -bool TQPointArray::setPoints( int nPoints, const TQCOORD *points ) -{ - if ( !resize(nPoints) ) - return FALSE; - int i = 0; - while ( nPoints-- ) { // make array of points - setPoint( i++, *points, *(points+1) ); - points++; - points++; - } - return TRUE; -} - -/*! - \overload - - Resizes the array to \a nPoints and sets the points in the array - to the values taken from the variable argument list. - - Returns TRUE if successful, or FALSE if the array could not be - resized (typically due to lack of memory). - - The example code creates an array with two points (1,2) and (3,4): - - \code - TQPointArray a; - a.setPoints( 2, 1,2, 3,4 ); - \endcode - - The points are given as a sequence of integers, starting with \a - firstx then \a firsty, and so on. - - \sa resize(), putPoints() -*/ - -bool TQPointArray::setPoints( int nPoints, int firstx, int firsty, ... ) -{ - va_list ap; - if ( !resize(nPoints) ) - return FALSE; - setPoint( 0, firstx, firsty ); // set first point - int i = 1, x, y; - nPoints--; - va_start( ap, firsty ); - while ( nPoints-- ) { - x = va_arg( ap, int ); - y = va_arg( ap, int ); - setPoint( i++, x, y ); - } - va_end( ap ); - return TRUE; -} - -/*! \overload - \internal - Copies \a nPoints points from the \a points coord array into - this point array, and resizes the point array if - \c{index+nPoints} exceeds the size of the array. - - Returns TRUE if successful, or FALSE if the array could not be - resized (typically due to lack of memory). - -*/ - -bool TQPointArray::putPoints( int index, int nPoints, const TQCOORD *points ) -{ - if ( index + nPoints > (int)size() ) { // extend array - if ( !resize( index + nPoints ) ) - return FALSE; - } - int i = index; - while ( nPoints-- ) { // make array of points - setPoint( i++, *points, *(points+1) ); - points++; - points++; - } - return TRUE; -} - -/*! - Copies \a nPoints points from the variable argument list into this - point array from position \a index, and resizes the point array if - \c{index+nPoints} exceeds the size of the array. - - Returns TRUE if successful, or FALSE if the array could not be - resized (typically due to lack of memory). - - The example code creates an array with three points (4,5), (6,7) - and (8,9), by expanding the array from 1 to 3 points: - - \code - TQPointArray a( 1 ); - a[0] = TQPoint( 4, 5 ); - a.putPoints( 1, 2, 6,7, 8,9 ); // index == 1, points == 2 - \endcode - - This has the same result, but here putPoints overwrites rather - than extends: - \code - TQPointArray a( 3 ); - a.putPoints( 0, 3, 4,5, 0,0, 8,9 ); - a.putPoints( 1, 1, 6,7 ); - \endcode - - The points are given as a sequence of integers, starting with \a - firstx then \a firsty, and so on. - - \sa resize() -*/ - -bool TQPointArray::putPoints( int index, int nPoints, int firstx, int firsty, - ... ) -{ - va_list ap; - if ( index + nPoints > (int)size() ) { // extend array - if ( !resize(index + nPoints) ) - return FALSE; - } - if ( nPoints <= 0 ) - return TRUE; - setPoint( index, firstx, firsty ); // set first point - int i = index + 1, x, y; - nPoints--; - va_start( ap, firsty ); - while ( nPoints-- ) { - x = va_arg( ap, int ); - y = va_arg( ap, int ); - setPoint( i++, x, y ); - } - va_end( ap ); - return TRUE; -} - - -/*! - \overload - - This version of the function copies \a nPoints from \a from into - this array, starting at \a index in this array and \a fromIndex in - \a from. \a fromIndex is 0 by default. - - \code - TQPointArray a; - a.putPoints( 0, 3, 1,2, 0,0, 5,6 ); - // a is now the three-point array ( 1,2, 0,0, 5,6 ); - TQPointArray b; - b.putPoints( 0, 3, 4,4, 5,5, 6,6 ); - // b is now ( 4,4, 5,5, 6,6 ); - a.putPoints( 2, 3, b ); - // a is now ( 1,2, 0,0, 4,4, 5,5, 6,6 ); - \endcode -*/ - -bool TQPointArray::putPoints( int index, int nPoints, - const TQPointArray & from, int fromIndex ) -{ - if ( index + nPoints > (int)size() ) { // extend array - if ( !resize(index + nPoints) ) - return FALSE; - } - if ( nPoints <= 0 ) - return TRUE; - int n = 0; - while( n < nPoints ) { - setPoint( index+n, from[fromIndex+n] ); - n++; - } - return TRUE; -} - - -/*! - Returns the bounding rectangle of the points in the array, or - TQRect(0,0,0,0) if the array is empty. -*/ - -TQRect TQPointArray::boundingRect() const -{ - if ( isEmpty() ) - return TQRect( 0, 0, 0, 0 ); // null rectangle - TQPoint *pd = data(); - int minx, maxx, miny, maxy; - minx = maxx = pd->x(); - miny = maxy = pd->y(); - pd++; - for ( int i=1; i<(int)size(); i++ ) { // find min+max x and y - if ( pd->x() < minx ) - minx = pd->x(); - else if ( pd->x() > maxx ) - maxx = pd->x(); - if ( pd->y() < miny ) - miny = pd->y(); - else if ( pd->y() > maxy ) - maxy = pd->y(); - pd++; - } - return TQRect( TQPoint(minx,miny), TQPoint(maxx,maxy) ); -} - - -static inline int fix_angle( int a ) -{ - if ( a > 16*360 ) - a %= 16*360; - else if ( a < -16*360 ) { - a = -( (-a) % (16*360) ); - } - return a; -} - -/*! - Sets the points of the array to those describing an arc of an - ellipse with size, width \a w by height \a h, and position (\a x, - \a y), starting from angle \a a1 and spanning by angle \a a2. The - resulting array has sufficient resolution for pixel accuracy (see - the overloaded function which takes an additional TQWMatrix - parameter). - - Angles are specified in 16ths of a degree, i.e. a full circle - equals 5760 (16*360). Positive values mean counter-clockwise, - whereas negative values mean the clockwise direction. Zero degrees - is at the 3 o'clock position. - - See the \link tqcanvasellipse.html#anglediagram angle diagram\endlink. -*/ - -void TQPointArray::makeArc( int x, int y, int w, int h, int a1, int a2 ) -{ -#if !defined(QT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS) - TQWMatrix unit; - makeArc(x,y,w,h,a1,a2,unit); -#else - a1 = fix_angle( a1 ); - if ( a1 < 0 ) - a1 += 16*360; - a2 = fix_angle( a2 ); - int a3 = a2 > 0 ? a2 : -a2; // abs angle - makeEllipse( x, y, w, h ); - int npts = a3*size()/(16*360); // # points in arc array - TQPointArray a(npts); - int i = a1*size()/(16*360); - int j = 0; - if ( a2 > 0 ) { - while ( npts-- ) { - if ( i >= (int)size() ) // wrap index - i = 0; - a.TQMemArray::at( j++ ) = TQMemArray::at( i++ ); - } - } else { - while ( npts-- ) { - if ( i < 0 ) // wrap index - i = (int)size()-1; - a.TQMemArray::at( j++ ) = TQMemArray::at( i-- ); - } - } - *this = a; - return; -#endif -} - -#ifndef TQT_NO_TRANSFORMATIONS -// Based upon: -// parelarc.c from Graphics Gems III -// VanAken / Simar, "A Parametric Elliptical Arc Algorithm" -// -static void -qtr_elips(TQPointArray& a, int off, double dxP, double dyP, double dxQ, double dyQ, double dxK, double dyK, int m) -{ -#define PIV2 102944 /* fixed point PI/2 */ -#define TWOPI 411775 /* fixed point 2*PI */ -#define HALF 32768 /* fixed point 1/2 */ - - int xP, yP, xQ, yQ, xK, yK; - xP = int(dxP * 65536.0); yP = int(dyP * 65536.0); - xQ = int(dxQ * 65536.0); yQ = int(dyQ * 65536.0); - xK = int(dxK * 65536.0); yK = int(dyK * 65536.0); - - int i; - int vx, ux, vy, uy, xJ, yJ; - - vx = xK - xQ; /* displacements from center */ - ux = xK - xP; - vy = yK - yQ; - uy = yK - yP; - xJ = xP - vx + HALF; /* center of ellipse J */ - yJ = yP - vy + HALF; - - int r; - ux -= (r = ux >> (2*m + 3)); /* cancel 2nd-order error */ - ux -= (r >>= (2*m + 4)); /* cancel 4th-order error */ - ux -= r >> (2*m + 3); /* cancel 6th-order error */ - ux += vx >> (m + 1); /* cancel 1st-order error */ - uy -= (r = uy >> (2*m + 3)); /* cancel 2nd-order error */ - uy -= (r >>= (2*m + 4)); /* cancel 4th-order error */ - uy -= r >> (2*m + 3); /* cancel 6th-order error */ - uy += vy >> (m + 1); /* cancel 1st-order error */ - - const int qn = a.size()/4; - for (i = 0; i < qn; i++) { - a[off+i] = TQPoint((xJ + vx) >> 16, (yJ + vy) >> 16); - ux -= vx >> m; - vx += ux >> m; - uy -= vy >> m; - vy += uy >> m; - } - -#undef PIV2 -#undef TWOPI -#undef HALF -} - - -/*! - \overload - - Sets the points of the array to those describing an arc of an - ellipse with width \a w and height \a h and position (\a x, \a y), - starting from angle \a a1, and spanning angle by \a a2, and - transformed by the matrix \a xf. The resulting array has - sufficient resolution for pixel accuracy. - - Angles are specified in 16ths of a degree, i.e. a full circle - equals 5760 (16*360). Positive values mean counter-clockwise, - whereas negative values mean the clockwise direction. Zero degrees - is at the 3 o'clock position. - - See the \link tqcanvasellipse.html#anglediagram angle diagram\endlink. -*/ -void TQPointArray::makeArc( int x, int y, int w, int h, - int a1, int a2, - const TQWMatrix& xf ) -{ -#define PIV2 102944 /* fixed point PI/2 */ - if ( --w < 0 || --h < 0 || !a2 ) { - resize( 0 ); - return; - } - - bool rev = a2 < 0; - if ( rev ) { - a1 += a2; - a2 = -a2; - } - a1 = fix_angle( a1 ); - if ( a1 < 0 ) - a1 += 16*360; - a2 = fix_angle( a2 ); - - bool arc = a1 != 0 || a2 != 360*16 || rev; - - double xP, yP, xQ, yQ, xK, yK; - - xf.map(x+w, y+h/2.0, &xP, &yP); - xf.map(x+w/2.0, y, &xQ, &yQ); - xf.map(x+w, y, &xK, &yK); - - int m = 3; - int max; - int q = int(TQMAX(TQABS(xP-xQ),TQABS(yP-yQ))); - if ( arc ) - q *= 2; - do { - m++; - max = 4*(1 + (PIV2 >> (16 - m)) ); - } while (max < q && m < 16); // 16 limits memory usage on HUGE arcs - - double inc = 1.0/(1<> (16 - m)); - resize(qn*4); - - qtr_elips(*this, 0, xP, yP, xQ, yQ, xK, yK, m); - xP = xQ; yP = yQ; - xf.map(x, y+h/2.0, &xQ, &yQ); - xf.map(x, y, &xK, &yK); - qtr_elips(*this, qn, xP, yP, xQ, yQ, xK, yK, m); - xP = xQ; yP = yQ; - xf.map(x+w/2.0, y+h, &xQ, &yQ); - xf.map(x, y+h, &xK, &yK); - qtr_elips(*this, qn*2, xP, yP, xQ, yQ, xK, yK, m); - xP = xQ; yP = yQ; - xf.map(x+w, y+h/2.0, &xQ, &yQ); - xf.map(x+w, y+h, &xK, &yK); - qtr_elips(*this, qn*3, xP, yP, xQ, yQ, xK, yK, m); - - int n = size(); - - if ( arc ) { - double da1 = double(a1)*Q_PI / (360*8); - double da3 = double(a2+a1)*Q_PI / (360*8); - int i = int(da1/inc+0.5); - int l = int(da3/inc+0.5); - int k = (l-i)+1; - TQPointArray r(k); - int j = 0; - - if ( rev ) { - while ( k-- ) - r[j++] = at((i+k)%n); - } else { - while ( j < k ) { - r[j] = at((i+j)%n); - j++; - } - } - *this = r; - } -#undef PIV2 -} - -#endif // TQT_NO_TRANSFORMATIONS - -/*! - Sets the points of the array to those describing an ellipse with - size, width \a w by height \a h, and position (\a x, \a y). - - The returned array has sufficient resolution for use as pixels. -*/ -void TQPointArray::makeEllipse( int x, int y, int w, int h ) -{ // midpoint, 1/4 ellipse -#if !defined(QT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS) - TQWMatrix unit; - makeArc(x,y,w,h,0,360*16,unit); - return; -#else - if ( w <= 0 || h <= 0 ) { - if ( w == 0 || h == 0 ) { - resize( 0 ); - return; - } - if ( w < 0 ) { // negative width - w = -w; - x -= w; - } - if ( h < 0 ) { // negative height - h = -h; - y -= h; - } - } - int s = (w+h+2)/2; // max size of xx,yy array - int *px = new int[s]; // 1/4th of ellipse - int *py = new int[s]; - int xx, yy, i=0; - double d1, d2; - double a2=(w/2)*(w/2), b2=(h/2)*(h/2); - xx = 0; - yy = int(h/2); - d1 = b2 - a2*(h/2) + 0.25*a2; - px[i] = xx; - py[i] = yy; - i++; - while ( a2*(yy-0.5) > b2*(xx+0.5) ) { // region 1 - if ( d1 < 0 ) { - d1 = d1 + b2*(3.0+2*xx); - xx++; - } else { - d1 = d1 + b2*(3.0+2*xx) + 2.0*a2*(1-yy); - xx++; - yy--; - } - px[i] = xx; - py[i] = yy; - i++; - } - d2 = b2*(xx+0.5)*(xx+0.5) + a2*(yy-1)*(yy-1) - a2*b2; - while ( yy > 0 ) { // region 2 - if ( d2 < 0 ) { - d2 = d2 + 2.0*b2*(xx+1) + a2*(3-2*yy); - xx++; - yy--; - } else { - d2 = d2 + a2*(3-2*yy); - yy--; - } - px[i] = xx; - py[i] = yy; - i++; - } - s = i; - resize( 4*s ); // make full point array - x += w/2; - y += h/2; - for ( i=0; i - * 1 if T is on the open ray ending at P: <--P - * 2 if T is on the closed interior along: P--Q - * 3 if T is on the open ray beginning at Q: Q--> - * - * Example: consider the line P = (3,2), Q = (17,7). A plot - * of the test points T(x,y) (with 0 mapped onto '.') yields: - * - * 8| . . . . . . . . . . . . . . . . . 3 3 - * Y 7| . . . . . . . . . . . . . . 2 2 Q 3 3 Q = 2 - * 6| . . . . . . . . . . . 2 2 2 2 2 . . . - * a 5| . . . . . . . . 2 2 2 2 2 2 . . . . . - * x 4| . . . . . 2 2 2 2 2 2 . . . . . . . . - * i 3| . . . 2 2 2 2 2 . . . . . . . . . . . - * s 2| 1 1 P 2 2 . . . . . . . . . . . . . . P = 2 - * 1| 1 1 . . . . . . . . . . . . . . . . . - * +-------------------------------------- - * 1 2 3 4 5 X-axis 10 15 19 - * - * Point-Line distance is normalized with the Infinity Norm - * avoiding square-root code and tightening the test vs the - * Manhattan Norm. All math is done on the field of integers. - * The latter replaces the initial ">= MAX(...)" test with - * "> (ABS(qx-px) + ABS(qy-py))" loosening both inequality - * and norm, yielding a broader target line for selection. - * The tightest test is employed here for best discrimination - * in merging collinear (to grid coordinates) vertex chains - * into a larger, spanning vectors within the Lemming editor. - */ - - // if all points are coincident, return condition 2 (on line) - if(q[0]==p[0] && q[1]==p[1] && q[0]==t[0] && q[1]==t[1]) { - return 2; - } - - if ( TQABS((q[1]-p[1])*(t[0]-p[0])-(t[1]-p[1])*(q[0]-p[0])) >= - (TQMAX(TQABS(q[0]-p[0]), TQABS(q[1]-p[1])))) return 0; - - if (((q[0] maxsize / 2 ) - { - // This never happens in practice. - - if ( accsize >= maxsize-4 ) - return; - // Running out of space - approximate by a line. - acc[accsize++] = ctrl[0]; - acc[accsize++] = ctrl[1]; - acc[accsize++] = ctrl[6]; - acc[accsize++] = ctrl[7]; - return; - } - - //intersects: - double l[8]; - double r[8]; - split( ctrl, l, r); - - // convert to integers for line condition check - int c0[2]; c0[0] = int(ctrl[0]); c0[1] = int(ctrl[1]); - int c1[2]; c1[0] = int(ctrl[2]); c1[1] = int(ctrl[3]); - int c2[2]; c2[0] = int(ctrl[4]); c2[1] = int(ctrl[5]); - int c3[2]; c3[0] = int(ctrl[6]); c3[1] = int(ctrl[7]); - - // #### Duplication needed? - if ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1 - && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1 - && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) - { - // Approximate by one line. - // Dont need to write last pt as it is the same as first pt - // on the next segment - acc[accsize++] = l[0]; - acc[accsize++] = l[1]; - return; - } - - if ( ( pnt_on_line( c0, c3, c1 ) == 2 && pnt_on_line( c0, c3, c2 ) == 2 ) - || ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1 - && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1 - && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) ) - { - // Approximate by one line. - // Dont need to write last pt as it is the same as first pt - // on the next segment - acc[accsize++] = l[0]; - acc[accsize++] = l[1]; - return; - } - - // Too big and too curved - recusively subdivide. - polygonizeTQBezier( acc, accsize, l, maxsize ); - polygonizeTQBezier( acc, accsize, r, maxsize ); -} - -/*! - Returns the Bezier points for the four control points in this - array. -*/ - -TQPointArray TQPointArray::cubicBezier() const -{ -#ifdef USE_SIMPLE_QBEZIER_CODE - if ( size() != 4 ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPointArray::bezier: The array must have 4 control points" ); -#endif - TQPointArray p; - return p; - } - - int v; - float xvec[4]; - float yvec[4]; - for ( v=0; v<4; v++ ) { // store all x,y in xvec,yvec - int x, y; - point( v, &x, &y ); - xvec[v] = (float)x; - yvec[v] = (float)y; - } - - TQRect r = boundingRect(); - int m = TQMAX(r.width(),r.height())/2; - m = TQMIN(m,30); // m = number of result points - if ( m < 2 ) // at least two points - m = 2; - TQPointArray p( m ); // p = Bezier point array - TQPointData *pd = p.data(); - - float x0 = xvec[0], y0 = yvec[0]; - float dt = 1.0F/m; - float cx = 3.0F * (xvec[1] - x0); - float bx = 3.0F * (xvec[2] - xvec[1]) - cx; - float ax = xvec[3] - (x0 + cx + bx); - float cy = 3.0F * (yvec[1] - y0); - float by = 3.0F * (yvec[2] - yvec[1]) - cy; - float ay = yvec[3] - (y0 + cy + by); - float t = dt; - - pd->rx() = (TQCOORD)xvec[0]; - pd->ry() = (TQCOORD)yvec[0]; - pd++; - m -= 2; - - while ( m-- ) { - pd->rx() = (TQCOORD)tqRound( ((ax * t + bx) * t + cx) * t + x0 ); - pd->ry() = (TQCOORD)tqRound( ((ay * t + by) * t + cy) * t + y0 ); - pd++; - t += dt; - } - - pd->rx() = (TQCOORD)xvec[3]; - pd->ry() = (TQCOORD)yvec[3]; - - return p; -#else - - if ( size() != 4 ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPointArray::bezier: The array must have 4 control points" ); -#endif - TQPointArray pa; - return pa; - } else { - TQRect r = boundingRect(); - int m = 4+2*TQMAX(r.width(),r.height()); - double *p = new double[m]; - double ctrl[8]; - int i; - for (i=0; i<4; i++) { - ctrl[i*2] = at(i).x(); - ctrl[i*2+1] = at(i).y(); - } - int len=0; - polygonizeTQBezier( p, len, ctrl, m ); - TQPointArray pa((len/2)+1); // one extra point for last point on line - int j=0; - for (i=0; j>( TQDataStream &s, TQPointArray &a ) -{ - uint i; - uint len; - s >> len; // read size of array - if ( !a.resize( len ) ) // no memory - return s; - TQPoint p; - for ( i=0; i> p; - a.setPoint( i, p ); - } - return s; -} -#endif //TQT_NO_DATASTREAM - - - -struct TQShortPoint { // Binary compatible with XPoint - short x, y; -}; - -uint TQPointArray::splen = 0; -void* TQPointArray::sp = 0; // Really a TQShortPoint* - -/*! - \internal - - Converts the point coords to short (16bit) size, compatible with - X11's XPoint structure. The pointer returned points to a static - array, so its contents will be overwritten the next time this - function is called. -*/ - -void* TQPointArray::shortPoints( int index, int nPoints ) const -{ - - if ( isNull() || !nPoints ) - return 0; - TQPoint* p = data(); - p += index; - uint i = nPoints < 0 ? size() : nPoints; - if ( splen < i ) { - if ( sp ) - delete[] ((TQShortPoint*)sp); - sp = new TQShortPoint[i]; - splen = i; - } - TQShortPoint* ps = (TQShortPoint*)sp; - while ( i-- ) { - ps->x = (short)p->x(); - ps->y = (short)p->y(); - p++; - ps++; - } - return sp; -} - - -/*! - \internal - - Deallocates the internal buffer used by shortPoints(). -*/ - -void TQPointArray::cleanBuffers() -{ - if ( sp ) - delete[] ((TQShortPoint*)sp); - sp = 0; - splen = 0; -} diff --git a/src/kernel/qpolygonscanner.cpp b/src/kernel/qpolygonscanner.cpp index 95ebcff71..44d59e7b8 100644 --- a/src/kernel/qpolygonscanner.cpp +++ b/src/kernel/qpolygonscanner.cpp @@ -39,7 +39,7 @@ **********************************************************************/ #include "ntqpolygonscanner.h" -#include "ntqpointarray.h" +#include "tqpointarray.h" #include diff --git a/src/kernel/qprinter.cpp b/src/kernel/qprinter.cpp deleted file mode 100644 index 37ef9af8f..000000000 --- a/src/kernel/qprinter.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/********************************************************************** -** -** Implementation of TQPrinter class -** -** Created : 941003 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqprinter.h" -#include "qprinter_p.h" - -#ifndef TQT_NO_PRINTER - -/*! - \class TQPrinter ntqprinter.h - \brief The TQPrinter class is a paint device that paints on a printer. - - \ingroup images - \ingroup graphics - \mainclass - - On Windows it uses the built-in printer drivers. On X11 it - generates postscript and sends that to lpr, lp, or another print - command. - - TQPrinter is used in much the same way as TQWidget and TQPixmap are - used. The big difference is that you must keep track of the pages. - - TQPrinter supports a number of settable parameters, most of which - can be changed by the end user when the application calls - TQPrinter::setup(). - - The most important parameters are: - \list - \i setOrientation() tells TQPrinter which page orientation to use (virtual). - \i setPageSize() tells TQPrinter what page size to expect from the - printer. - \i setResolution() tells TQPrinter what resolution you wish the - printer to provide (in dpi). - \i setFullPage() tells TQPrinter whether you want to deal with the - full page or just with the part the printer can draw on. The - default is FALSE, so that by default you should be able to paint - on (0,0). If TRUE the origin of the coordinate system will be in - the top left corner of the paper and most probably the printer - will not be able to paint something there due to it's physical - margins. - \i setNumCopies() tells TQPrinter how many copies of the document - it should print. - \i setMinMax() tells TQPrinter and TQPrintDialog what the allowed - range for fromPage() and toPage() are. - \endlist - - Except where noted, you can only call the set functions before - setup(), or between TQPainter::end() and setup(). (Some may take - effect between setup() and begin(), or between begin() and end(), - but that's strictly undocumented and such behaviour may differ - depending on platform.) - - There are also some settings that the user sets (through the - printer dialog) and that applications are expected to obey: - - \list - - \i pageOrder() tells the application program whether to print - first-page-first or last-page-first. - - \i colorMode() tells the application program whether to print in - color or grayscale. (If you print in color and the printer does - not support color, TQt will try to approximate. The document may - take longer to print, but the quality should not be made visibly - poorer.) - - \i fromPage() and toPage() indicate what pages the application - program should print. - - \i paperSource() tells the application progam which paper source - to print from. - - \endlist - - You can of course call these functions to establish defaults - before you ask the user through TQPrinter::setup(). - - Once you start printing, calling newPage() is essential. You will - probably also need to look at the TQPaintDeviceMetrics for the - printer (see the \link simple-application.html#printersimple print - function\endlink in the Application walk-through). In previous versions, - paint device metrics were valid only after the TQPrinter has been set - up, i.e. after setup() has returned successfully. This is no longer - the case and paint device metrics can be requested safely before set up. - - If you want to abort the print job, abort() will try its best to - stop printing. It may cancel the entire job or just some of it. - - \omit Need a function to setup() without a dialog (i.e. use defaults). - \endomit - - The TrueType font embedding for TQt's postscript driver uses code - by David Chappell of Trinity College Computing Center. - - \legalese - - Copyright 1995, Trinity College Computing Center. - Written by David Chappell. - - Permission to use, copy, modify, and distribute this software and - its documentation for any purpose and without fee is hereby - granted, provided that the above copyright notice appear in all - copies and that both that copyright notice and this permission - notice appear in supporting documentation. This software is - provided "as is" without express or implied warranty. - - TrueType font support. These functions allow PPR to generate - PostScript fonts from Microsoft compatible TrueType font files. - - The functions in this file do most of the work to convert a - TrueType font to a type 3 PostScript font. - - Most of the material in this file is derived from a program called - "ttf2ps" which L. S. Ng posted to the usenet news group - "comp.sources.postscript". The author did not provide a copyright - notice or indicate any restrictions on use. - - Last revised 11 July 1995. - -*/ - -/*! - \enum TQPrinter::PrinterMode - - This enum describes the mode the printer should work in. It - basically presets a certain resolution and working mode. - - \value ScreenResolution Sets the resolution of the print device to - the screen resolution. This has the big advantage that the results - obtained when painting on the printer will match more or less - exactly the visible output on the screen. It is the easiest to - use, as font metrics on the screen and on the printer are the - same. This is the default value. ScreenResolution will produce a - lower quality output than HighResolution and should only be used - for drafts. - - \value PrinterResolution Use the physical resolution of the - printer on Windows. On Unix, set the postscript resolution to 72 - dpi. - - \value HighResolution Use printer resolution on windows, set the - resolution of the postscript driver to 600dpi. - - \value Compatible Almost the same as PrinterResolution, but keeps - some peculiarities of the TQt 2.x printer driver. This is useful - for applications ported from TQt 2.x to TQt 3.x. -*/ - -/*! - \enum TQPrinter::Orientation - - This enum type (not to be confused with TQt::Orientation) is used - to specify each page's orientation. - - \value Portrait the page's height is greater than its width (the - default). - - \value Landscape the page's width is greater than its height. - - This type interacts with \l TQPrinter::PageSize and - TQPrinter::setFullPage() to determine the final size of the page - available to the application. -*/ - - -/*! - \enum TQPrinter::PageSize - - This enum type specifies what paper size TQPrinter should use. - TQPrinter does not check that the paper size is available; it just - uses this information, together with TQPrinter::Orientation and - TQPrinter::setFullPage(), to determine the printable area (see - TQPaintDeviceMetrics). - - The defined sizes (with setFullPage(TRUE)) are: - - \value A0 841 x 1189 mm This value is not supported on windows. - \value A1 594 x 841 mm This value is not supported on windows. - \value A2 420 x 594 mm - \value A3 297 x 420 mm - \value A4 210 x 297 mm, 8.26 x 11.7 inches - \value A5 148 x 210 mm - \value A6 105 x 148 mm - \value A7 74 x 105 mm - \value A8 52 x 74 mm - \value A9 37 x 52 mm - \value B0 1030 x 1456 mm - \value B1 728 x 1030 mm - \value B10 32 x 45 mm - \value B2 515 x 728 mm - \value B3 364 x 515 mm - \value B4 257 x 364 mm - \value B5 182 x 257 mm, 7.17 x 10.13 inches - \value B6 128 x 182 mm - \value B7 91 x 128 mm - \value B8 64 x 91 mm - \value B9 45 x 64 mm - \value C5E 163 x 229 mm - \value Comm10E 105 x 241 mm, US Common #10 Envelope - \value DLE 110 x 220 mm - \value Executive 7.5 x 10 inches, 191 x 254 mm - \value Folio 210 x 330 mm - \value Ledger 432 x 279 mm - \value Legal 8.5 x 14 inches, 216 x 356 mm - \value Letter 8.5 x 11 inches, 216 x 279 mm - \value Tabloid 279 x 432 mm - \value Custom - \value NPageSize (internal) - - With setFullPage(FALSE) (the default), the metrics will be a bit - smaller; how much depends on the printer in use. -*/ - - -/*! - \enum TQPrinter::PageOrder - - This enum type is used by TQPrinter to tell the application program - how to print. - - \value FirstPageFirst the lowest-numbered page should be printed - first. - - \value LastPageFirst the highest-numbered page should be printed - first. -*/ - -/*! - \enum TQPrinter::ColorMode - - This enum type is used to indicate whether TQPrinter should print - in color or not. - - \value Color print in color if available, otherwise in grayscale. - - \value GrayScale print in grayscale, even on color printers. - Might be a little faster than \c Color. This is the default. -*/ - -/*! - \enum TQPrinter::PaperSource - - This enum type specifies what paper source TQPrinter is to use. - TQPrinter does not check that the paper source is available; it - just uses this information to try and set the paper source. - Whether it will set the paper source depends on whether the - printer has that particular source. - - Note: this is currently only implemented for Windows. - - \value OnlyOne - \value Lower - \value Middle - \value Manual - \value Envelope - \value EnvelopeManual - \value Auto - \value Tractor - \value SmallFormat - \value LargeFormat - \value LargeCapacity - \value Cassette - \value FormSource -*/ - -/*! - \enum TQPrinter::PrintRange - - This enum is used to specify which print range the application - should use to print. - - \value AllPages All pages should be printed - \value Selection Only the selection should be printed. - \value PageRange From page, to page option. - - \sa setPrintRange(), printRange() -*/ - -/*! - \enum TQPrinter::PrinterOption - - This enum describes various printer options that appear in the - printer setup dialog. It is used to enable and disable these - options in the setup dialog. - - \value PrintToFile Describes if print to file should be enabled. - \value PrintSelection Describes if printing selections should be enabled. - \value PrintPageRange Describes if printing page ranges (from, to) should - be enabled - - \sa setOptionEnabled(), isOptionEnabled() -*/ - - -/*! - \fn TQString TQPrinter::printerName() const - - Returns the printer name. This value is initially set to the name - of the default printer. - - \sa setPrinterName() -*/ - -/*! - \fn bool TQPrinter::outputToFile() const - - Returns TRUE if the output should be written to a file, or FALSE - if the output should be sent directly to the printer. The default - setting is FALSE. - - This function is currently only supported under X11 and Mac OS X. - - \sa setOutputToFile(), setOutputFileName() -*/ - -/*! - Specifies whether the output should be written to a file or sent - directly to the printer. - - Will output to a file if \a enable is TRUE, or will output - directly to the printer if \a enable is FALSE. - - This function is currently only supported under X11 and Mac OS X. - - \sa outputToFile(), setOutputFileName() -*/ - -void TQPrinter::setOutputToFile( bool enable ) -{ - if ( state != 0 ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPrinter::setOutputToFile: Cannot do this during printing" ); -#endif - return; - } - output_file = enable; -} - - -/*! - \fn TQString TQPrinter::outputFileName() const - - Returns the name of the output file. There is no default file - name. - - \sa setOutputFileName(), setOutputToFile() -*/ - -/*! - Sets the name of the output file to \a fileName. - - Setting a null or empty name (0 or "") disables output to a file, - i.e. calls setOutputToFile(FALSE). Setting a non-empty name - enables output to a file, i.e. calls setOutputToFile(TRUE). - - This function is currently only supported under X11. - - \sa outputFileName(), setOutputToFile() -*/ - -void TQPrinter::setOutputFileName( const TQString &fileName ) -{ - if ( state != 0 ) { -#if defined(QT_CHECK_STATE) - tqWarning("TQPrinter::setOutputFileName: Cannot do this during printing"); -#endif - return; - } - output_filename = fileName; - output_file = !output_filename.isEmpty(); -} - - -/*! - \fn TQString TQPrinter::printProgram() const - - Returns the name of the program that sends the print output to the - printer. - - The default is to return a null string; meaning that TQPrinter will - try to be smart in a system-dependent way. On X11 only, you can - set it to something different to use a specific print program. - - On Windows, this function returns the name of the printer device - driver. - - \sa setPrintProgram() setPrinterSelectionOption() -*/ - -/*! - Sets the name of the program that should do the print job to \a - printProg. - - On X11, this function sets the program to call with the PostScript - output. On other platforms, it has no effect. - - \sa printProgram() -*/ - -void TQPrinter::setPrintProgram( const TQString &printProg ) -{ - print_prog = printProg; -} - - -/*! - \fn TQString TQPrinter::docName() const - - Returns the document name. - - \sa setDocName() -*/ - -/*! - Sets the document name to \a name. -*/ - -void TQPrinter::setDocName( const TQString &name ) -{ - if ( state != 0 ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPrinter::setDocName: Cannot do this during printing" ); -#endif - return; - } - doc_name = name; -} - - -/*! - \fn TQString TQPrinter::creator() const - - Returns the name of the application that created the document. - - \sa setCreator() -*/ - -/*! - Sets the name of the application that created the document to \a - creator. - - This function is only applicable to the X11 version of TQt. If no - creator name is specified, the creator will be set to "TQt" - followed by some version number. - - \sa creator() -*/ - -void TQPrinter::setCreator( const TQString &creator ) -{ - creator_name = creator; -} - - -/*! - \fn Orientation TQPrinter::orientation() const - - Returns the orientation setting. The default value is \c - TQPrinter::Portrait. - - \sa setOrientation() -*/ - -/*! - Sets the print orientation to \a orientation. - - The orientation can be either \c TQPrinter::Portrait or \c - TQPrinter::Landscape. - - The printer driver reads this setting and prints using the - specified orientation. On Windows this setting won't take effect - until the printer dialog is shown (using TQPrinter::setup()). - - Windows only! This option can be changed while printing and will - take effect from the next call to newPage() - - \sa orientation() -*/ - -void TQPrinter::setOrientation( Orientation orientation ) -{ - orient = orientation; -#if defined(TQ_WS_WIN) - reinit(); -#endif -} - - -/*! - \fn PageSize TQPrinter::pageSize() const - - Returns the printer page size. The default value is system-dependent. - - \sa setPageSize() -*/ - - -/*! - Sets the printer page size to \a newPageSize if that size is - supported. The result if undefined if \a newPageSize is not - supported. - - The default page size is system-dependent. - - This function is useful mostly for setting a default value that - the user can override in the print dialog when you call setup(). - - \sa pageSize() PageSize setFullPage() setResolution() -*/ - -void TQPrinter::setPageSize( PageSize newPageSize ) -{ - if ( newPageSize > NPageSize ) { -#if defined(QT_CHECK_STATE) - tqWarning("TQPrinter::SetPageSize: illegal page size %d", newPageSize ); -#endif - return; - } - page_size = newPageSize; -#if defined(TQ_WS_WIN) - reinit(); -#endif -} - -/*! - Sets the page order to \a newPageOrder. - - The page order can be \c TQPrinter::FirstPageFirst or \c - TQPrinter::LastPageFirst. The application programmer is responsible - for reading the page order and printing accordingly. - - This function is useful mostly for setting a default value that - the user can override in the print dialog when you call setup(). - - \bug This value is not kept in sync with the Windows or Mac OS X printer - dialogs. -*/ - -void TQPrinter::setPageOrder( PageOrder newPageOrder ) -{ - page_order = newPageOrder; -#if defined(TQ_WS_WIN) - reinit(); -#endif -} - - -/*! - Returns the current page order. - - The default page order is \c FirstPageFirst. - - \bug This value is not kept in sync with the Windows or Mac OS X printer - dialogs. -*/ - -TQPrinter::PageOrder TQPrinter::pageOrder() const -{ - return page_order; -} - - -/*! - Sets the printer's color mode to \a newColorMode, which can be - either \c Color or \c GrayScale (the default). - - \sa colorMode() -*/ - -void TQPrinter::setColorMode( ColorMode newColorMode ) -{ - color_mode = newColorMode; -#if defined(TQ_WS_WIN) - reinit(); -#endif -} - - -/*! - Returns the current color mode. The default color mode is \c - Color. - - \sa setColorMode() -*/ - -TQPrinter::ColorMode TQPrinter::colorMode() const -{ - return color_mode; -} - - -/*! - \fn int TQPrinter::fromPage() const - - Returns the from-page setting. The default value is 0. - - If fromPage() and toPage() both return 0 this signifies 'print the - whole document'. - - The programmer is responsible for reading this setting and - printing accordingly. - - \sa setFromTo(), toPage() -*/ - -/*! - \fn int TQPrinter::toPage() const - - Returns the to-page setting. The default value is 0. - - If fromPage() and toPage() both return 0 this signifies 'print the - whole document'. - - The programmer is responsible for reading this setting and - printing accordingly. - - \sa setFromTo(), fromPage() -*/ - -/*! - Sets the from-page and to-page settings to \a fromPage and \a - toPage respectively. - - The from-page and to-page settings specify what pages to print. - - If fromPage() and toPage() both return 0 this signifies 'print the - whole document'. - - This function is useful mostly to set a default value that the - user can override in the print dialog when you call setup(). - - \sa fromPage(), toPage(), setMinMax(), setup() -*/ - -void TQPrinter::setFromTo( int fromPage, int toPage ) -{ - if ( state != 0 ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPrinter::setFromTo: Cannot do this during printing" ); -#endif - return; - } - from_pg = fromPage; - to_pg = toPage; -} - - -/*! - \fn int TQPrinter::minPage() const - - Returns the min-page setting, i.e. the lowest page number a user - is allowed to choose. The default value is 0. - - \sa maxPage(), setMinMax() setFromTo() -*/ - -/*! - \fn int TQPrinter::maxPage() const - - Returns the max-page setting. A user can't choose a higher page - number than maxPage() when they select a print range. The default - value is 0. - - \sa minPage(), setMinMax() setFromTo() -*/ - -/*! - Sets the min-page and max-page settings to \a minPage and \a - maxPage respectively. - - The min-page and max-page restrict the from-page and to-page - settings. When the printer setup dialog appears, the user cannot - select a from page or a to page that are outside the range - specified by min and max pages. - - \sa minPage(), maxPage(), setFromTo(), setup() -*/ - -void TQPrinter::setMinMax( int minPage, int maxPage ) -{ - min_pg = minPage; - max_pg = maxPage; - if ( from_pg == 0 || from_pg < minPage ) - from_pg = minPage; - if ( to_pg == 0 || to_pg > maxPage ) - to_pg = maxPage; -} - - -/*! - \fn int TQPrinter::numCopies() const - - Returns the number of copies to be printed. The default value is 1. - - This value will return the number of times the application is - required to print in order to match the number specified in the - printer setup dialog. This has been done since some printer - drivers are not capable of buffering up the copies and the - application in those cases have to make an explicit call to the - print code for each copy. - - \sa setNumCopies() -*/ - -/*! - \fn bool TQPrinter::collateCopiesEnabled() const - - \internal - - Returns TRUE if the application should provide the user with the - option of choosing a collated printout; otherwise returns FALSE. - - Collation means that each page is printed in order, i.e. print the - first page, then the second page, then the third page and so on, and - then repeat this sequence for as many copies as have been requested. - If you don't collate you get several copies of the first page, then - several copies of the second page, then several copies of the third - page, and so on. - - \sa setCollateCopiesEnabled() setCollateCopies() collateCopies() -*/ - -/*! - \fn void TQPrinter::setCollateCopiesEnabled(bool enable) - - \internal - - If \a enable is TRUE (the default) the user is given the choice of - whether to print out multiple copies collated in the print dialog. - If \a enable is FALSE, then collateCopies() will be ignored. - - Collation means that each page is printed in order, i.e. print the - first page, then the second page, then the third page and so on, and - then repeat this sequence for as many copies as have been requested. - If you don't collate you get several copies of the first page, then - several copies of the second page, then several copies of the third - page, and so on. - - \sa collateCopiesEnabled() setCollateCopies() collateCopies() -*/ - -/*! - \fn bool TQPrinter::collateCopies() const - - \internal - - Returns TRUE if collation is turned on when multiple copies is selected. - Returns FALSE if it is turned off when multiple copies is selected. - - \sa collateCopiesEnabled() setCollateCopiesEnabled() setCollateCopies() -*/ - -/*! - \internal - - Sets the default value for collation checkbox when the print dialog appears. - If \a on is TRUE, it will enable setCollateCopiesEnabled(). - The default value is FALSE. This value will be changed by what the - user presses in the print dialog. - - \sa collateCopiesEnabled() setCollateCopiesEnabled() collateCopies() -*/ - -void TQPrinter::setCollateCopies(bool on) -{ - if (!collateCopiesEnabled() && on) - setCollateCopiesEnabled(on); - usercolcopies = on; -} - -/*! - Sets the number of copies to be printed to \a numCopies. - - The printer driver reads this setting and prints the specified - number of copies. - - \sa numCopies(), setup() -*/ - -void TQPrinter::setNumCopies( int numCopies ) -{ - ncopies = numCopies; -#if defined(TQ_WS_WIN) - reinit(); -#endif -} - - -/*! - Returns the printer options selection string. This is useful only - if the print command has been explicitly set. - - The default value (a null string) implies that the printer should - be selected in a system-dependent manner. - - Any other value implies that the given value should be used. - - \sa setPrinterSelectionOption() -*/ - -TQString TQPrinter::printerSelectionOption() const -{ - return option_string; -} - - -/*! - Sets the printer to use \a option to select the printer. \a option - is null by default (which implies that TQt should be smart enough - to guess correctly), but it can be set to other values to use a - specific printer selection option. - - If the printer selection option is changed while the printer is - active, the current print job may or may not be affected. - - \sa printerSelectionOption() -*/ - -void TQPrinter::setPrinterSelectionOption( const TQString & option ) -{ - option_string = option; -} - - -/*! - Sets TQPrinter to have the origin of the coordinate system at the - top-left corner of the paper if \a fp is TRUE, or where it thinks - the top-left corner of the printable area is if \a fp is FALSE. - - The default is FALSE. You can (probably) print on (0,0), and - TQPaintDeviceMetrics will report something smaller than the size - indicated by PageSize. (Note that TQPrinter may be wrong on Unix - systems - it does not have perfect knowledge of the physical - printer.) - - If you set \a fp to TRUE, TQPaintDeviceMetrics will report the - exact same size as indicated by \c PageSize, but you cannot print - on all of that - you must take care of the output margins - yourself. - - \sa PageSize setPageSize() TQPaintDeviceMetrics fullPage() -*/ - -void TQPrinter::setFullPage( bool fp ) -{ - to_edge = fp; -} - - -/*! - Returns TRUE if the origin of the printer's coordinate system is - at the corner of the sheet and FALSE if it is at the edge of the - printable area. - - See setFullPage() for details and caveats. - - \sa setFullPage() PageSize TQPaintDeviceMetrics -*/ - -bool TQPrinter::fullPage() const -{ - return to_edge; -} - - -/*! - Requests that the printer prints at \a dpi or as near to \a dpi as - possible. - - This setting affects the coordinate system as returned by, for - example, TQPaintDeviceMetrics and TQPainter::viewport(). - - The value depends on the \c PrintingMode used in the TQPrinter - constructor. By default, the dpi value of the screen is used. - - This function must be called before setup() to have an effect on - all platforms. - - \sa resolution() setPageSize() -*/ - -void TQPrinter::setResolution( int dpi ) -{ - res = dpi; - res_set = TRUE; -} - - -/*! - Returns the current assumed resolution of the printer, as set by - setResolution() or by the printer subsystem. - - \sa setResolution() -*/ - -int TQPrinter::resolution() const -{ - return res; -} - -/*! - Sets the paper source setting to \a source. - - Windows only! This option can be changed while printing and will - take effect from the next call to newPage() - - \sa paperSource() -*/ - -void TQPrinter::setPaperSource( PaperSource source ) -{ - paper_source = source; -#if defined(TQ_WS_WIN) - reinit(); -#endif -} - -/*! - Returns the currently set paper source of the printer. - - \sa setPaperSource() -*/ - -TQPrinter::PaperSource TQPrinter::paperSource() const -{ - return paper_source; -} - -/*! - Sets the default selected page range to be used when the print setup - dialog is opened to \a range. If the PageRange specified by \a range is - currently disabled the function does nothing. - - \sa printRange() -*/ -void TQPrinter::setPrintRange( PrintRange range ) -{ - if( range != AllPages ) { - if( range == Selection - && !isOptionEnabled( PrintSelection ) ) { - setOptionEnabled( PrintSelection, TRUE ); - } - else if( range == PageRange - && !isOptionEnabled( PrintPageRange ) ) { - setOptionEnabled( PrintPageRange, TRUE ); - } - } - d->printRange = range; -} - -/*! - Returns the PageRange of the TQPrinter. After the print setup dialog - has been opened, this function returns the value selected by the user. - - \sa setPrintRange() -*/ -TQPrinter::PrintRange TQPrinter::printRange() const -{ - return d->printRange; -} - -/*! - Enables the printer option with the identifier \a option if \a - enable is TRUE, and disables option \a option if \a enable is FALSE. - - \sa isOptionEnabled() -*/ -void TQPrinter::setOptionEnabled( PrinterOption option, bool enable ) -{ - if( enable ) { - d->printerOptions |= ( 1 << option ); - if( ( option == PrintPageRange ) && min_pg==0 && max_pg==0 ) - max_pg = 9999; - } else { - d->printerOptions &= ( ~( 1 << option ) ); - } -} - -/*! - Returns TRUE if the printer option with identifier \a option is enabled; - otherwise returns FALSE. - - \sa setOptionEnabled() - */ -bool TQPrinter::isOptionEnabled( PrinterOption option ) -{ - return d->printerOptions & ( 1 << option ); -} -#endif // TQT_NO_PRINTER - diff --git a/src/kernel/qprinter_p.h b/src/kernel/qprinter_p.h deleted file mode 100644 index 3b01895dd..000000000 --- a/src/kernel/qprinter_p.h +++ /dev/null @@ -1,62 +0,0 @@ -/********************************************************************** -** -** Definition of TQPrinter class -** -** Created : 940927 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#ifndef TQPRINTER_P_H -#define TQPRINTER_P_H -#ifndef TQT_NO_PRINTER - -#ifndef QT_H -#include -#include -#include -#include -#endif // QT_H - -class TQPrinterPrivate -{ -public: - TQ_UINT32 printerOptions; - TQPrinter::PrintRange printRange; - - virtual ~TQPrinterPrivate() {}; -}; - -#endif -#endif diff --git a/src/kernel/qprinter_unix.cpp b/src/kernel/qprinter_unix.cpp deleted file mode 100644 index 0c7cdfa6b..000000000 --- a/src/kernel/qprinter_unix.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQPrinter class for Unix -** -** Created : 950810 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "qplatformdefs.h" - -// POSIX Large File Support redefines open -> open64 -static inline int qt_open(const char *pathname, int flags, mode_t mode) -{ return ::open(pathname, flags, mode); } -#if defined(open) -# undef open -#endif - -#include "ntqprinter.h" - -#ifndef TQT_NO_PRINTER - -#include "tqpaintdevicemetrics.h" -#include "qpsprinter_p.h" -#include "ntqprintdialog.h" -#include "ntqapplication.h" -#include "qprinter_p.h" - -#include // For ::sleep() -#include - - -// NOT REVISED - - -class TQPrinterUnixPrivate : public TQPrinterPrivate -{ -public: - bool marginsSpecified; - uint topMargin; - uint leftMargin; - uint bottomMargin; - uint rightMargin; -}; - -#define D ( (TQPrinterUnixPrivate*) d ) - -/***************************************************************************** - TQPrinter member functions - *****************************************************************************/ - -// TQPrinter states - -#define PST_IDLE 0 -#define PST_ACTIVE 1 -#define PST_ERROR 2 -#define PST_ABORTED 3 - -// Default values for TQPrinter members - -struct PrinterDefaults { - TQString printerName; - bool outputToFile; - TQString outputFileName; - TQPrinter::Orientation orientation; - TQPrinter::PageSize pageSize; - TQPrinter::PageOrder pageOrder; - TQPrinter::ColorMode colorMode; - int numCopies; -}; - -static PrinterDefaults * globalPrinterDefaults = 0; - -/*! - Constructs a printer paint device with mode \a m. - - \sa TQPrinter::PrinterMode -*/ - -TQPrinter::TQPrinter( PrinterMode m ) - : TQPaintDevice( TQInternal::Printer | TQInternal::ExternalDevice ) -{ - pdrv = 0; - pid = 0; - orient = Portrait; - page_size = A4; - page_order = FirstPageFirst; - color_mode = GrayScale; - ncopies = 1; - printer_name = getenv("PRINTER"); - from_pg = to_pg = min_pg = max_pg = 0; - state = PST_IDLE; - output_file = FALSE; - to_edge = FALSE; - paper_source = OnlyOne; - switch ( m ) { - case ScreenResolution: - res = TQPaintDevice::x11AppDpiY(); - break; - case Compatible: - case PrinterResolution: - res = 72; - break; - case HighResolution: - res = 600; - } - - d = new TQPrinterUnixPrivate; - D->marginsSpecified = FALSE; - d->printerOptions = 0; - setOptionEnabled( PrintToFile, TRUE ); - setOptionEnabled( PrintPageRange, TRUE ); - setPrintRange( AllPages ); -} - -/*! - Destroys the printer paint device and cleans up. -*/ - -TQPrinter::~TQPrinter() -{ - delete pdrv; - if ( pid ) { - (void)::kill( pid, 6 ); - (void)::wait( 0 ); - pid = 0; - } - delete d; -} - - -/*! - Advances to a new page on the printer. Returns TRUE if successful; - otherwise returns FALSE. -*/ - -bool TQPrinter::newPage() -{ - if ( state == PST_ACTIVE && pdrv ) - return ((TQPSPrinter*)pdrv)->cmd( TQPSPrinter::NewPage, 0, 0 ); - return FALSE; -} - - -/*! - Aborts the print job. Returns TRUE if successful; otherwise - returns FALSE. - - \sa aborted() -*/ - -bool TQPrinter::abort() -{ - if ( state == PST_ACTIVE && pdrv ) { - ((TQPSPrinter*)pdrv)->cmd( TQPSPrinter::AbortPrinting, 0, 0 ); - state = PST_ABORTED; - if ( pid ) { - (void)::kill( pid, 6 ); - (void)::wait( 0 ); - pid = 0; - } - } - return state == PST_ABORTED; -} - -/*! - Returns TRUE if the print job was aborted; otherwise returns - FALSE. - - \sa abort() -*/ - -bool TQPrinter::aborted() const -{ - return state == PST_ABORTED; -} - -/*! - Sets the printer name to \a name. - - The default printer will be used if no printer name is set. - - Under X11, the \c PRINTER environment variable defines the default - printer. Under any other window system, the window system defines - the default printer. - - \sa printerName() -*/ - -void TQPrinter::setPrinterName( const TQString &name ) -{ - if ( state != 0 ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQPrinter::setPrinterName: Cannot do this during printing" ); -#endif - return; - } - printer_name = name; -} - -static void deleteGlobalPrinterDefaults() -{ - delete globalPrinterDefaults; - globalPrinterDefaults = 0; -} - -/*! - Opens a printer setup dialog, with parent \a parent, and asks the - user to specify which printer they wish to use and what settings - it should have. - - Returns TRUE if the user pressed "OK" to print, or FALSE if the - user canceled the operation. -*/ - -bool TQPrinter::setup( TQWidget * parent ) -{ -#ifndef TQT_NO_PRINTDIALOG - bool result = TQPrintDialog::getPrinterSetup( this, parent ); -#else - bool result = FALSE; -#endif - if ( result ) { - if ( !globalPrinterDefaults ) { - globalPrinterDefaults = new PrinterDefaults; - tqAddPostRoutine( deleteGlobalPrinterDefaults ); - } - globalPrinterDefaults->printerName = printerName(); - globalPrinterDefaults->outputToFile = outputToFile(); - globalPrinterDefaults->outputFileName = outputFileName(); - globalPrinterDefaults->orientation = orientation(); - globalPrinterDefaults->pageSize = pageSize(); - globalPrinterDefaults->pageOrder = pageOrder(); - globalPrinterDefaults->colorMode = colorMode(); - } - return result; -} - -static void closeAllOpenFds() -{ - // hack time... getting the maximum number of open - // files, if possible. if not we assume it's the - // larger of 256 and the fd we got - int i; -#if defined(Q_OS_OS2EMX) - LONG req_count = 0; - ULONG rc, handle_count; - rc = DosSetRelMaxFH (&req_count, &handle_count); - /* if (rc != NO_ERROR) ... */ - i = (int)handle_count; -#elif defined(_SC_OPEN_MAX) - i = (int)sysconf( _SC_OPEN_MAX ); -#elif defined(_POSIX_OPEN_MAX) - i = (int)_POSIX_OPEN_MAX; -#elif defined(OPEN_MAX) - i = (int)OPEN_MAX; -#else - i = TQMAX( 256, fds[0] ); -#endif // Q_OS_OS2EMX // ways-to-set i - while( --i > 0 ) - ::close( i ); -} - - - -static const char * const psToStr[TQPrinter::NPageSize+1] = -{ "A4", "B5", "Letter", "Legal", "Executive", - "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1", - "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E", - "DLE", "Folio", "Ledger", "Tabloid", 0 -}; - - -/*! - \internal - Handles painter commands to the printer. -*/ - -bool TQPrinter::cmd( int c, TQPainter *paint, TQPDevCmdParam *p ) -{ - if ( c == PdcBegin ) { - if ( state == PST_IDLE ) { - if ( output_file ) { - int fd = 0; - fd = qt_open( output_filename.local8Bit(), - O_CREAT | O_NOCTTY | O_TRUNC | O_WRONLY, - 0666 ); - if ( fd >= 0 ) { - pdrv = new TQPSPrinter( this, fd ); - state = PST_ACTIVE; - } - } else { - TQString pr; - if ( printer_name ) - pr = printer_name; - TQApplication::flushX(); - int fds[2]; - if ( pipe( fds ) != 0 ) { - tqWarning( "TQPSPrinter: could not open pipe to print" ); - state = PST_ERROR; - return FALSE; - } - -// ### shouldn't we use TQProcess here???? -#if 0 && defined(Q_OS_OS2EMX) - // this code is still not used, and maybe it's not - // usable either, any more. if you want to use it, - // you may need to fix it first. - - // old comment: - - // this code is usable but not in use. spawn() is - // preferable to fork()/exec() for very large - // programs. if fork()/exec() is a problem and you - // use OS/2, remove '0 && ' from the #if. - int tmp; - tmp = dup(0); - dup2( fds[0], 0 ); - ::close( fds[0] ); - fcntl(tmp, F_SETFD, FD_CLOEXEC); - fcntl(fds[1], F_SETFD, FD_CLOEXEC); - if ( option_string ) - pr.prepend( option_string ); - else - pr.prepend( "-P" ); // ### - if ( spawnlp(P_NOWAIT,print_prog.data(), print_prog.data(), - pr.data(), output->name(), 0) == -1 ) { - ; // couldn't exec, ignored - } - dup2( tmp, 0 ); - ::close( tmp ); - pdrv = new TQPSPrinter( this, fds[1] ); - state = PST_ACTIVE; -#else - pid = fork(); - if ( pid == 0 ) { // child process - // if possible, exit quickly, so the actual lp/lpr - // becomes a child of init, and ::waitpid() is - // guaranteed not to wait. - if ( fork() > 0 ) { - closeAllOpenFds(); - - // try to replace this process with "true" - this prevents - // global destructors from being called (that could possibly - // do wrong things to the parent process) - (void)execlp("true", "true", (char *)0); - (void)execl("/bin/true", "true", (char *)0); - (void)execl("/usr/bin/true", "true", (char *)0); - ::exit( 0 ); - } - dup2( fds[0], 0 ); - - closeAllOpenFds(); - - if ( print_prog ) { - if ( option_string ) - pr.prepend( option_string ); - else - pr.prepend( TQString::fromLatin1( "-P" ) ); - (void)execlp( print_prog.ascii(), print_prog.ascii(), - pr.ascii(), (char *)0 ); - } else { - // if no print program has been specified, be smart - // about the option string too. - TQStringList lprhack; - TQStringList lphack; - TQString media; - if ( pr || option_string ) { - if ( option_string ) { - lprhack = TQStringList::split(TQChar(' '), option_string); - lphack = lprhack; - } else { - lprhack.append( TQString::fromLatin1( "-P" ) ); - lphack.append( TQString::fromLatin1( "-d" ) ); - } - lprhack.append(pr); - lphack.append(pr); - } - char ** lpargs = new char *[lphack.size()+6]; - lpargs[0] = (char *)"lp"; - uint i; - for (i = 0; i < lphack.size(); ++i) - lpargs[i+1] = (char *)lphack[i].ascii(); -#ifndef Q_OS_OSF - if (psToStr[page_size]) { - lpargs[++i] = (char *)"-o"; - lpargs[++i] = (char *)psToStr[page_size]; - lpargs[++i] = (char *)"-o"; - media = "media="; - media += psToStr[page_size]; - lpargs[++i] = (char *)media.ascii(); - } -#endif - lpargs[++i] = 0; - char **lprargs = new char *[lprhack.size()+1]; - lprargs[0] = (char *)"lpr"; - for (uint x = 0; x < lprhack.size(); ++x) - lprargs[x+1] = (char *)lprhack[x].ascii(); - lprargs[lprhack.size() + 1] = 0; - (void)execvp( "lp", lpargs ); - (void)execvp( "lpr", lprargs ); - (void)execv( "/bin/lp", lpargs); - (void)execv( "/bin/lpr", lprargs); - (void)execv( "/usr/bin/lp", lpargs); - (void)execv( "/usr/bin/lpr", lprargs); - } - // if we couldn't exec anything, close the fd, - // wait for a second so the parent process (the - // child of the GUI process) has exited. then - // exit. - ::close( 0 ); - (void)::sleep( 1 ); - ::exit( 0 ); - } else { // parent process - ::close( fds[0] ); - pdrv = new TQPSPrinter( this, fds[1] ); - state = PST_ACTIVE; - } -#endif // else part of Q_OS_OS2EMX - } - if ( state == PST_ACTIVE && pdrv ) - return ((TQPSPrinter*)pdrv)->cmd( c, paint, p ); - } else { - // ignore it? I don't know - } - } else { - bool r = FALSE; - if ( state == PST_ACTIVE && pdrv ) { - r = ((TQPSPrinter*)pdrv)->cmd( c, paint, p ); - if ( c == PdcEnd ) { - state = PST_IDLE; - delete pdrv; - pdrv = 0; - if ( pid ) { - (void)::waitpid( pid, 0, 0 ); - pid = 0; - } - } - } else if ( state == PST_ABORTED && c == PdcEnd ) - state = PST_IDLE; - return r; - } - return TRUE; -} - - -#define MM(n) int((n * 720 + 127) / 254) -#define IN(n) int(n * 72) - -struct PaperSize { - int width, height; -}; - -static const PaperSize paperSizes[TQPrinter::NPageSize] = -{ - { MM(210), MM(297) }, // A4 - { MM(176), MM(250) }, // B5 - { IN(8.5), IN(11) }, // Letter - { IN(8.5), IN(14) }, // Legal - { IN(7.5), IN(10) }, // Executive - { MM(841), MM(1189) }, // A0 - { MM(594), MM(841) }, // A1 - { MM(420), MM(594) }, // A2 - { MM(297), MM(420) }, // A3 - { MM(148), MM(210) }, // A5 - { MM(105), MM(148) }, // A6 - { MM(74), MM(105)}, // A7 - { MM(52), MM(74) }, // A8 - { MM(37), MM(52) }, // A9 - { MM(1000), MM(1414) }, // B0 - { MM(707), MM(1000) }, // B1 - { MM(31), MM(44) }, // B10 - { MM(500), MM(707) }, // B2 - { MM(353), MM(500) }, // B3 - { MM(250), MM(353) }, // B4 - { MM(125), MM(176) }, // B6 - { MM(88), MM(125) }, // B7 - { MM(62), MM(88) }, // B8 - { MM(44), MM(62) }, // B9 - { MM(162), MM(229) }, // C5E - { IN(4.125), IN(9.5) }, // Comm10E - { MM(110), MM(220) }, // DLE - { IN(8.5), IN(13) }, // Folio - { IN(17), IN(11) }, // Ledger - { IN(11), IN(17) } // Tabloid -}; - -/*! - Internal implementation of the virtual TQPaintDevice::metric() function. - - Use the TQPaintDeviceMetrics class instead. - - \internal - Hard coded return values for PostScript under X. -*/ - -int TQPrinter::metric( int m ) const -{ - int val; - PageSize s = pageSize(); -#if defined(QT_CHECK_RANGE) - Q_ASSERT( (uint)s < (uint)NPageSize ); -#endif - switch ( m ) { - case TQPaintDeviceMetrics::PdmWidth: - val = orient == Portrait ? paperSizes[s].width : paperSizes[s].height; - if ( res != 72 ) - val = (val * res + 36) / 72; - if ( !fullPage() ) { - if ( D->marginsSpecified ) - val -= D->leftMargin + D->rightMargin; - else - val -= 2*margins().width(); - } - break; - case TQPaintDeviceMetrics::PdmHeight: - val = orient == Portrait ? paperSizes[s].height : paperSizes[s].width; - if ( res != 72 ) - val = (val * res + 36) / 72; - if ( !fullPage() ) { - if ( D->marginsSpecified ) - val -= D->topMargin + D->bottomMargin; - else - val -= 2*margins().height(); - } - break; - case TQPaintDeviceMetrics::PdmDpiX: - val = res; - break; - case TQPaintDeviceMetrics::PdmDpiY: - val = res; - break; - case TQPaintDeviceMetrics::PdmPhysicalDpiX: - case TQPaintDeviceMetrics::PdmPhysicalDpiY: - val = 72; - break; - case TQPaintDeviceMetrics::PdmWidthMM: - // double rounding error here. hooray. - val = metric( TQPaintDeviceMetrics::PdmWidth ); - val = (val * 254 + 5*res) / (10*res); - break; - case TQPaintDeviceMetrics::PdmHeightMM: - val = metric( TQPaintDeviceMetrics::PdmHeight ); - val = (val * 254 + 5*res) / (10*res); - break; - case TQPaintDeviceMetrics::PdmNumColors: - val = 16777216; - break; - case TQPaintDeviceMetrics::PdmDepth: - val = 24; - break; - default: - val = 0; -#if defined(QT_CHECK_RANGE) - tqWarning( "TQPixmap::metric: Invalid metric command" ); -#endif - } - return val; -} - - -/*! - Returns the width of the left margin and the height of the top - margin of the printer. On Unix, this is a best-effort guess, not - based on perfect knowledge. - - If you have called setFullPage( TRUE ), margins().width() may be - treated as the smallest sane left margin you can use, and - margins().height() as the smallest sane top margin you can - use. - - If you have called setFullPage( FALSE ) (this is the default), - margins() is automatically subtracted from the pageSize() by - TQPrinter. - - \sa setFullPage() TQPaintDeviceMetrics PageSize -*/ -TQSize TQPrinter::margins() const -{ - if ( D->marginsSpecified ) - return TQSize( D->leftMargin, D->topMargin ); - - if (orient == Portrait) - return TQSize( res/2, res/3 ); - - return TQSize( res/3, res/2 ); -} - -/*! - \overload - - Sets \a top, \a left, \a bottom and \a right to the margins of the - printer. On Unix, this is a best-effort guess, not based on - perfect knowledge. - - If you have called setFullPage( TRUE ), the four values specify - the smallest sane margins you can use. - - If you have called setFullPage( FALSE ) (this is the default), - the margins are automatically subtracted from the pageSize() by - TQPrinter. - - \sa setFullPage() TQPaintDeviceMetrics PageSize -*/ -void TQPrinter::margins( uint *top, uint *left, uint *bottom, uint *right ) const -{ - if ( !D->marginsSpecified ) { - int x = orient == Portrait ? res/2 : res/3; - int y = orient == Portrait ? res/3 : res/2; - *top = *bottom = y; - *left = *right = x; - } else { - *top = D->topMargin; - *left = D->leftMargin; - *bottom = D->bottomMargin; - *right = D->rightMargin; - } -} - -/*! - Sets the printer margins to the sizes specified in \a top, \a left, - \a bottom and \a right. - - This function currently only has an effect on Unix systems. - - \sa margins() -*/ -void TQPrinter::setMargins( uint top, uint left, uint bottom, uint right ) -{ - D->topMargin = top; - D->leftMargin = left; - D->bottomMargin = bottom; - D->rightMargin = right; - D->marginsSpecified = TRUE; -} - -#endif diff --git a/src/kernel/qpsprinter_p.h b/src/kernel/qpsprinter_p.h index 47939b1db..46d93b4b2 100644 --- a/src/kernel/qpsprinter_p.h +++ b/src/kernel/qpsprinter_p.h @@ -48,7 +48,7 @@ // ------------- // // This file is not part of the TQt API. It exists for the convenience -// of qpsprinter.cpp and qprinter_x11.cpp. +// of qpsprinter.cpp and tqprinter_x11.cpp. // This header file may change from version to version without notice, // or even be removed. // @@ -58,7 +58,7 @@ #ifndef QT_H -#include "ntqprinter.h" +#include "tqprinter.h" #include "tqtextstream.h" #endif // QT_H diff --git a/src/kernel/qrect.cpp b/src/kernel/qrect.cpp deleted file mode 100644 index db941c3b1..000000000 --- a/src/kernel/qrect.cpp +++ /dev/null @@ -1,960 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQRect class -** -** Created : 931028 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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. -** -**********************************************************************/ - -#define TQRECT_C -#include "ntqrect.h" -#include "tqdatastream.h" - -/*! - \class TQRect - \brief The TQRect class defines a rectangle in the plane. - - \ingroup images - \ingroup graphics - \mainclass - - A rectangle is internally represented as an upper-left corner and - a bottom-right corner, but it is normally expressed as an - upper-left corner and a size. - - The coordinate type is TQCOORD (defined in \c ntqwindowdefs.h as \c - int). The minimum value of TQCOORD is TQCOORD_MIN (-2147483648) and - the maximum value is TQCOORD_MAX (2147483647). - - Note that the size (width and height) of a rectangle might be - different from what you are used to. If the top-left corner and - the bottom-right corner are the same, the height and the width of - the rectangle will both be 1. - - Generally, \e{width = right - left + 1} and \e{height = bottom - - top + 1}. We designed it this way to make it correspond to - rectangular spaces used by drawing functions in which the width - and height denote a number of pixels. For example, drawing a - rectangle with width and height 1 draws a single pixel. - - The default coordinate system has origin (0, 0) in the top-left - corner. The positive direction of the y axis is down, and the - positive x axis is from left to right. - - A TQRect can be constructed with a set of left, top, width and - height integers, from two TQPoints or from a TQPoint and a TQSize. - After creation the dimensions can be changed, e.g. with setLeft(), - setRight(), setTop() and setBottom(), or by setting sizes, e.g. - setWidth(), setHeight() and setSize(). The dimensions can also be - changed with the move functions, e.g. moveBy(), moveCenter(), - moveBottomRight(), etc. You can also add coordinates to a - rectangle with addCoords(). - - You can test to see if a TQRect contains a specific point with - contains(). You can also test to see if two TQRects intersect with - intersects() (see also intersect()). To get the bounding rectangle - of two TQRects use unite(). - - \sa TQPoint, TQSize -*/ - - -/***************************************************************************** - TQRect member functions - *****************************************************************************/ - -/*! - \fn TQRect::TQRect() - - Constructs an invalid rectangle. -*/ - -/*! - Constructs a rectangle with \a topLeft as the top-left corner and - \a bottomRight as the bottom-right corner. -*/ - -TQRect::TQRect( const TQPoint &topLeft, const TQPoint &bottomRight ) -{ - x1 = (TQCOORD)topLeft.x(); - y1 = (TQCOORD)topLeft.y(); - x2 = (TQCOORD)bottomRight.x(); - y2 = (TQCOORD)bottomRight.y(); -} - -/*! - Constructs a rectangle with \a topLeft as the top-left corner and - \a size as the rectangle size. -*/ - -TQRect::TQRect( const TQPoint &topLeft, const TQSize &size ) -{ - x1 = (TQCOORD)topLeft.x(); - y1 = (TQCOORD)topLeft.y(); - x2 = (TQCOORD)(x1+size.width()-1); - y2 = (TQCOORD)(y1+size.height()-1); -} - -/*! - \fn TQRect::TQRect( int left, int top, int width, int height ) - - Constructs a rectangle with the \a top, \a left corner and \a - width and \a height. - - Example (creates three identical rectangles): - \code - TQRect r1( TQPoint(100,200), TQPoint(110,215) ); - TQRect r2( TQPoint(100,200), TQSize(11,16) ); - TQRect r3( 100, 200, 11, 16 ); - \endcode -*/ - - -/*! - \fn bool TQRect::isNull() const - - Returns TRUE if the rectangle is a null rectangle; otherwise - returns FALSE. - - A null rectangle has both the width and the height set to 0, that - is right() == left() - 1 and bottom() == top() - 1. - - Note that if right() == left() and bottom() == top(), then the - rectangle has width 1 and height 1. - - A null rectangle is also empty. - - A null rectangle is not valid. - - \sa isEmpty(), isValid() -*/ - -/*! - \fn bool TQRect::isEmpty() const - - Returns TRUE if the rectangle is empty; otherwise returns FALSE. - - An empty rectangle has a left() \> right() or top() \> bottom(). - - An empty rectangle is not valid. \c{isEmpty() == !isValid()} - - \sa isNull(), isValid(), normalize() -*/ - -/*! - \fn bool TQRect::isValid() const - - Returns TRUE if the rectangle is valid; otherwise returns FALSE. - - A valid rectangle has a left() \<= right() and top() \<= bottom(). - - Note that non-trivial operations like intersections are not defined - for invalid rectangles. - - \c{isValid() == !isEmpty()} - - \sa isNull(), isEmpty(), normalize() -*/ - - -/*! - Returns a normalized rectangle, i.e. a rectangle that has a - non-negative width and height. - - It swaps left and right if left() \> right(), and swaps top and - bottom if top() \> bottom(). - - \sa isValid() -*/ - -TQRect TQRect::normalize() const -{ - TQRect r; - if ( x2 < x1 ) { // swap bad x values - r.x1 = x2; - r.x2 = x1; - } else { - r.x1 = x1; - r.x2 = x2; - } - if ( y2 < y1 ) { // swap bad y values - r.y1 = y2; - r.y2 = y1; - } else { - r.y1 = y1; - r.y2 = y2; - } - return r; -} - - -/*! - \fn int TQRect::left() const - - Returns the left coordinate of the rectangle. Identical to x(). - - \sa setLeft(), right(), topLeft(), bottomLeft() -*/ - -/*! - \fn int TQRect::top() const - - Returns the top coordinate of the rectangle. Identical to y(). - - \sa setTop(), bottom(), topLeft(), topRight() -*/ - -/*! - \fn int TQRect::right() const - - Returns the right coordinate of the rectangle. - - \sa setRight(), left(), topRight(), bottomRight() -*/ - -/*! - \fn int TQRect::bottom() const - - Returns the bottom coordinate of the rectangle. - - \sa setBottom(), top(), bottomLeft(), bottomRight() -*/ - -/*! - \fn TQCOORD &TQRect::rLeft() - - Returns a reference to the left coordinate of the rectangle. - - \sa rTop(), rRight(), rBottom() -*/ - -/*! - \fn TQCOORD &TQRect::rTop() - - Returns a reference to the top coordinate of the rectangle. - - \sa rLeft(), rRight(), rBottom() -*/ - -/*! - \fn TQCOORD &TQRect::rRight() - - Returns a reference to the right coordinate of the rectangle. - - \sa rLeft(), rTop(), rBottom() -*/ - -/*! - \fn TQCOORD &TQRect::rBottom() - - Returns a reference to the bottom coordinate of the rectangle. - - \sa rLeft(), rTop(), rRight() -*/ - -/*! - \fn int TQRect::x() const - - Returns the left coordinate of the rectangle. Identical to left(). - - \sa left(), y(), setX() -*/ - -/*! - \fn int TQRect::y() const - - Returns the top coordinate of the rectangle. Identical to top(). - - \sa top(), x(), setY() -*/ - -/*! - \fn void TQRect::setLeft( int pos ) - - Sets the left edge of the rectangle to \a pos. May change the - width, but will never change the right edge of the rectangle. - - Identical to setX(). - - \sa left(), setTop(), setWidth() -*/ - -/*! - \fn void TQRect::setTop( int pos ) - - Sets the top edge of the rectangle to \a pos. May change the - height, but will never change the bottom edge of the rectangle. - - Identical to setY(). - - \sa top(), setBottom(), setHeight() -*/ - -/*! - \fn void TQRect::setRight( int pos ) - - Sets the right edge of the rectangle to \a pos. May change the - width, but will never change the left edge of the rectangle. - - \sa right(), setLeft(), setWidth() -*/ - -/*! - \fn void TQRect::setBottom( int pos ) - - Sets the bottom edge of the rectangle to \a pos. May change the - height, but will never change the top edge of the rectangle. - - \sa bottom(), setTop(), setHeight() -*/ - -/*! - \fn void TQRect::setX( int x ) - - Sets the x position of the rectangle (its left end) to \a x. May - change the width, but will never change the right edge of the - rectangle. - - Identical to setLeft(). - - \sa x(), setY() -*/ - -/*! - \fn void TQRect::setY( int y ) - - Sets the y position of the rectangle (its top) to \a y. May change - the height, but will never change the bottom edge of the - rectangle. - - Identical to setTop(). - - \sa y(), setX() -*/ - -/*! - Set the top-left corner of the rectangle to \a p. May change - the size, but will the never change the bottom-right corner of - the rectangle. - - \sa topLeft(), moveTopLeft(), setBottomRight(), setTopRight(), setBottomLeft() -*/ -void TQRect::setTopLeft( const TQPoint &p ) -{ - setLeft( p.x() ); - setTop( p.y() ); -} - -/*! - Set the bottom-right corner of the rectangle to \a p. May change - the size, but will the never change the top-left corner of - the rectangle. - - \sa bottomRight(), moveBottomRight(), setTopLeft(), setTopRight(), setBottomLeft() -*/ -void TQRect::setBottomRight( const TQPoint &p ) -{ - setRight( p.x() ); - setBottom( p.y() ); -} - -/*! - Set the top-right corner of the rectangle to \a p. May change - the size, but will the never change the bottom-left corner of - the rectangle. - - \sa topRight(), moveTopRight(), setTopLeft(), setBottomRight(), setBottomLeft() -*/ -void TQRect::setTopRight( const TQPoint &p ) -{ - setRight( p.x() ); - setTop( p.y() ); -} - -/*! - Set the bottom-left corner of the rectangle to \a p. May change - the size, but will the never change the top-right corner of - the rectangle. - - \sa bottomLeft(), moveBottomLeft(), setTopLeft(), setBottomRight(), setTopRight() -*/ -void TQRect::setBottomLeft( const TQPoint &p ) -{ - setLeft( p.x() ); - setBottom( p.y() ); -} - -/*! - \fn TQPoint TQRect::topLeft() const - - Returns the top-left position of the rectangle. - - \sa setTopLeft(), moveTopLeft(), bottomRight(), left(), top() -*/ - -/*! - \fn TQPoint TQRect::bottomRight() const - - Returns the bottom-right position of the rectangle. - - \sa setBottomRight(), moveBottomRight(), topLeft(), right(), bottom() -*/ - -/*! - \fn TQPoint TQRect::topRight() const - - Returns the top-right position of the rectangle. - - \sa setTopRight(), moveTopRight(), bottomLeft(), top(), right() -*/ - -/*! - \fn TQPoint TQRect::bottomLeft() const - - Returns the bottom-left position of the rectangle. - - \sa setBottomLeft(), moveBottomLeft(), topRight(), bottom(), left() -*/ - -/*! - \fn TQPoint TQRect::center() const - - Returns the center point of the rectangle. - - \sa moveCenter(), topLeft(), bottomRight(), topRight(), bottomLeft() -*/ - - -/*! - Extracts the rectangle parameters as the position \a *x, \a *y and - width \a *w and height \a *h. - - \sa setRect(), coords() -*/ - -void TQRect::rect( int *x, int *y, int *w, int *h ) const -{ - *x = x1; - *y = y1; - *w = x2-x1+1; - *h = y2-y1+1; -} - -/*! - Extracts the rectangle parameters as the top-left point \a *xp1, - \a *yp1 and the bottom-right point \a *xp2, \a *yp2. - - \sa setCoords(), rect() -*/ - -void TQRect::coords( int *xp1, int *yp1, int *xp2, int *yp2 ) const -{ - *xp1 = x1; - *yp1 = y1; - *xp2 = x2; - *yp2 = y2; -} - - -/*! - Sets the left position of the rectangle to \a pos, leaving the - size unchanged. - - \sa left(), setLeft(), moveTop(), moveRight(), moveBottom() -*/ -void TQRect::moveLeft( int pos ) -{ - x2 += (TQCOORD)(pos - x1); - x1 = (TQCOORD)pos; -} - -/*! - Sets the top position of the rectangle to \a pos, leaving the - size unchanged. - - \sa top(), setTop(), moveLeft(), moveRight(), moveBottom() -*/ - -void TQRect::moveTop( int pos ) -{ - y2 += (TQCOORD)(pos - y1); - y1 = (TQCOORD)pos; -} - -/*! - Sets the right position of the rectangle to \a pos, leaving the - size unchanged. - - \sa right(), setRight(), moveLeft(), moveTop(), moveBottom() -*/ - -void TQRect::moveRight( int pos ) -{ - x1 += (TQCOORD)(pos - x2); - x2 = (TQCOORD)pos; -} - -/*! - Sets the bottom position of the rectangle to \a pos, leaving the - size unchanged. - - \sa bottom(), setBottom(), moveLeft(), moveTop(), moveRight() -*/ - -void TQRect::moveBottom( int pos ) -{ - y1 += (TQCOORD)(pos - y2); - y2 = (TQCOORD)pos; -} - -/*! - Sets the top-left position of the rectangle to \a p, leaving the - size unchanged. - - \sa topLeft(), setTopLeft(), moveBottomRight(), moveTopRight(), moveBottomLeft() -*/ - -void TQRect::moveTopLeft( const TQPoint &p ) -{ - moveLeft( p.x() ); - moveTop( p.y() ); -} - -/*! - Sets the bottom-right position of the rectangle to \a p, leaving - the size unchanged. - - \sa bottomRight(), setBottomRight(), moveTopLeft(), moveTopRight(), moveBottomLeft() -*/ - -void TQRect::moveBottomRight( const TQPoint &p ) -{ - moveRight( p.x() ); - moveBottom( p.y() ); -} - -/*! - Sets the top-right position of the rectangle to \a p, leaving the - size unchanged. - - \sa topRight(), setTopRight(), moveTopLeft(), moveBottomRight(), moveBottomLeft() -*/ - -void TQRect::moveTopRight( const TQPoint &p ) -{ - moveRight( p.x() ); - moveTop( p.y() ); -} - -/*! - Sets the bottom-left position of the rectangle to \a p, leaving - the size unchanged. - - \sa bottomLeft(), setBottomLeft(), moveTopLeft(), moveBottomRight(), moveTopRight() -*/ - -void TQRect::moveBottomLeft( const TQPoint &p ) -{ - moveLeft( p.x() ); - moveBottom( p.y() ); -} - - -/*! - Sets the center point of the rectangle to \a p, leaving the size - unchanged. - - \sa center(), moveTopLeft(), moveBottomRight(), moveTopRight(), moveBottomLeft() -*/ - -void TQRect::moveCenter( const TQPoint &p ) -{ - TQCOORD w = x2 - x1; - TQCOORD h = y2 - y1; - x1 = (TQCOORD)(p.x() - w/2); - y1 = (TQCOORD)(p.y() - h/2); - x2 = x1 + w; - y2 = y1 + h; -} - - -/*! - Moves the rectangle \a dx along the x axis and \a dy along the y - axis, relative to the current position. Positive values move the - rectangle to the right and down. - - \sa moveTopLeft() -*/ - -void TQRect::moveBy( int dx, int dy ) -{ - x1 += (TQCOORD)dx; - y1 += (TQCOORD)dy; - x2 += (TQCOORD)dx; - y2 += (TQCOORD)dy; -} - -/*! - Sets the coordinates of the rectangle's top-left corner to \a (x, - y), and its size to \a (w, h). - - \sa rect(), setCoords() -*/ - -void TQRect::setRect( int x, int y, int w, int h ) -{ - x1 = (TQCOORD)x; - y1 = (TQCOORD)y; - x2 = (TQCOORD)(x+w-1); - y2 = (TQCOORD)(y+h-1); -} - -/*! - Sets the coordinates of the rectangle's top-left corner to \a - (xp1, yp1), and the coordinates of its bottom-right corner to \a - (xp2, yp2). - - \sa coords(), setRect() -*/ - -void TQRect::setCoords( int xp1, int yp1, int xp2, int yp2 ) -{ - x1 = (TQCOORD)xp1; - y1 = (TQCOORD)yp1; - x2 = (TQCOORD)xp2; - y2 = (TQCOORD)yp2; -} - -/*! - Adds \a xp1, \a yp1, \a xp2 and \a yp2 respectively to the - existing coordinates of the rectangle. -*/ - -void TQRect::addCoords( int xp1, int yp1, int xp2, int yp2 ) -{ - x1 += (TQCOORD)xp1; - y1 += (TQCOORD)yp1; - x2 += (TQCOORD)xp2; - y2 += (TQCOORD)yp2; -} - -/*! - \fn TQSize TQRect::size() const - - Returns the size of the rectangle. - - \sa width(), height() -*/ - -/*! - \fn int TQRect::width() const - - Returns the width of the rectangle. The width includes both the - left and right edges, i.e. width = right - left + 1. - - \sa height(), size(), setHeight() -*/ - -/*! - \fn int TQRect::height() const - - Returns the height of the rectangle. The height includes both the - top and bottom edges, i.e. height = bottom - top + 1. - - \sa width(), size(), setHeight() -*/ - -/*! - Sets the width of the rectangle to \a w. The right edge is - changed, but not the left edge. - - \sa width(), setLeft(), setRight(), setSize() -*/ - -void TQRect::setWidth( int w ) -{ - x2 = (TQCOORD)(x1 + w - 1); -} - -/*! - Sets the height of the rectangle to \a h. The top edge is not - moved, but the bottom edge may be moved. - - \sa height(), setTop(), setBottom(), setSize() -*/ - -void TQRect::setHeight( int h ) -{ - y2 = (TQCOORD)(y1 + h - 1); -} - -/*! - Sets the size of the rectangle to \a s. The top-left corner is not - moved. - - \sa size(), setWidth(), setHeight() -*/ - -void TQRect::setSize( const TQSize &s ) -{ - x2 = (TQCOORD)(s.width() +x1-1); - y2 = (TQCOORD)(s.height()+y1-1); -} - -/*! - Returns TRUE if the point \a p is inside or on the edge of the - rectangle; otherwise returns FALSE. - - If \a proper is TRUE, this function returns TRUE only if \a p is - inside (not on the edge). -*/ - -bool TQRect::contains( const TQPoint &p, bool proper ) const -{ - if ( proper ) - return p.x() > x1 && p.x() < x2 && - p.y() > y1 && p.y() < y2; - else - return p.x() >= x1 && p.x() <= x2 && - p.y() >= y1 && p.y() <= y2; -} - -/*! - \overload bool TQRect::contains( int x, int y, bool proper ) const - - Returns TRUE if the point \a x, \a y is inside this rectangle; - otherwise returns FALSE. - - If \a proper is TRUE, this function returns TRUE only if the point - is entirely inside (not on the edge). -*/ - -/*! - \overload bool TQRect::contains( int x, int y ) const - - Returns TRUE if the point \a x, \a y is inside this rectangle; - otherwise returns FALSE. -*/ - -/*! - \overload - - Returns TRUE if the rectangle \a r is inside this rectangle; - otherwise returns FALSE. - - If \a proper is TRUE, this function returns TRUE only if \a r is - entirely inside (not on the edge). - - \sa unite(), intersect(), intersects() -*/ - -bool TQRect::contains( const TQRect &r, bool proper ) const -{ - if ( proper ) - return r.x1 > x1 && r.x2 < x2 && r.y1 > y1 && r.y2 < y2; - else - return r.x1 >= x1 && r.x2 <= x2 && r.y1 >= y1 && r.y2 <= y2; -} - -/*! - Unites this rectangle with rectangle \a r. -*/ -TQRect& TQRect::operator|=(const TQRect &r) -{ - *this = *this | r; - return *this; -} - -/*! - Intersects this rectangle with rectangle \a r. -*/ -TQRect& TQRect::operator&=(const TQRect &r) -{ - *this = *this & r; - return *this; -} - - -/*! - Returns the bounding rectangle of this rectangle and rectangle \a - r. - - The bounding rectangle of a nonempty rectangle and an empty or - invalid rectangle is defined to be the nonempty rectangle. - - \sa operator|=(), operator&(), intersects(), contains() -*/ - -TQRect TQRect::operator|(const TQRect &r) const -{ - if ( isValid() ) { - if ( r.isValid() ) { - TQRect tmp; - tmp.setLeft( TQMIN( x1, r.x1 ) ); - tmp.setRight( TQMAX( x2, r.x2 ) ); - tmp.setTop( TQMIN( y1, r.y1 ) ); - tmp.setBottom( TQMAX( y2, r.y2 ) ); - return tmp; - } else { - return *this; - } - } else { - return r; - } -} - -/*! - Returns the bounding rectangle of this rectangle and rectangle \a - r. \c{r.unite(s)} is equivalent to \c{r|s}. -*/ -TQRect TQRect::unite( const TQRect &r ) const -{ - return *this | r; -} - - -/*! - Returns the intersection of this rectangle and rectangle \a r. - - Returns an empty rectangle if there is no intersection. - - \sa operator&=(), operator|(), isEmpty(), intersects(), contains() -*/ - -TQRect TQRect::operator&( const TQRect &r ) const -{ - TQRect tmp; - tmp.x1 = TQMAX( x1, r.x1 ); - tmp.x2 = TQMIN( x2, r.x2 ); - tmp.y1 = TQMAX( y1, r.y1 ); - tmp.y2 = TQMIN( y2, r.y2 ); - return tmp; -} - -/*! - Returns the intersection of this rectangle and rectangle \a r. - \c{r.intersect(s)} is equivalent to \c{r&s}. -*/ -TQRect TQRect::intersect( const TQRect &r ) const -{ - return *this & r; -} - -/*! - Returns TRUE if this rectangle intersects with rectangle \a r - (there is at least one pixel that is within both rectangles); - otherwise returns FALSE. - - \sa intersect(), contains() -*/ - -bool TQRect::intersects( const TQRect &r ) const -{ - return ( TQMAX( x1, r.x1 ) <= TQMIN( x2, r.x2 ) && - TQMAX( y1, r.y1 ) <= TQMIN( y2, r.y2 ) ); -} - - -/*! - \relates TQRect - - Returns TRUE if \a r1 and \a r2 are equal; otherwise returns FALSE. -*/ - -bool operator==( const TQRect &r1, const TQRect &r2 ) -{ - return r1.x1==r2.x1 && r1.x2==r2.x2 && r1.y1==r2.y1 && r1.y2==r2.y2; -} - -/*! - \relates TQRect - - Returns TRUE if \a r1 and \a r2 are different; otherwise returns FALSE. -*/ - -bool operator!=( const TQRect &r1, const TQRect &r2 ) -{ - return r1.x1!=r2.x1 || r1.x2!=r2.x2 || r1.y1!=r2.y1 || r1.y2!=r2.y2; -} - - -/***************************************************************************** - TQRect stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -/*! - \relates TQRect - - Writes the TQRect, \a r, to the stream \a s, and returns a - reference to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQRect &r ) -{ - if ( s.version() == 1 ) - s << (TQ_INT16)r.left() << (TQ_INT16)r.top() - << (TQ_INT16)r.right() << (TQ_INT16)r.bottom(); - else - s << (TQ_INT32)r.left() << (TQ_INT32)r.top() - << (TQ_INT32)r.right() << (TQ_INT32)r.bottom(); - return s; -} - -/*! - \relates TQRect - - Reads a TQRect from the stream \a s into rect \a r and returns a - reference to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator>>( TQDataStream &s, TQRect &r ) -{ - if ( s.version() == 1 ) { - TQ_INT16 x1, y1, x2, y2; - s >> x1; s >> y1; s >> x2; s >> y2; - r.setCoords( x1, y1, x2, y2 ); - } - else { - TQ_INT32 x1, y1, x2, y2; - s >> x1; s >> y1; s >> x2; s >> y2; - r.setCoords( x1, y1, x2, y2 ); - } - return s; -} -#endif // TQT_NO_DATASTREAM diff --git a/src/kernel/qregion.cpp b/src/kernel/qregion.cpp deleted file mode 100644 index cc8fae37d..000000000 --- a/src/kernel/qregion.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQRegion class -** -** Created : 950726 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqregion.h" -#include "ntqpointarray.h" -#include "tqbuffer.h" -#include "tqdatastream.h" - -// BEING REVISED: paul -/*! - \class TQRegion ntqregion.h - \brief The TQRegion class specifies a clip region for a painter. - - \ingroup images - \ingroup graphics - - TQRegion is used with TQPainter::setClipRegion() to limit the paint - area to what needs to be painted. There is also a - TQWidget::repaint() that takes a TQRegion parameter. TQRegion is the - best tool for reducing flicker. - - A region can be created from a rectangle, an ellipse, a polygon or - a bitmap. Complex regions may be created by combining simple - regions using unite(), intersect(), subtract() or eor() (exclusive - or). You can move a region using translate(). - - You can test whether a region isNull(), isEmpty() or if it - contains() a TQPoint or TQRect. The bounding rectangle is given by - boundingRect(). - - The function rects() gives a decomposition of the region into - rectangles. - - Example of using complex regions: - \code - void MyWidget::paintEvent( TQPaintEvent * ) - { - TQPainter p; // our painter - TQRegion r1( TQRect(100,100,200,80), // r1 = elliptic region - TQRegion::Ellipse ); - TQRegion r2( TQRect(100,120,90,30) ); // r2 = rectangular region - TQRegion r3 = r1.intersect( r2 ); // r3 = intersection - p.begin( this ); // start painting widget - p.setClipRegion( r3 ); // set clip region - ... // paint clipped graphics - p.end(); // painting done - } - \endcode - - TQRegion is an \link shclass.html implicitly shared\endlink class. - - \warning Due to window system limitations, the whole coordinate - space for a region is limited to the points between -32767 and - 32767 on Mac OS X and Windows 95/98/ME. - - \sa TQPainter::setClipRegion(), TQPainter::setClipRect() -*/ - - -/*! - \enum TQRegion::RegionType - - Specifies the shape of the region to be created. - - \value Rectangle the region covers the entire rectangle. - \value Ellipse the region is an ellipse inside the rectangle. -*/ - -/*! - \fn Region TQRegion::handle() const - - Returns the region's handle. -*/ - -/***************************************************************************** - TQRegion member functions - *****************************************************************************/ - -/*! - Constructs a rectangular or elliptic region. - - If \a t is \c Rectangle, the region is the filled rectangle (\a x, - \a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled - ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size - (\a w ,\a h ). -*/ -TQRegion::TQRegion( int x, int y, int w, int h, RegionType t ) -{ - TQRegion tmp(TQRect(x,y,w,h),t); - tmp.data->ref(); - data = tmp.data; -} - -/*! - Detaches from shared region data to make sure that this region is - the only one referring to the data. - - \sa copy(), \link shclass.html shared classes\endlink -*/ - -void TQRegion::detach() -{ - if ( data->count != 1 ) - *this = copy(); -} - -#ifndef TQT_NO_DATASTREAM -/* - Executes region commands in the internal buffer and rebuilds the - original region. - - We do this when we read a region from the data stream. - - If \a ver is non-0, uses the format version \a ver on reading the - byte array. -*/ - -void TQRegion::exec( const TQByteArray &buffer, int ver ) -{ - TQBuffer buf( buffer ); - TQDataStream s( &buf ); - if ( ver ) - s.setVersion( ver ); - buf.open( IO_ReadOnly ); - TQRegion rgn; -#if defined(QT_CHECK_STATE) - int test_cnt = 0; -#endif - while ( !s.eof() ) { - TQ_INT32 id; - if ( s.version() == 1 ) { - int id_int; - s >> id_int; - id = id_int; - } else { - s >> id; - } -#if defined(QT_CHECK_STATE) - if ( test_cnt > 0 && id != TQRGN_TRANSLATE ) - tqWarning( "TQRegion::exec: Internal error" ); - test_cnt++; -#endif - if ( id == TQRGN_SETRECT || id == TQRGN_SETELLIPSE ) { - TQRect r; - s >> r; - rgn = TQRegion( r, id == TQRGN_SETRECT ? Rectangle : Ellipse ); - } else if ( id == TQRGN_SETPTARRAY_ALT || id == TQRGN_SETPTARRAY_WIND ) { - TQPointArray a; - s >> a; - rgn = TQRegion( a, id == TQRGN_SETPTARRAY_WIND ); - } else if ( id == TQRGN_TRANSLATE ) { - TQPoint p; - s >> p; - rgn.translate( p.x(), p.y() ); - } else if ( id >= TQRGN_OR && id <= TQRGN_XOR ) { - TQByteArray bop1, bop2; - TQRegion r1, r2; - s >> bop1; r1.exec( bop1 ); - s >> bop2; r2.exec( bop2 ); - switch ( id ) { - case TQRGN_OR: - rgn = r1.unite( r2 ); - break; - case TQRGN_AND: - rgn = r1.intersect( r2 ); - break; - case TQRGN_SUB: - rgn = r1.subtract( r2 ); - break; - case TQRGN_XOR: - rgn = r1.eor( r2 ); - break; - } - } else if ( id == TQRGN_RECTS ) { - // (This is the only form used in TQt 2.0) - TQ_UINT32 n; - s >> n; - TQRect r; - for ( int i=0; i<(int)n; i++ ) { - s >> r; - rgn = rgn.unite( TQRegion(r) ); - } - } - } - buf.close(); - *this = rgn; -} - - -/***************************************************************************** - TQRegion stream functions - *****************************************************************************/ - -/*! - \relates TQRegion - - Writes the region \a r to the stream \a s and returns a reference - to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQRegion &r ) -{ - TQMemArray a = r.rects(); - if ( a.isEmpty() ) { - s << (TQ_UINT32)0; - } else { - if ( s.version() == 1 ) { - int i; - for ( i=(int)a.size()-1; i>0; i-- ) { - s << (TQ_UINT32)(12+i*24); - s << (int)TQRGN_OR; - } - for ( i=0; i<(int)a.size(); i++ ) { - s << (TQ_UINT32)(4+8) << (int)TQRGN_SETRECT << a[i]; - } - } - else { - s << (TQ_UINT32)(4+4+16*a.size()); // 16: storage size of TQRect - s << (TQ_INT32)TQRGN_RECTS; - s << (TQ_UINT32)a.size(); - for ( int i=0; i<(int)a.size(); i++ ) - s << a[i]; - } - } - return s; -} - -/*! - \relates TQRegion - - Reads a region from the stream \a s into \a r and returns a - reference to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator>>( TQDataStream &s, TQRegion &r ) -{ - TQByteArray b; - s >> b; - r.exec( b, s.version() ); - return s; -} -#endif //TQT_NO_DATASTREAM - -// These are not inline - they can be implemented better on some platforms -// (eg. Windows at least provides 3-variable operations). For now, simple. - - -/*! - Applies the unite() function to this region and \a r. \c r1|r2 is - equivalent to \c r1.unite(r2) - - \sa unite(), operator+() -*/ -const TQRegion TQRegion::operator|( const TQRegion &r ) const - { return unite(r); } - -/*! - Applies the unite() function to this region and \a r. \c r1+r2 is - equivalent to \c r1.unite(r2) - - \sa unite(), operator|() -*/ -const TQRegion TQRegion::operator+( const TQRegion &r ) const - { return unite(r); } - -/*! - Applies the intersect() function to this region and \a r. \c r1&r2 - is equivalent to \c r1.intersect(r2) - - \sa intersect() -*/ -const TQRegion TQRegion::operator&( const TQRegion &r ) const - { return intersect(r); } - -/*! - Applies the subtract() function to this region and \a r. \c r1-r2 - is equivalent to \c r1.subtract(r2) - - \sa subtract() -*/ -const TQRegion TQRegion::operator-( const TQRegion &r ) const - { return subtract(r); } - -/*! - Applies the eor() function to this region and \a r. \c r1^r2 is - equivalent to \c r1.eor(r2) - - \sa eor() -*/ -const TQRegion TQRegion::operator^( const TQRegion &r ) const - { return eor(r); } - -/*! - Applies the unite() function to this region and \a r and assigns - the result to this region. \c r1|=r2 is equivalent to \c - r1=r1.unite(r2) - - \sa unite() -*/ -TQRegion& TQRegion::operator|=( const TQRegion &r ) - { return *this = *this | r; } - -/*! - Applies the unite() function to this region and \a r and assigns - the result to this region. \c r1+=r2 is equivalent to \c - r1=r1.unite(r2) - - \sa intersect() -*/ -TQRegion& TQRegion::operator+=( const TQRegion &r ) - { return *this = *this + r; } - -/*! - Applies the intersect() function to this region and \a r and - assigns the result to this region. \c r1&=r2 is equivalent to \c - r1=r1.intersect(r2) - - \sa intersect() -*/ -TQRegion& TQRegion::operator&=( const TQRegion &r ) - { return *this = *this & r; } - -/*! - Applies the subtract() function to this region and \a r and - assigns the result to this region. \c r1-=r2 is equivalent to \c - r1=r1.subtract(r2) - - \sa subtract() -*/ -TQRegion& TQRegion::operator-=( const TQRegion &r ) - { return *this = *this - r; } - -/*! - Applies the eor() function to this region and \a r and - assigns the result to this region. \c r1^=r2 is equivalent to \c - r1=r1.eor(r2) - - \sa eor() -*/ -TQRegion& TQRegion::operator^=( const TQRegion &r ) - { return *this = *this ^ r; } - diff --git a/src/kernel/qregion_x11.cpp b/src/kernel/qregion_x11.cpp deleted file mode 100644 index c10856a0d..000000000 --- a/src/kernel/qregion_x11.cpp +++ /dev/null @@ -1,2896 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQRegion class for X11 -** -** Created : 940729 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqregion.h" -#include "ntqpointarray.h" -#include "tqbuffer.h" -#include "tqimage.h" -#include "tqbitmap.h" -#include "qt_x11_p.h" - -#include - -// inline TQRect::setCoords -inline void qt_setCoords( TQRect *r, int xp1, int yp1, int xp2, int yp2 ) -{ - r->x1 = (TQCOORD)xp1; - r->y1 = (TQCOORD)yp1; - r->x2 = (TQCOORD)xp2; - r->y2 = (TQCOORD)yp2; -} - -/* - * clip region - */ - -struct TQRegionPrivate { - int numRects; - TQMemArray rects; - TQRect extents; - - TQRegionPrivate() { numRects = 0; } - TQRegionPrivate( const TQRect &r ) : rects(1) { - numRects = 1; - rects[0] = r; - extents = r; - } - - TQRegionPrivate( const TQRegionPrivate &r ) { - rects = r.rects.copy(); - numRects = r.numRects; - extents = r.extents; - } - - TQRegionPrivate &operator=( const TQRegionPrivate &r ) { - rects = r.rects.copy(); - numRects = r.numRects; - extents = r.extents; - return *this; - } - -}; - - -static void UnionRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg); -static void IntersectRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg); -static void miRegionOp(TQRegionPrivate *newReg, TQRegionPrivate *reg1, TQRegionPrivate *reg2, - void (*overlapFunc)(...), - void (*nonOverlap1Func)(...), - void (*nonOverlap2Func)(...)); -#define RectangleOut 0 -#define RectangleIn 1 -#define RectanglePart 2 -#define EvenOddRule 0 -#define WindingRule 1 - -// START OF region.h extract -/* $XConsortium: region.h,v 11.14 94/04/17 20:22:20 rws Exp $ */ -/************************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ - -#ifndef _XREGION_H -#define _XREGION_H - -#include - -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - - -/* 1 if two BOXs overlap. - * 0 if two BOXs do not overlap. - * Remember, x2 and y2 are not in the region - */ -#define EXTENTCHECK(r1, r2) \ - ((r1)->right() >= (r2)->left() && \ - (r1)->left() <= (r2)->right() && \ - (r1)->bottom() >= (r2)->top() && \ - (r1)->top() <= (r2)->bottom()) - -/* - * update region extents - */ -#define EXTENTS(r,idRect){\ - if((r)->left() < (idRect)->extents.left())\ - (idRect)->extents.setLeft( (r)->left() );\ - if((r)->top() < (idRect)->extents.top())\ - (idRect)->extents.setTop( (r)->top() );\ - if((r)->right() > (idRect)->extents.right())\ - (idRect)->extents.setRight( (r)->right() );\ - if((r)->bottom() > (idRect)->extents.bottom())\ - (idRect)->extents.setBottom( (r)->bottom() );\ - } - -/* - * Check to see if there is enough memory in the present region. - */ -#define MEMCHECK(reg, rect, firstrect){\ - if ((reg)->numRects >= (int)((reg)->rects.size()-1)){\ - firstrect.resize(firstrect.size() * 2); \ - (rect) = (firstrect).data() + (reg)->numRects;\ - }\ - } - - -#define EMPTY_REGION(pReg) pReg->numRects = 0 - -#define REGION_NOT_EMPTY(pReg) pReg->numRects - -/* - * number of points to buffer before sending them off - * to scanlines() : Must be an even number - */ -#define NUMPTSTOBUFFER 200 - -/* - * used to allocate buffers for points and link - * the buffers together - */ -typedef struct _POINTBLOCK { - TQPoint pts[NUMPTSTOBUFFER]; - struct _POINTBLOCK *next; -} POINTBLOCK; - -#endif -// END OF region.h extract - -// START OF Region.c extract -/* $XConsortium: Region.c /main/30 1996/10/22 14:21:24 kaleb $ */ -/************************************************************************ - -Copyright (c) 1987, 1988 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ -/* - * The functions in this file implement the Region abstraction, similar to one - * used in the X11 sample server. A Region is simply an area, as the name - * implies, and is implemented as a "y-x-banded" array of rectangles. To - * explain: Each Region is made up of a certain number of rectangles sorted - * by y coordinate first, and then by x coordinate. - * - * Furthermore, the rectangles are banded such that every rectangle with a - * given upper-left y coordinate (y1) will have the same lower-right y - * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it - * will span the entire vertical distance of the band. This means that some - * areas that could be merged into a taller rectangle will be represented as - * several shorter rectangles to account for shorter rectangles to its left - * or right but within its "vertical scope". - * - * An added constraint on the rectangles is that they must cover as much - * horizontal area as possible. E.g. no two rectangles in a band are allowed - * to touch. - * - * Whenever possible, bands will be merged together to cover a greater vertical - * distance (and thus reduce the number of rectangles). Two bands can be merged - * only if the bottom of one touches the top of the other and they have - * rectangles in the same places (of the same width, of course). This maintains - * the y-x-banding that's so nice to have... - */ -/* $XFree86: xc/lib/X11/Region.c,v 1.1.1.2.2.2 1998/10/04 15:22:50 hohndel Exp $ */ - -typedef void (*voidProcp)(...); - - -static -void UnionRectWithRegion(const TQRect *rect, TQRegionPrivate *source, TQRegionPrivate *dest) -{ - TQRegionPrivate region; - - if (!rect->width() || !rect->height()) - return; - region.rects.resize(1); - region.numRects = 1; - region.rects[0] = *rect; - region.extents = *rect; - - UnionRegion(®ion, source, dest); - return; -} - -/*- - *----------------------------------------------------------------------- - * miSetExtents -- - * Reset the extents of a region to what they should be. Called by - * miSubtract and miIntersect b/c they can't figure it out along the - * way or do so easily, as miUnion can. - * - * Results: - * None. - * - * Side Effects: - * The region's 'extents' structure is overwritten. - * - *----------------------------------------------------------------------- - */ -static void -miSetExtents (TQRegionPrivate *pReg) -{ - TQRect *pBox, - *pBoxEnd, - *pExtents; - - if (pReg->numRects == 0) - { - qt_setCoords(&pReg->extents, 0, 0, 0, 0); - return; - } - - pExtents = &pReg->extents; - pBox = pReg->rects.data(); - pBoxEnd = &pBox[pReg->numRects - 1]; - - /* - * Since pBox is the first rectangle in the region, it must have the - * smallest y1 and since pBoxEnd is the last rectangle in the region, - * it must have the largest y2, because of banding. Initialize x1 and - * x2 from pBox and pBoxEnd, resp., as good things to initialize them - * to... - */ - pExtents->setLeft( pBox->left() ); - pExtents->setTop( pBox->top() ); - pExtents->setRight( pBoxEnd->right() ); - pExtents->setBottom( pBoxEnd->bottom() ); - - Q_ASSERT(pExtents->top() <= pExtents->bottom()); - while (pBox <= pBoxEnd) - { - if (pBox->left() < pExtents->left()) - { - pExtents->setLeft( pBox->left() ); - } - if (pBox->right() > pExtents->right()) - { - pExtents->setRight( pBox->right() ); - } - pBox++; - } - Q_ASSERT(pExtents->left() <= pExtents->right()); -} - - -/* TranslateRegion(pRegion, x, y) - translates in place - added by raymond -*/ - -static -int -OffsetRegion(TQRegionPrivate *pRegion, int x, int y) -{ - int nbox; - TQRect *pbox; - - pbox = pRegion->rects.data(); - nbox = pRegion->numRects; - - while(nbox--) - { - pbox->moveBy(x, y); - pbox++; - } - pRegion->extents.moveBy(x, y); - return 1; -} - -/*====================================================================== - * Region Intersection - *====================================================================*/ -/*- - *----------------------------------------------------------------------- - * miIntersectO -- - * Handle an overlapping band for miIntersect. - * - * Results: - * None. - * - * Side Effects: - * Rectangles may be added to the region. - * - *----------------------------------------------------------------------- - */ -/* static void*/ -static -int -miIntersectO (TQRegionPrivate *pReg, TQRect *r1, TQRect *r1End, - TQRect *r2, TQRect *r2End, int y1, int y2) -{ - int x1; - int x2; - TQRect *pNextRect; - - pNextRect = pReg->rects.data() + pReg->numRects; - - while ((r1 != r1End) && (r2 != r2End)) - { - x1 = TQMAX(r1->left(),r2->left()); - x2 = TQMIN(r1->right(),r2->right()); - - /* - * If there's any overlap between the two rectangles, add that - * overlap to the new region. - * There's no need to check for subsumption because the only way - * such a need could arise is if some region has two rectangles - * right next to each other. Since that should never happen... - */ - if (x1 <= x2) - { - Q_ASSERT(y1<=y2); - - MEMCHECK(pReg, pNextRect, pReg->rects) - qt_setCoords( pNextRect, x1, y1, x2, y2 ); - pReg->numRects++; - pNextRect++; - } - - /* - * Need to advance the pointers. Shift the one that extends - * to the right the least, since the other still has a chance to - * overlap with that region's next rectangle, if you see what I mean. - */ - if (r1->right() < r2->right()) - { - r1++; - } - else if (r2->right() < r1->right()) - { - r2++; - } - else - { - r1++; - r2++; - } - } - return 0; /* lint */ -} - -static -void -IntersectRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg) -{ - /* check for trivial reject */ - if ( (!(reg1->numRects)) || (!(reg2->numRects)) || - (!EXTENTCHECK(®1->extents, ®2->extents))) - newReg->numRects = 0; - else - miRegionOp (newReg, reg1, reg2, - (voidProcp) miIntersectO, (voidProcp) NULL, (voidProcp) NULL); - - /* - * Can't alter newReg's extents before we call miRegionOp because - * it might be one of the source regions and miRegionOp depends - * on the extents of those regions being the same. Besides, this - * way there's no checking against rectangles that will be nuked - * due to coalescing, so we have to examine fewer rectangles. - */ - miSetExtents(newReg); - return; -} - -/*====================================================================== - * Generic Region Operator - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * miCoalesce -- - * Attempt to merge the boxes in the current band with those in the - * previous one. Used only by miRegionOp. - * - * Results: - * The new index for the previous band. - * - * Side Effects: - * If coalescing takes place: - * - rectangles in the previous band will have their y2 fields - * altered. - * - pReg->numRects will be decreased. - * - *----------------------------------------------------------------------- - */ -/* static int*/ -static -int -miCoalesce (TQRegionPrivate *pReg, int prevStart, int curStart) - //Region pReg; /* Region to coalesce */ - //prevStart; /* Index of start of previous band */ - //curStart; /* Index of start of current band */ -{ - TQRect *pPrevBox; /* Current box in previous band */ - TQRect *pCurBox; /* Current box in current band */ - TQRect *pRegEnd; /* End of region */ - int curNumRects; /* Number of rectangles in current - * band */ - int prevNumRects; /* Number of rectangles in previous - * band */ - int bandY1; /* Y1 coordinate for current band */ - - pRegEnd = pReg->rects.data() + pReg->numRects; - - pPrevBox = pReg->rects.data() + prevStart; - prevNumRects = curStart - prevStart; - - /* - * Figure out how many rectangles are in the current band. Have to do - * this because multiple bands could have been added in miRegionOp - * at the end when one region has been exhausted. - */ - pCurBox = pReg->rects.data() + curStart; - bandY1 = pCurBox->top(); - for (curNumRects = 0; - (pCurBox != pRegEnd) && (pCurBox->top() == bandY1); - curNumRects++) - { - pCurBox++; - } - - if (pCurBox != pRegEnd) - { - /* - * If more than one band was added, we have to find the start - * of the last band added so the next coalescing job can start - * at the right place... (given when multiple bands are added, - * this may be pointless -- see above). - */ - pRegEnd--; - while ((pRegEnd-1)->top() == pRegEnd->top()) - { - pRegEnd--; - } - curStart = pRegEnd - pReg->rects.data(); - pRegEnd = pReg->rects.data() + pReg->numRects; - } - - if ((curNumRects == prevNumRects) && (curNumRects != 0)) { - pCurBox -= curNumRects; - /* - * The bands may only be coalesced if the bottom of the previous - * matches the top scanline of the current. - */ - if (pPrevBox->bottom() == pCurBox->top() - 1) - { - /* - * Make sure the bands have boxes in the same places. This - * assumes that boxes have been added in such a way that they - * cover the most area possible. I.e. two boxes in a band must - * have some horizontal space between them. - */ - do - { - if ((pPrevBox->left() != pCurBox->left()) || - (pPrevBox->right() != pCurBox->right())) - { - /* - * The bands don't line up so they can't be coalesced. - */ - return (curStart); - } - pPrevBox++; - pCurBox++; - prevNumRects -= 1; - } while (prevNumRects != 0); - - pReg->numRects -= curNumRects; - pCurBox -= curNumRects; - pPrevBox -= curNumRects; - - /* - * The bands may be merged, so set the bottom y of each box - * in the previous band to that of the corresponding box in - * the current band. - */ - do - { - pPrevBox->setBottom( pCurBox->bottom() ); - pPrevBox++; - pCurBox++; - curNumRects -= 1; - } while (curNumRects != 0); - - /* - * If only one band was added to the region, we have to backup - * curStart to the start of the previous band. - * - * If more than one band was added to the region, copy the - * other bands down. The assumption here is that the other bands - * came from the same region as the current one and no further - * coalescing can be done on them since it's all been done - * already... curStart is already in the right place. - */ - if (pCurBox == pRegEnd) - { - curStart = prevStart; - } - else - { - do - { - *pPrevBox++ = *pCurBox++; - } while (pCurBox != pRegEnd); - } - - } - } - return (curStart); -} - -/*- - *----------------------------------------------------------------------- - * miRegionOp -- - * Apply an operation to two regions. Called by miUnion, miInverse, - * miSubtract, miIntersect... - * - * Results: - * None. - * - * Side Effects: - * The new region is overwritten. - * - * Notes: - * The idea behind this function is to view the two regions as sets. - * Together they cover a rectangle of area that this function divides - * into horizontal bands where points are covered only by one region - * or by both. For the first case, the nonOverlapFunc is called with - * each the band and the band's upper and lower extents. For the - * second, the overlapFunc is called to process the entire band. It - * is responsible for clipping the rectangles in the band, though - * this function provides the boundaries. - * At the end of each band, the new region is coalesced, if possible, - * to reduce the number of rectangles in the region. - * - *----------------------------------------------------------------------- - */ -/* static void*/ -static void -miRegionOp(TQRegionPrivate *newReg, TQRegionPrivate *reg1, TQRegionPrivate *reg2, - void (*overlapFunc)(...), - void (*nonOverlap1Func)(...), - void (*nonOverlap2Func)(...)) - //Region newReg; /* Place to store result */ - //Region reg1; /* First region in operation */ - //Region reg2; /* 2d region in operation */ - //void (*overlapFunc)(); /* Function to call for over- - //* lapping bands */ - //void (*nonOverlap1Func)(); /* Function to call for non- - //* overlapping bands in region - //* 1 */ - //void (*nonOverlap2Func)(); /* Function to call for non- - //* overlapping bands in region - //* 2 */ -{ - TQRect *r1; /* Pointer into first region */ - TQRect *r2; /* Pointer into 2d region */ - TQRect *r1End; /* End of 1st region */ - TQRect *r2End; /* End of 2d region */ - int ybot; /* Bottom of intersection */ - int ytop; /* Top of intersection */ - int prevBand; /* Index of start of - * previous band in newReg */ - int curBand; /* Index of start of current - * band in newReg */ - TQRect *r1BandEnd; /* End of current band in r1 */ - TQRect *r2BandEnd; /* End of current band in r2 */ - int top; /* Top of non-overlapping - * band */ - int bot; /* Bottom of non-overlapping - * band */ - - /* - * Initialization: - * set r1, r2, r1End and r2End appropriately, preserve the important - * parts of the destination region until the end in case it's one of - * the two source regions, then mark the "new" region empty, allocating - * another array of rectangles for it to use. - */ - r1 = reg1->rects.data(); - r2 = reg2->rects.data(); - r1End = r1 + reg1->numRects; - r2End = r2 + reg2->numRects; - - TQMemArray oldRects = newReg->rects; - - newReg->rects.detach(); - EMPTY_REGION(newReg); - - /* - * Allocate a reasonable number of rectangles for the new region. The idea - * is to allocate enough so the individual functions don't need to - * reallocate and copy the array, which is time consuming, yet we don't - * have to worry about using too much memory. I hope to be able to - * nuke the realloc() at the end of this function eventually. - */ - newReg->rects.resize( TQMAX(reg1->numRects,reg2->numRects) * 2 ); - - /* - * Initialize ybot and ytop. - * In the upcoming loop, ybot and ytop serve different functions depending - * on whether the band being handled is an overlapping or non-overlapping - * band. - * In the case of a non-overlapping band (only one of the regions - * has points in the band), ybot is the bottom of the most recent - * intersection and thus clips the top of the rectangles in that band. - * ytop is the top of the next intersection between the two regions and - * serves to clip the bottom of the rectangles in the current band. - * For an overlapping band (where the two regions intersect), ytop clips - * the top of the rectangles of both regions and ybot clips the bottoms. - */ - if (reg1->extents.top() < reg2->extents.top()) - ybot = reg1->extents.top() - 1; - else - ybot = reg2->extents.top() - 1; - - /* - * prevBand serves to mark the start of the previous band so rectangles - * can be coalesced into larger rectangles. qv. miCoalesce, above. - * In the beginning, there is no previous band, so prevBand == curBand - * (curBand is set later on, of course, but the first band will always - * start at index 0). prevBand and curBand must be indices because of - * the possible expansion, and resultant moving, of the new region's - * array of rectangles. - */ - prevBand = 0; - - do - { - curBand = newReg->numRects; - - /* - * This algorithm proceeds one source-band (as opposed to a - * destination band, which is determined by where the two regions - * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the - * rectangle after the last one in the current band for their - * respective regions. - */ - r1BandEnd = r1; - while ((r1BandEnd != r1End) && (r1BandEnd->top() == r1->top())) - { - r1BandEnd++; - } - - r2BandEnd = r2; - while ((r2BandEnd != r2End) && (r2BandEnd->top() == r2->top())) - { - r2BandEnd++; - } - - /* - * First handle the band that doesn't intersect, if any. - * - * Note that attention is restricted to one band in the - * non-intersecting region at once, so if a region has n - * bands between the current position and the next place it overlaps - * the other, this entire loop will be passed through n times. - */ - if (r1->top() < r2->top()) - { - top = TQMAX(r1->top(),ybot+1); - bot = TQMIN(r1->bottom(),r2->top()-1); - - if ((nonOverlap1Func != (voidProcp)NULL) && bot >= top) - { - (* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot); - } - - ytop = r2->top(); - } - else if (r2->top() < r1->top()) - { - top = TQMAX(r2->top(),ybot+1); - bot = TQMIN(r2->bottom(),r1->top()-1); - - if ((nonOverlap2Func != (voidProcp)NULL) && bot >= top) - { - (* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot); - } - - ytop = r1->top(); - } - else - { - ytop = r1->top(); - } - - /* - * If any rectangles got added to the region, try and coalesce them - * with rectangles from the previous band. Note we could just do - * this test in miCoalesce, but some machines incur a not - * inconsiderable cost for function calls, so... - */ - if (newReg->numRects != curBand) - { - prevBand = miCoalesce (newReg, prevBand, curBand); - } - - /* - * Now see if we've hit an intersecting band. The two bands only - * intersect if ybot >= ytop - */ - ybot = TQMIN(r1->bottom(), r2->bottom()); - curBand = newReg->numRects; - if (ybot >= ytop) - { - (* overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); - - } - - if (newReg->numRects != curBand) - { - prevBand = miCoalesce (newReg, prevBand, curBand); - } - - /* - * If we've finished with a band (y2 == ybot) we skip forward - * in the region to the next band. - */ - if (r1->bottom() == ybot) - { - r1 = r1BandEnd; - } - if (r2->bottom() == ybot) - { - r2 = r2BandEnd; - } - } while ((r1 != r1End) && (r2 != r2End)); - - /* - * Deal with whichever region still has rectangles left. - */ - curBand = newReg->numRects; - if (r1 != r1End) - { - if (nonOverlap1Func != (voidProcp)NULL) - { - do - { - r1BandEnd = r1; - while ((r1BandEnd < r1End) && (r1BandEnd->top() == r1->top())) - { - r1BandEnd++; - } - (* nonOverlap1Func) (newReg, r1, r1BandEnd, - TQMAX(r1->top(),ybot+1), r1->bottom()); - r1 = r1BandEnd; - } while (r1 != r1End); - } - } - else if ((r2 != r2End) && (nonOverlap2Func != (voidProcp)NULL)) - { - do - { - r2BandEnd = r2; - while ((r2BandEnd < r2End) && (r2BandEnd->top() == r2->top())) - { - r2BandEnd++; - } - (* nonOverlap2Func) (newReg, r2, r2BandEnd, - TQMAX(r2->top(),ybot+1), r2->bottom()); - r2 = r2BandEnd; - } while (r2 != r2End); - } - - if (newReg->numRects != curBand) - { - (void) miCoalesce (newReg, prevBand, curBand); - } - - /* - * A bit of cleanup. To keep regions from growing without bound, - * we shrink the array of rectangles to match the new number of - * rectangles in the region. This never goes to 0, however... - * - * Only do this stuff if the number of rectangles allocated is more than - * twice the number of rectangles in the region (a simple optimization...). - */ - if (newReg->numRects < (int)(newReg->rects.size() >> 1)) - { - if (REGION_NOT_EMPTY(newReg)) - { - newReg->rects.resize(newReg->numRects); - } - else - { - /* - * No point in doing the extra work involved in an realloc if - * the region is empty - */ - newReg->rects.resize(1); - } - } - return; -} - - -/*====================================================================== - * Region Union - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * miUnionNonO -- - * Handle a non-overlapping band for the union operation. Just - * Adds the rectangles into the region. Doesn't have to check for - * subsumption or anything. - * - * Results: - * None. - * - * Side Effects: - * pReg->numRects is incremented and the final rectangles overwritten - * with the rectangles we're passed. - * - *----------------------------------------------------------------------- - */ -/* static void*/ -static -int -miUnionNonO (TQRegionPrivate *pReg, TQRect * r, - TQRect * rEnd, int y1, int y2) -{ - TQRect * pNextRect; - - pNextRect = pReg->rects.data() + pReg->numRects; - - Q_ASSERT(y1 <= y2); - - while (r != rEnd) - { - Q_ASSERT(r->left() <= r->right()); - MEMCHECK(pReg, pNextRect, pReg->rects) - qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); - pReg->numRects++; - pNextRect++; - - r++; - } - return 0; /* lint */ -} - - -/*- - *----------------------------------------------------------------------- - * miUnionO -- - * Handle an overlapping band for the union operation. Picks the - * left-most rectangle each time and merges it into the region. - * - * Results: - * None. - * - * Side Effects: - * Rectangles are overwritten in pReg->rects and pReg->numRects will - * be changed. - * - *----------------------------------------------------------------------- - */ - -/* static void*/ -static -int -miUnionO (TQRegionPrivate *pReg, TQRect *r1, TQRect *r1End, - TQRect *r2, TQRect *r2End, int y1, int y2) -{ - TQRect *pNextRect; - - pNextRect = pReg->rects.data() + pReg->numRects; - -#define MERGERECT(r) \ - if ((pReg->numRects != 0) && \ - (pNextRect[-1].top() == y1) && \ - (pNextRect[-1].bottom() == y2) && \ - (pNextRect[-1].right() >= r->left()-1)) { \ - if (pNextRect[-1].right() < r->right()) { \ - pNextRect[-1].setRight( r->right() ); \ - Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \ - } \ - } else { \ - MEMCHECK(pReg, pNextRect, pReg->rects) \ - qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); \ - pReg->numRects++; \ - pNextRect++; \ - } \ - r++; - - Q_ASSERT (y1<=y2); - while ((r1 != r1End) && (r2 != r2End)) { - if (r1->left() < r2->left()) { - MERGERECT(r1) - } else { - MERGERECT(r2) - } - } - - if (r1 != r1End) - { - do - { - MERGERECT(r1) - } while (r1 != r1End); - } - else while (r2 != r2End) - { - MERGERECT(r2) - } - return 0; /* lint */ -} - -static void UnionRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg) -{ - /* checks all the simple cases */ - - /* - * Region 1 and 2 are the same or region 1 is empty - */ - if ( (reg1 == reg2) || (!(reg1->numRects)) ) - { - *newReg = *reg2; - return; - } - - /* - * if nothing to union (region 2 empty) - */ - if (!(reg2->numRects)) - { - *newReg = *reg1; - return; - } - - /* - * Region 1 completely subsumes region 2 - */ - if ((reg1->numRects == 1) && - (reg1->extents.left() <= reg2->extents.left()) && - (reg1->extents.top() <= reg2->extents.top()) && - (reg1->extents.right() >= reg2->extents.right()) && - (reg1->extents.bottom() >= reg2->extents.bottom())) - { - *newReg = *reg1; - return; - } - - /* - * Region 2 completely subsumes region 1 - */ - if ((reg2->numRects == 1) && - (reg2->extents.left() <= reg1->extents.left()) && - (reg2->extents.top() <= reg1->extents.top()) && - (reg2->extents.right() >= reg1->extents.right()) && - (reg2->extents.bottom() >= reg1->extents.bottom())) - { - *newReg = *reg2; - return; - } - - miRegionOp (newReg, reg1, reg2, (voidProcp) miUnionO, - (voidProcp) miUnionNonO, (voidProcp) miUnionNonO); - - qt_setCoords( &newReg->extents, - TQMIN(reg1->extents.left(), reg2->extents.left()), - TQMIN(reg1->extents.top(), reg2->extents.top()), - TQMAX(reg1->extents.right(), reg2->extents.right()), - TQMAX(reg1->extents.bottom(), reg2->extents.bottom()) ); - - return; -} - -/*====================================================================== - * Region Subtraction - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * miSubtractNonO -- - * Deal with non-overlapping band for subtraction. Any parts from - * region 2 we discard. Anything from region 1 we add to the region. - * - * Results: - * None. - * - * Side Effects: - * pReg may be affected. - * - *----------------------------------------------------------------------- - */ -/* static void*/ -static -int -miSubtractNonO1 (TQRegionPrivate *pReg, TQRect *r, - TQRect *rEnd, int y1, int y2) -{ - TQRect *pNextRect; - - pNextRect = pReg->rects.data() + pReg->numRects; - - Q_ASSERT(y1<=y2); - - while (r != rEnd) - { - Q_ASSERT(r->left()<=r->right()); - MEMCHECK(pReg, pNextRect, pReg->rects) - qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); - pReg->numRects++; - pNextRect++; - - r++; - } - return 0; /* lint */ -} - -/*- - *----------------------------------------------------------------------- - * miSubtractO -- - * Overlapping band subtraction. x1 is the left-most point not yet - * checked. - * - * Results: - * None. - * - * Side Effects: - * pReg may have rectangles added to it. - * - *----------------------------------------------------------------------- - */ -/* static void*/ -static -int -miSubtractO (TQRegionPrivate *pReg, TQRect *r1, TQRect *r1End, - TQRect *r2, TQRect *r2End, int y1, int y2) -{ - TQRect *pNextRect; - int x1; - - x1 = r1->left(); - - Q_ASSERT(y1<=y2); - pNextRect = pReg->rects.data() + pReg->numRects; - - while ((r1 != r1End) && (r2 != r2End)) - { - if (r2->right() < x1) - { - /* - * Subtrahend missed the boat: go to next subtrahend. - */ - r2++; - } - else if (r2->left() <= x1) - { - /* - * Subtrahend precedes minuend: nuke left edge of minuend. - */ - x1 = r2->right()+1; - if (x1 > r1->right()) - { - /* - * Minuend completely covered: advance to next minuend and - * reset left fence to edge of new minuend. - */ - r1++; - if (r1 != r1End) - x1 = r1->left(); - } - else - { - /* - * Subtrahend now used up since it doesn't extend beyond - * minuend - */ - r2++; - } - } - else if (r2->left() <= r1->right()) - { - /* - * Left part of subtrahend covers part of minuend: add uncovered - * part of minuend to region and skip to next subtrahend. - */ - Q_ASSERT(x1left()); - MEMCHECK(pReg, pNextRect, pReg->rects) - qt_setCoords( pNextRect, x1, y1, r2->left() - 1, y2 ); - pReg->numRects++; - pNextRect++; - - x1 = r2->right() + 1; - if (x1 > r1->right()) - { - /* - * Minuend used up: advance to new... - */ - r1++; - if (r1 != r1End) - x1 = r1->left(); - } - else - { - /* - * Subtrahend used up - */ - r2++; - } - } - else - { - /* - * Minuend used up: add any remaining piece before advancing. - */ - if (r1->right() >= x1) - { - MEMCHECK(pReg, pNextRect, pReg->rects) - qt_setCoords( pNextRect, x1, y1, r1->right(), y2 ); - pReg->numRects++; - pNextRect++; - } - r1++; - if ( r1 != r1End ) - x1 = r1->left(); - } - } - - /* - * Add remaining minuend rectangles to region. - */ - while (r1 != r1End) - { - Q_ASSERT(x1<=r1->right()); - MEMCHECK(pReg, pNextRect, pReg->rects) - qt_setCoords( pNextRect, x1, y1, r1->right(), y2 ); - pReg->numRects++; - pNextRect++; - - r1++; - if (r1 != r1End) - { - x1 = r1->left(); - } - } - return 0; /* lint */ -} - -/*- - *----------------------------------------------------------------------- - * miSubtract -- - * Subtract regS from regM and leave the result in regD. - * S stands for subtrahend, M for minuend and D for difference. - * - * Side Effects: - * regD is overwritten. - * - *----------------------------------------------------------------------- - */ - -static void SubtractRegion(TQRegionPrivate *regM, TQRegionPrivate *regS, TQRegionPrivate *regD) -{ - /* check for trivial reject */ - if ( (!(regM->numRects)) || (!(regS->numRects)) || - (!EXTENTCHECK(®M->extents, ®S->extents)) ) - { - *regD = *regM; - return; - } - - miRegionOp (regD, regM, regS, (voidProcp) miSubtractO, - (voidProcp) miSubtractNonO1, (voidProcp) NULL); - - /* - * Can't alter newReg's extents before we call miRegionOp because - * it might be one of the source regions and miRegionOp depends - * on the extents of those regions being the unaltered. Besides, this - * way there's no checking against rectangles that will be nuked - * due to coalescing, so we have to examine fewer rectangles. - */ - miSetExtents (regD); -} - -static void XorRegion( TQRegionPrivate *sra, TQRegionPrivate *srb, TQRegionPrivate *dr ) -{ - TQRegionPrivate tra, trb; - - SubtractRegion(sra,srb,&tra); - SubtractRegion(srb,sra,&trb); - UnionRegion(&tra,&trb,dr); -} - -/* - * Check to see if two regions are equal - */ -static bool EqualRegion( TQRegionPrivate *r1, TQRegionPrivate *r2 ) -{ - int i; - - if( r1->numRects != r2->numRects ) return FALSE; - else if( r1->numRects == 0 ) return TRUE; - else if ( r1->extents.left() != r2->extents.left() || - r1->extents.right() != r2->extents.right() || - r1->extents.top() != r2->extents.top() || - r1->extents.bottom() != r2->extents.bottom() ) - return FALSE; - else { - TQRect *rr1 = r1->rects.data(); - TQRect *rr2 = r2->rects.data(); - for( i=0; i < r1->numRects; i++, rr1++, rr2++ ) { - if ( rr1->left() != rr2->left() || - rr1->right() != rr2->right() || - rr1->top() != rr2->top() || - rr1->bottom() != rr2->bottom() ) - return FALSE; - } - } - return TRUE; -} - -static bool PointInRegion( TQRegionPrivate *pRegion, int x, int y ) -{ - int i; - - if (pRegion->numRects == 0) - return FALSE; - if (!pRegion->extents.contains(x, y)) - return FALSE; - for (i=0; inumRects; i++) - { - if (pRegion->rects[i].contains(x, y)) - return TRUE; - } - return FALSE; -} - -static bool RectInRegion(TQRegionPrivate *region, - int rx, int ry, unsigned int rwidth, unsigned int rheight) -{ - TQRect *pbox; - TQRect *pboxEnd; - TQRect rect(rx, ry, rwidth, rheight); - TQRect *prect = ▭ - int partIn, partOut; - - /* this is (just) a useful optimization */ - if ((region->numRects == 0) || !EXTENTCHECK(®ion->extents, prect)) - return(RectangleOut); - - partOut = FALSE; - partIn = FALSE; - - /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ - for (pbox = region->rects.data(), pboxEnd = pbox + region->numRects; - pbox < pboxEnd; - pbox++) - { - - if (pbox->bottom() < ry) - continue; /* getting up to speed or skipping remainder of band */ - - if (pbox->top() > ry) - { - partOut = TRUE; /* missed part of rectangle above */ - if (partIn || (pbox->top() > prect->bottom())) - break; - ry = pbox->top(); /* x guaranteed to be == prect->x1 */ - } - - if (pbox->right() < rx) - continue; /* not far enough over yet */ - - if (pbox->left() > rx) - { - partOut = TRUE; /* missed part of rectangle to left */ - if (partIn) - break; - } - - if (pbox->left() <= prect->right()) - { - partIn = TRUE; /* definitely overlap */ - if (partOut) - break; - } - - if (pbox->right() >= prect->right()) - { - ry = pbox->bottom() + 1; /* finished with this band */ - if (ry > prect->bottom()) - break; - rx = prect->left(); /* reset x out to left again */ - } else - { - /* - * Because boxes in a band are maximal width, if the first box - * to overlap the rectangle doesn't completely cover it in that - * band, the rectangle must be partially out, since some of it - * will be uncovered in that band. partIn will have been set true - * by now... - */ - break; - } - - } - - return(partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : - RectangleOut); -} -// END OF Region.c extract -// START OF poly.h extract -/* $XConsortium: poly.h,v 1.4 94/04/17 20:22:19 rws Exp $ */ -/************************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ - -/* - * This file contains a few macros to help track - * the edge of a filled object. The object is assumed - * to be filled in scanline order, and thus the - * algorithm used is an extension of Bresenham's line - * drawing algorithm which assumes that y is always the - * major axis. - * Since these pieces of code are the same for any filled shape, - * it is more convenient to gather the library in one - * place, but since these pieces of code are also in - * the inner loops of output primitives, procedure call - * overhead is out of the question. - * See the author for a derivation if needed. - */ - - -/* - * In scan converting polygons, we want to choose those pixels - * which are inside the polygon. Thus, we add .5 to the starting - * x coordinate for both left and right edges. Now we choose the - * first pixel which is inside the pgon for the left edge and the - * first pixel which is outside the pgon for the right edge. - * Draw the left pixel, but not the right. - * - * How to add .5 to the starting x coordinate: - * If the edge is moving to the right, then subtract dy from the - * error term from the general form of the algorithm. - * If the edge is moving to the left, then add dy to the error term. - * - * The reason for the difference between edges moving to the left - * and edges moving to the right is simple: If an edge is moving - * to the right, then we want the algorithm to flip immediately. - * If it is moving to the left, then we don't want it to flip until - * we traverse an entire pixel. - */ -#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \ - int dx; /* local storage */ \ -\ - /* \ - * if the edge is horizontal, then it is ignored \ - * and assumed not to be processed. Otherwise, do this stuff. \ - */ \ - if ((dy) != 0) { \ - xStart = (x1); \ - dx = (x2) - xStart; \ - if (dx < 0) { \ - m = dx / (dy); \ - m1 = m - 1; \ - incr1 = -2 * dx + 2 * (dy) * m1; \ - incr2 = -2 * dx + 2 * (dy) * m; \ - d = 2 * m * (dy) - 2 * dx - 2 * (dy); \ - } else { \ - m = dx / (dy); \ - m1 = m + 1; \ - incr1 = 2 * dx - 2 * (dy) * m1; \ - incr2 = 2 * dx - 2 * (dy) * m; \ - d = -2 * m * (dy) + 2 * dx; \ - } \ - } \ -} - -#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \ - if (m1 > 0) { \ - if (d > 0) { \ - minval += m1; \ - d += incr1; \ - } \ - else { \ - minval += m; \ - d += incr2; \ - } \ - } else {\ - if (d >= 0) { \ - minval += m1; \ - d += incr1; \ - } \ - else { \ - minval += m; \ - d += incr2; \ - } \ - } \ -} - - -/* - * This structure contains all of the information needed - * to run the bresenham algorithm. - * The variables may be hardcoded into the declarations - * instead of using this structure to make use of - * register declarations. - */ -typedef struct { - int minor_axis; /* minor axis */ - int d; /* decision variable */ - int m, m1; /* slope and slope+1 */ - int incr1, incr2; /* error increments */ -} BRESINFO; - - -#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \ - BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \ - bres.m, bres.m1, bres.incr1, bres.incr2) - -#define BRESINCRPGONSTRUCT(bres) \ - BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2) - - - -/* - * These are the data structures needed to scan - * convert regions. Two different scan conversion - * methods are available -- the even-odd method, and - * the winding number method. - * The even-odd rule states that a point is inside - * the polygon if a ray drawn from that point in any - * direction will pass through an odd number of - * path segments. - * By the winding number rule, a point is decided - * to be inside the polygon if a ray drawn from that - * point in any direction passes through a different - * number of clockwise and counter-clockwise path - * segments. - * - * These data structures are adapted somewhat from - * the algorithm in (Foley/Van Dam) for scan converting - * polygons. - * The basic algorithm is to start at the top (smallest y) - * of the polygon, stepping down to the bottom of - * the polygon by incrementing the y coordinate. We - * keep a list of edges which the current scanline crosses, - * sorted by x. This list is called the Active Edge Table (AET) - * As we change the y-coordinate, we update each entry in - * in the active edge table to reflect the edges new xcoord. - * This list must be sorted at each scanline in case - * two edges intersect. - * We also keep a data structure known as the Edge Table (ET), - * which keeps track of all the edges which the current - * scanline has not yet reached. The ET is basically a - * list of ScanLineList structures containing a list of - * edges which are entered at a given scanline. There is one - * ScanLineList per scanline at which an edge is entered. - * When we enter a new edge, we move it from the ET to the AET. - * - * From the AET, we can implement the even-odd rule as in - * (Foley/Van Dam). - * The winding number rule is a little trickier. We also - * keep the EdgeTableEntries in the AET linked by the - * nextWETE (winding EdgeTableEntry) link. This allows - * the edges to be linked just as before for updating - * purposes, but only uses the edges linked by the nextWETE - * link as edges representing spans of the polygon to - * drawn (as with the even-odd rule). - */ - -/* - * for the winding number rule - */ -#define CLOCKWISE 1 -#define COUNTERCLOCKWISE -1 - -typedef struct _EdgeTableEntry { - int ymax; /* ycoord at which we exit this edge. */ - BRESINFO bres; /* Bresenham info to run the edge */ - struct _EdgeTableEntry *next; /* next in the list */ - struct _EdgeTableEntry *back; /* for insertion sort */ - struct _EdgeTableEntry *nextWETE; /* for winding num rule */ - int ClockWise; /* flag for winding number rule */ -} EdgeTableEntry; - - -typedef struct _ScanLineList{ - int scanline; /* the scanline represented */ - EdgeTableEntry *edgelist; /* header node */ - struct _ScanLineList *next; /* next in the list */ -} ScanLineList; - - -typedef struct { - int ymax; /* ymax for the polygon */ - int ymin; /* ymin for the polygon */ - ScanLineList scanlines; /* header node */ -} EdgeTable; - - -/* - * Here is a struct to help with storage allocation - * so we can allocate a big chunk at a time, and then take - * pieces from this heap when we need to. - */ -#define SLLSPERBLOCK 25 - -typedef struct _ScanLineListBlock { - ScanLineList SLLs[SLLSPERBLOCK]; - struct _ScanLineListBlock *next; -} ScanLineListBlock; - - - -/* - * - * a few macros for the inner loops of the fill code where - * performance considerations don't allow a procedure call. - * - * Evaluate the given edge at the given scanline. - * If the edge has expired, then we leave it and fix up - * the active edge table; otherwise, we increment the - * x value to be ready for the next scanline. - * The winding number rule is in effect, so we must notify - * the caller when the edge has been removed so he - * can reorder the Winding Active Edge Table. - */ -#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \ - if (pAET->ymax == y) { /* leaving this edge */ \ - pPrevAET->next = pAET->next; \ - pAET = pPrevAET->next; \ - fixWAET = 1; \ - if (pAET) \ - pAET->back = pPrevAET; \ - } \ - else { \ - BRESINCRPGONSTRUCT(pAET->bres) \ - pPrevAET = pAET; \ - pAET = pAET->next; \ - } \ -} - - -/* - * Evaluate the given edge at the given scanline. - * If the edge has expired, then we leave it and fix up - * the active edge table; otherwise, we increment the - * x value to be ready for the next scanline. - * The even-odd rule is in effect. - */ -#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \ - if (pAET->ymax == y) { /* leaving this edge */ \ - pPrevAET->next = pAET->next; \ - pAET = pPrevAET->next; \ - if (pAET) \ - pAET->back = pPrevAET; \ - } \ - else { \ - BRESINCRPGONSTRUCT(pAET->bres) \ - pPrevAET = pAET; \ - pAET = pAET->next; \ - } \ -} -// END OF poly.h extract -// START OF PolyReg.c extract -/* $XConsortium: PolyReg.c,v 11.23 94/11/17 21:59:37 converse Exp $ */ -/************************************************************************ - -Copyright (c) 1987 X Consortium - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -************************************************************************/ -/* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */ - -#define LARGE_COORDINATE 1000000 -#define SMALL_COORDINATE -LARGE_COORDINATE - -/* - * InsertEdgeInET - * - * Insert the given edge into the edge table. - * First we must find the correct bucket in the - * Edge table, then find the right slot in the - * bucket. Finally, we can insert it. - * - */ -static void -InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline, - ScanLineListBlock **SLLBlock, int *iSLLBlock) -{ - EdgeTableEntry *start, *prev; - ScanLineList *pSLL, *pPrevSLL; - ScanLineListBlock *tmpSLLBlock; - - /* - * find the right bucket to put the edge into - */ - pPrevSLL = &ET->scanlines; - pSLL = pPrevSLL->next; - while (pSLL && (pSLL->scanline < scanline)) - { - pPrevSLL = pSLL; - pSLL = pSLL->next; - } - - /* - * reassign pSLL (pointer to ScanLineList) if necessary - */ - if ((!pSLL) || (pSLL->scanline > scanline)) - { - if (*iSLLBlock > SLLSPERBLOCK-1) - { - tmpSLLBlock = - (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock)); - (*SLLBlock)->next = tmpSLLBlock; - tmpSLLBlock->next = (ScanLineListBlock *)NULL; - *SLLBlock = tmpSLLBlock; - *iSLLBlock = 0; - } - pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); - - pSLL->next = pPrevSLL->next; - pSLL->edgelist = (EdgeTableEntry *)NULL; - pPrevSLL->next = pSLL; - } - pSLL->scanline = scanline; - - /* - * now insert the edge in the right bucket - */ - prev = (EdgeTableEntry *)NULL; - start = pSLL->edgelist; - while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) - { - prev = start; - start = start->next; - } - ETE->next = start; - - if (prev) - prev->next = ETE; - else - pSLL->edgelist = ETE; -} - -/* - * CreateEdgeTable - * - * This routine creates the edge table for - * scan converting polygons. - * The Edge Table (ET) looks like: - * - * EdgeTable - * -------- - * | ymax | ScanLineLists - * |scanline|-->------------>-------------->... - * -------- |scanline| |scanline| - * |edgelist| |edgelist| - * --------- --------- - * | | - * | | - * V V - * list of ETEs list of ETEs - * - * where ETE is an EdgeTableEntry data structure, - * and there is one ScanLineList per scanline at - * which an edge is initially entered. - * - */ - -static void -CreateETandAET(int count, TQPoint *pts, - EdgeTable *ET, EdgeTableEntry *AET, EdgeTableEntry *pETEs, - ScanLineListBlock *pSLLBlock) -{ - TQPoint *top, *bottom; - TQPoint *PrevPt, *CurrPt; - int iSLLBlock = 0; - int dy; - - if (count < 2) return; - - /* - * initialize the Active Edge Table - */ - AET->next = (EdgeTableEntry *)NULL; - AET->back = (EdgeTableEntry *)NULL; - AET->nextWETE = (EdgeTableEntry *)NULL; - AET->bres.minor_axis = SMALL_COORDINATE; - - /* - * initialize the Edge Table. - */ - ET->scanlines.next = (ScanLineList *)NULL; - ET->ymax = SMALL_COORDINATE; - ET->ymin = LARGE_COORDINATE; - pSLLBlock->next = (ScanLineListBlock *)NULL; - - PrevPt = &pts[count-1]; - - /* - * for each vertex in the array of points. - * In this loop we are dealing with two vertices at - * a time -- these make up one edge of the polygon. - */ - while (count--) - { - CurrPt = pts++; - - /* - * find out which point is above and which is below. - */ - if (PrevPt->y() > CurrPt->y() ) - { - bottom = PrevPt, top = CurrPt; - pETEs->ClockWise = 0; - } - else - { - bottom = CurrPt, top = PrevPt; - pETEs->ClockWise = 1; - } - - /* - * don't add horizontal edges to the Edge table. - */ - if ( bottom->y() != top->y() ) - { - pETEs->ymax = bottom->y()-1; /* -1 so we don't get last scanline */ - - /* - * initialize integer edge algorithm - */ - dy = bottom->y() - top->y(); - BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres) - - InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock); - - if (PrevPt->y() > ET->ymax) - ET->ymax = PrevPt->y(); - if (PrevPt->y() < ET->ymin) - ET->ymin = PrevPt->y(); - pETEs++; - } - - PrevPt = CurrPt; - } -} - -/* - * loadAET - * - * This routine moves EdgeTableEntries from the - * EdgeTable into the Active Edge Table, - * leaving them sorted by smaller x coordinate. - * - */ - -static void -loadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs) -{ - EdgeTableEntry *pPrevAET; - EdgeTableEntry *tmp; - - pPrevAET = AET; - AET = AET->next; - while (ETEs) - { - while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) - { - pPrevAET = AET; - AET = AET->next; - } - tmp = ETEs->next; - ETEs->next = AET; - if (AET) - AET->back = ETEs; - ETEs->back = pPrevAET; - pPrevAET->next = ETEs; - pPrevAET = ETEs; - - ETEs = tmp; - } -} - -/* - * computeWAET - * - * This routine links the AET by the - * nextWETE (winding EdgeTableEntry) link for - * use by the winding number rule. The final - * Active Edge Table (AET) might look something - * like: - * - * AET - * ---------- --------- --------- - * |ymax | |ymax | |ymax | - * | ... | |... | |... | - * |next |->|next |->|next |->... - * |nextWETE| |nextWETE| |nextWETE| - * --------- --------- ^-------- - * | | | - * V-------------------> V---> ... - * - */ -static void -computeWAET(EdgeTableEntry *AET) -{ - EdgeTableEntry *pWETE; - int inside = 1; - int isInside = 0; - - AET->nextWETE = (EdgeTableEntry *)NULL; - pWETE = AET; - AET = AET->next; - while (AET) - { - if (AET->ClockWise) - isInside++; - else - isInside--; - - if ((!inside && !isInside) || - ( inside && isInside)) - { - pWETE->nextWETE = AET; - pWETE = AET; - inside = !inside; - } - AET = AET->next; - } - pWETE->nextWETE = (EdgeTableEntry *)NULL; -} - -/* - * InsertionSort - * - * Just a simple insertion sort using - * pointers and back pointers to sort the Active - * Edge Table. - * - */ - -static int -InsertionSort(EdgeTableEntry *AET) -{ - EdgeTableEntry *pETEchase; - EdgeTableEntry *pETEinsert; - EdgeTableEntry *pETEchaseBackTMP; - int changed = 0; - - AET = AET->next; - while (AET) - { - pETEinsert = AET; - pETEchase = AET; - while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) - pETEchase = pETEchase->back; - - AET = AET->next; - if (pETEchase != pETEinsert) - { - pETEchaseBackTMP = pETEchase->back; - pETEinsert->back->next = AET; - if (AET) - AET->back = pETEinsert->back; - pETEinsert->next = pETEchase; - pETEchase->back->next = pETEinsert; - pETEchase->back = pETEinsert; - pETEinsert->back = pETEchaseBackTMP; - changed = 1; - } - } - return(changed); -} - -/* - * Clean up our act. - */ -static void -FreeStorage(ScanLineListBlock *pSLLBlock) -{ - ScanLineListBlock *tmpSLLBlock; - - while (pSLLBlock) - { - tmpSLLBlock = pSLLBlock->next; - free((char *)pSLLBlock); - pSLLBlock = tmpSLLBlock; - } -} - -/* - * Create an array of rectangles from a list of points. - * If indeed these things (POINTS, RECTS) are the same, - * then this proc is still needed, because it allocates - * storage for the array, which was allocated on the - * stack by the calling procedure. - * - */ -static int PtsToRegion(int numFullPtBlocks, int iCurPtBlock, - POINTBLOCK *FirstPtBlock, TQRegionPrivate *reg) -{ - TQRect *rects; - TQPoint *pts; - POINTBLOCK *CurPtBlock; - int i; - TQRect *extents; - int numRects; - - extents = ®->extents; - - numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; - - reg->rects.resize(numRects); - - CurPtBlock = FirstPtBlock; - rects = reg->rects.data() - 1; - numRects = 0; - extents->setLeft( INT_MAX ); - extents->setRight( INT_MIN ); - - for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { - /* the loop uses 2 points per iteration */ - i = NUMPTSTOBUFFER >> 1; - if (!numFullPtBlocks) - i = iCurPtBlock >> 1; - for (pts = CurPtBlock->pts; i--; pts += 2) { - if ( pts->x() == pts[1].x() ) - continue; - if (numRects && pts->x() == rects->left() && pts->y() == rects->bottom() + 1 && - pts[1].x() == rects->right() && - (numRects == 1 || rects[-1].top() != rects->top()) && - (i && pts[2].y() > pts[1].y() )) { - rects->setBottom( pts[1].y() ); - continue; - } - numRects++; - rects++; - qt_setCoords( rects, pts->x(), pts->y(), pts[1].x() - 1, pts[1].y() ); - if (rects->left() < extents->left()) - extents->setLeft( rects->left() ); - if (rects->right() > extents->right()) - extents->setRight( rects->right() ); - } - CurPtBlock = CurPtBlock->next; - } - - if (numRects) { - extents->setTop( reg->rects[0].top() ); - extents->setBottom( rects->bottom() ); - } else { - qt_setCoords(extents, 0, 0, 0, 0); - } - reg->numRects = numRects; - - return(TRUE); -} - -/* - * polytoregion - * - * Scan converts a polygon by returning a run-length - * encoding of the resultant bitmap -- the run-length - * encoding is in the form of an array of rectangles. - */ -static TQRegionPrivate *PolygonRegion(TQPoint *Pts, int Count, int rule) - //Point *Pts; /* the pts */ - //int Count; /* number of pts */ - //int rule; /* winding rule */ -{ - TQRegionPrivate *region; - EdgeTableEntry *pAET; /* Active Edge Table */ - int y; /* current scanline */ - int iPts = 0; /* number of pts in buffer */ - EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ - ScanLineList *pSLL; /* current scanLineList */ - TQPoint *pts; /* output buffer */ - EdgeTableEntry *pPrevAET; /* ptr to previous AET */ - EdgeTable ET; /* header node for ET */ - EdgeTableEntry AET; /* header node for AET */ - EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ - ScanLineListBlock SLLBlock; /* header for scanlinelist */ - int fixWAET = FALSE; - POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ - POINTBLOCK *tmpPtBlock; - int numFullPtBlocks = 0; - - if ( !(region = new TQRegionPrivate) ) - return 0; - - /* special case a rectangle */ - pts = Pts; - if (((Count == 4) || - ((Count == 5) && (pts[4].x() == pts[0].x() ) && (pts[4].y() == pts[0].y() ))) && - (((pts[0].y() == pts[1].y()) && - (pts[1].x() == pts[2].x()) && - (pts[2].y() == pts[3].y()) && - (pts[3].x() == pts[0].x())) || - ((pts[0].x() == pts[1].x()) && - (pts[1].y() == pts[2].y()) && - (pts[2].x() == pts[3].x()) && - (pts[3].y() == pts[0].y())))) { - region->extents.setLeft( TQMIN(pts[0].x(), pts[2].x()) ); - region->extents.setTop( TQMIN(pts[0].y(), pts[2].y()) ); - region->extents.setRight( TQMAX(pts[0].x(), pts[2].x()) ); - region->extents.setBottom( TQMAX(pts[0].y(), pts[2].y()) ); - if ((region->extents.left() <= region->extents.right()) && - (region->extents.top() <= region->extents.bottom())) { - region->numRects = 1; - region->rects.resize(1); - region->rects[0] = region->extents; - } - return region; - } - - if (! (pETEs = (EdgeTableEntry *) - malloc((unsigned) (sizeof(EdgeTableEntry) * Count)))) - return 0; - - pts = FirstPtBlock.pts; - CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock); - pSLL = ET.scanlines.next; - curPtBlock = &FirstPtBlock; - - if (rule == EvenOddRule) { - /* - * for each scanline - */ - for (y = ET.ymin; y < ET.ymax; y++) { - /* - * Add a new edge to the active edge table when we - * get to the next edge. - */ - if (pSLL != NULL && y == pSLL->scanline) { - loadAET(&AET, pSLL->edgelist); - pSLL = pSLL->next; - } - pPrevAET = &AET; - pAET = AET.next; - - /* - * for each active edge - */ - while (pAET) { - pts->setX( pAET->bres.minor_axis ), pts->setY( y ); - pts++, iPts++; - - /* - * send out the buffer - */ - if (iPts == NUMPTSTOBUFFER) { - tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); - curPtBlock->next = tmpPtBlock; - curPtBlock = tmpPtBlock; - pts = curPtBlock->pts; - numFullPtBlocks++; - iPts = 0; - } - EVALUATEEDGEEVENODD(pAET, pPrevAET, y) - } - (void) InsertionSort(&AET); - } - } - else { - /* - * for each scanline - */ - for (y = ET.ymin; y < ET.ymax; y++) { - /* - * Add a new edge to the active edge table when we - * get to the next edge. - */ - if (pSLL != NULL && y == pSLL->scanline) { - loadAET(&AET, pSLL->edgelist); - computeWAET(&AET); - pSLL = pSLL->next; - } - pPrevAET = &AET; - pAET = AET.next; - pWETE = pAET; - - /* - * for each active edge - */ - while (pAET) { - /* - * add to the buffer only those edges that - * are in the Winding active edge table. - */ - if (pWETE == pAET) { - pts->setX( pAET->bres.minor_axis), pts->setY( y ); - pts++, iPts++; - - /* - * send out the buffer - */ - if (iPts == NUMPTSTOBUFFER) { - tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); - curPtBlock->next = tmpPtBlock; - curPtBlock = tmpPtBlock; - pts = curPtBlock->pts; - numFullPtBlocks++; iPts = 0; - } - pWETE = pWETE->nextWETE; - } - EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) - } - - /* - * recompute the winding active edge table if - * we just resorted or have exited an edge. - */ - if (InsertionSort(&AET) || fixWAET) { - computeWAET(&AET); - fixWAET = FALSE; - } - } - } - FreeStorage(SLLBlock.next); - (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); - for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { - tmpPtBlock = curPtBlock->next; - free((char *)curPtBlock); - curPtBlock = tmpPtBlock; - } - free((char *)pETEs); - return region; -} -// END OF PolyReg.c extract - -TQRegionPrivate *qt_bitmapToRegion(const TQBitmap& bitmap) -{ - TQImage image = bitmap.convertToImage(); - - TQRegionPrivate *region = new TQRegionPrivate; - TQRect xr; - -#define AddSpan \ - { \ - qt_setCoords( &xr, prev1, y, x-1, y ); \ - UnionRectWithRegion( &xr, region, region ); \ - } - - const int zero=0; - bool little = image.bitOrder() == TQImage::LittleEndian; - - int x, y; - for (y=0; yw-8 || byte!=all ) { - if ( little ) { - for ( int b=8; b>0 && x>= 1; - x++; - } - } else { - for ( int b=8; b>0 && xdata; - data->ref(); -} - -/*! \internal - Internal constructor that creates a null region. -*/ - -TQRegion::TQRegion( bool is_null ) -{ - data = new TQRegionData; - TQ_CHECK_PTR( data ); - data->region = new TQRegionPrivate; - data->is_null = is_null; - data->rgn = 0; - data->xrectangles = 0; -} - -/*! - \overload - - Create a region based on the rectange \a r with region type \a t. - - If the rectangle is invalid a null region will be created. - - \sa TQRegion::RegionType -*/ - -TQRegion::TQRegion( const TQRect &r, RegionType t ) -{ - if ( r.isEmpty() ) { - if ( !empty_region ) { // avoid too many allocs - tqAddPostRoutine( cleanup_empty_region ); - empty_region = new TQRegion( TRUE ); - TQ_CHECK_PTR( empty_region ); - } - data = empty_region->data; - data->ref(); - } else { - data = new TQRegionData; - TQ_CHECK_PTR( data ); - data->is_null = FALSE; - data->rgn = 0; - data->xrectangles = 0; - if ( t == Rectangle ) { // rectangular region - data->region = new TQRegionPrivate( r ); - } else if ( t == Ellipse ) { // elliptic region - TQPointArray a; - a.makeEllipse( r.x(), r.y(), r.width(), r.height() ); - data->region = PolygonRegion( (TQPoint*)a.data(), a.size(), - EvenOddRule ); - } - } -} - - -/*! - Constructs a polygon region from the point array \a a. - - If \a winding is TRUE, the polygon region is filled using the - winding algorithm, otherwise the default even-odd fill algorithm - is used. - - This constructor may create complex regions that will slow down - painting when used. -*/ - -TQRegion::TQRegion( const TQPointArray &a, bool winding ) -{ - if (a.size() > 2) { - data = new TQRegionData; - TQ_CHECK_PTR( data ); - data->is_null = FALSE; - data->rgn = 0; - data->xrectangles = 0; - data->region = PolygonRegion( (TQPoint*)a.data(), a.size(), - winding ? WindingRule : EvenOddRule ); - } else { - if ( !empty_region ) { - tqAddPostRoutine( cleanup_empty_region ); - empty_region = new TQRegion( TRUE ); - TQ_CHECK_PTR( empty_region ); - } - data = empty_region->data; - data->ref(); - } -} - - -/*! - Constructs a new region which is equal to region \a r. -*/ - -TQRegion::TQRegion( const TQRegion &r ) -{ - data = r.data; - data->ref(); -} - - -/*! - Constructs a region from the bitmap \a bm. - - The resulting region consists of the pixels in bitmap \a bm that - are \c color1, as if each pixel was a 1 by 1 rectangle. - - This constructor may create complex regions that will slow down - painting when used. Note that drawing masked pixmaps can be done - much faster using TQPixmap::setMask(). -*/ -TQRegion::TQRegion( const TQBitmap & bm ) -{ - if ( bm.isNull() ) { - if ( !empty_region ) { // avoid too many allocs - tqAddPostRoutine( cleanup_empty_region ); - empty_region = new TQRegion( TRUE ); - TQ_CHECK_PTR( empty_region ); - } - data = empty_region->data; - data->ref(); - } else { - data = new TQRegionData; - TQ_CHECK_PTR( data ); - data->is_null = FALSE; - data->rgn = 0; - data->xrectangles = 0; - data->region = qt_bitmapToRegion(bm); - } -} - -/*! - Destroys the region. -*/ - -TQRegion::~TQRegion() -{ - if ( data->deref() ) { - delete data->region; - if ( data->rgn ) - XDestroyRegion( data->rgn ); - if ( data->xrectangles ) - free( data->xrectangles ); - delete data; - } -} - - -/*! - Assigns \a r to this region and returns a reference to the region. -*/ - -TQRegion &TQRegion::operator=( const TQRegion &r ) -{ - r.data->ref(); // beware of r = r - if ( data->deref() ) { - delete data->region; - if ( data->rgn ) - XDestroyRegion( data->rgn ); - if ( data->xrectangles ) - free( data->xrectangles ); - delete data; - } - data = r.data; - return *this; -} - - -/*! - Returns a \link shclass.html deep copy\endlink of the region. - - \sa detach() -*/ - -TQRegion TQRegion::copy() const -{ - TQRegion r( data->is_null ); - *r.data->region = *data->region; - return r; -} - -/*! - Returns TRUE if the region is a null region; otherwise returns - FALSE. - - A null region is a region that has not been initialized. A null - region is always empty. - - \sa isEmpty() -*/ - -bool TQRegion::isNull() const -{ - return data->is_null; -} - - -/*! - Returns TRUE if the region is empty; otherwise returns FALSE. An - empty region is a region that contains no points. - - Example: - \code - TQRegion r1( 10, 10, 20, 20 ); - TQRegion r2( 40, 40, 20, 20 ); - TQRegion r3; - r1.isNull(); // FALSE - r1.isEmpty(); // FALSE - r3.isNull(); // TRUE - r3.isEmpty(); // TRUE - r3 = r1.intersect( r2 ); // r3 = intersection of r1 and r2 - r3.isNull(); // FALSE - r3.isEmpty(); // TRUE - r3 = r1.unite( r2 ); // r3 = union of r1 and r2 - r3.isNull(); // FALSE - r3.isEmpty(); // FALSE - \endcode - - \sa isNull() -*/ - -bool TQRegion::isEmpty() const -{ - return data->is_null || ( data->region->numRects == 0 ); -} - - -/*! - Returns TRUE if the region contains the point \a p; otherwise - returns FALSE. -*/ - -bool TQRegion::contains( const TQPoint &p ) const -{ - return PointInRegion( data->region, p.x(), p.y() ); -} - -/*! - \overload - - Returns TRUE if the region overlaps the rectangle \a r; otherwise - returns FALSE. -*/ - -bool TQRegion::contains( const TQRect &r ) const -{ - return RectInRegion( data->region, r.left(), r.top(), - r.width(), r.height() ) != RectangleOut; -} - - -/*! - Translates (moves) the region \a dx along the X axis and \a dy - along the Y axis. -*/ - -void TQRegion::translate( int dx, int dy ) -{ - if ( empty_region && data == empty_region->data ) - return; - detach(); - OffsetRegion( data->region, dx, dy ); - if ( data->xrectangles ) { - free( data->xrectangles ); - data->xrectangles = 0; - } -} - - -/*! - Returns a region which is the union of this region and \a r. - - \img runion.png Region Union - - The figure shows the union of two elliptical regions. -*/ - -TQRegion TQRegion::unite( const TQRegion &r ) const -{ - TQRegion result( FALSE ); - UnionRegion( data->region, r.data->region, result.data->region ); - return result; -} - -/*! - Returns a region which is the intersection of this region and \a r. - - \img rintersect.png Region Intersection - - The figure shows the intersection of two elliptical regions. -*/ - -TQRegion TQRegion::intersect( const TQRegion &r ) const -{ - TQRegion result( FALSE ); - IntersectRegion( data->region, r.data->region, result.data->region ); - return result; -} - -/*! - Returns a region which is \a r subtracted from this region. - - \img rsubtract.png Region Subtraction - - The figure shows the result when the ellipse on the right is - subtracted from the ellipse on the left. (\c left-right ) -*/ - -TQRegion TQRegion::subtract( const TQRegion &r ) const -{ - TQRegion result( FALSE ); - SubtractRegion( data->region, r.data->region, result.data->region ); - return result; -} - -/*! - Returns a region which is the exclusive or (XOR) of this region - and \a r. - - \img rxor.png Region XORed - - The figure shows the exclusive or of two elliptical regions. -*/ - -TQRegion TQRegion::eor( const TQRegion &r ) const -{ - TQRegion result( FALSE ); - XorRegion( data->region, r.data->region, result.data->region ); - return result; -} - -/*! - Returns the bounding rectangle of this region. An empty region - gives a rectangle that is TQRect::isNull(). -*/ - -TQRect TQRegion::boundingRect() const -{ - return data->region->extents; -} - - -/*! - Returns an array of non-overlapping rectangles that make up the - region. - - The union of all the rectangles is equal to the original region. -*/ - -TQMemArray TQRegion::rects() const -{ - TQMemArray rects; - rects.duplicate( data->region->rects, data->region->numRects ); - return rects; -} - -/*! - Sets the region to be the given set of rectangles. The rectangles - \e must be optimal Y-X sorted bands as follows: -
    -
  • The rectangles must not intersect -
  • All rectangles with a given top coordinate must have the same height. -
  • No two rectangles may abut horizontally (they should be combined - into a single wider rectangle in that case). -
  • The rectangles must be sorted ascendingly by Y as the major sort key - and X as the minor sort key. -
-*/ -void TQRegion::setRects( const TQRect *rects, int num ) -{ - *this = TQRegion( FALSE ); - if ( !rects || (num == 1 && rects->isEmpty()) ) - num = 0; - - data->region->rects.duplicate( rects, num ); - data->region->numRects = num; - if ( num == 0 ) { - data->region->extents = TQRect(); - } else { - int left = INT_MAX, right = INT_MIN, top = INT_MAX, bottom = INT_MIN; - int i; - for ( i = 0; i < num; i++ ) { - left = TQMIN( rects[i].left(), left ); - right = TQMAX( rects[i].right(), right ); - top = TQMIN( rects[i].top(), top ); - bottom = TQMAX( rects[i].bottom(), bottom ); - } - data->region->extents = TQRect( TQPoint(left, top), TQPoint(right, bottom) ); - } -} - -/*! - Returns TRUE if the region is equal to \a r; otherwise returns - FALSE. -*/ - -bool TQRegion::operator==( const TQRegion &r ) const -{ - return data == r.data ? - TRUE : EqualRegion( data->region, r.data->region ); -} - -/*! - \fn bool TQRegion::operator!=( const TQRegion &r ) const - - Returns TRUE if the region is different from \a r; otherwise - returns FALSE. -*/ - -/* - This is how X represents regions internally. -*/ - -struct BOX { - short x1, x2, y1, y2; -}; - -struct _XRegion { - long size; - long numRects; - BOX *rects; - BOX extents; -}; - - -void TQRegion::updateX11Region() const -{ - data->rgn = XCreateRegion(); - - for( int i = 0; i < data->region->numRects; i++ ) { - XRectangle r; - const TQRect &rect = data->region->rects[i]; - r.x = TQMAX( SHRT_MIN, rect.x() ); - r.y = TQMAX( SHRT_MIN, rect.y() ); - r.width = TQMIN( USHRT_MAX, rect.width() ); - r.height = TQMIN( USHRT_MAX, rect.height() ); - XUnionRectWithRegion( &r, data->rgn, data->rgn ); - } -} - - -void *TQRegion::clipRectangles( int &num ) const -{ - if ( !data->xrectangles ) { - XRectangle *r = (XRectangle *) malloc( data->region->numRects * sizeof( XRectangle ) ); - data->xrectangles = r; - for( int i = 0; i < data->region->numRects; i++ ) { - const TQRect &rect = data->region->rects[i]; - r->x = TQMAX( SHRT_MIN, rect.x() ); - r->y = TQMAX( SHRT_MIN, rect.y() ); - r->width = TQMIN( USHRT_MAX, rect.width() ); - r->height = TQMIN( USHRT_MAX, rect.height() ); - r++; - } - } - num = data->region->numRects; - return data->xrectangles; -} diff --git a/src/kernel/qrichtext_p.h b/src/kernel/qrichtext_p.h index c9e40ef84..8ef3396df 100644 --- a/src/kernel/qrichtext_p.h +++ b/src/kernel/qrichtext_p.h @@ -56,7 +56,7 @@ #ifndef QT_H #include "tqstring.h" #include "tqptrlist.h" -#include "ntqrect.h" +#include "tqrect.h" #include "tqfontmetrics.h" #include "tqintdict.h" #include "tqmap.h" @@ -68,7 +68,7 @@ #include "tqvaluestack.h" #include "tqobject.h" #include "tqdict.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqstylesheet.h" #include "tqptrvector.h" #include "tqpainter.h" diff --git a/src/kernel/qscriptengine.cpp b/src/kernel/qscriptengine.cpp index b84aab65d..bbf0f30bb 100644 --- a/src/kernel/qscriptengine.cpp +++ b/src/kernel/qscriptengine.cpp @@ -37,7 +37,7 @@ #include "qscriptengine_p.h" #include "tqstring.h" -#include "ntqrect.h" +#include "tqrect.h" #include "tqfont.h" #include #include "tqtextengine_p.h" diff --git a/src/kernel/qt_gfx.pri b/src/kernel/qt_gfx.pri index f0124824e..c66f3141e 100644 --- a/src/kernel/qt_gfx.pri +++ b/src/kernel/qt_gfx.pri @@ -98,8 +98,8 @@ jpeg { else:DEFINES += TQT_NO_IMAGEIO_JPEG #png support -HEADERS+=$$KERNEL_H/ntqpngio.h -SOURCES+=$$KERNEL_CPP/qpngio.cpp +HEADERS+=$$KERNEL_H/tqpngio.h +SOURCES+=$$KERNEL_CPP/tqpngio.cpp png { system-png { unix:LIBS += -lpng diff --git a/src/kernel/qt_kernel.pri b/src/kernel/qt_kernel.pri index 946fdbd96..c56afb6b2 100644 --- a/src/kernel/qt_kernel.pri +++ b/src/kernel/qt_kernel.pri @@ -53,19 +53,19 @@ kernel { $$KERNEL_H/tqpaintdevice.h \ $$KERNEL_H/tqpainter.h \ $$KERNEL_P/tqpainter_p.h \ - $$KERNEL_H/ntqpalette.h \ + $$KERNEL_H/tqpalette.h \ $$KERNEL_H/tqpaintdevicemetrics.h \ - $$KERNEL_H/ntqpen.h \ - $$KERNEL_H/ntqpicture.h \ - $$KERNEL_H/ntqpixmap.h \ - $$KERNEL_H/ntqpixmapcache.h \ - $$KERNEL_H/ntqpointarray.h \ - $$KERNEL_H/ntqpoint.h \ + $$KERNEL_H/tqpen.h \ + $$KERNEL_H/tqpicture.h \ + $$KERNEL_H/tqpixmap.h \ + $$KERNEL_H/tqpixmapcache.h \ + $$KERNEL_H/tqpointarray.h \ + $$KERNEL_H/tqpoint.h \ $$KERNEL_H/ntqpolygonscanner.h \ - $$KERNEL_H/ntqprinter.h \ + $$KERNEL_H/tqprinter.h \ $$KERNEL_H/tqprocess.h \ - $$KERNEL_H/ntqrect.h \ - $$KERNEL_H/ntqregion.h \ + $$KERNEL_H/tqrect.h \ + $$KERNEL_H/tqregion.h \ $$KERNEL_H/tqsessionmanager.h \ $$KERNEL_H/tqsignal.h \ $$KERNEL_H/tqsignalmapper.h \ @@ -87,7 +87,7 @@ kernel { $$KERNEL_H/tqwidgetintdict.h \ $$KERNEL_H/tqwidgetlist.h \ $$KERNEL_H/ntqwindowdefs.h \ - $$KERNEL_H/ntqwmatrix.h \ + $$KERNEL_H/tqwmatrix.h \ $$KERNEL_H/ntqvariant.h \ $$KERNEL_P/qrichtext_p.h \ $$KERNEL_P/qinternal_p.h \ @@ -120,12 +120,12 @@ kernel { $$KERNEL_CPP/tqfont_win.cpp \ $$KERNEL_CPP/qinputcontext_win.cpp \ $$KERNEL_CPP/tqmime_win.cpp \ - $$KERNEL_CPP/qpixmap_win.cpp \ - $$KERNEL_CPP/qprinter_win.cpp \ + $$KERNEL_CPP/tqpixmap_win.cpp \ + $$KERNEL_CPP/tqprinter_win.cpp \ $$KERNEL_CPP/tqprocess_win.cpp \ $$KERNEL_CPP/tqpaintdevice_win.cpp \ $$KERNEL_CPP/tqpainter_win.cpp \ - $$KERNEL_CPP/qregion_win.cpp \ + $$KERNEL_CPP/tqregion_win.cpp \ $$KERNEL_CPP/qsound_win.cpp \ $$KERNEL_CPP/tqthread_win.cpp \ $$KERNEL_CPP/tqwidget_win.cpp \ @@ -143,10 +143,10 @@ kernel { $$KERNEL_CPP/qinputcontext.cpp \ $$KERNEL_CPP/qinputcontext_x11.cpp \ $$KERNEL_CPP/qmotifdnd_x11.cpp \ - $$KERNEL_CPP/qpixmap_x11.cpp \ + $$KERNEL_CPP/tqpixmap_x11.cpp \ $$KERNEL_CPP/tqpaintdevice_x11.cpp \ $$KERNEL_CPP/tqpainter_x11.cpp \ - $$KERNEL_CPP/qregion_x11.cpp \ + $$KERNEL_CPP/tqregion_x11.cpp \ $$KERNEL_CPP/qsound_x11.cpp \ $$KERNEL_CPP/tqwidget_x11.cpp \ $$KERNEL_CPP/tqwidgetcreate_x11.cpp \ @@ -170,18 +170,18 @@ kernel { $$KERNEL_CPP/tqmime_mac.cpp \ $$KERNEL_CPP/qdnd_mac.cpp \ $$KERNEL_CPP/qdesktopwidget_mac.cpp \ - $$KERNEL_CPP/qpixmap_mac.cpp \ - $$KERNEL_CPP/qprinter_mac.cpp \ + $$KERNEL_CPP/tqpixmap_mac.cpp \ + $$KERNEL_CPP/tqprinter_mac.cpp \ $$KERNEL_CPP/tqpaintdevice_mac.cpp \ $$KERNEL_CPP/tqpainter_mac.cpp \ - $$KERNEL_CPP/qregion_mac.cpp \ + $$KERNEL_CPP/tqregion_mac.cpp \ $$KERNEL_CPP/tqwidget_mac.cpp \ $$KERNEL_CPP/qeventloop_mac.cpp \ $$KERNEL_CPP/tqfont_mac.cpp \ $$KERNEL_CPP/tqfontengine_mac.cpp DEFINES += QMAC_ONE_PIXEL_LOCK } else:unix { - SOURCES += $$KERNEL_CPP/qprinter_unix.cpp \ + SOURCES += $$KERNEL_CPP/tqprinter_unix.cpp \ $$KERNEL_CPP/qpsprinter.cpp glibmainloop { SOURCES += $$KERNEL_CPP/qeventloop_unix_glib.cpp @@ -228,18 +228,18 @@ kernel { $$KERNEL_CPP/tqobject.cpp \ $$KERNEL_CPP/tqobjectcleanuphandler.cpp \ $$KERNEL_CPP/tqpainter.cpp \ - $$KERNEL_CPP/qpalette.cpp \ + $$KERNEL_CPP/tqpalette.cpp \ $$KERNEL_CPP/tqpaintdevicemetrics.cpp \ - $$KERNEL_CPP/qpicture.cpp \ - $$KERNEL_CPP/qpixmap.cpp \ - $$KERNEL_CPP/qpixmapcache.cpp \ - $$KERNEL_CPP/qpointarray.cpp \ - $$KERNEL_CPP/qpoint.cpp \ + $$KERNEL_CPP/tqpicture.cpp \ + $$KERNEL_CPP/tqpixmap.cpp \ + $$KERNEL_CPP/tqpixmapcache.cpp \ + $$KERNEL_CPP/tqpointarray.cpp \ + $$KERNEL_CPP/tqpoint.cpp \ $$KERNEL_CPP/qpolygonscanner.cpp \ - $$KERNEL_CPP/qprinter.cpp \ + $$KERNEL_CPP/tqprinter.cpp \ $$KERNEL_CPP/tqprocess.cpp \ - $$KERNEL_CPP/qrect.cpp \ - $$KERNEL_CPP/qregion.cpp \ + $$KERNEL_CPP/tqrect.cpp \ + $$KERNEL_CPP/tqregion.cpp \ $$KERNEL_CPP/tqsignal.cpp \ $$KERNEL_CPP/tqsignalmapper.cpp \ $$KERNEL_CPP/tqsize.cpp \ @@ -255,7 +255,7 @@ kernel { $$KERNEL_CPP/tqurloperator.cpp \ $$KERNEL_CPP/tqurlinfo.cpp \ $$KERNEL_CPP/tqwidget.cpp \ - $$KERNEL_CPP/qwmatrix.cpp \ + $$KERNEL_CPP/tqwmatrix.cpp \ $$KERNEL_CPP/qvariant.cpp \ $$KERNEL_CPP/qrichtext.cpp \ $$KERNEL_CPP/qinternal.cpp \ diff --git a/src/kernel/qt_pch.h b/src/kernel/qt_pch.h index bfd957097..54ca333f9 100644 --- a/src/kernel/qt_pch.h +++ b/src/kernel/qt_pch.h @@ -32,7 +32,7 @@ #include // All moc genereated code has this include #include #include -#include +#include #include #include #include diff --git a/src/kernel/qvariant.cpp b/src/kernel/qvariant.cpp index 3f8944ab7..ac3157676 100644 --- a/src/kernel/qvariant.cpp +++ b/src/kernel/qvariant.cpp @@ -45,18 +45,18 @@ #include "tqstring.h" #include "tqcstring.h" #include "tqfont.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqimage.h" #include "tqbrush.h" -#include "ntqpoint.h" -#include "ntqrect.h" +#include "tqpoint.h" +#include "tqrect.h" #include "tqsize.h" #include "tqcolor.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "tqiconset.h" #include "tqdatastream.h" -#include "ntqregion.h" -#include "ntqpointarray.h" +#include "tqregion.h" +#include "tqpointarray.h" #include "tqbitmap.h" #include "ntqcursor.h" #include "tqdatetime.h" @@ -64,7 +64,7 @@ #include "ntqshared.h" #include "tqbitarray.h" #include "ntqkeysequence.h" -#include "ntqpen.h" +#include "tqpen.h" #ifndef DBL_DIG #define DBL_DIG 10 diff --git a/src/kernel/qwmatrix.cpp b/src/kernel/qwmatrix.cpp deleted file mode 100644 index 78dc80c0d..000000000 --- a/src/kernel/qwmatrix.cpp +++ /dev/null @@ -1,1036 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQWMatrix class -** -** Created : 941020 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** 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 "ntqwmatrix.h" -#include "tqdatastream.h" -#include "ntqregion.h" -#if defined(TQ_WS_X11) -double qsincos( double, bool calcCos ); // defined in tqpainter_x11.cpp -#else -#include -#endif - -#include - -#ifndef TQT_NO_WMATRIX - -/*! - \class TQWMatrix ntqwmatrix.h - \brief The TQWMatrix class specifies 2D transformations of a - coordinate system. - - \ingroup graphics - \ingroup images - - The standard coordinate system of a \link TQPaintDevice paint - device\endlink has the origin located at the top-left position. X - values increase to the right; Y values increase downward. - - This coordinate system is the default for the TQPainter, which - renders graphics in a paint device. A user-defined coordinate - system can be specified by setting a TQWMatrix for the painter. - - Example: - \code - MyWidget::paintEvent( TQPaintEvent * ) - { - TQPainter p; // our painter - TQWMatrix m; // our transformation matrix - m.rotate( 22.5 ); // rotated coordinate system - p.begin( this ); // start painting - p.setWorldMatrix( m ); // use rotated coordinate system - p.drawText( 30,20, "detator" ); // draw rotated text at 30,20 - p.end(); // painting done - } - \endcode - - A matrix specifies how to translate, scale, shear or rotate the - graphics; the actual transformation is performed by the drawing - routines in TQPainter and by TQPixmap::xForm(). - - The TQWMatrix class contains a 3x3 matrix of the form: - - - - -
m11m12 0
m21m22 0
dx dy  1
- - A matrix transforms a point in the plane to another point: - \code - x' = m11*x + m21*y + dx - y' = m22*y + m12*x + dy - \endcode - - The point \e (x, y) is the original point, and \e (x', y') is the - transformed point. \e (x', y') can be transformed back to \e (x, - y) by performing the same operation on the \link - TQWMatrix::invert() inverted matrix\endlink. - - The elements \e dx and \e dy specify horizontal and vertical - translation. The elements \e m11 and \e m22 specify horizontal and - vertical scaling. The elements \e m12 and \e m21 specify - horizontal and vertical shearing. - - The identity matrix has \e m11 and \e m22 set to 1; all others are - set to 0. This matrix maps a point to itself. - - Translation is the simplest transformation. Setting \e dx and \e - dy will move the coordinate system \e dx units along the X axis - and \e dy units along the Y axis. - - Scaling can be done by setting \e m11 and \e m22. For example, - setting \e m11 to 2 and \e m22 to 1.5 will double the height and - increase the width by 50%. - - Shearing is controlled by \e m12 and \e m21. Setting these - elements to values different from zero will twist the coordinate - system. - - Rotation is achieved by carefully setting both the shearing - factors and the scaling factors. The TQWMatrix also has a function - that sets \link rotate() rotation \endlink directly. - - TQWMatrix lets you combine transformations like this: - \code - TQWMatrix m; // identity matrix - m.translate(10, -20); // first translate (10,-20) - m.rotate(25); // then rotate 25 degrees - m.scale(1.2, 0.7); // finally scale it - \endcode - - Here's the same example using basic matrix operations: - \code - double a = pi/180 * 25; // convert 25 to radians - double sina = sin(a); - double cosa = cos(a); - TQWMatrix m1(1, 0, 0, 1, 10, -20); // translation matrix - TQWMatrix m2( cosa, sina, // rotation matrix - -sina, cosa, 0, 0 ); - TQWMatrix m3(1.2, 0, 0, 0.7, 0, 0); // scaling matrix - TQWMatrix m; - m = m3 * m2 * m1; // combine all transformations - \endcode - - \l TQPainter has functions to translate, scale, shear and rotate the - coordinate system without using a TQWMatrix. Although these - functions are very convenient, it can be more efficient to build a - TQWMatrix and call TQPainter::setWorldMatrix() if you want to perform - more than a single transform operation. - - \sa TQPainter::setWorldMatrix(), TQPixmap::xForm() -*/ - -bool qt_old_transformations = TRUE; - -/*! - \enum TQWMatrix::TransformationMode - - \keyword transformation matrix - - TQWMatrix offers two transformation modes. Calculations can either - be done in terms of points (Points mode, the default), or in - terms of area (Area mode). - - In Points mode the transformation is applied to the points that - mark out the shape's bounding line. In Areas mode the - transformation is applied in such a way that the area of the - contained region is correctly transformed under the matrix. - - \value Points transformations are applied to the shape's points. - \value Areas transformations are applied (e.g. to the width and - height) so that the area is transformed. - - Example: - - Suppose we have a rectangle, - \c{TQRect( 10, 20, 30, 40 )} and a transformation matrix - \c{TQWMatrix( 2, 0, 0, 2, 0, 0 )} to double the rectangle's size. - - In Points mode, the matrix will transform the top-left (10,20) and - the bottom-right (39,59) points producing a rectangle with its - top-left point at (20,40) and its bottom-right point at (78,118), - i.e. with a width of 59 and a height of 79. - - In Areas mode, the matrix will transform the top-left point in - the same way as in Points mode to (20/40), and double the width - and height, so the bottom-right will become (69,99), i.e. a width - of 60 and a height of 80. - - Because integer arithmetic is used (for speed), rounding - differences mean that the modes will produce slightly different - results given the same shape and the same transformation, - especially when scaling up. This also means that some operations - are not commutative. - - Under Points mode, \c{matrix * ( region1 | region2 )} is not equal to - \c{matrix * region1 | matrix * region2}. Under Area mode, \c{matrix * - (pointarray[i])} is not neccesarily equal to - \c{(matrix * pointarry)[i]}. - - \img xform.png Comparison of Points and Areas TransformationModes -*/ - -/*! - Sets the transformation mode that TQWMatrix and painter - transformations use to \a m. - - \sa TQWMatrix::TransformationMode -*/ -void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m ) -{ - if ( m == TQWMatrix::Points ) - qt_old_transformations = TRUE; - else - qt_old_transformations = FALSE; -} - - -/*! - Returns the current transformation mode. - - \sa TQWMatrix::TransformationMode -*/ -TQWMatrix::TransformationMode TQWMatrix::transformationMode() -{ - return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas ); -} - - -// some defines to inline some code -#define MAPDOUBLE( x, y, nx, ny ) \ -{ \ - double fx = x; \ - double fy = y; \ - nx = _m11*fx + _m21*fy + _dx; \ - ny = _m12*fx + _m22*fy + _dy; \ -} - -#define MAPINT( x, y, nx, ny ) \ -{ \ - double fx = x; \ - double fy = y; \ - nx = tqRound(_m11*fx + _m21*fy + _dx); \ - ny = tqRound(_m12*fx + _m22*fy + _dy); \ -} - -/***************************************************************************** - TQWMatrix member functions - *****************************************************************************/ - -/*! - Constructs an identity matrix. All elements are set to zero except - \e m11 and \e m22 (scaling), which are set to 1. -*/ - -TQWMatrix::TQWMatrix() -{ - _m11 = _m22 = 1.0; - _m12 = _m21 = _dx = _dy = 0.0; -} - -/*! - Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a - m22, \a dx and \a dy. -*/ - -TQWMatrix::TQWMatrix( double m11, double m12, double m21, double m22, - double dx, double dy ) -{ - _m11 = m11; _m12 = m12; - _m21 = m21; _m22 = m22; - _dx = dx; _dy = dy; -} - - -/*! - Sets the matrix elements to the specified values, \a m11, \a m12, - \a m21, \a m22, \a dx and \a dy. -*/ - -void TQWMatrix::setMatrix( double m11, double m12, double m21, double m22, - double dx, double dy ) -{ - _m11 = m11; _m12 = m12; - _m21 = m21; _m22 = m22; - _dx = dx; _dy = dy; -} - - -/*! - \fn double TQWMatrix::m11() const - - Returns the X scaling factor. -*/ - -/*! - \fn double TQWMatrix::m12() const - - Returns the vertical shearing factor. -*/ - -/*! - \fn double TQWMatrix::m21() const - - Returns the horizontal shearing factor. -*/ - -/*! - \fn double TQWMatrix::m22() const - - Returns the Y scaling factor. -*/ - -/*! - \fn double TQWMatrix::dx() const - - Returns the horizontal translation. -*/ - -/*! - \fn double TQWMatrix::dy() const - - Returns the vertical translation. -*/ - - -/*! - \overload - - Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the - following formulae: - - \code - *tx = m11*x + m21*y + dx - *ty = m22*y + m12*x + dy - \endcode -*/ - -void TQWMatrix::map( double x, double y, double *tx, double *ty ) const -{ - MAPDOUBLE( x, y, *tx, *ty ); -} - -/*! - Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the formulae: - - \code - *tx = m11*x + m21*y + dx (rounded to the nearest integer) - *ty = m22*y + m12*x + dy (rounded to the nearest integer) - \endcode -*/ - -void TQWMatrix::map( int x, int y, int *tx, int *ty ) const -{ - MAPINT( x, y, *tx, *ty ); -} - -/*! - \fn TQPoint TQWMatrix::map( const TQPoint &p ) const - - \overload - - Transforms \a p to using the formulae: - - \code - retx = m11*px + m21*py + dx (rounded to the nearest integer) - rety = m22*py + m12*px + dy (rounded to the nearest integer) - \endcode -*/ - -/*! - \fn TQRect TQWMatrix::map( const TQRect &r ) const - - \obsolete - - Please use \l TQWMatrix::mapRect() instead. - - Note that this method does return the bounding rectangle of the \a r, when - shearing or rotations are used. -*/ - -/*! - \fn TQPointArray TQWMatrix::map( const TQPointArray &a ) const - - \overload - - Returns the point array \a a transformed by calling map for each point. -*/ - - -/*! - \fn TQRegion TQWMatrix::map( const TQRegion &r ) const - - \overload - - Transforms the region \a r. - - Calling this method can be rather expensive, if rotations or - shearing are used. -*/ - -/*! - \fn TQRegion TQWMatrix::mapToRegion( const TQRect &rect ) const - - Returns the transformed rectangle \a rect. - - A rectangle which has been rotated or sheared may result in a - non-rectangular region being returned. - - Calling this method can be expensive, if rotations or shearing are - used. If you just need to know the bounding rectangle of the - returned region, use mapRect() which is a lot faster than this - function. - - \sa TQWMatrix::mapRect() -*/ - - -/*! - Returns the transformed rectangle \a rect. - - The bounding rectangle is returned if rotation or shearing has - been specified. - - If you need to know the exact region \a rect maps to use \l - operator*(). - - \sa operator*() -*/ - -TQRect TQWMatrix::mapRect( const TQRect &rect ) const -{ - TQRect result; - if( qt_old_transformations ) { - if ( _m12 == 0.0F && _m21 == 0.0F ) { - result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize(); - } else { - TQPointArray a( rect ); - a = map( a ); - result = a.boundingRect(); - } - } else { - if ( _m12 == 0.0F && _m21 == 0.0F ) { - int x = tqRound( _m11*rect.x() + _dx ); - int y = tqRound( _m22*rect.y() + _dy ); - int w = tqRound( _m11*rect.width() ); - int h = tqRound( _m22*rect.height() ); - if ( w < 0 ) { - w = -w; - x -= w-1; - } - if ( h < 0 ) { - h = -h; - y -= h-1; - } - result = TQRect( x, y, w, h ); - } else { - - // see mapToPolygon for explanations of the algorithm. - double x0, y0; - double x, y; - MAPDOUBLE( rect.left(), rect.top(), x0, y0 ); - double xmin = x0; - double ymin = y0; - double xmax = x0; - double ymax = y0; - MAPDOUBLE( rect.right() + 1, rect.top(), x, y ); - xmin = TQMIN( xmin, x ); - ymin = TQMIN( ymin, y ); - xmax = TQMAX( xmax, x ); - ymax = TQMAX( ymax, y ); - MAPDOUBLE( rect.right() + 1, rect.bottom() + 1, x, y ); - xmin = TQMIN( xmin, x ); - ymin = TQMIN( ymin, y ); - xmax = TQMAX( xmax, x ); - ymax = TQMAX( ymax, y ); - MAPDOUBLE( rect.left(), rect.bottom() + 1, x, y ); - xmin = TQMIN( xmin, x ); - ymin = TQMIN( ymin, y ); - xmax = TQMAX( xmax, x ); - ymax = TQMAX( ymax, y ); - double w = xmax - xmin; - double h = ymax - ymin; - xmin -= ( xmin - x0 ) / w; - ymin -= ( ymin - y0 ) / h; - xmax -= ( xmax - x0 ) / w; - ymax -= ( ymax - y0 ) / h; - result = TQRect( tqRound(xmin), tqRound(ymin), tqRound(xmax)-tqRound(xmin)+1, tqRound(ymax)-tqRound(ymin)+1 ); - } - } - return result; -} - - -/*! - \internal -*/ -TQPoint TQWMatrix::operator *( const TQPoint &p ) const -{ - double fx = p.x(); - double fy = p.y(); - return TQPoint( tqRound(_m11*fx + _m21*fy + _dx), - tqRound(_m12*fx + _m22*fy + _dy) ); -} - - -struct TQWMDoublePoint { - double x; - double y; -}; - -/*! - \internal -*/ -TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const -{ - if( qt_old_transformations ) { - TQPointArray result = a.copy(); - int x, y; - for ( int i=0; i<(int)result.size(); i++ ) { - result.point( i, &x, &y ); - MAPINT( x, y, x, y ); - result.setPoint( i, x, y ); - } - return result; - } else { - int size = a.size(); - int i; - TQMemArray p( size ); - TQPoint *da = a.data(); - TQWMDoublePoint *dp = p.data(); - double xmin = INT_MAX; - double ymin = xmin; - double xmax = INT_MIN; - double ymax = xmax; - int xminp = 0; - int yminp = 0; - for( i = 0; i < size; i++ ) { - dp[i].x = da[i].x(); - dp[i].y = da[i].y(); - if ( dp[i].x < xmin ) { - xmin = dp[i].x; - xminp = i; - } - if ( dp[i].y < ymin ) { - ymin = dp[i].y; - yminp = i; - } - xmax = TQMAX( xmax, dp[i].x ); - ymax = TQMAX( ymax, dp[i].y ); - } - double w = TQMAX( xmax - xmin, 1 ); - double h = TQMAX( ymax - ymin, 1 ); - for( i = 0; i < size; i++ ) { - dp[i].x += (dp[i].x - xmin)/w; - dp[i].y += (dp[i].y - ymin)/h; - MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y ); - } - - // now apply correction back for transformed values... - xmin = INT_MAX; - ymin = xmin; - xmax = INT_MIN; - ymax = xmax; - for( i = 0; i < size; i++ ) { - xmin = TQMIN( xmin, dp[i].x ); - ymin = TQMIN( ymin, dp[i].y ); - xmax = TQMAX( xmax, dp[i].x ); - ymax = TQMAX( ymax, dp[i].y ); - } - w = TQMAX( xmax - xmin, 1 ); - h = TQMAX( ymax - ymin, 1 ); - - TQPointArray result( size ); - TQPoint *dr = result.data(); - for( i = 0; i < size; i++ ) { - dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) ); - dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) ); - } - return result; - } -} - -/*! -\internal -*/ -TQRegion TQWMatrix::operator * (const TQRect &rect ) const -{ - TQRegion result; - if ( isIdentity() ) { - result = rect; - } else if ( _m12 == 0.0F && _m21 == 0.0F ) { - if( qt_old_transformations ) { - result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize(); - } else { - int x = tqRound( _m11*rect.x() + _dx ); - int y = tqRound( _m22*rect.y() + _dy ); - int w = tqRound( _m11*rect.width() ); - int h = tqRound( _m22*rect.height() ); - if ( w < 0 ) { - w = -w; - x -= w - 1; - } - if ( h < 0 ) { - h = -h; - y -= h - 1; - } - result = TQRect( x, y, w, h ); - } - } else { - result = TQRegion( mapToPolygon( rect ) ); - } - return result; - -} - -/*! - Returns the transformed rectangle \a rect as a polygon. - - Polygons and rectangles behave slightly differently - when transformed (due to integer rounding), so - \c{matrix.map( TQPointArray( rect ) )} is not always the same as - \c{matrix.mapToPolygon( rect )}. -*/ -TQPointArray TQWMatrix::mapToPolygon( const TQRect &rect ) const -{ - TQPointArray a( 4 ); - if ( qt_old_transformations ) { - a = TQPointArray( rect ); - return operator *( a ); - } - double x[4], y[4]; - if ( _m12 == 0.0F && _m21 == 0.0F ) { - x[0] = tqRound( _m11*rect.x() + _dx ); - y[0] = tqRound( _m22*rect.y() + _dy ); - double w = tqRound( _m11*rect.width() ); - double h = tqRound( _m22*rect.height() ); - if ( w < 0 ) { - w = -w; - x[0] -= w - 1.; - } - if ( h < 0 ) { - h = -h; - y[0] -= h - 1.; - } - x[1] = x[0]+w-1; - x[2] = x[1]; - x[3] = x[0]; - y[1] = y[0]; - y[2] = y[0]+h-1; - y[3] = y[2]; - } else { - MAPINT( rect.left(), rect.top(), x[0], y[0] ); - MAPINT( rect.right() + 1, rect.top(), x[1], y[1] ); - MAPINT( rect.right() + 1, rect.bottom() + 1, x[2], y[2] ); - MAPINT( rect.left(), rect.bottom() + 1, x[3], y[3] ); - - /* - Including rectangles as we have are evil. - - We now have a rectangle that is one pixel to wide and one to - high. the tranformed position of the top-left corner is - correct. All other points need some adjustments. - - Doing this mathematically exact would force us to calculate some square roots, - something we don't want for the sake of speed. - - Instead we use an approximation, that converts to the correct - answer when m12 -> 0 and m21 -> 0, and accept smaller - errors in the general transformation case. - - The solution is to calculate the width and height of the - bounding rect, and scale the points 1/2/3 by (xp-x0)/xw pixel direction - to point 0. - */ - - double xmin = x[0]; - double ymin = y[0]; - double xmax = x[0]; - double ymax = y[0]; - int i; - for( i = 1; i< 4; i++ ) { - xmin = TQMIN( xmin, x[i] ); - ymin = TQMIN( ymin, y[i] ); - xmax = TQMAX( xmax, x[i] ); - ymax = TQMAX( ymax, y[i] ); - } - double w = xmax - xmin; - double h = ymax - ymin; - - for( i = 1; i < 4; i++ ) { - x[i] -= (x[i] - x[0])/w; - y[i] -= (y[i] - y[0])/h; - } - } -#if 0 - int i; - for( i = 0; i< 4; i++ ) - tqDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], tqRound(x[i]), tqRound(y[i]) ); - tqDebug( "width=%f, height=%f", sqrt( (x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0]) ), - sqrt( (x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3]) ) ); -#endif - // all coordinates are correctly, tranform to a pointarray - // (rounding to the next integer) - a.setPoints( 4, tqRound( x[0] ), tqRound( y[0] ), - tqRound( x[1] ), tqRound( y[1] ), - tqRound( x[2] ), tqRound( y[2] ), - tqRound( x[3] ), tqRound( y[3] ) ); - return a; -} - -/*! -\internal -*/ -TQRegion TQWMatrix::operator * (const TQRegion &r ) const -{ - if ( isIdentity() ) - return r; - TQMemArray rects = r.rects(); - TQRegion result; - TQRect *rect = rects.data(); - int i = rects.size(); - if ( _m12 == 0.0F && _m21 == 0.0F && _m11 > 1.0F && _m22 > 1.0F ) { - // simple case, no rotation - while ( i ) { - int x = tqRound( _m11*rect->x() + _dx ); - int y = tqRound( _m22*rect->y() + _dy ); - int w = tqRound( _m11*rect->width() ); - int h = tqRound( _m22*rect->height() ); - if ( w < 0 ) { - w = -w; - x -= w-1; - } - if ( h < 0 ) { - h = -h; - y -= h-1; - } - *rect = TQRect( x, y, w, h ); - rect++; - i--; - } - result.setRects( rects.data(), rects.size() ); - } else { - while ( i ) { - result |= operator *( *rect ); - rect++; - i--; - } - } - return result; -} - -/*! - Resets the matrix to an identity matrix. - - All elements are set to zero, except \e m11 and \e m22 (scaling) - which are set to 1. - - \sa isIdentity() -*/ - -void TQWMatrix::reset() -{ - _m11 = _m22 = 1.0; - _m12 = _m21 = _dx = _dy = 0.0; -} - -/*! - Returns TRUE if the matrix is the identity matrix; otherwise returns FALSE. - - \sa reset() -*/ -bool TQWMatrix::isIdentity() const -{ - return _m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0 - && _dx == 0.0 && _dy == 0.0; -} - -/*! - Moves the coordinate system \a dx along the X-axis and \a dy along - the Y-axis. - - Returns a reference to the matrix. - - \sa scale(), shear(), rotate() -*/ - -TQWMatrix &TQWMatrix::translate( double dx, double dy ) -{ - _dx += dx*_m11 + dy*_m21; - _dy += dy*_m22 + dx*_m12; - return *this; -} - -/*! - Scales the coordinate system unit by \a sx horizontally and \a sy - vertically. - - Returns a reference to the matrix. - - \sa translate(), shear(), rotate() -*/ - -TQWMatrix &TQWMatrix::scale( double sx, double sy ) -{ - _m11 *= sx; - _m12 *= sx; - _m21 *= sy; - _m22 *= sy; - return *this; -} - -/*! - Shears the coordinate system by \a sh horizontally and \a sv - vertically. - - Returns a reference to the matrix. - - \sa translate(), scale(), rotate() -*/ - -TQWMatrix &TQWMatrix::shear( double sh, double sv ) -{ - double tm11 = sv*_m21; - double tm12 = sv*_m22; - double tm21 = sh*_m11; - double tm22 = sh*_m12; - _m11 += tm11; - _m12 += tm12; - _m21 += tm21; - _m22 += tm22; - return *this; -} - -const double deg2rad = 0.017453292519943295769; // pi/180 - -/*! - Rotates the coordinate system \a a degrees counterclockwise. - - Returns a reference to the matrix. - - \sa translate(), scale(), shear() -*/ - -TQWMatrix &TQWMatrix::rotate( double a ) -{ - double b = deg2rad*a; // convert to radians -#if defined(TQ_WS_X11) - double sina = qsincos(b,FALSE); // fast and convenient - double cosa = qsincos(b,TRUE); -#else - double sina = sin(b); - double cosa = cos(b); -#endif - double tm11 = cosa*_m11 + sina*_m21; - double tm12 = cosa*_m12 + sina*_m22; - double tm21 = -sina*_m11 + cosa*_m21; - double tm22 = -sina*_m12 + cosa*_m22; - _m11 = tm11; _m12 = tm12; - _m21 = tm21; _m22 = tm22; - return *this; -} - -/*! - \fn bool TQWMatrix::isInvertible() const - - Returns TRUE if the matrix is invertible; otherwise returns FALSE. - - \sa invert() -*/ - -/*! - \fn double TQWMatrix::det() const - - Returns the matrix's determinant. -*/ - - -/*! - Returns the inverted matrix. - - If the matrix is singular (not invertible), the identity matrix is - returned. - - If \a invertible is not 0: the value of \a *invertible is set - to TRUE if the matrix is invertible; otherwise \a *invertible is - set to FALSE. - - \sa isInvertible() -*/ - -TQWMatrix TQWMatrix::invert( bool *invertible ) const -{ - double determinant = det(); - if ( determinant == 0.0 ) { - if ( invertible ) - *invertible = FALSE; // singular matrix - TQWMatrix defaultMatrix; - return defaultMatrix; - } - else { // invertible matrix - if ( invertible ) - *invertible = TRUE; - double dinv = 1.0/determinant; - TQWMatrix imatrix( (_m22*dinv), (-_m12*dinv), - (-_m21*dinv), ( _m11*dinv), - ((_m21*_dy - _m22*_dx)*dinv), - ((_m12*_dx - _m11*_dy)*dinv) ); - return imatrix; - } -} - - -/*! - Returns TRUE if this matrix is equal to \a m; otherwise returns FALSE. -*/ - -bool TQWMatrix::operator==( const TQWMatrix &m ) const -{ - return _m11 == m._m11 && - _m12 == m._m12 && - _m21 == m._m21 && - _m22 == m._m22 && - _dx == m._dx && - _dy == m._dy; -} - -/*! - Returns TRUE if this matrix is not equal to \a m; otherwise returns FALSE. -*/ - -bool TQWMatrix::operator!=( const TQWMatrix &m ) const -{ - return _m11 != m._m11 || - _m12 != m._m12 || - _m21 != m._m21 || - _m22 != m._m22 || - _dx != m._dx || - _dy != m._dy; -} - -/*! - Returns the result of multiplying this matrix by matrix \a m. -*/ - -TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m ) -{ - double tm11 = _m11*m._m11 + _m12*m._m21; - double tm12 = _m11*m._m12 + _m12*m._m22; - double tm21 = _m21*m._m11 + _m22*m._m21; - double tm22 = _m21*m._m12 + _m22*m._m22; - - double tdx = _dx*m._m11 + _dy*m._m21 + m._dx; - double tdy = _dx*m._m12 + _dy*m._m22 + m._dy; - - _m11 = tm11; _m12 = tm12; - _m21 = tm21; _m22 = tm22; - _dx = tdx; _dy = tdy; - return *this; -} - -/*! - \overload - \relates TQWMatrix - Returns the product of \a m1 * \a m2. - - Note that matrix multiplication is not commutative, i.e. a*b != - b*a. -*/ - -TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 ) -{ - TQWMatrix result = m1; - result *= m2; - return result; -} - -/***************************************************************************** - TQWMatrix stream functions - *****************************************************************************/ -#ifndef TQT_NO_DATASTREAM -/*! - \relates TQWMatrix - - Writes the matrix \a m to the stream \a s and returns a reference - to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator<<( TQDataStream &s, const TQWMatrix &m ) -{ - if ( s.version() == 1 ) - s << (float)m.m11() << (float)m.m12() << (float)m.m21() - << (float)m.m22() << (float)m.dx() << (float)m.dy(); - else - s << m.m11() << m.m12() << m.m21() << m.m22() - << m.dx() << m.dy(); - return s; -} - -/*! - \relates TQWMatrix - - Reads the matrix \a m from the stream \a s and returns a reference - to the stream. - - \sa \link datastreamformat.html Format of the TQDataStream operators \endlink -*/ - -TQDataStream &operator>>( TQDataStream &s, TQWMatrix &m ) -{ - if ( s.version() == 1 ) { - float m11, m12, m21, m22, dx, dy; - s >> m11; s >> m12; s >> m21; s >> m22; - s >> dx; s >> dy; - m.setMatrix( m11, m12, m21, m22, dx, dy ); - } - else { - double m11, m12, m21, m22, dx, dy; - s >> m11; s >> m12; s >> m21; s >> m22; - s >> dx; s >> dy; - m.setMatrix( m11, m12, m21, m22, dx, dy ); - } - return s; -} -#endif // TQT_NO_DATASTREAM - -#endif // TQT_NO_WMATRIX - diff --git a/src/kernel/tqbitmap.h b/src/kernel/tqbitmap.h index 22307b551..c74f37241 100644 --- a/src/kernel/tqbitmap.h +++ b/src/kernel/tqbitmap.h @@ -42,7 +42,7 @@ #define TQBITMAP_H #ifndef QT_H -#include "ntqpixmap.h" +#include "tqpixmap.h" #endif // QT_H diff --git a/src/kernel/tqclipboard.cpp b/src/kernel/tqclipboard.cpp index 37393b7c4..f7c2836f5 100644 --- a/src/kernel/tqclipboard.cpp +++ b/src/kernel/tqclipboard.cpp @@ -45,7 +45,7 @@ #include "ntqapplication.h" #include "qapplication_p.h" #include "tqdragobject.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" /*! \class TQClipboard tqclipboard.h diff --git a/src/kernel/tqdragobject.cpp b/src/kernel/tqdragobject.cpp index 3c8921a59..f8557de55 100644 --- a/src/kernel/tqdragobject.cpp +++ b/src/kernel/tqdragobject.cpp @@ -48,7 +48,7 @@ #include "tqdragobject.h" #include "tqtextcodec.h" #include "ntqapplication.h" -#include "ntqpoint.h" +#include "tqpoint.h" #include "tqwidget.h" #include "tqbuffer.h" #include "ntqgif.h" diff --git a/src/kernel/tqfontmetrics.h b/src/kernel/tqfontmetrics.h index 814a411e6..b635a864e 100644 --- a/src/kernel/tqfontmetrics.h +++ b/src/kernel/tqfontmetrics.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "tqfont.h" -#include "ntqrect.h" +#include "tqrect.h" #endif // QT_H class TQTextCodec; diff --git a/src/kernel/tqiconset.h b/src/kernel/tqiconset.h index 66fc71146..7caa24b74 100644 --- a/src/kernel/tqiconset.h +++ b/src/kernel/tqiconset.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "tqobject.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #endif // QT_H #ifndef TQT_NO_ICONSET diff --git a/src/kernel/tqimage.cpp b/src/kernel/tqimage.cpp index 58b8a1221..733bb10d7 100644 --- a/src/kernel/tqimage.cpp +++ b/src/kernel/tqimage.cpp @@ -46,13 +46,13 @@ #include "tqbuffer.h" #include "tqptrlist.h" #include "ntqasyncimageio.h" -#include "ntqpngio.h" +#include "tqpngio.h" #include "ntqmngio.h" #include "ntqjpegio.h" #include "tqmap.h" #include #include "tqimageformatinterface_p.h" -#include "ntqwmatrix.h" +#include "tqwmatrix.h" #include "ntqapplication.h" #include "tqmime.h" #include "tqdragobject.h" diff --git a/src/kernel/tqimage.h b/src/kernel/tqimage.h index b65b1de43..605b3551c 100644 --- a/src/kernel/tqimage.h +++ b/src/kernel/tqimage.h @@ -42,7 +42,7 @@ #define TQIMAGE_H #ifndef QT_H -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqstrlist.h" #include "tqstringlist.h" #endif // QT_H diff --git a/src/kernel/tqmovie.cpp b/src/kernel/tqmovie.cpp index d12ff2f6c..54743cbd6 100644 --- a/src/kernel/tqmovie.cpp +++ b/src/kernel/tqmovie.cpp @@ -48,7 +48,7 @@ #include "tqfile.h" #include "tqbuffer.h" #include "tqobject.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #ifndef TQT_NO_MOVIE diff --git a/src/kernel/tqmovie.h b/src/kernel/tqmovie.h index 8e92ec6d4..c340590e8 100644 --- a/src/kernel/tqmovie.h +++ b/src/kernel/tqmovie.h @@ -42,7 +42,7 @@ #define TQMOVIE_H #ifndef QT_H -#include "ntqpixmap.h" // ### remove or keep for users' convenience? +#include "tqpixmap.h" // ### remove or keep for users' convenience? #endif // QT_H #ifndef TQT_NO_MOVIE diff --git a/src/kernel/tqpaintdevice.h b/src/kernel/tqpaintdevice.h index 2b9cd421f..9e6cc6697 100644 --- a/src/kernel/tqpaintdevice.h +++ b/src/kernel/tqpaintdevice.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "ntqwindowdefs.h" -#include "ntqrect.h" +#include "tqrect.h" #endif // QT_H class TQIODevice; diff --git a/src/kernel/tqpainter.cpp b/src/kernel/tqpainter.cpp index 325d11eea..5303d5549 100644 --- a/src/kernel/tqpainter.cpp +++ b/src/kernel/tqpainter.cpp @@ -3083,7 +3083,7 @@ TQRect TQPainter::boundingRect( const TQRect &r, int flags, *****************************************************************************/ /*! - \class TQPen ntqpen.h + \class TQPen tqpen.h \brief The TQPen class defines how a TQPainter should draw lines and outlines of shapes. diff --git a/src/kernel/tqpainter.h b/src/kernel/tqpainter.h index bd2799577..29a10406d 100644 --- a/src/kernel/tqpainter.h +++ b/src/kernel/tqpainter.h @@ -46,11 +46,11 @@ #include "tqcolor.h" #include "tqfontmetrics.h" #include "tqfontinfo.h" -#include "ntqregion.h" -#include "ntqpen.h" +#include "tqregion.h" +#include "tqpen.h" #include "tqbrush.h" -#include "ntqpointarray.h" -#include "ntqwmatrix.h" +#include "tqpointarray.h" +#include "tqwmatrix.h" #endif // QT_H class TQTextCodec; diff --git a/src/kernel/tqpainter_x11.cpp b/src/kernel/tqpainter_x11.cpp index e61b2fab2..22d892d17 100644 --- a/src/kernel/tqpainter_x11.cpp +++ b/src/kernel/tqpainter_x11.cpp @@ -44,7 +44,7 @@ #include "tqpainter.h" #include "tqwidget.h" #include "tqbitmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "tqtextcodec.h" #include "tqpaintdevicemetrics.h" @@ -137,7 +137,7 @@ static const TQt::HANDLE rendhd = 0; #endif // hack, so we don't have to make TQRegion::clipRectangles() public or include -// X11 headers in ntqregion.h +// X11 headers in tqregion.h inline void *qt_getClipRects( const TQRegion &r, int &num ) { return r.clipRectangles( num ); @@ -2925,7 +2925,7 @@ void TQPainter::drawTiledPixmap( int x, int y, int w, int h, } #else // for now we'll just output the original and let the postscript - // code make what it can of it. qpicture will be unhappy. + // code make what it can of it. tqpicture will be unhappy. drawTile( this, x, y, w, h, pixmap, sx, sy ); #endif } diff --git a/src/kernel/tqpalette.cpp b/src/kernel/tqpalette.cpp new file mode 100644 index 000000000..6ae0459d1 --- /dev/null +++ b/src/kernel/tqpalette.cpp @@ -0,0 +1,1200 @@ +/**************************************************************************** +** +** Implementation of TQColorGroup and TQPalette classes +** +** Created : 950323 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqpalette.h" + +#ifndef TQT_NO_PALETTE +#include "tqdatastream.h" +#include "ntqcleanuphandler.h" + +/***************************************************************************** + TQColorGroup member functions + *****************************************************************************/ + +/*! + \class TQColorGroup tqpalette.h + \brief The TQColorGroup class contains a group of widget colors. + + \ingroup appearance + \ingroup graphics + \ingroup images + + A color group contains a group of colors used by widgets for + drawing themselves. We recommend that widgets use color group + roles such as "foreground" and "base" rather than literal colors + like "red" or "turquoise". The color roles are enumerated and + defined in the \l ColorRole documentation. + + The most common use of TQColorGroup is like this: + + \code + TQPainter p; + ... + p.setPen( colorGroup().foreground() ); + p.drawLine( ... ) + \endcode + + It is also possible to modify color groups or create new color + groups from scratch. + + The color group class can be created using three different + constructors or by modifying one supplied by TQt. The default + constructor creates an all-black color group, which can then be + modified using set functions; there's also a constructor for + specifying all the color group colors. And there is also a copy + constructor. + + We strongly recommend using a system-supplied color group and + modifying that as necessary. + + You modify a color group by calling the access functions + setColor() and setBrush(), depending on whether you want a pure + color or a pixmap pattern. + + There are also corresponding color() and brush() getters, and a + commonly used convenience function to get each ColorRole: + background(), foreground(), base(), etc. + + \sa TQColor TQPalette TQWidget::colorGroup() +*/ + + +/*! + \enum TQColorGroup::ColorRole + + The ColorRole enum defines the different symbolic color roles used + in current GUIs. + + The central roles are: + + \value Background general background color. + + \value Foreground general foreground color. + + \value Base used as background color for text entry widgets, for example; + usually white or another light color. + + \value Text the foreground color used with \c Base. Usually this + is the same as the \c Foreground, in which case it must provide good + contrast with \c Background and \c Base. + + \value Button general button background color in which buttons need a + background different from \c Background, as in the Macintosh style. + + \value ButtonText a foreground color used with the \c Button color. + + There are some color roles used mostly for 3D bevel and shadow + effects: + + \value Light lighter than \c Button color. + + \value Midlight between \c Button and \c Light. + + \value Dark darker than \c Button. + + \value Mid between \c Button and \c Dark. + + \value Shadow a very dark color. + By default, the shadow color is \c TQt::black. + + All of these are normally derived from \c Background and used in + ways that depend on that relationship. For example, buttons depend + on it to make the bevels look attractive, and Motif scroll bars + depend on \c Mid to be slightly different from \c Background. + + Selected (marked) items have two roles: + + \value Highlight a color to indicate a selected item or the + current item. By default, the highlight color is \c TQt::darkBlue. + + \value HighlightedText a text color that contrasts with \c Highlight. + By default, the highlighted text color is \c TQt::white. + + Finally, there is a special role for text that needs to be + drawn where \c Text or \c Foreground would give poor contrast, + such as on pressed push buttons: + + \value BrightText a text color that is very different from \c + Foreground and contrasts well with e.g. \c Dark. + + \value Link a text color used for unvisited hyperlinks. + By default, the link color is \c TQt::blue. + + \value LinkVisited a text color used for already visited hyperlinks. + By default, the linkvisited color is \c TQt::magenta. + + \value NColorRoles Internal. + + Note that text colors can be used for things other than just + words; text colors are \e usually used for text, but it's quite + common to use the text color roles for lines, icons, etc. + + This image shows most of the color roles in use: + \img palette.png Color Roles +*/ + + +class TQColorGroupPrivate : public TQShared +{ +public: + TQBrush br[TQColorGroup::NColorRoles]; + TQColorGroupPrivate* detach() { + if ( count > 1 ) { + deref(); + TQColorGroupPrivate* d = new TQColorGroupPrivate; + for (int i=0; ibr[i] = br[i]; + return d; + } + return this; + } +}; + +/*! + Constructs a color group with all colors set to black. +*/ + +TQColorGroup::TQColorGroup() +{ + static TQColorGroupPrivate* defColorGroupData = 0; + if ( !defColorGroupData ) { + static TQSharedCleanupHandler defColorGroupCleanup; + defColorGroupData = new TQColorGroupPrivate; + defColorGroupCleanup.set( &defColorGroupData ); + } + d = defColorGroupData; + br = d->br; + d->ref(); +} + +/*! + Constructs a color group that is an independent copy of \a other. +*/ +TQColorGroup::TQColorGroup( const TQColorGroup& other ) +{ + d = other.d; + d->ref(); + br = d->br; +} + +/*! + Copies the colors of \a other to this color group. +*/ +TQColorGroup& TQColorGroup::operator =(const TQColorGroup& other) +{ + if ( d != other.d ) { + if ( d->deref() ) + delete d; + d = other.d; + br = d->br; + d->ref(); + } + return *this; +} + +static TQColor qt_mix_colors( TQColor a, TQColor b) +{ + return TQColor( (a.red() + b.red()) / 2, (a.green() + b.green()) / 2, (a.blue() + b.blue()) / 2 ); +} + + +/*! + Constructs a color group. You can pass either brushes, pixmaps or + plain colors for \a foreground, \a button, \a light, \a dark, \a + mid, \a text, \a bright_text, \a base and \a background. + + \sa TQBrush +*/ + TQColorGroup::TQColorGroup( const TQBrush &foreground, const TQBrush &button, + const TQBrush &light, const TQBrush &dark, + const TQBrush &mid, const TQBrush &text, + const TQBrush &bright_text, const TQBrush &base, + const TQBrush &background) +{ + d = new TQColorGroupPrivate; + br = d->br; + br[Foreground] = foreground; + br[Button] = button; + br[Light] = light; + br[Dark] = dark; + br[Mid] = mid; + br[Text] = text; + br[BrightText] = bright_text; + br[ButtonText] = text; + br[Base] = base; + br[Background] = background; + br[Midlight] = qt_mix_colors( br[Button].color(), br[Light].color() ); + br[Shadow] = TQt::black; + br[Highlight] = TQt::darkBlue; + br[HighlightedText] = TQt::white; + br[Link] = TQt::blue; + br[LinkVisited] = TQt::magenta; +} + + +/*!\obsolete + + Constructs a color group with the specified colors. The button + color will be set to the background color. +*/ + +TQColorGroup::TQColorGroup( const TQColor &foreground, const TQColor &background, + const TQColor &light, const TQColor &dark, + const TQColor &mid, + const TQColor &text, const TQColor &base ) +{ + d = new TQColorGroupPrivate; + br = d->br; + br[Foreground] = TQBrush(foreground); + br[Button] = TQBrush(background); + br[Light] = TQBrush(light); + br[Dark] = TQBrush(dark); + br[Mid] = TQBrush(mid); + br[Text] = TQBrush(text); + br[BrightText] = br[Light]; + br[ButtonText] = br[Text]; + br[Base] = TQBrush(base); + br[Background] = TQBrush(background); + br[Midlight] = qt_mix_colors( br[Button].color(), br[Light].color() ); + br[Shadow] = TQt::black; + br[Highlight] = TQt::darkBlue; + br[HighlightedText] = TQt::white; + br[Link] = TQt::blue; + br[LinkVisited] = TQt::magenta; +} + +/*! + Destroys the color group. +*/ + +TQColorGroup::~TQColorGroup() +{ + if ( d->deref() ) + delete d; +} + +/*! + Returns the color that has been set for color role \a r. + + \sa brush() ColorRole + */ +const TQColor &TQColorGroup::color( ColorRole r ) const +{ + return br[r].color(); +} + +/*! + Returns the brush that has been set for color role \a r. + + \sa color() setBrush() ColorRole +*/ +const TQBrush &TQColorGroup::brush( ColorRole r ) const +{ + return br[r]; +} + +/*! + Sets the brush used for color role \a r to a solid color \a c. + + \sa brush() setColor() ColorRole +*/ +void TQColorGroup::setColor( ColorRole r, const TQColor &c ) +{ + setBrush( r, TQBrush(c) ); +} + +/*! + Sets the brush used for color role \a r to \a b. + + \sa brush() setColor() ColorRole +*/ +void TQColorGroup::setBrush( ColorRole r, const TQBrush &b ) +{ + d = d->detach(); + br = d->br; + br[r] = b; +} + + +/*! + \fn const TQColor & TQColorGroup::foreground() const + + Returns the foreground color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::button() const + + Returns the button color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::light() const + + Returns the light color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor& TQColorGroup::midlight() const + + Returns the midlight color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::dark() const + + Returns the dark color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::mid() const + + Returns the mid color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::text() const + + Returns the text foreground color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::brightText() const + + Returns the bright text foreground color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::buttonText() const + + Returns the button text foreground color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::base() const + + Returns the base color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::background() const + + Returns the background color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::shadow() const + + Returns the shadow color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::highlight() const + + Returns the highlight color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::highlightedText() const + + Returns the highlighted text color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::link() const + + Returns the unvisited link text color of the color group. + + \sa ColorRole +*/ + +/*! + \fn const TQColor & TQColorGroup::linkVisited() const + + Returns the visited link text color of the color group. + + \sa ColorRole +*/ + +/*! + \fn bool TQColorGroup::operator!=( const TQColorGroup &g ) const + + Returns TRUE if this color group is different from \a g; otherwise + returns FALSE. + + \sa operator!=() +*/ + +/*! + Returns TRUE if this color group is equal to \a g; otherwise + returns FALSE. + + \sa operator==() +*/ + +bool TQColorGroup::operator==( const TQColorGroup &g ) const +{ + if ( d == g.d ) + return TRUE; + for( int r = 0 ; r < NColorRoles ; r++ ) + if ( br[r] != g.br[r] ) + return FALSE; + return TRUE; +} + + +/***************************************************************************** + TQPalette member functions + *****************************************************************************/ + +/*! + \class TQPalette tqpalette.h + + \brief The TQPalette class contains color groups for each widget state. + + \ingroup appearance + \ingroup shared + \ingroup graphics + \ingroup images + \mainclass + + A palette consists of three color groups: \e active, \e disabled, + and \e inactive. All widgets contain a palette, and all widgets in + TQt use their palette to draw themselves. This makes the user + interface easily configurable and easier to keep consistent. + + If you create a new widget we strongly recommend that you use the + colors in the palette rather than hard-coding specific colors. + + The color groups: + \list + \i The active() group is used for the window that has keyboard focus. + \i The inactive() group is used for other windows. + \i The disabled() group is used for widgets (not windows) that are + disabled for some reason. + \endlist + + Both active and inactive windows can contain disabled widgets. + (Disabled widgets are often called \e inaccessible or \e{grayed + out}.) + + In Motif style, active() and inactive() look the same. In Windows + 2000 style and Macintosh Platinum style, the two styles look + slightly different. + + There are setActive(), setInactive(), and setDisabled() functions + to modify the palette. + + Colors and brushes can be set for particular roles in any of a + palette's color groups with setColor() and setBrush(). + + You can copy a palette using the copy constructor and test to see + if two palettes are \e identical using isCopyOf(). + + \sa TQApplication::setPalette(), TQWidget::setPalette(), TQColorGroup, TQColor +*/ + +/*! + \enum TQPalette::ColorGroup + + \value Disabled + \value Active + \value Inactive + \value NColorGroups +*/ + +static int palette_count = 1; + +/*! + Constructs a palette that consists of color groups with only black + colors. +*/ + +TQPalette::TQPalette() +{ + static TQPalData *defPalData = 0; + if ( !defPalData ) { // create common palette data + defPalData = new TQPalData; // for the default palette + static TQSharedCleanupHandler defPalCleanup; + defPalCleanup.set( &defPalData ); + defPalData->ser_no = palette_count++; + } + data = defPalData; + data->ref(); +} + +/*!\obsolete + Constructs a palette from the \a button color. The other colors are + automatically calculated, based on this color. Background will be + the button color as well. +*/ + +TQPalette::TQPalette( const TQColor &button ) +{ + data = new TQPalData; + TQ_CHECK_PTR( data ); + data->ser_no = palette_count++; + TQColor bg = button, btn = button, fg, base, disfg; + int h, s, v; + bg.hsv( &h, &s, &v ); + if ( v > 128 ) { // light background + fg = TQt::black; + base = TQt::white; + disfg = TQt::darkGray; + } else { // dark background + fg = TQt::white; + base = TQt::black; + disfg = TQt::darkGray; + } + data->active = TQColorGroup( fg, btn, btn.light(150), btn.dark(), + btn.dark(150), fg, TQt::white, base, bg ); + data->disabled = TQColorGroup( disfg, btn, btn.light(150), btn.dark(), + btn.dark(150), disfg, TQt::white, base, bg ); + data->inactive = data->active; +} + +/*! + Constructs a palette from a \a button color and a \a background. + The other colors are automatically calculated, based on these + colors. +*/ + +TQPalette::TQPalette( const TQColor &button, const TQColor &background ) +{ + data = new TQPalData; + TQ_CHECK_PTR( data ); + data->ser_no = palette_count++; + TQColor bg = background, btn = button, fg, base, disfg; + int h, s, v; + bg.hsv( &h, &s, &v ); + if ( v > 128 ) { // light background + fg = TQt::black; + base = TQt::white; + disfg = TQt::darkGray; + } else { // dark background + fg = TQt::white; + base = TQt::black; + disfg = TQt::darkGray; + } + data->active = TQColorGroup( fg, btn, btn.light(150), btn.dark(), + btn.dark(150), fg, TQt::white, base, bg ); + data->disabled = TQColorGroup( disfg, btn, btn.light(150), btn.dark(), + btn.dark(150), disfg, TQt::white, base, bg ); + data->inactive = data->active; +} + +/*! + Constructs a palette that consists of the three color groups \a + active, \a disabled and \a inactive. See the \link #details + Detailed Description\endlink for definitions of the color groups + and \l TQColorGroup::ColorRole for definitions of each color role + in the three groups. + + \sa TQColorGroup TQColorGroup::ColorRole TQPalette +*/ + +TQPalette::TQPalette( const TQColorGroup &active, const TQColorGroup &disabled, + const TQColorGroup &inactive ) +{ + data = new TQPalData; + TQ_CHECK_PTR( data ); + data->ser_no = palette_count++; + data->active = active; + data->disabled = disabled; + data->inactive = inactive; +} + +/*! + Constructs a copy of \a p. + + This constructor is fast (it uses copy-on-write). +*/ + +TQPalette::TQPalette( const TQPalette &p ) +{ + data = p.data; + data->ref(); +} + +/*! + Destroys the palette. +*/ + +TQPalette::~TQPalette() +{ + if ( data->deref() ) + delete data; +} + +/*! + Assigns \a p to this palette and returns a reference to this + palette. + + This is fast (it uses copy-on-write). + + \sa copy() +*/ + +TQPalette &TQPalette::operator=( const TQPalette &p ) +{ + p.data->ref(); + if ( data->deref() ) + delete data; + data = p.data; + return *this; +} + + +/*! + Returns the color in color group \a gr, used for color role \a r. + + \sa brush() setColor() TQColorGroup::ColorRole +*/ +const TQColor &TQPalette::color( ColorGroup gr, TQColorGroup::ColorRole r ) const +{ + return directBrush( gr, r ).color(); +} + +/*! + Returns the brush in color group \a gr, used for color role \a r. + + \sa color() setBrush() TQColorGroup::ColorRole +*/ +const TQBrush &TQPalette::brush( ColorGroup gr, TQColorGroup::ColorRole r ) const +{ + return directBrush( gr, r ); +} + +/*! + Sets the brush in color group \a gr, used for color role \a r, to + the solid color \a c. + + \sa setBrush() color() TQColorGroup::ColorRole +*/ +void TQPalette::setColor( ColorGroup gr, TQColorGroup::ColorRole r, + const TQColor &c) +{ + setBrush( gr, r, TQBrush(c) ); +} + +/*! + Sets the brush in color group \a gr, used for color role \a r, to + \a b. + + \sa brush() setColor() TQColorGroup::ColorRole +*/ +void TQPalette::setBrush( ColorGroup gr, TQColorGroup::ColorRole r, + const TQBrush &b) +{ + detach(); + data->ser_no = palette_count++; + directSetBrush( gr, r, b); +} + +/*! + \overload + + Sets the brush color used for color role \a r to color \a c in all + three color groups. + + \sa color() setBrush() TQColorGroup::ColorRole +*/ +void TQPalette::setColor( TQColorGroup::ColorRole r, const TQColor &c ) +{ + setBrush( r, TQBrush(c) ); +} + +/*! + \overload + + Sets the brush in for color role \a r in all three color groups to + \a b. + + \sa brush() setColor() TQColorGroup::ColorRole active() inactive() disabled() +*/ +void TQPalette::setBrush( TQColorGroup::ColorRole r, const TQBrush &b ) +{ + detach(); + data->ser_no = palette_count++; + directSetBrush( Active, r, b ); + directSetBrush( Disabled, r, b ); + directSetBrush( Inactive, r, b ); +} + + +/*! + Returns a deep copy of this palette. + + \warning This is slower than the copy constructor and assignment + operator and offers no benefits. +*/ + +TQPalette TQPalette::copy() const +{ + TQPalette p( data->active, data->disabled, data->inactive ); + return p; +} + + +/*! + Detaches this palette from any other TQPalette objects with which + it might implicitly share TQColorGroup objects. In essence, does + the copying part of copy-on-write. + + Calling this should generally not be necessary; TQPalette calls it + itself when necessary. +*/ + +void TQPalette::detach() +{ + if ( data->count != 1 ) + *this = copy(); +} + +/*! + \fn const TQColorGroup & TQPalette::disabled() const + + Returns the disabled color group of this palette. + + \sa TQColorGroup, setDisabled(), active(), inactive() +*/ + +/*! + Sets the \c Disabled color group to \a g. + + \sa disabled() setActive() setInactive() +*/ + +void TQPalette::setDisabled( const TQColorGroup &g ) +{ + detach(); + data->ser_no = palette_count++; + data->disabled = g; +} + +/*! + \fn const TQColorGroup & TQPalette::active() const + + Returns the active color group of this palette. + + \sa TQColorGroup, setActive(), inactive(), disabled() +*/ + +/*! + Sets the \c Active color group to \a g. + + \sa active() setDisabled() setInactive() TQColorGroup +*/ + +void TQPalette::setActive( const TQColorGroup &g ) +{ + detach(); + data->ser_no = palette_count++; + data->active = g; +} + +/*! + \fn const TQColorGroup & TQPalette::inactive() const + + Returns the inactive color group of this palette. + + \sa TQColorGroup, setInactive(), active(), disabled() +*/ + +/*! + Sets the \c Inactive color group to \a g. + + \sa active() setDisabled() setActive() TQColorGroup +*/ + +void TQPalette::setInactive( const TQColorGroup &g ) +{ + detach(); + data->ser_no = palette_count++; + data->inactive = g; +} + + +/*! + \fn bool TQPalette::operator!=( const TQPalette &p ) const + + Returns TRUE (slowly) if this palette is different from \a p; + otherwise returns FALSE (usually quickly). +*/ + +/*! + Returns TRUE (usually quickly) if this palette is equal to \a p; + otherwise returns FALSE (slowly). +*/ + +bool TQPalette::operator==( const TQPalette &p ) const +{ + return data->active == p.data->active && + data->disabled == p.data->disabled && + data->inactive == p.data->inactive; +} + + +/*! + \fn int TQPalette::serialNumber() const + + Returns a number that uniquely identifies this TQPalette object. + The serial number is intended for caching. Its value may not be + used for anything other than equality testing. + + Note that TQPalette uses copy-on-write, and the serial number + changes during the lazy copy operation (detach()), not during a + shallow copy (copy constructor or assignment). + + \sa TQPixmap TQPixmapCache TQCache +*/ + + +/***************************************************************************** + TQColorGroup/TQPalette stream functions + *****************************************************************************/ + +#ifndef TQT_NO_DATASTREAM +/*! + \relates TQColorGroup + + Writes color group, \a g to the stream \a s. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQColorGroup &g ) +{ + if ( s.version() == 1 ) { + // TQt 1.x + s << g.foreground() + << g.background() + << g.light() + << g.dark() + << g.mid() + << g.text() + << g.base(); + } else { + int max = TQColorGroup::NColorRoles; + if ( s.version() <= 3) // TQt 2.x + max = 14; + + for( int r = 0 ; r < max ; r++ ) + s << g.brush( (TQColorGroup::ColorRole)r); + } + return s; +} + +/*! + \related TQColorGroup + + Reads a color group from the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQColorGroup &g ) +{ + if ( s.version() == 1 ) { + // TQt 1.x + TQColor fg, bg, light, dark, mid, text, base; + s >> fg >> bg >> light >> dark >> mid >> text >> base; + TQPalette p( bg ); + TQColorGroup n( p.active() ); + n.setColor( TQColorGroup::Foreground, fg ); + n.setColor( TQColorGroup::Light, light ); + n.setColor( TQColorGroup::Dark, dark ); + n.setColor( TQColorGroup::Mid, mid ); + n.setColor( TQColorGroup::Text, text ); + n.setColor( TQColorGroup::Base, base ); + g = n; + } else { + int max = TQColorGroup::NColorRoles; + if (s.version() <= 3) // TQt 2.x + max = 14; + + TQBrush tmp; + for( int r = 0 ; r < max; r++ ) { + s >> tmp; + g.setBrush( (TQColorGroup::ColorRole)r, tmp); + } + } + return s; +} + + +/*! + \relates TQPalette + + Writes the palette, \a p to the stream \a s and returns a + reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQPalette &p ) +{ + return s << p.active() + << p.disabled() + << p.inactive(); +} + + +static void readV1ColorGroup( TQDataStream &s, TQColorGroup &g, + TQPalette::ColorGroup r ) +{ + TQColor fg, bg, light, dark, mid, text, base; + s >> fg >> bg >> light >> dark >> mid >> text >> base; + TQPalette p( bg ); + TQColorGroup n; + switch ( r ) { + case TQPalette::Disabled: + n = p.disabled(); + break; + case TQPalette::Inactive: + n = p.inactive(); + break; + default: + n = p.active(); + break; + } + n.setColor( TQColorGroup::Foreground, fg ); + n.setColor( TQColorGroup::Light, light ); + n.setColor( TQColorGroup::Dark, dark ); + n.setColor( TQColorGroup::Mid, mid ); + n.setColor( TQColorGroup::Text, text ); + n.setColor( TQColorGroup::Base, base ); + g = n; +} + + +/*! + \relates TQPalette + + Reads a palette from the stream, \a s into the palette \a p, and + returns a reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQPalette &p ) +{ + TQColorGroup active, disabled, inactive; + if ( s.version() == 1 ) { + readV1ColorGroup( s, active, TQPalette::Active ); + readV1ColorGroup( s, disabled, TQPalette::Disabled ); + readV1ColorGroup( s, inactive, TQPalette::Inactive ); + } else { + s >> active >> disabled >> inactive; + } + TQPalette newpal( active, disabled, inactive ); + p = newpal; + return s; +} +#endif //TQT_NO_DATASTREAM + +/*! + Returns TRUE if this palette and \a p are copies of each other, + i.e. one of them was created as a copy of the other and neither + was subsequently modified; otherwise returns FALSE. This is much + stricter than equality. + + \sa operator=() operator==() +*/ + +bool TQPalette::isCopyOf( const TQPalette & p ) +{ + return data && data == p.data; +} + +const TQBrush &TQPalette::directBrush( ColorGroup gr, TQColorGroup::ColorRole r ) const +{ + if ( (uint)gr > (uint)TQPalette::NColorGroups ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPalette::directBrush: colorGroup(%i) out of range", gr ); +#endif + return data->active.br[TQColorGroup::Foreground]; + } + if ( (uint)r >= (uint)TQColorGroup::NColorRoles ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPalette::directBrush: colorRole(%i) out of range", r ); +#endif + return data->active.br[TQColorGroup::Foreground]; + } + switch( gr ) { + case Active: + return data->active.br[r]; + //break; + case Disabled: + return data->disabled.br[r]; + //break; + case Inactive: + return data->inactive.br[r]; + //break; + default: + break; + } +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPalette::directBrush: colorGroup(%i) internal error", gr ); +#endif + return data->active.br[TQColorGroup::Foreground]; // Satisfy compiler +} + +void TQPalette::directSetBrush( ColorGroup gr, TQColorGroup::ColorRole r, const TQBrush& b) +{ + if ( (uint)gr > (uint)TQPalette::NColorGroups ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPalette::directBrush: colorGroup(%i) out of range", gr ); +#endif + return; + } + if ( (uint)r >= (uint)TQColorGroup::NColorRoles ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPalette::directBrush: colorRole(%i) out of range", r ); +#endif + return; + } + switch( gr ) { + case Active: + data->active.setBrush(r,b); + break; + case Disabled: + data->disabled.setBrush(r,b); + break; + case Inactive: + data->inactive.setBrush(r,b); + break; + default: +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPalette::directBrush: colorGroup(%i) internal error", gr ); +#endif + break; + } +} + + +/*!\internal*/ +TQColorGroup::ColorRole TQPalette::foregroundRoleFromMode( TQt::BackgroundMode mode ) +{ + switch (mode) { + case TQt::PaletteButton: + return TQColorGroup::ButtonText; + case TQt::PaletteBase: + return TQColorGroup::Text; + case TQt::PaletteDark: + case TQt::PaletteShadow: + return TQColorGroup::Light; + case TQt::PaletteHighlight: + return TQColorGroup::HighlightedText; + case TQt::PaletteBackground: + default: + return TQColorGroup::Foreground; + } +} + +/*!\internal*/ +TQColorGroup::ColorRole TQPalette::backgroundRoleFromMode( TQt::BackgroundMode mode) +{ + switch (mode) { + case TQt::PaletteForeground: + return TQColorGroup::Foreground; + case TQt::PaletteButton: + return TQColorGroup::Button; + case TQt::PaletteLight: + return TQColorGroup::Light; + case TQt::PaletteMidlight: + return TQColorGroup::Midlight; + case TQt::PaletteDark: + return TQColorGroup::Dark; + case TQt::PaletteMid: + return TQColorGroup::Mid; + case TQt::PaletteText: + return TQColorGroup::Text; + case TQt::PaletteBrightText: + return TQColorGroup::BrightText; + case TQt::PaletteButtonText: + return TQColorGroup::ButtonText; + case TQt::PaletteBase: + return TQColorGroup::Base; + case TQt::PaletteShadow: + return TQColorGroup::Shadow; + case TQt::PaletteHighlight: + return TQColorGroup::Highlight; + case TQt::PaletteHighlightedText: + return TQColorGroup::HighlightedText; + case TQt::PaletteLink: + return TQColorGroup::Link; + case TQt::PaletteLinkVisited: + return TQColorGroup::LinkVisited; + case TQt::PaletteBackground: + default: + return TQColorGroup::Background; + } +} + +#endif // TQT_NO_PALETTE diff --git a/src/kernel/tqpalette.h b/src/kernel/tqpalette.h new file mode 100644 index 000000000..9f0ca13f0 --- /dev/null +++ b/src/kernel/tqpalette.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Definition of TQColorGroup and TQPalette classes +** +** Created : 950323 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPALETTE_H +#define TQPALETTE_H + +#ifndef QT_H +#include "ntqwindowdefs.h" +#include "tqcolor.h" +#include "ntqshared.h" +#include "tqbrush.h" // TQColor->TQBrush conversion +#endif // QT_H + +#ifndef TQT_NO_PALETTE + +class TQColorGroupPrivate; + +class TQ_EXPORT TQColorGroup +{ +public: + TQColorGroup(); + TQColorGroup( const TQColor &foreground, const TQColor &button, + const TQColor &light, const TQColor &dark, const TQColor &mid, + const TQColor &text, const TQColor &base ); + TQColorGroup( const TQBrush &foreground, const TQBrush &button, + const TQBrush &light, const TQBrush &dark, const TQBrush &mid, + const TQBrush &text, const TQBrush &bright_text, + const TQBrush &base, const TQBrush &background); + TQColorGroup( const TQColorGroup & ); + + ~TQColorGroup(); + + TQColorGroup& operator =(const TQColorGroup&); + + // Do not change the order, the serialization format depends on it + enum ColorRole { Foreground, Button, Light, Midlight, Dark, Mid, + Text, BrightText, ButtonText, Base, Background, Shadow, + Highlight, HighlightedText, Link, LinkVisited, + NColorRoles }; + + const TQColor &color( ColorRole ) const; + const TQBrush &brush( ColorRole ) const; + void setColor( ColorRole, const TQColor & ); + void setBrush( ColorRole, const TQBrush & ); + + const TQColor &foreground() const { return br[Foreground].color(); } + const TQColor &button() const { return br[Button].color(); } + const TQColor &light() const { return br[Light].color(); } + const TQColor &dark() const { return br[Dark].color(); } + const TQColor &mid() const { return br[Mid].color(); } + const TQColor &text() const { return br[Text].color(); } + const TQColor &base() const { return br[Base].color(); } + const TQColor &background() const { return br[Background].color(); } + + const TQColor &midlight() const { return br[Midlight].color(); } + const TQColor &brightText() const { return br[BrightText].color(); } + const TQColor &buttonText() const { return br[ButtonText].color(); } + const TQColor &shadow() const { return br[Shadow].color(); } + const TQColor &highlight() const { return br[Highlight].color(); } + const TQColor &highlightedText() const{return br[HighlightedText].color(); } + const TQColor &link() const { return br[Link].color(); } + const TQColor &linkVisited() const { return br[LinkVisited].color(); } + + bool operator==( const TQColorGroup &g ) const; + bool operator!=( const TQColorGroup &g ) const + { return !(operator==(g)); } + +private: + TQBrush *br; + TQColorGroupPrivate * d; + + friend class TQPalette; +}; + + +class TQ_EXPORT TQPalette +{ +public: + TQPalette(); + TQPalette( const TQColor &button ); + TQPalette( const TQColor &button, const TQColor &background ); + TQPalette( const TQColorGroup &active, const TQColorGroup &disabled, + const TQColorGroup &inactive ); + TQPalette( const TQPalette & ); + ~TQPalette(); + TQPalette &operator=( const TQPalette & ); + + enum ColorGroup { Disabled, Active, Inactive, NColorGroups }; + + const TQColor &color( ColorGroup, TQColorGroup::ColorRole ) const; + const TQBrush &brush( ColorGroup, TQColorGroup::ColorRole ) const; + void setColor( ColorGroup, TQColorGroup::ColorRole, const TQColor & ); + void setBrush( ColorGroup, TQColorGroup::ColorRole, const TQBrush & ); + + void setColor( TQColorGroup::ColorRole, const TQColor & ); + void setBrush( TQColorGroup::ColorRole, const TQBrush & ); + + TQPalette copy() const; + + const TQColorGroup &active() const { return data->active; } + const TQColorGroup &disabled() const { return data->disabled; } + const TQColorGroup &inactive() const { return data->inactive; } + + void setActive( const TQColorGroup & ); + void setDisabled( const TQColorGroup & ); + void setInactive( const TQColorGroup & ); + + bool operator==( const TQPalette &p ) const; + bool operator!=( const TQPalette &p ) const + { return !(operator==(p)); } + bool isCopyOf( const TQPalette & ); + + int serialNumber() const { return data->ser_no; } + + + static TQColorGroup::ColorRole foregroundRoleFromMode( TQt::BackgroundMode mode ); + static TQColorGroup::ColorRole backgroundRoleFromMode( TQt::BackgroundMode mode); + +private: + void detach(); + const TQBrush &directBrush( ColorGroup, TQColorGroup::ColorRole ) const; + void directSetBrush( ColorGroup, TQColorGroup::ColorRole, const TQBrush& ); + + struct TQPalData : public TQShared { + TQColorGroup disabled; + TQColorGroup active; + int ser_no; + TQColorGroup inactive; + } *data; +}; + + +/***************************************************************************** + TQColorGroup/TQPalette stream functions + *****************************************************************************/ + +#ifndef TQT_NO_DATASTREAM +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQColorGroup & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQColorGroup & ); + +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPalette & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPalette & ); +#endif // TQT_NO_DATASTREAM + +#endif // TQT_NO_PALETTE +#endif // TQPALETTE_H diff --git a/src/kernel/tqpen.h b/src/kernel/tqpen.h new file mode 100644 index 000000000..3a0a0f8d0 --- /dev/null +++ b/src/kernel/tqpen.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Definition of TQPen class +** +** Created : 940112 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPEN_H +#define TQPEN_H + +#ifndef QT_H +#include "tqcolor.h" +#include "ntqshared.h" +#endif // QT_H + + +class TQ_EXPORT TQPen: public TQt +{ +public: + TQPen(); + TQPen( PenStyle ); + TQPen( const TQColor &color, uint width=0, PenStyle style=SolidLine ); + TQPen( const TQColor &cl, uint w, PenStyle s, PenCapStyle c, PenJoinStyle j); + TQPen( const TQPen & ); + ~TQPen(); + TQPen &operator=( const TQPen & ); + + PenStyle style() const { return data->style; } + void setStyle( PenStyle ); + uint width() const { return data->width; } + void setWidth( uint ); + const TQColor &color() const { return data->color; } + void setColor( const TQColor & ); + PenCapStyle capStyle() const; + void setCapStyle( PenCapStyle ); + PenJoinStyle joinStyle() const; + void setJoinStyle( PenJoinStyle ); + + bool operator==( const TQPen &p ) const; + bool operator!=( const TQPen &p ) const + { return !(operator==(p)); } + +private: + friend class TQPainter; +#ifdef TQ_WS_WIN + friend class TQFontEngineWin; +#endif + + TQPen copy() const; + void detach(); + void init( const TQColor &, uint, uint ); + struct TQPenData : public TQShared { // pen data + PenStyle style; + uint width; + TQColor color; + TQ_UINT16 linest; + } *data; +}; + + +/***************************************************************************** + TQPen stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPen & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPen & ); +#endif + +#endif // TQPEN_H diff --git a/src/kernel/tqpicture.cpp b/src/kernel/tqpicture.cpp new file mode 100644 index 000000000..3ab6a000b --- /dev/null +++ b/src/kernel/tqpicture.cpp @@ -0,0 +1,1229 @@ +/**************************************************************************** +** +** Implementation of TQPicture class +** +** Created : 940802 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqpicture.h" + +#ifndef TQT_NO_PICTURE + +#include "tqpainter.h" +#include "tqpixmap.h" +#include "tqimage.h" +#include "tqfile.h" +#include "tqdatastream.h" +#include "tqpaintdevicemetrics.h" + +#ifndef TQT_NO_SVG +#include "private/qsvgdevice_p.h" +#endif + +/*! + \class TQPicture tqpicture.h + \brief The TQPicture class is a paint device that records and + replays TQPainter commands. + + \ingroup graphics + \ingroup images + \ingroup shared + + A picture serializes painter commands to an IO device in a + platform-independent format. For example, a picture created under + Windows can be read on a Sun SPARC. + + Pictures are called meta-files on some platforms. + + TQt pictures use a proprietary binary format. Unlike native picture + (meta-file) formats on many window systems, TQt pictures have no + limitations regarding their contents. Everything that can be + painted can also be stored in a picture, e.g. fonts, pixmaps, + regions, transformed graphics, etc. + + TQPicture is an \link shclass.html implicitly shared\endlink class. + + Example of how to record a picture: + \code + TQPicture pic; + TQPainter p; + p.begin( &pic ); // paint in picture + p.drawEllipse( 10,20, 80,70 ); // draw an ellipse + p.end(); // painting done + pic.save( "drawing.pic" ); // save picture + \endcode + + Example of how to replay a picture: + \code + TQPicture pic; + pic.load( "drawing.pic" ); // load picture + TQPainter p; + p.begin( &myWidget ); // paint in myWidget + p.drawPicture( pic ); // draw the picture + p.end(); // painting done + \endcode + + Pictures can also be drawn using play(). Some basic data about a + picture is available, for example, size(), isNull() and + boundingRect(). + +*/ + + +static const char *mfhdr_tag = "TQPIC"; // header tag +static const TQ_UINT16 mfhdr_maj = 5; // major version # +static const TQ_UINT16 mfhdr_min = 0; // minor version # + + +/*! + Constructs an empty picture. + + The \a formatVersion parameter may be used to \e create a TQPicture + that can be read by applications that are compiled with earlier + versions of TQt. + \list + \i \a formatVersion == 1 is binary compatible with TQt 1.x and later. + \i \a formatVersion == 2 is binary compatible with TQt 2.0.x and later. + \i \a formatVersion == 3 is binary compatible with TQt 2.1.x and later. + \i \a formatVersion == 4 is binary compatible with TQt 3.0.x and later. + \i \a formatVersion == 5 is binary compatible with TQt 3.1. + \endlist + + Note that the default formatVersion is -1 which signifies the + current release, i.e. for TQt 3.1 a formatVersion of 5 is the same + as the default formatVersion of -1. + + Reading pictures generated by earlier versions of TQt is supported + and needs no special coding; the format is automatically detected. +*/ + +TQPicture::TQPicture( int formatVersion ) + : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ) + // set device type +{ + d = new TQPicturePrivate; + +#if defined(QT_CHECK_RANGE) + if ( formatVersion == 0 ) + tqWarning( "TQPicture: invalid format version 0" ); +#endif + + // still accept the 0 default from before TQt 3.0. + if ( formatVersion > 0 && formatVersion != (int)mfhdr_maj ) { + d->formatMajor = formatVersion; + d->formatMinor = 0; + d->formatOk = FALSE; + } + else { + d->resetFormat(); + } +} + +/*! + Constructs a \link shclass.html shallow copy\endlink of \a pic. +*/ + +TQPicture::TQPicture( const TQPicture &pic ) + : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice ) +{ + d = pic.d; + d->ref(); +} + +/*! + Destroys the picture. +*/ +TQPicture::~TQPicture() +{ + if ( d->deref() ) + delete d; +} + + +/*! + \fn bool TQPicture::isNull() const + + Returns TRUE if the picture contains no data; otherwise returns + FALSE. +*/ + +/*! + \fn uint TQPicture::size() const + + Returns the size of the picture data. + + \sa data() +*/ + +/*! + \fn const char* TQPicture::data() const + + Returns a pointer to the picture data. The pointer is only valid + until the next non-const function is called on this picture. The + returned pointer is 0 if the picture contains no data. + + \sa size(), isNull() +*/ + +/*! + Sets the picture data directly from \a data and \a size. This + function copies the input data. + + \sa data(), size() +*/ + +void TQPicture::setData( const char* data, uint size ) +{ + detach(); + TQByteArray a( size ); + memcpy( a.data(), data, size ); + d->pictb.setBuffer( a ); // set byte array in buffer + d->resetFormat(); // we'll have to check +} + + +/*! + Loads a picture from the file specified by \a fileName and returns + TRUE if successful; otherwise returns FALSE. + + By default, the file will be interpreted as being in the native + TQPicture format. Specifying the \a format string is optional and + is only needed for importing picture data stored in a different + format. + + Currently, the only external format supported is the \link + http://www.w3.org/Graphics/SVG/ W3C SVG \endlink format which + requires the \link xml.html TQt XML module \endlink. The + corresponding \a format string is "svg". + + \sa save() +*/ + +bool TQPicture::load( const TQString &fileName, const char *format ) +{ + TQFile f( fileName ); + if ( !f.open(IO_ReadOnly) ) + return FALSE; + return load( &f, format ); +} + +/*! + \overload + + \a dev is the device to use for loading. +*/ + +bool TQPicture::load( TQIODevice *dev, const char *format ) +{ +#ifndef TQT_NO_SVG + if ( qstrcmp( format, "svg" ) == 0 ) { + TQSvgDevice svg; + if ( !svg.load( dev ) ) + return FALSE; + TQPainter p( this ); + bool b = svg.play( &p ); + d->brect = svg.boundingRect(); + return b; + } +#endif + if ( format ) { + tqWarning( "TQPicture::load: No such picture format: %s", format ); + return FALSE; + } + + detach(); + TQByteArray a = dev->readAll(); + d->pictb.setBuffer( a ); // set byte array in buffer + return d->checkFormat(); +} + +/*! + Saves a picture to the file specified by \a fileName and returns + TRUE if successful; otherwise returns FALSE. + + Specifying the file \a format string is optional. It's not + recommended unless you intend to export the picture data for + use by a third party reader. By default the data will be saved in + the native TQPicture file format. + + Currently, the only external format supported is the \link + http://www.w3.org/Graphics/SVG/ W3C SVG \endlink format which + requires the \link xml.html TQt XML module \endlink. The + corresponding \a format string is "svg". + + \sa load() +*/ + +bool TQPicture::save( const TQString &fileName, const char *format ) +{ + if ( paintingActive() ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPicture::save: still being painted on. " + "Call TQPainter::end() first" ); +#endif + return FALSE; + } + +#ifndef TQT_NO_SVG + // identical to TQIODevice* code below but the file name + // makes a difference when it comes to saving pixmaps + if ( tqstricmp( format, "svg" ) == 0 ) { + TQSvgDevice svg; + TQPainter p( &svg ); + if ( !play( &p ) ) + return FALSE; + svg.setBoundingRect( boundingRect() ); + return svg.save( fileName ); + } +#endif + + TQFile f( fileName ); + if ( !f.open(IO_WriteOnly) ) + return FALSE; + return save( &f, format ); +} + +/*! + \overload + + \a dev is the device to use for saving. +*/ + +bool TQPicture::save( TQIODevice *dev, const char *format ) +{ + if ( paintingActive() ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPicture::save: still being painted on. " + "Call TQPainter::end() first" ); +#endif + return FALSE; + } + +#ifndef TQT_NO_SVG + if ( tqstricmp( format, "svg" ) == 0 ) { + TQSvgDevice svg; + TQPainter p( &svg ); + if ( !play( &p ) ) + return FALSE; + svg.setBoundingRect( boundingRect() ); + return svg.save( dev ); + } +#endif + if ( format ) { + tqWarning( "TQPicture::save: No such picture format: %s", format ); + return FALSE; + } + + dev->writeBlock( d->pictb.buffer().data(), d->pictb.buffer().size() ); + return TRUE; +} + +/*! + Returns the picture's bounding rectangle or an invalid rectangle + if the picture contains no data. +*/ + +TQRect TQPicture::boundingRect() const +{ + if ( !d->formatOk ) + d->checkFormat(); + return d->brect; +} + +/*! + Sets the picture's bounding rectangle to \a r. The automatically + calculated value is overriden. +*/ + +void TQPicture::setBoundingRect( const TQRect &r ) +{ + if ( !d->formatOk ) + d->checkFormat(); + d->brect = r; +} + +/*! + Replays the picture using \a painter, and returns TRUE if + successful; otherwise returns FALSE. + + This function does exactly the same as TQPainter::drawPicture() + with (x, y) = (0, 0). +*/ + +bool TQPicture::play( TQPainter *painter ) +{ + if ( d->pictb.size() == 0 ) // nothing recorded + return TRUE; + + if ( !d->formatOk && !d->checkFormat() ) + return FALSE; + + d->pictb.open( IO_ReadOnly ); // open buffer device + TQDataStream s; + s.setDevice( &d->pictb ); // attach data stream to buffer + s.device()->at( 10 ); // go directly to the data + s.setVersion( d->formatMajor == 4 ? 3 : d->formatMajor ); + + TQ_UINT8 c, clen; + TQ_UINT32 nrecords; + s >> c >> clen; + Q_ASSERT( c == PdcBegin ); + // bounding rect was introduced in ver 4. Read in checkFormat(). + if ( d->formatMajor >= 4 ) { + TQ_INT32 dummy; + s >> dummy >> dummy >> dummy >> dummy; + } + s >> nrecords; + if ( !exec( painter, s, nrecords ) ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPicture::play: Format error" ); +#endif + d->pictb.close(); + return FALSE; + } + d->pictb.close(); + return TRUE; // no end-command +} + + +/*! + \internal + Iterates over the internal picture data and draws the picture using + \a painter. +*/ + +bool TQPicture::exec( TQPainter *painter, TQDataStream &s, int nrecords ) +{ +#if defined(QT_DEBUG) + int strm_pos; +#endif + TQ_UINT8 c; // command id + TQ_UINT8 tiny_len; // 8-bit length descriptor + TQ_INT32 len; // 32-bit length descriptor + TQ_INT16 i_16, i1_16, i2_16; // parameters... + TQ_INT8 i_8; + TQ_UINT32 ul; + TQCString str1; + TQString str; + TQPoint p, p1, p2; + TQRect r; + TQPointArray a; + TQColor color; + TQFont font; + TQPen pen; + TQBrush brush; + TQRegion rgn; +#ifndef TQT_NO_TRANSFORMATIONS + TQWMatrix matrix; +#endif + + while ( nrecords-- && !s.eof() ) { + s >> c; // read cmd + s >> tiny_len; // read param length + if ( tiny_len == 255 ) // longer than 254 bytes + s >> len; + else + len = tiny_len; +#if defined(QT_DEBUG) + strm_pos = s.device()->at(); +#endif + switch ( c ) { // exec cmd + case PdcNOP: + break; + case PdcDrawPoint: + s >> p; + painter->drawPoint( p ); + break; + case PdcMoveTo: + s >> p; + painter->moveTo( p ); + break; + case PdcLineTo: + s >> p; + painter->lineTo( p ); + break; + case PdcDrawLine: + s >> p1 >> p2; + painter->drawLine( p1, p2 ); + break; + case PdcDrawRect: + s >> r; + painter->drawRect( r ); + break; + case PdcDrawRoundRect: + s >> r >> i1_16 >> i2_16; + painter->drawRoundRect( r, i1_16, i2_16 ); + break; + case PdcDrawEllipse: + s >> r; + painter->drawEllipse( r ); + break; + case PdcDrawArc: + s >> r >> i1_16 >> i2_16; + painter->drawArc( r, i1_16, i2_16 ); + break; + case PdcDrawPie: + s >> r >> i1_16 >> i2_16; + painter->drawPie( r, i1_16, i2_16 ); + break; + case PdcDrawChord: + s >> r >> i1_16 >> i2_16; + painter->drawChord( r, i1_16, i2_16 ); + break; + case PdcDrawLineSegments: + s >> a; + painter->drawLineSegments( a ); + break; + case PdcDrawPolyline: + s >> a; + painter->drawPolyline( a ); + break; + case PdcDrawPolygon: + s >> a >> i_8; + painter->drawPolygon( a, i_8 ); + break; + case PdcDrawCubicBezier: + s >> a; +#ifndef TQT_NO_BEZIER + painter->drawCubicBezier( a ); +#endif + break; + case PdcDrawText: + s >> p >> str1; + painter->drawText( p, str1 ); + break; + case PdcDrawTextFormatted: + s >> r >> i_16 >> str1; + painter->drawText( r, i_16, str1 ); + break; + case PdcDrawText2: + s >> p >> str; + painter->drawText( p, str ); + break; + case PdcDrawText2Formatted: + s >> r >> i_16 >> str; + painter->drawText( r, i_16, str ); + break; + case PdcDrawPixmap: { + TQPixmap pixmap; + if ( d->formatMajor < 4 ) { + s >> p >> pixmap; + painter->drawPixmap( p, pixmap ); + } else { + s >> r >> pixmap; + painter->drawPixmap( r, pixmap ); + } + } + break; + case PdcDrawImage: { + TQImage image; + if ( d->formatMajor < 4 ) { + s >> p >> image; + painter->drawImage( p, image ); + } else { + s >> r >> image; + painter->drawImage( r, image ); + } + } + break; + case PdcBegin: + s >> ul; // number of records + if ( !exec( painter, s, ul ) ) + return FALSE; + break; + case PdcEnd: + if ( nrecords == 0 ) + return TRUE; + break; + case PdcSave: + painter->save(); + break; + case PdcRestore: + painter->restore(); + break; + case PdcSetBkColor: + s >> color; + painter->setBackgroundColor( color ); + break; + case PdcSetBkMode: + s >> i_8; + painter->setBackgroundMode( (TQt::BGMode)i_8 ); + break; + case PdcSetROP: + s >> i_8; + painter->setRasterOp( (TQt::RasterOp)i_8 ); + break; + case PdcSetBrushOrigin: + s >> p; + painter->setBrushOrigin( p ); + break; + case PdcSetFont: + s >> font; + painter->setFont( font ); + break; + case PdcSetPen: + s >> pen; + painter->setPen( pen ); + break; + case PdcSetBrush: + s >> brush; + painter->setBrush( brush ); + break; + case PdcSetTabStops: + s >> i_16; + painter->setTabStops( i_16 ); + break; + case PdcSetTabArray: + s >> i_16; + if ( i_16 == 0 ) { + painter->setTabArray( 0 ); + } else { + int *ta = new int[i_16]; + TQ_CHECK_PTR( ta ); + for ( int i=0; i> i1_16; + ta[i] = i1_16; + } + painter->setTabArray( ta ); + delete [] ta; + } + break; + case PdcSetVXform: + s >> i_8; +#ifndef TQT_NO_TRANSFORMATIONS + painter->setViewXForm( i_8 ); +#endif + break; + case PdcSetWindow: + s >> r; +#ifndef TQT_NO_TRANSFORMATIONS + painter->setWindow( r ); +#endif + break; + case PdcSetViewport: + s >> r; +#ifndef TQT_NO_TRANSFORMATIONS + painter->setViewport( r ); +#endif + break; + case PdcSetWXform: + s >> i_8; +#ifndef TQT_NO_TRANSFORMATIONS + painter->setWorldXForm( i_8 ); +#endif + break; + case PdcSetWMatrix: +#ifndef TQT_NO_TRANSFORMATIONS // #### fix me! + s >> matrix >> i_8; + painter->setWorldMatrix( matrix, i_8 ); +#endif + break; +#ifndef TQT_NO_TRANSFORMATIONS + case PdcSaveWMatrix: + painter->saveWorldMatrix(); + break; + case PdcRestoreWMatrix: + painter->restoreWorldMatrix(); + break; +#endif + case PdcSetClip: + s >> i_8; + painter->setClipping( i_8 ); + break; + case PdcSetClipRegion: + s >> rgn >> i_8; + painter->setClipRegion( rgn, (TQPainter::CoordinateMode)i_8 ); + break; + default: +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPicture::play: Invalid command %d", c ); +#endif + if ( len ) // skip unknown command + s.device()->at( s.device()->at()+len ); + } +#if defined(QT_DEBUG) + //tqDebug( "device->at(): %i, strm_pos: %i len: %i", s.device()->at(), strm_pos, len ); + Q_ASSERT( TQ_INT32(s.device()->at() - strm_pos) == len ); +#endif + } + return FALSE; +} + + +/*! + \internal + Records painter commands and stores them in the pictb buffer. +*/ + +bool TQPicture::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) +{ + detach(); + return d->cmd( c, pt, p ); +} + +/*! + \internal + Implementation of the function forwarded above to the internal data struct. +*/ + +bool TQPicture::TQPicturePrivate::cmd( int c, TQPainter *pt, TQPDevCmdParam *p ) +{ + TQDataStream s; + s.setDevice( &pictb ); + // when moving up to 4 the TQDataStream version remained at 3 + s.setVersion( formatMajor != 4 ? formatMajor : 3 ); + if ( c == PdcBegin ) { // begin; write header + TQByteArray empty( 0 ); + pictb.setBuffer( empty ); // reset byte array in buffer + pictb.open( IO_WriteOnly ); + s.writeRawBytes( mfhdr_tag, 4 ); + s << (TQ_UINT16)0 << (TQ_UINT16)formatMajor << (TQ_UINT16)formatMinor; + s << (TQ_UINT8)c << (TQ_UINT8)sizeof(TQ_INT32); + brect = TQRect(); + if ( formatMajor >= 4 ) { + s << (TQ_INT32)brect.left() << (TQ_INT32)brect.top() + << (TQ_INT32)brect.width() << (TQ_INT32)brect.height(); + } + trecs = 0; + s << (TQ_UINT32)trecs; // total number of records + formatOk = FALSE; + return TRUE; + } else if ( c == PdcEnd ) { // end; calc checksum and close + trecs++; + s << (TQ_UINT8)c << (TQ_UINT8)0; + TQByteArray buf = pictb.buffer(); + int cs_start = sizeof(TQ_UINT32); // pos of checksum word + int data_start = cs_start + sizeof(TQ_UINT16); + int brect_start = data_start + 2*sizeof(TQ_INT16) + 2*sizeof(TQ_UINT8); + int pos = pictb.at(); + pictb.at( brect_start ); + if ( formatMajor >= 4 ) { // bounding rectangle + s << (TQ_INT32)brect.left() << (TQ_INT32)brect.top() + << (TQ_INT32)brect.width() << (TQ_INT32)brect.height(); + } + s << (TQ_UINT32)trecs; // write number of records + pictb.at( cs_start ); + TQ_UINT16 cs = (TQ_UINT16)tqChecksum( buf.data()+data_start, pos-data_start ); + s << cs; // write checksum + pictb.close(); + return TRUE; + } + trecs++; + s << (TQ_UINT8)c; // write cmd to stream + s << (TQ_UINT8)0; // write dummy length info + int pos = (int)pictb.at(); // save position + TQRect br; // bounding rect addition + bool corr = FALSE; // correction for pen width + + switch ( c ) { + case PdcDrawPoint: + case PdcMoveTo: + case PdcLineTo: + case PdcSetBrushOrigin: + s << *p[0].point; + br = TQRect( *p[0].point, TQSize( 1, 1 ) ); + corr = TRUE; + break; + case PdcDrawLine: + s << *p[0].point << *p[1].point; + br = TQRect( *p[0].point, *p[1].point ).normalize(); + corr = TRUE; + break; + case PdcDrawRect: + case PdcDrawEllipse: + s << *p[0].rect; + br = *p[0].rect; + corr = TRUE; + break; + case PdcDrawRoundRect: + case PdcDrawArc: + case PdcDrawPie: + case PdcDrawChord: + s << *p[0].rect << (TQ_INT16)p[1].ival << (TQ_INT16)p[2].ival; + br = *p[0].rect; + corr = TRUE; + break; + case PdcDrawLineSegments: + case PdcDrawPolyline: + s << *p[0].ptarr; + br = p[0].ptarr->boundingRect(); + corr = TRUE; + break; +#ifndef TQT_NO_BEZIER + case PdcDrawCubicBezier: + s << *p[0].ptarr; + br = p[0].ptarr->cubicBezier().boundingRect(); + corr = TRUE; + break; +#endif + case PdcDrawPolygon: + s << *p[0].ptarr << (TQ_INT8)p[1].ival; + br = p[0].ptarr->boundingRect(); + corr = TRUE; + break; + case PdcDrawText2: + if ( formatMajor == 1 ) { + pictb.at( pos - 2 ); + s << (TQ_UINT8)PdcDrawText << (TQ_UINT8)0; + TQCString str1( (*p[1].str).latin1() ); + s << *p[0].point << str1; + } + else { + s << *p[0].point << *p[1].str; + } + br = pt->fontMetrics().boundingRect( *p[1].str ); + br.moveBy( p[0].point->x(), p[0].point->y() ); + break; + case PdcDrawText2Formatted: + if ( formatMajor == 1 ) { + pictb.at( pos - 2 ); + s << (TQ_UINT8)PdcDrawTextFormatted << (TQ_UINT8)0; + TQCString str1( (*p[2].str).latin1() ); + s << *p[0].rect << (TQ_INT16)p[1].ival << str1; + } + else { + s << *p[0].rect << (TQ_INT16)p[1].ival << *p[2].str; + } + br = *p[0].rect; + break; + case PdcDrawPixmap: + if ( formatMajor < 4 ) { + s << *p[0].point; + s << *p[1].pixmap; + br = TQRect( *p[0].point, p[1].pixmap->size() ); + } else { + s << *p[0].rect; + s << *p[1].pixmap; + br = *p[0].rect; + } + break; + case PdcDrawImage: + if ( formatMajor < 4 ) { + TQPoint pt( p[0].point->x(), p[0].point->y() ); + s << pt; + s << *p[1].image; + br = TQRect( *p[0].point, p[1].image->size() ); + } else { + s << *p[0].rect; + s << *p[1].image; + br = *p[0].rect; + } + break; + case PdcSave: + case PdcRestore: + break; + case PdcSetBkColor: + s << *p[0].color; + break; + case PdcSetBkMode: + case PdcSetROP: + s << (TQ_INT8)p[0].ival; + break; + case PdcSetFont: { + TQFont fnt = *p[0].font; + if (fnt.pointSize() > 0) + // we have to store pixels to get correct replay. + // the resolution is 72 dpi, so points == pixels + fnt.setPixelSize(TQFontInfo(fnt).pixelSize()); + s << fnt; + } + break; + case PdcSetPen: + s << *p[0].pen; + break; + case PdcSetBrush: + s << *p[0].brush; + break; + case PdcSetTabStops: + s << (TQ_INT16)p[0].ival; + break; + case PdcSetTabArray: + s << (TQ_INT16)p[0].ival; + if ( p[0].ival ) { + int *ta = p[1].ivec; + for ( int i=0; ipen().width() / 2; + br.setCoords( br.left() - w2, br.top() - w2, + br.right() + w2, br.bottom() + w2 ); + } +#ifndef TQT_NO_TRANSFORMATIONS + br = pt->worldMatrix().map( br ); +#endif + if ( pt->hasClipping() ) { + TQRect cr = pt->clipRegion().boundingRect(); + br &= cr; + } + if ( br.isValid() ) + brect |= br; // merge with existing rect + } + + return TRUE; +} + + +/*! + Internal implementation of the virtual TQPaintDevice::metric() + function. + + Use the TQPaintDeviceMetrics class instead. + + A picture has the following hard-coded values: dpi=72, + numcolors=16777216 and depth=24. + + \a m is the metric to get. +*/ + +int TQPicture::metric( int m ) const +{ + int val; + switch ( m ) { + // ### hard coded dpi and color depth values ! + case TQPaintDeviceMetrics::PdmWidth: + val = d->brect.width(); + break; + case TQPaintDeviceMetrics::PdmHeight: + val = d->brect.height(); + break; + case TQPaintDeviceMetrics::PdmWidthMM: + val = int(25.4/72.0*d->brect.width()); + break; + case TQPaintDeviceMetrics::PdmHeightMM: + val = int(25.4/72.0*d->brect.height()); + break; + case TQPaintDeviceMetrics::PdmDpiX: + case TQPaintDeviceMetrics::PdmPhysicalDpiX: + val = 72; + break; + case TQPaintDeviceMetrics::PdmDpiY: + case TQPaintDeviceMetrics::PdmPhysicalDpiY: + val = 72; + break; + case TQPaintDeviceMetrics::PdmNumColors: + val = 16777216; + break; + case TQPaintDeviceMetrics::PdmDepth: + val = 24; + break; + default: + val = 0; +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPicture::metric: Invalid metric command" ); +#endif + } + return val; +} + +/*! + Detaches from shared picture data and makes sure that this picture + is the only one referring to the data. + + If multiple pictures share common data, this picture makes a copy + of the data and detaches itself from the sharing mechanism. + Nothing is done if there is just a single reference. +*/ + +void TQPicture::detach() +{ + if ( d->count != 1 ) + *this = copy(); +} + +/*! + Returns a \link shclass.html deep copy\endlink of the picture. +*/ + +TQPicture TQPicture::copy() const +{ + TQPicture p; + TQByteArray a( size() ); + memcpy( a.data(), data(), size() ); + p.d->pictb.setBuffer( a ); // set byte array in buffer + if ( d->pictb.isOpen() ) { // copy buffer state + p.d->pictb.open( d->pictb.mode() ); + p.d->pictb.at( d->pictb.at() ); + } + p.d->trecs = d->trecs; + p.d->formatOk = d->formatOk; + p.d->formatMinor = d->formatMajor; + p.d->brect = boundingRect(); + return p; +} + +/***************************************************************************** + TQPainter member functions + *****************************************************************************/ + +/*! + Replays the picture \a pic translated by (\a x, \a y). + + This function does exactly the same as TQPicture::play() when + called with (\a x, \a y) = (0, 0). +*/ + +void TQPainter::drawPicture( int x, int y, const TQPicture &pic ) +{ + save(); + translate( x, y ); + ((TQPicture*)&pic)->play( (TQPainter*)this ); + restore(); +} + +/*! + \overload void TQPainter::drawPicture( const TQPoint &p, const TQPicture &pic ) + + Draws picture \a pic at point \a p. +*/ + +void TQPainter::drawPicture( const TQPoint &p, const TQPicture &pic ) +{ + drawPicture( p.x(), p.y(), pic ); +} + +/*! + \obsolete + + Use one of the other TQPainter::drawPicture() functions with a (0, 0) + offset instead. +*/ + +void TQPainter::drawPicture( const TQPicture &pic ) +{ + drawPicture( 0, 0, pic ); +} + +/*! + Assigns a \link shclass.html shallow copy\endlink of \a p to this + picture and returns a reference to this picture. +*/ + +TQPicture& TQPicture::operator= (const TQPicture& p) +{ + p.d->ref(); // avoid 'x = x' + if ( d->deref() ) + delete d; + d = p.d; + return *this; +} + + +/*! + \internal + + Sets formatOk to FALSE and resets the format version numbers to default +*/ + +void TQPicture::TQPicturePrivate::resetFormat() +{ + formatOk = FALSE; + formatMajor = mfhdr_maj; + formatMinor = mfhdr_min; +} + +/*! + \internal + + Checks data integrity and format version number. Set formatOk to TRUE + on success, to FALSE otherwise. Returns the resulting formatOk value. +*/ + +bool TQPicture::TQPicturePrivate::checkFormat() +{ + resetFormat(); + + // can't check anything in an empty buffer + if ( pictb.size() == 0 ) + return FALSE; + + pictb.open( IO_ReadOnly ); // open buffer device + TQDataStream s; + s.setDevice( &pictb ); // attach data stream to buffer + + char mf_id[4]; // picture header tag + s.readRawBytes( mf_id, 4 ); // read actual tag + if ( memcmp(mf_id, mfhdr_tag, 4) != 0 ) { // wrong header id +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPicture::checkFormat: Incorrect header" ); +#endif + pictb.close(); + return FALSE; + } + + int cs_start = sizeof(TQ_UINT32); // pos of checksum word + int data_start = cs_start + sizeof(TQ_UINT16); + TQ_UINT16 cs,ccs; + TQByteArray buf = pictb.buffer(); // pointer to data + s >> cs; // read checksum + ccs = tqChecksum( buf.data() + data_start, buf.size() - data_start ); + if ( ccs != cs ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPicture::checkFormat: Invalid checksum %x, %x expected", + ccs, cs ); +#endif + pictb.close(); + return FALSE; + } + + TQ_UINT16 major, minor; + s >> major >> minor; // read version number + if ( major > mfhdr_maj ) { // new, incompatible version +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPicture::checkFormat: Incompatible version %d.%d", + major, minor); +#endif + pictb.close(); + return FALSE; + } + s.setVersion( major != 4 ? major : 3 ); + + TQ_UINT8 c, clen; + s >> c >> clen; + if ( c == PdcBegin ) { + if ( !( major >= 1 && major <= 3 )) { + TQ_INT32 l, t, w, h; + s >> l >> t >> w >> h; + brect = TQRect( l, t, w, h ); + } + } else { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPicture::checkFormat: Format error" ); +#endif + pictb.close(); + return FALSE; + } + pictb.close(); + + formatOk = TRUE; // picture seems to be ok + formatMajor = major; + formatMinor = minor; + return TRUE; +} + +/***************************************************************************** + TQPicture stream functions + *****************************************************************************/ + +/*! + \relates TQPicture + + Writes picture \a r to the stream \a s and returns a reference to + the stream. +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQPicture &r ) +{ + TQ_UINT32 size = r.d->pictb.buffer().size(); + s << size; + // null picture ? + if ( size == 0 ) + return s; + // just write the whole buffer to the stream + return s.writeRawBytes ( r.d->pictb.buffer().data(), + r.d->pictb.buffer().size() ); +} + +/*! + \relates TQPicture + + Reads a picture from the stream \a s into picture \a r and returns + a reference to the stream. +*/ + +TQDataStream &operator>>( TQDataStream &s, TQPicture &r ) +{ + TQDataStream sr; + + // "init"; this code is similar to the beginning of TQPicture::cmd() + sr.setDevice( &r.d->pictb ); + sr.setVersion( r.d->formatMajor ); + TQ_UINT32 len; + s >> len; + TQByteArray data( len ); + if ( len > 0 ) + s.readRawBytes( data.data(), len ); + + r.d->pictb.setBuffer( data ); + r.d->resetFormat(); + + return s; +} + +#endif // TQT_NO_PICTURE + diff --git a/src/kernel/tqpicture.h b/src/kernel/tqpicture.h new file mode 100644 index 000000000..28512b61f --- /dev/null +++ b/src/kernel/tqpicture.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Definition of TQPicture class +** +** Created : 940729 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPICTURE_H +#define TQPICTURE_H + +#ifndef QT_H +#include "tqpaintdevice.h" +#include "tqbuffer.h" +#endif // QT_H + +#ifndef TQT_NO_PICTURE + +class TQ_EXPORT TQPicture : public TQPaintDevice // picture class +{ +public: + TQPicture( int formatVersion = -1 ); + TQPicture( const TQPicture & ); + ~TQPicture(); + + bool isNull() const; + + uint size() const; + const char* data() const; + virtual void setData( const char* data, uint size ); + + bool play( TQPainter * ); + + bool load( TQIODevice *dev, const char *format = 0 ); + bool load( const TQString &fileName, const char *format = 0 ); + bool save( TQIODevice *dev, const char *format = 0 ); + bool save( const TQString &fileName, const char *format = 0 ); + + TQRect boundingRect() const; + void setBoundingRect( const TQRect &r ); + + TQPicture& operator= (const TQPicture&); + + friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPicture & ); + friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPicture & ); + +protected: + bool cmd( int, TQPainter *, TQPDevCmdParam * ); + int metric( int ) const; + void detach(); + TQPicture copy() const; + +private: + bool exec( TQPainter *, TQDataStream &, int ); + + struct TQPicturePrivate : public TQShared { + bool cmd( int, TQPainter *, TQPDevCmdParam * ); + bool checkFormat(); + void resetFormat(); + + TQBuffer pictb; + int trecs; + bool formatOk; + int formatMajor; + int formatMinor; + TQRect brect; + } *d; +}; + + +inline bool TQPicture::isNull() const +{ + return d->pictb.buffer().isNull(); +} + +inline uint TQPicture::size() const +{ + return d->pictb.buffer().size(); +} + +inline const char* TQPicture::data() const +{ + return d->pictb.buffer().data(); +} + +/***************************************************************************** + TQPicture stream functions + *****************************************************************************/ + +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPicture & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPicture & ); + +#endif // TQT_NO_PICTURE + +#endif // TQPICTURE_H diff --git a/src/kernel/tqpixmap.cpp b/src/kernel/tqpixmap.cpp new file mode 100644 index 000000000..460dfc64d --- /dev/null +++ b/src/kernel/tqpixmap.cpp @@ -0,0 +1,1510 @@ +/**************************************************************************** +** +** Implementation of TQPixmap class +** +** Created : 950301 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "ntqapplication.h" +#include +#include "tqmime.h" +#include "tqdragobject.h" +#include "tqfile.h" + +/*! + \class TQPixmap tqpixmap.h + \brief The TQPixmap class is an off-screen, pixel-based paint device. + + \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 mask with createHeuristicMask() and setMask(). Use + selfMask() to see if the pixmap is identical to its mask. + + 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 contains 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 contains 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 device 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(QT_CHECK_STATE) + if ( !abs_name.isEmpty() ) + tqWarning( "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(QT_CHECK_STATE) + tqWarning("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(Q_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) + tqWarning("TQPixmap::resize: TODO: resize alpha data"); + else +#endif // TQ_WS_X11 + if ( data->mask ) { // resize mask as well + if ( data->selfmask ) { // preserve self-mask + pm.setMask( *((TQBitmap*)&pm) ); + } else { // independent mask + TQBitmap m = *data->mask; + m.resize( w, h ); + pm.setMask( m ); + } + } + *this = pm; +} + + +/*! + \fn const TQBitmap *TQPixmap::mask() const + + Returns the mask bitmap, or 0 if no mask has been set. + + \sa setMask(), TQBitmap, hasAlpha() +*/ + +/*! + Sets a mask bitmap. + + The \a newmask bitmap defines the clip mask for this pixmap. Every + pixel in \a newmask corresponds to a pixel in this pixmap. Pixel + value 1 means opaque and pixel value 0 means transparent. The mask + must have the same size as this pixmap. + + \warning Setting the mask 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.mask() ); + \endcode + Now, alpha and alphacopy are visually different. + + Setting a \link isNull() null\endlink mask resets the mask. + + \sa mask(), createHeuristicMask(), TQBitmap +*/ + +void TQPixmap::setMask( const TQBitmap &newmask ) +{ + const TQPixmap *tmp = &newmask; // dec cxx bug + if ( (data == tmp->data) || + ( newmask.handle() && newmask.handle() == handle() ) ) { + TQPixmap m = tmp->copy( TRUE ); + setMask( *((TQBitmap*)&m) ); + data->selfmask = TRUE; // mask == pixmap + return; + } + + if ( newmask.isNull() ) { // reset the mask + if (data->mask) { + detach(); + data->selfmask = FALSE; + + delete data->mask; + data->mask = 0; + } + return; + } + + detach(); + data->selfmask = FALSE; + + if ( newmask.width() != width() || newmask.height() != height() ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPixmap::setMask: The pixmap and the mask must have " + "the same size" ); +#endif + return; + } +#if defined(TQ_WS_MAC) || (defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)) + // when setting the mask, we get rid of the alpha channel completely + delete data->alphapm; + data->alphapm = 0; +#endif // TQ_WS_X11 && !TQT_NO_XFTFREETYPE + + delete data->mask; + TQBitmap* newmaskcopy; + if ( newmask.mask() ) + newmaskcopy = (TQBitmap*)new TQPixmap( tmp->copy( TRUE ) ); + else + newmaskcopy = new TQBitmap( newmask ); +#ifdef TQ_WS_X11 + newmaskcopy->x11SetScreen( x11Screen() ); +#endif + data->mask = newmaskcopy; +} + + +/*! + \fn bool TQPixmap::selfMask() const + + Returns TRUE if the pixmap's mask is identical to the pixmap + itself; otherwise returns FALSE. + + \sa mask() +*/ + +#ifndef TQT_NO_IMAGE_HEURISTIC_MASK +/*! + Creates and returns a heuristic mask 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 mask 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 mask is just large enough to cover the + pixels; otherwise, the mask 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 device. 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* device, const char* format, int quality ) const +{ + if ( isNull() ) + return FALSE; // nothing to save + TQImageIO io( device, format ); + return doImageIO( &io, quality ); +} + +/*! \internal +*/ + +bool TQPixmap::doImageIO( TQImageIO* io, int quality ) const +{ + if ( !io ) + return FALSE; + io->setImage( convertToImage() ); +#if defined(QT_CHECK_RANGE) + if ( quality > 100 || quality < -1 ) + tqWarning( "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 ); + + const TQObjectList * children = w->children(); + if ( children ) { + TQPainter p( &res ); + TQObjectListIt it( *children ); + TQObject * child; + while( (child=it.current()) != 0 ) { + ++it; + if ( child->isWidgetType() && + !((TQWidget *)child)->isHidden() && + !((TQWidget *)child)->isTopLevel() && + ((TQWidget *)child)->geometry().intersects( w->rect() ) ) { + // those conditions aren't quite right, it's possible + // to have a grandchild completely outside its + // grandparent, but partially inside its parent. 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 children, 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 + children 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 contains 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>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 QT_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 QT_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 QT_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 diff --git a/src/kernel/tqpixmap.h b/src/kernel/tqpixmap.h new file mode 100644 index 000000000..70609d4a7 --- /dev/null +++ b/src/kernel/tqpixmap.h @@ -0,0 +1,340 @@ +/**************************************************************************** +** +** Definition of TQPixmap class +** +** Created : 940501 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPIXMAP_H +#define TQPIXMAP_H + +#ifndef QT_H +#include "tqpaintdevice.h" +#include "tqcolor.h" // char*->TQColor conversion +#include "tqstring.h" // char*->TQString conversion +#include "ntqnamespace.h" +#endif // QT_H + +class TQPixmapPrivate; + +#if defined(TQ_WS_WIN) +// Internal pixmap memory optimization class for Windows 9x +class TQMultiCellPixmap; +#endif + + +class TQ_EXPORT TQPixmap : public TQPaintDevice, public TQt +{ +public: + enum ColorMode { Auto, Color, Mono }; + enum Optimization { DefaultOptim, NoOptim, MemoryOptim=NoOptim, + NormalOptim, BestOptim }; + + TQPixmap(); + TQPixmap( const TQImage& image ); + TQPixmap( int w, int h, int depth = -1, Optimization = DefaultOptim ); + TQPixmap( const TQSize &, int depth = -1, Optimization = DefaultOptim ); +#ifndef TQT_NO_IMAGEIO + TQPixmap( const TQString& fileName, const char *format=0, + ColorMode mode=Auto ); + TQPixmap( const TQString& fileName, const char *format, + int conversion_flags ); + TQPixmap( const char *xpm[] ); // ### in 4.0, 'const char * const xpm[]'? + TQPixmap( const TQByteArray &data ); +#endif + TQPixmap( const TQPixmap & ); + ~TQPixmap(); + + TQPixmap &operator=( const TQPixmap & ); + TQPixmap &operator=( const TQImage & ); + + bool isNull() const; + + int width() const { return data->w; } + int height() const { return data->h; } + TQSize size() const { return TQSize(data->w,data->h); } + TQRect rect() const { return TQRect(0,0,data->w,data->h); } + int depth() const { return data->d; } + static int defaultDepth(); + + void fill( const TQColor &fillColor = TQt::white ); + void fill( const TQWidget *, int xofs, int yofs ); + void fill( const TQWidget *, const TQPoint &ofs ); + void resize( int width, int height ); + void resize( const TQSize & ); + + const TQBitmap *mask() const; + void setMask( const TQBitmap & ); + bool selfMask() const; + bool hasAlpha() const; + bool hasAlphaChannel() const; +#ifndef TQT_NO_IMAGE_HEURISTIC_MASK + TQBitmap createHeuristicMask( bool clipTight = TRUE ) const; +#endif +#ifndef TQT_NO_MIME + static TQPixmap fromMimeSource( const TQString& abs_name ); +#endif + static TQPixmap grabWindow( WId, int x=0, int y=0, int w=-1, int h=-1 ); + static TQPixmap grabWidget( TQWidget * widget, + int x=0, int y=0, int w=-1, int h=-1 ); + +#ifndef TQT_NO_PIXMAP_TRANSFORMATION + TQPixmap xForm( const TQWMatrix & ) const; + static TQWMatrix trueMatrix( const TQWMatrix &, int w, int h ); +#endif + + TQImage convertToImage() const; + bool convertFromImage( const TQImage &, ColorMode mode=Auto ); + bool convertFromImage( const TQImage &, int conversion_flags ); +#ifndef TQT_NO_IMAGEIO + static const char* imageFormat( const TQString &fileName ); + bool load( const TQString& fileName, const char *format=0, + ColorMode mode=Auto ); + bool load( const TQString& fileName, const char *format, + int conversion_flags ); + bool loadFromData( const uchar *buf, uint len, + const char* format=0, + ColorMode mode=Auto ); + bool loadFromData( const uchar *buf, uint len, + const char* format, + int conversion_flags ); + bool loadFromData( const TQByteArray &data, + const char* format=0, + int conversion_flags=0 ); + bool save( const TQString& fileName, const char* format, int quality = -1 ) const; + bool save( TQIODevice* device, const char* format, int quality = -1 ) const; +#endif + +#if defined(TQ_WS_WIN) + HBITMAP hbm() const; +#endif + + int serialNumber() const; + + Optimization optimization() const; + void setOptimization( Optimization ); + static Optimization defaultOptimization(); + static void setDefaultOptimization( Optimization ); + + virtual void detach(); + + bool isTQBitmap() const; + +#if defined(TQ_WS_WIN) + // These functions are internal and used by Windows 9x only + bool isMultiCellPixmap() const; + HDC multiCellHandle() const; + HBITMAP multiCellBitmap() const; + int multiCellOffset() const; + int allocCell(); + void freeCell( bool = FALSE ); +#endif + +#if defined(TQ_WS_X11) + static int x11SetDefaultScreen( int screen ); + void x11SetScreen( int screen ); +#endif + +#ifndef Q_QDOC + TQ_DUMMY_COMPARISON_OPERATOR(TQPixmap) +#endif + +protected: + TQPixmap( int w, int h, const uchar *data, bool isXbitmap ); + int metric( int ) const; + +#if defined(TQ_WS_WIN) + struct TQMCPI { // mem optim for win9x + TQMultiCellPixmap *mcp; + int offset; + }; +#endif + + struct TQPixmapData : public TQShared { // internal pixmap data + TQCOORD w, h; + short d; + uint uninit : 1; + uint bitmap : 1; + uint selfmask : 1; +#if defined(TQ_WS_WIN) + uint mcp : 1; +#endif + int ser_no; + TQBitmap *mask; +#if defined(TQ_WS_WIN) + TQPixmap *maskpm; + union { + HBITMAP hbm; // if mcp == FALSE + TQMCPI *mcpi; // if mcp == TRUE + } hbm_or_mcpi; + uchar *realAlphaBits; +#ifdef Q_OS_TEMP + uchar* ppvBits; // Pointer to DIBSection bits +#endif +#elif defined(TQ_WS_X11) + void *ximage; + void *maskgc; + TQPixmap *alphapm; +#elif defined(TQ_WS_MAC) + ColorTable *clut; + TQPixmap *alphapm; +#endif + Optimization optim; +#if defined(TQ_WS_WIN) + HBITMAP old_hbm; +#endif + } *data; +private: +#ifndef TQT_NO_IMAGEIO + bool doImageIO( TQImageIO* io, int quality ) const; +#endif + TQPixmap( int w, int h, int depth, bool, Optimization ); + void init( int, int, int, bool, Optimization ); + void deref(); + TQPixmap copy( bool ignoreMask = FALSE ) const; +#if defined(TQ_WS_WIN) + void initAlphaPixmap( uchar *bytes, int length, struct tagBITMAPINFO *bmi ); + void convertToAlphaPixmap( bool initAlpha=TRUE ); + static void bitBltAlphaPixmap( TQPixmap *dst, int dx, int dy, + const TQPixmap *src, int sx, int sy, + int sw, int sh, bool useDstAlpha ); +#endif + static Optimization defOptim; + friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int, + const TQPaintDevice *, + int, int, int, int, RasterOp, bool ); + friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int, + const TQImage* src, + int, int, int, int, int conversion_flags ); + friend TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy, + const TQPixmap *src, int sx, int sy, + int sw, int sh ); + +#if defined(TQ_WS_MAC) + friend void unclippedScaledBitBlt(TQPaintDevice *, int, int, int, int, + const TQPaintDevice *, int, int, int, int, + TQt::RasterOp, bool, bool); +#endif + + friend class TQBitmap; + friend class TQPaintDevice; + friend class TQPainter; + friend class TQGLWidget; +}; + + +inline bool TQPixmap::isNull() const +{ + return data->w == 0; +} + +inline void TQPixmap::fill( const TQWidget *w, const TQPoint &ofs ) +{ + fill( w, ofs.x(), ofs.y() ); +} + +inline void TQPixmap::resize( const TQSize &s ) +{ + resize( s.width(), s.height() ); +} + +inline const TQBitmap *TQPixmap::mask() const +{ + return data->mask; +} + +inline bool TQPixmap::selfMask() const +{ + return data->selfmask; +} + +#if defined(TQ_WS_WIN) +inline HBITMAP TQPixmap::hbm() const +{ + return data->mcp ? 0 : data->hbm_or_mcpi.hbm; +} +#endif + +inline int TQPixmap::serialNumber() const +{ + return data->ser_no; +} + +inline TQPixmap::Optimization TQPixmap::optimization() const +{ + return data->optim; +} + +inline bool TQPixmap::isTQBitmap() const +{ + return data->bitmap; +} + +#if defined(TQ_WS_WIN) +inline bool TQPixmap::isMultiCellPixmap() const +{ + return data->mcp; +} +#endif + + +/***************************************************************************** + TQPixmap stream functions + *****************************************************************************/ + +#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO) +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPixmap & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPixmap & ); +#endif + +/***************************************************************************** + TQPixmap (and TQImage) helper functions + *****************************************************************************/ + +#ifndef TQT_NO_PIXMAP_TRANSFORMATION +# define QT_XFORM_TYPE_MSBFIRST 0 +# define QT_XFORM_TYPE_LSBFIRST 1 +# if defined(TQ_WS_WIN) +# define QT_XFORM_TYPE_WINDOWSPIXMAP 2 +# endif +bool qt_xForm_helper( const TQWMatrix&, int, int, int, uchar*, int, int, int, uchar*, int, int, int ); +#endif + +TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy, + const TQPixmap *src, int sx = 0, int sy = 0, + int sw = -1, int sh = -1 ); + +#endif // TQPIXMAP_H diff --git a/src/kernel/tqpixmap_x11.cpp b/src/kernel/tqpixmap_x11.cpp new file mode 100644 index 000000000..b1e6c6894 --- /dev/null +++ b/src/kernel/tqpixmap_x11.cpp @@ -0,0 +1,2482 @@ +/**************************************************************************** +** +** Implementation of TQPixmap class for X11 +** +** Created : 940501 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "qplatformdefs.h" + +#if defined(Q_OS_WIN32) && defined(QT_MITSHM) +#undef QT_MITSHM +#endif + +#ifdef QT_MITSHM + +// Use the MIT Shared Memory extension for pixmap<->image conversions +#define QT_MITSHM_CONVERSIONS + +// Uncomment the next line to enable the MIT Shared Memory extension +// for TQPixmap::xForm() +// +// WARNING: This has some problems: +// +// 1. Consumes a 800x600 pixmap +// 2. TQt does not handle the ShmCompletion message, so you will +// get strange effects if you xForm() repeatedly. +// +// #define QT_MITSHM_XFORM + +#else +#undef QT_MITSHM_CONVERSIONS +#undef QT_MITSHM_XFORM +#endif + +#include "tqbitmap.h" +#include "tqpaintdevicemetrics.h" +#include "tqimage.h" +#include "tqwmatrix.h" +#include "ntqapplication.h" +#include "qt_x11_p.h" + +#include + +#if defined(Q_CC_MIPS) +# define for if(0){}else for +#endif + + +/*! + \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(QT_MITSHM_XFORM) + +static bool xshminit = FALSE; +static XShmSegmentInfo xshminfo; +static XImage *xshmimg = 0; +static Pixmap xshmpm = 0; + +static void tqt_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 ) { + tqt_cleanup_mitshm(); + } else { + if ( !XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok) ) + return FALSE; // MIT Shm not supported + tqAddPostRoutine( tqt_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 // QT_MITSHM_XFORM + +#ifdef QT_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 QT_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 QT_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 QT_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 // QT_MITSHM_CONVERSIONS + +/***************************************************************************** + Internal functions + *****************************************************************************/ + +extern const uchar *qt_get_bitflip_array(); // defined in tqimage.cpp + +static uchar *flip_bits( const uchar *bits, int len ) +{ + 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(QT_CHECK_RANGE) + tqWarning( "build_scale_table: internal error, nBits = %i", nBits ); +#endif + return; + } + if (!*table) { + static bool firstTable = TRUE; + if ( firstTable ) { + tqAddPostRoutine( 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 tqt_use_xrender; // defined in qapplication_x11.cpp +extern bool tqt_has_xft; // defined in tqfont_x11.cpp + +#ifndef TQT_NO_XFTFREETYPE +#ifndef QT_XFT2 +// Xft1 doesn't have XftDrawCreateAlpha, so we fake it in qtaddons_x11.cpp +extern "C" XftDraw *XftDrawCreateAlpha( Display *, TQt::HANDLE, int ); +#endif // QT_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(QT_CHECK_STATE) + if ( tqApp->type() == TQApplication::Tty ) { + tqWarning( "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(QT_CHECK_RANGE) + if ( !make_null ) + tqWarning( "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 ( tqt_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 ( tqt_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 = tqt_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(QT_CHECK_RANGE) + tqWarning( "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 QT_MITSHM_CONVERSIONS + bool mitshm_ximage = false; + XShmSegmentInfo shminfo; +#endif + if ( !xi ) { // fetch data from X server +#ifdef QT_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 QT_MITSHM_CONVERSIONS + if( mitshm_ximage ) + qt_XShmDestroyImage( xi, &shminfo ); + else +#endif + qSafeXDestroyImage( xi ); + ((TQPixmap*)this)->data->ximage = 0; + return image; + } + + const TQPixmap* msk = mask(); + const TQPixmap *alf = data->alphapm; + + TQImage alpha; + if (alf) { + XImage* axi; +#ifdef QT_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 QT_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; ydata + xi->bytes_per_line*y; + for ( int x=0; x 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; ybytes_per_line; + } + } else { + /* Typically 2 or 4 bits display depth */ +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPixmap::convertToImage: Display not supported (bpp=%d)", + xi->bits_per_pixel ); +#endif + image.reset(); +#ifdef QT_MITSHM_CONVERSIONS + if( mitshm_ximage ) + qt_XShmDestroyImage( xi, &shminfo ); + else +#endif + qSafeXDestroyImage( xi ); + ((TQPixmap*)this)->data->ximage = 0; + 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 + 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> 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> 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 QT_MITSHM_CONVERSIONS + if( mitshm_ximage ) + qt_XShmDestroyImage( xi, &shminfo ); + else +#endif + qSafeXDestroyImage( xi ); + ((TQPixmap*)this)->data->ximage = 0; + } else { // keep ximage data +#ifdef QT_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(QT_CHECK_NULL) + tqWarning( "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 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; yw = 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; +#ifdef QT_MITSHM_CONVERSIONS + int newbits_size = 0; + 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 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 QT_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 8 && xi->byte_order == LSBFirst ) + bppc++; + + int wordsize; + bool bigendian; + tqSysInfo( &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 + tqFatal("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< thres) \ + r += (1<<(8-rbits)); \ + if ( g <= (255-(1<<(8-gbits))) && ((g< thres) \ + g += (1<<(8-gbits)); \ + if ( b <= (255-(1<<(8-bbits))) && ((b< 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 = (r & red_mask)|(g & green_mask) | (b & blue_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< thres) \ + r += (1<<(8-rbits)); \ + int g = tqGreen( *p ); \ + if ( g <= (255-(1<<(8-gbits))) && ((g< thres) \ + g += (1<<(8-gbits)); \ + int b = tqBlue ( *p++ ); \ + if ( b <= (255-(1<<(8-bbits))) && ((b< 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; ybytes_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>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>3,0x7c00,0x3e0,0x1f,5,5,5) + *dst16++ = pixel; + } + ) + break; + case BPP16_MSB: // 16 bit MSB + CYCLE( + for ( uint x=0; x> 8); + *dst++ = pixel; + } + ) + break; + case BPP16_LSB: // 16 bit LSB + CYCLE( + for ( uint x=0; x> 8; + } + ) + break; + default: + tqFatal("Logic error"); + } + } else { + switch ( mode ) { + case BPP8: // 8 bit + CYCLE( + Q_UNUSED(p); + for ( uint x=0; x>3,0xf800,0x7e0,0x1f) + *dst16++ = pixel; + } + ) + break; + case BPP16_7_2_M3: + CYCLE( + TQ_INT16* dst16 = (TQ_INT16*)dst; + for ( uint x=0; x>3,0x7c00,0x3e0,0x1f) + *dst16++ = pixel; + } + ) + break; + case BPP16_MSB: // 16 bit MSB + CYCLE( + for ( uint x=0; x> 8); + *dst++ = pixel; + } + ) + break; + case BPP16_LSB: // 16 bit LSB + CYCLE( + for ( uint x=0; x> 8; + } + ) + break; + case BPP24_MSB: // 24 bit MSB + CYCLE( + for ( uint x=0; x> 16; + *dst++ = pixel >> 8; + *dst++ = pixel; + } + ) + break; + case BPP24_LSB: // 24 bit LSB + CYCLE( + for ( uint x=0; x> 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> 24; + *dst++ = pixel >> 16; + *dst++ = pixel >> 8; + *dst++ = pixel; + } + ) + break; + case BPP32_LSB: // 32 bit LSB + CYCLE( + for ( uint x=0; x> 8; + *dst++ = pixel >> 16; + *dst++ = pixel >> 24; + } + ) + break; + default: + tqFatal("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 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; juse ) { + 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; juse ) { + 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 ) { // X image not created +#ifdef QT_MITSHM_CONVERSIONS + xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo ); + if( xi != NULL ) + mitshm_ximage = true; + else +#endif + 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 ); +#ifdef QT_MITSHM_CONVERSIONS + newbits_size = xi->bytes_per_line * h; +#endif + TQ_CHECK_PTR( newerbits ); + if ( !newerbits ) // no memory + return FALSE; + uchar* p = newbits; + for ( uint y=0; ybits_per_pixel != 8 ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPixmap::convertFromImage: Display not supported " + "(bpp=%d)", xi->bits_per_pixel ); +#endif + } +#ifdef QT_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 ( tqt_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 QT_MITSHM_CONVERSIONS + if( mitshm_ximage ) + XShmPutImage( dpy, hd, tqt_xget_readonly_gc( x11Screen(), FALSE ), + xi, 0, 0, 0, 0, w, h, False ); + else +#endif + XPutImage( dpy, hd, tqt_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 QT_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 (tqt_use_xrender && tqt_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 QT_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 QT_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 QT_MITSHM_CONVERSIONS + if( mitshm_ximage || mitshm_aximage ) + XSync( x11Display(), False ); // wait until processed +#endif + + if ( data->optim != BestOptim ) { // throw away image +#ifdef QT_MITSHM_CONVERSIONS + if( mitshm_ximage ) + qt_XShmDestroyImage( xi, &shminfo ); + else +#endif + qSafeXDestroyImage( xi ); + data->ximage = 0; + } else { // keep ximage that we created +#ifdef QT_MITSHM_CONVERSIONS + if( mitshm_ximage ) { // copy the XImage? + qt_XShmDestroyImage( xi, &shminfo ); + xi = 0; + } +#endif + data->ximage = xi; + } + if( axi ) { +#ifdef QT_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 = tqt_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(QT_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(QT_MITSHM_XFORM) + if ( use_mitshm ) { + dptr = (uchar *)xshmimg->data; + uchar fillbyte = bpp == 8 ? white.pixel() : 0xff; + for ( int y=0; ybytes_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(QT_MITSHM_XFORM) + } +#endif + + // #define QT_DEBUG_XIMAGE +#if defined(QT_DEBUG_XIMAGE) + tqDebug( "----IMAGE--INFO--------------" ); + tqDebug( "width............. %d", xi->width ); + tqDebug( "height............ %d", xi->height ); + tqDebug( "xoffset........... %d", xi->xoffset ); + tqDebug( "format............ %d", xi->format ); + tqDebug( "byte order........ %d", xi->byte_order ); + tqDebug( "bitmap unit....... %d", xi->bitmap_unit ); + tqDebug( "bitmap bit order.. %d", xi->bitmap_bit_order ); + tqDebug( "depth............. %d", xi->depth ); + tqDebug( "bytes per line.... %d", xi->bytes_per_line ); + tqDebug( "bits per pixel.... %d", xi->bits_per_pixel ); +#endif + + int type; + if ( xi->bitmap_bit_order == MSBFirst ) + type = QT_XFORM_TYPE_MSBFIRST; + else + type = QT_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(QT_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(QT_CHECK_RANGE) + tqWarning( "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 = tqt_xget_readonly_gc( x11Screen(), FALSE ); + TQPixmap pm( w, h ); + pm.data->uninit = FALSE; + pm.x11SetScreen( x11Screen() ); +#if defined(QT_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(QT_MITSHM_XFORM) + } +#endif + + if ( data->mask ) // xform mask, too + pm.setMask( data->mask->xForm(matrix) ); + +#ifndef TQT_NO_XFTFREETYPE + if ( tqt_use_xrender && tqt_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 = QT_XFORM_TYPE_MSBFIRST; + else + type = QT_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 + tqDebug("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 QT_CHECK_NULL + Q_ASSERT( dst != 0 ); + Q_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 tqt_use_xrender; // from qapplication_x11.cpp + if ( ! tqt_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 +} diff --git a/src/kernel/tqpixmapcache.cpp b/src/kernel/tqpixmapcache.cpp new file mode 100644 index 000000000..a61b0aa71 --- /dev/null +++ b/src/kernel/tqpixmapcache.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Implementation of TQPixmapCache class +** +** Created : 950504 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqpixmapcache.h" +#include "tqcache.h" +#include "tqobject.h" +#include "ntqcleanuphandler.h" + + +// REVISED: paul +/*! + \class TQPixmapCache tqpixmapcache.h + + \brief The TQPixmapCache class provides an application-global cache for + pixmaps. + + \ingroup environment + \ingroup graphics + \ingroup images + + This class is a tool for optimized drawing with TQPixmap. You can + use it to store temporary pixmaps that are expensive to generate + without using more storage space than cacheLimit(). Use insert() + to insert pixmaps, find() to find them and clear() to empty the + cache. + + For example, TQRadioButton has a non-trivial visual representation + so we don't want to regenerate a pixmap whenever a radio button is + displayed or changes state. In the function + TQRadioButton::drawButton(), we do not draw the radio button + directly. Instead, we first check the global pixmap cache for a + pixmap with the key "$qt_radio_nnn_", where \c nnn is a numerical + value that specifies the the radio button state. If a pixmap is + found, we bitBlt() it onto the widget and return. Otherwise, we + create a new pixmap, draw the radio button in the pixmap, and + finally insert the pixmap in the global pixmap cache, using the + key above. The bitBlt() is ten times faster than drawing the + radio button. All radio buttons in the program share the cached + pixmap since TQPixmapCache is application-global. + + TQPixmapCache contains no member data, only static functions to + access the global pixmap cache. It creates an internal TQCache for + caching the pixmaps. + + The cache associates a pixmap with a string (key). If two pixmaps + are inserted into the cache using equal keys, then the last pixmap + will hide the first pixmap. The TQDict and TQCache classes do + exactly the same. + + The cache becomes full when the total size of all pixmaps in the + cache exceeds cacheLimit(). The initial cache limit is 1024 KByte + (1 MByte); it is changed with setCacheLimit(). A pixmap takes + roughly width*height*depth/8 bytes of memory. + + See the \l TQCache documentation for more details about the cache + mechanism. +*/ + + +static const int cache_size = 149; // size of internal hash array +#ifdef TQ_WS_MAC9 +static int cache_limit = 256; // 256 KB cache limit +#else +static int cache_limit = 1024; // 1024 KB cache limit +#endif + +class TQPMCache: public TQObject, public TQCache +{ +public: + TQPMCache(): + TQObject( 0, "global pixmap cache" ), + TQCache( cache_limit * 1024, cache_size ), + id( 0 ), ps( 0 ), t( FALSE ) + { + setAutoDelete( TRUE ); + } + ~TQPMCache() {} + void timerEvent( TQTimerEvent * ); + bool insert( const TQString& k, const TQPixmap *d, int c, int p = 0 ); +private: + int id; + int ps; + bool t; +}; + + +/* + This is supposed to cut the cache size down by about 80-90% in a + minute once the application becomes idle, to let any inserted pixmap + remain in the cache for some time before it becomes a candidate for + cleaning-up, and to not cut down the size of the cache while the + cache is in active use. + + When the last pixmap has been deleted from the cache, kill the + timer so TQt won't keep the CPU from going into sleep mode. +*/ + +void TQPMCache::timerEvent( TQTimerEvent * ) +{ + int mc = maxCost(); + bool nt = totalCost() == ps; + setMaxCost( nt ? totalCost() * 3 / 4 : totalCost() -1 ); + setMaxCost( mc ); + ps = totalCost(); + + if ( !count() ) { + killTimer( id ); + id = 0; + } else if ( nt != t ) { + killTimer( id ); + id = startTimer( nt ? 10000 : 30000 ); + t = nt; + } +} + +bool TQPMCache::insert( const TQString& k, const TQPixmap *d, int c, int p ) +{ + bool r = TQCache::insert( k, d, c, p ); + if ( r && !id ) { + id = startTimer( 30000 ); + t = FALSE; + } + return r; +} + +static TQPMCache *pm_cache = 0; // global pixmap cache + +static TQSingleCleanupHandler qpm_cleanup_cache; + +/*! + Returns the pixmap associated with the \a key in the cache, or + null if there is no such pixmap. + + \warning If valid, you should copy the pixmap immediately (this is + fast). Subsequent insertions into the cache could cause the + pointer to become invalid. For this reason, we recommend you use + find(const TQString&, TQPixmap&) instead. + + Example: + \code + TQPixmap* pp; + TQPixmap p; + if ( (pp=TQPixmapCache::find("my_big_image", pm)) ) { + p = *pp; + } else { + p.load("bigimage.png"); + TQPixmapCache::insert("my_big_image", new TQPixmap(p)); + } + painter->drawPixmap(0, 0, p); + \endcode +*/ + +TQPixmap *TQPixmapCache::find( const TQString &key ) +{ + return pm_cache ? pm_cache->find(key) : 0; +} + + +/*! + \overload + + Looks for a cached pixmap associated with the \a key in the cache. + If a pixmap is found, the function sets \a pm to that pixmap and + returns TRUE; otherwise leaves \a pm alone and returns FALSE. + + Example: + \code + TQPixmap p; + if ( !TQPixmapCache::find("my_big_image", pm) ) { + pm.load("bigimage.png"); + TQPixmapCache::insert("my_big_image", pm); + } + painter->drawPixmap(0, 0, p); + \endcode +*/ + +bool TQPixmapCache::find( const TQString &key, TQPixmap& pm ) +{ + TQPixmap* p = pm_cache ? pm_cache->find(key) : 0; + if ( p ) pm = *p; + return !!p; +} + + +/*! + \obsolete + Inserts the pixmap \a pm associated with \a key into the cache. + Returns TRUE if successful, or FALSE if the pixmap is too big for the cache. + + + Note: \a pm must be allocated on the heap (using \c new). + + If this function returns FALSE, you must delete \a pm yourself. + + If this function returns TRUE, do not use \a pm afterwards or + keep references to it because any other insertions into the cache, + whether from anywhere in the application or within TQt itself, could cause + the pixmap to be discarded from the cache and the pointer to + become invalid. + + Due to these dangers, we strongly recommend that you use + insert(const TQString&, const TQPixmap&) instead. + +*/ + +bool TQPixmapCache::insert( const TQString &key, TQPixmap *pm ) +{ + if ( !pm_cache ) { // create pixmap cache + pm_cache = new TQPMCache; + TQ_CHECK_PTR( pm_cache ); + qpm_cleanup_cache.set( &pm_cache ); + } + return pm_cache->insert( key, pm, pm->width()*pm->height()*pm->depth()/8 ); +} + +/*! + Inserts a copy of the pixmap \a pm associated with the \a key into + the cache. + + All pixmaps inserted by the TQt library have a key starting with + "$qt", so your own pixmap keys should never begin "$qt". + + When a pixmap is inserted and the cache is about to exceed its + limit, it removes pixmaps until there is enough room for the + pixmap to be inserted. + + The oldest pixmaps (least recently accessed in the cache) are + deleted when more space is needed. + + \sa setCacheLimit(). +*/ + +bool TQPixmapCache::insert( const TQString &key, const TQPixmap& pm ) +{ + if ( !pm_cache ) { // create pixmap cache + pm_cache = new TQPMCache; + TQ_CHECK_PTR( pm_cache ); + qpm_cleanup_cache.set( &pm_cache ); + } + TQPixmap *p = new TQPixmap(pm); + bool rt = pm_cache->insert( key, p, p->width()*p->height()*p->depth()/8 ); + if ( !rt ) + delete p; + + return rt; +} + +/*! + Returns the cache limit (in kilobytes). + + The default setting is 1024 kilobytes. + + \sa setCacheLimit(). +*/ + +int TQPixmapCache::cacheLimit() +{ + return cache_limit; +} + +/*! + Sets the cache limit to \a n kilobytes. + + The default setting is 1024 kilobytes. + + \sa cacheLimit() +*/ + +void TQPixmapCache::setCacheLimit( int n ) +{ +#ifdef TQ_WS_MAC9 + if(n > 256) + tqWarning("TQPixmapCache::setCacheLimit: Setting cache limits high is harmfull to mac9's health"); +#endif + cache_limit = n; + if ( pm_cache ) + pm_cache->setMaxCost( 1024*cache_limit ); +} + + +/*! + Removes the pixmap associated with \a key from the cache. +*/ +void TQPixmapCache::remove( const TQString &key ) +{ + if ( pm_cache ) + pm_cache->remove( key ); +} + + +/*! + Removes all pixmaps from the cache. +*/ + +void TQPixmapCache::clear() +{ + if ( pm_cache ) + pm_cache->clear(); +} diff --git a/src/kernel/tqpixmapcache.h b/src/kernel/tqpixmapcache.h new file mode 100644 index 000000000..9cff8f18b --- /dev/null +++ b/src/kernel/tqpixmapcache.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Definition of TQPixmapCache class +** +** Created : 950501 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPIXMAPCACHE_H +#define TQPIXMAPCACHE_H + +#ifndef QT_H +#include "tqpixmap.h" +#endif // QT_H + + +class TQ_EXPORT TQPixmapCache // global pixmap cache +{ +public: + static int cacheLimit(); + static void setCacheLimit( int ); + static TQPixmap *find( const TQString &key ); + static bool find( const TQString &key, TQPixmap& ); + static bool insert( const TQString &key, TQPixmap * ); + static bool insert( const TQString &key, const TQPixmap& ); + static void remove( const TQString &key ); + static void clear(); +}; + + +#endif // TQPIXMAPCACHE_H diff --git a/src/kernel/tqpngio.cpp b/src/kernel/tqpngio.cpp new file mode 100644 index 000000000..16d17eb6f --- /dev/null +++ b/src/kernel/tqpngio.cpp @@ -0,0 +1,1351 @@ +/**************************************************************************** +** +** Implementation of PNG TQImage IOHandler +** +** Created : 970521 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqpngio.h" + +#ifndef TQT_NO_IMAGEIO_PNG + +#include "ntqasyncimageio.h" +#include "tqiodevice.h" + +#include +#if PNG_LIBPNG_VER>=10500 +#include +#endif /* LIBPNG 1.5 */ + + +#ifdef Q_OS_TEMP +#define CALLBACK_CALL_TYPE __cdecl +#else +#define CALLBACK_CALL_TYPE +#endif + + +/* + All PNG files load to the minimal TQImage equivalent. + + All TQImage formats output to reasonably efficient PNG equivalents. + Never to grayscale. +*/ + +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif + +static +void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) +{ + TQImageIO* iio = (TQImageIO*)png_get_io_ptr(png_ptr); + TQIODevice* in = iio->ioDevice(); + + while (length) { + int nr = in->readBlock((char*)data, length); + if (nr <= 0) { + png_error(png_ptr, "Read Error"); + return; + } + length -= nr; + } +} + + +static +void CALLBACK_CALL_TYPE qpiw_write_fn( png_structp png_ptr, png_bytep data, png_size_t length ) +{ + TQPNGImageWriter* qpiw = (TQPNGImageWriter*)png_get_io_ptr( png_ptr ); + TQIODevice* out = qpiw->device(); + + uint nr = out->writeBlock( (char*)data, length ); + if ( nr != length ) { + png_error( png_ptr, "Write Error" ); + return; + } +} + + +static +void CALLBACK_CALL_TYPE qpiw_flush_fn( png_structp png_ptr ) +{ + TQPNGImageWriter* qpiw = (TQPNGImageWriter*)png_get_io_ptr( png_ptr ); + TQIODevice* out = qpiw->device(); + + out->flush(); +} + +#if defined(Q_C_CALLBACKS) +} +#endif + +static +void setup_qt( TQImage& image, png_structp png_ptr, png_infop info_ptr, float screen_gamma=0.0 ) +{ + if ( screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) ) { + double file_gamma; + png_get_gAMA(png_ptr, info_ptr, &file_gamma); + png_set_gamma( png_ptr, screen_gamma, file_gamma ); + } + + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int color_type; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + 0, 0, 0); + +#if PNG_LIBPNG_VER>=10500 + png_colorp info_ptr_palette = NULL; + int info_ptr_num_palette = 0; + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)) { + png_get_PLTE(png_ptr, info_ptr, &info_ptr_palette, &info_ptr_num_palette); + } + + png_bytep info_ptr_trans_alpha = NULL; + int info_ptr_num_trans = 0; + png_color_16p info_ptr_trans_color = NULL; + + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_get_tRNS(png_ptr, info_ptr, &info_ptr_trans_alpha, &info_ptr_num_trans, &info_ptr_trans_color); + } +#endif /* LIBPNG 1.5 */ + + if ( color_type == PNG_COLOR_TYPE_GRAY ) { + // Black & White or 8-bit grayscale +#if PNG_LIBPNG_VER>=10500 + if ( bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1 ) { +#else /* LIBPNG 1.5 */ + if ( bit_depth == 1 && info_ptr->channels == 1 ) { +#endif /* LIBPNG 1.5 */ + png_set_invert_mono( png_ptr ); + png_read_update_info( png_ptr, info_ptr ); + if (!image.create( width, height, 1, 2, TQImage::BigEndian )) + return; + image.setColor( 1, tqRgb(0,0,0) ); + image.setColor( 0, tqRgb(255,255,255) ); + } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_set_expand(png_ptr); + png_set_strip_16(png_ptr); + png_set_gray_to_rgb(png_ptr); + + if (!image.create(width, height, 32)) + return; + image.setAlphaBuffer(TRUE); + + if (TQImage::systemByteOrder() == TQImage::BigEndian) + png_set_swap_alpha(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + } else { + if ( bit_depth == 16 ) + png_set_strip_16(png_ptr); + else if ( bit_depth < 8 ) + png_set_packing(png_ptr); + int ncols = bit_depth < 8 ? 1 << bit_depth : 256; + png_read_update_info(png_ptr, info_ptr); + if (!image.create(width, height, 8, ncols)) + return; + for (int i=0; i=10500 + const int g = info_ptr_trans_color->gray; +#elif PNG_LIBPNG_VER>=10400 + const int g = info_ptr->trans_color.gray; +#else + const int g = info_ptr->trans_values.gray; +#endif + if (g < ncols) { + image.setAlphaBuffer(TRUE); + image.setColor(g, image.color(g) & TQT_RGB_MASK); + } + } + } + } else if ( color_type == PNG_COLOR_TYPE_PALETTE + && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE) +#if PNG_LIBPNG_VER>=10500 + && info_ptr_num_palette <= 256 ) +#else /* LIBPNG 1.5 */ + && info_ptr->num_palette <= 256 ) +#endif /* LIBPNG 1.5 */ + { + // 1-bit and 8-bit color + if ( bit_depth != 1 ) + png_set_packing( png_ptr ); + png_read_update_info( png_ptr, info_ptr ); + png_get_IHDR(png_ptr, info_ptr, + &width, &height, &bit_depth, &color_type, 0, 0, 0); +#if PNG_LIBPNG_VER>=10500 + if (!image.create(width, height, bit_depth, info_ptr_num_palette, +#else /* LIBPNG 1.5 */ + if (!image.create(width, height, bit_depth, info_ptr->num_palette, +#endif /* LIBPNG 1.5 */ + TQImage::BigEndian)) + return; + int i = 0; + if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) { + image.setAlphaBuffer( TRUE ); + +#if PNG_LIBPNG_VER>=10500 + while ( i < info_ptr_num_trans ) { + image.setColor(i, tqRgba( + info_ptr_palette[i].red, + info_ptr_palette[i].green, + info_ptr_palette[i].blue, +#else /* LIBPNG 1.5 */ + while ( i < info_ptr->num_trans ) { + image.setColor(i, tqRgba( + info_ptr->palette[i].red, + info_ptr->palette[i].green, + info_ptr->palette[i].blue, +#endif /* LIBPNG 1.5 */ +#if PNG_LIBPNG_VER>=10500 + info_ptr_trans_alpha[i] +#elif PNG_LIBPNG_VER>=10400 + info_ptr->trans_alpha[i] +#else + info_ptr->trans[i] +#endif + ) + ); + i++; + } + } +#if PNG_LIBPNG_VER>=10500 + while ( i < info_ptr_num_palette ) { + image.setColor(i, tqRgba( + info_ptr_palette[i].red, + info_ptr_palette[i].green, + info_ptr_palette[i].blue, +#else /* LIBPNG 1.5 */ + while ( i < info_ptr->num_palette ) { + image.setColor(i, tqRgba( + info_ptr->palette[i].red, + info_ptr->palette[i].green, + info_ptr->palette[i].blue, +#endif /* LIBPNG 1.5 */ + 0xff + ) + ); + i++; + } + } else { + // 32-bit + if ( bit_depth == 16 ) + png_set_strip_16(png_ptr); + + png_set_expand(png_ptr); + + if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) + png_set_gray_to_rgb(png_ptr); + + if (!image.create(width, height, 32)) + return; + + // Only add filler if no alpha, or we can get 5 channel data. + if (!(color_type & PNG_COLOR_MASK_ALPHA) + && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_set_filler(png_ptr, 0xff, + TQImage::systemByteOrder() == TQImage::BigEndian ? + PNG_FILLER_BEFORE : PNG_FILLER_AFTER); + // We want 4 bytes, but it isn't an alpha channel + } else { + image.setAlphaBuffer(TRUE); + } + + if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { + png_set_swap_alpha(png_ptr); + } + + png_read_update_info(png_ptr, info_ptr); + } + + // TQt==ARGB==Big(ARGB)==Little(BGRA) + if ( TQImage::systemByteOrder() == TQImage::LittleEndian ) { + png_set_bgr(png_ptr); + } +} + + +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif +static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const_charp message) +{ + tqWarning("libpng warning: %s", message); +} + +#if defined(Q_C_CALLBACKS) +} +#endif + + +static +void read_png_image(TQImageIO* iio) +{ + png_structp png_ptr; + png_infop info_ptr; + png_infop end_info; + png_bytep* row_pointers; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0); + if (!png_ptr) { + iio->setStatus(-1); + return; + } + + png_set_error_fn(png_ptr, 0, 0, qt_png_warning); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, 0, 0); + iio->setStatus(-2); + return; + } + + end_info = png_create_info_struct(png_ptr); + if (!end_info) { + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + iio->setStatus(-3); + return; + } + +#if PNG_LIBPNG_VER>=10500 + if (setjmp(png_jmpbuf(png_ptr))) { +#else /* LIBPNG 1.5 */ + if (setjmp(png_ptr->jmpbuf)) { +#endif /* LIBPNG 1.5 */ + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + iio->setStatus(-4); + return; + } + + png_set_read_fn(png_ptr, (void*)iio, iod_read_fn); + png_read_info(png_ptr, info_ptr); + + TQImage image; + setup_qt(image, png_ptr, info_ptr, iio->gamma()); + if (image.isNull()) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + iio->setStatus(-5); + return; + } + + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int color_type; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + 0, 0, 0); + + uchar** jt = image.jumpTable(); + row_pointers=new png_bytep[height]; + + for (uint y=0; y=10400 + (info_ptr->trans_color.red << 8 >> bit_depth)&0xff, + (info_ptr->trans_color.green << 8 >> bit_depth)&0xff, + (info_ptr->trans_color.blue << 8 >> bit_depth)&0xff); +#else + (info_ptr->trans_values.red << 8 >> bit_depth)&0xff, + (info_ptr->trans_values.green << 8 >> bit_depth)&0xff, + (info_ptr->trans_values.blue << 8 >> bit_depth)&0xff); +#endif + for (uint y=0; ywidth; x++) { + if (((uint**)jt)[y][x] == trans) { + ((uint**)jt)[y][x] &= 0x00FFFFFF; + } else { + } + } + } + } +#endif + + image.setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr)); + image.setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr)); + +#ifndef TQT_NO_IMAGE_TEXT + png_textp text_ptr; + int num_text=0; + png_get_text(png_ptr,info_ptr,&text_ptr,&num_text); + while (num_text--) { + image.setText(text_ptr->key,0,text_ptr->text); + text_ptr++; + } +#endif + + delete [] row_pointers; + + if ( image.hasAlphaBuffer() ) { + // Many PNG files lie (eg. from PhotoShop). Fortunately this loop will + // usually be quick to find those that tell the truth. + TQRgb* c; + int n; + if (image.depth()==32) { + c = (TQRgb*)image.bits(); + n = image.bytesPerLine() * image.height() / 4; + } else { + c = image.colorTable(); + n = image.numColors(); + } + while ( n-- && tqAlpha(*c++)==0xff ) + ; + if ( n<0 ) // LIAR! + image.setAlphaBuffer(FALSE); + } + + iio->setImage(image); + + png_read_end(png_ptr, end_info); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + + iio->setStatus(0); +} + +TQPNGImageWriter::TQPNGImageWriter(TQIODevice* iod) : + dev(iod), + frames_written(0), + disposal(Unspecified), + looping(-1), + ms_delay(-1), + gamma(0.0) +{ +} + +TQPNGImageWriter::~TQPNGImageWriter() +{ +} + +void TQPNGImageWriter::setDisposalMethod(DisposalMethod dm) +{ + disposal = dm; +} + +void TQPNGImageWriter::setLooping(int loops) +{ + looping = loops; +} + +void TQPNGImageWriter::setFrameDelay(int msecs) +{ + ms_delay = msecs; +} + +void TQPNGImageWriter::setGamma(float g) +{ + gamma = g; +} + + +#ifndef TQT_NO_IMAGE_TEXT +static void set_text(const TQImage& image, png_structp png_ptr, png_infop info_ptr, bool short_not_long) +{ + TQValueList keys = image.textList(); + if ( keys.count() ) { + png_textp text_ptr = new png_text[keys.count()]; + int i=0; + for (TQValueList::Iterator it=keys.begin(); + it != keys.end(); ++it) + { + TQString t = image.text(*it); + if ( (t.length() <= 200) == short_not_long ) { + if ( t.length() < 40 ) + text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE; + else + text_ptr[i].compression = PNG_TEXT_COMPRESSION_zTXt; + text_ptr[i].key = (png_charp)(*it).key.data(); + text_ptr[i].text = (png_charp)t.latin1(); + //text_ptr[i].text = tqstrdup(t.latin1()); + i++; + } + } + png_set_text(png_ptr, info_ptr, text_ptr, i); + //for (int j=0; j=10500 + if (setjmp(png_jmpbuf(png_ptr))) { +#else /* LIBPNG 1.5 */ + if (setjmp(png_ptr->jmpbuf)) { +#endif /* LIBPNG 1.5 */ + png_destroy_write_struct(&png_ptr, &info_ptr); + return FALSE; + } + + int quality = quality_in; + if (quality >= 0) { + if (quality > 9) { +#if defined(QT_CHECK_RANGE) + tqWarning( "PNG: Quality %d out of range", quality ); +#endif + quality = 9; + } + png_set_compression_level(png_ptr, quality); + } + + if (gamma != 0.0) { + png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); + } + + png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); + + png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), + image.depth() == 1 ? 1 : 8 /* per channel */, + image.depth() == 32 + ? image.hasAlphaBuffer() + ? PNG_COLOR_TYPE_RGB_ALPHA + : PNG_COLOR_TYPE_RGB + : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); + +#if PNG_LIBPNG_VER>=10500 + png_color_8 sig_bit; + sig_bit.red = 8; + sig_bit.green = 8; + sig_bit.blue = 8; + png_set_sBIT(png_ptr, info_ptr, &sig_bit); +#else /* LIBPNG 1.5 */ + //png_set_sBIT(png_ptr, info_ptr, 8); + info_ptr->sig_bit.red = 8; + info_ptr->sig_bit.green = 8; + info_ptr->sig_bit.blue = 8; +#endif /* LIBPNG 1.5 */ + + if (image.depth() == 1 && image.bitOrder() == TQImage::LittleEndian) + png_set_packswap(png_ptr); + + png_colorp palette = 0; + png_bytep copy_trans = 0; + if (image.numColors()) { + // Paletted + int num_palette = image.numColors(); + palette = new png_color[num_palette]; + png_set_PLTE(png_ptr, info_ptr, palette, num_palette); + int* trans = new int[num_palette]; + int num_trans = 0; +#if PNG_LIBPNG_VER>=10500 + png_colorp info_ptr_palette = NULL; + int tmp; + png_get_PLTE(png_ptr, info_ptr, &info_ptr_palette, &tmp); +#endif /* LIBPNG 1.5 */ + for (int i=0; i=10500 + info_ptr_palette[i].red = tqRed(rgb); + info_ptr_palette[i].green = tqGreen(rgb); + info_ptr_palette[i].blue = tqBlue(rgb); +#else /* LIBPNG 1.5 */ + info_ptr->palette[i].red = tqRed(rgb); + info_ptr->palette[i].green = tqGreen(rgb); + info_ptr->palette[i].blue = tqBlue(rgb); +#endif /* LIBPNG 1.5 */ + if (image.hasAlphaBuffer()) { + trans[i] = rgb >> 24; + if (trans[i] < 255) { + num_trans = i+1; + } + } + } +#if PNG_LIBPNG_VER>=10500 + png_set_PLTE(png_ptr, info_ptr, info_ptr_palette, num_palette); +#endif /* LIBPNG 1.5 */ + if (num_trans) { + copy_trans = new png_byte[num_trans]; + for (int i=0; i=10500 + png_color_8p sig_bit; + png_get_sBIT(png_ptr, info_ptr, &sig_bit); + sig_bit->alpha = 8; + png_set_sBIT(png_ptr, info_ptr, sig_bit); +#else /* LIBPNG 1.5 */ + info_ptr->sig_bit.alpha = 8; +#endif /* LIBPNG 1.5 */ + } + + // Swap ARGB to RGBA (normal PNG format) before saving on + // BigEndian machines + if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { + png_set_swap_alpha(png_ptr); + } + + // TQt==ARGB==Big(ARGB)==Little(BGRA) + if ( TQImage::systemByteOrder() == TQImage::LittleEndian ) { + png_set_bgr(png_ptr); + } + + if (off_x || off_y) { + png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL); + } + + if ( frames_written > 0 ) + png_set_sig_bytes(png_ptr, 8); + + if ( image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0 ) { + png_set_pHYs(png_ptr, info_ptr, + image.dotsPerMeterX(), image.dotsPerMeterY(), + PNG_RESOLUTION_METER); + } + +#ifndef TQT_NO_IMAGE_TEXT + // Write short texts early. + set_text(image,png_ptr,info_ptr,TRUE); +#endif + + png_write_info(png_ptr, info_ptr); + +#ifndef TQT_NO_IMAGE_TEXT + // Write long texts later. + set_text(image,png_ptr,info_ptr,FALSE); +#endif + + if ( image.depth() != 1 ) + png_set_packing(png_ptr); + + if ( image.depth() == 32 && !image.hasAlphaBuffer() ) + png_set_filler(png_ptr, 0, + TQImage::systemByteOrder() == TQImage::BigEndian ? + PNG_FILLER_BEFORE : PNG_FILLER_AFTER); + + if ( looping >= 0 && frames_written == 0 ) { + uchar data[13] = "NETSCAPE2.0"; + // 0123456789aBC + data[0xB] = looping%0x100; + data[0xC] = looping/0x100; + png_write_chunk(png_ptr, (png_byte*)"gIFx", data, 13); + } + if ( ms_delay >= 0 || disposal!=Unspecified ) { + uchar data[4]; + data[0] = disposal; + data[1] = 0; + data[2] = (ms_delay/10)/0x100; // hundredths + data[3] = (ms_delay/10)%0x100; + png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); + } + + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int color_type; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, + 0, 0, 0); + + uchar** jt = image.jumpTable(); + row_pointers=new png_bytep[height]; + uint y; + for (y=0; yioDevice()); + int quality = iio->quality(); + if ( quality >= 0 ) { + quality = TQMIN( quality, 100 ); + quality = (100-quality) * 9 / 91; // map [0,100] -> [9,0] + } + writer.setGamma(iio->gamma()); + bool ok = writer.writeImage( iio->image(), quality ); + iio->setStatus( ok ? 0 : -1 ); +} + +/*! + \class TQPNGImagePacker tqpngio.h + \brief The TQPNGImagePacker class creates well-compressed PNG animations. + + \ingroup images + \ingroup graphics + + By using transparency, TQPNGImagePacker allows you to build a PNG + image from a sequence of TQImages. + + Images are added using packImage(). +*/ + + +/*! + Creates an image packer that writes PNG data to IO device \a iod + using a \a storage_depth bit encoding (use 8 or 32, depending on + the desired quality and compression requirements). + + 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 + conversionflags to specify how you'd prefer this to happen. + + \sa TQt::ImageConversionFlags +*/ +TQPNGImagePacker::TQPNGImagePacker(TQIODevice* iod, int storage_depth, + int conversionflags) : + TQPNGImageWriter(iod), + depth(storage_depth), + convflags(conversionflags), + alignx(1) +{ +} + +/*! + Aligns pixel differences to \a x pixels. For example, using 8 can + improve playback on certain hardware. Normally the default of + 1-pixel alignment (i.e. no alignment) gives better compression and + performance. +*/ +void TQPNGImagePacker::setPixelAlignment(int x) +{ + alignx = x; +} + +/*! + Adds the image \a img to the PNG animation, analyzing the + differences between this and the previous image to improve + compression. +*/ +bool TQPNGImagePacker::packImage(const TQImage& img) +{ + TQImage image = img.convertDepth(32); + if ( previous.isNull() ) { + // First image + writeImage(image.convertDepth(depth,convflags)); + } else { + bool done; + int minx, maxx, miny, maxy; + int w = image.width(); + int h = image.height(); + + TQRgb** jt = (TQRgb**)image.jumpTable(); + TQRgb** pjt = (TQRgb**)previous.jumpTable(); + + // Find left edge of change + done = FALSE; + for (minx = 0; minx < w && !done; minx++) { + for (int ty = 0; ty < h; ty++) { + if ( jt[ty][minx] != pjt[ty][minx] ) { + done = TRUE; + break; + } + } + } + minx--; + + // Find right edge of change + done = FALSE; + for (maxx = w-1; maxx >= 0 && !done; maxx--) { + for (int ty = 0; ty < h; ty++) { + if ( jt[ty][maxx] != pjt[ty][maxx] ) { + done = TRUE; + break; + } + } + } + maxx++; + + // Find top edge of change + done = FALSE; + for (miny = 0; miny < h && !done; miny++) { + for (int tx = 0; tx < w; tx++) { + if ( jt[miny][tx] != pjt[miny][tx] ) { + done = TRUE; + break; + } + } + } + miny--; + + // Find right edge of change + done = FALSE; + for (maxy = h-1; maxy >= 0 && !done; maxy--) { + for (int tx = 0; tx < w; tx++) { + if ( jt[maxy][tx] != pjt[maxy][tx] ) { + done = TRUE; + break; + } + } + } + maxy++; + + if ( minx > maxx ) minx=maxx=0; + if ( miny > maxy ) miny=maxy=0; + + if ( alignx > 1 ) { + minx -= minx % alignx; + maxx = maxx - maxx % alignx + alignx - 1; + } + + int dw = maxx-minx+1; + int dh = maxy-miny+1; + + TQImage diff(dw, dh, 32); + + diff.setAlphaBuffer(TRUE); + int x, y; + if ( alignx < 1 ) + alignx = 1; + for (y = 0; y < dh; y++) { + TQRgb* li = (TQRgb*)image.scanLine(y+miny)+minx; + TQRgb* lp = (TQRgb*)previous.scanLine(y+miny)+minx; + TQRgb* ld = (TQRgb*)diff.scanLine(y); + if ( alignx ) { + for (x = 0; x < dw; x+=alignx) { + int i; + for (i=0; iinfo(png_ptr,info); +} + +static void +CALLBACK_CALL_TYPE row_callback(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) +{ + TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr); + that->row(png_ptr,new_row,row_num,pass); +} + +static void +CALLBACK_CALL_TYPE end_callback(png_structp png_ptr, png_infop info) +{ + TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr); + that->end(png_ptr,info); +} + +#if 0 +#ifdef PNG_USER_CHUNKS_SUPPORTED +static int +CALLBACK_CALL_TYPE user_chunk_callback(png_structp png_ptr, + png_unknown_chunkp chunk) +{ + TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr); + return that->user_chunk(png_ptr,chunk->data,chunk->size); +} +#endif +#endif + +#if defined(Q_C_CALLBACKS) +} +#endif + + +/*! + Constructs a TQPNGFormat object. +*/ +TQPNGFormat::TQPNGFormat() +{ + state = MovieStart; + first_frame = 1; + base_offx = 0; + base_offy = 0; + png_ptr = 0; + info_ptr = 0; +} + + +/*! + Destroys a TQPNGFormat object. +*/ +TQPNGFormat::~TQPNGFormat() +{ + if ( png_ptr ) + png_destroy_read_struct(&png_ptr, &info_ptr, 0); +} + + +/*! + This function decodes some data into image changes. + + Returns the number of bytes consumed. +*/ +int TQPNGFormat::decode(TQImage& img, TQImageConsumer* cons, + const uchar* buffer, int length) +{ + consumer = cons; + image = &img; + + if ( state != Inside ) { + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png_ptr) { + info_ptr = 0; + image = 0; + return -1; + } + + png_set_error_fn(png_ptr, 0, 0, qt_png_warning); + png_set_compression_level(png_ptr, 9); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + image = 0; + return -1; + } + +#if PNG_LIBPNG_VER>=10500 + if (setjmp(png_jmpbuf(png_ptr))) { +#else /* LIBPNG 1.5 */ + if (setjmp((png_ptr)->jmpbuf)) { +#endif /* LIBPNG 1.5 */ + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + image = 0; + return -1; + } + + png_set_progressive_read_fn(png_ptr, (void *)this, + info_callback, row_callback, end_callback); + +#ifdef PNG_USER_CHUNKS_SUPPORTED + // Can't do this yet. libpng has a crash bug with unknown (user) chunks. + // Warwick has sent them a patch. + // png_set_read_user_chunk_fn(png_ptr, 0, user_chunk_callback); + // png_set_keep_unknown_chunks(png_ptr, 2/*HANDLE_CHUNK_IF_SAFE*/, 0, 0); +#endif + + if ( state != MovieStart && *buffer != 0211 ) { + // Good, no signature - the preferred way to concat PNG images. + // Skip them. + png_set_sig_bytes(png_ptr, 8); + } + + state = Inside; + } + + if ( !png_ptr ) return 0; + +#if PNG_LIBPNG_VER>=10500 + if (setjmp(png_jmpbuf(png_ptr))) { +#else /* LIBPNG 1.5 */ + if (setjmp(png_ptr->jmpbuf)) { +#endif /* LIBPNG 1.5 */ + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + image = 0; + state = MovieStart; + return -1; + } + unused_data = 0; + png_process_data(png_ptr, info_ptr, (png_bytep)buffer, length); + int l = length - unused_data; + + // TODO: send incremental stuff to consumer (optional) + + if ( state != Inside ) { + if ( png_ptr ) + png_destroy_read_struct(&png_ptr, &info_ptr, 0); + } + + image = 0; + return l; +} + +void TQPNGFormat::info(png_structp png, png_infop) +{ + png_set_interlace_handling(png); + setup_qt(*image, png, info_ptr); +} + +void TQPNGFormat::row(png_structp png, png_bytep new_row, + png_uint_32 row_num, int) +{ + uchar* old_row = image->scanLine(row_num); + png_progressive_combine_row(png, old_row, new_row); +} + + +void TQPNGFormat::end(png_structp png, png_infop info) +{ + int offx = png_get_x_offset_pixels(png,info) - base_offx; + int offy = png_get_y_offset_pixels(png,info) - base_offy; + if ( first_frame ) { + base_offx = offx; + base_offy = offy; + first_frame = 0; + } + image->setOffset(TQPoint(offx,offy)); + image->setDotsPerMeterX(png_get_x_pixels_per_meter(png,info)); + image->setDotsPerMeterY(png_get_y_pixels_per_meter(png,info)); +#ifndef TQT_NO_IMAGE_TEXT + png_textp text_ptr; + int num_text=0; + png_get_text(png,info,&text_ptr,&num_text); + while (num_text--) { + image->setText(text_ptr->key,0,text_ptr->text); + text_ptr++; + } +#endif + TQRect r(0,0,image->width(),image->height()); + consumer->frameDone(TQPoint(offx,offy),r); + consumer->end(); + state = FrameStart; +#if PNG_LIBPNG_VER>=10500 + unused_data = png_process_data_pause(png, 0); +#else /* LIBPNG 1.5 */ + unused_data = (int)png->buffer_size; // Since libpng doesn't tell us +#endif /* LIBPNG 1.5 */ +} + +#ifdef PNG_USER_CHUNKS_SUPPORTED + +/* +#ifndef TQT_NO_IMAGE_TEXT +static bool skip(png_uint_32& max, png_bytep& data) +{ + while (*data) { + if ( !max ) return FALSE; + max--; + data++; + } + if ( !max ) return FALSE; + max--; + data++; // skip to after NUL + return TRUE; +} +#endif +*/ + +int TQPNGFormat::user_chunk(png_structp png, + png_bytep data, png_uint_32 length) +{ +#if 0 // NOT SUPPORTED: experimental PNG animation. + // tqDebug("Got %ld-byte %s chunk", length, png->chunk_name); + if ( 0==qstrcmp((char*)png->chunk_name, "gIFg") + && length == 4 ) { + + //TQPNGImageWriter::DisposalMethod disposal = + // (TQPNGImageWriter::DisposalMethod)data[0]; + // ### TODO: use the disposal method + int ms_delay = ((data[2] << 8) | data[3])*10; + consumer->setFramePeriod(ms_delay); + return 1; + } else if ( 0==qstrcmp((char*)png->chunk_name, "gIFx") + && length == 13 ) { + if ( tqstrncmp((char*)data,"NETSCAPE2.0",11)==0 ) { + int looping = (data[0xC]<<8)|data[0xB]; + consumer->setLooping(looping); + return 1; + } + } +#else + Q_UNUSED( png ) + Q_UNUSED( data ) + Q_UNUSED( length ) +#endif + +#ifndef TQT_NO_IMAGE_TEXT + /* + + libpng now supports this chunk. + + + if ( 0==qstrcmp((char*)png->chunk_name, "iTXt") && length>=6 ) { + const char* keyword = (const char*)data; + if ( !skip(length,data) ) return 0; + if ( length >= 4 ) { + char compression_flag = *data++; + char compression_method = *data++; + if ( compression_flag == compression_method ) { + // fool the compiler into thinking they're used + } + const char* lang = (const char*)data; + if ( !skip(length,data) ) return 0; + // const char* keyword_utf8 = (const char*)data; + if ( !skip(length,data) ) return 0; + const char* text_utf8 = (const char*)data; + if ( !skip(length,data) ) return 0; + TQString text = TQString::fromUtf8(text_utf8); + image->setText(keyword,lang[0] ? lang : 0,text); + return 1; + } + } + */ +#endif + + return 0; +} +#endif + + +static TQPNGFormatType* globalPngFormatTypeObject = 0; + +#endif // TQT_NO_ASYNC_IMAGE_IO + +static bool done = FALSE; +void qCleanupPngIO() +{ +#ifndef TQT_NO_ASYNC_IMAGE_IO + if ( globalPngFormatTypeObject ) { + delete globalPngFormatTypeObject; + globalPngFormatTypeObject = 0; + } +#endif + done = FALSE; +} + +void qInitPngIO() +{ + if ( !done ) { + done = TRUE; + TQImageIO::defineIOHandler( "PNG", "^.PNG\r", 0, read_png_image, + write_png_image); +#ifndef TQT_NO_ASYNC_IMAGE_IO + globalPngFormatTypeObject = new TQPNGFormatType; +#endif + tqAddPostRoutine( qCleanupPngIO ); + } +} + +void qt_zlib_compression_hack() +{ + compress(0,0,0,0); + uncompress(0,0,0,0); +} + +#endif // TQT_NO_IMAGEIO_PNG diff --git a/src/kernel/tqpngio.h b/src/kernel/tqpngio.h new file mode 100644 index 000000000..42c85c653 --- /dev/null +++ b/src/kernel/tqpngio.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Definition of PNG TQImage IOHandler +** +** Created : 970521 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPNGIO_H +#define TQPNGIO_H + +#ifndef QT_H +#include "tqimage.h" +#endif // QT_H + +#ifndef TQT_NO_IMAGEIO_PNG + +void qInitPngIO(); + +class TQIODevice; + +#ifndef Q_PNGEXPORT +#if !defined(QT_PLUGIN) +#define Q_PNGEXPORT TQ_EXPORT +#else +#define Q_PNGEXPORT +#endif +#endif + +class Q_PNGEXPORT TQPNGImageWriter { +public: + TQPNGImageWriter(TQIODevice*); + ~TQPNGImageWriter(); + + enum DisposalMethod { Unspecified, NoDisposal, RestoreBackground, RestoreImage }; + void setDisposalMethod(DisposalMethod); + void setLooping(int loops=0); // 0 == infinity + void setFrameDelay(int msecs); + void setGamma(float); + + bool writeImage(const TQImage& img, int x, int y); + bool writeImage(const TQImage& img, int quality, int x, int y); + bool writeImage(const TQImage& img) + { return writeImage(img, 0, 0); } + bool writeImage(const TQImage& img, int quality) + { return writeImage(img, quality, 0, 0); } + + TQIODevice* device() { return dev; } + +private: + TQIODevice* dev; + int frames_written; + DisposalMethod disposal; + int looping; + int ms_delay; + float gamma; +}; + +class Q_PNGEXPORT TQPNGImagePacker : public TQPNGImageWriter { +public: + TQPNGImagePacker(TQIODevice*, int depth, int convflags); + + void setPixelAlignment(int x); + bool packImage(const TQImage& img); + +private: + TQImage previous; + int depth; + int convflags; + int alignx; +}; + +#endif // TQT_NO_IMAGEIO_PNG + +#endif // TQPNGIO_H diff --git a/src/kernel/tqpoint.cpp b/src/kernel/tqpoint.cpp new file mode 100644 index 000000000..e9237521c --- /dev/null +++ b/src/kernel/tqpoint.cpp @@ -0,0 +1,443 @@ +/**************************************************************************** +** +** Implementation of TQPoint class +** +** Created : 931028 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqpoint.h" +#include "tqdatastream.h" + + +/*! + \class TQPoint tqpoint.h + \brief The TQPoint class defines a point in the plane. + + \ingroup images + \ingroup graphics + \mainclass + + A point is specified by an x coordinate and a y coordinate. + + The coordinate type is \c TQCOORD (a 32-bit integer). The minimum + value of \c TQCOORD is \c TQCOORD_MIN (-2147483648) and the maximum + value is \c TQCOORD_MAX (2147483647). + + The coordinates are accessed by the functions x() and y(); they + can be set by setX() and setY() or by the reference functions rx() + and ry(). + + Given a point \e p, the following statements are all equivalent: + \code + p.setX( p.x() + 1 ); + p += TQPoint( 1, 0 ); + p.rx()++; + \endcode + + A TQPoint can also be used as a vector. Addition and subtraction + of TQPoints are defined as for vectors (each component is added + separately). You can divide or multiply a TQPoint by an \c int or a + \c double. The function manhattanLength() gives an inexpensive + approximation of the length of the TQPoint interpreted as a vector. + + Example: + \code + //TQPoint oldPos is defined somewhere else + MyWidget::mouseMoveEvent( TQMouseEvent *e ) + { + TQPoint vector = e->pos() - oldPos; + if ( vector.manhattanLength() > 3 ) + ... //mouse has moved more than 3 pixels since oldPos + } + \endcode + + TQPoints can be compared for equality or inequality, and they can + be written to and read from a TQStream. + + \sa TQPointArray TQSize, TQRect +*/ + + +/***************************************************************************** + TQPoint member functions + *****************************************************************************/ + +/*! + \fn TQPoint::TQPoint() + + Constructs a point with coordinates (0, 0) (isNull() returns TRUE). +*/ + +/*! + \fn TQPoint::TQPoint( int xpos, int ypos ) + + Constructs a point with x value \a xpos and y value \a ypos. +*/ + +/*! + \fn bool TQPoint::isNull() const + + Returns TRUE if both the x value and the y value are 0; otherwise + returns FALSE. +*/ + +/*! + \fn int TQPoint::x() const + + Returns the x coordinate of the point. + + \sa setX() y() +*/ + +/*! + \fn int TQPoint::y() const + + Returns the y coordinate of the point. + + \sa setY() x() +*/ + +/*! + \fn void TQPoint::setX( int x ) + + Sets the x coordinate of the point to \a x. + + \sa x() setY() +*/ + +/*! + \fn void TQPoint::setY( int y ) + + Sets the y coordinate of the point to \a y. + + \sa y() setX() +*/ + + +/*! + \fn TQCOORD &TQPoint::rx() + + Returns a reference to the x coordinate of the point. + + Using a reference makes it possible to directly manipulate x. + + Example: + \code + TQPoint p( 1, 2 ); + p.rx()--; // p becomes (0, 2) + \endcode + + \sa ry() +*/ + +/*! + \fn TQCOORD &TQPoint::ry() + + Returns a reference to the y coordinate of the point. + + Using a reference makes it possible to directly manipulate y. + + Example: + \code + TQPoint p( 1, 2 ); + p.ry()++; // p becomes (1, 3) + \endcode + + \sa rx() +*/ + + +/*! + \fn TQPoint &TQPoint::operator+=( const TQPoint &p ) + + Adds point \a p to this point and returns a reference to this + point. + + Example: + \code + TQPoint p( 3, 7 ); + TQPoint q( -1, 4 ); + p += q; // p becomes (2,11) + \endcode +*/ + +/*! + \fn TQPoint &TQPoint::operator-=( const TQPoint &p ) + + Subtracts point \a p from this point and returns a reference to + this point. + + Example: + \code + TQPoint p( 3, 7 ); + TQPoint q( -1, 4 ); + p -= q; // p becomes (4,3) + \endcode +*/ + +/*! + \fn TQPoint &TQPoint::operator*=( int c ) + + Multiplies this point's x and y by \a c, and returns a reference + to this point. + + Example: + \code + TQPoint p( -1, 4 ); + p *= 2; // p becomes (-2,8) + \endcode +*/ + +/*! + \overload TQPoint &TQPoint::operator*=( double c ) + + Multiplies this point's x and y by \a c, and returns a reference + to this point. + + Example: + \code + TQPoint p( -1, 4 ); + p *= 2.5; // p becomes (-3,10) + \endcode + + Note that the result is truncated because points are held as + integers. +*/ + + +/*! + \fn bool operator==( const TQPoint &p1, const TQPoint &p2 ) + + \relates TQPoint + + Returns TRUE if \a p1 and \a p2 are equal; otherwise returns FALSE. +*/ + +/*! + \fn bool operator!=( const TQPoint &p1, const TQPoint &p2 ) + + \relates TQPoint + + Returns TRUE if \a p1 and \a p2 are not equal; otherwise returns FALSE. +*/ + +/*! + \fn const TQPoint operator+( const TQPoint &p1, const TQPoint &p2 ) + + \relates TQPoint + + Returns the sum of \a p1 and \a p2; each component is added separately. +*/ + +/*! + \fn const TQPoint operator-( const TQPoint &p1, const TQPoint &p2 ) + + \relates TQPoint + + Returns \a p2 subtracted from \a p1; each component is subtracted + separately. +*/ + +/*! + \fn const TQPoint operator*( const TQPoint &p, int c ) + + \relates TQPoint + + Returns the TQPoint formed by multiplying both components of \a p + by \a c. +*/ + +/*! + \overload const TQPoint operator*( int c, const TQPoint &p ) + + \relates TQPoint + + Returns the TQPoint formed by multiplying both components of \a p + by \a c. +*/ + +/*! + \overload const TQPoint operator*( const TQPoint &p, double c ) + + \relates TQPoint + + Returns the TQPoint formed by multiplying both components of \a p + by \a c. + + Note that the result is truncated because points are held as + integers. +*/ + +/*! + \overload const TQPoint operator*( double c, const TQPoint &p ) + + \relates TQPoint + + Returns the TQPoint formed by multiplying both components of \a p + by \a c. + + Note that the result is truncated because points are held as + integers. +*/ + +/*! + \overload const TQPoint operator-( const TQPoint &p ) + + \relates TQPoint + + Returns the TQPoint formed by changing the sign of both components + of \a p, equivalent to \c{TQPoint(0,0) - p}. +*/ + +/*! + \fn TQPoint &TQPoint::operator/=( int c ) + + Divides both x and y by \a c, and returns a reference to this + point. + + Example: + \code + TQPoint p( -2, 8 ); + p /= 2; // p becomes (-1,4) + \endcode +*/ + +/*! + \overload TQPoint &TQPoint::operator/=( double c ) + + Divides both x and y by \a c, and returns a reference to this + point. + + Example: + \code + TQPoint p( -3, 10 ); + p /= 2.5; // p becomes (-1,4) + \endcode + + Note that the result is truncated because points are held as + integers. +*/ + +/*! + \fn const TQPoint operator/( const TQPoint &p, int c ) + + \relates TQPoint + + Returns the TQPoint formed by dividing both components of \a p by + \a c. +*/ + +/*! + \overload const TQPoint operator/( const TQPoint &p, double c ) + + \relates TQPoint + + Returns the TQPoint formed by dividing both components of \a p + by \a c. + + Note that the result is truncated because points are held as + integers. +*/ + + +void TQPoint::warningDivByZero() +{ +#if defined(QT_CHECK_MATH) + tqWarning( "TQPoint: Division by zero error" ); +#endif +} + + +/***************************************************************************** + TQPoint stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +/*! + \relates TQPoint + + Writes point \a p to the stream \a s and returns a reference to + the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQPoint &p ) +{ + if ( s.version() == 1 ) + s << (TQ_INT16)p.x() << (TQ_INT16)p.y(); + else + s << (TQ_INT32)p.x() << (TQ_INT32)p.y(); + return s; +} + +/*! + \relates TQPoint + + Reads a TQPoint from the stream \a s into point \a p and returns a + reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQPoint &p ) +{ + if ( s.version() == 1 ) { + TQ_INT16 x, y; + s >> x; p.rx() = x; + s >> y; p.ry() = y; + } + else { + TQ_INT32 x, y; + s >> x; p.rx() = x; + s >> y; p.ry() = y; + } + return s; +} +#endif // TQT_NO_DATASTREAM +/*! + Returns the sum of the absolute values of x() and y(), + traditionally known as the "Manhattan length" of the vector from + the origin to the point. The tradition arises because such + distances apply to travelers who can only travel on a rectangular + grid, like the streets of Manhattan. + + This is a useful, and quick to calculate, approximation to the + true length: sqrt(pow(x(),2)+pow(y(),2)). +*/ +int TQPoint::manhattanLength() const +{ + return TQABS(x())+TQABS(y()); +} diff --git a/src/kernel/tqpoint.h b/src/kernel/tqpoint.h new file mode 100644 index 000000000..c38e379b2 --- /dev/null +++ b/src/kernel/tqpoint.h @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Definition of TQPoint class +** +** Created : 931028 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPOINT_H +#define TQPOINT_H + +#ifndef QT_H +#include "ntqwindowdefs.h" +#endif // QT_H + + +class TQ_EXPORT TQPoint +{ +public: + TQPoint(); + TQPoint( int xpos, int ypos ); + + bool isNull() const; + + int x() const; + int y() const; + void setX( int x ); + void setY( int y ); + + int manhattanLength() const; + + TQCOORD &rx(); + TQCOORD &ry(); + + TQPoint &operator+=( const TQPoint &p ); + TQPoint &operator-=( const TQPoint &p ); + TQPoint &operator*=( int c ); + TQPoint &operator*=( double c ); + TQPoint &operator/=( int c ); + TQPoint &operator/=( double c ); + + friend inline bool operator==( const TQPoint &, const TQPoint & ); + friend inline bool operator!=( const TQPoint &, const TQPoint & ); + friend inline const TQPoint operator+( const TQPoint &, const TQPoint & ); + friend inline const TQPoint operator-( const TQPoint &, const TQPoint & ); + friend inline const TQPoint operator*( const TQPoint &, int ); + friend inline const TQPoint operator*( int, const TQPoint & ); + friend inline const TQPoint operator*( const TQPoint &, double ); + friend inline const TQPoint operator*( double, const TQPoint & ); + friend inline const TQPoint operator-( const TQPoint & ); + friend inline const TQPoint operator/( const TQPoint &, int ); + friend inline const TQPoint operator/( const TQPoint &, double ); + +private: + static void warningDivByZero(); + +#if defined(Q_OS_MAC) + TQCOORD yp; + TQCOORD xp; +#else + TQCOORD xp; + TQCOORD yp; +#endif +}; + + +/***************************************************************************** + TQPoint stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPoint & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPoint & ); +#endif + +/***************************************************************************** + TQPoint inline functions + *****************************************************************************/ + +inline TQPoint::TQPoint() +{ xp=0; yp=0; } + +inline TQPoint::TQPoint( int xpos, int ypos ) +{ xp=(TQCOORD)xpos; yp=(TQCOORD)ypos; } + +inline bool TQPoint::isNull() const +{ return xp == 0 && yp == 0; } + +inline int TQPoint::x() const +{ return xp; } + +inline int TQPoint::y() const +{ return yp; } + +inline void TQPoint::setX( int x ) +{ xp = (TQCOORD)x; } + +inline void TQPoint::setY( int y ) +{ yp = (TQCOORD)y; } + +inline TQCOORD &TQPoint::rx() +{ return xp; } + +inline TQCOORD &TQPoint::ry() +{ return yp; } + +inline TQPoint &TQPoint::operator+=( const TQPoint &p ) +{ xp+=p.xp; yp+=p.yp; return *this; } + +inline TQPoint &TQPoint::operator-=( const TQPoint &p ) +{ xp-=p.xp; yp-=p.yp; return *this; } + +inline TQPoint &TQPoint::operator*=( int c ) +{ xp*=(TQCOORD)c; yp*=(TQCOORD)c; return *this; } + +inline TQPoint &TQPoint::operator*=( double c ) +{ xp=(TQCOORD)(xp*c); yp=(TQCOORD)(yp*c); return *this; } + +inline bool operator==( const TQPoint &p1, const TQPoint &p2 ) +{ return p1.xp == p2.xp && p1.yp == p2.yp; } + +inline bool operator!=( const TQPoint &p1, const TQPoint &p2 ) +{ return p1.xp != p2.xp || p1.yp != p2.yp; } + +inline const TQPoint operator+( const TQPoint &p1, const TQPoint &p2 ) +{ return TQPoint(p1.xp+p2.xp, p1.yp+p2.yp); } + +inline const TQPoint operator-( const TQPoint &p1, const TQPoint &p2 ) +{ return TQPoint(p1.xp-p2.xp, p1.yp-p2.yp); } + +inline const TQPoint operator*( const TQPoint &p, int c ) +{ return TQPoint(p.xp*c, p.yp*c); } + +inline const TQPoint operator*( int c, const TQPoint &p ) +{ return TQPoint(p.xp*c, p.yp*c); } + +inline const TQPoint operator*( const TQPoint &p, double c ) +{ return TQPoint((TQCOORD)(p.xp*c), (TQCOORD)(p.yp*c)); } + +inline const TQPoint operator*( double c, const TQPoint &p ) +{ return TQPoint((TQCOORD)(p.xp*c), (TQCOORD)(p.yp*c)); } + +inline const TQPoint operator-( const TQPoint &p ) +{ return TQPoint(-p.xp, -p.yp); } + +inline TQPoint &TQPoint::operator/=( int c ) +{ +#if defined(QT_CHECK_MATH) + if ( c == 0 ) + warningDivByZero(); +#endif + xp/=(TQCOORD)c; + yp/=(TQCOORD)c; + return *this; +} + +inline TQPoint &TQPoint::operator/=( double c ) +{ +#if defined(QT_CHECK_MATH) + if ( c == 0.0 ) + warningDivByZero(); +#endif + xp=(TQCOORD)(xp/c); + yp=(TQCOORD)(yp/c); + return *this; +} + +inline const TQPoint operator/( const TQPoint &p, int c ) +{ +#if defined(QT_CHECK_MATH) + if ( c == 0 ) + TQPoint::warningDivByZero(); +#endif + return TQPoint(p.xp/c, p.yp/c); +} + +inline const TQPoint operator/( const TQPoint &p, double c ) +{ +#if defined(QT_CHECK_MATH) + if ( c == 0.0 ) + TQPoint::warningDivByZero(); +#endif + return TQPoint((TQCOORD)(p.xp/c), (TQCOORD)(p.yp/c)); +} + +#define Q_DEFINED_QPOINT +#include "ntqwinexport.h" +#endif // TQPOINT_H diff --git a/src/kernel/tqpointarray.cpp b/src/kernel/tqpointarray.cpp new file mode 100644 index 000000000..9d7bafccc --- /dev/null +++ b/src/kernel/tqpointarray.cpp @@ -0,0 +1,1109 @@ +/**************************************************************************** +** +** Implementation of TQPointArray class +** +** Created : 940213 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqpointarray.h" +#include "tqrect.h" +#include "tqdatastream.h" +#include "tqwmatrix.h" +#include + +const double Q_PI = 3.14159265358979323846; // pi // one more useful comment + + +/*! + \class TQPointArray tqpointarray.h + \brief The TQPointArray class provides an array of points. + + \ingroup images + \ingroup graphics + \ingroup shared + + A TQPointArray is an array of TQPoint objects. In addition to the + functions provided by TQMemArray, TQPointArray provides some + point-specific functions. + + For convenient reading and writing of the point data use + setPoints(), putPoints(), point(), and setPoint(). + + For geometry operations use boundingRect() and translate(). There + is also the TQWMatrix::map() function for more general + transformations of TQPointArrays. You can also create arcs and + ellipses with makeArc() and makeEllipse(). + + Among others, TQPointArray is used by TQPainter::drawLineSegments(), + TQPainter::drawPolyline(), TQPainter::drawPolygon() and + TQPainter::drawCubicBezier(). + + Note that because this class is a TQMemArray, copying an array and + modifying the copy modifies the original as well, i.e. a shallow + copy. If you need a deep copy use copy() or detach(), for example: + + \code + void drawGiraffe( const TQPointArray & r, TQPainter * p ) + { + TQPointArray tmp = r; + tmp.detach(); + // some code that modifies tmp + p->drawPoints( tmp ); + } + \endcode + + If you forget the tmp.detach(), the const array will be modified. + + \sa TQPainter TQWMatrix TQMemArray +*/ + + +/***************************************************************************** + TQPointArray member functions + *****************************************************************************/ + +/*! + \fn TQPointArray::TQPointArray() + + Constructs a null point array. + + \sa isNull() +*/ + +/*! + \fn TQPointArray::TQPointArray( int size ) + + Constructs a point array with room for \a size points. Makes a + null array if \a size == 0. + + \sa resize(), isNull() +*/ + +/*! + \fn TQPointArray::TQPointArray( const TQPointArray &a ) + + Constructs a shallow copy of the point array \a a. + + \sa copy() detach() +*/ + +/*! + Constructs a point array from the rectangle \a r. + + If \a closed is FALSE, then the point array just contains the + following four points in the listed order: r.topLeft(), + r.topRight(), r.bottomRight() and r.bottomLeft(). + + If \a closed is TRUE, then a fifth point is set to r.topLeft(). +*/ + +TQPointArray::TQPointArray( const TQRect &r, bool closed ) +{ + setPoints( 4, r.left(), r.top(), + r.right(), r.top(), + r.right(), r.bottom(), + r.left(), r.bottom() ); + if ( closed ) { + resize( 5 ); + setPoint( 4, r.left(), r.top() ); + } +} + +/*! + \internal + Constructs a point array with \a nPoints points, taken from the + \a points array. + + Equivalent to setPoints(nPoints, points). +*/ + +TQPointArray::TQPointArray( int nPoints, const TQCOORD *points ) +{ + setPoints( nPoints, points ); +} + + +/*! + \fn TQPointArray::~TQPointArray() + + Destroys the point array. +*/ + + +/*! + \fn TQPointArray &TQPointArray::operator=( const TQPointArray &a ) + + Assigns a shallow copy of \a a to this point array and returns a + reference to this point array. + + Equivalent to assign(a). + + \sa copy() detach() +*/ + +/*! + \fn TQPointArray TQPointArray::copy() const + + Creates a deep copy of the array. + + \sa detach() +*/ + + + +/*! + Translates all points in the array by \a (dx, dy). +*/ + +void TQPointArray::translate( int dx, int dy ) +{ + TQPoint *p = data(); + int i = size(); + TQPoint pt( dx, dy ); + while ( i-- ) { + *p += pt; + p++; + } +} + + +/*! + Reads the coordinates of the point at position \a index within the + array and writes them into \a *x and \a *y. +*/ + +void TQPointArray::point( uint index, int *x, int *y ) const +{ + TQPoint p = TQMemArray::at( index ); + if ( x ) + *x = (int)p.x(); + if ( y ) + *y = (int)p.y(); +} + +/*! + \overload + + Returns the point at position \a index within the array. +*/ + +TQPoint TQPointArray::point( uint index ) const +{ // #### index out of bounds + return TQMemArray::at( index ); +} + +/*! + \fn void TQPointArray::setPoint( uint i, const TQPoint &p ) + + \overload + + Sets the point at array index \a i to \a p. +*/ + +/*! + Sets the point at position \a index in the array to \a (x, y). +*/ + +void TQPointArray::setPoint( uint index, int x, int y ) +{ // #### index out of bounds + TQMemArray::at( index ) = TQPoint( x, y ); +} + +/*! + \internal + Resizes the array to \a nPoints and sets the points in the array to + the values taken from \a points. + + Returns TRUE if successful, or FALSE if the array could not be + resized (normally due to lack of memory). + + The example code creates an array with two points (1,2) and (3,4): + \code + static TQCOORD points[] = { 1,2, 3,4 }; + TQPointArray a; + a.setPoints( 2, points ); + \endcode + + \sa resize(), putPoints() +*/ + +bool TQPointArray::setPoints( int nPoints, const TQCOORD *points ) +{ + if ( !resize(nPoints) ) + return FALSE; + int i = 0; + while ( nPoints-- ) { // make array of points + setPoint( i++, *points, *(points+1) ); + points++; + points++; + } + return TRUE; +} + +/*! + \overload + + Resizes the array to \a nPoints and sets the points in the array + to the values taken from the variable argument list. + + Returns TRUE if successful, or FALSE if the array could not be + resized (typically due to lack of memory). + + The example code creates an array with two points (1,2) and (3,4): + + \code + TQPointArray a; + a.setPoints( 2, 1,2, 3,4 ); + \endcode + + The points are given as a sequence of integers, starting with \a + firstx then \a firsty, and so on. + + \sa resize(), putPoints() +*/ + +bool TQPointArray::setPoints( int nPoints, int firstx, int firsty, ... ) +{ + va_list ap; + if ( !resize(nPoints) ) + return FALSE; + setPoint( 0, firstx, firsty ); // set first point + int i = 1, x, y; + nPoints--; + va_start( ap, firsty ); + while ( nPoints-- ) { + x = va_arg( ap, int ); + y = va_arg( ap, int ); + setPoint( i++, x, y ); + } + va_end( ap ); + return TRUE; +} + +/*! \overload + \internal + Copies \a nPoints points from the \a points coord array into + this point array, and resizes the point array if + \c{index+nPoints} exceeds the size of the array. + + Returns TRUE if successful, or FALSE if the array could not be + resized (typically due to lack of memory). + +*/ + +bool TQPointArray::putPoints( int index, int nPoints, const TQCOORD *points ) +{ + if ( index + nPoints > (int)size() ) { // extend array + if ( !resize( index + nPoints ) ) + return FALSE; + } + int i = index; + while ( nPoints-- ) { // make array of points + setPoint( i++, *points, *(points+1) ); + points++; + points++; + } + return TRUE; +} + +/*! + Copies \a nPoints points from the variable argument list into this + point array from position \a index, and resizes the point array if + \c{index+nPoints} exceeds the size of the array. + + Returns TRUE if successful, or FALSE if the array could not be + resized (typically due to lack of memory). + + The example code creates an array with three points (4,5), (6,7) + and (8,9), by expanding the array from 1 to 3 points: + + \code + TQPointArray a( 1 ); + a[0] = TQPoint( 4, 5 ); + a.putPoints( 1, 2, 6,7, 8,9 ); // index == 1, points == 2 + \endcode + + This has the same result, but here putPoints overwrites rather + than extends: + \code + TQPointArray a( 3 ); + a.putPoints( 0, 3, 4,5, 0,0, 8,9 ); + a.putPoints( 1, 1, 6,7 ); + \endcode + + The points are given as a sequence of integers, starting with \a + firstx then \a firsty, and so on. + + \sa resize() +*/ + +bool TQPointArray::putPoints( int index, int nPoints, int firstx, int firsty, + ... ) +{ + va_list ap; + if ( index + nPoints > (int)size() ) { // extend array + if ( !resize(index + nPoints) ) + return FALSE; + } + if ( nPoints <= 0 ) + return TRUE; + setPoint( index, firstx, firsty ); // set first point + int i = index + 1, x, y; + nPoints--; + va_start( ap, firsty ); + while ( nPoints-- ) { + x = va_arg( ap, int ); + y = va_arg( ap, int ); + setPoint( i++, x, y ); + } + va_end( ap ); + return TRUE; +} + + +/*! + \overload + + This version of the function copies \a nPoints from \a from into + this array, starting at \a index in this array and \a fromIndex in + \a from. \a fromIndex is 0 by default. + + \code + TQPointArray a; + a.putPoints( 0, 3, 1,2, 0,0, 5,6 ); + // a is now the three-point array ( 1,2, 0,0, 5,6 ); + TQPointArray b; + b.putPoints( 0, 3, 4,4, 5,5, 6,6 ); + // b is now ( 4,4, 5,5, 6,6 ); + a.putPoints( 2, 3, b ); + // a is now ( 1,2, 0,0, 4,4, 5,5, 6,6 ); + \endcode +*/ + +bool TQPointArray::putPoints( int index, int nPoints, + const TQPointArray & from, int fromIndex ) +{ + if ( index + nPoints > (int)size() ) { // extend array + if ( !resize(index + nPoints) ) + return FALSE; + } + if ( nPoints <= 0 ) + return TRUE; + int n = 0; + while( n < nPoints ) { + setPoint( index+n, from[fromIndex+n] ); + n++; + } + return TRUE; +} + + +/*! + Returns the bounding rectangle of the points in the array, or + TQRect(0,0,0,0) if the array is empty. +*/ + +TQRect TQPointArray::boundingRect() const +{ + if ( isEmpty() ) + return TQRect( 0, 0, 0, 0 ); // null rectangle + TQPoint *pd = data(); + int minx, maxx, miny, maxy; + minx = maxx = pd->x(); + miny = maxy = pd->y(); + pd++; + for ( int i=1; i<(int)size(); i++ ) { // find min+max x and y + if ( pd->x() < minx ) + minx = pd->x(); + else if ( pd->x() > maxx ) + maxx = pd->x(); + if ( pd->y() < miny ) + miny = pd->y(); + else if ( pd->y() > maxy ) + maxy = pd->y(); + pd++; + } + return TQRect( TQPoint(minx,miny), TQPoint(maxx,maxy) ); +} + + +static inline int fix_angle( int a ) +{ + if ( a > 16*360 ) + a %= 16*360; + else if ( a < -16*360 ) { + a = -( (-a) % (16*360) ); + } + return a; +} + +/*! + Sets the points of the array to those describing an arc of an + ellipse with size, width \a w by height \a h, and position (\a x, + \a y), starting from angle \a a1 and spanning by angle \a a2. The + resulting array has sufficient resolution for pixel accuracy (see + the overloaded function which takes an additional TQWMatrix + parameter). + + Angles are specified in 16ths of a degree, i.e. a full circle + equals 5760 (16*360). Positive values mean counter-clockwise, + whereas negative values mean the clockwise direction. Zero degrees + is at the 3 o'clock position. + + See the \link tqcanvasellipse.html#anglediagram angle diagram\endlink. +*/ + +void TQPointArray::makeArc( int x, int y, int w, int h, int a1, int a2 ) +{ +#if !defined(QT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS) + TQWMatrix unit; + makeArc(x,y,w,h,a1,a2,unit); +#else + a1 = fix_angle( a1 ); + if ( a1 < 0 ) + a1 += 16*360; + a2 = fix_angle( a2 ); + int a3 = a2 > 0 ? a2 : -a2; // abs angle + makeEllipse( x, y, w, h ); + int npts = a3*size()/(16*360); // # points in arc array + TQPointArray a(npts); + int i = a1*size()/(16*360); + int j = 0; + if ( a2 > 0 ) { + while ( npts-- ) { + if ( i >= (int)size() ) // wrap index + i = 0; + a.TQMemArray::at( j++ ) = TQMemArray::at( i++ ); + } + } else { + while ( npts-- ) { + if ( i < 0 ) // wrap index + i = (int)size()-1; + a.TQMemArray::at( j++ ) = TQMemArray::at( i-- ); + } + } + *this = a; + return; +#endif +} + +#ifndef TQT_NO_TRANSFORMATIONS +// Based upon: +// parelarc.c from Graphics Gems III +// VanAken / Simar, "A Parametric Elliptical Arc Algorithm" +// +static void +qtr_elips(TQPointArray& a, int off, double dxP, double dyP, double dxQ, double dyQ, double dxK, double dyK, int m) +{ +#define PIV2 102944 /* fixed point PI/2 */ +#define TWOPI 411775 /* fixed point 2*PI */ +#define HALF 32768 /* fixed point 1/2 */ + + int xP, yP, xQ, yQ, xK, yK; + xP = int(dxP * 65536.0); yP = int(dyP * 65536.0); + xQ = int(dxQ * 65536.0); yQ = int(dyQ * 65536.0); + xK = int(dxK * 65536.0); yK = int(dyK * 65536.0); + + int i; + int vx, ux, vy, uy, xJ, yJ; + + vx = xK - xQ; /* displacements from center */ + ux = xK - xP; + vy = yK - yQ; + uy = yK - yP; + xJ = xP - vx + HALF; /* center of ellipse J */ + yJ = yP - vy + HALF; + + int r; + ux -= (r = ux >> (2*m + 3)); /* cancel 2nd-order error */ + ux -= (r >>= (2*m + 4)); /* cancel 4th-order error */ + ux -= r >> (2*m + 3); /* cancel 6th-order error */ + ux += vx >> (m + 1); /* cancel 1st-order error */ + uy -= (r = uy >> (2*m + 3)); /* cancel 2nd-order error */ + uy -= (r >>= (2*m + 4)); /* cancel 4th-order error */ + uy -= r >> (2*m + 3); /* cancel 6th-order error */ + uy += vy >> (m + 1); /* cancel 1st-order error */ + + const int qn = a.size()/4; + for (i = 0; i < qn; i++) { + a[off+i] = TQPoint((xJ + vx) >> 16, (yJ + vy) >> 16); + ux -= vx >> m; + vx += ux >> m; + uy -= vy >> m; + vy += uy >> m; + } + +#undef PIV2 +#undef TWOPI +#undef HALF +} + + +/*! + \overload + + Sets the points of the array to those describing an arc of an + ellipse with width \a w and height \a h and position (\a x, \a y), + starting from angle \a a1, and spanning angle by \a a2, and + transformed by the matrix \a xf. The resulting array has + sufficient resolution for pixel accuracy. + + Angles are specified in 16ths of a degree, i.e. a full circle + equals 5760 (16*360). Positive values mean counter-clockwise, + whereas negative values mean the clockwise direction. Zero degrees + is at the 3 o'clock position. + + See the \link tqcanvasellipse.html#anglediagram angle diagram\endlink. +*/ +void TQPointArray::makeArc( int x, int y, int w, int h, + int a1, int a2, + const TQWMatrix& xf ) +{ +#define PIV2 102944 /* fixed point PI/2 */ + if ( --w < 0 || --h < 0 || !a2 ) { + resize( 0 ); + return; + } + + bool rev = a2 < 0; + if ( rev ) { + a1 += a2; + a2 = -a2; + } + a1 = fix_angle( a1 ); + if ( a1 < 0 ) + a1 += 16*360; + a2 = fix_angle( a2 ); + + bool arc = a1 != 0 || a2 != 360*16 || rev; + + double xP, yP, xQ, yQ, xK, yK; + + xf.map(x+w, y+h/2.0, &xP, &yP); + xf.map(x+w/2.0, y, &xQ, &yQ); + xf.map(x+w, y, &xK, &yK); + + int m = 3; + int max; + int q = int(TQMAX(TQABS(xP-xQ),TQABS(yP-yQ))); + if ( arc ) + q *= 2; + do { + m++; + max = 4*(1 + (PIV2 >> (16 - m)) ); + } while (max < q && m < 16); // 16 limits memory usage on HUGE arcs + + double inc = 1.0/(1<> (16 - m)); + resize(qn*4); + + qtr_elips(*this, 0, xP, yP, xQ, yQ, xK, yK, m); + xP = xQ; yP = yQ; + xf.map(x, y+h/2.0, &xQ, &yQ); + xf.map(x, y, &xK, &yK); + qtr_elips(*this, qn, xP, yP, xQ, yQ, xK, yK, m); + xP = xQ; yP = yQ; + xf.map(x+w/2.0, y+h, &xQ, &yQ); + xf.map(x, y+h, &xK, &yK); + qtr_elips(*this, qn*2, xP, yP, xQ, yQ, xK, yK, m); + xP = xQ; yP = yQ; + xf.map(x+w, y+h/2.0, &xQ, &yQ); + xf.map(x+w, y+h, &xK, &yK); + qtr_elips(*this, qn*3, xP, yP, xQ, yQ, xK, yK, m); + + int n = size(); + + if ( arc ) { + double da1 = double(a1)*Q_PI / (360*8); + double da3 = double(a2+a1)*Q_PI / (360*8); + int i = int(da1/inc+0.5); + int l = int(da3/inc+0.5); + int k = (l-i)+1; + TQPointArray r(k); + int j = 0; + + if ( rev ) { + while ( k-- ) + r[j++] = at((i+k)%n); + } else { + while ( j < k ) { + r[j] = at((i+j)%n); + j++; + } + } + *this = r; + } +#undef PIV2 +} + +#endif // TQT_NO_TRANSFORMATIONS + +/*! + Sets the points of the array to those describing an ellipse with + size, width \a w by height \a h, and position (\a x, \a y). + + The returned array has sufficient resolution for use as pixels. +*/ +void TQPointArray::makeEllipse( int x, int y, int w, int h ) +{ // midpoint, 1/4 ellipse +#if !defined(QT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS) + TQWMatrix unit; + makeArc(x,y,w,h,0,360*16,unit); + return; +#else + if ( w <= 0 || h <= 0 ) { + if ( w == 0 || h == 0 ) { + resize( 0 ); + return; + } + if ( w < 0 ) { // negative width + w = -w; + x -= w; + } + if ( h < 0 ) { // negative height + h = -h; + y -= h; + } + } + int s = (w+h+2)/2; // max size of xx,yy array + int *px = new int[s]; // 1/4th of ellipse + int *py = new int[s]; + int xx, yy, i=0; + double d1, d2; + double a2=(w/2)*(w/2), b2=(h/2)*(h/2); + xx = 0; + yy = int(h/2); + d1 = b2 - a2*(h/2) + 0.25*a2; + px[i] = xx; + py[i] = yy; + i++; + while ( a2*(yy-0.5) > b2*(xx+0.5) ) { // region 1 + if ( d1 < 0 ) { + d1 = d1 + b2*(3.0+2*xx); + xx++; + } else { + d1 = d1 + b2*(3.0+2*xx) + 2.0*a2*(1-yy); + xx++; + yy--; + } + px[i] = xx; + py[i] = yy; + i++; + } + d2 = b2*(xx+0.5)*(xx+0.5) + a2*(yy-1)*(yy-1) - a2*b2; + while ( yy > 0 ) { // region 2 + if ( d2 < 0 ) { + d2 = d2 + 2.0*b2*(xx+1) + a2*(3-2*yy); + xx++; + yy--; + } else { + d2 = d2 + a2*(3-2*yy); + yy--; + } + px[i] = xx; + py[i] = yy; + i++; + } + s = i; + resize( 4*s ); // make full point array + x += w/2; + y += h/2; + for ( i=0; i + * 1 if T is on the open ray ending at P: <--P + * 2 if T is on the closed interior along: P--Q + * 3 if T is on the open ray beginning at Q: Q--> + * + * Example: consider the line P = (3,2), Q = (17,7). A plot + * of the test points T(x,y) (with 0 mapped onto '.') yields: + * + * 8| . . . . . . . . . . . . . . . . . 3 3 + * Y 7| . . . . . . . . . . . . . . 2 2 Q 3 3 Q = 2 + * 6| . . . . . . . . . . . 2 2 2 2 2 . . . + * a 5| . . . . . . . . 2 2 2 2 2 2 . . . . . + * x 4| . . . . . 2 2 2 2 2 2 . . . . . . . . + * i 3| . . . 2 2 2 2 2 . . . . . . . . . . . + * s 2| 1 1 P 2 2 . . . . . . . . . . . . . . P = 2 + * 1| 1 1 . . . . . . . . . . . . . . . . . + * +-------------------------------------- + * 1 2 3 4 5 X-axis 10 15 19 + * + * Point-Line distance is normalized with the Infinity Norm + * avoiding square-root code and tightening the test vs the + * Manhattan Norm. All math is done on the field of integers. + * The latter replaces the initial ">= MAX(...)" test with + * "> (ABS(qx-px) + ABS(qy-py))" loosening both inequality + * and norm, yielding a broader target line for selection. + * The tightest test is employed here for best discrimination + * in merging collinear (to grid coordinates) vertex chains + * into a larger, spanning vectors within the Lemming editor. + */ + + // if all points are coincident, return condition 2 (on line) + if(q[0]==p[0] && q[1]==p[1] && q[0]==t[0] && q[1]==t[1]) { + return 2; + } + + if ( TQABS((q[1]-p[1])*(t[0]-p[0])-(t[1]-p[1])*(q[0]-p[0])) >= + (TQMAX(TQABS(q[0]-p[0]), TQABS(q[1]-p[1])))) return 0; + + if (((q[0] maxsize / 2 ) + { + // This never happens in practice. + + if ( accsize >= maxsize-4 ) + return; + // Running out of space - approximate by a line. + acc[accsize++] = ctrl[0]; + acc[accsize++] = ctrl[1]; + acc[accsize++] = ctrl[6]; + acc[accsize++] = ctrl[7]; + return; + } + + //intersects: + double l[8]; + double r[8]; + split( ctrl, l, r); + + // convert to integers for line condition check + int c0[2]; c0[0] = int(ctrl[0]); c0[1] = int(ctrl[1]); + int c1[2]; c1[0] = int(ctrl[2]); c1[1] = int(ctrl[3]); + int c2[2]; c2[0] = int(ctrl[4]); c2[1] = int(ctrl[5]); + int c3[2]; c3[0] = int(ctrl[6]); c3[1] = int(ctrl[7]); + + // #### Duplication needed? + if ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1 + && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1 + && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) + { + // Approximate by one line. + // Dont need to write last pt as it is the same as first pt + // on the next segment + acc[accsize++] = l[0]; + acc[accsize++] = l[1]; + return; + } + + if ( ( pnt_on_line( c0, c3, c1 ) == 2 && pnt_on_line( c0, c3, c2 ) == 2 ) + || ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1 + && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1 + && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) ) + { + // Approximate by one line. + // Dont need to write last pt as it is the same as first pt + // on the next segment + acc[accsize++] = l[0]; + acc[accsize++] = l[1]; + return; + } + + // Too big and too curved - recusively subdivide. + polygonizeTQBezier( acc, accsize, l, maxsize ); + polygonizeTQBezier( acc, accsize, r, maxsize ); +} + +/*! + Returns the Bezier points for the four control points in this + array. +*/ + +TQPointArray TQPointArray::cubicBezier() const +{ +#ifdef USE_SIMPLE_QBEZIER_CODE + if ( size() != 4 ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPointArray::bezier: The array must have 4 control points" ); +#endif + TQPointArray p; + return p; + } + + int v; + float xvec[4]; + float yvec[4]; + for ( v=0; v<4; v++ ) { // store all x,y in xvec,yvec + int x, y; + point( v, &x, &y ); + xvec[v] = (float)x; + yvec[v] = (float)y; + } + + TQRect r = boundingRect(); + int m = TQMAX(r.width(),r.height())/2; + m = TQMIN(m,30); // m = number of result points + if ( m < 2 ) // at least two points + m = 2; + TQPointArray p( m ); // p = Bezier point array + TQPointData *pd = p.data(); + + float x0 = xvec[0], y0 = yvec[0]; + float dt = 1.0F/m; + float cx = 3.0F * (xvec[1] - x0); + float bx = 3.0F * (xvec[2] - xvec[1]) - cx; + float ax = xvec[3] - (x0 + cx + bx); + float cy = 3.0F * (yvec[1] - y0); + float by = 3.0F * (yvec[2] - yvec[1]) - cy; + float ay = yvec[3] - (y0 + cy + by); + float t = dt; + + pd->rx() = (TQCOORD)xvec[0]; + pd->ry() = (TQCOORD)yvec[0]; + pd++; + m -= 2; + + while ( m-- ) { + pd->rx() = (TQCOORD)tqRound( ((ax * t + bx) * t + cx) * t + x0 ); + pd->ry() = (TQCOORD)tqRound( ((ay * t + by) * t + cy) * t + y0 ); + pd++; + t += dt; + } + + pd->rx() = (TQCOORD)xvec[3]; + pd->ry() = (TQCOORD)yvec[3]; + + return p; +#else + + if ( size() != 4 ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPointArray::bezier: The array must have 4 control points" ); +#endif + TQPointArray pa; + return pa; + } else { + TQRect r = boundingRect(); + int m = 4+2*TQMAX(r.width(),r.height()); + double *p = new double[m]; + double ctrl[8]; + int i; + for (i=0; i<4; i++) { + ctrl[i*2] = at(i).x(); + ctrl[i*2+1] = at(i).y(); + } + int len=0; + polygonizeTQBezier( p, len, ctrl, m ); + TQPointArray pa((len/2)+1); // one extra point for last point on line + int j=0; + for (i=0; j>( TQDataStream &s, TQPointArray &a ) +{ + uint i; + uint len; + s >> len; // read size of array + if ( !a.resize( len ) ) // no memory + return s; + TQPoint p; + for ( i=0; i> p; + a.setPoint( i, p ); + } + return s; +} +#endif //TQT_NO_DATASTREAM + + + +struct TQShortPoint { // Binary compatible with XPoint + short x, y; +}; + +uint TQPointArray::splen = 0; +void* TQPointArray::sp = 0; // Really a TQShortPoint* + +/*! + \internal + + Converts the point coords to short (16bit) size, compatible with + X11's XPoint structure. The pointer returned points to a static + array, so its contents will be overwritten the next time this + function is called. +*/ + +void* TQPointArray::shortPoints( int index, int nPoints ) const +{ + + if ( isNull() || !nPoints ) + return 0; + TQPoint* p = data(); + p += index; + uint i = nPoints < 0 ? size() : nPoints; + if ( splen < i ) { + if ( sp ) + delete[] ((TQShortPoint*)sp); + sp = new TQShortPoint[i]; + splen = i; + } + TQShortPoint* ps = (TQShortPoint*)sp; + while ( i-- ) { + ps->x = (short)p->x(); + ps->y = (short)p->y(); + p++; + ps++; + } + return sp; +} + + +/*! + \internal + + Deallocates the internal buffer used by shortPoints(). +*/ + +void TQPointArray::cleanBuffers() +{ + if ( sp ) + delete[] ((TQShortPoint*)sp); + sp = 0; + splen = 0; +} diff --git a/src/kernel/tqpointarray.h b/src/kernel/tqpointarray.h new file mode 100644 index 000000000..386910f15 --- /dev/null +++ b/src/kernel/tqpointarray.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Definition of TQPointArray class +** +** Created : 940213 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPOINTARRAY_H +#define TQPOINTARRAY_H + +#ifndef QT_H +#include "tqmemarray.h" +#include "tqpoint.h" +#endif // QT_H + + +#if defined(Q_TEMPLATEDLL) +//Q_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray; +#endif + +class TQ_EXPORT TQPointArray : public TQMemArray +{ +public: + TQPointArray() {} + ~TQPointArray() {} + TQPointArray( int size ) : TQMemArray( size ) {} + TQPointArray( const TQPointArray &a ) : TQMemArray( a ) {} + TQPointArray( const TQRect &r, bool closed=FALSE ); + TQPointArray( int nPoints, const TQCOORD *points ); + + TQPointArray &operator=( const TQPointArray &a ) + { return (TQPointArray&)assign( a ); } + + TQPointArray copy() const + { TQPointArray tmp; return *((TQPointArray*)&tmp.duplicate(*this)); } + + void translate( int dx, int dy ); + TQRect boundingRect() const; + + void point( uint i, int *x, int *y ) const; + TQPoint point( uint i ) const; + void setPoint( uint i, int x, int y ); + void setPoint( uint i, const TQPoint &p ); + bool setPoints( int nPoints, const TQCOORD *points ); + bool setPoints( int nPoints, int firstx, int firsty, ... ); + bool putPoints( int index, int nPoints, const TQCOORD *points ); + bool putPoints( int index, int nPoints, int firstx, int firsty, ... ); + bool putPoints( int index, int nPoints, + const TQPointArray & from, int fromIndex=0 ); + + void makeArc( int x, int y, int w, int h, int a1, int a2 ); + void makeEllipse( int x, int y, int w, int h ); + void makeArc( int x, int y, int w, int h, int a1, int a2, + const TQWMatrix& ); +#ifndef TQT_NO_BEZIER + TQPointArray cubicBezier() const; +#endif + void* shortPoints( int index = 0, int nPoints = -1 ) const; + static void cleanBuffers(); + +protected: + static uint splen; + static void* sp; +}; + + +/***************************************************************************** + TQPointArray stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPointArray & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPointArray & ); +#endif + +/***************************************************************************** + Misc. TQPointArray functions + *****************************************************************************/ + +inline void TQPointArray::setPoint( uint i, const TQPoint &p ) +{ + setPoint( i, p.x(), p.y() ); +} + + +#endif // TQPOINTARRAY_H diff --git a/src/kernel/tqprinter.cpp b/src/kernel/tqprinter.cpp new file mode 100644 index 000000000..eaaa3854f --- /dev/null +++ b/src/kernel/tqprinter.cpp @@ -0,0 +1,1028 @@ +/********************************************************************** +** +** Implementation of TQPrinter class +** +** Created : 941003 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqprinter.h" +#include "tqprinter_p.h" + +#ifndef TQT_NO_PRINTER + +/*! + \class TQPrinter tqprinter.h + \brief The TQPrinter class is a paint device that paints on a printer. + + \ingroup images + \ingroup graphics + \mainclass + + On Windows it uses the built-in printer drivers. On X11 it + generates postscript and sends that to lpr, lp, or another print + command. + + TQPrinter is used in much the same way as TQWidget and TQPixmap are + used. The big difference is that you must keep track of the pages. + + TQPrinter supports a number of settable parameters, most of which + can be changed by the end user when the application calls + TQPrinter::setup(). + + The most important parameters are: + \list + \i setOrientation() tells TQPrinter which page orientation to use (virtual). + \i setPageSize() tells TQPrinter what page size to expect from the + printer. + \i setResolution() tells TQPrinter what resolution you wish the + printer to provide (in dpi). + \i setFullPage() tells TQPrinter whether you want to deal with the + full page or just with the part the printer can draw on. The + default is FALSE, so that by default you should be able to paint + on (0,0). If TRUE the origin of the coordinate system will be in + the top left corner of the paper and most probably the printer + will not be able to paint something there due to it's physical + margins. + \i setNumCopies() tells TQPrinter how many copies of the document + it should print. + \i setMinMax() tells TQPrinter and TQPrintDialog what the allowed + range for fromPage() and toPage() are. + \endlist + + Except where noted, you can only call the set functions before + setup(), or between TQPainter::end() and setup(). (Some may take + effect between setup() and begin(), or between begin() and end(), + but that's strictly undocumented and such behaviour may differ + depending on platform.) + + There are also some settings that the user sets (through the + printer dialog) and that applications are expected to obey: + + \list + + \i pageOrder() tells the application program whether to print + first-page-first or last-page-first. + + \i colorMode() tells the application program whether to print in + color or grayscale. (If you print in color and the printer does + not support color, TQt will try to approximate. The document may + take longer to print, but the quality should not be made visibly + poorer.) + + \i fromPage() and toPage() indicate what pages the application + program should print. + + \i paperSource() tells the application progam which paper source + to print from. + + \endlist + + You can of course call these functions to establish defaults + before you ask the user through TQPrinter::setup(). + + Once you start printing, calling newPage() is essential. You will + probably also need to look at the TQPaintDeviceMetrics for the + printer (see the \link simple-application.html#printersimple print + function\endlink in the Application walk-through). In previous versions, + paint device metrics were valid only after the TQPrinter has been set + up, i.e. after setup() has returned successfully. This is no longer + the case and paint device metrics can be requested safely before set up. + + If you want to abort the print job, abort() will try its best to + stop printing. It may cancel the entire job or just some of it. + + \omit Need a function to setup() without a dialog (i.e. use defaults). + \endomit + + The TrueType font embedding for TQt's postscript driver uses code + by David Chappell of Trinity College Computing Center. + + \legalese + + Copyright 1995, Trinity College Computing Center. + Written by David Chappell. + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby + granted, provided that the above copyright notice appear in all + copies and that both that copyright notice and this permission + notice appear in supporting documentation. This software is + provided "as is" without express or implied warranty. + + TrueType font support. These functions allow PPR to generate + PostScript fonts from Microsoft compatible TrueType font files. + + The functions in this file do most of the work to convert a + TrueType font to a type 3 PostScript font. + + Most of the material in this file is derived from a program called + "ttf2ps" which L. S. Ng posted to the usenet news group + "comp.sources.postscript". The author did not provide a copyright + notice or indicate any restrictions on use. + + Last revised 11 July 1995. + +*/ + +/*! + \enum TQPrinter::PrinterMode + + This enum describes the mode the printer should work in. It + basically presets a certain resolution and working mode. + + \value ScreenResolution Sets the resolution of the print device to + the screen resolution. This has the big advantage that the results + obtained when painting on the printer will match more or less + exactly the visible output on the screen. It is the easiest to + use, as font metrics on the screen and on the printer are the + same. This is the default value. ScreenResolution will produce a + lower quality output than HighResolution and should only be used + for drafts. + + \value PrinterResolution Use the physical resolution of the + printer on Windows. On Unix, set the postscript resolution to 72 + dpi. + + \value HighResolution Use printer resolution on windows, set the + resolution of the postscript driver to 600dpi. + + \value Compatible Almost the same as PrinterResolution, but keeps + some peculiarities of the TQt 2.x printer driver. This is useful + for applications ported from TQt 2.x to TQt 3.x. +*/ + +/*! + \enum TQPrinter::Orientation + + This enum type (not to be confused with TQt::Orientation) is used + to specify each page's orientation. + + \value Portrait the page's height is greater than its width (the + default). + + \value Landscape the page's width is greater than its height. + + This type interacts with \l TQPrinter::PageSize and + TQPrinter::setFullPage() to determine the final size of the page + available to the application. +*/ + + +/*! + \enum TQPrinter::PageSize + + This enum type specifies what paper size TQPrinter should use. + TQPrinter does not check that the paper size is available; it just + uses this information, together with TQPrinter::Orientation and + TQPrinter::setFullPage(), to determine the printable area (see + TQPaintDeviceMetrics). + + The defined sizes (with setFullPage(TRUE)) are: + + \value A0 841 x 1189 mm This value is not supported on windows. + \value A1 594 x 841 mm This value is not supported on windows. + \value A2 420 x 594 mm + \value A3 297 x 420 mm + \value A4 210 x 297 mm, 8.26 x 11.7 inches + \value A5 148 x 210 mm + \value A6 105 x 148 mm + \value A7 74 x 105 mm + \value A8 52 x 74 mm + \value A9 37 x 52 mm + \value B0 1030 x 1456 mm + \value B1 728 x 1030 mm + \value B10 32 x 45 mm + \value B2 515 x 728 mm + \value B3 364 x 515 mm + \value B4 257 x 364 mm + \value B5 182 x 257 mm, 7.17 x 10.13 inches + \value B6 128 x 182 mm + \value B7 91 x 128 mm + \value B8 64 x 91 mm + \value B9 45 x 64 mm + \value C5E 163 x 229 mm + \value Comm10E 105 x 241 mm, US Common #10 Envelope + \value DLE 110 x 220 mm + \value Executive 7.5 x 10 inches, 191 x 254 mm + \value Folio 210 x 330 mm + \value Ledger 432 x 279 mm + \value Legal 8.5 x 14 inches, 216 x 356 mm + \value Letter 8.5 x 11 inches, 216 x 279 mm + \value Tabloid 279 x 432 mm + \value Custom + \value NPageSize (internal) + + With setFullPage(FALSE) (the default), the metrics will be a bit + smaller; how much depends on the printer in use. +*/ + + +/*! + \enum TQPrinter::PageOrder + + This enum type is used by TQPrinter to tell the application program + how to print. + + \value FirstPageFirst the lowest-numbered page should be printed + first. + + \value LastPageFirst the highest-numbered page should be printed + first. +*/ + +/*! + \enum TQPrinter::ColorMode + + This enum type is used to indicate whether TQPrinter should print + in color or not. + + \value Color print in color if available, otherwise in grayscale. + + \value GrayScale print in grayscale, even on color printers. + Might be a little faster than \c Color. This is the default. +*/ + +/*! + \enum TQPrinter::PaperSource + + This enum type specifies what paper source TQPrinter is to use. + TQPrinter does not check that the paper source is available; it + just uses this information to try and set the paper source. + Whether it will set the paper source depends on whether the + printer has that particular source. + + Note: this is currently only implemented for Windows. + + \value OnlyOne + \value Lower + \value Middle + \value Manual + \value Envelope + \value EnvelopeManual + \value Auto + \value Tractor + \value SmallFormat + \value LargeFormat + \value LargeCapacity + \value Cassette + \value FormSource +*/ + +/*! + \enum TQPrinter::PrintRange + + This enum is used to specify which print range the application + should use to print. + + \value AllPages All pages should be printed + \value Selection Only the selection should be printed. + \value PageRange From page, to page option. + + \sa setPrintRange(), printRange() +*/ + +/*! + \enum TQPrinter::PrinterOption + + This enum describes various printer options that appear in the + printer setup dialog. It is used to enable and disable these + options in the setup dialog. + + \value PrintToFile Describes if print to file should be enabled. + \value PrintSelection Describes if printing selections should be enabled. + \value PrintPageRange Describes if printing page ranges (from, to) should + be enabled + + \sa setOptionEnabled(), isOptionEnabled() +*/ + + +/*! + \fn TQString TQPrinter::printerName() const + + Returns the printer name. This value is initially set to the name + of the default printer. + + \sa setPrinterName() +*/ + +/*! + \fn bool TQPrinter::outputToFile() const + + Returns TRUE if the output should be written to a file, or FALSE + if the output should be sent directly to the printer. The default + setting is FALSE. + + This function is currently only supported under X11 and Mac OS X. + + \sa setOutputToFile(), setOutputFileName() +*/ + +/*! + Specifies whether the output should be written to a file or sent + directly to the printer. + + Will output to a file if \a enable is TRUE, or will output + directly to the printer if \a enable is FALSE. + + This function is currently only supported under X11 and Mac OS X. + + \sa outputToFile(), setOutputFileName() +*/ + +void TQPrinter::setOutputToFile( bool enable ) +{ + if ( state != 0 ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPrinter::setOutputToFile: Cannot do this during printing" ); +#endif + return; + } + output_file = enable; +} + + +/*! + \fn TQString TQPrinter::outputFileName() const + + Returns the name of the output file. There is no default file + name. + + \sa setOutputFileName(), setOutputToFile() +*/ + +/*! + Sets the name of the output file to \a fileName. + + Setting a null or empty name (0 or "") disables output to a file, + i.e. calls setOutputToFile(FALSE). Setting a non-empty name + enables output to a file, i.e. calls setOutputToFile(TRUE). + + This function is currently only supported under X11. + + \sa outputFileName(), setOutputToFile() +*/ + +void TQPrinter::setOutputFileName( const TQString &fileName ) +{ + if ( state != 0 ) { +#if defined(QT_CHECK_STATE) + tqWarning("TQPrinter::setOutputFileName: Cannot do this during printing"); +#endif + return; + } + output_filename = fileName; + output_file = !output_filename.isEmpty(); +} + + +/*! + \fn TQString TQPrinter::printProgram() const + + Returns the name of the program that sends the print output to the + printer. + + The default is to return a null string; meaning that TQPrinter will + try to be smart in a system-dependent way. On X11 only, you can + set it to something different to use a specific print program. + + On Windows, this function returns the name of the printer device + driver. + + \sa setPrintProgram() setPrinterSelectionOption() +*/ + +/*! + Sets the name of the program that should do the print job to \a + printProg. + + On X11, this function sets the program to call with the PostScript + output. On other platforms, it has no effect. + + \sa printProgram() +*/ + +void TQPrinter::setPrintProgram( const TQString &printProg ) +{ + print_prog = printProg; +} + + +/*! + \fn TQString TQPrinter::docName() const + + Returns the document name. + + \sa setDocName() +*/ + +/*! + Sets the document name to \a name. +*/ + +void TQPrinter::setDocName( const TQString &name ) +{ + if ( state != 0 ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPrinter::setDocName: Cannot do this during printing" ); +#endif + return; + } + doc_name = name; +} + + +/*! + \fn TQString TQPrinter::creator() const + + Returns the name of the application that created the document. + + \sa setCreator() +*/ + +/*! + Sets the name of the application that created the document to \a + creator. + + This function is only applicable to the X11 version of TQt. If no + creator name is specified, the creator will be set to "TQt" + followed by some version number. + + \sa creator() +*/ + +void TQPrinter::setCreator( const TQString &creator ) +{ + creator_name = creator; +} + + +/*! + \fn Orientation TQPrinter::orientation() const + + Returns the orientation setting. The default value is \c + TQPrinter::Portrait. + + \sa setOrientation() +*/ + +/*! + Sets the print orientation to \a orientation. + + The orientation can be either \c TQPrinter::Portrait or \c + TQPrinter::Landscape. + + The printer driver reads this setting and prints using the + specified orientation. On Windows this setting won't take effect + until the printer dialog is shown (using TQPrinter::setup()). + + Windows only! This option can be changed while printing and will + take effect from the next call to newPage() + + \sa orientation() +*/ + +void TQPrinter::setOrientation( Orientation orientation ) +{ + orient = orientation; +#if defined(TQ_WS_WIN) + reinit(); +#endif +} + + +/*! + \fn PageSize TQPrinter::pageSize() const + + Returns the printer page size. The default value is system-dependent. + + \sa setPageSize() +*/ + + +/*! + Sets the printer page size to \a newPageSize if that size is + supported. The result if undefined if \a newPageSize is not + supported. + + The default page size is system-dependent. + + This function is useful mostly for setting a default value that + the user can override in the print dialog when you call setup(). + + \sa pageSize() PageSize setFullPage() setResolution() +*/ + +void TQPrinter::setPageSize( PageSize newPageSize ) +{ + if ( newPageSize > NPageSize ) { +#if defined(QT_CHECK_STATE) + tqWarning("TQPrinter::SetPageSize: illegal page size %d", newPageSize ); +#endif + return; + } + page_size = newPageSize; +#if defined(TQ_WS_WIN) + reinit(); +#endif +} + +/*! + Sets the page order to \a newPageOrder. + + The page order can be \c TQPrinter::FirstPageFirst or \c + TQPrinter::LastPageFirst. The application programmer is responsible + for reading the page order and printing accordingly. + + This function is useful mostly for setting a default value that + the user can override in the print dialog when you call setup(). + + \bug This value is not kept in sync with the Windows or Mac OS X printer + dialogs. +*/ + +void TQPrinter::setPageOrder( PageOrder newPageOrder ) +{ + page_order = newPageOrder; +#if defined(TQ_WS_WIN) + reinit(); +#endif +} + + +/*! + Returns the current page order. + + The default page order is \c FirstPageFirst. + + \bug This value is not kept in sync with the Windows or Mac OS X printer + dialogs. +*/ + +TQPrinter::PageOrder TQPrinter::pageOrder() const +{ + return page_order; +} + + +/*! + Sets the printer's color mode to \a newColorMode, which can be + either \c Color or \c GrayScale (the default). + + \sa colorMode() +*/ + +void TQPrinter::setColorMode( ColorMode newColorMode ) +{ + color_mode = newColorMode; +#if defined(TQ_WS_WIN) + reinit(); +#endif +} + + +/*! + Returns the current color mode. The default color mode is \c + Color. + + \sa setColorMode() +*/ + +TQPrinter::ColorMode TQPrinter::colorMode() const +{ + return color_mode; +} + + +/*! + \fn int TQPrinter::fromPage() const + + Returns the from-page setting. The default value is 0. + + If fromPage() and toPage() both return 0 this signifies 'print the + whole document'. + + The programmer is responsible for reading this setting and + printing accordingly. + + \sa setFromTo(), toPage() +*/ + +/*! + \fn int TQPrinter::toPage() const + + Returns the to-page setting. The default value is 0. + + If fromPage() and toPage() both return 0 this signifies 'print the + whole document'. + + The programmer is responsible for reading this setting and + printing accordingly. + + \sa setFromTo(), fromPage() +*/ + +/*! + Sets the from-page and to-page settings to \a fromPage and \a + toPage respectively. + + The from-page and to-page settings specify what pages to print. + + If fromPage() and toPage() both return 0 this signifies 'print the + whole document'. + + This function is useful mostly to set a default value that the + user can override in the print dialog when you call setup(). + + \sa fromPage(), toPage(), setMinMax(), setup() +*/ + +void TQPrinter::setFromTo( int fromPage, int toPage ) +{ + if ( state != 0 ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPrinter::setFromTo: Cannot do this during printing" ); +#endif + return; + } + from_pg = fromPage; + to_pg = toPage; +} + + +/*! + \fn int TQPrinter::minPage() const + + Returns the min-page setting, i.e. the lowest page number a user + is allowed to choose. The default value is 0. + + \sa maxPage(), setMinMax() setFromTo() +*/ + +/*! + \fn int TQPrinter::maxPage() const + + Returns the max-page setting. A user can't choose a higher page + number than maxPage() when they select a print range. The default + value is 0. + + \sa minPage(), setMinMax() setFromTo() +*/ + +/*! + Sets the min-page and max-page settings to \a minPage and \a + maxPage respectively. + + The min-page and max-page restrict the from-page and to-page + settings. When the printer setup dialog appears, the user cannot + select a from page or a to page that are outside the range + specified by min and max pages. + + \sa minPage(), maxPage(), setFromTo(), setup() +*/ + +void TQPrinter::setMinMax( int minPage, int maxPage ) +{ + min_pg = minPage; + max_pg = maxPage; + if ( from_pg == 0 || from_pg < minPage ) + from_pg = minPage; + if ( to_pg == 0 || to_pg > maxPage ) + to_pg = maxPage; +} + + +/*! + \fn int TQPrinter::numCopies() const + + Returns the number of copies to be printed. The default value is 1. + + This value will return the number of times the application is + required to print in order to match the number specified in the + printer setup dialog. This has been done since some printer + drivers are not capable of buffering up the copies and the + application in those cases have to make an explicit call to the + print code for each copy. + + \sa setNumCopies() +*/ + +/*! + \fn bool TQPrinter::collateCopiesEnabled() const + + \internal + + Returns TRUE if the application should provide the user with the + option of choosing a collated printout; otherwise returns FALSE. + + Collation means that each page is printed in order, i.e. print the + first page, then the second page, then the third page and so on, and + then repeat this sequence for as many copies as have been requested. + If you don't collate you get several copies of the first page, then + several copies of the second page, then several copies of the third + page, and so on. + + \sa setCollateCopiesEnabled() setCollateCopies() collateCopies() +*/ + +/*! + \fn void TQPrinter::setCollateCopiesEnabled(bool enable) + + \internal + + If \a enable is TRUE (the default) the user is given the choice of + whether to print out multiple copies collated in the print dialog. + If \a enable is FALSE, then collateCopies() will be ignored. + + Collation means that each page is printed in order, i.e. print the + first page, then the second page, then the third page and so on, and + then repeat this sequence for as many copies as have been requested. + If you don't collate you get several copies of the first page, then + several copies of the second page, then several copies of the third + page, and so on. + + \sa collateCopiesEnabled() setCollateCopies() collateCopies() +*/ + +/*! + \fn bool TQPrinter::collateCopies() const + + \internal + + Returns TRUE if collation is turned on when multiple copies is selected. + Returns FALSE if it is turned off when multiple copies is selected. + + \sa collateCopiesEnabled() setCollateCopiesEnabled() setCollateCopies() +*/ + +/*! + \internal + + Sets the default value for collation checkbox when the print dialog appears. + If \a on is TRUE, it will enable setCollateCopiesEnabled(). + The default value is FALSE. This value will be changed by what the + user presses in the print dialog. + + \sa collateCopiesEnabled() setCollateCopiesEnabled() collateCopies() +*/ + +void TQPrinter::setCollateCopies(bool on) +{ + if (!collateCopiesEnabled() && on) + setCollateCopiesEnabled(on); + usercolcopies = on; +} + +/*! + Sets the number of copies to be printed to \a numCopies. + + The printer driver reads this setting and prints the specified + number of copies. + + \sa numCopies(), setup() +*/ + +void TQPrinter::setNumCopies( int numCopies ) +{ + ncopies = numCopies; +#if defined(TQ_WS_WIN) + reinit(); +#endif +} + + +/*! + Returns the printer options selection string. This is useful only + if the print command has been explicitly set. + + The default value (a null string) implies that the printer should + be selected in a system-dependent manner. + + Any other value implies that the given value should be used. + + \sa setPrinterSelectionOption() +*/ + +TQString TQPrinter::printerSelectionOption() const +{ + return option_string; +} + + +/*! + Sets the printer to use \a option to select the printer. \a option + is null by default (which implies that TQt should be smart enough + to guess correctly), but it can be set to other values to use a + specific printer selection option. + + If the printer selection option is changed while the printer is + active, the current print job may or may not be affected. + + \sa printerSelectionOption() +*/ + +void TQPrinter::setPrinterSelectionOption( const TQString & option ) +{ + option_string = option; +} + + +/*! + Sets TQPrinter to have the origin of the coordinate system at the + top-left corner of the paper if \a fp is TRUE, or where it thinks + the top-left corner of the printable area is if \a fp is FALSE. + + The default is FALSE. You can (probably) print on (0,0), and + TQPaintDeviceMetrics will report something smaller than the size + indicated by PageSize. (Note that TQPrinter may be wrong on Unix + systems - it does not have perfect knowledge of the physical + printer.) + + If you set \a fp to TRUE, TQPaintDeviceMetrics will report the + exact same size as indicated by \c PageSize, but you cannot print + on all of that - you must take care of the output margins + yourself. + + \sa PageSize setPageSize() TQPaintDeviceMetrics fullPage() +*/ + +void TQPrinter::setFullPage( bool fp ) +{ + to_edge = fp; +} + + +/*! + Returns TRUE if the origin of the printer's coordinate system is + at the corner of the sheet and FALSE if it is at the edge of the + printable area. + + See setFullPage() for details and caveats. + + \sa setFullPage() PageSize TQPaintDeviceMetrics +*/ + +bool TQPrinter::fullPage() const +{ + return to_edge; +} + + +/*! + Requests that the printer prints at \a dpi or as near to \a dpi as + possible. + + This setting affects the coordinate system as returned by, for + example, TQPaintDeviceMetrics and TQPainter::viewport(). + + The value depends on the \c PrintingMode used in the TQPrinter + constructor. By default, the dpi value of the screen is used. + + This function must be called before setup() to have an effect on + all platforms. + + \sa resolution() setPageSize() +*/ + +void TQPrinter::setResolution( int dpi ) +{ + res = dpi; + res_set = TRUE; +} + + +/*! + Returns the current assumed resolution of the printer, as set by + setResolution() or by the printer subsystem. + + \sa setResolution() +*/ + +int TQPrinter::resolution() const +{ + return res; +} + +/*! + Sets the paper source setting to \a source. + + Windows only! This option can be changed while printing and will + take effect from the next call to newPage() + + \sa paperSource() +*/ + +void TQPrinter::setPaperSource( PaperSource source ) +{ + paper_source = source; +#if defined(TQ_WS_WIN) + reinit(); +#endif +} + +/*! + Returns the currently set paper source of the printer. + + \sa setPaperSource() +*/ + +TQPrinter::PaperSource TQPrinter::paperSource() const +{ + return paper_source; +} + +/*! + Sets the default selected page range to be used when the print setup + dialog is opened to \a range. If the PageRange specified by \a range is + currently disabled the function does nothing. + + \sa printRange() +*/ +void TQPrinter::setPrintRange( PrintRange range ) +{ + if( range != AllPages ) { + if( range == Selection + && !isOptionEnabled( PrintSelection ) ) { + setOptionEnabled( PrintSelection, TRUE ); + } + else if( range == PageRange + && !isOptionEnabled( PrintPageRange ) ) { + setOptionEnabled( PrintPageRange, TRUE ); + } + } + d->printRange = range; +} + +/*! + Returns the PageRange of the TQPrinter. After the print setup dialog + has been opened, this function returns the value selected by the user. + + \sa setPrintRange() +*/ +TQPrinter::PrintRange TQPrinter::printRange() const +{ + return d->printRange; +} + +/*! + Enables the printer option with the identifier \a option if \a + enable is TRUE, and disables option \a option if \a enable is FALSE. + + \sa isOptionEnabled() +*/ +void TQPrinter::setOptionEnabled( PrinterOption option, bool enable ) +{ + if( enable ) { + d->printerOptions |= ( 1 << option ); + if( ( option == PrintPageRange ) && min_pg==0 && max_pg==0 ) + max_pg = 9999; + } else { + d->printerOptions &= ( ~( 1 << option ) ); + } +} + +/*! + Returns TRUE if the printer option with identifier \a option is enabled; + otherwise returns FALSE. + + \sa setOptionEnabled() + */ +bool TQPrinter::isOptionEnabled( PrinterOption option ) +{ + return d->printerOptions & ( 1 << option ); +} +#endif // TQT_NO_PRINTER + diff --git a/src/kernel/tqprinter.h b/src/kernel/tqprinter.h new file mode 100644 index 000000000..de561901a --- /dev/null +++ b/src/kernel/tqprinter.h @@ -0,0 +1,284 @@ +/********************************************************************** +** +** Definition of TQPrinter class +** +** Created : 940927 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPRINTER_H +#define TQPRINTER_H + +#ifndef QT_H +#include "tqpaintdevice.h" +#include "tqstring.h" +#include "tqstringlist.h" +#endif // QT_H + +#ifndef TQT_NO_PRINTER + +#if defined(B0) +#undef B0 // Terminal hang-up. We assume that you do not want that. +#endif + +class TQPrinterPrivate; + +class TQ_EXPORT TQPrinter : public TQPaintDevice +{ +public: + enum PrinterMode { ScreenResolution, PrinterResolution, HighResolution, Compatible }; + + TQPrinter( PrinterMode mode = ScreenResolution ); + ~TQPrinter(); + + enum Orientation { Portrait, Landscape }; + + enum PageSize { A4, B5, Letter, Legal, Executive, + A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1, + B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E, + DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom }; + + enum PageOrder { FirstPageFirst, LastPageFirst }; + + enum ColorMode { GrayScale, Color }; + + enum PaperSource { OnlyOne, Lower, Middle, Manual, Envelope, + EnvelopeManual, Auto, Tractor, SmallFormat, + LargeFormat, LargeCapacity, Cassette, FormSource }; + + enum PrintRange { AllPages, + Selection, + PageRange }; + + enum PrinterOption { PrintToFile, + PrintSelection, + PrintPageRange }; + + TQString printerName() const; + virtual void setPrinterName( const TQString &); + bool outputToFile() const; + virtual void setOutputToFile( bool ); + TQString outputFileName()const; + virtual void setOutputFileName( const TQString &); + + TQString printProgram() const; + virtual void setPrintProgram( const TQString &); + + TQString printerSelectionOption() const; + virtual void setPrinterSelectionOption( const TQString & ); + + TQString docName() const; + virtual void setDocName( const TQString &); + TQString creator() const; + virtual void setCreator( const TQString &); + + Orientation orientation() const; + virtual void setOrientation( Orientation ); + PageSize pageSize() const; + virtual void setPageSize( PageSize ); +#ifdef TQ_WS_WIN + void setWinPageSize( short winPageSize ); + short winPageSize() const; +#endif +#ifdef TQ_WS_MAC + bool printSetup(); + bool pageSetup(); +#endif + virtual void setPageOrder( PageOrder ); + PageOrder pageOrder() const; + + void setResolution( int ); + int resolution() const; + + virtual void setColorMode( ColorMode ); + ColorMode colorMode() const; + + virtual void setFullPage( bool ); + bool fullPage() const; + TQSize margins() const; + void setMargins( uint top, uint left, uint bottom, uint right ); + void margins( uint *top, uint *left, uint *bottom, uint *right ) const; + + int fromPage() const; + int toPage() const; + virtual void setFromTo( int fromPage, int toPage ); + int minPage() const; + int maxPage() const; + virtual void setMinMax( int minPage, int maxPage ); + int numCopies() const; + virtual void setNumCopies( int ); + + bool collateCopiesEnabled() const; + void setCollateCopiesEnabled(bool ); + + bool collateCopies() const; + void setCollateCopies( bool ); + + PrintRange printRange() const; + void setPrintRange( PrintRange range ); + + bool newPage(); + bool abort(); + bool aborted() const; + + bool setup( TQWidget *parent = 0 ); + + PaperSource paperSource() const; + virtual void setPaperSource( PaperSource ); + + void setOptionEnabled( PrinterOption, bool enable ); + bool isOptionEnabled( PrinterOption ); + +protected: + bool cmd( int, TQPainter *, TQPDevCmdParam * ); + int metric( int ) const; + +#if defined(TQ_WS_WIN) + virtual void setActive(); + virtual void setIdle(); +#endif + +private: +#if defined(TQ_WS_X11) + TQPaintDevice *pdrv; + int pid; +#endif +#if defined(TQ_WS_MAC) + friend class TQPrinterPrivate; + PMPageFormat pformat; + PMPrintSettings psettings; + PMPrintSession psession; + bool prepare(PMPrintSettings *); + bool prepare(PMPageFormat *); + void interpret(PMPrintSettings *); + void interpret(PMPageFormat *); +#endif +#if defined(TQ_WS_WIN) + void readPdlg( void* ); + void readPdlgA( void* ); + void writeDevmode( TQt::HANDLE ); + void writeDevmodeA( TQt::HANDLE ); + void reinit(); + + bool viewOffsetDone; + TQPainter* painter; + TQt::HANDLE hdevmode; + TQt::HANDLE hdevnames; +#endif + + int state; + TQString printer_name; + TQString option_string; + TQString output_filename; + bool output_file; + TQString print_prog; + TQString doc_name; + TQString creator_name; + + PageSize page_size; + PaperSource paper_source; + PageOrder page_order; + ColorMode color_mode; + Orientation orient; + uint to_edge : 1; + uint appcolcopies : 1; + uint usercolcopies : 1; + uint res_set : 1; + short from_pg, to_pg; + short min_pg, max_pg; + short ncopies; + int res; + TQPrinterPrivate *d; + +private: // Disabled copy constructor and operator= +#if defined(TQ_DISABLE_COPY) + TQPrinter( const TQPrinter & ); + TQPrinter &operator=( const TQPrinter & ); +#endif +}; + + +inline TQString TQPrinter::printerName() const +{ return printer_name; } + +inline bool TQPrinter::outputToFile() const +{ return output_file; } + +inline TQString TQPrinter::outputFileName() const +{ return output_filename; } + +inline TQString TQPrinter::printProgram() const +{ return print_prog; } + +inline TQString TQPrinter::docName() const +{ return doc_name; } + +inline TQString TQPrinter::creator() const +{ return creator_name; } + +inline TQPrinter::PageSize TQPrinter::pageSize() const +{ return page_size; } + +inline TQPrinter::Orientation TQPrinter::orientation() const +{ return orient; } + +inline int TQPrinter::fromPage() const +{ return from_pg; } + +inline int TQPrinter::toPage() const +{ return to_pg; } + +inline int TQPrinter::minPage() const +{ return min_pg; } + +inline int TQPrinter::maxPage() const +{ return max_pg; } + +inline int TQPrinter::numCopies() const +{ return ncopies; } + +inline bool TQPrinter::collateCopiesEnabled() const +{ return appcolcopies; } + +inline void TQPrinter::setCollateCopiesEnabled(bool v) +{ appcolcopies = v; } + +inline bool TQPrinter::collateCopies() const +{ return usercolcopies; } + + +#endif // TQT_NO_PRINTER + +#endif // TQPRINTER_H diff --git a/src/kernel/tqprinter_p.h b/src/kernel/tqprinter_p.h new file mode 100644 index 000000000..a9e46a9f3 --- /dev/null +++ b/src/kernel/tqprinter_p.h @@ -0,0 +1,62 @@ +/********************************************************************** +** +** Definition of TQPrinter class +** +** Created : 940927 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQPRINTER_P_H +#define TQPRINTER_P_H +#ifndef TQT_NO_PRINTER + +#ifndef QT_H +#include +#include +#include +#include +#endif // QT_H + +class TQPrinterPrivate +{ +public: + TQ_UINT32 printerOptions; + TQPrinter::PrintRange printRange; + + virtual ~TQPrinterPrivate() {}; +}; + +#endif +#endif diff --git a/src/kernel/tqprinter_unix.cpp b/src/kernel/tqprinter_unix.cpp new file mode 100644 index 000000000..b5ae63926 --- /dev/null +++ b/src/kernel/tqprinter_unix.cpp @@ -0,0 +1,668 @@ +/**************************************************************************** +** +** Implementation of TQPrinter class for Unix +** +** Created : 950810 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "qplatformdefs.h" + +// POSIX Large File Support redefines open -> open64 +static inline int qt_open(const char *pathname, int flags, mode_t mode) +{ return ::open(pathname, flags, mode); } +#if defined(open) +# undef open +#endif + +#include "tqprinter.h" + +#ifndef TQT_NO_PRINTER + +#include "tqpaintdevicemetrics.h" +#include "qpsprinter_p.h" +#include "ntqprintdialog.h" +#include "ntqapplication.h" +#include "tqprinter_p.h" + +#include // For ::sleep() +#include + + +// NOT REVISED + + +class TQPrinterUnixPrivate : public TQPrinterPrivate +{ +public: + bool marginsSpecified; + uint topMargin; + uint leftMargin; + uint bottomMargin; + uint rightMargin; +}; + +#define D ( (TQPrinterUnixPrivate*) d ) + +/***************************************************************************** + TQPrinter member functions + *****************************************************************************/ + +// TQPrinter states + +#define PST_IDLE 0 +#define PST_ACTIVE 1 +#define PST_ERROR 2 +#define PST_ABORTED 3 + +// Default values for TQPrinter members + +struct PrinterDefaults { + TQString printerName; + bool outputToFile; + TQString outputFileName; + TQPrinter::Orientation orientation; + TQPrinter::PageSize pageSize; + TQPrinter::PageOrder pageOrder; + TQPrinter::ColorMode colorMode; + int numCopies; +}; + +static PrinterDefaults * globalPrinterDefaults = 0; + +/*! + Constructs a printer paint device with mode \a m. + + \sa TQPrinter::PrinterMode +*/ + +TQPrinter::TQPrinter( PrinterMode m ) + : TQPaintDevice( TQInternal::Printer | TQInternal::ExternalDevice ) +{ + pdrv = 0; + pid = 0; + orient = Portrait; + page_size = A4; + page_order = FirstPageFirst; + color_mode = GrayScale; + ncopies = 1; + printer_name = getenv("PRINTER"); + from_pg = to_pg = min_pg = max_pg = 0; + state = PST_IDLE; + output_file = FALSE; + to_edge = FALSE; + paper_source = OnlyOne; + switch ( m ) { + case ScreenResolution: + res = TQPaintDevice::x11AppDpiY(); + break; + case Compatible: + case PrinterResolution: + res = 72; + break; + case HighResolution: + res = 600; + } + + d = new TQPrinterUnixPrivate; + D->marginsSpecified = FALSE; + d->printerOptions = 0; + setOptionEnabled( PrintToFile, TRUE ); + setOptionEnabled( PrintPageRange, TRUE ); + setPrintRange( AllPages ); +} + +/*! + Destroys the printer paint device and cleans up. +*/ + +TQPrinter::~TQPrinter() +{ + delete pdrv; + if ( pid ) { + (void)::kill( pid, 6 ); + (void)::wait( 0 ); + pid = 0; + } + delete d; +} + + +/*! + Advances to a new page on the printer. Returns TRUE if successful; + otherwise returns FALSE. +*/ + +bool TQPrinter::newPage() +{ + if ( state == PST_ACTIVE && pdrv ) + return ((TQPSPrinter*)pdrv)->cmd( TQPSPrinter::NewPage, 0, 0 ); + return FALSE; +} + + +/*! + Aborts the print job. Returns TRUE if successful; otherwise + returns FALSE. + + \sa aborted() +*/ + +bool TQPrinter::abort() +{ + if ( state == PST_ACTIVE && pdrv ) { + ((TQPSPrinter*)pdrv)->cmd( TQPSPrinter::AbortPrinting, 0, 0 ); + state = PST_ABORTED; + if ( pid ) { + (void)::kill( pid, 6 ); + (void)::wait( 0 ); + pid = 0; + } + } + return state == PST_ABORTED; +} + +/*! + Returns TRUE if the print job was aborted; otherwise returns + FALSE. + + \sa abort() +*/ + +bool TQPrinter::aborted() const +{ + return state == PST_ABORTED; +} + +/*! + Sets the printer name to \a name. + + The default printer will be used if no printer name is set. + + Under X11, the \c PRINTER environment variable defines the default + printer. Under any other window system, the window system defines + the default printer. + + \sa printerName() +*/ + +void TQPrinter::setPrinterName( const TQString &name ) +{ + if ( state != 0 ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQPrinter::setPrinterName: Cannot do this during printing" ); +#endif + return; + } + printer_name = name; +} + +static void deleteGlobalPrinterDefaults() +{ + delete globalPrinterDefaults; + globalPrinterDefaults = 0; +} + +/*! + Opens a printer setup dialog, with parent \a parent, and asks the + user to specify which printer they wish to use and what settings + it should have. + + Returns TRUE if the user pressed "OK" to print, or FALSE if the + user canceled the operation. +*/ + +bool TQPrinter::setup( TQWidget * parent ) +{ +#ifndef TQT_NO_PRINTDIALOG + bool result = TQPrintDialog::getPrinterSetup( this, parent ); +#else + bool result = FALSE; +#endif + if ( result ) { + if ( !globalPrinterDefaults ) { + globalPrinterDefaults = new PrinterDefaults; + tqAddPostRoutine( deleteGlobalPrinterDefaults ); + } + globalPrinterDefaults->printerName = printerName(); + globalPrinterDefaults->outputToFile = outputToFile(); + globalPrinterDefaults->outputFileName = outputFileName(); + globalPrinterDefaults->orientation = orientation(); + globalPrinterDefaults->pageSize = pageSize(); + globalPrinterDefaults->pageOrder = pageOrder(); + globalPrinterDefaults->colorMode = colorMode(); + } + return result; +} + +static void closeAllOpenFds() +{ + // hack time... getting the maximum number of open + // files, if possible. if not we assume it's the + // larger of 256 and the fd we got + int i; +#if defined(Q_OS_OS2EMX) + LONG req_count = 0; + ULONG rc, handle_count; + rc = DosSetRelMaxFH (&req_count, &handle_count); + /* if (rc != NO_ERROR) ... */ + i = (int)handle_count; +#elif defined(_SC_OPEN_MAX) + i = (int)sysconf( _SC_OPEN_MAX ); +#elif defined(_POSIX_OPEN_MAX) + i = (int)_POSIX_OPEN_MAX; +#elif defined(OPEN_MAX) + i = (int)OPEN_MAX; +#else + i = TQMAX( 256, fds[0] ); +#endif // Q_OS_OS2EMX // ways-to-set i + while( --i > 0 ) + ::close( i ); +} + + + +static const char * const psToStr[TQPrinter::NPageSize+1] = +{ "A4", "B5", "Letter", "Legal", "Executive", + "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1", + "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E", + "DLE", "Folio", "Ledger", "Tabloid", 0 +}; + + +/*! + \internal + Handles painter commands to the printer. +*/ + +bool TQPrinter::cmd( int c, TQPainter *paint, TQPDevCmdParam *p ) +{ + if ( c == PdcBegin ) { + if ( state == PST_IDLE ) { + if ( output_file ) { + int fd = 0; + fd = qt_open( output_filename.local8Bit(), + O_CREAT | O_NOCTTY | O_TRUNC | O_WRONLY, + 0666 ); + if ( fd >= 0 ) { + pdrv = new TQPSPrinter( this, fd ); + state = PST_ACTIVE; + } + } else { + TQString pr; + if ( printer_name ) + pr = printer_name; + TQApplication::flushX(); + int fds[2]; + if ( pipe( fds ) != 0 ) { + tqWarning( "TQPSPrinter: could not open pipe to print" ); + state = PST_ERROR; + return FALSE; + } + +// ### shouldn't we use TQProcess here???? +#if 0 && defined(Q_OS_OS2EMX) + // this code is still not used, and maybe it's not + // usable either, any more. if you want to use it, + // you may need to fix it first. + + // old comment: + + // this code is usable but not in use. spawn() is + // preferable to fork()/exec() for very large + // programs. if fork()/exec() is a problem and you + // use OS/2, remove '0 && ' from the #if. + int tmp; + tmp = dup(0); + dup2( fds[0], 0 ); + ::close( fds[0] ); + fcntl(tmp, F_SETFD, FD_CLOEXEC); + fcntl(fds[1], F_SETFD, FD_CLOEXEC); + if ( option_string ) + pr.prepend( option_string ); + else + pr.prepend( "-P" ); // ### + if ( spawnlp(P_NOWAIT,print_prog.data(), print_prog.data(), + pr.data(), output->name(), 0) == -1 ) { + ; // couldn't exec, ignored + } + dup2( tmp, 0 ); + ::close( tmp ); + pdrv = new TQPSPrinter( this, fds[1] ); + state = PST_ACTIVE; +#else + pid = fork(); + if ( pid == 0 ) { // child process + // if possible, exit quickly, so the actual lp/lpr + // becomes a child of init, and ::waitpid() is + // guaranteed not to wait. + if ( fork() > 0 ) { + closeAllOpenFds(); + + // try to replace this process with "true" - this prevents + // global destructors from being called (that could possibly + // do wrong things to the parent process) + (void)execlp("true", "true", (char *)0); + (void)execl("/bin/true", "true", (char *)0); + (void)execl("/usr/bin/true", "true", (char *)0); + ::exit( 0 ); + } + dup2( fds[0], 0 ); + + closeAllOpenFds(); + + if ( print_prog ) { + if ( option_string ) + pr.prepend( option_string ); + else + pr.prepend( TQString::fromLatin1( "-P" ) ); + (void)execlp( print_prog.ascii(), print_prog.ascii(), + pr.ascii(), (char *)0 ); + } else { + // if no print program has been specified, be smart + // about the option string too. + TQStringList lprhack; + TQStringList lphack; + TQString media; + if ( pr || option_string ) { + if ( option_string ) { + lprhack = TQStringList::split(TQChar(' '), option_string); + lphack = lprhack; + } else { + lprhack.append( TQString::fromLatin1( "-P" ) ); + lphack.append( TQString::fromLatin1( "-d" ) ); + } + lprhack.append(pr); + lphack.append(pr); + } + char ** lpargs = new char *[lphack.size()+6]; + lpargs[0] = (char *)"lp"; + uint i; + for (i = 0; i < lphack.size(); ++i) + lpargs[i+1] = (char *)lphack[i].ascii(); +#ifndef Q_OS_OSF + if (psToStr[page_size]) { + lpargs[++i] = (char *)"-o"; + lpargs[++i] = (char *)psToStr[page_size]; + lpargs[++i] = (char *)"-o"; + media = "media="; + media += psToStr[page_size]; + lpargs[++i] = (char *)media.ascii(); + } +#endif + lpargs[++i] = 0; + char **lprargs = new char *[lprhack.size()+1]; + lprargs[0] = (char *)"lpr"; + for (uint x = 0; x < lprhack.size(); ++x) + lprargs[x+1] = (char *)lprhack[x].ascii(); + lprargs[lprhack.size() + 1] = 0; + (void)execvp( "lp", lpargs ); + (void)execvp( "lpr", lprargs ); + (void)execv( "/bin/lp", lpargs); + (void)execv( "/bin/lpr", lprargs); + (void)execv( "/usr/bin/lp", lpargs); + (void)execv( "/usr/bin/lpr", lprargs); + } + // if we couldn't exec anything, close the fd, + // wait for a second so the parent process (the + // child of the GUI process) has exited. then + // exit. + ::close( 0 ); + (void)::sleep( 1 ); + ::exit( 0 ); + } else { // parent process + ::close( fds[0] ); + pdrv = new TQPSPrinter( this, fds[1] ); + state = PST_ACTIVE; + } +#endif // else part of Q_OS_OS2EMX + } + if ( state == PST_ACTIVE && pdrv ) + return ((TQPSPrinter*)pdrv)->cmd( c, paint, p ); + } else { + // ignore it? I don't know + } + } else { + bool r = FALSE; + if ( state == PST_ACTIVE && pdrv ) { + r = ((TQPSPrinter*)pdrv)->cmd( c, paint, p ); + if ( c == PdcEnd ) { + state = PST_IDLE; + delete pdrv; + pdrv = 0; + if ( pid ) { + (void)::waitpid( pid, 0, 0 ); + pid = 0; + } + } + } else if ( state == PST_ABORTED && c == PdcEnd ) + state = PST_IDLE; + return r; + } + return TRUE; +} + + +#define MM(n) int((n * 720 + 127) / 254) +#define IN(n) int(n * 72) + +struct PaperSize { + int width, height; +}; + +static const PaperSize paperSizes[TQPrinter::NPageSize] = +{ + { MM(210), MM(297) }, // A4 + { MM(176), MM(250) }, // B5 + { IN(8.5), IN(11) }, // Letter + { IN(8.5), IN(14) }, // Legal + { IN(7.5), IN(10) }, // Executive + { MM(841), MM(1189) }, // A0 + { MM(594), MM(841) }, // A1 + { MM(420), MM(594) }, // A2 + { MM(297), MM(420) }, // A3 + { MM(148), MM(210) }, // A5 + { MM(105), MM(148) }, // A6 + { MM(74), MM(105)}, // A7 + { MM(52), MM(74) }, // A8 + { MM(37), MM(52) }, // A9 + { MM(1000), MM(1414) }, // B0 + { MM(707), MM(1000) }, // B1 + { MM(31), MM(44) }, // B10 + { MM(500), MM(707) }, // B2 + { MM(353), MM(500) }, // B3 + { MM(250), MM(353) }, // B4 + { MM(125), MM(176) }, // B6 + { MM(88), MM(125) }, // B7 + { MM(62), MM(88) }, // B8 + { MM(44), MM(62) }, // B9 + { MM(162), MM(229) }, // C5E + { IN(4.125), IN(9.5) }, // Comm10E + { MM(110), MM(220) }, // DLE + { IN(8.5), IN(13) }, // Folio + { IN(17), IN(11) }, // Ledger + { IN(11), IN(17) } // Tabloid +}; + +/*! + Internal implementation of the virtual TQPaintDevice::metric() function. + + Use the TQPaintDeviceMetrics class instead. + + \internal + Hard coded return values for PostScript under X. +*/ + +int TQPrinter::metric( int m ) const +{ + int val; + PageSize s = pageSize(); +#if defined(QT_CHECK_RANGE) + Q_ASSERT( (uint)s < (uint)NPageSize ); +#endif + switch ( m ) { + case TQPaintDeviceMetrics::PdmWidth: + val = orient == Portrait ? paperSizes[s].width : paperSizes[s].height; + if ( res != 72 ) + val = (val * res + 36) / 72; + if ( !fullPage() ) { + if ( D->marginsSpecified ) + val -= D->leftMargin + D->rightMargin; + else + val -= 2*margins().width(); + } + break; + case TQPaintDeviceMetrics::PdmHeight: + val = orient == Portrait ? paperSizes[s].height : paperSizes[s].width; + if ( res != 72 ) + val = (val * res + 36) / 72; + if ( !fullPage() ) { + if ( D->marginsSpecified ) + val -= D->topMargin + D->bottomMargin; + else + val -= 2*margins().height(); + } + break; + case TQPaintDeviceMetrics::PdmDpiX: + val = res; + break; + case TQPaintDeviceMetrics::PdmDpiY: + val = res; + break; + case TQPaintDeviceMetrics::PdmPhysicalDpiX: + case TQPaintDeviceMetrics::PdmPhysicalDpiY: + val = 72; + break; + case TQPaintDeviceMetrics::PdmWidthMM: + // double rounding error here. hooray. + val = metric( TQPaintDeviceMetrics::PdmWidth ); + val = (val * 254 + 5*res) / (10*res); + break; + case TQPaintDeviceMetrics::PdmHeightMM: + val = metric( TQPaintDeviceMetrics::PdmHeight ); + val = (val * 254 + 5*res) / (10*res); + break; + case TQPaintDeviceMetrics::PdmNumColors: + val = 16777216; + break; + case TQPaintDeviceMetrics::PdmDepth: + val = 24; + break; + default: + val = 0; +#if defined(QT_CHECK_RANGE) + tqWarning( "TQPixmap::metric: Invalid metric command" ); +#endif + } + return val; +} + + +/*! + Returns the width of the left margin and the height of the top + margin of the printer. On Unix, this is a best-effort guess, not + based on perfect knowledge. + + If you have called setFullPage( TRUE ), margins().width() may be + treated as the smallest sane left margin you can use, and + margins().height() as the smallest sane top margin you can + use. + + If you have called setFullPage( FALSE ) (this is the default), + margins() is automatically subtracted from the pageSize() by + TQPrinter. + + \sa setFullPage() TQPaintDeviceMetrics PageSize +*/ +TQSize TQPrinter::margins() const +{ + if ( D->marginsSpecified ) + return TQSize( D->leftMargin, D->topMargin ); + + if (orient == Portrait) + return TQSize( res/2, res/3 ); + + return TQSize( res/3, res/2 ); +} + +/*! + \overload + + Sets \a top, \a left, \a bottom and \a right to the margins of the + printer. On Unix, this is a best-effort guess, not based on + perfect knowledge. + + If you have called setFullPage( TRUE ), the four values specify + the smallest sane margins you can use. + + If you have called setFullPage( FALSE ) (this is the default), + the margins are automatically subtracted from the pageSize() by + TQPrinter. + + \sa setFullPage() TQPaintDeviceMetrics PageSize +*/ +void TQPrinter::margins( uint *top, uint *left, uint *bottom, uint *right ) const +{ + if ( !D->marginsSpecified ) { + int x = orient == Portrait ? res/2 : res/3; + int y = orient == Portrait ? res/3 : res/2; + *top = *bottom = y; + *left = *right = x; + } else { + *top = D->topMargin; + *left = D->leftMargin; + *bottom = D->bottomMargin; + *right = D->rightMargin; + } +} + +/*! + Sets the printer margins to the sizes specified in \a top, \a left, + \a bottom and \a right. + + This function currently only has an effect on Unix systems. + + \sa margins() +*/ +void TQPrinter::setMargins( uint top, uint left, uint bottom, uint right ) +{ + D->topMargin = top; + D->leftMargin = left; + D->bottomMargin = bottom; + D->rightMargin = right; + D->marginsSpecified = TRUE; +} + +#endif diff --git a/src/kernel/tqrect.cpp b/src/kernel/tqrect.cpp new file mode 100644 index 000000000..9e45f1fab --- /dev/null +++ b/src/kernel/tqrect.cpp @@ -0,0 +1,960 @@ +/**************************************************************************** +** +** Implementation of TQRect class +** +** Created : 931028 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#define TQRECT_C +#include "tqrect.h" +#include "tqdatastream.h" + +/*! + \class TQRect + \brief The TQRect class defines a rectangle in the plane. + + \ingroup images + \ingroup graphics + \mainclass + + A rectangle is internally represented as an upper-left corner and + a bottom-right corner, but it is normally expressed as an + upper-left corner and a size. + + The coordinate type is TQCOORD (defined in \c ntqwindowdefs.h as \c + int). The minimum value of TQCOORD is TQCOORD_MIN (-2147483648) and + the maximum value is TQCOORD_MAX (2147483647). + + Note that the size (width and height) of a rectangle might be + different from what you are used to. If the top-left corner and + the bottom-right corner are the same, the height and the width of + the rectangle will both be 1. + + Generally, \e{width = right - left + 1} and \e{height = bottom - + top + 1}. We designed it this way to make it correspond to + rectangular spaces used by drawing functions in which the width + and height denote a number of pixels. For example, drawing a + rectangle with width and height 1 draws a single pixel. + + The default coordinate system has origin (0, 0) in the top-left + corner. The positive direction of the y axis is down, and the + positive x axis is from left to right. + + A TQRect can be constructed with a set of left, top, width and + height integers, from two TQPoints or from a TQPoint and a TQSize. + After creation the dimensions can be changed, e.g. with setLeft(), + setRight(), setTop() and setBottom(), or by setting sizes, e.g. + setWidth(), setHeight() and setSize(). The dimensions can also be + changed with the move functions, e.g. moveBy(), moveCenter(), + moveBottomRight(), etc. You can also add coordinates to a + rectangle with addCoords(). + + You can test to see if a TQRect contains a specific point with + contains(). You can also test to see if two TQRects intersect with + intersects() (see also intersect()). To get the bounding rectangle + of two TQRects use unite(). + + \sa TQPoint, TQSize +*/ + + +/***************************************************************************** + TQRect member functions + *****************************************************************************/ + +/*! + \fn TQRect::TQRect() + + Constructs an invalid rectangle. +*/ + +/*! + Constructs a rectangle with \a topLeft as the top-left corner and + \a bottomRight as the bottom-right corner. +*/ + +TQRect::TQRect( const TQPoint &topLeft, const TQPoint &bottomRight ) +{ + x1 = (TQCOORD)topLeft.x(); + y1 = (TQCOORD)topLeft.y(); + x2 = (TQCOORD)bottomRight.x(); + y2 = (TQCOORD)bottomRight.y(); +} + +/*! + Constructs a rectangle with \a topLeft as the top-left corner and + \a size as the rectangle size. +*/ + +TQRect::TQRect( const TQPoint &topLeft, const TQSize &size ) +{ + x1 = (TQCOORD)topLeft.x(); + y1 = (TQCOORD)topLeft.y(); + x2 = (TQCOORD)(x1+size.width()-1); + y2 = (TQCOORD)(y1+size.height()-1); +} + +/*! + \fn TQRect::TQRect( int left, int top, int width, int height ) + + Constructs a rectangle with the \a top, \a left corner and \a + width and \a height. + + Example (creates three identical rectangles): + \code + TQRect r1( TQPoint(100,200), TQPoint(110,215) ); + TQRect r2( TQPoint(100,200), TQSize(11,16) ); + TQRect r3( 100, 200, 11, 16 ); + \endcode +*/ + + +/*! + \fn bool TQRect::isNull() const + + Returns TRUE if the rectangle is a null rectangle; otherwise + returns FALSE. + + A null rectangle has both the width and the height set to 0, that + is right() == left() - 1 and bottom() == top() - 1. + + Note that if right() == left() and bottom() == top(), then the + rectangle has width 1 and height 1. + + A null rectangle is also empty. + + A null rectangle is not valid. + + \sa isEmpty(), isValid() +*/ + +/*! + \fn bool TQRect::isEmpty() const + + Returns TRUE if the rectangle is empty; otherwise returns FALSE. + + An empty rectangle has a left() \> right() or top() \> bottom(). + + An empty rectangle is not valid. \c{isEmpty() == !isValid()} + + \sa isNull(), isValid(), normalize() +*/ + +/*! + \fn bool TQRect::isValid() const + + Returns TRUE if the rectangle is valid; otherwise returns FALSE. + + A valid rectangle has a left() \<= right() and top() \<= bottom(). + + Note that non-trivial operations like intersections are not defined + for invalid rectangles. + + \c{isValid() == !isEmpty()} + + \sa isNull(), isEmpty(), normalize() +*/ + + +/*! + Returns a normalized rectangle, i.e. a rectangle that has a + non-negative width and height. + + It swaps left and right if left() \> right(), and swaps top and + bottom if top() \> bottom(). + + \sa isValid() +*/ + +TQRect TQRect::normalize() const +{ + TQRect r; + if ( x2 < x1 ) { // swap bad x values + r.x1 = x2; + r.x2 = x1; + } else { + r.x1 = x1; + r.x2 = x2; + } + if ( y2 < y1 ) { // swap bad y values + r.y1 = y2; + r.y2 = y1; + } else { + r.y1 = y1; + r.y2 = y2; + } + return r; +} + + +/*! + \fn int TQRect::left() const + + Returns the left coordinate of the rectangle. Identical to x(). + + \sa setLeft(), right(), topLeft(), bottomLeft() +*/ + +/*! + \fn int TQRect::top() const + + Returns the top coordinate of the rectangle. Identical to y(). + + \sa setTop(), bottom(), topLeft(), topRight() +*/ + +/*! + \fn int TQRect::right() const + + Returns the right coordinate of the rectangle. + + \sa setRight(), left(), topRight(), bottomRight() +*/ + +/*! + \fn int TQRect::bottom() const + + Returns the bottom coordinate of the rectangle. + + \sa setBottom(), top(), bottomLeft(), bottomRight() +*/ + +/*! + \fn TQCOORD &TQRect::rLeft() + + Returns a reference to the left coordinate of the rectangle. + + \sa rTop(), rRight(), rBottom() +*/ + +/*! + \fn TQCOORD &TQRect::rTop() + + Returns a reference to the top coordinate of the rectangle. + + \sa rLeft(), rRight(), rBottom() +*/ + +/*! + \fn TQCOORD &TQRect::rRight() + + Returns a reference to the right coordinate of the rectangle. + + \sa rLeft(), rTop(), rBottom() +*/ + +/*! + \fn TQCOORD &TQRect::rBottom() + + Returns a reference to the bottom coordinate of the rectangle. + + \sa rLeft(), rTop(), rRight() +*/ + +/*! + \fn int TQRect::x() const + + Returns the left coordinate of the rectangle. Identical to left(). + + \sa left(), y(), setX() +*/ + +/*! + \fn int TQRect::y() const + + Returns the top coordinate of the rectangle. Identical to top(). + + \sa top(), x(), setY() +*/ + +/*! + \fn void TQRect::setLeft( int pos ) + + Sets the left edge of the rectangle to \a pos. May change the + width, but will never change the right edge of the rectangle. + + Identical to setX(). + + \sa left(), setTop(), setWidth() +*/ + +/*! + \fn void TQRect::setTop( int pos ) + + Sets the top edge of the rectangle to \a pos. May change the + height, but will never change the bottom edge of the rectangle. + + Identical to setY(). + + \sa top(), setBottom(), setHeight() +*/ + +/*! + \fn void TQRect::setRight( int pos ) + + Sets the right edge of the rectangle to \a pos. May change the + width, but will never change the left edge of the rectangle. + + \sa right(), setLeft(), setWidth() +*/ + +/*! + \fn void TQRect::setBottom( int pos ) + + Sets the bottom edge of the rectangle to \a pos. May change the + height, but will never change the top edge of the rectangle. + + \sa bottom(), setTop(), setHeight() +*/ + +/*! + \fn void TQRect::setX( int x ) + + Sets the x position of the rectangle (its left end) to \a x. May + change the width, but will never change the right edge of the + rectangle. + + Identical to setLeft(). + + \sa x(), setY() +*/ + +/*! + \fn void TQRect::setY( int y ) + + Sets the y position of the rectangle (its top) to \a y. May change + the height, but will never change the bottom edge of the + rectangle. + + Identical to setTop(). + + \sa y(), setX() +*/ + +/*! + Set the top-left corner of the rectangle to \a p. May change + the size, but will the never change the bottom-right corner of + the rectangle. + + \sa topLeft(), moveTopLeft(), setBottomRight(), setTopRight(), setBottomLeft() +*/ +void TQRect::setTopLeft( const TQPoint &p ) +{ + setLeft( p.x() ); + setTop( p.y() ); +} + +/*! + Set the bottom-right corner of the rectangle to \a p. May change + the size, but will the never change the top-left corner of + the rectangle. + + \sa bottomRight(), moveBottomRight(), setTopLeft(), setTopRight(), setBottomLeft() +*/ +void TQRect::setBottomRight( const TQPoint &p ) +{ + setRight( p.x() ); + setBottom( p.y() ); +} + +/*! + Set the top-right corner of the rectangle to \a p. May change + the size, but will the never change the bottom-left corner of + the rectangle. + + \sa topRight(), moveTopRight(), setTopLeft(), setBottomRight(), setBottomLeft() +*/ +void TQRect::setTopRight( const TQPoint &p ) +{ + setRight( p.x() ); + setTop( p.y() ); +} + +/*! + Set the bottom-left corner of the rectangle to \a p. May change + the size, but will the never change the top-right corner of + the rectangle. + + \sa bottomLeft(), moveBottomLeft(), setTopLeft(), setBottomRight(), setTopRight() +*/ +void TQRect::setBottomLeft( const TQPoint &p ) +{ + setLeft( p.x() ); + setBottom( p.y() ); +} + +/*! + \fn TQPoint TQRect::topLeft() const + + Returns the top-left position of the rectangle. + + \sa setTopLeft(), moveTopLeft(), bottomRight(), left(), top() +*/ + +/*! + \fn TQPoint TQRect::bottomRight() const + + Returns the bottom-right position of the rectangle. + + \sa setBottomRight(), moveBottomRight(), topLeft(), right(), bottom() +*/ + +/*! + \fn TQPoint TQRect::topRight() const + + Returns the top-right position of the rectangle. + + \sa setTopRight(), moveTopRight(), bottomLeft(), top(), right() +*/ + +/*! + \fn TQPoint TQRect::bottomLeft() const + + Returns the bottom-left position of the rectangle. + + \sa setBottomLeft(), moveBottomLeft(), topRight(), bottom(), left() +*/ + +/*! + \fn TQPoint TQRect::center() const + + Returns the center point of the rectangle. + + \sa moveCenter(), topLeft(), bottomRight(), topRight(), bottomLeft() +*/ + + +/*! + Extracts the rectangle parameters as the position \a *x, \a *y and + width \a *w and height \a *h. + + \sa setRect(), coords() +*/ + +void TQRect::rect( int *x, int *y, int *w, int *h ) const +{ + *x = x1; + *y = y1; + *w = x2-x1+1; + *h = y2-y1+1; +} + +/*! + Extracts the rectangle parameters as the top-left point \a *xp1, + \a *yp1 and the bottom-right point \a *xp2, \a *yp2. + + \sa setCoords(), rect() +*/ + +void TQRect::coords( int *xp1, int *yp1, int *xp2, int *yp2 ) const +{ + *xp1 = x1; + *yp1 = y1; + *xp2 = x2; + *yp2 = y2; +} + + +/*! + Sets the left position of the rectangle to \a pos, leaving the + size unchanged. + + \sa left(), setLeft(), moveTop(), moveRight(), moveBottom() +*/ +void TQRect::moveLeft( int pos ) +{ + x2 += (TQCOORD)(pos - x1); + x1 = (TQCOORD)pos; +} + +/*! + Sets the top position of the rectangle to \a pos, leaving the + size unchanged. + + \sa top(), setTop(), moveLeft(), moveRight(), moveBottom() +*/ + +void TQRect::moveTop( int pos ) +{ + y2 += (TQCOORD)(pos - y1); + y1 = (TQCOORD)pos; +} + +/*! + Sets the right position of the rectangle to \a pos, leaving the + size unchanged. + + \sa right(), setRight(), moveLeft(), moveTop(), moveBottom() +*/ + +void TQRect::moveRight( int pos ) +{ + x1 += (TQCOORD)(pos - x2); + x2 = (TQCOORD)pos; +} + +/*! + Sets the bottom position of the rectangle to \a pos, leaving the + size unchanged. + + \sa bottom(), setBottom(), moveLeft(), moveTop(), moveRight() +*/ + +void TQRect::moveBottom( int pos ) +{ + y1 += (TQCOORD)(pos - y2); + y2 = (TQCOORD)pos; +} + +/*! + Sets the top-left position of the rectangle to \a p, leaving the + size unchanged. + + \sa topLeft(), setTopLeft(), moveBottomRight(), moveTopRight(), moveBottomLeft() +*/ + +void TQRect::moveTopLeft( const TQPoint &p ) +{ + moveLeft( p.x() ); + moveTop( p.y() ); +} + +/*! + Sets the bottom-right position of the rectangle to \a p, leaving + the size unchanged. + + \sa bottomRight(), setBottomRight(), moveTopLeft(), moveTopRight(), moveBottomLeft() +*/ + +void TQRect::moveBottomRight( const TQPoint &p ) +{ + moveRight( p.x() ); + moveBottom( p.y() ); +} + +/*! + Sets the top-right position of the rectangle to \a p, leaving the + size unchanged. + + \sa topRight(), setTopRight(), moveTopLeft(), moveBottomRight(), moveBottomLeft() +*/ + +void TQRect::moveTopRight( const TQPoint &p ) +{ + moveRight( p.x() ); + moveTop( p.y() ); +} + +/*! + Sets the bottom-left position of the rectangle to \a p, leaving + the size unchanged. + + \sa bottomLeft(), setBottomLeft(), moveTopLeft(), moveBottomRight(), moveTopRight() +*/ + +void TQRect::moveBottomLeft( const TQPoint &p ) +{ + moveLeft( p.x() ); + moveBottom( p.y() ); +} + + +/*! + Sets the center point of the rectangle to \a p, leaving the size + unchanged. + + \sa center(), moveTopLeft(), moveBottomRight(), moveTopRight(), moveBottomLeft() +*/ + +void TQRect::moveCenter( const TQPoint &p ) +{ + TQCOORD w = x2 - x1; + TQCOORD h = y2 - y1; + x1 = (TQCOORD)(p.x() - w/2); + y1 = (TQCOORD)(p.y() - h/2); + x2 = x1 + w; + y2 = y1 + h; +} + + +/*! + Moves the rectangle \a dx along the x axis and \a dy along the y + axis, relative to the current position. Positive values move the + rectangle to the right and down. + + \sa moveTopLeft() +*/ + +void TQRect::moveBy( int dx, int dy ) +{ + x1 += (TQCOORD)dx; + y1 += (TQCOORD)dy; + x2 += (TQCOORD)dx; + y2 += (TQCOORD)dy; +} + +/*! + Sets the coordinates of the rectangle's top-left corner to \a (x, + y), and its size to \a (w, h). + + \sa rect(), setCoords() +*/ + +void TQRect::setRect( int x, int y, int w, int h ) +{ + x1 = (TQCOORD)x; + y1 = (TQCOORD)y; + x2 = (TQCOORD)(x+w-1); + y2 = (TQCOORD)(y+h-1); +} + +/*! + Sets the coordinates of the rectangle's top-left corner to \a + (xp1, yp1), and the coordinates of its bottom-right corner to \a + (xp2, yp2). + + \sa coords(), setRect() +*/ + +void TQRect::setCoords( int xp1, int yp1, int xp2, int yp2 ) +{ + x1 = (TQCOORD)xp1; + y1 = (TQCOORD)yp1; + x2 = (TQCOORD)xp2; + y2 = (TQCOORD)yp2; +} + +/*! + Adds \a xp1, \a yp1, \a xp2 and \a yp2 respectively to the + existing coordinates of the rectangle. +*/ + +void TQRect::addCoords( int xp1, int yp1, int xp2, int yp2 ) +{ + x1 += (TQCOORD)xp1; + y1 += (TQCOORD)yp1; + x2 += (TQCOORD)xp2; + y2 += (TQCOORD)yp2; +} + +/*! + \fn TQSize TQRect::size() const + + Returns the size of the rectangle. + + \sa width(), height() +*/ + +/*! + \fn int TQRect::width() const + + Returns the width of the rectangle. The width includes both the + left and right edges, i.e. width = right - left + 1. + + \sa height(), size(), setHeight() +*/ + +/*! + \fn int TQRect::height() const + + Returns the height of the rectangle. The height includes both the + top and bottom edges, i.e. height = bottom - top + 1. + + \sa width(), size(), setHeight() +*/ + +/*! + Sets the width of the rectangle to \a w. The right edge is + changed, but not the left edge. + + \sa width(), setLeft(), setRight(), setSize() +*/ + +void TQRect::setWidth( int w ) +{ + x2 = (TQCOORD)(x1 + w - 1); +} + +/*! + Sets the height of the rectangle to \a h. The top edge is not + moved, but the bottom edge may be moved. + + \sa height(), setTop(), setBottom(), setSize() +*/ + +void TQRect::setHeight( int h ) +{ + y2 = (TQCOORD)(y1 + h - 1); +} + +/*! + Sets the size of the rectangle to \a s. The top-left corner is not + moved. + + \sa size(), setWidth(), setHeight() +*/ + +void TQRect::setSize( const TQSize &s ) +{ + x2 = (TQCOORD)(s.width() +x1-1); + y2 = (TQCOORD)(s.height()+y1-1); +} + +/*! + Returns TRUE if the point \a p is inside or on the edge of the + rectangle; otherwise returns FALSE. + + If \a proper is TRUE, this function returns TRUE only if \a p is + inside (not on the edge). +*/ + +bool TQRect::contains( const TQPoint &p, bool proper ) const +{ + if ( proper ) + return p.x() > x1 && p.x() < x2 && + p.y() > y1 && p.y() < y2; + else + return p.x() >= x1 && p.x() <= x2 && + p.y() >= y1 && p.y() <= y2; +} + +/*! + \overload bool TQRect::contains( int x, int y, bool proper ) const + + Returns TRUE if the point \a x, \a y is inside this rectangle; + otherwise returns FALSE. + + If \a proper is TRUE, this function returns TRUE only if the point + is entirely inside (not on the edge). +*/ + +/*! + \overload bool TQRect::contains( int x, int y ) const + + Returns TRUE if the point \a x, \a y is inside this rectangle; + otherwise returns FALSE. +*/ + +/*! + \overload + + Returns TRUE if the rectangle \a r is inside this rectangle; + otherwise returns FALSE. + + If \a proper is TRUE, this function returns TRUE only if \a r is + entirely inside (not on the edge). + + \sa unite(), intersect(), intersects() +*/ + +bool TQRect::contains( const TQRect &r, bool proper ) const +{ + if ( proper ) + return r.x1 > x1 && r.x2 < x2 && r.y1 > y1 && r.y2 < y2; + else + return r.x1 >= x1 && r.x2 <= x2 && r.y1 >= y1 && r.y2 <= y2; +} + +/*! + Unites this rectangle with rectangle \a r. +*/ +TQRect& TQRect::operator|=(const TQRect &r) +{ + *this = *this | r; + return *this; +} + +/*! + Intersects this rectangle with rectangle \a r. +*/ +TQRect& TQRect::operator&=(const TQRect &r) +{ + *this = *this & r; + return *this; +} + + +/*! + Returns the bounding rectangle of this rectangle and rectangle \a + r. + + The bounding rectangle of a nonempty rectangle and an empty or + invalid rectangle is defined to be the nonempty rectangle. + + \sa operator|=(), operator&(), intersects(), contains() +*/ + +TQRect TQRect::operator|(const TQRect &r) const +{ + if ( isValid() ) { + if ( r.isValid() ) { + TQRect tmp; + tmp.setLeft( TQMIN( x1, r.x1 ) ); + tmp.setRight( TQMAX( x2, r.x2 ) ); + tmp.setTop( TQMIN( y1, r.y1 ) ); + tmp.setBottom( TQMAX( y2, r.y2 ) ); + return tmp; + } else { + return *this; + } + } else { + return r; + } +} + +/*! + Returns the bounding rectangle of this rectangle and rectangle \a + r. \c{r.unite(s)} is equivalent to \c{r|s}. +*/ +TQRect TQRect::unite( const TQRect &r ) const +{ + return *this | r; +} + + +/*! + Returns the intersection of this rectangle and rectangle \a r. + + Returns an empty rectangle if there is no intersection. + + \sa operator&=(), operator|(), isEmpty(), intersects(), contains() +*/ + +TQRect TQRect::operator&( const TQRect &r ) const +{ + TQRect tmp; + tmp.x1 = TQMAX( x1, r.x1 ); + tmp.x2 = TQMIN( x2, r.x2 ); + tmp.y1 = TQMAX( y1, r.y1 ); + tmp.y2 = TQMIN( y2, r.y2 ); + return tmp; +} + +/*! + Returns the intersection of this rectangle and rectangle \a r. + \c{r.intersect(s)} is equivalent to \c{r&s}. +*/ +TQRect TQRect::intersect( const TQRect &r ) const +{ + return *this & r; +} + +/*! + Returns TRUE if this rectangle intersects with rectangle \a r + (there is at least one pixel that is within both rectangles); + otherwise returns FALSE. + + \sa intersect(), contains() +*/ + +bool TQRect::intersects( const TQRect &r ) const +{ + return ( TQMAX( x1, r.x1 ) <= TQMIN( x2, r.x2 ) && + TQMAX( y1, r.y1 ) <= TQMIN( y2, r.y2 ) ); +} + + +/*! + \relates TQRect + + Returns TRUE if \a r1 and \a r2 are equal; otherwise returns FALSE. +*/ + +bool operator==( const TQRect &r1, const TQRect &r2 ) +{ + return r1.x1==r2.x1 && r1.x2==r2.x2 && r1.y1==r2.y1 && r1.y2==r2.y2; +} + +/*! + \relates TQRect + + Returns TRUE if \a r1 and \a r2 are different; otherwise returns FALSE. +*/ + +bool operator!=( const TQRect &r1, const TQRect &r2 ) +{ + return r1.x1!=r2.x1 || r1.x2!=r2.x2 || r1.y1!=r2.y1 || r1.y2!=r2.y2; +} + + +/***************************************************************************** + TQRect stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +/*! + \relates TQRect + + Writes the TQRect, \a r, to the stream \a s, and returns a + reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQRect &r ) +{ + if ( s.version() == 1 ) + s << (TQ_INT16)r.left() << (TQ_INT16)r.top() + << (TQ_INT16)r.right() << (TQ_INT16)r.bottom(); + else + s << (TQ_INT32)r.left() << (TQ_INT32)r.top() + << (TQ_INT32)r.right() << (TQ_INT32)r.bottom(); + return s; +} + +/*! + \relates TQRect + + Reads a TQRect from the stream \a s into rect \a r and returns a + reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQRect &r ) +{ + if ( s.version() == 1 ) { + TQ_INT16 x1, y1, x2, y2; + s >> x1; s >> y1; s >> x2; s >> y2; + r.setCoords( x1, y1, x2, y2 ); + } + else { + TQ_INT32 x1, y1, x2, y2; + s >> x1; s >> y1; s >> x2; s >> y2; + r.setCoords( x1, y1, x2, y2 ); + } + return s; +} +#endif // TQT_NO_DATASTREAM diff --git a/src/kernel/tqrect.h b/src/kernel/tqrect.h new file mode 100644 index 000000000..d7dd2886b --- /dev/null +++ b/src/kernel/tqrect.h @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Definition of TQRect class +** +** Created : 931028 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQRECT_H +#define TQRECT_H + +#ifndef QT_H +#include "tqsize.h" +#endif // QT_H + +#if defined(topLeft) +#error "Macro definition of topLeft conflicts with TQRect" +// don't just silently undo people's defines: #undef topLeft +#endif + +class TQ_EXPORT TQRect // rectangle class +{ +public: + TQRect() { x1 = y1 = 0; x2 = y2 = -1; } + TQRect( const TQPoint &topleft, const TQPoint &bottomright ); + TQRect( const TQPoint &topleft, const TQSize &size ); + TQRect( int left, int top, int width, int height ); + + bool isNull() const; + bool isEmpty() const; + bool isValid() const; + TQRect normalize() const; + + int left() const; + int top() const; + int right() const; + int bottom() const; + + TQCOORD &rLeft(); + TQCOORD &rTop(); + TQCOORD &rRight(); + TQCOORD &rBottom(); + + int x() const; + int y() const; + void setLeft( int pos ); + void setTop( int pos ); + void setRight( int pos ); + void setBottom( int pos ); + void setX( int x ); + void setY( int y ); + + void setTopLeft( const TQPoint &p ); + void setBottomRight( const TQPoint &p ); + void setTopRight( const TQPoint &p ); + void setBottomLeft( const TQPoint &p ); + + TQPoint topLeft() const; + TQPoint bottomRight() const; + TQPoint topRight() const; + TQPoint bottomLeft() const; + TQPoint center() const; + + void rect( int *x, int *y, int *w, int *h ) const; + void coords( int *x1, int *y1, int *x2, int *y2 ) const; + + void moveLeft( int pos ); + void moveTop( int pos ); + void moveRight( int pos ); + void moveBottom( int pos ); + void moveTopLeft( const TQPoint &p ); + void moveBottomRight( const TQPoint &p ); + void moveTopRight( const TQPoint &p ); + void moveBottomLeft( const TQPoint &p ); + void moveCenter( const TQPoint &p ); + void moveBy( int dx, int dy ); + + void setRect( int x, int y, int w, int h ); + void setCoords( int x1, int y1, int x2, int y2 ); + void addCoords( int x1, int y1, int x2, int y2 ); + + TQSize size() const; + int width() const; + int height() const; + void setWidth( int w ); + void setHeight( int h ); + void setSize( const TQSize &s ); + + TQRect operator|(const TQRect &r) const; + TQRect operator&(const TQRect &r) const; + TQRect& operator|=(const TQRect &r); + TQRect& operator&=(const TQRect &r); + + bool contains( const TQPoint &p, bool proper=FALSE ) const; + bool contains( int x, int y ) const; // inline methods, _don't_ merge these + bool contains( int x, int y, bool proper ) const; + bool contains( const TQRect &r, bool proper=FALSE ) const; + TQRect unite( const TQRect &r ) const; + TQRect intersect( const TQRect &r ) const; + bool intersects( const TQRect &r ) const; + + friend TQ_EXPORT bool operator==( const TQRect &, const TQRect & ); + friend TQ_EXPORT bool operator!=( const TQRect &, const TQRect & ); + +private: +#if defined(TQ_WS_X11) || defined(Q_OS_TEMP) + friend void qt_setCoords( TQRect *r, int xp1, int yp1, int xp2, int yp2 ); +#endif +#if defined(Q_OS_MAC) + TQCOORD y1; + TQCOORD x1; + TQCOORD y2; + TQCOORD x2; +#else + TQCOORD x1; + TQCOORD y1; + TQCOORD x2; + TQCOORD y2; +#endif +}; + +TQ_EXPORT bool operator==( const TQRect &, const TQRect & ); +TQ_EXPORT bool operator!=( const TQRect &, const TQRect & ); + + +/***************************************************************************** + TQRect stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRect & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRect & ); +#endif + +/***************************************************************************** + TQRect inline member functions + *****************************************************************************/ + +inline TQRect::TQRect( int left, int top, int width, int height ) +{ + x1 = (TQCOORD)left; + y1 = (TQCOORD)top; + x2 = (TQCOORD)(left+width-1); + y2 = (TQCOORD)(top+height-1); +} + +inline bool TQRect::isNull() const +{ return x2 == x1-1 && y2 == y1-1; } + +inline bool TQRect::isEmpty() const +{ return x1 > x2 || y1 > y2; } + +inline bool TQRect::isValid() const +{ return x1 <= x2 && y1 <= y2; } + +inline int TQRect::left() const +{ return x1; } + +inline int TQRect::top() const +{ return y1; } + +inline int TQRect::right() const +{ return x2; } + +inline int TQRect::bottom() const +{ return y2; } + +inline TQCOORD &TQRect::rLeft() +{ return x1; } + +inline TQCOORD & TQRect::rTop() +{ return y1; } + +inline TQCOORD & TQRect::rRight() +{ return x2; } + +inline TQCOORD & TQRect::rBottom() +{ return y2; } + +inline int TQRect::x() const +{ return x1; } + +inline int TQRect::y() const +{ return y1; } + +inline void TQRect::setLeft( int pos ) +{ x1 = (TQCOORD)pos; } + +inline void TQRect::setTop( int pos ) +{ y1 = (TQCOORD)pos; } + +inline void TQRect::setRight( int pos ) +{ x2 = (TQCOORD)pos; } + +inline void TQRect::setBottom( int pos ) +{ y2 = (TQCOORD)pos; } + +inline void TQRect::setX( int x ) +{ x1 = (TQCOORD)x; } + +inline void TQRect::setY( int y ) +{ y1 = (TQCOORD)y; } + +inline TQPoint TQRect::topLeft() const +{ return TQPoint(x1, y1); } + +inline TQPoint TQRect::bottomRight() const +{ return TQPoint(x2, y2); } + +inline TQPoint TQRect::topRight() const +{ return TQPoint(x2, y1); } + +inline TQPoint TQRect::bottomLeft() const +{ return TQPoint(x1, y2); } + +inline TQPoint TQRect::center() const +{ return TQPoint((x1+x2)/2, (y1+y2)/2); } + +inline int TQRect::width() const +{ return x2 - x1 + 1; } + +inline int TQRect::height() const +{ return y2 - y1 + 1; } + +inline TQSize TQRect::size() const +{ return TQSize(x2-x1+1, y2-y1+1); } + +inline bool TQRect::contains( int x, int y, bool proper ) const +{ + if ( proper ) + return x > x1 && x < x2 && + y > y1 && y < y2; + else + return x >= x1 && x <= x2 && + y >= y1 && y <= y2; +} + +inline bool TQRect::contains( int x, int y ) const +{ + return x >= x1 && x <= x2 && + y >= y1 && y <= y2; +} +#define Q_DEFINED_QRECT +#include "ntqwinexport.h" +#endif // TQRECT_H diff --git a/src/kernel/tqregion.cpp b/src/kernel/tqregion.cpp new file mode 100644 index 000000000..c15811ebd --- /dev/null +++ b/src/kernel/tqregion.cpp @@ -0,0 +1,383 @@ +/**************************************************************************** +** +** Implementation of TQRegion class +** +** Created : 950726 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqregion.h" +#include "tqpointarray.h" +#include "tqbuffer.h" +#include "tqdatastream.h" + +// BEING REVISED: paul +/*! + \class TQRegion tqregion.h + \brief The TQRegion class specifies a clip region for a painter. + + \ingroup images + \ingroup graphics + + TQRegion is used with TQPainter::setClipRegion() to limit the paint + area to what needs to be painted. There is also a + TQWidget::repaint() that takes a TQRegion parameter. TQRegion is the + best tool for reducing flicker. + + A region can be created from a rectangle, an ellipse, a polygon or + a bitmap. Complex regions may be created by combining simple + regions using unite(), intersect(), subtract() or eor() (exclusive + or). You can move a region using translate(). + + You can test whether a region isNull(), isEmpty() or if it + contains() a TQPoint or TQRect. The bounding rectangle is given by + boundingRect(). + + The function rects() gives a decomposition of the region into + rectangles. + + Example of using complex regions: + \code + void MyWidget::paintEvent( TQPaintEvent * ) + { + TQPainter p; // our painter + TQRegion r1( TQRect(100,100,200,80), // r1 = elliptic region + TQRegion::Ellipse ); + TQRegion r2( TQRect(100,120,90,30) ); // r2 = rectangular region + TQRegion r3 = r1.intersect( r2 ); // r3 = intersection + p.begin( this ); // start painting widget + p.setClipRegion( r3 ); // set clip region + ... // paint clipped graphics + p.end(); // painting done + } + \endcode + + TQRegion is an \link shclass.html implicitly shared\endlink class. + + \warning Due to window system limitations, the whole coordinate + space for a region is limited to the points between -32767 and + 32767 on Mac OS X and Windows 95/98/ME. + + \sa TQPainter::setClipRegion(), TQPainter::setClipRect() +*/ + + +/*! + \enum TQRegion::RegionType + + Specifies the shape of the region to be created. + + \value Rectangle the region covers the entire rectangle. + \value Ellipse the region is an ellipse inside the rectangle. +*/ + +/*! + \fn Region TQRegion::handle() const + + Returns the region's handle. +*/ + +/***************************************************************************** + TQRegion member functions + *****************************************************************************/ + +/*! + Constructs a rectangular or elliptic region. + + If \a t is \c Rectangle, the region is the filled rectangle (\a x, + \a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled + ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size + (\a w ,\a h ). +*/ +TQRegion::TQRegion( int x, int y, int w, int h, RegionType t ) +{ + TQRegion tmp(TQRect(x,y,w,h),t); + tmp.data->ref(); + data = tmp.data; +} + +/*! + Detaches from shared region data to make sure that this region is + the only one referring to the data. + + \sa copy(), \link shclass.html shared classes\endlink +*/ + +void TQRegion::detach() +{ + if ( data->count != 1 ) + *this = copy(); +} + +#ifndef TQT_NO_DATASTREAM +/* + Executes region commands in the internal buffer and rebuilds the + original region. + + We do this when we read a region from the data stream. + + If \a ver is non-0, uses the format version \a ver on reading the + byte array. +*/ + +void TQRegion::exec( const TQByteArray &buffer, int ver ) +{ + TQBuffer buf( buffer ); + TQDataStream s( &buf ); + if ( ver ) + s.setVersion( ver ); + buf.open( IO_ReadOnly ); + TQRegion rgn; +#if defined(QT_CHECK_STATE) + int test_cnt = 0; +#endif + while ( !s.eof() ) { + TQ_INT32 id; + if ( s.version() == 1 ) { + int id_int; + s >> id_int; + id = id_int; + } else { + s >> id; + } +#if defined(QT_CHECK_STATE) + if ( test_cnt > 0 && id != TQRGN_TRANSLATE ) + tqWarning( "TQRegion::exec: Internal error" ); + test_cnt++; +#endif + if ( id == TQRGN_SETRECT || id == TQRGN_SETELLIPSE ) { + TQRect r; + s >> r; + rgn = TQRegion( r, id == TQRGN_SETRECT ? Rectangle : Ellipse ); + } else if ( id == TQRGN_SETPTARRAY_ALT || id == TQRGN_SETPTARRAY_WIND ) { + TQPointArray a; + s >> a; + rgn = TQRegion( a, id == TQRGN_SETPTARRAY_WIND ); + } else if ( id == TQRGN_TRANSLATE ) { + TQPoint p; + s >> p; + rgn.translate( p.x(), p.y() ); + } else if ( id >= TQRGN_OR && id <= TQRGN_XOR ) { + TQByteArray bop1, bop2; + TQRegion r1, r2; + s >> bop1; r1.exec( bop1 ); + s >> bop2; r2.exec( bop2 ); + switch ( id ) { + case TQRGN_OR: + rgn = r1.unite( r2 ); + break; + case TQRGN_AND: + rgn = r1.intersect( r2 ); + break; + case TQRGN_SUB: + rgn = r1.subtract( r2 ); + break; + case TQRGN_XOR: + rgn = r1.eor( r2 ); + break; + } + } else if ( id == TQRGN_RECTS ) { + // (This is the only form used in TQt 2.0) + TQ_UINT32 n; + s >> n; + TQRect r; + for ( int i=0; i<(int)n; i++ ) { + s >> r; + rgn = rgn.unite( TQRegion(r) ); + } + } + } + buf.close(); + *this = rgn; +} + + +/***************************************************************************** + TQRegion stream functions + *****************************************************************************/ + +/*! + \relates TQRegion + + Writes the region \a r to the stream \a s and returns a reference + to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQRegion &r ) +{ + TQMemArray a = r.rects(); + if ( a.isEmpty() ) { + s << (TQ_UINT32)0; + } else { + if ( s.version() == 1 ) { + int i; + for ( i=(int)a.size()-1; i>0; i-- ) { + s << (TQ_UINT32)(12+i*24); + s << (int)TQRGN_OR; + } + for ( i=0; i<(int)a.size(); i++ ) { + s << (TQ_UINT32)(4+8) << (int)TQRGN_SETRECT << a[i]; + } + } + else { + s << (TQ_UINT32)(4+4+16*a.size()); // 16: storage size of TQRect + s << (TQ_INT32)TQRGN_RECTS; + s << (TQ_UINT32)a.size(); + for ( int i=0; i<(int)a.size(); i++ ) + s << a[i]; + } + } + return s; +} + +/*! + \relates TQRegion + + Reads a region from the stream \a s into \a r and returns a + reference to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQRegion &r ) +{ + TQByteArray b; + s >> b; + r.exec( b, s.version() ); + return s; +} +#endif //TQT_NO_DATASTREAM + +// These are not inline - they can be implemented better on some platforms +// (eg. Windows at least provides 3-variable operations). For now, simple. + + +/*! + Applies the unite() function to this region and \a r. \c r1|r2 is + equivalent to \c r1.unite(r2) + + \sa unite(), operator+() +*/ +const TQRegion TQRegion::operator|( const TQRegion &r ) const + { return unite(r); } + +/*! + Applies the unite() function to this region and \a r. \c r1+r2 is + equivalent to \c r1.unite(r2) + + \sa unite(), operator|() +*/ +const TQRegion TQRegion::operator+( const TQRegion &r ) const + { return unite(r); } + +/*! + Applies the intersect() function to this region and \a r. \c r1&r2 + is equivalent to \c r1.intersect(r2) + + \sa intersect() +*/ +const TQRegion TQRegion::operator&( const TQRegion &r ) const + { return intersect(r); } + +/*! + Applies the subtract() function to this region and \a r. \c r1-r2 + is equivalent to \c r1.subtract(r2) + + \sa subtract() +*/ +const TQRegion TQRegion::operator-( const TQRegion &r ) const + { return subtract(r); } + +/*! + Applies the eor() function to this region and \a r. \c r1^r2 is + equivalent to \c r1.eor(r2) + + \sa eor() +*/ +const TQRegion TQRegion::operator^( const TQRegion &r ) const + { return eor(r); } + +/*! + Applies the unite() function to this region and \a r and assigns + the result to this region. \c r1|=r2 is equivalent to \c + r1=r1.unite(r2) + + \sa unite() +*/ +TQRegion& TQRegion::operator|=( const TQRegion &r ) + { return *this = *this | r; } + +/*! + Applies the unite() function to this region and \a r and assigns + the result to this region. \c r1+=r2 is equivalent to \c + r1=r1.unite(r2) + + \sa intersect() +*/ +TQRegion& TQRegion::operator+=( const TQRegion &r ) + { return *this = *this + r; } + +/*! + Applies the intersect() function to this region and \a r and + assigns the result to this region. \c r1&=r2 is equivalent to \c + r1=r1.intersect(r2) + + \sa intersect() +*/ +TQRegion& TQRegion::operator&=( const TQRegion &r ) + { return *this = *this & r; } + +/*! + Applies the subtract() function to this region and \a r and + assigns the result to this region. \c r1-=r2 is equivalent to \c + r1=r1.subtract(r2) + + \sa subtract() +*/ +TQRegion& TQRegion::operator-=( const TQRegion &r ) + { return *this = *this - r; } + +/*! + Applies the eor() function to this region and \a r and + assigns the result to this region. \c r1^=r2 is equivalent to \c + r1=r1.eor(r2) + + \sa eor() +*/ +TQRegion& TQRegion::operator^=( const TQRegion &r ) + { return *this = *this ^ r; } + diff --git a/src/kernel/tqregion.h b/src/kernel/tqregion.h new file mode 100644 index 000000000..51b3ac9b1 --- /dev/null +++ b/src/kernel/tqregion.h @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Definition of TQRegion class +** +** Created : 940514 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQREGION_H +#define TQREGION_H + +#ifndef QT_H +#include "ntqshared.h" +#include "tqrect.h" +#endif // QT_H + +#ifdef TQ_WS_X11 +struct TQRegionPrivate; +#endif + +class TQ_EXPORT TQRegion +{ +public: + enum RegionType { Rectangle, Ellipse }; + + TQRegion(); + TQRegion( int x, int y, int w, int h, RegionType = Rectangle ); + TQRegion( const TQRect &, RegionType = Rectangle ); + TQRegion( const TQPointArray &, bool winding=FALSE ); + TQRegion( const TQRegion & ); + TQRegion( const TQBitmap & ); + ~TQRegion(); + TQRegion &operator=( const TQRegion & ); + + bool isNull() const; + bool isEmpty() const; + + bool contains( const TQPoint &p ) const; + bool contains( const TQRect &r ) const; + + void translate( int dx, int dy ); + + TQRegion unite( const TQRegion & ) const; + TQRegion intersect( const TQRegion &) const; + TQRegion subtract( const TQRegion & ) const; + TQRegion eor( const TQRegion & ) const; + + TQRect boundingRect() const; + TQMemArray rects() const; + void setRects( const TQRect *, int ); + + const TQRegion operator|( const TQRegion & ) const; + const TQRegion operator+( const TQRegion & ) const; + const TQRegion operator&( const TQRegion & ) const; + const TQRegion operator-( const TQRegion & ) const; + const TQRegion operator^( const TQRegion & ) const; + TQRegion& operator|=( const TQRegion & ); + TQRegion& operator+=( const TQRegion & ); + TQRegion& operator&=( const TQRegion & ); + TQRegion& operator-=( const TQRegion & ); + TQRegion& operator^=( const TQRegion & ); + + bool operator==( const TQRegion & ) const; + bool operator!=( const TQRegion &r ) const + { return !(operator==(r)); } + +#if defined(TQ_WS_WIN) + HRGN handle() const { return data->rgn; } +#elif defined(TQ_WS_X11) + Region handle() const { if(!data->rgn) updateX11Region(); return data->rgn; } +#elif defined(TQ_WS_MAC) + RgnHandle handle(bool require_rgn=FALSE) const; +#endif + +#ifndef TQT_NO_DATASTREAM + friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRegion & ); + friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRegion & ); +#endif +private: + TQRegion( bool ); + TQRegion copy() const; + void detach(); +#if defined(TQ_WS_WIN) + TQRegion winCombine( const TQRegion &, int ) const; +#endif +#if defined(TQ_WS_X11) + void updateX11Region() const; + void *clipRectangles( int &num ) const; + friend void *qt_getClipRects( const TQRegion &, int & ); +#endif + void exec( const TQByteArray &, int ver = 0 ); + struct TQRegionData : public TQShared { +#if defined(TQ_WS_WIN) + HRGN rgn; +#elif defined(TQ_WS_X11) + Region rgn; + void *xrectangles; + TQRegionPrivate *region; +#elif defined(TQ_WS_MAC) + uint is_rect:1; + TQRect rect; + RgnHandle rgn; +#endif + bool is_null; + } *data; +#if defined(TQ_WS_MAC) + friend struct qt_mac_rgn_data_cache; + friend TQRegionData *qt_mac_get_rgn_data(); + friend void qt_mac_free_rgn_data(TQRegionData *); + void rectifyRegion(); +#elif defined(TQ_WS_WIN) + friend class TQETWidget; +#endif + +}; + + +#define TQRGN_SETRECT 1 // region stream commands +#define TQRGN_SETELLIPSE 2 // (these are internal) +#define TQRGN_SETPTARRAY_ALT 3 +#define TQRGN_SETPTARRAY_WIND 4 +#define TQRGN_TRANSLATE 5 +#define TQRGN_OR 6 +#define TQRGN_AND 7 +#define TQRGN_SUB 8 +#define TQRGN_XOR 9 +#define TQRGN_RECTS 10 + + +/***************************************************************************** + TQRegion stream functions + *****************************************************************************/ + +#ifndef TQT_NO_DATASTREAM +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRegion & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRegion & ); +#endif + + +#endif // TQREGION_H diff --git a/src/kernel/tqregion_x11.cpp b/src/kernel/tqregion_x11.cpp new file mode 100644 index 000000000..801aadb6d --- /dev/null +++ b/src/kernel/tqregion_x11.cpp @@ -0,0 +1,2896 @@ +/**************************************************************************** +** +** Implementation of TQRegion class for X11 +** +** Created : 940729 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqregion.h" +#include "tqpointarray.h" +#include "tqbuffer.h" +#include "tqimage.h" +#include "tqbitmap.h" +#include "qt_x11_p.h" + +#include + +// inline TQRect::setCoords +inline void qt_setCoords( TQRect *r, int xp1, int yp1, int xp2, int yp2 ) +{ + r->x1 = (TQCOORD)xp1; + r->y1 = (TQCOORD)yp1; + r->x2 = (TQCOORD)xp2; + r->y2 = (TQCOORD)yp2; +} + +/* + * clip region + */ + +struct TQRegionPrivate { + int numRects; + TQMemArray rects; + TQRect extents; + + TQRegionPrivate() { numRects = 0; } + TQRegionPrivate( const TQRect &r ) : rects(1) { + numRects = 1; + rects[0] = r; + extents = r; + } + + TQRegionPrivate( const TQRegionPrivate &r ) { + rects = r.rects.copy(); + numRects = r.numRects; + extents = r.extents; + } + + TQRegionPrivate &operator=( const TQRegionPrivate &r ) { + rects = r.rects.copy(); + numRects = r.numRects; + extents = r.extents; + return *this; + } + +}; + + +static void UnionRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg); +static void IntersectRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg); +static void miRegionOp(TQRegionPrivate *newReg, TQRegionPrivate *reg1, TQRegionPrivate *reg2, + void (*overlapFunc)(...), + void (*nonOverlap1Func)(...), + void (*nonOverlap2Func)(...)); +#define RectangleOut 0 +#define RectangleIn 1 +#define RectanglePart 2 +#define EvenOddRule 0 +#define WindingRule 1 + +// START OF region.h extract +/* $XConsortium: region.h,v 11.14 94/04/17 20:22:20 rws Exp $ */ +/************************************************************************ + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ + +#ifndef _XREGION_H +#define _XREGION_H + +#include + +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + + +/* 1 if two BOXs overlap. + * 0 if two BOXs do not overlap. + * Remember, x2 and y2 are not in the region + */ +#define EXTENTCHECK(r1, r2) \ + ((r1)->right() >= (r2)->left() && \ + (r1)->left() <= (r2)->right() && \ + (r1)->bottom() >= (r2)->top() && \ + (r1)->top() <= (r2)->bottom()) + +/* + * update region extents + */ +#define EXTENTS(r,idRect){\ + if((r)->left() < (idRect)->extents.left())\ + (idRect)->extents.setLeft( (r)->left() );\ + if((r)->top() < (idRect)->extents.top())\ + (idRect)->extents.setTop( (r)->top() );\ + if((r)->right() > (idRect)->extents.right())\ + (idRect)->extents.setRight( (r)->right() );\ + if((r)->bottom() > (idRect)->extents.bottom())\ + (idRect)->extents.setBottom( (r)->bottom() );\ + } + +/* + * Check to see if there is enough memory in the present region. + */ +#define MEMCHECK(reg, rect, firstrect){\ + if ((reg)->numRects >= (int)((reg)->rects.size()-1)){\ + firstrect.resize(firstrect.size() * 2); \ + (rect) = (firstrect).data() + (reg)->numRects;\ + }\ + } + + +#define EMPTY_REGION(pReg) pReg->numRects = 0 + +#define REGION_NOT_EMPTY(pReg) pReg->numRects + +/* + * number of points to buffer before sending them off + * to scanlines() : Must be an even number + */ +#define NUMPTSTOBUFFER 200 + +/* + * used to allocate buffers for points and link + * the buffers together + */ +typedef struct _POINTBLOCK { + TQPoint pts[NUMPTSTOBUFFER]; + struct _POINTBLOCK *next; +} POINTBLOCK; + +#endif +// END OF region.h extract + +// START OF Region.c extract +/* $XConsortium: Region.c /main/30 1996/10/22 14:21:24 kaleb $ */ +/************************************************************************ + +Copyright (c) 1987, 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ +/* + * The functions in this file implement the Region abstraction, similar to one + * used in the X11 sample server. A Region is simply an area, as the name + * implies, and is implemented as a "y-x-banded" array of rectangles. To + * explain: Each Region is made up of a certain number of rectangles sorted + * by y coordinate first, and then by x coordinate. + * + * Furthermore, the rectangles are banded such that every rectangle with a + * given upper-left y coordinate (y1) will have the same lower-right y + * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it + * will span the entire vertical distance of the band. This means that some + * areas that could be merged into a taller rectangle will be represented as + * several shorter rectangles to account for shorter rectangles to its left + * or right but within its "vertical scope". + * + * An added constraint on the rectangles is that they must cover as much + * horizontal area as possible. E.g. no two rectangles in a band are allowed + * to touch. + * + * Whenever possible, bands will be merged together to cover a greater vertical + * distance (and thus reduce the number of rectangles). Two bands can be merged + * only if the bottom of one touches the top of the other and they have + * rectangles in the same places (of the same width, of course). This maintains + * the y-x-banding that's so nice to have... + */ +/* $XFree86: xc/lib/X11/Region.c,v 1.1.1.2.2.2 1998/10/04 15:22:50 hohndel Exp $ */ + +typedef void (*voidProcp)(...); + + +static +void UnionRectWithRegion(const TQRect *rect, TQRegionPrivate *source, TQRegionPrivate *dest) +{ + TQRegionPrivate region; + + if (!rect->width() || !rect->height()) + return; + region.rects.resize(1); + region.numRects = 1; + region.rects[0] = *rect; + region.extents = *rect; + + UnionRegion(®ion, source, dest); + return; +} + +/*- + *----------------------------------------------------------------------- + * miSetExtents -- + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect b/c they can't figure it out along the + * way or do so easily, as miUnion can. + * + * Results: + * None. + * + * Side Effects: + * The region's 'extents' structure is overwritten. + * + *----------------------------------------------------------------------- + */ +static void +miSetExtents (TQRegionPrivate *pReg) +{ + TQRect *pBox, + *pBoxEnd, + *pExtents; + + if (pReg->numRects == 0) + { + qt_setCoords(&pReg->extents, 0, 0, 0, 0); + return; + } + + pExtents = &pReg->extents; + pBox = pReg->rects.data(); + pBoxEnd = &pBox[pReg->numRects - 1]; + + /* + * Since pBox is the first rectangle in the region, it must have the + * smallest y1 and since pBoxEnd is the last rectangle in the region, + * it must have the largest y2, because of banding. Initialize x1 and + * x2 from pBox and pBoxEnd, resp., as good things to initialize them + * to... + */ + pExtents->setLeft( pBox->left() ); + pExtents->setTop( pBox->top() ); + pExtents->setRight( pBoxEnd->right() ); + pExtents->setBottom( pBoxEnd->bottom() ); + + Q_ASSERT(pExtents->top() <= pExtents->bottom()); + while (pBox <= pBoxEnd) + { + if (pBox->left() < pExtents->left()) + { + pExtents->setLeft( pBox->left() ); + } + if (pBox->right() > pExtents->right()) + { + pExtents->setRight( pBox->right() ); + } + pBox++; + } + Q_ASSERT(pExtents->left() <= pExtents->right()); +} + + +/* TranslateRegion(pRegion, x, y) + translates in place + added by raymond +*/ + +static +int +OffsetRegion(TQRegionPrivate *pRegion, int x, int y) +{ + int nbox; + TQRect *pbox; + + pbox = pRegion->rects.data(); + nbox = pRegion->numRects; + + while(nbox--) + { + pbox->moveBy(x, y); + pbox++; + } + pRegion->extents.moveBy(x, y); + return 1; +} + +/*====================================================================== + * Region Intersection + *====================================================================*/ +/*- + *----------------------------------------------------------------------- + * miIntersectO -- + * Handle an overlapping band for miIntersect. + * + * Results: + * None. + * + * Side Effects: + * Rectangles may be added to the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +int +miIntersectO (TQRegionPrivate *pReg, TQRect *r1, TQRect *r1End, + TQRect *r2, TQRect *r2End, int y1, int y2) +{ + int x1; + int x2; + TQRect *pNextRect; + + pNextRect = pReg->rects.data() + pReg->numRects; + + while ((r1 != r1End) && (r2 != r2End)) + { + x1 = TQMAX(r1->left(),r2->left()); + x2 = TQMIN(r1->right(),r2->right()); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + * There's no need to check for subsumption because the only way + * such a need could arise is if some region has two rectangles + * right next to each other. Since that should never happen... + */ + if (x1 <= x2) + { + Q_ASSERT(y1<=y2); + + MEMCHECK(pReg, pNextRect, pReg->rects) + qt_setCoords( pNextRect, x1, y1, x2, y2 ); + pReg->numRects++; + pNextRect++; + } + + /* + * Need to advance the pointers. Shift the one that extends + * to the right the least, since the other still has a chance to + * overlap with that region's next rectangle, if you see what I mean. + */ + if (r1->right() < r2->right()) + { + r1++; + } + else if (r2->right() < r1->right()) + { + r2++; + } + else + { + r1++; + r2++; + } + } + return 0; /* lint */ +} + +static +void +IntersectRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg) +{ + /* check for trivial reject */ + if ( (!(reg1->numRects)) || (!(reg2->numRects)) || + (!EXTENTCHECK(®1->extents, ®2->extents))) + newReg->numRects = 0; + else + miRegionOp (newReg, reg1, reg2, + (voidProcp) miIntersectO, (voidProcp) NULL, (voidProcp) NULL); + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being the same. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(newReg); + return; +} + +/*====================================================================== + * Generic Region Operator + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miCoalesce -- + * Attempt to merge the boxes in the current band with those in the + * previous one. Used only by miRegionOp. + * + * Results: + * The new index for the previous band. + * + * Side Effects: + * If coalescing takes place: + * - rectangles in the previous band will have their y2 fields + * altered. + * - pReg->numRects will be decreased. + * + *----------------------------------------------------------------------- + */ +/* static int*/ +static +int +miCoalesce (TQRegionPrivate *pReg, int prevStart, int curStart) + //Region pReg; /* Region to coalesce */ + //prevStart; /* Index of start of previous band */ + //curStart; /* Index of start of current band */ +{ + TQRect *pPrevBox; /* Current box in previous band */ + TQRect *pCurBox; /* Current box in current band */ + TQRect *pRegEnd; /* End of region */ + int curNumRects; /* Number of rectangles in current + * band */ + int prevNumRects; /* Number of rectangles in previous + * band */ + int bandY1; /* Y1 coordinate for current band */ + + pRegEnd = pReg->rects.data() + pReg->numRects; + + pPrevBox = pReg->rects.data() + prevStart; + prevNumRects = curStart - prevStart; + + /* + * Figure out how many rectangles are in the current band. Have to do + * this because multiple bands could have been added in miRegionOp + * at the end when one region has been exhausted. + */ + pCurBox = pReg->rects.data() + curStart; + bandY1 = pCurBox->top(); + for (curNumRects = 0; + (pCurBox != pRegEnd) && (pCurBox->top() == bandY1); + curNumRects++) + { + pCurBox++; + } + + if (pCurBox != pRegEnd) + { + /* + * If more than one band was added, we have to find the start + * of the last band added so the next coalescing job can start + * at the right place... (given when multiple bands are added, + * this may be pointless -- see above). + */ + pRegEnd--; + while ((pRegEnd-1)->top() == pRegEnd->top()) + { + pRegEnd--; + } + curStart = pRegEnd - pReg->rects.data(); + pRegEnd = pReg->rects.data() + pReg->numRects; + } + + if ((curNumRects == prevNumRects) && (curNumRects != 0)) { + pCurBox -= curNumRects; + /* + * The bands may only be coalesced if the bottom of the previous + * matches the top scanline of the current. + */ + if (pPrevBox->bottom() == pCurBox->top() - 1) + { + /* + * Make sure the bands have boxes in the same places. This + * assumes that boxes have been added in such a way that they + * cover the most area possible. I.e. two boxes in a band must + * have some horizontal space between them. + */ + do + { + if ((pPrevBox->left() != pCurBox->left()) || + (pPrevBox->right() != pCurBox->right())) + { + /* + * The bands don't line up so they can't be coalesced. + */ + return (curStart); + } + pPrevBox++; + pCurBox++; + prevNumRects -= 1; + } while (prevNumRects != 0); + + pReg->numRects -= curNumRects; + pCurBox -= curNumRects; + pPrevBox -= curNumRects; + + /* + * The bands may be merged, so set the bottom y of each box + * in the previous band to that of the corresponding box in + * the current band. + */ + do + { + pPrevBox->setBottom( pCurBox->bottom() ); + pPrevBox++; + pCurBox++; + curNumRects -= 1; + } while (curNumRects != 0); + + /* + * If only one band was added to the region, we have to backup + * curStart to the start of the previous band. + * + * If more than one band was added to the region, copy the + * other bands down. The assumption here is that the other bands + * came from the same region as the current one and no further + * coalescing can be done on them since it's all been done + * already... curStart is already in the right place. + */ + if (pCurBox == pRegEnd) + { + curStart = prevStart; + } + else + { + do + { + *pPrevBox++ = *pCurBox++; + } while (pCurBox != pRegEnd); + } + + } + } + return (curStart); +} + +/*- + *----------------------------------------------------------------------- + * miRegionOp -- + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect... + * + * Results: + * None. + * + * Side Effects: + * The new region is overwritten. + * + * Notes: + * The idea behind this function is to view the two regions as sets. + * Together they cover a rectangle of area that this function divides + * into horizontal bands where points are covered only by one region + * or by both. For the first case, the nonOverlapFunc is called with + * each the band and the band's upper and lower extents. For the + * second, the overlapFunc is called to process the entire band. It + * is responsible for clipping the rectangles in the band, though + * this function provides the boundaries. + * At the end of each band, the new region is coalesced, if possible, + * to reduce the number of rectangles in the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miRegionOp(TQRegionPrivate *newReg, TQRegionPrivate *reg1, TQRegionPrivate *reg2, + void (*overlapFunc)(...), + void (*nonOverlap1Func)(...), + void (*nonOverlap2Func)(...)) + //Region newReg; /* Place to store result */ + //Region reg1; /* First region in operation */ + //Region reg2; /* 2d region in operation */ + //void (*overlapFunc)(); /* Function to call for over- + //* lapping bands */ + //void (*nonOverlap1Func)(); /* Function to call for non- + //* overlapping bands in region + //* 1 */ + //void (*nonOverlap2Func)(); /* Function to call for non- + //* overlapping bands in region + //* 2 */ +{ + TQRect *r1; /* Pointer into first region */ + TQRect *r2; /* Pointer into 2d region */ + TQRect *r1End; /* End of 1st region */ + TQRect *r2End; /* End of 2d region */ + int ybot; /* Bottom of intersection */ + int ytop; /* Top of intersection */ + int prevBand; /* Index of start of + * previous band in newReg */ + int curBand; /* Index of start of current + * band in newReg */ + TQRect *r1BandEnd; /* End of current band in r1 */ + TQRect *r2BandEnd; /* End of current band in r2 */ + int top; /* Top of non-overlapping + * band */ + int bot; /* Bottom of non-overlapping + * band */ + + /* + * Initialization: + * set r1, r2, r1End and r2End appropriately, preserve the important + * parts of the destination region until the end in case it's one of + * the two source regions, then mark the "new" region empty, allocating + * another array of rectangles for it to use. + */ + r1 = reg1->rects.data(); + r2 = reg2->rects.data(); + r1End = r1 + reg1->numRects; + r2End = r2 + reg2->numRects; + + TQMemArray oldRects = newReg->rects; + + newReg->rects.detach(); + EMPTY_REGION(newReg); + + /* + * Allocate a reasonable number of rectangles for the new region. The idea + * is to allocate enough so the individual functions don't need to + * reallocate and copy the array, which is time consuming, yet we don't + * have to worry about using too much memory. I hope to be able to + * nuke the realloc() at the end of this function eventually. + */ + newReg->rects.resize( TQMAX(reg1->numRects,reg2->numRects) * 2 ); + + /* + * Initialize ybot and ytop. + * In the upcoming loop, ybot and ytop serve different functions depending + * on whether the band being handled is an overlapping or non-overlapping + * band. + * In the case of a non-overlapping band (only one of the regions + * has points in the band), ybot is the bottom of the most recent + * intersection and thus clips the top of the rectangles in that band. + * ytop is the top of the next intersection between the two regions and + * serves to clip the bottom of the rectangles in the current band. + * For an overlapping band (where the two regions intersect), ytop clips + * the top of the rectangles of both regions and ybot clips the bottoms. + */ + if (reg1->extents.top() < reg2->extents.top()) + ybot = reg1->extents.top() - 1; + else + ybot = reg2->extents.top() - 1; + + /* + * prevBand serves to mark the start of the previous band so rectangles + * can be coalesced into larger rectangles. qv. miCoalesce, above. + * In the beginning, there is no previous band, so prevBand == curBand + * (curBand is set later on, of course, but the first band will always + * start at index 0). prevBand and curBand must be indices because of + * the possible expansion, and resultant moving, of the new region's + * array of rectangles. + */ + prevBand = 0; + + do + { + curBand = newReg->numRects; + + /* + * This algorithm proceeds one source-band (as opposed to a + * destination band, which is determined by where the two regions + * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the + * rectangle after the last one in the current band for their + * respective regions. + */ + r1BandEnd = r1; + while ((r1BandEnd != r1End) && (r1BandEnd->top() == r1->top())) + { + r1BandEnd++; + } + + r2BandEnd = r2; + while ((r2BandEnd != r2End) && (r2BandEnd->top() == r2->top())) + { + r2BandEnd++; + } + + /* + * First handle the band that doesn't intersect, if any. + * + * Note that attention is restricted to one band in the + * non-intersecting region at once, so if a region has n + * bands between the current position and the next place it overlaps + * the other, this entire loop will be passed through n times. + */ + if (r1->top() < r2->top()) + { + top = TQMAX(r1->top(),ybot+1); + bot = TQMIN(r1->bottom(),r2->top()-1); + + if ((nonOverlap1Func != (voidProcp)NULL) && bot >= top) + { + (* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot); + } + + ytop = r2->top(); + } + else if (r2->top() < r1->top()) + { + top = TQMAX(r2->top(),ybot+1); + bot = TQMIN(r2->bottom(),r1->top()-1); + + if ((nonOverlap2Func != (voidProcp)NULL) && bot >= top) + { + (* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot); + } + + ytop = r1->top(); + } + else + { + ytop = r1->top(); + } + + /* + * If any rectangles got added to the region, try and coalesce them + * with rectangles from the previous band. Note we could just do + * this test in miCoalesce, but some machines incur a not + * inconsiderable cost for function calls, so... + */ + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * Now see if we've hit an intersecting band. The two bands only + * intersect if ybot >= ytop + */ + ybot = TQMIN(r1->bottom(), r2->bottom()); + curBand = newReg->numRects; + if (ybot >= ytop) + { + (* overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); + + } + + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * If we've finished with a band (y2 == ybot) we skip forward + * in the region to the next band. + */ + if (r1->bottom() == ybot) + { + r1 = r1BandEnd; + } + if (r2->bottom() == ybot) + { + r2 = r2BandEnd; + } + } while ((r1 != r1End) && (r2 != r2End)); + + /* + * Deal with whichever region still has rectangles left. + */ + curBand = newReg->numRects; + if (r1 != r1End) + { + if (nonOverlap1Func != (voidProcp)NULL) + { + do + { + r1BandEnd = r1; + while ((r1BandEnd < r1End) && (r1BandEnd->top() == r1->top())) + { + r1BandEnd++; + } + (* nonOverlap1Func) (newReg, r1, r1BandEnd, + TQMAX(r1->top(),ybot+1), r1->bottom()); + r1 = r1BandEnd; + } while (r1 != r1End); + } + } + else if ((r2 != r2End) && (nonOverlap2Func != (voidProcp)NULL)) + { + do + { + r2BandEnd = r2; + while ((r2BandEnd < r2End) && (r2BandEnd->top() == r2->top())) + { + r2BandEnd++; + } + (* nonOverlap2Func) (newReg, r2, r2BandEnd, + TQMAX(r2->top(),ybot+1), r2->bottom()); + r2 = r2BandEnd; + } while (r2 != r2End); + } + + if (newReg->numRects != curBand) + { + (void) miCoalesce (newReg, prevBand, curBand); + } + + /* + * A bit of cleanup. To keep regions from growing without bound, + * we shrink the array of rectangles to match the new number of + * rectangles in the region. This never goes to 0, however... + * + * Only do this stuff if the number of rectangles allocated is more than + * twice the number of rectangles in the region (a simple optimization...). + */ + if (newReg->numRects < (int)(newReg->rects.size() >> 1)) + { + if (REGION_NOT_EMPTY(newReg)) + { + newReg->rects.resize(newReg->numRects); + } + else + { + /* + * No point in doing the extra work involved in an realloc if + * the region is empty + */ + newReg->rects.resize(1); + } + } + return; +} + + +/*====================================================================== + * Region Union + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miUnionNonO -- + * Handle a non-overlapping band for the union operation. Just + * Adds the rectangles into the region. Doesn't have to check for + * subsumption or anything. + * + * Results: + * None. + * + * Side Effects: + * pReg->numRects is incremented and the final rectangles overwritten + * with the rectangles we're passed. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +int +miUnionNonO (TQRegionPrivate *pReg, TQRect * r, + TQRect * rEnd, int y1, int y2) +{ + TQRect * pNextRect; + + pNextRect = pReg->rects.data() + pReg->numRects; + + Q_ASSERT(y1 <= y2); + + while (r != rEnd) + { + Q_ASSERT(r->left() <= r->right()); + MEMCHECK(pReg, pNextRect, pReg->rects) + qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); + pReg->numRects++; + pNextRect++; + + r++; + } + return 0; /* lint */ +} + + +/*- + *----------------------------------------------------------------------- + * miUnionO -- + * Handle an overlapping band for the union operation. Picks the + * left-most rectangle each time and merges it into the region. + * + * Results: + * None. + * + * Side Effects: + * Rectangles are overwritten in pReg->rects and pReg->numRects will + * be changed. + * + *----------------------------------------------------------------------- + */ + +/* static void*/ +static +int +miUnionO (TQRegionPrivate *pReg, TQRect *r1, TQRect *r1End, + TQRect *r2, TQRect *r2End, int y1, int y2) +{ + TQRect *pNextRect; + + pNextRect = pReg->rects.data() + pReg->numRects; + +#define MERGERECT(r) \ + if ((pReg->numRects != 0) && \ + (pNextRect[-1].top() == y1) && \ + (pNextRect[-1].bottom() == y2) && \ + (pNextRect[-1].right() >= r->left()-1)) { \ + if (pNextRect[-1].right() < r->right()) { \ + pNextRect[-1].setRight( r->right() ); \ + Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \ + } \ + } else { \ + MEMCHECK(pReg, pNextRect, pReg->rects) \ + qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); \ + pReg->numRects++; \ + pNextRect++; \ + } \ + r++; + + Q_ASSERT (y1<=y2); + while ((r1 != r1End) && (r2 != r2End)) { + if (r1->left() < r2->left()) { + MERGERECT(r1) + } else { + MERGERECT(r2) + } + } + + if (r1 != r1End) + { + do + { + MERGERECT(r1) + } while (r1 != r1End); + } + else while (r2 != r2End) + { + MERGERECT(r2) + } + return 0; /* lint */ +} + +static void UnionRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg) +{ + /* checks all the simple cases */ + + /* + * Region 1 and 2 are the same or region 1 is empty + */ + if ( (reg1 == reg2) || (!(reg1->numRects)) ) + { + *newReg = *reg2; + return; + } + + /* + * if nothing to union (region 2 empty) + */ + if (!(reg2->numRects)) + { + *newReg = *reg1; + return; + } + + /* + * Region 1 completely subsumes region 2 + */ + if ((reg1->numRects == 1) && + (reg1->extents.left() <= reg2->extents.left()) && + (reg1->extents.top() <= reg2->extents.top()) && + (reg1->extents.right() >= reg2->extents.right()) && + (reg1->extents.bottom() >= reg2->extents.bottom())) + { + *newReg = *reg1; + return; + } + + /* + * Region 2 completely subsumes region 1 + */ + if ((reg2->numRects == 1) && + (reg2->extents.left() <= reg1->extents.left()) && + (reg2->extents.top() <= reg1->extents.top()) && + (reg2->extents.right() >= reg1->extents.right()) && + (reg2->extents.bottom() >= reg1->extents.bottom())) + { + *newReg = *reg2; + return; + } + + miRegionOp (newReg, reg1, reg2, (voidProcp) miUnionO, + (voidProcp) miUnionNonO, (voidProcp) miUnionNonO); + + qt_setCoords( &newReg->extents, + TQMIN(reg1->extents.left(), reg2->extents.left()), + TQMIN(reg1->extents.top(), reg2->extents.top()), + TQMAX(reg1->extents.right(), reg2->extents.right()), + TQMAX(reg1->extents.bottom(), reg2->extents.bottom()) ); + + return; +} + +/*====================================================================== + * Region Subtraction + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miSubtractNonO -- + * Deal with non-overlapping band for subtraction. Any parts from + * region 2 we discard. Anything from region 1 we add to the region. + * + * Results: + * None. + * + * Side Effects: + * pReg may be affected. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +int +miSubtractNonO1 (TQRegionPrivate *pReg, TQRect *r, + TQRect *rEnd, int y1, int y2) +{ + TQRect *pNextRect; + + pNextRect = pReg->rects.data() + pReg->numRects; + + Q_ASSERT(y1<=y2); + + while (r != rEnd) + { + Q_ASSERT(r->left()<=r->right()); + MEMCHECK(pReg, pNextRect, pReg->rects) + qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); + pReg->numRects++; + pNextRect++; + + r++; + } + return 0; /* lint */ +} + +/*- + *----------------------------------------------------------------------- + * miSubtractO -- + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. + * + * Results: + * None. + * + * Side Effects: + * pReg may have rectangles added to it. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static +int +miSubtractO (TQRegionPrivate *pReg, TQRect *r1, TQRect *r1End, + TQRect *r2, TQRect *r2End, int y1, int y2) +{ + TQRect *pNextRect; + int x1; + + x1 = r1->left(); + + Q_ASSERT(y1<=y2); + pNextRect = pReg->rects.data() + pReg->numRects; + + while ((r1 != r1End) && (r2 != r2End)) + { + if (r2->right() < x1) + { + /* + * Subtrahend missed the boat: go to next subtrahend. + */ + r2++; + } + else if (r2->left() <= x1) + { + /* + * Subtrahend precedes minuend: nuke left edge of minuend. + */ + x1 = r2->right()+1; + if (x1 > r1->right()) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->left(); + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->left() <= r1->right()) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + Q_ASSERT(x1left()); + MEMCHECK(pReg, pNextRect, pReg->rects) + qt_setCoords( pNextRect, x1, y1, r2->left() - 1, y2 ); + pReg->numRects++; + pNextRect++; + + x1 = r2->right() + 1; + if (x1 > r1->right()) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->left(); + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->right() >= x1) + { + MEMCHECK(pReg, pNextRect, pReg->rects) + qt_setCoords( pNextRect, x1, y1, r1->right(), y2 ); + pReg->numRects++; + pNextRect++; + } + r1++; + if ( r1 != r1End ) + x1 = r1->left(); + } + } + + /* + * Add remaining minuend rectangles to region. + */ + while (r1 != r1End) + { + Q_ASSERT(x1<=r1->right()); + MEMCHECK(pReg, pNextRect, pReg->rects) + qt_setCoords( pNextRect, x1, y1, r1->right(), y2 ); + pReg->numRects++; + pNextRect++; + + r1++; + if (r1 != r1End) + { + x1 = r1->left(); + } + } + return 0; /* lint */ +} + +/*- + *----------------------------------------------------------------------- + * miSubtract -- + * Subtract regS from regM and leave the result in regD. + * S stands for subtrahend, M for minuend and D for difference. + * + * Side Effects: + * regD is overwritten. + * + *----------------------------------------------------------------------- + */ + +static void SubtractRegion(TQRegionPrivate *regM, TQRegionPrivate *regS, TQRegionPrivate *regD) +{ + /* check for trivial reject */ + if ( (!(regM->numRects)) || (!(regS->numRects)) || + (!EXTENTCHECK(®M->extents, ®S->extents)) ) + { + *regD = *regM; + return; + } + + miRegionOp (regD, regM, regS, (voidProcp) miSubtractO, + (voidProcp) miSubtractNonO1, (voidProcp) NULL); + + /* + * Can't alter newReg's extents before we call miRegionOp because + * it might be one of the source regions and miRegionOp depends + * on the extents of those regions being the unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents (regD); +} + +static void XorRegion( TQRegionPrivate *sra, TQRegionPrivate *srb, TQRegionPrivate *dr ) +{ + TQRegionPrivate tra, trb; + + SubtractRegion(sra,srb,&tra); + SubtractRegion(srb,sra,&trb); + UnionRegion(&tra,&trb,dr); +} + +/* + * Check to see if two regions are equal + */ +static bool EqualRegion( TQRegionPrivate *r1, TQRegionPrivate *r2 ) +{ + int i; + + if( r1->numRects != r2->numRects ) return FALSE; + else if( r1->numRects == 0 ) return TRUE; + else if ( r1->extents.left() != r2->extents.left() || + r1->extents.right() != r2->extents.right() || + r1->extents.top() != r2->extents.top() || + r1->extents.bottom() != r2->extents.bottom() ) + return FALSE; + else { + TQRect *rr1 = r1->rects.data(); + TQRect *rr2 = r2->rects.data(); + for( i=0; i < r1->numRects; i++, rr1++, rr2++ ) { + if ( rr1->left() != rr2->left() || + rr1->right() != rr2->right() || + rr1->top() != rr2->top() || + rr1->bottom() != rr2->bottom() ) + return FALSE; + } + } + return TRUE; +} + +static bool PointInRegion( TQRegionPrivate *pRegion, int x, int y ) +{ + int i; + + if (pRegion->numRects == 0) + return FALSE; + if (!pRegion->extents.contains(x, y)) + return FALSE; + for (i=0; inumRects; i++) + { + if (pRegion->rects[i].contains(x, y)) + return TRUE; + } + return FALSE; +} + +static bool RectInRegion(TQRegionPrivate *region, + int rx, int ry, unsigned int rwidth, unsigned int rheight) +{ + TQRect *pbox; + TQRect *pboxEnd; + TQRect rect(rx, ry, rwidth, rheight); + TQRect *prect = ▭ + int partIn, partOut; + + /* this is (just) a useful optimization */ + if ((region->numRects == 0) || !EXTENTCHECK(®ion->extents, prect)) + return(RectangleOut); + + partOut = FALSE; + partIn = FALSE; + + /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + for (pbox = region->rects.data(), pboxEnd = pbox + region->numRects; + pbox < pboxEnd; + pbox++) + { + + if (pbox->bottom() < ry) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->top() > ry) + { + partOut = TRUE; /* missed part of rectangle above */ + if (partIn || (pbox->top() > prect->bottom())) + break; + ry = pbox->top(); /* x guaranteed to be == prect->x1 */ + } + + if (pbox->right() < rx) + continue; /* not far enough over yet */ + + if (pbox->left() > rx) + { + partOut = TRUE; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->left() <= prect->right()) + { + partIn = TRUE; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->right() >= prect->right()) + { + ry = pbox->bottom() + 1; /* finished with this band */ + if (ry > prect->bottom()) + break; + rx = prect->left(); /* reset x out to left again */ + } else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + break; + } + + } + + return(partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) : + RectangleOut); +} +// END OF Region.c extract +// START OF poly.h extract +/* $XConsortium: poly.h,v 1.4 94/04/17 20:22:19 rws Exp $ */ +/************************************************************************ + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ + +/* + * This file contains a few macros to help track + * the edge of a filled object. The object is assumed + * to be filled in scanline order, and thus the + * algorithm used is an extension of Bresenham's line + * drawing algorithm which assumes that y is always the + * major axis. + * Since these pieces of code are the same for any filled shape, + * it is more convenient to gather the library in one + * place, but since these pieces of code are also in + * the inner loops of output primitives, procedure call + * overhead is out of the question. + * See the author for a derivation if needed. + */ + + +/* + * In scan converting polygons, we want to choose those pixels + * which are inside the polygon. Thus, we add .5 to the starting + * x coordinate for both left and right edges. Now we choose the + * first pixel which is inside the pgon for the left edge and the + * first pixel which is outside the pgon for the right edge. + * Draw the left pixel, but not the right. + * + * How to add .5 to the starting x coordinate: + * If the edge is moving to the right, then subtract dy from the + * error term from the general form of the algorithm. + * If the edge is moving to the left, then add dy to the error term. + * + * The reason for the difference between edges moving to the left + * and edges moving to the right is simple: If an edge is moving + * to the right, then we want the algorithm to flip immediately. + * If it is moving to the left, then we don't want it to flip until + * we traverse an entire pixel. + */ +#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \ + int dx; /* local storage */ \ +\ + /* \ + * if the edge is horizontal, then it is ignored \ + * and assumed not to be processed. Otherwise, do this stuff. \ + */ \ + if ((dy) != 0) { \ + xStart = (x1); \ + dx = (x2) - xStart; \ + if (dx < 0) { \ + m = dx / (dy); \ + m1 = m - 1; \ + incr1 = -2 * dx + 2 * (dy) * m1; \ + incr2 = -2 * dx + 2 * (dy) * m; \ + d = 2 * m * (dy) - 2 * dx - 2 * (dy); \ + } else { \ + m = dx / (dy); \ + m1 = m + 1; \ + incr1 = 2 * dx - 2 * (dy) * m1; \ + incr2 = 2 * dx - 2 * (dy) * m; \ + d = -2 * m * (dy) + 2 * dx; \ + } \ + } \ +} + +#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \ + if (m1 > 0) { \ + if (d > 0) { \ + minval += m1; \ + d += incr1; \ + } \ + else { \ + minval += m; \ + d += incr2; \ + } \ + } else {\ + if (d >= 0) { \ + minval += m1; \ + d += incr1; \ + } \ + else { \ + minval += m; \ + d += incr2; \ + } \ + } \ +} + + +/* + * This structure contains all of the information needed + * to run the bresenham algorithm. + * The variables may be hardcoded into the declarations + * instead of using this structure to make use of + * register declarations. + */ +typedef struct { + int minor_axis; /* minor axis */ + int d; /* decision variable */ + int m, m1; /* slope and slope+1 */ + int incr1, incr2; /* error increments */ +} BRESINFO; + + +#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \ + BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \ + bres.m, bres.m1, bres.incr1, bres.incr2) + +#define BRESINCRPGONSTRUCT(bres) \ + BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2) + + + +/* + * These are the data structures needed to scan + * convert regions. Two different scan conversion + * methods are available -- the even-odd method, and + * the winding number method. + * The even-odd rule states that a point is inside + * the polygon if a ray drawn from that point in any + * direction will pass through an odd number of + * path segments. + * By the winding number rule, a point is decided + * to be inside the polygon if a ray drawn from that + * point in any direction passes through a different + * number of clockwise and counter-clockwise path + * segments. + * + * These data structures are adapted somewhat from + * the algorithm in (Foley/Van Dam) for scan converting + * polygons. + * The basic algorithm is to start at the top (smallest y) + * of the polygon, stepping down to the bottom of + * the polygon by incrementing the y coordinate. We + * keep a list of edges which the current scanline crosses, + * sorted by x. This list is called the Active Edge Table (AET) + * As we change the y-coordinate, we update each entry in + * in the active edge table to reflect the edges new xcoord. + * This list must be sorted at each scanline in case + * two edges intersect. + * We also keep a data structure known as the Edge Table (ET), + * which keeps track of all the edges which the current + * scanline has not yet reached. The ET is basically a + * list of ScanLineList structures containing a list of + * edges which are entered at a given scanline. There is one + * ScanLineList per scanline at which an edge is entered. + * When we enter a new edge, we move it from the ET to the AET. + * + * From the AET, we can implement the even-odd rule as in + * (Foley/Van Dam). + * The winding number rule is a little trickier. We also + * keep the EdgeTableEntries in the AET linked by the + * nextWETE (winding EdgeTableEntry) link. This allows + * the edges to be linked just as before for updating + * purposes, but only uses the edges linked by the nextWETE + * link as edges representing spans of the polygon to + * drawn (as with the even-odd rule). + */ + +/* + * for the winding number rule + */ +#define CLOCKWISE 1 +#define COUNTERCLOCKWISE -1 + +typedef struct _EdgeTableEntry { + int ymax; /* ycoord at which we exit this edge. */ + BRESINFO bres; /* Bresenham info to run the edge */ + struct _EdgeTableEntry *next; /* next in the list */ + struct _EdgeTableEntry *back; /* for insertion sort */ + struct _EdgeTableEntry *nextWETE; /* for winding num rule */ + int ClockWise; /* flag for winding number rule */ +} EdgeTableEntry; + + +typedef struct _ScanLineList{ + int scanline; /* the scanline represented */ + EdgeTableEntry *edgelist; /* header node */ + struct _ScanLineList *next; /* next in the list */ +} ScanLineList; + + +typedef struct { + int ymax; /* ymax for the polygon */ + int ymin; /* ymin for the polygon */ + ScanLineList scanlines; /* header node */ +} EdgeTable; + + +/* + * Here is a struct to help with storage allocation + * so we can allocate a big chunk at a time, and then take + * pieces from this heap when we need to. + */ +#define SLLSPERBLOCK 25 + +typedef struct _ScanLineListBlock { + ScanLineList SLLs[SLLSPERBLOCK]; + struct _ScanLineListBlock *next; +} ScanLineListBlock; + + + +/* + * + * a few macros for the inner loops of the fill code where + * performance considerations don't allow a procedure call. + * + * Evaluate the given edge at the given scanline. + * If the edge has expired, then we leave it and fix up + * the active edge table; otherwise, we increment the + * x value to be ready for the next scanline. + * The winding number rule is in effect, so we must notify + * the caller when the edge has been removed so he + * can reorder the Winding Active Edge Table. + */ +#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \ + if (pAET->ymax == y) { /* leaving this edge */ \ + pPrevAET->next = pAET->next; \ + pAET = pPrevAET->next; \ + fixWAET = 1; \ + if (pAET) \ + pAET->back = pPrevAET; \ + } \ + else { \ + BRESINCRPGONSTRUCT(pAET->bres) \ + pPrevAET = pAET; \ + pAET = pAET->next; \ + } \ +} + + +/* + * Evaluate the given edge at the given scanline. + * If the edge has expired, then we leave it and fix up + * the active edge table; otherwise, we increment the + * x value to be ready for the next scanline. + * The even-odd rule is in effect. + */ +#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \ + if (pAET->ymax == y) { /* leaving this edge */ \ + pPrevAET->next = pAET->next; \ + pAET = pPrevAET->next; \ + if (pAET) \ + pAET->back = pPrevAET; \ + } \ + else { \ + BRESINCRPGONSTRUCT(pAET->bres) \ + pPrevAET = pAET; \ + pAET = pAET->next; \ + } \ +} +// END OF poly.h extract +// START OF PolyReg.c extract +/* $XConsortium: PolyReg.c,v 11.23 94/11/17 21:59:37 converse Exp $ */ +/************************************************************************ + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ +/* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */ + +#define LARGE_COORDINATE 1000000 +#define SMALL_COORDINATE -LARGE_COORDINATE + +/* + * InsertEdgeInET + * + * Insert the given edge into the edge table. + * First we must find the correct bucket in the + * Edge table, then find the right slot in the + * bucket. Finally, we can insert it. + * + */ +static void +InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline, + ScanLineListBlock **SLLBlock, int *iSLLBlock) +{ + EdgeTableEntry *start, *prev; + ScanLineList *pSLL, *pPrevSLL; + ScanLineListBlock *tmpSLLBlock; + + /* + * find the right bucket to put the edge into + */ + pPrevSLL = &ET->scanlines; + pSLL = pPrevSLL->next; + while (pSLL && (pSLL->scanline < scanline)) + { + pPrevSLL = pSLL; + pSLL = pSLL->next; + } + + /* + * reassign pSLL (pointer to ScanLineList) if necessary + */ + if ((!pSLL) || (pSLL->scanline > scanline)) + { + if (*iSLLBlock > SLLSPERBLOCK-1) + { + tmpSLLBlock = + (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock)); + (*SLLBlock)->next = tmpSLLBlock; + tmpSLLBlock->next = (ScanLineListBlock *)NULL; + *SLLBlock = tmpSLLBlock; + *iSLLBlock = 0; + } + pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); + + pSLL->next = pPrevSLL->next; + pSLL->edgelist = (EdgeTableEntry *)NULL; + pPrevSLL->next = pSLL; + } + pSLL->scanline = scanline; + + /* + * now insert the edge in the right bucket + */ + prev = (EdgeTableEntry *)NULL; + start = pSLL->edgelist; + while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) + { + prev = start; + start = start->next; + } + ETE->next = start; + + if (prev) + prev->next = ETE; + else + pSLL->edgelist = ETE; +} + +/* + * CreateEdgeTable + * + * This routine creates the edge table for + * scan converting polygons. + * The Edge Table (ET) looks like: + * + * EdgeTable + * -------- + * | ymax | ScanLineLists + * |scanline|-->------------>-------------->... + * -------- |scanline| |scanline| + * |edgelist| |edgelist| + * --------- --------- + * | | + * | | + * V V + * list of ETEs list of ETEs + * + * where ETE is an EdgeTableEntry data structure, + * and there is one ScanLineList per scanline at + * which an edge is initially entered. + * + */ + +static void +CreateETandAET(int count, TQPoint *pts, + EdgeTable *ET, EdgeTableEntry *AET, EdgeTableEntry *pETEs, + ScanLineListBlock *pSLLBlock) +{ + TQPoint *top, *bottom; + TQPoint *PrevPt, *CurrPt; + int iSLLBlock = 0; + int dy; + + if (count < 2) return; + + /* + * initialize the Active Edge Table + */ + AET->next = (EdgeTableEntry *)NULL; + AET->back = (EdgeTableEntry *)NULL; + AET->nextWETE = (EdgeTableEntry *)NULL; + AET->bres.minor_axis = SMALL_COORDINATE; + + /* + * initialize the Edge Table. + */ + ET->scanlines.next = (ScanLineList *)NULL; + ET->ymax = SMALL_COORDINATE; + ET->ymin = LARGE_COORDINATE; + pSLLBlock->next = (ScanLineListBlock *)NULL; + + PrevPt = &pts[count-1]; + + /* + * for each vertex in the array of points. + * In this loop we are dealing with two vertices at + * a time -- these make up one edge of the polygon. + */ + while (count--) + { + CurrPt = pts++; + + /* + * find out which point is above and which is below. + */ + if (PrevPt->y() > CurrPt->y() ) + { + bottom = PrevPt, top = CurrPt; + pETEs->ClockWise = 0; + } + else + { + bottom = CurrPt, top = PrevPt; + pETEs->ClockWise = 1; + } + + /* + * don't add horizontal edges to the Edge table. + */ + if ( bottom->y() != top->y() ) + { + pETEs->ymax = bottom->y()-1; /* -1 so we don't get last scanline */ + + /* + * initialize integer edge algorithm + */ + dy = bottom->y() - top->y(); + BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres) + + InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock); + + if (PrevPt->y() > ET->ymax) + ET->ymax = PrevPt->y(); + if (PrevPt->y() < ET->ymin) + ET->ymin = PrevPt->y(); + pETEs++; + } + + PrevPt = CurrPt; + } +} + +/* + * loadAET + * + * This routine moves EdgeTableEntries from the + * EdgeTable into the Active Edge Table, + * leaving them sorted by smaller x coordinate. + * + */ + +static void +loadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs) +{ + EdgeTableEntry *pPrevAET; + EdgeTableEntry *tmp; + + pPrevAET = AET; + AET = AET->next; + while (ETEs) + { + while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) + { + pPrevAET = AET; + AET = AET->next; + } + tmp = ETEs->next; + ETEs->next = AET; + if (AET) + AET->back = ETEs; + ETEs->back = pPrevAET; + pPrevAET->next = ETEs; + pPrevAET = ETEs; + + ETEs = tmp; + } +} + +/* + * computeWAET + * + * This routine links the AET by the + * nextWETE (winding EdgeTableEntry) link for + * use by the winding number rule. The final + * Active Edge Table (AET) might look something + * like: + * + * AET + * ---------- --------- --------- + * |ymax | |ymax | |ymax | + * | ... | |... | |... | + * |next |->|next |->|next |->... + * |nextWETE| |nextWETE| |nextWETE| + * --------- --------- ^-------- + * | | | + * V-------------------> V---> ... + * + */ +static void +computeWAET(EdgeTableEntry *AET) +{ + EdgeTableEntry *pWETE; + int inside = 1; + int isInside = 0; + + AET->nextWETE = (EdgeTableEntry *)NULL; + pWETE = AET; + AET = AET->next; + while (AET) + { + if (AET->ClockWise) + isInside++; + else + isInside--; + + if ((!inside && !isInside) || + ( inside && isInside)) + { + pWETE->nextWETE = AET; + pWETE = AET; + inside = !inside; + } + AET = AET->next; + } + pWETE->nextWETE = (EdgeTableEntry *)NULL; +} + +/* + * InsertionSort + * + * Just a simple insertion sort using + * pointers and back pointers to sort the Active + * Edge Table. + * + */ + +static int +InsertionSort(EdgeTableEntry *AET) +{ + EdgeTableEntry *pETEchase; + EdgeTableEntry *pETEinsert; + EdgeTableEntry *pETEchaseBackTMP; + int changed = 0; + + AET = AET->next; + while (AET) + { + pETEinsert = AET; + pETEchase = AET; + while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) + pETEchase = pETEchase->back; + + AET = AET->next; + if (pETEchase != pETEinsert) + { + pETEchaseBackTMP = pETEchase->back; + pETEinsert->back->next = AET; + if (AET) + AET->back = pETEinsert->back; + pETEinsert->next = pETEchase; + pETEchase->back->next = pETEinsert; + pETEchase->back = pETEinsert; + pETEinsert->back = pETEchaseBackTMP; + changed = 1; + } + } + return(changed); +} + +/* + * Clean up our act. + */ +static void +FreeStorage(ScanLineListBlock *pSLLBlock) +{ + ScanLineListBlock *tmpSLLBlock; + + while (pSLLBlock) + { + tmpSLLBlock = pSLLBlock->next; + free((char *)pSLLBlock); + pSLLBlock = tmpSLLBlock; + } +} + +/* + * Create an array of rectangles from a list of points. + * If indeed these things (POINTS, RECTS) are the same, + * then this proc is still needed, because it allocates + * storage for the array, which was allocated on the + * stack by the calling procedure. + * + */ +static int PtsToRegion(int numFullPtBlocks, int iCurPtBlock, + POINTBLOCK *FirstPtBlock, TQRegionPrivate *reg) +{ + TQRect *rects; + TQPoint *pts; + POINTBLOCK *CurPtBlock; + int i; + TQRect *extents; + int numRects; + + extents = ®->extents; + + numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; + + reg->rects.resize(numRects); + + CurPtBlock = FirstPtBlock; + rects = reg->rects.data() - 1; + numRects = 0; + extents->setLeft( INT_MAX ); + extents->setRight( INT_MIN ); + + for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { + /* the loop uses 2 points per iteration */ + i = NUMPTSTOBUFFER >> 1; + if (!numFullPtBlocks) + i = iCurPtBlock >> 1; + for (pts = CurPtBlock->pts; i--; pts += 2) { + if ( pts->x() == pts[1].x() ) + continue; + if (numRects && pts->x() == rects->left() && pts->y() == rects->bottom() + 1 && + pts[1].x() == rects->right() && + (numRects == 1 || rects[-1].top() != rects->top()) && + (i && pts[2].y() > pts[1].y() )) { + rects->setBottom( pts[1].y() ); + continue; + } + numRects++; + rects++; + qt_setCoords( rects, pts->x(), pts->y(), pts[1].x() - 1, pts[1].y() ); + if (rects->left() < extents->left()) + extents->setLeft( rects->left() ); + if (rects->right() > extents->right()) + extents->setRight( rects->right() ); + } + CurPtBlock = CurPtBlock->next; + } + + if (numRects) { + extents->setTop( reg->rects[0].top() ); + extents->setBottom( rects->bottom() ); + } else { + qt_setCoords(extents, 0, 0, 0, 0); + } + reg->numRects = numRects; + + return(TRUE); +} + +/* + * polytoregion + * + * Scan converts a polygon by returning a run-length + * encoding of the resultant bitmap -- the run-length + * encoding is in the form of an array of rectangles. + */ +static TQRegionPrivate *PolygonRegion(TQPoint *Pts, int Count, int rule) + //Point *Pts; /* the pts */ + //int Count; /* number of pts */ + //int rule; /* winding rule */ +{ + TQRegionPrivate *region; + EdgeTableEntry *pAET; /* Active Edge Table */ + int y; /* current scanline */ + int iPts = 0; /* number of pts in buffer */ + EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ + ScanLineList *pSLL; /* current scanLineList */ + TQPoint *pts; /* output buffer */ + EdgeTableEntry *pPrevAET; /* ptr to previous AET */ + EdgeTable ET; /* header node for ET */ + EdgeTableEntry AET; /* header node for AET */ + EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ + ScanLineListBlock SLLBlock; /* header for scanlinelist */ + int fixWAET = FALSE; + POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ + POINTBLOCK *tmpPtBlock; + int numFullPtBlocks = 0; + + if ( !(region = new TQRegionPrivate) ) + return 0; + + /* special case a rectangle */ + pts = Pts; + if (((Count == 4) || + ((Count == 5) && (pts[4].x() == pts[0].x() ) && (pts[4].y() == pts[0].y() ))) && + (((pts[0].y() == pts[1].y()) && + (pts[1].x() == pts[2].x()) && + (pts[2].y() == pts[3].y()) && + (pts[3].x() == pts[0].x())) || + ((pts[0].x() == pts[1].x()) && + (pts[1].y() == pts[2].y()) && + (pts[2].x() == pts[3].x()) && + (pts[3].y() == pts[0].y())))) { + region->extents.setLeft( TQMIN(pts[0].x(), pts[2].x()) ); + region->extents.setTop( TQMIN(pts[0].y(), pts[2].y()) ); + region->extents.setRight( TQMAX(pts[0].x(), pts[2].x()) ); + region->extents.setBottom( TQMAX(pts[0].y(), pts[2].y()) ); + if ((region->extents.left() <= region->extents.right()) && + (region->extents.top() <= region->extents.bottom())) { + region->numRects = 1; + region->rects.resize(1); + region->rects[0] = region->extents; + } + return region; + } + + if (! (pETEs = (EdgeTableEntry *) + malloc((unsigned) (sizeof(EdgeTableEntry) * Count)))) + return 0; + + pts = FirstPtBlock.pts; + CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock); + pSLL = ET.scanlines.next; + curPtBlock = &FirstPtBlock; + + if (rule == EvenOddRule) { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + + /* + * for each active edge + */ + while (pAET) { + pts->setX( pAET->bres.minor_axis ), pts->setY( y ); + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; + iPts = 0; + } + EVALUATEEDGEEVENODD(pAET, pPrevAET, y) + } + (void) InsertionSort(&AET); + } + } + else { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + computeWAET(&AET); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + pWETE = pAET; + + /* + * for each active edge + */ + while (pAET) { + /* + * add to the buffer only those edges that + * are in the Winding active edge table. + */ + if (pWETE == pAET) { + pts->setX( pAET->bres.minor_axis), pts->setY( y ); + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; iPts = 0; + } + pWETE = pWETE->nextWETE; + } + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) + } + + /* + * recompute the winding active edge table if + * we just resorted or have exited an edge. + */ + if (InsertionSort(&AET) || fixWAET) { + computeWAET(&AET); + fixWAET = FALSE; + } + } + } + FreeStorage(SLLBlock.next); + (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); + for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { + tmpPtBlock = curPtBlock->next; + free((char *)curPtBlock); + curPtBlock = tmpPtBlock; + } + free((char *)pETEs); + return region; +} +// END OF PolyReg.c extract + +TQRegionPrivate *qt_bitmapToRegion(const TQBitmap& bitmap) +{ + TQImage image = bitmap.convertToImage(); + + TQRegionPrivate *region = new TQRegionPrivate; + TQRect xr; + +#define AddSpan \ + { \ + qt_setCoords( &xr, prev1, y, x-1, y ); \ + UnionRectWithRegion( &xr, region, region ); \ + } + + const int zero=0; + bool little = image.bitOrder() == TQImage::LittleEndian; + + int x, y; + for (y=0; yw-8 || byte!=all ) { + if ( little ) { + for ( int b=8; b>0 && x>= 1; + x++; + } + } else { + for ( int b=8; b>0 && xdata; + data->ref(); +} + +/*! \internal + Internal constructor that creates a null region. +*/ + +TQRegion::TQRegion( bool is_null ) +{ + data = new TQRegionData; + TQ_CHECK_PTR( data ); + data->region = new TQRegionPrivate; + data->is_null = is_null; + data->rgn = 0; + data->xrectangles = 0; +} + +/*! + \overload + + Create a region based on the rectange \a r with region type \a t. + + If the rectangle is invalid a null region will be created. + + \sa TQRegion::RegionType +*/ + +TQRegion::TQRegion( const TQRect &r, RegionType t ) +{ + if ( r.isEmpty() ) { + if ( !empty_region ) { // avoid too many allocs + tqAddPostRoutine( cleanup_empty_region ); + empty_region = new TQRegion( TRUE ); + TQ_CHECK_PTR( empty_region ); + } + data = empty_region->data; + data->ref(); + } else { + data = new TQRegionData; + TQ_CHECK_PTR( data ); + data->is_null = FALSE; + data->rgn = 0; + data->xrectangles = 0; + if ( t == Rectangle ) { // rectangular region + data->region = new TQRegionPrivate( r ); + } else if ( t == Ellipse ) { // elliptic region + TQPointArray a; + a.makeEllipse( r.x(), r.y(), r.width(), r.height() ); + data->region = PolygonRegion( (TQPoint*)a.data(), a.size(), + EvenOddRule ); + } + } +} + + +/*! + Constructs a polygon region from the point array \a a. + + If \a winding is TRUE, the polygon region is filled using the + winding algorithm, otherwise the default even-odd fill algorithm + is used. + + This constructor may create complex regions that will slow down + painting when used. +*/ + +TQRegion::TQRegion( const TQPointArray &a, bool winding ) +{ + if (a.size() > 2) { + data = new TQRegionData; + TQ_CHECK_PTR( data ); + data->is_null = FALSE; + data->rgn = 0; + data->xrectangles = 0; + data->region = PolygonRegion( (TQPoint*)a.data(), a.size(), + winding ? WindingRule : EvenOddRule ); + } else { + if ( !empty_region ) { + tqAddPostRoutine( cleanup_empty_region ); + empty_region = new TQRegion( TRUE ); + TQ_CHECK_PTR( empty_region ); + } + data = empty_region->data; + data->ref(); + } +} + + +/*! + Constructs a new region which is equal to region \a r. +*/ + +TQRegion::TQRegion( const TQRegion &r ) +{ + data = r.data; + data->ref(); +} + + +/*! + Constructs a region from the bitmap \a bm. + + The resulting region consists of the pixels in bitmap \a bm that + are \c color1, as if each pixel was a 1 by 1 rectangle. + + This constructor may create complex regions that will slow down + painting when used. Note that drawing masked pixmaps can be done + much faster using TQPixmap::setMask(). +*/ +TQRegion::TQRegion( const TQBitmap & bm ) +{ + if ( bm.isNull() ) { + if ( !empty_region ) { // avoid too many allocs + tqAddPostRoutine( cleanup_empty_region ); + empty_region = new TQRegion( TRUE ); + TQ_CHECK_PTR( empty_region ); + } + data = empty_region->data; + data->ref(); + } else { + data = new TQRegionData; + TQ_CHECK_PTR( data ); + data->is_null = FALSE; + data->rgn = 0; + data->xrectangles = 0; + data->region = qt_bitmapToRegion(bm); + } +} + +/*! + Destroys the region. +*/ + +TQRegion::~TQRegion() +{ + if ( data->deref() ) { + delete data->region; + if ( data->rgn ) + XDestroyRegion( data->rgn ); + if ( data->xrectangles ) + free( data->xrectangles ); + delete data; + } +} + + +/*! + Assigns \a r to this region and returns a reference to the region. +*/ + +TQRegion &TQRegion::operator=( const TQRegion &r ) +{ + r.data->ref(); // beware of r = r + if ( data->deref() ) { + delete data->region; + if ( data->rgn ) + XDestroyRegion( data->rgn ); + if ( data->xrectangles ) + free( data->xrectangles ); + delete data; + } + data = r.data; + return *this; +} + + +/*! + Returns a \link shclass.html deep copy\endlink of the region. + + \sa detach() +*/ + +TQRegion TQRegion::copy() const +{ + TQRegion r( data->is_null ); + *r.data->region = *data->region; + return r; +} + +/*! + Returns TRUE if the region is a null region; otherwise returns + FALSE. + + A null region is a region that has not been initialized. A null + region is always empty. + + \sa isEmpty() +*/ + +bool TQRegion::isNull() const +{ + return data->is_null; +} + + +/*! + Returns TRUE if the region is empty; otherwise returns FALSE. An + empty region is a region that contains no points. + + Example: + \code + TQRegion r1( 10, 10, 20, 20 ); + TQRegion r2( 40, 40, 20, 20 ); + TQRegion r3; + r1.isNull(); // FALSE + r1.isEmpty(); // FALSE + r3.isNull(); // TRUE + r3.isEmpty(); // TRUE + r3 = r1.intersect( r2 ); // r3 = intersection of r1 and r2 + r3.isNull(); // FALSE + r3.isEmpty(); // TRUE + r3 = r1.unite( r2 ); // r3 = union of r1 and r2 + r3.isNull(); // FALSE + r3.isEmpty(); // FALSE + \endcode + + \sa isNull() +*/ + +bool TQRegion::isEmpty() const +{ + return data->is_null || ( data->region->numRects == 0 ); +} + + +/*! + Returns TRUE if the region contains the point \a p; otherwise + returns FALSE. +*/ + +bool TQRegion::contains( const TQPoint &p ) const +{ + return PointInRegion( data->region, p.x(), p.y() ); +} + +/*! + \overload + + Returns TRUE if the region overlaps the rectangle \a r; otherwise + returns FALSE. +*/ + +bool TQRegion::contains( const TQRect &r ) const +{ + return RectInRegion( data->region, r.left(), r.top(), + r.width(), r.height() ) != RectangleOut; +} + + +/*! + Translates (moves) the region \a dx along the X axis and \a dy + along the Y axis. +*/ + +void TQRegion::translate( int dx, int dy ) +{ + if ( empty_region && data == empty_region->data ) + return; + detach(); + OffsetRegion( data->region, dx, dy ); + if ( data->xrectangles ) { + free( data->xrectangles ); + data->xrectangles = 0; + } +} + + +/*! + Returns a region which is the union of this region and \a r. + + \img runion.png Region Union + + The figure shows the union of two elliptical regions. +*/ + +TQRegion TQRegion::unite( const TQRegion &r ) const +{ + TQRegion result( FALSE ); + UnionRegion( data->region, r.data->region, result.data->region ); + return result; +} + +/*! + Returns a region which is the intersection of this region and \a r. + + \img rintersect.png Region Intersection + + The figure shows the intersection of two elliptical regions. +*/ + +TQRegion TQRegion::intersect( const TQRegion &r ) const +{ + TQRegion result( FALSE ); + IntersectRegion( data->region, r.data->region, result.data->region ); + return result; +} + +/*! + Returns a region which is \a r subtracted from this region. + + \img rsubtract.png Region Subtraction + + The figure shows the result when the ellipse on the right is + subtracted from the ellipse on the left. (\c left-right ) +*/ + +TQRegion TQRegion::subtract( const TQRegion &r ) const +{ + TQRegion result( FALSE ); + SubtractRegion( data->region, r.data->region, result.data->region ); + return result; +} + +/*! + Returns a region which is the exclusive or (XOR) of this region + and \a r. + + \img rxor.png Region XORed + + The figure shows the exclusive or of two elliptical regions. +*/ + +TQRegion TQRegion::eor( const TQRegion &r ) const +{ + TQRegion result( FALSE ); + XorRegion( data->region, r.data->region, result.data->region ); + return result; +} + +/*! + Returns the bounding rectangle of this region. An empty region + gives a rectangle that is TQRect::isNull(). +*/ + +TQRect TQRegion::boundingRect() const +{ + return data->region->extents; +} + + +/*! + Returns an array of non-overlapping rectangles that make up the + region. + + The union of all the rectangles is equal to the original region. +*/ + +TQMemArray TQRegion::rects() const +{ + TQMemArray rects; + rects.duplicate( data->region->rects, data->region->numRects ); + return rects; +} + +/*! + Sets the region to be the given set of rectangles. The rectangles + \e must be optimal Y-X sorted bands as follows: +
    +
  • The rectangles must not intersect +
  • All rectangles with a given top coordinate must have the same height. +
  • No two rectangles may abut horizontally (they should be combined + into a single wider rectangle in that case). +
  • The rectangles must be sorted ascendingly by Y as the major sort key + and X as the minor sort key. +
+*/ +void TQRegion::setRects( const TQRect *rects, int num ) +{ + *this = TQRegion( FALSE ); + if ( !rects || (num == 1 && rects->isEmpty()) ) + num = 0; + + data->region->rects.duplicate( rects, num ); + data->region->numRects = num; + if ( num == 0 ) { + data->region->extents = TQRect(); + } else { + int left = INT_MAX, right = INT_MIN, top = INT_MAX, bottom = INT_MIN; + int i; + for ( i = 0; i < num; i++ ) { + left = TQMIN( rects[i].left(), left ); + right = TQMAX( rects[i].right(), right ); + top = TQMIN( rects[i].top(), top ); + bottom = TQMAX( rects[i].bottom(), bottom ); + } + data->region->extents = TQRect( TQPoint(left, top), TQPoint(right, bottom) ); + } +} + +/*! + Returns TRUE if the region is equal to \a r; otherwise returns + FALSE. +*/ + +bool TQRegion::operator==( const TQRegion &r ) const +{ + return data == r.data ? + TRUE : EqualRegion( data->region, r.data->region ); +} + +/*! + \fn bool TQRegion::operator!=( const TQRegion &r ) const + + Returns TRUE if the region is different from \a r; otherwise + returns FALSE. +*/ + +/* + This is how X represents regions internally. +*/ + +struct BOX { + short x1, x2, y1, y2; +}; + +struct _XRegion { + long size; + long numRects; + BOX *rects; + BOX extents; +}; + + +void TQRegion::updateX11Region() const +{ + data->rgn = XCreateRegion(); + + for( int i = 0; i < data->region->numRects; i++ ) { + XRectangle r; + const TQRect &rect = data->region->rects[i]; + r.x = TQMAX( SHRT_MIN, rect.x() ); + r.y = TQMAX( SHRT_MIN, rect.y() ); + r.width = TQMIN( USHRT_MAX, rect.width() ); + r.height = TQMIN( USHRT_MAX, rect.height() ); + XUnionRectWithRegion( &r, data->rgn, data->rgn ); + } +} + + +void *TQRegion::clipRectangles( int &num ) const +{ + if ( !data->xrectangles ) { + XRectangle *r = (XRectangle *) malloc( data->region->numRects * sizeof( XRectangle ) ); + data->xrectangles = r; + for( int i = 0; i < data->region->numRects; i++ ) { + const TQRect &rect = data->region->rects[i]; + r->x = TQMAX( SHRT_MIN, rect.x() ); + r->y = TQMAX( SHRT_MIN, rect.y() ); + r->width = TQMIN( USHRT_MAX, rect.width() ); + r->height = TQMIN( USHRT_MAX, rect.height() ); + r++; + } + } + num = data->region->numRects; + return data->xrectangles; +} diff --git a/src/kernel/tqsize.h b/src/kernel/tqsize.h index 5ac364822..6bfb60865 100644 --- a/src/kernel/tqsize.h +++ b/src/kernel/tqsize.h @@ -42,7 +42,7 @@ #define TQSIZE_H #ifndef QT_H -#include "ntqpoint.h" // ### change to ntqwindowdefs.h? +#include "tqpoint.h" // ### change to ntqwindowdefs.h? #endif // QT_H class TQ_EXPORT TQSize diff --git a/src/kernel/tqstyle.cpp b/src/kernel/tqstyle.cpp index a8403969d..9bf8c4509 100644 --- a/src/kernel/tqstyle.cpp +++ b/src/kernel/tqstyle.cpp @@ -43,7 +43,7 @@ #include "ntqapplication.h" #include "tqpainter.h" #include "tqbitmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "ntqframe.h" #include "ntqlayout.h" #include "ntqlistview.h" diff --git a/src/kernel/tqstyle.h b/src/kernel/tqstyle.h index 15ecd20fe..d0f3712f0 100644 --- a/src/kernel/tqstyle.h +++ b/src/kernel/tqstyle.h @@ -42,7 +42,7 @@ #ifndef QT_H #include "tqobject.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqcolor.h" #include "tqiconset.h" #include "ntqtabbar.h" diff --git a/src/kernel/tqtextlayout_p.h b/src/kernel/tqtextlayout_p.h index 64c7f64db..58dced19b 100644 --- a/src/kernel/tqtextlayout_p.h +++ b/src/kernel/tqtextlayout_p.h @@ -40,7 +40,7 @@ #ifndef QT_H #include "tqstring.h" #include "ntqnamespace.h" -#include "ntqrect.h" +#include "tqrect.h" #endif // QT_H class TQTextEngine; diff --git a/src/kernel/tqwidget.cpp b/src/kernel/tqwidget.cpp index f1f1798d3..65f97e615 100644 --- a/src/kernel/tqwidget.cpp +++ b/src/kernel/tqwidget.cpp @@ -46,7 +46,7 @@ #include "tqptrdict.h" #include "ntqfocusdata.h" #include "ntqcursor.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqapplication.h" #include "qapplication_p.h" #include "tqbrush.h" diff --git a/src/kernel/tqwidget.h b/src/kernel/tqwidget.h index 9e1c3a07a..f683af712 100644 --- a/src/kernel/tqwidget.h +++ b/src/kernel/tqwidget.h @@ -45,7 +45,7 @@ #include "ntqwindowdefs.h" #include "tqobject.h" #include "tqpaintdevice.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "tqfont.h" #include "tqfontmetrics.h" #include "tqfontinfo.h" diff --git a/src/kernel/tqwmatrix.cpp b/src/kernel/tqwmatrix.cpp new file mode 100644 index 000000000..eb5ce5087 --- /dev/null +++ b/src/kernel/tqwmatrix.cpp @@ -0,0 +1,1036 @@ +/**************************************************************************** +** +** Implementation of TQWMatrix class +** +** Created : 941020 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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 "tqwmatrix.h" +#include "tqdatastream.h" +#include "tqregion.h" +#if defined(TQ_WS_X11) +double qsincos( double, bool calcCos ); // defined in tqpainter_x11.cpp +#else +#include +#endif + +#include + +#ifndef TQT_NO_WMATRIX + +/*! + \class TQWMatrix tqwmatrix.h + \brief The TQWMatrix class specifies 2D transformations of a + coordinate system. + + \ingroup graphics + \ingroup images + + The standard coordinate system of a \link TQPaintDevice paint + device\endlink has the origin located at the top-left position. X + values increase to the right; Y values increase downward. + + This coordinate system is the default for the TQPainter, which + renders graphics in a paint device. A user-defined coordinate + system can be specified by setting a TQWMatrix for the painter. + + Example: + \code + MyWidget::paintEvent( TQPaintEvent * ) + { + TQPainter p; // our painter + TQWMatrix m; // our transformation matrix + m.rotate( 22.5 ); // rotated coordinate system + p.begin( this ); // start painting + p.setWorldMatrix( m ); // use rotated coordinate system + p.drawText( 30,20, "detator" ); // draw rotated text at 30,20 + p.end(); // painting done + } + \endcode + + A matrix specifies how to translate, scale, shear or rotate the + graphics; the actual transformation is performed by the drawing + routines in TQPainter and by TQPixmap::xForm(). + + The TQWMatrix class contains a 3x3 matrix of the form: + + + + +
m11m12 0
m21m22 0
dx dy  1
+ + A matrix transforms a point in the plane to another point: + \code + x' = m11*x + m21*y + dx + y' = m22*y + m12*x + dy + \endcode + + The point \e (x, y) is the original point, and \e (x', y') is the + transformed point. \e (x', y') can be transformed back to \e (x, + y) by performing the same operation on the \link + TQWMatrix::invert() inverted matrix\endlink. + + The elements \e dx and \e dy specify horizontal and vertical + translation. The elements \e m11 and \e m22 specify horizontal and + vertical scaling. The elements \e m12 and \e m21 specify + horizontal and vertical shearing. + + The identity matrix has \e m11 and \e m22 set to 1; all others are + set to 0. This matrix maps a point to itself. + + Translation is the simplest transformation. Setting \e dx and \e + dy will move the coordinate system \e dx units along the X axis + and \e dy units along the Y axis. + + Scaling can be done by setting \e m11 and \e m22. For example, + setting \e m11 to 2 and \e m22 to 1.5 will double the height and + increase the width by 50%. + + Shearing is controlled by \e m12 and \e m21. Setting these + elements to values different from zero will twist the coordinate + system. + + Rotation is achieved by carefully setting both the shearing + factors and the scaling factors. The TQWMatrix also has a function + that sets \link rotate() rotation \endlink directly. + + TQWMatrix lets you combine transformations like this: + \code + TQWMatrix m; // identity matrix + m.translate(10, -20); // first translate (10,-20) + m.rotate(25); // then rotate 25 degrees + m.scale(1.2, 0.7); // finally scale it + \endcode + + Here's the same example using basic matrix operations: + \code + double a = pi/180 * 25; // convert 25 to radians + double sina = sin(a); + double cosa = cos(a); + TQWMatrix m1(1, 0, 0, 1, 10, -20); // translation matrix + TQWMatrix m2( cosa, sina, // rotation matrix + -sina, cosa, 0, 0 ); + TQWMatrix m3(1.2, 0, 0, 0.7, 0, 0); // scaling matrix + TQWMatrix m; + m = m3 * m2 * m1; // combine all transformations + \endcode + + \l TQPainter has functions to translate, scale, shear and rotate the + coordinate system without using a TQWMatrix. Although these + functions are very convenient, it can be more efficient to build a + TQWMatrix and call TQPainter::setWorldMatrix() if you want to perform + more than a single transform operation. + + \sa TQPainter::setWorldMatrix(), TQPixmap::xForm() +*/ + +bool qt_old_transformations = TRUE; + +/*! + \enum TQWMatrix::TransformationMode + + \keyword transformation matrix + + TQWMatrix offers two transformation modes. Calculations can either + be done in terms of points (Points mode, the default), or in + terms of area (Area mode). + + In Points mode the transformation is applied to the points that + mark out the shape's bounding line. In Areas mode the + transformation is applied in such a way that the area of the + contained region is correctly transformed under the matrix. + + \value Points transformations are applied to the shape's points. + \value Areas transformations are applied (e.g. to the width and + height) so that the area is transformed. + + Example: + + Suppose we have a rectangle, + \c{TQRect( 10, 20, 30, 40 )} and a transformation matrix + \c{TQWMatrix( 2, 0, 0, 2, 0, 0 )} to double the rectangle's size. + + In Points mode, the matrix will transform the top-left (10,20) and + the bottom-right (39,59) points producing a rectangle with its + top-left point at (20,40) and its bottom-right point at (78,118), + i.e. with a width of 59 and a height of 79. + + In Areas mode, the matrix will transform the top-left point in + the same way as in Points mode to (20/40), and double the width + and height, so the bottom-right will become (69,99), i.e. a width + of 60 and a height of 80. + + Because integer arithmetic is used (for speed), rounding + differences mean that the modes will produce slightly different + results given the same shape and the same transformation, + especially when scaling up. This also means that some operations + are not commutative. + + Under Points mode, \c{matrix * ( region1 | region2 )} is not equal to + \c{matrix * region1 | matrix * region2}. Under Area mode, \c{matrix * + (pointarray[i])} is not neccesarily equal to + \c{(matrix * pointarry)[i]}. + + \img xform.png Comparison of Points and Areas TransformationModes +*/ + +/*! + Sets the transformation mode that TQWMatrix and painter + transformations use to \a m. + + \sa TQWMatrix::TransformationMode +*/ +void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m ) +{ + if ( m == TQWMatrix::Points ) + qt_old_transformations = TRUE; + else + qt_old_transformations = FALSE; +} + + +/*! + Returns the current transformation mode. + + \sa TQWMatrix::TransformationMode +*/ +TQWMatrix::TransformationMode TQWMatrix::transformationMode() +{ + return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas ); +} + + +// some defines to inline some code +#define MAPDOUBLE( x, y, nx, ny ) \ +{ \ + double fx = x; \ + double fy = y; \ + nx = _m11*fx + _m21*fy + _dx; \ + ny = _m12*fx + _m22*fy + _dy; \ +} + +#define MAPINT( x, y, nx, ny ) \ +{ \ + double fx = x; \ + double fy = y; \ + nx = tqRound(_m11*fx + _m21*fy + _dx); \ + ny = tqRound(_m12*fx + _m22*fy + _dy); \ +} + +/***************************************************************************** + TQWMatrix member functions + *****************************************************************************/ + +/*! + Constructs an identity matrix. All elements are set to zero except + \e m11 and \e m22 (scaling), which are set to 1. +*/ + +TQWMatrix::TQWMatrix() +{ + _m11 = _m22 = 1.0; + _m12 = _m21 = _dx = _dy = 0.0; +} + +/*! + Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a + m22, \a dx and \a dy. +*/ + +TQWMatrix::TQWMatrix( double m11, double m12, double m21, double m22, + double dx, double dy ) +{ + _m11 = m11; _m12 = m12; + _m21 = m21; _m22 = m22; + _dx = dx; _dy = dy; +} + + +/*! + Sets the matrix elements to the specified values, \a m11, \a m12, + \a m21, \a m22, \a dx and \a dy. +*/ + +void TQWMatrix::setMatrix( double m11, double m12, double m21, double m22, + double dx, double dy ) +{ + _m11 = m11; _m12 = m12; + _m21 = m21; _m22 = m22; + _dx = dx; _dy = dy; +} + + +/*! + \fn double TQWMatrix::m11() const + + Returns the X scaling factor. +*/ + +/*! + \fn double TQWMatrix::m12() const + + Returns the vertical shearing factor. +*/ + +/*! + \fn double TQWMatrix::m21() const + + Returns the horizontal shearing factor. +*/ + +/*! + \fn double TQWMatrix::m22() const + + Returns the Y scaling factor. +*/ + +/*! + \fn double TQWMatrix::dx() const + + Returns the horizontal translation. +*/ + +/*! + \fn double TQWMatrix::dy() const + + Returns the vertical translation. +*/ + + +/*! + \overload + + Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the + following formulae: + + \code + *tx = m11*x + m21*y + dx + *ty = m22*y + m12*x + dy + \endcode +*/ + +void TQWMatrix::map( double x, double y, double *tx, double *ty ) const +{ + MAPDOUBLE( x, y, *tx, *ty ); +} + +/*! + Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the formulae: + + \code + *tx = m11*x + m21*y + dx (rounded to the nearest integer) + *ty = m22*y + m12*x + dy (rounded to the nearest integer) + \endcode +*/ + +void TQWMatrix::map( int x, int y, int *tx, int *ty ) const +{ + MAPINT( x, y, *tx, *ty ); +} + +/*! + \fn TQPoint TQWMatrix::map( const TQPoint &p ) const + + \overload + + Transforms \a p to using the formulae: + + \code + retx = m11*px + m21*py + dx (rounded to the nearest integer) + rety = m22*py + m12*px + dy (rounded to the nearest integer) + \endcode +*/ + +/*! + \fn TQRect TQWMatrix::map( const TQRect &r ) const + + \obsolete + + Please use \l TQWMatrix::mapRect() instead. + + Note that this method does return the bounding rectangle of the \a r, when + shearing or rotations are used. +*/ + +/*! + \fn TQPointArray TQWMatrix::map( const TQPointArray &a ) const + + \overload + + Returns the point array \a a transformed by calling map for each point. +*/ + + +/*! + \fn TQRegion TQWMatrix::map( const TQRegion &r ) const + + \overload + + Transforms the region \a r. + + Calling this method can be rather expensive, if rotations or + shearing are used. +*/ + +/*! + \fn TQRegion TQWMatrix::mapToRegion( const TQRect &rect ) const + + Returns the transformed rectangle \a rect. + + A rectangle which has been rotated or sheared may result in a + non-rectangular region being returned. + + Calling this method can be expensive, if rotations or shearing are + used. If you just need to know the bounding rectangle of the + returned region, use mapRect() which is a lot faster than this + function. + + \sa TQWMatrix::mapRect() +*/ + + +/*! + Returns the transformed rectangle \a rect. + + The bounding rectangle is returned if rotation or shearing has + been specified. + + If you need to know the exact region \a rect maps to use \l + operator*(). + + \sa operator*() +*/ + +TQRect TQWMatrix::mapRect( const TQRect &rect ) const +{ + TQRect result; + if( qt_old_transformations ) { + if ( _m12 == 0.0F && _m21 == 0.0F ) { + result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize(); + } else { + TQPointArray a( rect ); + a = map( a ); + result = a.boundingRect(); + } + } else { + if ( _m12 == 0.0F && _m21 == 0.0F ) { + int x = tqRound( _m11*rect.x() + _dx ); + int y = tqRound( _m22*rect.y() + _dy ); + int w = tqRound( _m11*rect.width() ); + int h = tqRound( _m22*rect.height() ); + if ( w < 0 ) { + w = -w; + x -= w-1; + } + if ( h < 0 ) { + h = -h; + y -= h-1; + } + result = TQRect( x, y, w, h ); + } else { + + // see mapToPolygon for explanations of the algorithm. + double x0, y0; + double x, y; + MAPDOUBLE( rect.left(), rect.top(), x0, y0 ); + double xmin = x0; + double ymin = y0; + double xmax = x0; + double ymax = y0; + MAPDOUBLE( rect.right() + 1, rect.top(), x, y ); + xmin = TQMIN( xmin, x ); + ymin = TQMIN( ymin, y ); + xmax = TQMAX( xmax, x ); + ymax = TQMAX( ymax, y ); + MAPDOUBLE( rect.right() + 1, rect.bottom() + 1, x, y ); + xmin = TQMIN( xmin, x ); + ymin = TQMIN( ymin, y ); + xmax = TQMAX( xmax, x ); + ymax = TQMAX( ymax, y ); + MAPDOUBLE( rect.left(), rect.bottom() + 1, x, y ); + xmin = TQMIN( xmin, x ); + ymin = TQMIN( ymin, y ); + xmax = TQMAX( xmax, x ); + ymax = TQMAX( ymax, y ); + double w = xmax - xmin; + double h = ymax - ymin; + xmin -= ( xmin - x0 ) / w; + ymin -= ( ymin - y0 ) / h; + xmax -= ( xmax - x0 ) / w; + ymax -= ( ymax - y0 ) / h; + result = TQRect( tqRound(xmin), tqRound(ymin), tqRound(xmax)-tqRound(xmin)+1, tqRound(ymax)-tqRound(ymin)+1 ); + } + } + return result; +} + + +/*! + \internal +*/ +TQPoint TQWMatrix::operator *( const TQPoint &p ) const +{ + double fx = p.x(); + double fy = p.y(); + return TQPoint( tqRound(_m11*fx + _m21*fy + _dx), + tqRound(_m12*fx + _m22*fy + _dy) ); +} + + +struct TQWMDoublePoint { + double x; + double y; +}; + +/*! + \internal +*/ +TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const +{ + if( qt_old_transformations ) { + TQPointArray result = a.copy(); + int x, y; + for ( int i=0; i<(int)result.size(); i++ ) { + result.point( i, &x, &y ); + MAPINT( x, y, x, y ); + result.setPoint( i, x, y ); + } + return result; + } else { + int size = a.size(); + int i; + TQMemArray p( size ); + TQPoint *da = a.data(); + TQWMDoublePoint *dp = p.data(); + double xmin = INT_MAX; + double ymin = xmin; + double xmax = INT_MIN; + double ymax = xmax; + int xminp = 0; + int yminp = 0; + for( i = 0; i < size; i++ ) { + dp[i].x = da[i].x(); + dp[i].y = da[i].y(); + if ( dp[i].x < xmin ) { + xmin = dp[i].x; + xminp = i; + } + if ( dp[i].y < ymin ) { + ymin = dp[i].y; + yminp = i; + } + xmax = TQMAX( xmax, dp[i].x ); + ymax = TQMAX( ymax, dp[i].y ); + } + double w = TQMAX( xmax - xmin, 1 ); + double h = TQMAX( ymax - ymin, 1 ); + for( i = 0; i < size; i++ ) { + dp[i].x += (dp[i].x - xmin)/w; + dp[i].y += (dp[i].y - ymin)/h; + MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y ); + } + + // now apply correction back for transformed values... + xmin = INT_MAX; + ymin = xmin; + xmax = INT_MIN; + ymax = xmax; + for( i = 0; i < size; i++ ) { + xmin = TQMIN( xmin, dp[i].x ); + ymin = TQMIN( ymin, dp[i].y ); + xmax = TQMAX( xmax, dp[i].x ); + ymax = TQMAX( ymax, dp[i].y ); + } + w = TQMAX( xmax - xmin, 1 ); + h = TQMAX( ymax - ymin, 1 ); + + TQPointArray result( size ); + TQPoint *dr = result.data(); + for( i = 0; i < size; i++ ) { + dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) ); + dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) ); + } + return result; + } +} + +/*! +\internal +*/ +TQRegion TQWMatrix::operator * (const TQRect &rect ) const +{ + TQRegion result; + if ( isIdentity() ) { + result = rect; + } else if ( _m12 == 0.0F && _m21 == 0.0F ) { + if( qt_old_transformations ) { + result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize(); + } else { + int x = tqRound( _m11*rect.x() + _dx ); + int y = tqRound( _m22*rect.y() + _dy ); + int w = tqRound( _m11*rect.width() ); + int h = tqRound( _m22*rect.height() ); + if ( w < 0 ) { + w = -w; + x -= w - 1; + } + if ( h < 0 ) { + h = -h; + y -= h - 1; + } + result = TQRect( x, y, w, h ); + } + } else { + result = TQRegion( mapToPolygon( rect ) ); + } + return result; + +} + +/*! + Returns the transformed rectangle \a rect as a polygon. + + Polygons and rectangles behave slightly differently + when transformed (due to integer rounding), so + \c{matrix.map( TQPointArray( rect ) )} is not always the same as + \c{matrix.mapToPolygon( rect )}. +*/ +TQPointArray TQWMatrix::mapToPolygon( const TQRect &rect ) const +{ + TQPointArray a( 4 ); + if ( qt_old_transformations ) { + a = TQPointArray( rect ); + return operator *( a ); + } + double x[4], y[4]; + if ( _m12 == 0.0F && _m21 == 0.0F ) { + x[0] = tqRound( _m11*rect.x() + _dx ); + y[0] = tqRound( _m22*rect.y() + _dy ); + double w = tqRound( _m11*rect.width() ); + double h = tqRound( _m22*rect.height() ); + if ( w < 0 ) { + w = -w; + x[0] -= w - 1.; + } + if ( h < 0 ) { + h = -h; + y[0] -= h - 1.; + } + x[1] = x[0]+w-1; + x[2] = x[1]; + x[3] = x[0]; + y[1] = y[0]; + y[2] = y[0]+h-1; + y[3] = y[2]; + } else { + MAPINT( rect.left(), rect.top(), x[0], y[0] ); + MAPINT( rect.right() + 1, rect.top(), x[1], y[1] ); + MAPINT( rect.right() + 1, rect.bottom() + 1, x[2], y[2] ); + MAPINT( rect.left(), rect.bottom() + 1, x[3], y[3] ); + + /* + Including rectangles as we have are evil. + + We now have a rectangle that is one pixel to wide and one to + high. the tranformed position of the top-left corner is + correct. All other points need some adjustments. + + Doing this mathematically exact would force us to calculate some square roots, + something we don't want for the sake of speed. + + Instead we use an approximation, that converts to the correct + answer when m12 -> 0 and m21 -> 0, and accept smaller + errors in the general transformation case. + + The solution is to calculate the width and height of the + bounding rect, and scale the points 1/2/3 by (xp-x0)/xw pixel direction + to point 0. + */ + + double xmin = x[0]; + double ymin = y[0]; + double xmax = x[0]; + double ymax = y[0]; + int i; + for( i = 1; i< 4; i++ ) { + xmin = TQMIN( xmin, x[i] ); + ymin = TQMIN( ymin, y[i] ); + xmax = TQMAX( xmax, x[i] ); + ymax = TQMAX( ymax, y[i] ); + } + double w = xmax - xmin; + double h = ymax - ymin; + + for( i = 1; i < 4; i++ ) { + x[i] -= (x[i] - x[0])/w; + y[i] -= (y[i] - y[0])/h; + } + } +#if 0 + int i; + for( i = 0; i< 4; i++ ) + tqDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], tqRound(x[i]), tqRound(y[i]) ); + tqDebug( "width=%f, height=%f", sqrt( (x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0]) ), + sqrt( (x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3]) ) ); +#endif + // all coordinates are correctly, tranform to a pointarray + // (rounding to the next integer) + a.setPoints( 4, tqRound( x[0] ), tqRound( y[0] ), + tqRound( x[1] ), tqRound( y[1] ), + tqRound( x[2] ), tqRound( y[2] ), + tqRound( x[3] ), tqRound( y[3] ) ); + return a; +} + +/*! +\internal +*/ +TQRegion TQWMatrix::operator * (const TQRegion &r ) const +{ + if ( isIdentity() ) + return r; + TQMemArray rects = r.rects(); + TQRegion result; + TQRect *rect = rects.data(); + int i = rects.size(); + if ( _m12 == 0.0F && _m21 == 0.0F && _m11 > 1.0F && _m22 > 1.0F ) { + // simple case, no rotation + while ( i ) { + int x = tqRound( _m11*rect->x() + _dx ); + int y = tqRound( _m22*rect->y() + _dy ); + int w = tqRound( _m11*rect->width() ); + int h = tqRound( _m22*rect->height() ); + if ( w < 0 ) { + w = -w; + x -= w-1; + } + if ( h < 0 ) { + h = -h; + y -= h-1; + } + *rect = TQRect( x, y, w, h ); + rect++; + i--; + } + result.setRects( rects.data(), rects.size() ); + } else { + while ( i ) { + result |= operator *( *rect ); + rect++; + i--; + } + } + return result; +} + +/*! + Resets the matrix to an identity matrix. + + All elements are set to zero, except \e m11 and \e m22 (scaling) + which are set to 1. + + \sa isIdentity() +*/ + +void TQWMatrix::reset() +{ + _m11 = _m22 = 1.0; + _m12 = _m21 = _dx = _dy = 0.0; +} + +/*! + Returns TRUE if the matrix is the identity matrix; otherwise returns FALSE. + + \sa reset() +*/ +bool TQWMatrix::isIdentity() const +{ + return _m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0 + && _dx == 0.0 && _dy == 0.0; +} + +/*! + Moves the coordinate system \a dx along the X-axis and \a dy along + the Y-axis. + + Returns a reference to the matrix. + + \sa scale(), shear(), rotate() +*/ + +TQWMatrix &TQWMatrix::translate( double dx, double dy ) +{ + _dx += dx*_m11 + dy*_m21; + _dy += dy*_m22 + dx*_m12; + return *this; +} + +/*! + Scales the coordinate system unit by \a sx horizontally and \a sy + vertically. + + Returns a reference to the matrix. + + \sa translate(), shear(), rotate() +*/ + +TQWMatrix &TQWMatrix::scale( double sx, double sy ) +{ + _m11 *= sx; + _m12 *= sx; + _m21 *= sy; + _m22 *= sy; + return *this; +} + +/*! + Shears the coordinate system by \a sh horizontally and \a sv + vertically. + + Returns a reference to the matrix. + + \sa translate(), scale(), rotate() +*/ + +TQWMatrix &TQWMatrix::shear( double sh, double sv ) +{ + double tm11 = sv*_m21; + double tm12 = sv*_m22; + double tm21 = sh*_m11; + double tm22 = sh*_m12; + _m11 += tm11; + _m12 += tm12; + _m21 += tm21; + _m22 += tm22; + return *this; +} + +const double deg2rad = 0.017453292519943295769; // pi/180 + +/*! + Rotates the coordinate system \a a degrees counterclockwise. + + Returns a reference to the matrix. + + \sa translate(), scale(), shear() +*/ + +TQWMatrix &TQWMatrix::rotate( double a ) +{ + double b = deg2rad*a; // convert to radians +#if defined(TQ_WS_X11) + double sina = qsincos(b,FALSE); // fast and convenient + double cosa = qsincos(b,TRUE); +#else + double sina = sin(b); + double cosa = cos(b); +#endif + double tm11 = cosa*_m11 + sina*_m21; + double tm12 = cosa*_m12 + sina*_m22; + double tm21 = -sina*_m11 + cosa*_m21; + double tm22 = -sina*_m12 + cosa*_m22; + _m11 = tm11; _m12 = tm12; + _m21 = tm21; _m22 = tm22; + return *this; +} + +/*! + \fn bool TQWMatrix::isInvertible() const + + Returns TRUE if the matrix is invertible; otherwise returns FALSE. + + \sa invert() +*/ + +/*! + \fn double TQWMatrix::det() const + + Returns the matrix's determinant. +*/ + + +/*! + Returns the inverted matrix. + + If the matrix is singular (not invertible), the identity matrix is + returned. + + If \a invertible is not 0: the value of \a *invertible is set + to TRUE if the matrix is invertible; otherwise \a *invertible is + set to FALSE. + + \sa isInvertible() +*/ + +TQWMatrix TQWMatrix::invert( bool *invertible ) const +{ + double determinant = det(); + if ( determinant == 0.0 ) { + if ( invertible ) + *invertible = FALSE; // singular matrix + TQWMatrix defaultMatrix; + return defaultMatrix; + } + else { // invertible matrix + if ( invertible ) + *invertible = TRUE; + double dinv = 1.0/determinant; + TQWMatrix imatrix( (_m22*dinv), (-_m12*dinv), + (-_m21*dinv), ( _m11*dinv), + ((_m21*_dy - _m22*_dx)*dinv), + ((_m12*_dx - _m11*_dy)*dinv) ); + return imatrix; + } +} + + +/*! + Returns TRUE if this matrix is equal to \a m; otherwise returns FALSE. +*/ + +bool TQWMatrix::operator==( const TQWMatrix &m ) const +{ + return _m11 == m._m11 && + _m12 == m._m12 && + _m21 == m._m21 && + _m22 == m._m22 && + _dx == m._dx && + _dy == m._dy; +} + +/*! + Returns TRUE if this matrix is not equal to \a m; otherwise returns FALSE. +*/ + +bool TQWMatrix::operator!=( const TQWMatrix &m ) const +{ + return _m11 != m._m11 || + _m12 != m._m12 || + _m21 != m._m21 || + _m22 != m._m22 || + _dx != m._dx || + _dy != m._dy; +} + +/*! + Returns the result of multiplying this matrix by matrix \a m. +*/ + +TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m ) +{ + double tm11 = _m11*m._m11 + _m12*m._m21; + double tm12 = _m11*m._m12 + _m12*m._m22; + double tm21 = _m21*m._m11 + _m22*m._m21; + double tm22 = _m21*m._m12 + _m22*m._m22; + + double tdx = _dx*m._m11 + _dy*m._m21 + m._dx; + double tdy = _dx*m._m12 + _dy*m._m22 + m._dy; + + _m11 = tm11; _m12 = tm12; + _m21 = tm21; _m22 = tm22; + _dx = tdx; _dy = tdy; + return *this; +} + +/*! + \overload + \relates TQWMatrix + Returns the product of \a m1 * \a m2. + + Note that matrix multiplication is not commutative, i.e. a*b != + b*a. +*/ + +TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 ) +{ + TQWMatrix result = m1; + result *= m2; + return result; +} + +/***************************************************************************** + TQWMatrix stream functions + *****************************************************************************/ +#ifndef TQT_NO_DATASTREAM +/*! + \relates TQWMatrix + + Writes the matrix \a m to the stream \a s and returns a reference + to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator<<( TQDataStream &s, const TQWMatrix &m ) +{ + if ( s.version() == 1 ) + s << (float)m.m11() << (float)m.m12() << (float)m.m21() + << (float)m.m22() << (float)m.dx() << (float)m.dy(); + else + s << m.m11() << m.m12() << m.m21() << m.m22() + << m.dx() << m.dy(); + return s; +} + +/*! + \relates TQWMatrix + + Reads the matrix \a m from the stream \a s and returns a reference + to the stream. + + \sa \link datastreamformat.html Format of the TQDataStream operators \endlink +*/ + +TQDataStream &operator>>( TQDataStream &s, TQWMatrix &m ) +{ + if ( s.version() == 1 ) { + float m11, m12, m21, m22, dx, dy; + s >> m11; s >> m12; s >> m21; s >> m22; + s >> dx; s >> dy; + m.setMatrix( m11, m12, m21, m22, dx, dy ); + } + else { + double m11, m12, m21, m22, dx, dy; + s >> m11; s >> m12; s >> m21; s >> m22; + s >> dx; s >> dy; + m.setMatrix( m11, m12, m21, m22, dx, dy ); + } + return s; +} +#endif // TQT_NO_DATASTREAM + +#endif // TQT_NO_WMATRIX + diff --git a/src/kernel/tqwmatrix.h b/src/kernel/tqwmatrix.h new file mode 100644 index 000000000..7ac138804 --- /dev/null +++ b/src/kernel/tqwmatrix.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Definition of TQWMatrix class +** +** Created : 941020 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** 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. +** +**********************************************************************/ + +#ifndef TQWMATRIX_H +#define TQWMATRIX_H + +#ifndef QT_H +#include "ntqwindowdefs.h" +#include "tqpointarray.h" +#include "tqrect.h" +#include "tqregion.h" +#endif // QT_H + +#ifndef TQT_NO_WMATRIX + + +class TQ_EXPORT TQWMatrix // 2D transform matrix +{ +public: + TQWMatrix(); + TQWMatrix( double m11, double m12, double m21, double m22, + double dx, double dy ); + + void setMatrix( double m11, double m12, double m21, double m22, + double dx, double dy ); + + double m11() const { return _m11; } + double m12() const { return _m12; } + double m21() const { return _m21; } + double m22() const { return _m22; } + double dx() const { return _dx; } + double dy() const { return _dy; } + + void map( int x, int y, int *tx, int *ty ) const; + void map( double x, double y, double *tx, double *ty ) const; + TQRect mapRect( const TQRect & ) const; + + TQPoint map( const TQPoint &p ) const { return operator *( p ); } + TQRect map( const TQRect &r ) const { return mapRect ( r ); } + TQPointArray map( const TQPointArray &a ) const { return operator * ( a ); } + TQRegion map( const TQRegion &r ) const { return operator *( r ); } + TQRegion mapToRegion( const TQRect &r ) const { return operator *( r ); } + TQPointArray mapToPolygon( const TQRect &r ) const; + + void reset(); + bool isIdentity() const; + + TQWMatrix &translate( double dx, double dy ); + TQWMatrix &scale( double sx, double sy ); + TQWMatrix &shear( double sh, double sv ); + TQWMatrix &rotate( double a ); + + bool isInvertible() const { return (_m11*_m22 - _m12*_m21) != 0; } + double det() const { return _m11*_m22 - _m12*_m21; } + + TQWMatrix invert( bool * = 0 ) const; + + bool operator==( const TQWMatrix & ) const; + bool operator!=( const TQWMatrix & ) const; + TQWMatrix &operator*=( const TQWMatrix & ); + + /* we use matrix multiplication semantics here */ + TQPoint operator * (const TQPoint & ) const; + TQRegion operator * (const TQRect & ) const; + TQRegion operator * (const TQRegion & ) const; + TQPointArray operator * ( const TQPointArray &a ) const; + + enum TransformationMode { + Points, Areas + }; + static void setTransformationMode( TQWMatrix::TransformationMode m ); + static TransformationMode transformationMode(); +private: + double _m11, _m12; + double _m21, _m22; + double _dx, _dy; +}; + +TQ_EXPORT TQWMatrix operator*( const TQWMatrix &, const TQWMatrix & ); + + +/***************************************************************************** + TQWMatrix stream functions + *****************************************************************************/ + +TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQWMatrix & ); +TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQWMatrix & ); + + +#endif // TQT_NO_WMATRIX + +#endif // TQWMATRIX_H -- cgit v1.2.3