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/canvas/tqcanvas.h | 6 +- src/codecs/tqtextcodecinterface_p.h | 2 +- src/dialogs/qprintdialog.cpp | 2 +- src/dialogs/qtabdialog.cpp | 2 +- src/dialogs/tqcolordialog.cpp | 2 +- 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 ++ src/opengl/ntqgl.h | 541 ------- src/opengl/ntqglcolormap.h | 99 -- src/opengl/qgl.cpp | 2367 ---------------------------- src/opengl/qgl_x11.cpp | 1406 ----------------- src/opengl/qgl_x11_p.h | 197 --- src/opengl/qglcolormap.cpp | 292 ---- src/opengl/qt_opengl.pri | 12 +- src/opengl/tqgl.cpp | 2367 ++++++++++++++++++++++++++++ src/opengl/tqgl.h | 541 +++++++ src/opengl/tqgl_x11.cpp | 1406 +++++++++++++++++ src/opengl/tqgl_x11_p.h | 197 +++ src/opengl/tqglcolormap.cpp | 292 ++++ src/opengl/tqglcolormap.h | 99 ++ src/sql/drivers/psql/tqsql_psql.cpp | 2 +- src/styles/ntqinterlacestyle.h | 2 +- src/styles/qcommonstyle.cpp | 4 +- src/styles/qcompactstyle.cpp | 2 +- src/styles/qinterlacestyle.cpp | 2 +- src/styles/qmotifplusstyle.cpp | 2 +- src/styles/qmotifstyle.cpp | 4 +- src/styles/qplatinumstyle.cpp | 4 +- src/styles/qsgistyle.cpp | 4 +- src/styles/qwindowsstyle.cpp | 2 +- src/table/ntqtable.h | 2 +- src/tools/qfeatures.txt | 4 +- src/tools/qwinexport.cpp | 4 +- src/widgets/ntqlistbox.h | 2 +- src/widgets/ntqsplashscreen.h | 2 +- src/widgets/qbutton.cpp | 2 +- src/widgets/qcheckbox.cpp | 4 +- src/widgets/qcombobox.cpp | 2 +- src/widgets/qdial.cpp | 4 +- src/widgets/qeffects.cpp | 2 +- src/widgets/qheader.cpp | 2 +- src/widgets/qlabel.cpp | 2 +- src/widgets/qlineedit.cpp | 2 +- src/widgets/qlistbox.cpp | 2 +- src/widgets/qlistview.cpp | 2 +- src/widgets/qmultilineedit.cpp | 2 +- src/widgets/qprogressbar.cpp | 4 +- src/widgets/qpushbutton.cpp | 2 +- src/widgets/qradiobutton.cpp | 4 +- src/widgets/qscrollview.cpp | 2 +- src/widgets/qspinbox.cpp | 2 +- src/widgets/qspinwidget.cpp | 2 +- src/widgets/qsplashscreen.cpp | 2 +- src/widgets/qwhatsthis.cpp | 2 +- src/widgets/tqdatetimeedit.cpp | 2 +- src/widgets/tqiconview.cpp | 6 +- src/widgets/tqiconview.h | 6 +- src/widgets/tqpopupmenu.cpp | 4 +- src/widgets/tqtextbrowser.h | 2 +- src/widgets/tqtextedit.cpp | 4 +- src/widgets/tqtoolbutton.cpp | 4 +- src/widgets/tqtoolbutton.h | 2 +- src/workspace/tqworkspace.cpp | 2 +- src/xml/qsvgdevice.cpp | 2 +- src/xml/qsvgdevice_p.h | 2 +- 154 files changed, 23883 insertions(+), 23883 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 delete mode 100644 src/opengl/ntqgl.h delete mode 100644 src/opengl/ntqglcolormap.h delete mode 100644 src/opengl/qgl.cpp delete mode 100644 src/opengl/qgl_x11.cpp delete mode 100644 src/opengl/qgl_x11_p.h delete mode 100644 src/opengl/qglcolormap.cpp create mode 100644 src/opengl/tqgl.cpp create mode 100644 src/opengl/tqgl.h create mode 100644 src/opengl/tqgl_x11.cpp create mode 100644 src/opengl/tqgl_x11_p.h create mode 100644 src/opengl/tqglcolormap.cpp create mode 100644 src/opengl/tqglcolormap.h (limited to 'src') diff --git a/src/canvas/tqcanvas.h b/src/canvas/tqcanvas.h index 28b30c42f..e6dbb685f 100644 --- a/src/canvas/tqcanvas.h +++ b/src/canvas/tqcanvas.h @@ -43,12 +43,12 @@ #ifndef QT_H #include "ntqscrollview.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqptrlist.h" #include "tqbrush.h" -#include "ntqpen.h" +#include "tqpen.h" #include "tqvaluelist.h" -#include "ntqpointarray.h" +#include "tqpointarray.h" #endif // QT_H #if !defined( TQT_MODULE_CANVAS ) || defined( QT_LICENSE_PROFESSIONAL ) || defined( QT_INTERNAL_CANVAS ) diff --git a/src/codecs/tqtextcodecinterface_p.h b/src/codecs/tqtextcodecinterface_p.h index 5a8baa04a..541889e2d 100644 --- a/src/codecs/tqtextcodecinterface_p.h +++ b/src/codecs/tqtextcodecinterface_p.h @@ -44,7 +44,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. // diff --git a/src/dialogs/qprintdialog.cpp b/src/dialogs/qprintdialog.cpp index e24c4a9c3..42efc6e81 100644 --- a/src/dialogs/qprintdialog.cpp +++ b/src/dialogs/qprintdialog.cpp @@ -50,7 +50,7 @@ #include "ntqlabel.h" #include "ntqlineedit.h" #include "ntqpushbutton.h" -#include "ntqprinter.h" +#include "tqprinter.h" #include "ntqlistview.h" #include "ntqlayout.h" #include "ntqbuttongroup.h" diff --git a/src/dialogs/qtabdialog.cpp b/src/dialogs/qtabdialog.cpp index d0aa11e05..1a5b1799e 100644 --- a/src/dialogs/qtabdialog.cpp +++ b/src/dialogs/qtabdialog.cpp @@ -47,7 +47,7 @@ #include "ntqtabwidget.h" #include "ntqpushbutton.h" #include "tqpainter.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqapplication.h" #include "ntqtabwidget.h" #include "tqwidgetstack.h" diff --git a/src/dialogs/tqcolordialog.cpp b/src/dialogs/tqcolordialog.cpp index 09040eef3..f90f8df2e 100644 --- a/src/dialogs/tqcolordialog.cpp +++ b/src/dialogs/tqcolordialog.cpp @@ -48,7 +48,7 @@ #include "ntqpushbutton.h" #include "ntqlineedit.h" #include "tqimage.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqdrawutil.h" #include "ntqvalidator.h" #include "tqdragobject.h" 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 diff --git a/src/opengl/ntqgl.h b/src/opengl/ntqgl.h deleted file mode 100644 index 86eeddf6e..000000000 --- a/src/opengl/ntqgl.h +++ /dev/null @@ -1,541 +0,0 @@ -/**************************************************************************** -** -** Definition of OpenGL classes for TQt -** -** Created : 970112 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the opengl 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 TQGL_H -#define TQGL_H - -#ifndef QT_H -#include "tqwidget.h" -#include "ntqglcolormap.h" -#endif // QT_H - -#if !defined( TQT_MODULE_OPENGL ) || defined( QT_LICENSE_PROFESSIONAL ) -#define TQM_EXPORT_OPENGL -#else -#define TQM_EXPORT_OPENGL TQ_EXPORT -#endif - -#ifndef TQT_NO_COMPAT -#define TQGL_VERSION 450 -#define TQGL_VERSION_STR "4.5" -TQM_EXPORT_OPENGL inline const char *qGLVersion() { - tqObsolete( 0, "qGLVersion", "qVersion" ); - return TQGL_VERSION_STR; -} -#endif - -#if defined(TQ_WS_WIN) -# include "qt_windows.h" -#endif - -#if defined(TQ_WS_MAC) -#if !defined( TQMAC_OPENGL_DOUBLEBUFFER ) -/* This macro is different now. If the macro is not defined TQGLWidget will - * try to determine when you need double buffering. If set to 0 it will - * never double buffer and *can* be acclerated. If set to 1 (the default) - * it will always double buffer. Unlike before the value of this macro does - * not upset binary compatability either. */ -#if QT_MACOSX_VERSION >= 0x1020 -# define TQMAC_OPENGL_DOUBLEBUFFER 0 -#endif -#endif -# include -# include -#else -# include -# include -#endif - -#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC) -class TQGLCmap; -#endif - -class TQPixmap; -#if defined(TQ_WS_X11) -class TQGLOverlayWidget; -#endif - -// Namespace class: -class TQM_EXPORT_OPENGL TQGL -{ -public: - enum FormatOption { - DoubleBuffer = 0x0001, - DepthBuffer = 0x0002, - Rgba = 0x0004, - AlphaChannel = 0x0008, - AccumBuffer = 0x0010, - StencilBuffer = 0x0020, - StereoBuffers = 0x0040, - DirectRendering = 0x0080, - HasOverlay = 0x0100, - SingleBuffer = DoubleBuffer << 16, - NoDepthBuffer = DepthBuffer << 16, - ColorIndex = Rgba << 16, - NoAlphaChannel = AlphaChannel << 16, - NoAccumBuffer = AccumBuffer << 16, - NoStencilBuffer = StencilBuffer << 16, - NoStereoBuffers = StereoBuffers << 16, - IndirectRendering = DirectRendering << 16, - NoOverlay = HasOverlay << 16 - }; -}; - - - -class TQM_EXPORT_OPENGL TQGLFormat : public TQGL -{ -public: - TQGLFormat(); - TQGLFormat( int options, int plane = 0 ); - - bool doubleBuffer() const; - void setDoubleBuffer( bool enable ); - bool depth() const; - void setDepth( bool enable ); - bool rgba() const; - void setRgba( bool enable ); - bool alpha() const; - void setAlpha( bool enable ); - bool accum() const; - void setAccum( bool enable ); - bool stencil() const; - void setStencil( bool enable ); - bool stereo() const; - void setStereo( bool enable ); - bool directRendering() const; - void setDirectRendering( bool enable ); - bool hasOverlay() const; - void setOverlay( bool enable ); - - int plane() const; - void setPlane( int plane ); - - void setOption( FormatOption opt ); - bool testOption( FormatOption opt ) const; - - static TQGLFormat defaultFormat(); - static void setDefaultFormat( const TQGLFormat& f ); - - static TQGLFormat defaultOverlayFormat(); - static void setDefaultOverlayFormat( const TQGLFormat& f ); - - static bool hasOpenGL(); - static bool hasOpenGLOverlays(); - - friend TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&, - const TQGLFormat& ); - friend TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&, - const TQGLFormat& ); -private: - uint opts; - int pln; -}; - - -TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&, const TQGLFormat& ); -TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&, const TQGLFormat& ); - -class TQM_EXPORT_OPENGL TQGLContext : public TQGL -{ -public: - TQGLContext( const TQGLFormat& format, TQPaintDevice* device ); - TQGLContext( const TQGLFormat& format ); - virtual ~TQGLContext(); - - virtual bool create( const TQGLContext* shareContext = 0 ); - bool isValid() const; - bool isSharing() const; - virtual void reset(); - - TQGLFormat format() const; - TQGLFormat requestedFormat() const; - virtual void setFormat( const TQGLFormat& format ); - - virtual void makeCurrent(); - virtual void swapBuffers() const; - - TQPaintDevice* device() const; - - TQColor overlayTransparentColor() const; - - static const TQGLContext* currentContext(); - -protected: - virtual bool chooseContext( const TQGLContext* shareContext = 0 ); - virtual void doneCurrent(); // ### 4.0: make this public - needed for multithreading stuff - -#if defined(TQ_WS_WIN) - virtual int choosePixelFormat( void* pfd, HDC pdc ); -#endif -#if defined(TQ_WS_X11) - virtual void* tryVisual( const TQGLFormat& f, int bufDepth = 1 ); - virtual void* chooseVisual(); -#endif -#if defined(TQ_WS_MAC) - virtual void* chooseMacVisual(GDHandle); -#endif - - bool deviceIsPixmap() const; - bool windowCreated() const; - void setWindowCreated( bool on ); - bool initialized() const; - void setInitialized( bool on ); - void generateFontDisplayLists( const TQFont & fnt, int listBase ); - - uint colorIndex( const TQColor& c ) const; - void setValid( bool valid ); - void setDevice( TQPaintDevice *pDev ); - -protected: -#if defined(TQ_WS_WIN) - HGLRC rc; - HDC dc; - WId win; - int pixelFormatId; - TQGLCmap* cmap; -#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC) - void* vi; - void* cx; -#if defined(TQ_WS_X11) - TQ_UINT32 gpm; -#endif -#endif - TQGLFormat glFormat; - TQGLFormat reqFormat; - static TQGLContext* currentCtx; - -private: - void init( TQPaintDevice *dev = 0 ); - class Private { - public: - bool valid; - bool sharing; - bool initDone; - bool crWin; - TQPaintDevice* paintDevice; - TQColor transpColor; -#ifdef TQ_WS_MAC - TQRect oldR; -#endif - }; - Private* d; - - friend class TQGLWidget; -#ifdef TQ_WS_MAC - void fixBufferRect(); -#endif - -private: // Disabled copy constructor and operator= - TQGLContext() {} - TQGLContext( const TQGLContext& ) {} - TQGLContext& operator=( const TQGLContext& ) { return *this; } -}; - - - - -class TQM_EXPORT_OPENGL TQGLWidget : public TQWidget, public TQGL -{ - TQ_OBJECT -public: - TQGLWidget( TQWidget* parent=0, const char* name=0, - const TQGLWidget* shareWidget = 0, WFlags f=0 ); - TQGLWidget( TQGLContext *context, TQWidget* parent, const char* name=0, - const TQGLWidget* shareWidget = 0, WFlags f=0 ); - TQGLWidget( const TQGLFormat& format, TQWidget* parent=0, const char* name=0, - const TQGLWidget* shareWidget = 0, WFlags f=0 ); - ~TQGLWidget(); - - void qglColor( const TQColor& c ) const; - void qglClearColor( const TQColor& c ) const; - - bool isValid() const; - bool isSharing() const; - virtual void makeCurrent(); - void doneCurrent(); - - bool doubleBuffer() const; - virtual void swapBuffers(); - - TQGLFormat format() const; -#ifndef Q_QDOC - virtual void setFormat( const TQGLFormat& format ); -#endif - - const TQGLContext* context() const; -#ifndef Q_QDOC - virtual void setContext( TQGLContext* context, - const TQGLContext* shareContext = 0, - bool deleteOldContext = TRUE ); -#endif - - virtual TQPixmap renderPixmap( int w = 0, int h = 0, - bool useContext = FALSE ); - virtual TQImage grabFrameBuffer( bool withAlpha = FALSE ); - - virtual void makeOverlayCurrent(); - const TQGLContext* overlayContext() const; - - static TQImage convertToGLFormat( const TQImage& img ); - - void setMouseTracking( bool enable ); - virtual void reparent( TQWidget* parent, WFlags f, const TQPoint& p, - bool showIt = FALSE ); - - const TQGLColormap & colormap() const; - void setColormap( const TQGLColormap & map ); - - void renderText( int x, int y, const TQString & str, - const TQFont & fnt = TQFont(), int listBase = 2000 ); - void renderText( double x, double y, double z, const TQString & str, - const TQFont & fnt = TQFont(), int listBase = 2000 ); -public slots: - virtual void updateGL(); - virtual void updateOverlayGL(); - -protected: - virtual void initializeGL(); - virtual void resizeGL( int w, int h ); - virtual void paintGL(); - - virtual void initializeOverlayGL(); - virtual void resizeOverlayGL( int w, int h ); - virtual void paintOverlayGL(); - - void setAutoBufferSwap( bool on ); - bool autoBufferSwap() const; - - void paintEvent( TQPaintEvent* ); - void resizeEvent( TQResizeEvent* ); - - virtual void glInit(); - virtual void glDraw(); - -private: - int displayListBase( const TQFont & fnt, int listBase ); - void cleanupColormaps(); - void init( TQGLContext *context, const TQGLWidget* shareWidget ); - bool renderCxPm( TQPixmap* pm ); - TQGLContext* glcx; - bool autoSwap; - - TQGLColormap cmap; - -#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC) - TQGLContext* olcx; -#elif defined(TQ_WS_X11) - TQGLOverlayWidget* olw; - friend class TQGLOverlayWidget; -#endif - -private: // Disabled copy constructor and operator= -#if defined(TQ_DISABLE_COPY) - TQGLWidget( const TQGLWidget& ); - TQGLWidget& operator=( const TQGLWidget& ); -#endif - -#if defined(TQ_WS_MAC) -private: - const TQGLContext *slcx; - uint pending_fix : 1, - glcx_dblbuf : 2, - dblbuf : 1, - clp_serial : 15; - TQPixmap *gl_pix; - TQGLFormat req_format; - - void macInternalRecreateContext( TQGLContext *ctx, - const TQGLContext* = NULL, - bool update = TRUE ); - bool macInternalDoubleBuffer( bool fix = TRUE ); - virtual void setRegionDirty( bool ); - virtual void macWidgetChangedWindow(); -#endif -private slots: - void macInternalFixBufferRect(); -}; - - -// -// TQGLFormat inline functions -// - -inline bool TQGLFormat::doubleBuffer() const -{ - return testOption( DoubleBuffer ); -} - -inline bool TQGLFormat::depth() const -{ - return testOption( DepthBuffer ); -} - -inline bool TQGLFormat::rgba() const -{ - return testOption( Rgba ); -} - -inline bool TQGLFormat::alpha() const -{ - return testOption( AlphaChannel ); -} - -inline bool TQGLFormat::accum() const -{ - return testOption( AccumBuffer ); -} - -inline bool TQGLFormat::stencil() const -{ - return testOption( StencilBuffer ); -} - -inline bool TQGLFormat::stereo() const -{ - return testOption( StereoBuffers ); -} - -inline bool TQGLFormat::directRendering() const -{ - return testOption( DirectRendering ); -} - -inline bool TQGLFormat::hasOverlay() const -{ - return testOption( HasOverlay ); -} - -// -// TQGLContext inline functions -// - -inline bool TQGLContext::isValid() const -{ - return d->valid; -} - -inline void TQGLContext::setValid( bool valid ) -{ - d->valid = valid; -} - -inline bool TQGLContext::isSharing() const -{ - return d->sharing; -} - -inline TQGLFormat TQGLContext::format() const -{ - return glFormat; -} - -inline TQGLFormat TQGLContext::requestedFormat() const -{ - return reqFormat; -} - -inline TQPaintDevice* TQGLContext::device() const -{ - return d->paintDevice; -} - -inline bool TQGLContext::deviceIsPixmap() const -{ - return d->paintDevice->devType() == TQInternal::Pixmap; -} - - -inline bool TQGLContext::windowCreated() const -{ - return d->crWin; -} - - -inline void TQGLContext::setWindowCreated( bool on ) -{ - d->crWin = on; -} - -inline bool TQGLContext::initialized() const -{ - return d->initDone; -} - -inline void TQGLContext::setInitialized( bool on ) -{ - d->initDone = on; -} - -inline const TQGLContext* TQGLContext::currentContext() -{ - return currentCtx; -} - -// -// TQGLWidget inline functions -// - -inline TQGLFormat TQGLWidget::format() const -{ - return glcx->format(); -} - -inline const TQGLContext *TQGLWidget::context() const -{ - return glcx; -} - -inline bool TQGLWidget::doubleBuffer() const -{ - return glcx->format().doubleBuffer(); -} - -inline void TQGLWidget::setAutoBufferSwap( bool on ) -{ - autoSwap = on; -} - -inline bool TQGLWidget::autoBufferSwap() const -{ - return autoSwap; -} - -#endif diff --git a/src/opengl/ntqglcolormap.h b/src/opengl/ntqglcolormap.h deleted file mode 100644 index 61fbd7c79..000000000 --- a/src/opengl/ntqglcolormap.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Definition of TQGLColormap class -** -** Created : 20010326 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the opengl 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 TQGLCOLORMAP_H -#define TQGLCOLORMAP_H - -#ifndef QT_H -#include "tqcolor.h" -#include "tqmemarray.h" -#include "ntqshared.h" -#endif // QT_H - -#if !defined( TQT_MODULE_OPENGL ) || defined( QT_LICENSE_PROFESSIONAL ) -#define TQM_EXPORT_OPENGL -#else -#define TQM_EXPORT_OPENGL TQ_EXPORT -#endif - -class TQWidget; -class TQM_EXPORT_OPENGL TQGLColormap -{ -public: - TQGLColormap(); - TQGLColormap( const TQGLColormap & ); - ~TQGLColormap(); - - TQGLColormap &operator=( const TQGLColormap & ); - - bool isEmpty() const; - int size() const; - void detach(); - - void setEntries( int count, const TQRgb * colors, int base = 0 ); - void setEntry( int idx, TQRgb color ); - void setEntry( int idx, const TQColor & color ); - TQRgb entryRgb( int idx ) const; - TQColor entryColor( int idx ) const; - int find( TQRgb color ) const; - int findNearest( TQRgb color ) const; - -private: - class Private : public TQShared - { - public: - Private() { - cells.resize( 256 ); // ### hardcoded to 256 entries for now - cmapHandle = 0; - } - - ~Private() { - } - - TQMemArray cells; - TQt::HANDLE cmapHandle; - }; - - Private * d; - - friend class TQGLWidget; -}; - -#endif diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp deleted file mode 100644 index 8c327941e..000000000 --- a/src/opengl/qgl.cpp +++ /dev/null @@ -1,2367 +0,0 @@ -/**************************************************************************** -** -** Implementation of OpenGL classes for TQt -** -** Created : 970112 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the opengl 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 "ntqgl.h" -#include "ntqpixmap.h" -#include "tqpaintdevicemetrics.h" -#include "tqimage.h" -#include "ntqcleanuphandler.h" -#include "tqptrdict.h" - -static TQGLFormat* qgl_default_format = 0; -static TQGLFormat* qgl_default_overlay_format = 0; - -#if defined(TQ_WS_X11) -#include "private/qt_x11_p.h" -#define INT32 dummy_INT32 -#define INT8 dummy_INT8 -#include -#undef INT32 -#undef INT8 -#include "qgl_x11_p.h" -#endif - -static TQCleanupHandler qgl_cleanup_format; - - -/*! - \class TQGL ntqgl.h - \brief The TQGL class is a namespace for miscellaneous identifiers - in the TQt OpenGL module. -\if defined(commercial) - It is part of the TQt Enterprise Edition. -\endif - - \module OpenGL - \ingroup graphics - \ingroup images - - - Normally you can ignore this class. TQGLWidget and the other - OpenGL* module classes inherit it, so when you make your - own TQGLWidget subclass you can use the identifiers in the TQGL - namespace without qualification. - - However, you may occasionally find yourself in situations where you - need to refer to these identifiers from outside the TQGL namespace's - scope, e.g. in static functions. In such cases, simply write e.g. \c - TQGL::DoubleBuffer instead of just \c DoubleBuffer. - - * OpenGL is a trademark of Silicon Graphics, Inc. in the - United States and other countries. - -*/ - - -/***************************************************************************** - TQGLFormat implementation - *****************************************************************************/ - - -/*! - \class TQGLFormat ntqgl.h - \brief The TQGLFormat class specifies the display format of an OpenGL - rendering context. -\if defined(commercial) - It is part of the TQt Enterprise Edition. -\endif - - \ingroup graphics - \ingroup images - \module OpenGL - - A display format has several characteristics: - \list - \i \link setDoubleBuffer() Double or single buffering.\endlink - \i \link setDepth() Depth buffer.\endlink - \i \link setRgba() RGBA or color index mode.\endlink - \i \link setAlpha() Alpha channel.\endlink - \i \link setAccum() Accumulation buffer.\endlink - \i \link setStencil() Stencil buffer.\endlink - \i \link setStereo() Stereo buffers.\endlink - \i \link setDirectRendering() Direct rendering.\endlink - \i \link setOverlay() Presence of an overlay.\endlink - \i \link setPlane() The plane of an overlay format.\endlink - \endlist - - You create and tell a TQGLFormat object what rendering options you - want from an OpenGL* rendering context. - - OpenGL drivers or accelerated hardware may or may not support - advanced features such as alpha channel or stereographic viewing. - If you request some features that the driver/hardware does not - provide when you create a TQGLWidget, you will get a rendering - context with the nearest subset of features. - - There are different ways to define the display characteristics of - a rendering context. One is to create a TQGLFormat and make it the - default for the entire application: - \code - TQGLFormat f; - f.setAlpha( TRUE ); - f.setStereo( TRUE ); - TQGLFormat::setDefaultFormat( f ); - \endcode - - Or you can specify the desired format when creating an object of - your TQGLWidget subclass: - \code - TQGLFormat f; - f.setDoubleBuffer( FALSE ); // single buffer - f.setDirectRendering( FALSE ); // software rendering - MyGLWidget* myWidget = new MyGLWidget( f, ... ); - \endcode - - After the widget has been created, you can find out which of the - requested features the system was able to provide: - \code - TQGLFormat f; - f.setOverlay( TRUE ); - f.setStereo( TRUE ); - MyGLWidget* myWidget = new MyGLWidget( f, ... ); - if ( !w->format().stereo() ) { - // ok, goggles off - if ( !w->format().hasOverlay() ) { - tqFatal( "Cool hardware required" ); - } - } - \endcode - - * OpenGL is a trademark of Silicon Graphics, Inc. in the - United States and other countries. - - \sa TQGLContext, TQGLWidget -*/ - - -/*! - Constructs a TQGLFormat object with the factory default settings: - \list - \i \link setDoubleBuffer() Double buffer:\endlink Enabled. - \i \link setDepth() Depth buffer:\endlink Enabled. - \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled). - \i \link setAlpha() Alpha channel:\endlink Disabled. - \i \link setAccum() Accumulator buffer:\endlink Disabled. - \i \link setStencil() Stencil buffer:\endlink Disabled. - \i \link setStereo() Stereo:\endlink Disabled. - \i \link setDirectRendering() Direct rendering:\endlink Enabled. - \i \link setOverlay() Overlay:\endlink Disabled. - \i \link setPlane() Plane:\endlink 0 (i.e., normal plane). - \endlist -*/ - -TQGLFormat::TQGLFormat() -{ - opts = DoubleBuffer | DepthBuffer | Rgba | DirectRendering; - pln = 0; -} - - -/*! - Creates a TQGLFormat object that is a copy of the current \link - defaultFormat() application default format\endlink. - - If \a options is not 0, this copy is modified by these format - options. The \a options parameter should be \c FormatOption values - OR'ed together. - - This constructor makes it easy to specify a certain desired format - in classes derived from TQGLWidget, for example: - \code - // The rendering in MyGLWidget depends on using - // stencil buffer and alpha channel - MyGLWidget::MyGLWidget( TQWidget* parent, const char* name ) - : TQGLWidget( TQGLFormat( StencilBuffer | AlphaChannel ), parent, name ) - { - if ( !format().stencil() ) - tqWarning( "Could not get stencil buffer; results will be suboptimal" ); - if ( !format().alphaChannel() ) - tqWarning( "Could not get alpha channel; results will be suboptimal" ); - ... - } - \endcode - - Note that there are \c FormatOption values to turn format settings - both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer, - \c DirectRendering and \c IndirectRendering, etc. - - The \a plane parameter defaults to 0 and is the plane which this - format should be associated with. Not all OpenGL implmentations - supports overlay/underlay rendering planes. - - \sa defaultFormat(), setOption() -*/ - -TQGLFormat::TQGLFormat( int options, int plane ) -{ - uint newOpts = options; - opts = defaultFormat().opts; - opts |= ( newOpts & 0xffff ); - opts &= ~( newOpts >> 16 ); - pln = plane; -} - - -/*! - \fn bool TQGLFormat::doubleBuffer() const - - Returns TRUE if double buffering is enabled; otherwise returns - FALSE. Double buffering is enabled by default. - - \sa setDoubleBuffer() -*/ - -/*! - If \a enable is TRUE sets double buffering; otherwise sets single - buffering. - - Double buffering is enabled by default. - - Double buffering is a technique where graphics are rendered on an - off-screen buffer and not directly to the screen. When the drawing - has been completed, the program calls a swapBuffers() function to - exchange the screen contents with the buffer. The result is - flicker-free drawing and often better performance. - - \sa doubleBuffer(), TQGLContext::swapBuffers(), - TQGLWidget::swapBuffers() -*/ - -void TQGLFormat::setDoubleBuffer( bool enable ) -{ - setOption( enable ? DoubleBuffer : SingleBuffer ); -} - - -/*! - \fn bool TQGLFormat::depth() const - - Returns TRUE if the depth buffer is enabled; otherwise returns - FALSE. The depth buffer is enabled by default. - - \sa setDepth() -*/ - -/*! - If \a enable is TRUE enables the depth buffer; otherwise disables - the depth buffer. - - The depth buffer is enabled by default. - - The purpose of a depth buffer (or Z-buffering) is to remove hidden - surfaces. Pixels are assigned Z values based on the distance to - the viewer. A pixel with a high Z value is closer to the viewer - than a pixel with a low Z value. This information is used to - decide whether to draw a pixel or not. - - \sa depth() -*/ - -void TQGLFormat::setDepth( bool enable ) -{ - setOption( enable ? DepthBuffer : NoDepthBuffer ); -} - - -/*! - \fn bool TQGLFormat::rgba() const - - Returns TRUE if RGBA color mode is set. Returns FALSE if color - index mode is set. The default color mode is RGBA. - - \sa setRgba() -*/ - -/*! - If \a enable is TRUE sets RGBA mode. If \a enable is FALSE sets - color index mode. - - The default color mode is RGBA. - - RGBA is the preferred mode for most OpenGL applications. In RGBA - color mode you specify colors as red + green + blue + alpha - quadruplets. - - In color index mode you specify an index into a color lookup - table. - - \sa rgba() -*/ - -void TQGLFormat::setRgba( bool enable ) -{ - setOption( enable ? Rgba : ColorIndex ); -} - - -/*! - \fn bool TQGLFormat::alpha() const - - Returns TRUE if the alpha channel of the framebuffer is enabled; - otherwise returns FALSE. The alpha channel is disabled by default. - - \sa setAlpha() -*/ - -/*! - If \a enable is TRUE enables the alpha channel; otherwise disables - the alpha channel. - - The alpha buffer is disabled by default. - - The alpha channel is typically used for implementing transparency - or translucency. The A in RGBA specifies the transparency of a - pixel. - - \sa alpha() -*/ - -void TQGLFormat::setAlpha( bool enable ) -{ - setOption( enable ? AlphaChannel : NoAlphaChannel ); -} - - -/*! - \fn bool TQGLFormat::accum() const - - Returns TRUE if the accumulation buffer is enabled; otherwise - returns FALSE. The accumulation buffer is disabled by default. - - \sa setAccum() -*/ - -/*! - If \a enable is TRUE enables the accumulation buffer; otherwise - disables the accumulation buffer. - - The accumulation buffer is disabled by default. - - The accumulation buffer is used to create blur effects and - multiple exposures. - - \sa accum() -*/ - -void TQGLFormat::setAccum( bool enable ) -{ - setOption( enable ? AccumBuffer : NoAccumBuffer ); -} - - -/*! - \fn bool TQGLFormat::stencil() const - - Returns TRUE if the stencil buffer is enabled; otherwise returns - FALSE. The stencil buffer is disabled by default. - - \sa setStencil() -*/ - -/*! - If \a enable is TRUE enables the stencil buffer; otherwise - disables the stencil buffer. - - The stencil buffer is disabled by default. - - The stencil buffer masks certain parts of the drawing area so that - masked parts are not drawn on. - - \sa stencil() -*/ - -void TQGLFormat::setStencil( bool enable ) -{ - setOption( enable ? StencilBuffer: NoStencilBuffer ); -} - - -/*! - \fn bool TQGLFormat::stereo() const - - Returns TRUE if stereo buffering is enabled; otherwise returns - FALSE. Stereo buffering is disabled by default. - - \sa setStereo() -*/ - -/*! - If \a enable is TRUE enables stereo buffering; otherwise disables - stereo buffering. - - Stereo buffering is disabled by default. - - Stereo buffering provides extra color buffers to generate left-eye - and right-eye images. - - \sa stereo() -*/ - -void TQGLFormat::setStereo( bool enable ) -{ - setOption( enable ? StereoBuffers : NoStereoBuffers ); -} - - -/*! - \fn bool TQGLFormat::directRendering() const - - Returns TRUE if direct rendering is enabled; otherwise returns - FALSE. - - Direct rendering is enabled by default. - - \sa setDirectRendering() -*/ - -/*! - If \a enable is TRUE enables direct rendering; otherwise disables - direct rendering. - - Direct rendering is enabled by default. - - Enabling this option will make OpenGL bypass the underlying window - system and render directly from hardware to the screen, if this is - supported by the system. - - \sa directRendering() -*/ - -void TQGLFormat::setDirectRendering( bool enable ) -{ - setOption( enable ? DirectRendering : IndirectRendering ); -} - - -/*! - \fn bool TQGLFormat::hasOverlay() const - - Returns TRUE if overlay plane is enabled; otherwise returns FALSE. - - Overlay is disabled by default. - - \sa setOverlay() -*/ - -/*! - If \a enable is TRUE enables an overlay plane; otherwise disables - the overlay plane. - - Enabling the overlay plane will cause TQGLWidget to create an - additional context in an overlay plane. See the TQGLWidget - documentation for further information. - - \sa hasOverlay() -*/ - -void TQGLFormat::setOverlay( bool enable ) -{ - setOption( enable ? HasOverlay : NoOverlay ); -} - -/*! - Returns the plane of this format. The default for normal formats - is 0, which means the normal plane. The default for overlay - formats is 1, which is the first overlay plane. - - \sa setPlane() -*/ -int TQGLFormat::plane() const -{ - return pln; -} - -/*! - Sets the requested plane to \a plane. 0 is the normal plane, 1 is - the first overlay plane, 2 is the second overlay plane, etc.; -1, - -2, etc. are underlay planes. - - Note that in contrast to other format specifications, the plane - specifications will be matched exactly. This means that if you - specify a plane that the underlying OpenGL system cannot provide, - an \link TQGLWidget::isValid() invalid\endlink TQGLWidget will be - created. - - \sa plane() -*/ -void TQGLFormat::setPlane( int plane ) -{ - pln = plane; -} - -/*! - Sets the format option to \a opt. - - \sa testOption() -*/ - -void TQGLFormat::setOption( FormatOption opt ) -{ - if ( opt & 0xffff ) - opts |= opt; - else - opts &= ~( opt >> 16 ); -} - - - -/*! - Returns TRUE if format option \a opt is set; otherwise returns FALSE. - - \sa setOption() -*/ - -bool TQGLFormat::testOption( FormatOption opt ) const -{ - if ( opt & 0xffff ) - return ( opts & opt ) != 0; - else - return ( opts & ( opt >> 16 ) ) == 0; -} - - - -/*! - \fn bool TQGLFormat::hasOpenGL() - - Returns TRUE if the window system has any OpenGL support; - otherwise returns FALSE. - - \warning This function must not be called until the TQApplication - object has been created. -*/ - - - -/*! - \fn bool TQGLFormat::hasOpenGLOverlays() - - Returns TRUE if the window system supports OpenGL overlays; - otherwise returns FALSE. - - \warning This function must not be called until the TQApplication - object has been created. -*/ - -/*! - Returns the default TQGLFormat for the application. All TQGLWidgets - that are created use this format unless another format is - specified, e.g. when they are constructed. - - If no special default format has been set using - setDefaultFormat(), the default format is the same as that created - with TQGLFormat(). - - \sa setDefaultFormat() -*/ - -TQGLFormat TQGLFormat::defaultFormat() -{ - if ( !qgl_default_format ) { - qgl_default_format = new TQGLFormat; - qgl_cleanup_format.add( &qgl_default_format ); - } - return *qgl_default_format; -} - -/*! - Sets a new default TQGLFormat for the application to \a f. For - example, to set single buffering as the default instead of double - buffering, your main() might contain code like this: - \code - TQApplication a(argc, argv); - TQGLFormat f; - f.setDoubleBuffer( FALSE ); - TQGLFormat::setDefaultFormat( f ); - \endcode - - \sa defaultFormat() -*/ - -void TQGLFormat::setDefaultFormat( const TQGLFormat &f ) -{ - if ( !qgl_default_format ) { - qgl_default_format = new TQGLFormat; - qgl_cleanup_format.add( &qgl_default_format ); - } - *qgl_default_format = f; -} - - -/*! - Returns the default TQGLFormat for overlay contexts. - - The factory default overlay format is: - \list - \i \link setDoubleBuffer() Double buffer:\endlink Disabled. - \i \link setDepth() Depth buffer:\endlink Disabled. - \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled). - \i \link setAlpha() Alpha channel:\endlink Disabled. - \i \link setAccum() Accumulator buffer:\endlink Disabled. - \i \link setStencil() Stencil buffer:\endlink Disabled. - \i \link setStereo() Stereo:\endlink Disabled. - \i \link setDirectRendering() Direct rendering:\endlink Enabled. - \i \link setOverlay() Overlay:\endlink Disabled. - \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane). - \endlist - - \sa setDefaultFormat() -*/ - -TQGLFormat TQGLFormat::defaultOverlayFormat() -{ - if ( !qgl_default_overlay_format ) { - qgl_default_overlay_format = new TQGLFormat; - qgl_default_overlay_format->opts = DirectRendering; - qgl_default_overlay_format->pln = 1; - qgl_cleanup_format.add( &qgl_default_overlay_format ); - } - return *qgl_default_overlay_format; -} - -/*! - Sets a new default TQGLFormat for overlay contexts to \a f. This - format is used whenever a TQGLWidget is created with a format that - hasOverlay() enabled. - - For example, to get a double buffered overlay context (if - available), use code like this: - - \code - TQGLFormat f = TQGLFormat::defaultOverlayFormat(); - f.setDoubleBuffer( TRUE ); - TQGLFormat::setDefaultOverlayFormat( f ); - \endcode - - As usual, you can find out after widget creation whether the - underlying OpenGL system was able to provide the requested - specification: - - \code - // ...continued from above - MyGLWidget* myWidget = new MyGLWidget( TQGLFormat( TQGL::HasOverlay ), ... ); - if ( myWidget->format().hasOverlay() ) { - // Yes, we got an overlay, let's check _its_ format: - TQGLContext* olContext = myWidget->overlayContext(); - if ( olContext->format().doubleBuffer() ) - ; // yes, we got a double buffered overlay - else - ; // no, only single buffered overlays are available - } - \endcode - - \sa defaultOverlayFormat() -*/ - -void TQGLFormat::setDefaultOverlayFormat( const TQGLFormat &f ) -{ - if ( !qgl_default_overlay_format ) { - qgl_default_overlay_format = new TQGLFormat; - qgl_cleanup_format.add( &qgl_default_overlay_format ); - } - *qgl_default_overlay_format = f; - // Make sure the user doesn't request that the overlays themselves - // have overlays, since it is unlikely that the system supports - // infinitely many planes... - qgl_default_overlay_format->setOverlay( FALSE ); -} - - -/*! - Returns TRUE if all the options of the two TQGLFormats are equal; - otherwise returns FALSE. -*/ - -bool operator==( const TQGLFormat& a, const TQGLFormat& b ) -{ - return (a.opts == b.opts) && (a.pln == b.pln); -} - - -/*! - Returns FALSE if all the options of the two TQGLFormats are equal; - otherwise returns TRUE. -*/ - -bool operator!=( const TQGLFormat& a, const TQGLFormat& b ) -{ - return !( a == b ); -} - - - -/***************************************************************************** - TQGLContext implementation - *****************************************************************************/ - -TQGLContext* TQGLContext::currentCtx = 0; - -/*! - \class TQGLContext ntqgl.h - \brief The TQGLContext class encapsulates an OpenGL rendering context. -\if defined(commercial) - It is part of the TQt Enterprise Edition. -\endif - - \ingroup graphics - \ingroup images - \module OpenGL - - An OpenGL* rendering context is a complete set of - OpenGL state variables. - - The context's \link TQGL::FormatOption format\endlink is set in the - constructor or later with setFormat(). The format options that are - actually set are returned by format(); the options you asked for - are returned by requestedFormat(). Note that after a TQGLContext - object has been constructed, the actual OpenGL context must be - created by explicitly calling the \link create() create()\endlink - function. The makeCurrent() function makes this context the - current rendering context. You can make \e no context current - using doneCurrent(). The reset() function will reset the context - and make it invalid. - - You can examine properties of the context with, e.g. isValid(), - isSharing(), initialized(), windowCreated() and - overlayTransparentColor(). - - If you're using double buffering you can swap the screen contents - with the off-screen buffer using swapBuffers(). - - Please note that TQGLContext is not thread safe. - - * OpenGL is a trademark of Silicon Graphics, Inc. in the - United States and other countries. - -*/ - - -/*! - Constructs an OpenGL context for the paint device \a device, which - can be a widget or a pixmap. The \a format specifies several - display options for the context. - - If the underlying OpenGL/Window system cannot satisfy all the - features requested in \a format, the nearest subset of features - will be used. After creation, the format() method will return the - actual format obtained. - - Note that after a TQGLContext object has been constructed, \link - create() create()\endlink must be called explicitly to create - the actual OpenGL context. The context will be \link isValid() - invalid\endlink if it was not possible to obtain a GL context at - all. - - \sa format(), isValid() -*/ - -TQGLContext::TQGLContext( const TQGLFormat &format, TQPaintDevice *device ) - : glFormat(format), reqFormat(format) -{ - init( device ); -} - -/*! - \overload - \internal -*/ -TQGLContext::TQGLContext( const TQGLFormat &format ) - : glFormat( format ), reqFormat(format) -{ - init(); -} - -/*! - Destroys the OpenGL context and frees its resources. -*/ - -TQGLContext::~TQGLContext() -{ - reset(); - if ( d ) - delete d; -} - - -/*! - \fn TQGLFormat TQGLContext::format() const - - Returns the frame buffer format that was obtained (this may be a - subset of what was requested). - - \sa requestedFormat() -*/ - -/*! - \fn TQGLFormat TQGLContext::requestedFormat() const - - Returns the frame buffer format that was originally requested in - the constructor or setFormat(). - - \sa format() -*/ - -/*! - Sets a \a format for this context. The context is \link reset() - reset\endlink. - - Call create() to create a new GL context that tries to match the - new format. - - \code - TQGLContext *cx; - // ... - TQGLFormat f; - f.setStereo( TRUE ); - cx->setFormat( f ); - if ( !cx->create() ) - exit(); // no OpenGL support, or cannot render on the specified paintdevice - if ( !cx->format().stereo() ) - exit(); // could not create stereo context - \endcode - - \sa format(), reset(), create() -*/ - -void TQGLContext::setFormat( const TQGLFormat &format ) -{ - reset(); - glFormat = reqFormat = format; -} - -/*! - \internal -*/ -void TQGLContext::setDevice( TQPaintDevice *pDev ) -{ - if ( isValid() ) - reset(); - d->paintDevice = pDev; - if ( d->paintDevice && (d->paintDevice->devType() != TQInternal::Widget - && d->paintDevice->devType() != TQInternal::Pixmap) ) { -#if defined(QT_CHECK_RANGE) - tqWarning( "TQGLContext: Unsupported paint device type" ); -#endif - } -} - -void TQGLContext::init( TQPaintDevice *dev ) -{ - d = new Private; - d->valid = FALSE; -#if defined(TQ_WS_X11) - qt_resolve_gl_symbols(); - gpm = 0; -#endif - setDevice( dev ); -#if defined(TQ_WS_WIN) - dc = 0; - win = 0; - pixelFormatId = 0; - cmap = 0; -#endif -#if defined(TQ_WS_MAC) - d->oldR = TQRect(1, 1, 1, 1); -#endif - d->crWin = FALSE; - d->initDone = FALSE; - d->sharing = FALSE; -} - -/*! - \fn bool TQGLContext::isValid() const - - Returns TRUE if a GL rendering context has been successfully - created; otherwise returns FALSE. -*/ - -/*! - \fn void TQGLContext::setValid( bool valid ) - \internal - - Forces the GL rendering context to be valid. -*/ - -/*! - \fn bool TQGLContext::isSharing() const - - Returns TRUE if display list sharing with another context was - requested in the create() call and the GL system was able to - fulfill this request; otherwise returns FALSE. Note that display - list sharing might not be supported between contexts with - different formats. -*/ - -/*! - \fn bool TQGLContext::deviceIsPixmap() const - - Returns TRUE if the paint device of this context is a pixmap; - otherwise returns FALSE. -*/ - -/*! - \fn bool TQGLContext::windowCreated() const - - Returns TRUE if a window has been created for this context; - otherwise returns FALSE. - - \sa setWindowCreated() -*/ - -/*! - \fn void TQGLContext::setWindowCreated( bool on ) - - If \a on is TRUE the context has had a window created for it. If - \a on is FALSE no window has been created for the context. - - \sa windowCreated() -*/ - -/*! - \fn uint TQGLContext::colorIndex( const TQColor& c ) const - - \internal - - Returns a colormap index for the color c, in ColorIndex mode. Used - by qglColor() and qglClearColor(). -*/ - - -/*! - \fn bool TQGLContext::initialized() const - - Returns TRUE if this context has been initialized, i.e. if - TQGLWidget::initializeGL() has been performed on it; otherwise - returns FALSE. - - \sa setInitialized() -*/ - -/*! - \fn void TQGLContext::setInitialized( bool on ) - - If \a on is TRUE the context has been initialized, i.e. - TQGLContext::setInitialized() has been called on it. If \a on is - FALSE the context has not been initialized. - - \sa initialized() -*/ - -/*! - \fn const TQGLContext* TQGLContext::currentContext() - - Returns the current context, i.e. the context to which any OpenGL - commands will currently be directed. Returns 0 if no context is - current. - - \sa makeCurrent() -*/ - -/*! - \fn TQColor TQGLContext::overlayTransparentColor() const - - If this context is a valid context in an overlay plane, returns - the plane's transparent color. Otherwise returns an \link - TQColor::isValid() invalid \endlink color. - - The returned color's \link TQColor::pixel() pixel \endlink value is - the index of the transparent color in the colormap of the overlay - plane. (Naturally, the color's RGB values are meaningless.) - - The returned TQColor object will generally work as expected only - when passed as the argument to TQGLWidget::qglColor() or - TQGLWidget::qglClearColor(). Under certain circumstances it can - also be used to draw transparent graphics with a TQPainter. See the - examples/opengl/overlay_x11 example for details. -*/ - - -/*! - Creates the GL context. Returns TRUE if it was successful in - creating a valid GL rendering context on the paint device - specified in the constructor; otherwise returns FALSE (i.e. the - context is invalid). - - After successful creation, format() returns the set of features of - the created GL rendering context. - - If \a shareContext points to a valid TQGLContext, this method will - try to establish OpenGL display list sharing between this context - and the \a shareContext. Note that this may fail if the two - contexts have different formats. Use isSharing() to see if sharing - succeeded. - - \warning Implementation note: initialization of C++ class - members usually takes place in the class constructor. TQGLContext - is an exception because it must be simple to customize. The - virtual functions chooseContext() (and chooseVisual() for X11) can - be reimplemented in a subclass to select a particular context. The - problem is that virtual functions are not properly called during - construction (even though this is correct C++) because C++ - constructs class hierarchies from the bottom up. For this reason - we need a create() function. - - \sa chooseContext(), format(), isValid() -*/ - -bool TQGLContext::create( const TQGLContext* shareContext ) -{ - reset(); - d->valid = chooseContext( shareContext ); - return d->valid; -} - - - -/*! - \fn bool TQGLContext::chooseContext( const TQGLContext* shareContext = 0 ) - - This semi-internal function is called by create(). It creates a - system-dependent OpenGL handle that matches the format() of \a - shareContext as closely as possible. - - On Windows, it calls the virtual function choosePixelFormat(), - which finds a matching pixel format identifier. On X11, it calls - the virtual function chooseVisual() which finds an appropriate X - visual. On other platforms it may work differently. -*/ - - -/*! - \fn void TQGLContext::reset() - - Resets the context and makes it invalid. - - \sa create(), isValid() -*/ - - -/*! - \fn void TQGLContext::makeCurrent() - - Makes this context the current OpenGL rendering context. All GL - functions you call operate on this context until another context - is made current. - - In some very rare cases the underlying call may fail. If this - occurs an error message is output to stderr. -*/ - - -/*! - \fn void TQGLContext::swapBuffers() const - - Swaps the screen contents with an off-screen buffer. Only works if - the context is in double buffer mode. - - \sa TQGLFormat::setDoubleBuffer() -*/ - - -/*! - \fn void TQGLContext::doneCurrent() - - Makes no GL context the current context. Normally, you do not need - to call this function; TQGLContext calls it as necessary. -*/ - - -/*! - \fn TQPaintDevice* TQGLContext::device() const - - Returns the paint device set for this context. - - \sa TQGLContext::TQGLContext() -*/ - -/*! - \fn void TQGLContext::generateFontDisplayLists( const TQFont& font, int listBase ) - - Generates a set of 256 display lists for the 256 first characters - in the font \a font. The first list will start at index \a listBase. - - \sa TQGLWidget::renderText() -*/ - - -/***************************************************************************** - TQGLWidget implementation - *****************************************************************************/ - - -/*! - \class TQGLWidget ntqgl.h - \brief The TQGLWidget class is a widget for rendering OpenGL graphics. -\if defined(commercial) - It is part of the TQt Enterprise Edition. -\endif - - \ingroup graphics - \ingroup images - \mainclass - \module OpenGL - - TQGLWidget provides functionality for displaying OpenGL* - graphics integrated into a TQt application. It is very simple to - use. You inherit from it and use the subclass like any other - TQWidget, except that instead of drawing the widget's contents - using TQPainter etc. you use the standard OpenGL rendering - commands. - - TQGLWidget provides three convenient virtual functions that you can - reimplement in your subclass to perform the typical OpenGL tasks: - - \list - \i paintGL() - Renders the OpenGL scene. Gets called whenever the widget - needs to be updated. - \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets - called whenever the the widget has been resized (and also when it - is shown for the first time because all newly created widgets get a - resize event automatically). - \i initializeGL() - Sets up the OpenGL rendering context, defines display - lists, etc. Gets called once before the first time resizeGL() or - paintGL() is called. - \endlist - - Here is a rough outline of how a TQGLWidget subclass might look: - - \code - class MyGLDrawer : public TQGLWidget - { - TQ_OBJECT // must include this if you use TQt signals/slots - - public: - MyGLDrawer( TQWidget *parent, const char *name ) - : TQGLWidget(parent, name) {} - - protected: - - void initializeGL() - { - // Set up the rendering context, define display lists etc.: - ... - glClearColor( 0.0, 0.0, 0.0, 0.0 ); - glEnable(GL_DEPTH_TEST); - ... - } - - void resizeGL( int w, int h ) - { - // setup viewport, projection etc.: - glViewport( 0, 0, (GLint)w, (GLint)h ); - ... - glFrustum( ... ); - ... - } - - void paintGL() - { - // draw the scene: - ... - glRotatef( ... ); - glMaterialfv( ... ); - glBegin( GL_QUADS ); - glVertex3f( ... ); - glVertex3f( ... ); - ... - glEnd(); - ... - } - - }; - \endcode - - If you need to trigger a repaint from places other than paintGL() - (a typical example is when using \link TQTimer timers\endlink to - animate scenes), you should call the widget's updateGL() function. - - Your widget's OpenGL rendering context is made current when - paintGL(), resizeGL(), or initializeGL() is called. If you need to - call the standard OpenGL API functions from other places (e.g. in - your widget's constructor or in your own paint functions), you - must call makeCurrent() first. - - TQGLWidget provides functions for requesting a new display \link - TQGLFormat format\endlink and you can also create widgets with - customized rendering \link TQGLContext contexts\endlink. - - You can also share OpenGL display lists between TQGLWidgets (see - the documentation of the TQGLWidget constructors for details). - - \section1 Overlays - - The TQGLWidget creates a GL overlay context in addition to the - normal context if overlays are supported by the underlying system. - - If you want to use overlays, you specify it in the \link TQGLFormat - format\endlink. (Note: Overlay must be requested in the format - passed to the TQGLWidget constructor.) Your GL widget should also - implement some or all of these virtual methods: - - \list - \i paintOverlayGL() - \i resizeOverlayGL() - \i initializeOverlayGL() - \endlist - - These methods work in the same way as the normal paintGL() etc. - functions, except that they will be called when the overlay - context is made current. You can explicitly make the overlay - context current by using makeOverlayCurrent(), and you can access - the overlay context directly (e.g. to ask for its transparent - color) by calling overlayContext(). - - On X servers in which the default visual is in an overlay plane, - non-GL TQt windows can also be used for overlays. See the - examples/opengl/overlay_x11 example program for details. - - * OpenGL is a trademark of Silicon Graphics, Inc. in the - United States and other countries. -*/ - -// ### BCI - fix in 4.0 - -// the display list cache can't be global because display lists are -// tied to the GL contexts for each individual widget - -class TQGLWidgetPrivate -{ -public: - TQMap displayListCache; -}; - -static TQPtrDict * qgl_d_ptr = 0; -static TQSingleCleanupHandler< TQPtrDict > qgl_cleanup_d_ptr; - -static TQGLWidgetPrivate * qgl_d( const TQGLWidget * w ) -{ - if ( !qgl_d_ptr ) { - qgl_d_ptr = new TQPtrDict; - qgl_cleanup_d_ptr.set( &qgl_d_ptr ); - qgl_d_ptr->setAutoDelete( TRUE ); - } - TQGLWidgetPrivate * ret = qgl_d_ptr->find( (void *) w ); - if ( !ret ) { - ret = new TQGLWidgetPrivate; - qgl_d_ptr->replace( (void *) w, ret ); - } - return ret; -} - -void qgl_delete_d( const TQGLWidget * w ) -{ - if ( qgl_d_ptr ) - qgl_d_ptr->remove( (void *) w ); -} - -/*! - Constructs an OpenGL widget with a \a parent widget and a \a name. - - The \link TQGLFormat::defaultFormat() default format\endlink is - used. The widget will be \link isValid() invalid\endlink if the - system has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. - - The \a parent, \a name and widget flag, \a f, arguments are passed - to the TQWidget constructor. - - If the \a shareWidget parameter points to a valid TQGLWidget, this - widget will share OpenGL display lists with \a shareWidget. If - this widget and \a shareWidget have different \link format() - formats\endlink, display list sharing may fail. You can check - whether display list sharing succeeded by calling isSharing(). - - The initialization of OpenGL rendering state, etc. should be done - by overriding the initializeGL() function, rather than in the - constructor of your TQGLWidget subclass. - - \sa TQGLFormat::defaultFormat() -*/ - -TQGLWidget::TQGLWidget( TQWidget *parent, const char *name, - const TQGLWidget* shareWidget, WFlags f ) - : TQWidget( parent, name, f | TQt::WWinOwnDC | TQt::WNoAutoErase ) -{ - init( new TQGLContext(TQGLFormat::defaultFormat(), this), shareWidget ); -} - - -/*! - Constructs an OpenGL widget with parent \a parent, called \a name. - - The \a format argument specifies the desired \link TQGLFormat - rendering options \endlink. If the underlying OpenGL/Window system - cannot satisfy all the features requested in \a format, the - nearest subset of features will be used. After creation, the - format() method will return the actual format obtained. - - The widget will be \link isValid() invalid\endlink if the system - has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. - - The \a parent, \a name and widget flag, \a f, arguments are passed - to the TQWidget constructor. - - If the \a shareWidget parameter points to a valid TQGLWidget, this - widget will share OpenGL display lists with \a shareWidget. If - this widget and \a shareWidget have different \link format() - formats\endlink, display list sharing may fail. You can check - whether display list sharing succeeded by calling isSharing(). - - The initialization of OpenGL rendering state, etc. should be done - by overriding the initializeGL() function, rather than in the - constructor of your TQGLWidget subclass. - - \sa TQGLFormat::defaultFormat(), isValid() -*/ - -TQGLWidget::TQGLWidget( const TQGLFormat &format, TQWidget *parent, - const char *name, const TQGLWidget* shareWidget, - WFlags f ) - : TQWidget( parent, name, f | TQt::WWinOwnDC | TQt::WNoAutoErase ) -{ - init( new TQGLContext(format, this), shareWidget ); -} - -/*! - Constructs an OpenGL widget with parent \a parent, called \a name. - - The \a context argument is a pointer to the TQGLContext that - you wish to be bound to this widget. This allows you to pass in - your own TQGLContext sub-classes. - - The widget will be \link isValid() invalid\endlink if the system - has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. - - The \a parent, \a name and widget flag, \a f, arguments are passed - to the TQWidget constructor. - - If the \a shareWidget parameter points to a valid TQGLWidget, this - widget will share OpenGL display lists with \a shareWidget. If - this widget and \a shareWidget have different \link format() - formats\endlink, display list sharing may fail. You can check - whether display list sharing succeeded by calling isSharing(). - - The initialization of OpenGL rendering state, etc. should be done - by overriding the initializeGL() function, rather than in the - constructor of your TQGLWidget subclass. - - \sa TQGLFormat::defaultFormat(), isValid() -*/ -TQGLWidget::TQGLWidget( TQGLContext *context, TQWidget *parent, - const char *name, const TQGLWidget *shareWidget, WFlags f ) - : TQWidget( parent, name, f | TQt::WWinOwnDC | TQt::WNoAutoErase ) -{ - init( context, shareWidget ); -} - -/*! - Destroys the widget. -*/ - -TQGLWidget::~TQGLWidget() -{ -#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT) - bool doRelease = ( glcx && glcx->windowCreated() ); -#endif - qgl_delete_d( this ); - delete glcx; -#if defined(Q_WGL) - delete olcx; -#endif -#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT) - if ( doRelease ) - glXReleaseBuffersMESA( x11Display(), winId() ); -#endif -#if defined(TQ_WS_MAC) - if(gl_pix) { - delete gl_pix; - gl_pix = NULL; - } -#endif - cleanupColormaps(); -} - - - - - -/*! - \fn TQGLFormat TQGLWidget::format() const - - Returns the format of the contained GL rendering context. -*/ - -/*! - \fn bool TQGLWidget::doubleBuffer() const - - Returns TRUE if the contained GL rendering context has double - buffering; otherwise returns FALSE. - - \sa TQGLFormat::doubleBuffer() -*/ - -/*! - \fn void TQGLWidget::setAutoBufferSwap( bool on ) - - If \a on is TRUE automatic GL buffer swapping is switched on; - otherwise it is switched off. - - If \a on is TRUE and the widget is using a double-buffered format, - the background and foreground GL buffers will automatically be - swapped after each paintGL() call. - - The buffer auto-swapping is on by default. - - \sa autoBufferSwap(), doubleBuffer(), swapBuffers() -*/ - -/*! - \fn bool TQGLWidget::autoBufferSwap() const - - Returns TRUE if the widget is doing automatic GL buffer swapping; - otherwise returns FALSE. - - \sa setAutoBufferSwap() -*/ - -/*! - \fn bool TQGLWidget::isValid() const - - Returns TRUE if the widget has a valid GL rendering context; - otherwise returns FALSE. A widget will be invalid if the system - has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. -*/ - -bool TQGLWidget::isValid() const -{ - return glcx->isValid(); -} - -/*! - \fn bool TQGLWidget::isSharing() const - - Returns TRUE if display list sharing with another TQGLWidget was - requested in the constructor, and the GL system was able to - provide it; otherwise returns FALSE. The GL system may fail to - provide display list sharing if the two TQGLWidgets use different - formats. - - \sa format() -*/ - -bool TQGLWidget::isSharing() const -{ - return glcx->isSharing(); -} - -/*! - \fn void TQGLWidget::makeCurrent() - - Makes this widget the current widget for OpenGL operations, i.e. - makes the widget's rendering context the current OpenGL rendering - context. -*/ - -void TQGLWidget::makeCurrent() -{ -#if defined( TQ_WS_MAC ) - macInternalDoubleBuffer(); //make sure the correct context is used -#endif - glcx->makeCurrent(); -} - -/*! - \fn void TQGLWidget::doneCurrent() - - Makes no GL context the current context. Normally, you do not need - to call this function; TQGLContext calls it as necessary. However, - it may be useful in multithreaded environments. -*/ - -void TQGLWidget::doneCurrent() -{ - glcx->doneCurrent(); -} - -/*! - \fn void TQGLWidget::swapBuffers() - - Swaps the screen contents with an off-screen buffer. This only - works if the widget's format specifies double buffer mode. - - Normally, there is no need to explicitly call this function - because it is done automatically after each widget repaint, i.e. - each time after paintGL() has been executed. - - \sa doubleBuffer(), setAutoBufferSwap(), TQGLFormat::setDoubleBuffer() -*/ - -void TQGLWidget::swapBuffers() -{ - glcx->swapBuffers(); -#if defined(TQ_WS_MAC) - if(macInternalDoubleBuffer() && gl_pix) - bitBlt(this, 0, 0, gl_pix); -#endif -} - - -/*! - \fn const TQGLContext* TQGLWidget::overlayContext() const - - Returns the overlay context of this widget, or 0 if this widget - has no overlay. - - \sa context() -*/ - - - -/*! - \fn void TQGLWidget::makeOverlayCurrent() - - Makes the overlay context of this widget current. Use this if you - need to issue OpenGL commands to the overlay context outside of - initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL(). - - Does nothing if this widget has no overlay. - - \sa makeCurrent() -*/ - - -/* - \obsolete - - Sets a new format for this widget. - - If the underlying OpenGL/Window system cannot satisfy all the - features requested in \a format, the nearest subset of features will - be used. After creation, the format() method will return the actual - rendering context format obtained. - - The widget will be assigned a new TQGLContext, and the initializeGL() - function will be executed for this new context before the first - resizeGL() or paintGL(). - - This method will try to keep any existing display list sharing with - other TQGLWidgets, but it may fail. Use isSharing() to test. - - \sa format(), isSharing(), isValid() -*/ - -void TQGLWidget::setFormat( const TQGLFormat &format ) -{ - setContext( new TQGLContext(format,this) ); -} - - - - -/*! - \fn const TQGLContext *TQGLWidget::context() const - - Returns the context of this widget. - - It is possible that the context is not valid (see isValid()), for - example, if the underlying hardware does not support the format - attributes that were requested. -*/ - -/* - \obsolete - - \fn void TQGLWidget::setContext( TQGLContext *context, - const TQGLContext* shareContext, - bool deleteOldContext ) - - Sets a new context for this widget. The TQGLContext \a context must - be created using \e new. TQGLWidget will delete \a context when - another context is set or when the widget is destroyed. - - If \a context is invalid, TQGLContext::create() is performed on - it. The initializeGL() function will then be executed for the new - context before the first resizeGL() or paintGL(). - - If \a context is invalid, this method will try to keep any existing - display list sharing with other TQGLWidgets this widget currently - has, or (if \a shareContext points to a valid context) start display - list sharing with that context, but it may fail. Use isSharing() to - test. - - If \a deleteOldContext is TRUE (the default), the existing context - will be deleted. You may use FALSE here if you have kept a pointer - to the old context (as returned by context()), and want to restore - that context later. - - \sa context(), isSharing() -*/ - - - -/*! - \fn void TQGLWidget::updateGL() - - Updates the widget by calling glDraw(). -*/ - -void TQGLWidget::updateGL() -{ - glDraw(); -} - - -/*! - \fn void TQGLWidget::updateOverlayGL() - - Updates the widget's overlay (if any). Will cause the virtual - function paintOverlayGL() to be executed. - - The widget's rendering context will become the current context and - initializeGL() will be called if it hasn't already been called. -*/ - - -/*! - This virtual function is called once before the first call to - paintGL() or resizeGL(), and then once whenever the widget has - been assigned a new TQGLContext. Reimplement it in a subclass. - - This function should set up any required OpenGL context rendering - flags, defining display lists, etc. - - There is no need to call makeCurrent() because this has already - been done when this function is called. -*/ - -void TQGLWidget::initializeGL() -{ -} - - -/*! - This virtual function is called whenever the widget needs to be - painted. Reimplement it in a subclass. - - There is no need to call makeCurrent() because this has already - been done when this function is called. -*/ - -void TQGLWidget::paintGL() -{ -} - - -/*! - \fn void TQGLWidget::resizeGL( int width , int height ) - - This virtual function is called whenever the widget has been - resized. The new size is passed in \a width and \a height. - Reimplement it in a subclass. - - There is no need to call makeCurrent() because this has already - been done when this function is called. -*/ - -void TQGLWidget::resizeGL( int, int ) -{ -} - - - -/*! - This virtual function is used in the same manner as initializeGL() - except that it operates on the widget's overlay context instead of - the widget's main context. This means that initializeOverlayGL() - is called once before the first call to paintOverlayGL() or - resizeOverlayGL(). Reimplement it in a subclass. - - This function should set up any required OpenGL context rendering - flags, defining display lists, etc. for the overlay context. - - There is no need to call makeOverlayCurrent() because this has - already been done when this function is called. -*/ - -void TQGLWidget::initializeOverlayGL() -{ -} - - -/*! - This virtual function is used in the same manner as paintGL() - except that it operates on the widget's overlay context instead of - the widget's main context. This means that paintOverlayGL() is - called whenever the widget's overlay needs to be painted. - Reimplement it in a subclass. - - There is no need to call makeOverlayCurrent() because this has - already been done when this function is called. -*/ - -void TQGLWidget::paintOverlayGL() -{ -} - - -/*! - \fn void TQGLWidget::resizeOverlayGL( int width , int height ) - - This virtual function is used in the same manner as paintGL() - except that it operates on the widget's overlay context instead of - the widget's main context. This means that resizeOverlayGL() is - called whenever the widget has been resized. The new size is - passed in \a width and \a height. Reimplement it in a subclass. - - There is no need to call makeOverlayCurrent() because this has - already been done when this function is called. -*/ - -void TQGLWidget::resizeOverlayGL( int, int ) -{ -} - - - - -/*! - Handles paint events. Will cause the virtual paintGL() function to - be called. - - The widget's rendering context will become the current context and - initializeGL() will be called if it hasn't already been called. -*/ - -void TQGLWidget::paintEvent( TQPaintEvent * ) -{ - glDraw(); - updateOverlayGL(); -} - - -/*! - \fn void TQGLWidget::resizeEvent( TQResizeEvent * ) - - Handles resize events. Calls the virtual function resizeGL(). -*/ - - -/*! - \fn void TQGLWidget::setMouseTracking( bool enable ) - - \reimp -*/ - - -/*! - Renders the current scene on a pixmap and returns the pixmap. - - You can use this method on both visible and invisible TQGLWidgets. - - This method will create a pixmap and a temporary TQGLContext to - render on the pixmap. It will then call initializeGL(), - resizeGL(), and paintGL() on this context. Finally, the widget's - original GL context is restored. - - The size of the pixmap will be \a w pixels wide and \a h pixels - high unless one of these parameters is 0 (the default), in which - case the pixmap will have the same size as the widget. - - If \a useContext is TRUE, this method will try to be more - efficient by using the existing GL context to render the pixmap. - The default is FALSE. Only use TRUE if you understand the risks. - - Overlays are not rendered onto the pixmap. - - If the GL rendering context and the desktop have different bit - depths, the result will most likely look surprising. - - Note that the creation of display lists, modifications of the view - frustum etc. should be done from within initializeGL(). If this is - not done, the temporary TQGLContext will not be initialized - properly, and the rendered pixmap may be incomplete/corrupted. -*/ - -TQPixmap TQGLWidget::renderPixmap( int w, int h, bool useContext ) -{ - TQSize sz = size(); - if ( (w > 0) && (h > 0) ) - sz = TQSize( w, h ); - -#if defined(TQ_WS_X11) - TQPixmap pm( sz.width(), sz.height(), x11Depth() ); - bool needConversion = x11Visual() != TQPaintDevice::x11AppVisual(); - - // make sure the pixmap uses the same visual as the widget itself - if ( needConversion ) { - TQPaintDeviceX11Data* xd = pm.getX11Data( TRUE ); - xd->x_depth = x11Depth(); - xd->x_visual = (Visual *) x11Visual(); - pm.setX11Data( xd ); - } -#else - TQPixmap pm; - pm.resize( sz ); -#endif - - glcx->doneCurrent(); - - bool success = TRUE; - - if ( useContext && isValid() && renderCxPm( &pm ) ) - return pm; - - TQGLFormat fmt = glcx->requestedFormat(); - fmt.setDirectRendering( FALSE ); // Direct is unlikely to work - fmt.setDoubleBuffer( FALSE ); // We don't need dbl buf - - TQGLContext* ocx = glcx; - bool wasCurrent = (TQGLContext::currentContext() == ocx ); - ocx->doneCurrent(); - glcx = new TQGLContext( fmt, &pm ); - glcx->create(); - - if ( glcx->isValid() ) - updateGL(); - else - success = FALSE; - - delete glcx; - glcx = ocx; - - if ( wasCurrent ) - ocx->makeCurrent(); - - if ( success ) { -#if defined(TQ_WS_X11) - if ( needConversion ) { - TQImage image = pm.convertToImage(); - TQPixmap p; - p = image; - return p; - } -#endif - return pm; - } else - return TQPixmap(); -} - - - -/*! - Returns an image of the frame buffer. If \a withAlpha is TRUE the - alpha channel is included. - - Depending on your hardware, you can explicitly select which color - buffer to grab with a glReadBuffer() call before calling this - function. -*/ -TQImage TQGLWidget::grabFrameBuffer( bool withAlpha ) -{ -#if defined( TQ_WS_MAC ) - if(dblbuf == macInternalDoubleBuffer(FALSE) && gl_pix) //why not optimize? - return ((TQPixmap*)gl_pix)->convertToImage(); -#endif - makeCurrent(); - TQImage res; - int w = width(); - int h = height(); - if ( format().rgba() ) { - res = TQImage( w, h, 32 ); - glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, res.bits() ); - if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { - // OpenGL gives RGBA; TQt wants ARGB - uint *p = (uint*)res.bits(); - uint *end = p + w*h; - if ( withAlpha && format().alpha() ) { - while ( p < end ) { - uint a = *p << 24; - *p = (*p >> 8) | a; - p++; - } - } - else { - while ( p < end ) - *p++ >>= 8; - } - } - else { - // OpenGL gives ABGR (i.e. RGBA backwards); TQt wants ARGB - res = res.swapRGB(); - } - res.setAlphaBuffer( withAlpha && format().alpha() ); - } - else { -#if defined (TQ_WS_WIN) - res = TQImage( w, h, 8 ); - glReadPixels( 0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, - res.bits() ); - int palSize = 0; - const TQRgb* pal = TQColor::palette( &palSize ); - if ( pal && palSize ) { - res.setNumColors( palSize ); - for ( int i = 0; i < palSize; i++ ) - res.setColor( i, pal[i] ); - } -#endif - } - - return res.mirror(); -} - - - -/*! - Initializes OpenGL for this widget's context. Calls the virtual - function initializeGL(). -*/ - -void TQGLWidget::glInit() -{ - if ( !isValid() ) - return; - makeCurrent(); - initializeGL(); - glcx->setInitialized( TRUE ); -} - - -/*! - Executes the virtual function paintGL(). - - The widget's rendering context will become the current context and - initializeGL() will be called if it hasn't already been called. -*/ - -void TQGLWidget::glDraw() -{ - if ( !isValid() ) - return; - makeCurrent(); - if ( glcx->deviceIsPixmap() ) - glDrawBuffer( GL_FRONT ); - if ( !glcx->initialized() ) { - glInit(); - TQPaintDeviceMetrics dm( glcx->device() ); - resizeGL( dm.width(), dm.height() ); // New context needs this "resize" - } - paintGL(); - if ( doubleBuffer() ) { - if ( autoSwap ) - swapBuffers(); - } else { - glFlush(); -#if defined( TQ_WS_MAC ) - if(dblbuf && gl_pix) - bitBlt(this, 0, 0, gl_pix); -#endif - } -} - - -/*! - Convenience function for specifying a drawing color to OpenGL. - Calls glColor3 (in RGBA mode) or glIndex (in color-index mode) - with the color \a c. Applies to the current GL context. - - \sa qglClearColor(), TQGLContext::currentContext(), TQColor -*/ - -void TQGLWidget::qglColor( const TQColor& c ) const -{ - const TQGLContext* ctx = TQGLContext::currentContext(); - if ( ctx ) { - if ( ctx->format().rgba() ) - glColor3ub( c.red(), c.green(), c.blue() ); - - else if ( ctx->device() == context()->device() - && !cmap.isEmpty() ) { // TQGLColormap in use? - int i = cmap.find( c.rgb() ); - if ( i < 0 ) - i = cmap.findNearest( c.rgb() ); - glIndexi( i ); - } else - glIndexi( ctx->colorIndex( c ) ); - } -} - -/*! - Convenience function for specifying the clearing color to OpenGL. - Calls glClearColor (in RGBA mode) or glClearIndex (in color-index - mode) with the color \a c. Applies to the current GL context. - - \sa qglColor(), TQGLContext::currentContext(), TQColor -*/ - -void TQGLWidget::qglClearColor( const TQColor& c ) const -{ - const TQGLContext* ctx = TQGLContext::currentContext(); - if ( ctx ) { - if ( ctx->format().rgba() ) - glClearColor( (GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0, - (GLfloat)c.blue() / 255.0, (GLfloat) 0.0 ); - else if ( ctx->device() == context()->device() - && !cmap.isEmpty() ) { // TQGLColormap in use? - int i = cmap.find( c.rgb() ); - if ( i < 0 ) - i = cmap.findNearest( c.rgb() ); - glClearIndex( i ); - } else - glClearIndex( ctx->colorIndex( c ) ); - } -} - - -/*! - Converts the image \a img into the unnamed format expected by - OpenGL functions such as glTexImage2D(). The returned image is not - usable as a TQImage, but TQImage::width(), TQImage::height() and - TQImage::bits() may be used with OpenGL. The following few lines - are from the texture example. Most of the code is irrelevant, so - we just quote the relevant bits: - - \quotefile opengl/texture/gltexobj.cpp - \skipto tex1 - \printline tex1 - \printline gllogo.bmp - - We create \e tex1 (and another variable) for OpenGL, and load a real - image into \e buf. - - \skipto convertToGLFormat - \printline convertToGLFormat - - A few lines later, we convert \e buf into OpenGL format and store it - in \e tex1. - - \skipto glTexImage2D - \printline glTexImage2D - \printline tex1.bits - - Note the dimension restrictions for texture images as described in - the glTexImage2D() documentation. The width must be 2^m + 2*border - and the height 2^n + 2*border where m and n are integers and - border is either 0 or 1. - - Another function in the same example uses \e tex1 with OpenGL. -*/ - - -TQImage TQGLWidget::convertToGLFormat( const TQImage& img ) -{ - TQImage res = img.convertDepth( 32 ); - res = res.mirror(); - - if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { - // TQt has ARGB; OpenGL wants RGBA - for ( int i=0; i < res.height(); i++ ) { - uint *p = (uint*)res.scanLine( i ); - uint *end = p + res.width(); - while ( p < end ) { - *p = (*p << 8) | ((*p >> 24) & 0xFF); - p++; - } - } - } - else { - // TQt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards) - res = res.swapRGB(); - } - return res; -} - - -/*! - \fn TQGLColormap & TQGLWidget::colormap() const - - Returns the colormap for this widget. - - Usually it is only top-level widgets that can have different - colormaps installed. Asking for the colormap of a child widget - will return the colormap for the child's top-level widget. - - If no colormap has been set for this widget, the TQColormap - returned will be empty. - - \sa setColormap() -*/ - -/*! - \fn void TQGLWidget::setColormap( const TQGLColormap & cmap ) - - Set the colormap for this widget to \a cmap. Usually it is only - top-level widgets that can have colormaps installed. - - \sa colormap() -*/ - -int TQGLWidget::displayListBase( const TQFont & fnt, int listBase ) -{ - int base; - - TQGLWidgetPrivate * d = qgl_d( this ); - if ( !d || !glcx ) { // this can't happen unless we run out of mem - return 0; - } - - // always regenerate font disp. lists for pixmaps - hw accelerated - // contexts can't handle this otherwise - bool regenerate = glcx->deviceIsPixmap(); - -#if 0 // TQT_NO_XFTFREETYPE - // font color needs to be part of the font cache key when using - // antialiased fonts since one set of glyphs needs to be generated - // for each font color - TQString color_key; - if (fnt.styleStrategy() != TQFont::NoAntialias) { - GLfloat color[4]; - glGetFloatv(GL_CURRENT_COLOR, color); - color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]); - } - TQString key = fnt.key() + color_key + TQString::number((int) regenerate); -#else - TQString key = fnt.key() + TQString::number((int) regenerate); -#endif - - if ( !regenerate && (d->displayListCache.find( key ) != d->displayListCache.end()) ) { - base = d->displayListCache[ key ]; - } else { - int maxBase = listBase - 256; - TQMapConstIterator it; - for ( it = d->displayListCache.begin(); it != d->displayListCache.end(); ++it ) { - if ( maxBase < it.data() ) { - maxBase = it.data(); - } - } - maxBase += 256; - glcx->generateFontDisplayLists( fnt, maxBase ); - d->displayListCache[ key ] = maxBase; - base = maxBase; - } - return base; -} - -/*! - Renders the string \a str into the GL context of this widget. - - \a x and \a y are specified in window coordinates, with the origin - in the upper left-hand corner of the window. If \a fnt is not - specified, the currently set application font will be used to - render the string. To change the color of the rendered text you can - use the glColor() call (or the qglColor() convenience function), - just before the renderText() call. Note that if you have - GL_LIGHTING enabled, the string will not appear in the color you - want. You should therefore switch lighting off before using - renderText(). - - \a listBase specifies the index of the first display list that is - generated by this function. The default value is 2000. 256 display - lists will be generated, one for each of the first 256 characters - in the font that is used to render the string. If several fonts are - used in the same widget, the display lists for these fonts will - follow the last generated list. You would normally not have to - change this value unless you are using lists in the same range. The - lists are deleted when the widget is destroyed. - - Note: This function only works reliably with ASCII strings. -*/ - -void TQGLWidget::renderText( int x, int y, const TQString & str, const TQFont & fnt, int listBase ) -{ - if (str.isEmpty()) - return; - makeCurrent(); - glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT | GL_CURRENT_BIT ); - glMatrixMode( GL_PROJECTION ); - glPushMatrix(); - glLoadIdentity(); - glOrtho( 0, width(), height(), 0, -1, 1 ); - glMatrixMode( GL_MODELVIEW ); - glPushMatrix(); - glLoadIdentity(); - - glRasterPos2i( 0, 0 ); - glBitmap(0, 0, 0, 0, x, -y, NULL); - glListBase( displayListBase( fnt, listBase ) ); - const char *cstr = str.latin1(); - glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr ); - - // restore the matrix stacks and GL state - glPopMatrix(); - glMatrixMode( GL_PROJECTION ); - glPopMatrix(); - glPopAttrib(); -} - -/*! \overload - - \a x, \a y and \a z are specified in scene or object coordinates - relative to the currently set projection and model matrices. This - can be useful if you want to annotate models with text labels and - have the labels move with the model as it is rotated etc. -*/ -void TQGLWidget::renderText( double x, double y, double z, const TQString & str, const TQFont & fnt, - int listBase ) -{ - if (str.isEmpty()) - return; - makeCurrent(); - glRasterPos3d( x, y, z ); - glPushAttrib( GL_LIST_BIT ); - glListBase( displayListBase( fnt, listBase ) ); - const char *cstr = str.latin1(); - glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr ); - glPopAttrib(); -} - -/***************************************************************************** - TQGL classes overview documentation. - *****************************************************************************/ - -/*! - -\page opengl.html - -\title TQt OpenGL 3D Graphics - -\if defined(commercial) -This module is part of the \link commercialeditions.html TQt Enterprise -Edition\endlink. -\endif - -\section1 Introduction - -OpenGL is a standard API for rendering 3D graphics. - -OpenGL only deals with 3D rendering and provides little or no support -for GUI programming issues. The user interface for an -OpenGL* application must be created with another toolkit, -such as Motif on the X platform, Microsoft Foundation Classes (MFC) -under Windows, or TQt on \e both platforms. - -The TQt OpenGL module makes it easy to use OpenGL in TQt applications. -It provides an OpenGL widget class that can be used just like any -other TQt widget, except that it opens an OpenGL display buffer where -you can use the OpenGL API to render the contents. - -The TQt OpenGL module is implemented as a platform-independent TQt/C++ -wrapper around the platform-dependent GLX, WGL, or AGL C APIs. The -functionality provided is very similar to Mark Kilgard's GLUT library, -but with much more non-OpenGL-specific GUI functionality, i.e. the -whole TQt API. - -\section1 Installation - -When you install TQt for X11, the configure script will autodetect if -OpenGL headers and libraries are installed on your system, and if so, -it will include the TQt OpenGL module in the TQt library. (If your -OpenGL headers or libraries are placed in a non-standard directory, -you may need to change the QMAKE_INCDIR_OPENGL and/or -QMAKE_LIBDIR_OPENGL in the config file for your system). Some -configurations require threading to be enabled for OpenGL, so if -OpenGL is not detected, try \c{configure -thread}. - -When you install TQt for Windows, the TQt OpenGL module is always -included. - -The TQt OpenGL module is not licensed for use with the TQt Professional -Edition. Consider upgrading to the TQt Enterprise Edition if you -require OpenGL support. - -Note about using Mesa on X11: Mesa versions earlier than 3.1 would use -the name "MesaGL" and "MesaGLU" for the libraries, instead of "GL" and -"GLU". If you want to use a pre-3.1 version of Mesa, you must change -the Makefiles to use these library names instead. The easiest way to -do this is to edit the QMAKE_LIBS_OPENGL line in the config file you -are using, changing "-lGL -lGLU" to "-lMesaGL -lMesaGLU"; then run -"configure" again. - -\section1 The TQGL Classes - -The OpenGL support classes in TQt are: -\list -\i \link TQGLWidget TQGLWidget\endlink: An easy-to-use TQt - widget for rendering OpenGL scenes. -\i \link TQGLContext TQGLContext\endlink: Encapsulates an OpenGL rendering context. -\i \link TQGLFormat TQGLFormat\endlink: Specifies the -display format of a rendering context. -\i \link TQGLColormap TQGLColormap\endlink: Handles indexed -colormaps in GL-index mode. -\endlist - -Many applications only need the high-level TQGLWidget class. The other -TQGL classes provide advanced features. X11 users might like to read -the notes on \link opengl-x11-overlays.html overlays\endlink. - -See also the \link opengl-examples.html OpenGL examples\endlink. - -The TQGL documentation assumes that you are familiar with OpenGL -programming. If you're new to the subject a good starting point is -\l{http://www.opengl.org/}. - - -* OpenGL is a trademark of Silicon Graphics, Inc. in the -United States and other countries. - -*/ - -/*! - \enum TQGL::FormatOption - - This enum specifies the format options. - - \value DoubleBuffer - \value DepthBuffer - \value Rgba - \value AlphaChannel - \value AccumBuffer - \value StencilBuffer - \value StereoBuffers - \value DirectRendering - \value HasOverlay - \value SingleBuffer - \value NoDepthBuffer - \value ColorIndex - \value NoAlphaChannel - \value NoAccumBuffer - \value NoStencilBuffer - \value NoStereoBuffers - \value IndirectRendering - \value NoOverlay -*/ diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp deleted file mode 100644 index 938228346..000000000 --- a/src/opengl/qgl_x11.cpp +++ /dev/null @@ -1,1406 +0,0 @@ -/**************************************************************************** -** -** Implementation of OpenGL classes for TQt -** -** Created : 970112 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the opengl 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 "ntqgl.h" - -#if defined(TQ_WS_X11) - -#include "tqmap.h" -#include "ntqpixmap.h" -#include "ntqapplication.h" - -#include "tqintdict.h" -#include "private/tqfontengine_p.h" - -#define INT8 dummy_INT8 -#define INT32 dummy_INT32 -#include -#undef INT8 -#undef INT32 -#include -#include -#include -#include - -// POSIX Large File Support redefines truncate -> truncate64 -#if defined(truncate) -# undef truncate -#endif - -#ifndef QT_DLOPEN_OPENGL -extern "C" { - Status XmuLookupStandardColormap( Display *dpy, int screen, VisualID visualid, - unsigned int depth, Atom property, - Bool replace, Bool retain ); -} -#endif - -#include "qgl_x11_p.h" -#ifdef QT_DLOPEN_OPENGL -#include "ntqlibrary.h" - -extern "C" { -_glCallLists qt_glCallLists; -_glClearColor qt_glClearColor; -_glClearIndex qt_glClearIndex; -_glColor3ub qt_glColor3ub; -_glDeleteLists qt_glDeleteLists; -_glDrawBuffer qt_glDrawBuffer; -_glFlush qt_glFlush; -_glIndexi qt_glIndexi; -_glListBase qt_glListBase; -_glLoadIdentity qt_glLoadIdentity; -_glMatrixMode qt_glMatrixMode; -_glOrtho qt_glOrtho; -_glPopAttrib qt_glPopAttrib; -_glPopMatrix qt_glPopMatrix; -_glPushAttrib qt_glPushAttrib; -_glPushMatrix qt_glPushMatrix; -_glRasterPos2i qt_glRasterPos2i; -_glRasterPos3d qt_glRasterPos3d; -_glReadPixels qt_glReadPixels; -_glViewport qt_glViewport; -_glPixelStorei qt_glPixelStorei; -_glBitmap qt_glBitmap; -_glDrawPixels qt_glDrawPixels; -_glNewList qt_glNewList; -_glGetFloatv qt_glGetFloatv; -_glGetIntegerv qt_glGetIntegerv; -_glEndList qt_glEndList; - -_glXChooseVisual qt_glXChooseVisual; -_glXCreateContext qt_glXCreateContext; -_glXCreateGLXPixmap qt_glXCreateGLXPixmap; -_glXDestroyContext qt_glXDestroyContext; -_glXDestroyGLXPixmap qt_glXDestroyGLXPixmap; -_glXGetClientString qt_glXGetClientString; -_glXGetConfig qt_glXGetConfig; -_glXIsDirect qt_glXIsDirect; -_glXMakeCurrent qt_glXMakeCurrent; -_glXQueryExtension qt_glXQueryExtension; -_glXQueryExtensionsString qt_glXQueryExtensionsString; -_glXQueryServerString qt_glXQueryServerString; -_glXSwapBuffers qt_glXSwapBuffers; -_glXUseXFont qt_glXUseXFont; -_glXWaitX qt_glXWaitX; -}; - -bool qt_resolve_gl_symbols(bool fatal) -{ - static bool gl_syms_resolved = FALSE; - if (gl_syms_resolved) - return TRUE; - - TQLibrary gl("GL.so.1"); - gl.setAutoUnload(FALSE); - - qt_glCallLists = (_glCallLists) gl.resolve("glCallLists"); - - if (!qt_glCallLists) { // if this fails the rest will surely fail - if (fatal) - tqFatal("Unable to resolve GL/GLX symbols - please check your GL library installation."); - return FALSE; - } - - qt_glClearColor = (_glClearColor) gl.resolve("glClearColor"); - qt_glClearIndex = (_glClearIndex) gl.resolve("glClearIndex"); - qt_glColor3ub = (_glColor3ub) gl.resolve("glColor3ub"); - qt_glDeleteLists = (_glDeleteLists) gl.resolve("glDeleteLists"); - qt_glDrawBuffer = (_glDrawBuffer) gl.resolve("glDrawBuffer"); - qt_glFlush = (_glFlush) gl.resolve("glFlush"); - qt_glIndexi = (_glIndexi) gl.resolve("glIndexi"); - qt_glListBase = (_glListBase) gl.resolve("glListBase"); - qt_glLoadIdentity = (_glLoadIdentity) gl.resolve("glLoadIdentity"); - qt_glMatrixMode = (_glMatrixMode) gl.resolve("glMatrixMode"); - qt_glOrtho = (_glOrtho) gl.resolve("glOrtho"); - qt_glPopAttrib = (_glPopAttrib) gl.resolve("glPopAttrib"); - qt_glPopMatrix = (_glPopMatrix) gl.resolve("glPopMatrix"); - qt_glPushAttrib = (_glPushAttrib) gl.resolve("glPushAttrib"); - qt_glPushMatrix = (_glPushMatrix) gl.resolve("glPushMatrix"); - qt_glRasterPos2i = (_glRasterPos2i) gl.resolve("glRasterPos2i"); - qt_glRasterPos3d = (_glRasterPos3d) gl.resolve("glRasterPos3d"); - qt_glReadPixels = (_glReadPixels) gl.resolve("glReadPixels"); - qt_glViewport = (_glViewport) gl.resolve("glViewport"); - qt_glPixelStorei = (_glPixelStorei) gl.resolve("glPixelStorei"); - qt_glBitmap = (_glBitmap) gl.resolve("glBitmap"); - qt_glDrawPixels = (_glDrawPixels) gl.resolve("glDrawPixels"); - qt_glNewList = (_glNewList) gl.resolve("glNewList"); - qt_glGetFloatv = (_glGetFloatv) gl.resolve("glGetFloatv"); - qt_glGetIntegerv = (_glGetIntegerv) gl.resolve("glGetIntegerv"); - qt_glEndList = (_glEndList) gl.resolve("glEndList"); - - qt_glXChooseVisual = (_glXChooseVisual) gl.resolve("glXChooseVisual"); - qt_glXCreateContext = (_glXCreateContext) gl.resolve("glXCreateContext"); - qt_glXCreateGLXPixmap = (_glXCreateGLXPixmap) gl.resolve("glXCreateGLXPixmap"); - qt_glXDestroyContext = (_glXDestroyContext) gl.resolve("glXDestroyContext"); - qt_glXDestroyGLXPixmap = (_glXDestroyGLXPixmap) gl.resolve("glXDestroyGLXPixmap"); - qt_glXGetClientString = (_glXGetClientString) gl.resolve("glXGetClientString"); - qt_glXGetConfig = (_glXGetConfig) gl.resolve("glXGetConfig"); - qt_glXIsDirect = (_glXIsDirect) gl.resolve("glXIsDirect"); - qt_glXMakeCurrent = (_glXMakeCurrent) gl.resolve("glXMakeCurrent"); - qt_glXQueryExtension = (_glXQueryExtension) gl.resolve("glXQueryExtension"); - qt_glXQueryExtensionsString = (_glXQueryExtensionsString) gl.resolve("glXQueryExtensionsString"); - qt_glXQueryServerString = (_glXQueryServerString) gl.resolve("glXQueryServerString"); - qt_glXSwapBuffers = (_glXSwapBuffers) gl.resolve("glXSwapBuffers"); - qt_glXUseXFont = (_glXUseXFont) gl.resolve("glXUseXFont"); - qt_glXWaitX = (_glXWaitX) gl.resolve("glXWaitX"); - gl_syms_resolved = TRUE; - return TRUE; -} -#endif // QT_DLOPEN_OPENGL - - -/* - The choose_cmap function is internal and used by TQGLWidget::setContext() - and GLX (not Windows). If the application can't find any sharable - colormaps, it must at least create as few colormaps as possible. The - dictionary solution below ensures only one colormap is created per visual. - Colormaps are also deleted when the application terminates. -*/ - -struct CMapEntry { - CMapEntry(); - ~CMapEntry(); - Colormap cmap; - bool alloc; - XStandardColormap scmap; -}; - -CMapEntry::CMapEntry() -{ - cmap = 0; - alloc = FALSE; - scmap.colormap = 0; -} - -CMapEntry::~CMapEntry() -{ - if ( alloc ) - XFreeColormap( TQPaintDevice::x11AppDisplay(), cmap ); -} - -static TQIntDict *cmap_dict = 0; -static bool mesa_gl = FALSE; -static TQIntDict< TQMap > *qglcmap_dict = 0; - -static void cleanup_cmaps() -{ - if (cmap_dict) { - cmap_dict->setAutoDelete(TRUE); - delete cmap_dict; - cmap_dict = 0; - } - if (qglcmap_dict) { - qglcmap_dict->setAutoDelete(TRUE); - delete qglcmap_dict; - qglcmap_dict = 0; - } -} - -static Colormap choose_cmap( Display *dpy, XVisualInfo *vi ) -{ - if ( !cmap_dict ) { - cmap_dict = new TQIntDict; - const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION ); - if ( v ) - mesa_gl = strstr(v,"Mesa") != 0; - tqAddPostRoutine( cleanup_cmaps ); - } - - CMapEntry *x = cmap_dict->find( (long) vi->visualid + ( vi->screen * 256 ) ); - if ( x ) // found colormap for visual - return x->cmap; - - x = new CMapEntry(); - - XStandardColormap *c; - int n, i; - - // tqDebug( "Choosing cmap for vID %0x", vi->visualid ); - - if ( vi->visualid == - XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( vi->screen ) ) ) { - // tqDebug( "Using x11AppColormap" ); - return TQPaintDevice::x11AppColormap( vi->screen ); - } - - if ( mesa_gl ) { // we're using MesaGL - Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", TRUE ); - if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 ) { - if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n, - hp_cmaps) ) { - i = 0; - while ( i < n && x->cmap == 0 ) { - if ( c[i].visualid == vi->visual->visualid ) { - x->cmap = c[i].colormap; - x->scmap = c[i]; - //tqDebug( "Using HP_RGB scmap" ); - - } - i++; - } - XFree( (char *)c ); - } - } - } -#if !defined(Q_OS_SOLARIS) - if ( !x->cmap ) { -#ifdef QT_DLOPEN_OPENGL - typedef Status (*_XmuLookupStandardColormap)( Display *dpy, int screen, VisualID visualid, unsigned int depth, - Atom property, Bool replace, Bool retain ); - _XmuLookupStandardColormap qt_XmuLookupStandardColormap; - qt_XmuLookupStandardColormap = (_XmuLookupStandardColormap) TQLibrary::resolve("Xmu.so.6", "XmuLookupStandardColormap"); - if (!qt_XmuLookupStandardColormap) - tqFatal("Unable to resolve Xmu symbols - please check your Xmu library installation."); -#define XmuLookupStandardColormap qt_XmuLookupStandardColormap - -#endif - - if ( XmuLookupStandardColormap(dpy,vi->screen,vi->visualid,vi->depth, - XA_RGB_DEFAULT_MAP,FALSE,TRUE) ) { - if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n, - XA_RGB_DEFAULT_MAP) ) { - i = 0; - while ( i < n && x->cmap == 0 ) { - if ( c[i].visualid == vi->visualid ) { - x->cmap = c[i].colormap; - x->scmap = c[i]; - //tqDebug( "Using RGB_DEFAULT scmap" ); - } - i++; - } - XFree( (char *)c ); - } - } - } -#endif - if ( !x->cmap ) { // no shared cmap found - x->cmap = XCreateColormap( dpy, RootWindow(dpy,vi->screen), vi->visual, - AllocNone ); - x->alloc = TRUE; - // tqDebug( "Allocating cmap" ); - } - - // associate cmap with visualid - cmap_dict->insert( (long) vi->visualid + ( vi->screen * 256 ), x ); - return x->cmap; -} - -struct TransColor -{ - VisualID vis; - int screen; - long color; -}; - -static TQMemArray trans_colors; -static int trans_colors_init = FALSE; - - -static void find_trans_colors() -{ - struct OverlayProp { - long visual; - long type; - long value; - long layer; - }; - - trans_colors_init = TRUE; - - Display* appDisplay = TQPaintDevice::x11AppDisplay(); - - int scr; - int lastsize = 0; - for ( scr = 0; scr < ScreenCount( appDisplay ); scr++ ) { - TQWidget* rootWin = TQApplication::desktop()->screen( scr ); - if ( !rootWin ) - return; // Should not happen - Atom overlayVisualsAtom = XInternAtom( appDisplay, - "SERVER_OVERLAY_VISUALS", True ); - if ( overlayVisualsAtom == None ) - return; // Server has no overlays - - Atom actualType; - int actualFormat; - ulong nItems; - ulong bytesAfter; - OverlayProp* overlayProps = 0; - int res = XGetWindowProperty( appDisplay, rootWin->winId(), - overlayVisualsAtom, 0, 10000, False, - overlayVisualsAtom, &actualType, - &actualFormat, &nItems, &bytesAfter, - (uchar**)&overlayProps ); - - if ( res != Success || actualType != overlayVisualsAtom - || actualFormat != 32 || nItems < 4 || !overlayProps ) - return; // Error reading property - - int numProps = nItems / 4; - trans_colors.resize( lastsize + numProps ); - int j = lastsize; - for ( int i = 0; i < numProps; i++ ) { - if ( overlayProps[i].type == 1 ) { - trans_colors[j].vis = (VisualID)overlayProps[i].visual; - trans_colors[j].screen = scr; - trans_colors[j].color = (int)overlayProps[i].value; - j++; - } - } - XFree( overlayProps ); - lastsize = j; - trans_colors.truncate( lastsize ); - } -} - - -/***************************************************************************** - TQGLFormat UNIX/GLX-specific code - *****************************************************************************/ - -bool TQGLFormat::hasOpenGL() -{ - if (!qt_resolve_gl_symbols(FALSE)) - return FALSE; - return glXQueryExtension(tqt_xdisplay(),0,0) != 0; -} - - -bool TQGLFormat::hasOpenGLOverlays() -{ - qt_resolve_gl_symbols(); - if ( !trans_colors_init ) - find_trans_colors(); - return trans_colors.size() > 0; -} - - - -/***************************************************************************** - TQGLContext UNIX/GLX-specific code - *****************************************************************************/ - -bool TQGLContext::chooseContext( const TQGLContext* shareContext ) -{ - Display* disp = d->paintDevice->x11Display(); - vi = chooseVisual(); - if ( !vi ) - return FALSE; - - if ( deviceIsPixmap() && - (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() || - ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) ) - { - XFree( vi ); - XVisualInfo appVisInfo; - memset( &appVisInfo, 0, sizeof(XVisualInfo) ); - appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() ); - appVisInfo.screen = d->paintDevice->x11Screen(); - int nvis; - vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis ); - if ( !vi ) - return FALSE; - - int useGL; - glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL ); - if ( !useGL ) - return FALSE; //# Chickening out already... - } - int res; - glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res ); - glFormat.setPlane( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res ); - glFormat.setDoubleBuffer( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res ); - glFormat.setDepth( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res ); - glFormat.setRgba( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res ); - glFormat.setAlpha( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res ); - glFormat.setAccum( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res ); - glFormat.setStencil( res ); - glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res ); - glFormat.setStereo( res ); - - Bool direct = format().directRendering() ? True : False; - - if ( shareContext && - ( !shareContext->isValid() || !shareContext->cx ) ) { -#if defined(QT_CHECK_NULL) - tqWarning("TQGLContext::chooseContext(): Cannot share with invalid context"); -#endif - shareContext = 0; - } - - // 1. Sharing between rgba and color-index will give wrong colors. - // 2. Contexts cannot be shared btw. direct/non-direct renderers. - // 3. Pixmaps cannot share contexts that are set up for direct rendering. - if ( shareContext && (format().rgba() != shareContext->format().rgba() || - (deviceIsPixmap() && - glXIsDirect( disp, (GLXContext)shareContext->cx )))) - shareContext = 0; - - cx = 0; - if ( shareContext ) { - cx = glXCreateContext( disp, (XVisualInfo *)vi, - (GLXContext)shareContext->cx, direct ); - if ( cx ) - d->sharing = TRUE; - } - if ( !cx ) - cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct ); - if ( !cx ) - return FALSE; - glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) ); - if ( deviceIsPixmap() ) { -#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT) - gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi, - d->paintDevice->handle(), - choose_cmap( disp, (XVisualInfo *)vi ) ); -#else - gpm = (TQ_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi, - d->paintDevice->handle() ); -#endif - if ( !gpm ) - return FALSE; - } - return TRUE; -} - - -/*! - X11 only: This virtual function tries to find a - visual that matches the format, reducing the demands if the original - request cannot be met. - - The algorithm for reducing the demands of the format is quite - simple-minded, so override this method in your subclass if your - application has spcific requirements on visual selection. - - \sa chooseContext() -*/ - -void *TQGLContext::chooseVisual() -{ - static int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also? - //todo: if pixmap, also make sure that vi->depth == pixmap->depth - void* vis = 0; - int i = 0; - bool fail = FALSE; - TQGLFormat fmt = format(); - bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double - bool triedDouble = FALSE; - while( !fail && !( vis = tryVisual( fmt, bufDepths[i] ) ) ) { - if ( !fmt.rgba() && bufDepths[i] > 1 ) { - i++; - continue; - } - if ( tryDouble ) { - fmt.setDoubleBuffer( TRUE ); - tryDouble = FALSE; - triedDouble = TRUE; - continue; - } - else if ( triedDouble ) { - fmt.setDoubleBuffer( FALSE ); - triedDouble = FALSE; - } - if ( fmt.stereo() ) { - fmt.setStereo( FALSE ); - continue; - } - if ( fmt.accum() ) { - fmt.setAccum( FALSE ); - continue; - } - if ( fmt.stencil() ) { - fmt.setStencil( FALSE ); - continue; - } - if ( fmt.alpha() ) { - fmt.setAlpha( FALSE ); - continue; - } - if ( fmt.depth() ) { - fmt.setDepth( FALSE ); - continue; - } - if ( fmt.doubleBuffer() ) { - fmt.setDoubleBuffer( FALSE ); - continue; - } - fail = TRUE; - } - glFormat = fmt; - return vis; -} - - -/*! - - \internal - - X11 only: This virtual function chooses a visual - that matches the OpenGL \link format() format\endlink. Reimplement this - function in a subclass if you need a custom visual. - - \sa chooseContext() -*/ - -void *TQGLContext::tryVisual( const TQGLFormat& f, int bufDepth ) -{ - int spec[40]; - int i = 0; - spec[i++] = GLX_LEVEL; - spec[i++] = f.plane(); - -#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) - static bool useTranspExt = FALSE; - static bool useTranspExtChecked = FALSE; - if ( f.plane() && !useTranspExtChecked && d->paintDevice ) { - TQCString estr( glXQueryExtensionsString( d->paintDevice->x11Display(), - d->paintDevice->x11Screen() ) ); - useTranspExt = estr.contains( "GLX_EXT_visual_info" ); - //# (A bit simplistic; that could theoretically be a substring) - if ( useTranspExt ) { - TQCString cstr( glXGetClientString( d->paintDevice->x11Display(), - GLX_VENDOR ) ); - useTranspExt = !cstr.contains( "Xi Graphics" ); // bug workaround - if ( useTranspExt ) { - // bug workaround - some systems (eg. FireGL) refuses to return an overlay - // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specfied, even if - // the implementation supports transparent overlays - int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, - f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, - None }; - XVisualInfo * vinf = glXChooseVisual( d->paintDevice->x11Display(), - d->paintDevice->x11Screen(), tmpSpec ); - if ( !vinf ) { - useTranspExt = FALSE; - } - } - } - - useTranspExtChecked = TRUE; - } - if ( f.plane() && useTranspExt ) { - // Required to avoid non-transparent overlay visual(!) on some systems - spec[i++] = GLX_TRANSPARENT_TYPE_EXT; - spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; - } -#endif - - if ( f.doubleBuffer() ) - spec[i++] = GLX_DOUBLEBUFFER; - if ( f.depth() ) { - spec[i++] = GLX_DEPTH_SIZE; - spec[i++] = 1; - } - if ( f.stereo() ) { - spec[i++] = GLX_STEREO; - } - if ( f.stencil() ) { - spec[i++] = GLX_STENCIL_SIZE; - spec[i++] = 1; - } - if ( f.rgba() ) { - spec[i++] = GLX_RGBA; - spec[i++] = GLX_RED_SIZE; - spec[i++] = 1; - spec[i++] = GLX_GREEN_SIZE; - spec[i++] = 1; - spec[i++] = GLX_BLUE_SIZE; - spec[i++] = 1; - if ( f.alpha() ) { - spec[i++] = GLX_ALPHA_SIZE; - spec[i++] = 1; - } - if ( f.accum() ) { - spec[i++] = GLX_ACCUM_RED_SIZE; - spec[i++] = 1; - spec[i++] = GLX_ACCUM_GREEN_SIZE; - spec[i++] = 1; - spec[i++] = GLX_ACCUM_BLUE_SIZE; - spec[i++] = 1; - if ( f.alpha() ) { - spec[i++] = GLX_ACCUM_ALPHA_SIZE; - spec[i++] = 1; - } - } - } - else { - spec[i++] = GLX_BUFFER_SIZE; - spec[i++] = bufDepth; - } - - spec[i] = None; - return glXChooseVisual( d->paintDevice->x11Display(), - d->paintDevice->x11Screen(), spec ); -} - - -void TQGLContext::reset() -{ - if ( !d->valid ) - return; - doneCurrent(); - if ( gpm ) - glXDestroyGLXPixmap( d->paintDevice->x11Display(), (GLXPixmap)gpm ); - gpm = 0; - glXDestroyContext( d->paintDevice->x11Display(), (GLXContext)cx ); - if ( vi ) - XFree( vi ); - vi = 0; - cx = 0; - d->crWin = FALSE; - d->sharing = FALSE; - d->valid = FALSE; - d->transpColor = TQColor(); - d->initDone = FALSE; -} - - -void TQGLContext::makeCurrent() -{ - if ( !d->valid ) { -#if defined(QT_CHECK_STATE) - tqWarning("TQGLContext::makeCurrent(): Cannot make invalid context current."); -#endif - return; - } - bool ok = TRUE; - if ( deviceIsPixmap() ) - ok = glXMakeCurrent( d->paintDevice->x11Display(), - (GLXPixmap)gpm, - (GLXContext)cx ); - - else - ok = glXMakeCurrent( d->paintDevice->x11Display(), - ((TQWidget *)d->paintDevice)->winId(), - (GLXContext)cx ); -#if defined(QT_CHECK_NULL) - // tqDebug("makeCurrent: %i, vi=%i, vi->vi=%i, vi->id=%i", (int)this, (int)vi, (int)((XVisualInfo*)vi)->visual, (int)((XVisualInfo*)vi)->visualid ); - if ( !ok ) - tqWarning("TQGLContext::makeCurrent(): Failed."); -#endif - if ( ok ) - currentCtx = this; -} - -void TQGLContext::doneCurrent() -{ - glXMakeCurrent( d->paintDevice->x11Display(), 0, 0 ); - currentCtx = 0; -} - - -void TQGLContext::swapBuffers() const -{ - if ( !d->valid ) - return; - if ( !deviceIsPixmap() ) - glXSwapBuffers( d->paintDevice->x11Display(), - ((TQWidget *)d->paintDevice)->winId() ); -} - -TQColor TQGLContext::overlayTransparentColor() const -{ - //### make more efficient using the transpColor member - if ( isValid() ) { - if ( !trans_colors_init ) - find_trans_colors(); - - VisualID myVisualId = ((XVisualInfo*)vi)->visualid; - int myScreen = ((XVisualInfo*)vi)->screen; - for ( int i = 0; i < (int)trans_colors.size(); i++ ) { - if ( trans_colors[i].vis == myVisualId && - trans_colors[i].screen == myScreen ) { - XColor col; - col.pixel = trans_colors[i].color; - col.red = col.green = col.blue = 0; - col.flags = 0; - Display *dpy = d->paintDevice->x11Display(); - if (col.pixel > (uint) ((XVisualInfo *)vi)->colormap_size - 1) - col.pixel = ((XVisualInfo *)vi)->colormap_size - 1; - XQueryColor(dpy, choose_cmap(dpy, (XVisualInfo *) vi), &col); - uchar r = (uchar)((col.red / 65535.0) * 255.0 + 0.5); - uchar g = (uchar)((col.green / 65535.0) * 255.0 + 0.5); - uchar b = (uchar)((col.blue / 65535.0) * 255.0 + 0.5); - return TQColor(tqRgb(r,g,b), trans_colors[i].color); - } - } - } - return TQColor(); // Invalid color -} - - -uint TQGLContext::colorIndex( const TQColor& c ) const -{ - int screen = ((XVisualInfo *)vi)->screen; - if ( isValid() ) { - if ( format().plane() - && c.pixel( screen ) == overlayTransparentColor().pixel( screen ) ) - return c.pixel( screen ); // Special; don't look-up - if ( ((XVisualInfo*)vi)->visualid == - XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( screen ) ) ) - return c.pixel( screen ); // We're using TQColor's cmap - - XVisualInfo *info = (XVisualInfo *) vi; - CMapEntry *x = cmap_dict->find( (long) info->visualid + ( info->screen * 256 ) ); - if ( x && !x->alloc) { // It's a standard colormap - int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0); - int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0); - int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0); - uint p = x->scmap.base_pixel - + ( rf * x->scmap.red_mult ) - + ( gf * x->scmap.green_mult ) - + ( bf * x->scmap.blue_mult ); - return p; - } else { - if (!qglcmap_dict) { - qglcmap_dict = new TQIntDict< TQMap >; - } - TQMap *cmap; - if ((cmap = qglcmap_dict->find((long) info->visualid)) == 0) { - cmap = new TQMap; - qglcmap_dict->insert((long) info->visualid, cmap); - } - - // already in the map? - TQRgb target = c.rgb(); - TQMap::Iterator it = cmap->begin(); - for (; it != cmap->end(); ++it) { - if ((*it) == target) - return it.key(); - } - - // need to alloc color - unsigned long plane_mask[2]; - unsigned long color_map_entry; - if (!XAllocColorCells (TQPaintDevice::x11AppDisplay(), x->cmap, TRUE, plane_mask, 0, - &color_map_entry, 1)) - return c.pixel(screen); - - XColor col; - col.flags = DoRed | DoGreen | DoBlue; - col.pixel = color_map_entry; - col.red = (ushort)((tqRed(c.rgb()) / 255.0) * 65535.0 + 0.5); - col.green = (ushort)((tqGreen(c.rgb()) / 255.0) * 65535.0 + 0.5); - col.blue = (ushort)((tqBlue(c.rgb()) / 255.0) * 65535.0 + 0.5); - XStoreColor(TQPaintDevice::x11AppDisplay(), x->cmap, &col); - - cmap->insert(color_map_entry, target); - return color_map_entry; - } - } - return 0; -} - -#ifndef TQT_NO_XFTFREETYPE -/*! \internal - This is basically a substitute for glxUseXFont() which can only - handle XLFD fonts. This version relies on XFT v2 to render the - glyphs, but it works with all fonts that XFT2 provides - both - antialiased and aliased bitmap and outline fonts. -*/ -void qgl_use_font(TQFontEngineXft *engine, int first, int count, int listBase) -{ - GLfloat color[4]; - glGetFloatv(GL_CURRENT_COLOR, color); - - // save the pixel unpack state - GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment; - glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes); - glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst); - glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength); - glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows); - glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels); - glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment); - - glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); - glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - Bool antialiased = False; -#if 0 // disable antialias support for now - XftPatternGetBool(engine->pattern(), XFT_ANTIALIAS, 0, &antialiased); -#endif -#ifdef QT_XFT2 - FT_Face face = XftLockFace(engine->font()); -#else - FT_Face face = engine->face(); -#endif - // start generating font glyphs - for (int i = first; i < count; ++i) { - int list = listBase + i; - GLfloat x0, y0, dx, dy; - - FT_Error err; - - err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT); - if (err) { - tqDebug("failed loading glyph %d from font", i); - Q_ASSERT(!err); - } - err = FT_Render_Glyph(face->glyph, (antialiased ? ft_render_mode_normal - : ft_render_mode_mono)); - if (err) { - tqDebug("failed rendering glyph %d from font", i); - Q_ASSERT(!err); - } - - FT_Bitmap bm = face->glyph->bitmap; - x0 = face->glyph->metrics.horiBearingX >> 6; - y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6; - dx = face->glyph->metrics.horiAdvance >> 6; - dy = 0; - int sz = bm.pitch * bm.rows; - uint *aa_glyph = 0; - uchar *ua_glyph = 0; - - if (antialiased) - aa_glyph = new uint[sz]; - else - ua_glyph = new uchar[sz]; - - // convert to GL format - for (int y = 0; y < bm.rows; ++y) { - for (int x = 0; x < bm.pitch; ++x) { - int c1 = y*bm.pitch + x; - int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x; - if (antialiased) { - aa_glyph[c1] = (int(color[0]*255) << 24) - | (int(color[1]*255) << 16) - | (int(color[2]*255) << 8) | bm.buffer[c2]; - } else { - ua_glyph[c1] = bm.buffer[c2]; - } - } - } - - glNewList(list, GL_COMPILE); - if (antialiased) { - // calling glBitmap() is just a trick to move the current - // raster pos, since glGet*() won't work in display lists - glBitmap(0, 0, 0, 0, x0, -y0, 0); - glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph); - glBitmap(0, 0, 0, 0, dx-x0, y0, 0); - } else { - glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph); - } - glEndList(); - antialiased ? delete[] aa_glyph : delete[] ua_glyph; - } - -#ifdef QT_XFT2 - XftUnlockFace(engine->font()); -#endif - - // restore pixel unpack settings - glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes); - glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst); - glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength); - glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels); - glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment); -} -#endif - -void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase ) -{ - TQFont f(fnt); - TQFontEngine *engine = f.d->engineForScript(TQFont::Latin); - -#ifndef TQT_NO_XFTFREETYPE - if(engine->type() == TQFontEngine::Xft) { - qgl_use_font((TQFontEngineXft *) engine, 0, 256, listBase); - return; - } -#endif - // glXUseXFont() only works with XLFD font structures and a few GL - // drivers crash if 0 is passed as the font handle - f.setStyleStrategy(TQFont::OpenGLCompatible); - if (f.handle() && (engine->type() == TQFontEngine::XLFD - || engine->type() == TQFontEngine::LatinXLFD)) { - glXUseXFont((Font) f.handle(), 0, 256, listBase); - } -} - -/***************************************************************************** - TQGLOverlayWidget (Internal overlay class for X11) - *****************************************************************************/ - -class TQGLOverlayWidget : public TQGLWidget -{ - TQ_OBJECT -public: - TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* parent, - const char* name=0, const TQGLWidget* shareWidget=0 ); - -protected: - void initializeGL(); - void paintGL(); - void resizeGL( int w, int h ); - -private: - TQGLWidget* realWidget; - -private: // Disabled copy constructor and operator= -#if defined(TQ_DISABLE_COPY) - TQGLOverlayWidget( const TQGLOverlayWidget& ); - TQGLOverlayWidget& operator=( const TQGLOverlayWidget& ); -#endif -}; - - -TQGLOverlayWidget::TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* parent, - const char* name, - const TQGLWidget* shareWidget ) - : TQGLWidget( format, parent, name, shareWidget ? shareWidget->olw : 0 ) -{ - realWidget = parent; -} - - - -void TQGLOverlayWidget::initializeGL() -{ - TQColor transparentColor = context()->overlayTransparentColor(); - if ( transparentColor.isValid() ) - qglClearColor( transparentColor ); - else - tqWarning( "TQGLOverlayWidget::initializeGL(): Could not get transparent color" ); - realWidget->initializeOverlayGL(); -} - - -void TQGLOverlayWidget::resizeGL( int w, int h ) -{ - glViewport( 0, 0, w, h ); - realWidget->resizeOverlayGL( w, h ); -} - - -void TQGLOverlayWidget::paintGL() -{ - realWidget->paintOverlayGL(); -} - -#undef Bool -#include "qgl_x11.moc" - -/***************************************************************************** - TQGLWidget UNIX/GLX-specific code - *****************************************************************************/ -void TQGLWidget::init( TQGLContext *context, const TQGLWidget *shareWidget ) -{ - qt_resolve_gl_symbols(); - - glcx = 0; - olw = 0; - autoSwap = TRUE; - if ( !context->device() ) - context->setDevice( this ); - - if ( shareWidget ) - setContext( context, shareWidget->context() ); - else - setContext( context ); - setBackgroundMode( NoBackground ); - - if ( isValid() && context->format().hasOverlay() ) { - TQCString olwName( name() ); - olwName += "-TQGL_internal_overlay_widget"; - olw = new TQGLOverlayWidget( TQGLFormat::defaultOverlayFormat(), - this, olwName, shareWidget ); - if ( olw->isValid() ) { - olw->setAutoBufferSwap( FALSE ); - olw->setFocusProxy( this ); - } - else { - delete olw; - olw = 0; - glcx->glFormat.setOverlay( FALSE ); - } - } -} - -/*! \reimp */ -void TQGLWidget::reparent( TQWidget* parent, WFlags f, const TQPoint& p, - bool showIt ) -{ - if (glcx) - glcx->doneCurrent(); - TQWidget::reparent( parent, f, p, FALSE ); - if ( showIt ) - show(); -} - - -void TQGLWidget::setMouseTracking( bool enable ) -{ - if ( olw ) - olw->setMouseTracking( enable ); - TQWidget::setMouseTracking( enable ); -} - - -void TQGLWidget::resizeEvent( TQResizeEvent * ) -{ - if ( !isValid() ) - return; - makeCurrent(); - if ( !glcx->initialized() ) - glInit(); - glXWaitX(); - resizeGL( width(), height() ); - if ( olw ) - olw->setGeometry( rect() ); -} - -const TQGLContext* TQGLWidget::overlayContext() const -{ - if ( olw ) - return olw->context(); - else - return 0; -} - - -void TQGLWidget::makeOverlayCurrent() -{ - if ( olw ) - olw->makeCurrent(); -} - - -void TQGLWidget::updateOverlayGL() -{ - if ( olw ) - olw->updateGL(); -} - -void TQGLWidget::setContext( TQGLContext *context, - const TQGLContext* shareContext, - bool deleteOldContext ) -{ - if ( context == 0 ) { -#if defined(QT_CHECK_NULL) - tqWarning( "TQGLWidget::setContext: Cannot set null context" ); -#endif - return; - } - if ( !context->deviceIsPixmap() && context->device() != this ) { -#if defined(QT_CHECK_STATE) - tqWarning( "TQGLWidget::setContext: Context must refer to this widget" ); -#endif - return; - } - - if ( glcx ) - glcx->doneCurrent(); - TQGLContext* oldcx = glcx; - glcx = context; - - bool createFailed = FALSE; - if ( !glcx->isValid() ) { - if ( !glcx->create( shareContext ? shareContext : oldcx ) ) - createFailed = TRUE; - } - if ( createFailed ) { - if ( deleteOldContext ) - delete oldcx; - return; - } - - if ( glcx->windowCreated() || glcx->deviceIsPixmap() ) { - if ( deleteOldContext ) - delete oldcx; - return; - } - - bool visible = isVisible(); - if ( visible ) - hide(); - - XVisualInfo *vi = (XVisualInfo*)glcx->vi; - XSetWindowAttributes a; - - a.colormap = choose_cmap( x11Display(), vi ); // find best colormap - a.background_pixel = backgroundColor().pixel( vi->screen ); - a.border_pixel = black.pixel( vi->screen ); - Window p = RootWindow( x11Display(), vi->screen ); - if ( parentWidget() ) - p = parentWidget()->winId(); - - Window w = XCreateWindow( x11Display(), p, x(), y(), width(), height(), - 0, vi->depth, InputOutput, vi->visual, - CWBackPixel|CWBorderPixel|CWColormap, &a ); - - Window *cmw; - Window *cmwret; - int count; - if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), - &cmwret, &count ) ) { - cmw = new Window[count+1]; - memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count ); - XFree( (char *)cmwret ); - int i; - for ( i=0; i= count ) // append new window - cmw[count++] = w; - } else { - count = 1; - cmw = new Window[count]; - cmw[0] = w; - } - -#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT) - if ( oldcx && oldcx->windowCreated() ) - glXReleaseBuffersMESA( x11Display(), winId() ); -#endif - if ( deleteOldContext ) - delete oldcx; - oldcx = 0; - - create( w ); - - XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, - count ); - delete [] cmw; - - if ( visible ) - show(); - XFlush( x11Display() ); - glcx->setWindowCreated( TRUE ); -} - - -bool TQGLWidget::renderCxPm( TQPixmap* pm ) -{ - if ( ((XVisualInfo*)glcx->vi)->depth != pm->depth() ) - return FALSE; - - GLXPixmap glPm; -#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT) - glPm = glXCreateGLXPixmapMESA( x11Display(), - (XVisualInfo*)glcx->vi, - (Pixmap)pm->handle(), - choose_cmap( pm->x11Display(), - (XVisualInfo*)glcx->vi ) ); -#else - glPm = (TQ_UINT32)glXCreateGLXPixmap( x11Display(), - (XVisualInfo*)glcx->vi, - (Pixmap)pm->handle() ); -#endif - - if ( !glXMakeCurrent( x11Display(), glPm, (GLXContext)glcx->cx ) ) { - glXDestroyGLXPixmap( x11Display(), glPm ); - return FALSE; - } - - glDrawBuffer( GL_FRONT ); - if ( !glcx->initialized() ) - glInit(); - resizeGL( pm->width(), pm->height() ); - paintGL(); - glFlush(); - makeCurrent(); - glXDestroyGLXPixmap( x11Display(), glPm ); - resizeGL( width(), height() ); - return TRUE; -} - -const TQGLColormap & TQGLWidget::colormap() const -{ - return cmap; -} - -/*\internal - Store color values in the given colormap. -*/ -static void qStoreColors( TQWidget * tlw, Colormap cmap, - const TQGLColormap & cols ) -{ - XColor c; - TQRgb color; - - for ( int i = 0; i < cols.size(); i++ ) { - color = cols.entryRgb( i ); - c.pixel = i; - c.red = (ushort)( (tqRed( color ) / 255.0) * 65535.0 + 0.5 ); - c.green = (ushort)( (tqGreen( color ) / 255.0) * 65535.0 + 0.5 ); - c.blue = (ushort)( (tqBlue( color ) / 255.0) * 65535.0 + 0.5 ); - c.flags = DoRed | DoGreen | DoBlue; - XStoreColor( tlw->x11Display(), cmap, &c ); - } -} - -/*\internal - Check whether the given visual supports dynamic colormaps or not. -*/ -static bool qCanAllocColors( TQWidget * w ) -{ - bool validVisual = FALSE; - int numVisuals; - long mask; - XVisualInfo templ; - XVisualInfo * visuals; - VisualID id = XVisualIDFromVisual( (Visual *) - w->topLevelWidget()->x11Visual() ); - - mask = VisualScreenMask; - templ.screen = w->x11Screen(); - visuals = XGetVisualInfo( w->x11Display(), mask, &templ, &numVisuals ); - - for ( int i = 0; i < numVisuals; i++ ) { - if ( visuals[i].visualid == id ) { - switch ( visuals[i].c_class ) { - case TrueColor: - case StaticColor: - case StaticGray: - case GrayScale: - validVisual = FALSE; - break; - case DirectColor: - case PseudoColor: - validVisual = TRUE; - break; - } - break; - } - } - XFree( visuals ); - - if ( !validVisual ) - return FALSE; - return TRUE; -} - -void TQGLWidget::setColormap( const TQGLColormap & c ) -{ - TQWidget * tlw = topLevelWidget(); // must return a valid widget - - cmap = c; - if ( !cmap.d ) - return; - - if ( !cmap.d->cmapHandle && !qCanAllocColors( this ) ) { - tqWarning( "TQGLWidget::setColormap: Cannot create a read/write " - "colormap for this visual" ); - return; - } - - // If the child GL widget is not of the same visual class as the - // toplevel widget we will get in trouble.. - Window wid = tlw->winId(); - Visual * vis = (Visual *) tlw->x11Visual();; - VisualID cvId = XVisualIDFromVisual( (Visual *) x11Visual() ); - VisualID tvId = XVisualIDFromVisual( (Visual *) tlw->x11Visual() ); - if ( cvId != tvId ) { - wid = winId(); - vis = (Visual *) x11Visual(); - } - - if ( !cmap.d->cmapHandle ) // allocate a cmap if necessary - cmap.d->cmapHandle = XCreateColormap( x11Display(), wid, vis, - AllocAll ); - - qStoreColors( this, (Colormap) cmap.d->cmapHandle, c ); - XSetWindowColormap( x11Display(), wid, (Colormap) cmap.d->cmapHandle ); - - // tell the wm that this window has a special colormap - Window * cmw; - Window * cmwret; - int count; - if ( XGetWMColormapWindows( x11Display(), tlw->winId(), &cmwret, - &count ) ) - { - cmw = new Window[count+1]; - memcpy( (char *) cmw, (char *) cmwret, sizeof(Window) * count ); - XFree( (char *) cmwret ); - int i; - for ( i = 0; i < count; i++ ) { - if ( cmw[i] == winId() ) { - break; - } - } - if ( i >= count ) // append new window only if not in the list - cmw[count++] = winId(); - } else { - count = 1; - cmw = new Window[count]; - cmw[0] = winId(); - } - XSetWMColormapWindows( x11Display(), tlw->winId(), cmw, count ); - delete [] cmw; -} - -/*! \internal - Free up any allocated colormaps. This fn is only called for - top-level widgets. -*/ -void TQGLWidget::cleanupColormaps() -{ - if ( !cmap.d ) - return; - - if ( cmap.d->cmapHandle ) { - XFreeColormap( topLevelWidget()->x11Display(), - (Colormap) cmap.d->cmapHandle ); - cmap.d->cmapHandle = 0; - } -} - -void TQGLWidget::macInternalFixBufferRect() -{ -} - -#endif diff --git a/src/opengl/qgl_x11_p.h b/src/opengl/qgl_x11_p.h deleted file mode 100644 index cbcd741b9..000000000 --- a/src/opengl/qgl_x11_p.h +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Definitions needed for resolving GL/GLX symbols using dlopen() -** under X11. -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the OpenGL 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. -** -** 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 TQGL_P_H -#define TQGL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the TQt API. This header file may -// change from version to version without notice, or even be -// removed. -// -// We mean it. -// -// - -#ifdef QT_DLOPEN_OPENGL -// resolve the GL symbols we use ourselves -bool qt_resolve_gl_symbols(bool = TRUE); -extern "C" { -// GL symbols -typedef void (*_glCallLists)( GLsizei n, GLenum type, const GLvoid *lists ); -typedef void (*_glClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); -typedef void (*_glClearIndex)( GLfloat c ); -typedef void (*_glColor3ub)( GLubyte red, GLubyte green, GLubyte blue ); -typedef void (*_glDeleteLists)( GLuint list, GLsizei range ); -typedef void (*_glDrawBuffer)( GLenum mode ); -typedef void (*_glFlush)( void ); -typedef void (*_glIndexi)( GLint c ); -typedef void (*_glListBase)( GLuint base ); -typedef void (*_glLoadIdentity)( void ); -typedef void (*_glMatrixMode)( GLenum mode ); -typedef void (*_glOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); -typedef void (*_glPopAttrib)( void ); -typedef void (*_glPopMatrix)( void ); -typedef void (*_glPushAttrib)( GLbitfield mask ); -typedef void (*_glPushMatrix)( void ); -typedef void (*_glRasterPos2i)( GLint x, GLint y ); -typedef void (*_glRasterPos3d)( GLdouble x, GLdouble y, GLdouble z ); -typedef void (*_glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); -typedef void (*_glViewport)( GLint x, GLint y, GLsizei width, GLsizei height ); -typedef void (*_glPixelStorei)( GLenum pname, GLint param ); -typedef void (*_glBitmap)( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ); -typedef void (*_glDrawPixels)( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); -typedef void (*_glNewList)( GLuint list, GLenum mode ); -typedef void (*_glGetFloatv)( GLenum pname, GLfloat *params ); -typedef void (*_glGetIntegerv)( GLenum pname, GLint *params ); -typedef void (*_glEndList)( void ); - - -// GLX symbols - should be in the GL lib as well -typedef XVisualInfo* (*_glXChooseVisual)(Display *dpy, int screen, int *attribList); -typedef GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); -typedef GLXPixmap (*_glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap); -typedef void (*_glXDestroyContext)(Display *dpy, GLXContext ctx); -typedef void (*_glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix); -typedef const char* (*_glXGetClientString)(Display *dpy, int name ); -typedef int (*_glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value); -typedef Bool (*_glXIsDirect)(Display *dpy, GLXContext ctx); -typedef Bool (*_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); -typedef Bool (*_glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase); -typedef const char* (*_glXQueryExtensionsString)(Display *dpy, int screen); -typedef const char* (*_glXQueryServerString)(Display *dpy, int screen, int name); -typedef void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable); -typedef void (*_glXUseXFont)(Font font, int first, int count, int listBase); -typedef void (*_glXWaitX)(void); - -extern _glCallLists qt_glCallLists; -extern _glClearColor qt_glClearColor; -extern _glClearIndex qt_glClearIndex; -extern _glColor3ub qt_glColor3ub; -extern _glDeleteLists qt_glDeleteLists; -extern _glDrawBuffer qt_glDrawBuffer; -extern _glFlush qt_glFlush; -extern _glIndexi qt_glIndexi; -extern _glListBase qt_glListBase; -extern _glLoadIdentity qt_glLoadIdentity; -extern _glMatrixMode qt_glMatrixMode; -extern _glOrtho qt_glOrtho; -extern _glPopAttrib qt_glPopAttrib; -extern _glPopMatrix qt_glPopMatrix; -extern _glPushAttrib qt_glPushAttrib; -extern _glPushMatrix qt_glPushMatrix; -extern _glRasterPos2i qt_glRasterPos2i; -extern _glRasterPos3d qt_glRasterPos3d; -extern _glReadPixels qt_glReadPixels; -extern _glViewport qt_glViewport; -extern _glPixelStorei qt_glPixelStorei; -extern _glBitmap qt_glBitmap; -extern _glDrawPixels qt_glDrawPixels; -extern _glNewList qt_glNewList; -extern _glGetFloatv qt_glGetFloatv; -extern _glGetIntegerv qt_glGetIntegerv; -extern _glEndList qt_glEndList; - -extern _glXChooseVisual qt_glXChooseVisual; -extern _glXCreateContext qt_glXCreateContext; -extern _glXCreateGLXPixmap qt_glXCreateGLXPixmap; -extern _glXDestroyContext qt_glXDestroyContext; -extern _glXDestroyGLXPixmap qt_glXDestroyGLXPixmap; -extern _glXGetClientString qt_glXGetClientString; -extern _glXGetConfig qt_glXGetConfig; -extern _glXIsDirect qt_glXIsDirect; -extern _glXMakeCurrent qt_glXMakeCurrent; -extern _glXQueryExtension qt_glXQueryExtension; -extern _glXQueryExtensionsString qt_glXQueryExtensionsString; -extern _glXQueryServerString qt_glXQueryServerString; -extern _glXSwapBuffers qt_glXSwapBuffers; -extern _glXUseXFont qt_glXUseXFont; -extern _glXWaitX qt_glXWaitX; -}; // extern "C" - -#define glCallLists qt_glCallLists -#define glClearColor qt_glClearColor -#define glClearIndex qt_glClearIndex -#define glColor3ub qt_glColor3ub -#define glDeleteLists qt_glDeleteLists -#define glDrawBuffer qt_glDrawBuffer -#define glFlush qt_glFlush -#define glIndexi qt_glIndexi -#define glListBase qt_glListBase -#define glLoadIdentity qt_glLoadIdentity -#define glMatrixMode qt_glMatrixMode -#define glOrtho qt_glOrtho -#define glPopAttrib qt_glPopAttrib -#define glPopMatrix qt_glPopMatrix -#define glPushAttrib qt_glPushAttrib -#define glPushMatrix qt_glPushMatrix -#define glRasterPos2i qt_glRasterPos2i -#define glRasterPos3d qt_glRasterPos3d -#define glReadPixels qt_glReadPixels -#define glViewport qt_glViewport -#define glPixelStorei qt_glPixelStorei -#define glBitmap qt_glBitmap -#define glDrawPixels qt_glDrawPixels -#define glNewList qt_glNewList -#define glGetFloatv qt_glGetFloatv -#define glGetIntegerv qt_glGetIntegerv -#define glEndList qt_glEndList - -#define glXChooseVisual qt_glXChooseVisual -#define glXCreateContext qt_glXCreateContext -#define glXCreateGLXPixmap qt_glXCreateGLXPixmap -#define glXDestroyContext qt_glXDestroyContext -#define glXDestroyGLXPixmap qt_glXDestroyGLXPixmap -#define glXGetClientString qt_glXGetClientString -#define glXGetConfig qt_glXGetConfig -#define glXIsDirect qt_glXIsDirect -#define glXMakeCurrent qt_glXMakeCurrent -#define glXQueryExtension qt_glXQueryExtension -#define glXQueryExtensionsString qt_glXQueryExtensionsString -#define glXQueryServerString qt_glXQueryServerString -#define glXSwapBuffers qt_glXSwapBuffers -#define glXUseXFont qt_glXUseXFont -#define glXWaitX qt_glXWaitX - -#else -inline bool qt_resolve_gl_symbols(bool = TRUE) { return TRUE; } -#endif // QT_DLOPEN_OPENGL -#endif // TQGL_P_H diff --git a/src/opengl/qglcolormap.cpp b/src/opengl/qglcolormap.cpp deleted file mode 100644 index 088c83030..000000000 --- a/src/opengl/qglcolormap.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/**************************************************************************** -** -** Implementation of TQGLColormap class -** -** Created : 20010326 -** -** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the opengl 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. -** -**********************************************************************/ - -/*! - \class TQGLColormap ntqglcolormap.h - \brief The TQGLColormap class is used for installing custom colormaps into - TQGLWidgets. -\if defined(commercial) - It is part of the TQt Enterprise Edition. -\endif - - \module OpenGL - \ingroup graphics - \ingroup images - - TQGLColormap provides a platform independent way of specifying and - installing indexed colormaps into TQGLWidgets. TQGLColormap is - especially useful when using the \link opengl.html OpenGL\endlink - color-index mode. - - Under X11 you must use an X server that supports either a \c - PseudoColor or \c DirectColor visual class. If your X server - currently only provides a \c GrayScale, \c TrueColor, \c - StaticColor or \c StaticGray visual, you will not be able to - allocate colorcells for writing. If this is the case, try setting - your X server to 8 bit mode. It should then provide you with at - least a \c PseudoColor visual. Note that you may experience - colormap flashing if your X server is running in 8 bit mode. - - Under Windows the size of the colormap is always set to 256 - colors. Note that under Windows you can also install colormaps - in child widgets. - - This class uses explicit sharing (see \link shclass.html Shared - Classes\endlink). - - Example of use: - \code - #include - #include - - int main() - { - TQApplication a( argc, argv ); - - MySuperGLWidget widget( 0 ); // A TQGLWidget in color-index mode - TQGLColormap colormap; - - // This will fill the colormap with colors ranging from - // black to white. - for ( int i = 0; i < colormap.size(); i++ ) - colormap.setEntry( i, tqRgb( i, i, i ) ); - - widget.setColormap( colormap ); - widget.show(); - return a.exec(); - } - \endcode - - \sa TQGLWidget::setColormap(), TQGLWidget::colormap() -*/ - -#include "ntqglcolormap.h" -#include "tqmemarray.h" - - -/*! - Construct a TQGLColormap. -*/ -TQGLColormap::TQGLColormap() -{ - d = 0; -} - - -/*! - Construct a shallow copy of \a map. -*/ -TQGLColormap::TQGLColormap( const TQGLColormap & map ) -{ - d = map.d; - if ( d ) - d->ref(); -} - -/*! - Dereferences the TQGLColormap and deletes it if this was the last - reference to it. -*/ -TQGLColormap::~TQGLColormap() -{ - if ( d && d->deref() ) { - delete d; - d = 0; - } -} - -/*! - Assign a shallow copy of \a map to this TQGLColormap. -*/ -TQGLColormap & TQGLColormap::operator=( const TQGLColormap & map ) -{ - if ( map.d != 0 ) - map.d->ref(); - - if ( d && d->deref() ) - delete d; - d = map.d; - - return *this; -} - -/*! - Detaches this TQGLColormap from the shared block. -*/ -void TQGLColormap::detach() -{ - if ( d && d->count != 1 ) { - // ### What about the actual colormap handle? - Private * newd = new Private(); - newd->cells = d->cells; - newd->cells.detach(); - if ( d->deref() ) - delete d; - d = newd; - } -} - -/*! - Set cell at index \a idx in the colormap to color \a color. -*/ -void TQGLColormap::setEntry( int idx, TQRgb color ) -{ - if ( !d ) - d = new Private(); - -#if defined(QT_CHECK_RANGE) - if ( idx < 0 || idx > (int) d->cells.size() ) { - tqWarning( "TQGLColormap::setRgb: Index out of range." ); - return; - } -#endif - d->cells[ idx ] = color; -} - -/*! - Set an array of cells in this colormap. \a count is the number of - colors that should be set, \a colors is the array of colors, and - \a base is the starting index. -*/ -void TQGLColormap::setEntries( int count, const TQRgb * colors, int base ) -{ - if ( !d ) - d = new Private(); - - if ( !colors || base < 0 || base >= (int) d->cells.size() ) - return; - - for( int i = base; i < base + count; i++ ) { - if ( i < (int) d->cells.size() ) - setEntry( i, colors[i] ); - else - break; - } -} - -/*! - Returns the TQRgb value in the colorcell with index \a idx. -*/ -TQRgb TQGLColormap::entryRgb( int idx ) const -{ - if ( !d || idx < 0 || idx > (int) d->cells.size() ) - return 0; - else - return d->cells[ idx ]; -} - -/*! - \overload - - Set the cell with index \a idx in the colormap to color \a color. -*/ -void TQGLColormap::setEntry( int idx, const TQColor & color ) -{ - setEntry( idx, color.rgb() ); -} - -/*! - Returns the TQRgb value in the colorcell with index \a idx. -*/ -TQColor TQGLColormap::entryColor( int idx ) const -{ - if ( !d || idx < 0 || idx > (int) d->cells.size() ) - return TQColor(); - else - return TQColor( d->cells[ idx ] ); -} - -/*! - Returns TRUE if the colormap is empty; otherwise returns FALSE. A - colormap with no color values set is considered to be empty. -*/ -bool TQGLColormap::isEmpty() const -{ - return (d == 0) || (d->cells.size() == 0) || (d->cmapHandle == 0); -} - - -/*! - Returns the number of colorcells in the colormap. -*/ -int TQGLColormap::size() const -{ - return d != 0 ? d->cells.size() : 0; -} - -/*! - Returns the index of the color \a color. If \a color is not in the - map, -1 is returned. -*/ -int TQGLColormap::find( TQRgb color ) const -{ - if ( d ) - return d->cells.find( color ); - return -1; -} - -/*! - Returns the index of the color that is the closest match to color - \a color. -*/ -int TQGLColormap::findNearest( TQRgb color ) const -{ - int idx = find( color ); - if ( idx >= 0 ) - return idx; - int mapSize = size(); - int mindist = 200000; - int r = tqRed( color ); - int g = tqGreen( color ); - int b = tqBlue( color ); - int rx, gx, bx, dist; - for ( int i=0; i < mapSize; i++ ) { - TQRgb ci = d->cells[i]; - rx = r - tqRed( ci ); - gx = g - tqGreen( ci ); - bx = b - tqBlue( ci ); - dist = rx*rx + gx*gx + bx*bx; // calculate distance - if ( dist < mindist ) { // minimal? - mindist = dist; - idx = i; - } - } - return idx; -} diff --git a/src/opengl/qt_opengl.pri b/src/opengl/qt_opengl.pri index b0c34887f..79b655422 100644 --- a/src/opengl/qt_opengl.pri +++ b/src/opengl/qt_opengl.pri @@ -1,13 +1,13 @@ # TQt opengl module opengl { - HEADERS += $$OPENGL_H/ntqgl.h \ - $$OPENGL_H/ntqglcolormap.h - SOURCES += $$OPENGL_CPP/qgl.cpp \ - $$OPENGL_CPP/qglcolormap.cpp + HEADERS += $$OPENGL_H/tqgl.h \ + $$OPENGL_H/tqglcolormap.h + SOURCES += $$OPENGL_CPP/tqgl.cpp \ + $$OPENGL_CPP/tqglcolormap.cpp x11 { - HEADERS += $$OPENGL_H/qgl_x11_p.h - SOURCES += $$OPENGL_CPP/qgl_x11.cpp + HEADERS += $$OPENGL_H/tqgl_x11_p.h + SOURCES += $$OPENGL_CPP/tqgl_x11.cpp } else:mac:SOURCES += $$OPENGL_CPP/qgl_mac.cpp else:win32:SOURCES += $$OPENGL_CPP/qgl_win.cpp diff --git a/src/opengl/tqgl.cpp b/src/opengl/tqgl.cpp new file mode 100644 index 000000000..1e8edd59a --- /dev/null +++ b/src/opengl/tqgl.cpp @@ -0,0 +1,2367 @@ +/**************************************************************************** +** +** Implementation of OpenGL classes for TQt +** +** Created : 970112 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the opengl 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 "tqgl.h" +#include "tqpixmap.h" +#include "tqpaintdevicemetrics.h" +#include "tqimage.h" +#include "ntqcleanuphandler.h" +#include "tqptrdict.h" + +static TQGLFormat* qgl_default_format = 0; +static TQGLFormat* qgl_default_overlay_format = 0; + +#if defined(TQ_WS_X11) +#include "private/qt_x11_p.h" +#define INT32 dummy_INT32 +#define INT8 dummy_INT8 +#include +#undef INT32 +#undef INT8 +#include "tqgl_x11_p.h" +#endif + +static TQCleanupHandler qgl_cleanup_format; + + +/*! + \class TQGL tqgl.h + \brief The TQGL class is a namespace for miscellaneous identifiers + in the TQt OpenGL module. +\if defined(commercial) + It is part of the TQt Enterprise Edition. +\endif + + \module OpenGL + \ingroup graphics + \ingroup images + + + Normally you can ignore this class. TQGLWidget and the other + OpenGL* module classes inherit it, so when you make your + own TQGLWidget subclass you can use the identifiers in the TQGL + namespace without qualification. + + However, you may occasionally find yourself in situations where you + need to refer to these identifiers from outside the TQGL namespace's + scope, e.g. in static functions. In such cases, simply write e.g. \c + TQGL::DoubleBuffer instead of just \c DoubleBuffer. + + * OpenGL is a trademark of Silicon Graphics, Inc. in the + United States and other countries. + +*/ + + +/***************************************************************************** + TQGLFormat implementation + *****************************************************************************/ + + +/*! + \class TQGLFormat tqgl.h + \brief The TQGLFormat class specifies the display format of an OpenGL + rendering context. +\if defined(commercial) + It is part of the TQt Enterprise Edition. +\endif + + \ingroup graphics + \ingroup images + \module OpenGL + + A display format has several characteristics: + \list + \i \link setDoubleBuffer() Double or single buffering.\endlink + \i \link setDepth() Depth buffer.\endlink + \i \link setRgba() RGBA or color index mode.\endlink + \i \link setAlpha() Alpha channel.\endlink + \i \link setAccum() Accumulation buffer.\endlink + \i \link setStencil() Stencil buffer.\endlink + \i \link setStereo() Stereo buffers.\endlink + \i \link setDirectRendering() Direct rendering.\endlink + \i \link setOverlay() Presence of an overlay.\endlink + \i \link setPlane() The plane of an overlay format.\endlink + \endlist + + You create and tell a TQGLFormat object what rendering options you + want from an OpenGL* rendering context. + + OpenGL drivers or accelerated hardware may or may not support + advanced features such as alpha channel or stereographic viewing. + If you request some features that the driver/hardware does not + provide when you create a TQGLWidget, you will get a rendering + context with the nearest subset of features. + + There are different ways to define the display characteristics of + a rendering context. One is to create a TQGLFormat and make it the + default for the entire application: + \code + TQGLFormat f; + f.setAlpha( TRUE ); + f.setStereo( TRUE ); + TQGLFormat::setDefaultFormat( f ); + \endcode + + Or you can specify the desired format when creating an object of + your TQGLWidget subclass: + \code + TQGLFormat f; + f.setDoubleBuffer( FALSE ); // single buffer + f.setDirectRendering( FALSE ); // software rendering + MyGLWidget* myWidget = new MyGLWidget( f, ... ); + \endcode + + After the widget has been created, you can find out which of the + requested features the system was able to provide: + \code + TQGLFormat f; + f.setOverlay( TRUE ); + f.setStereo( TRUE ); + MyGLWidget* myWidget = new MyGLWidget( f, ... ); + if ( !w->format().stereo() ) { + // ok, goggles off + if ( !w->format().hasOverlay() ) { + tqFatal( "Cool hardware required" ); + } + } + \endcode + + * OpenGL is a trademark of Silicon Graphics, Inc. in the + United States and other countries. + + \sa TQGLContext, TQGLWidget +*/ + + +/*! + Constructs a TQGLFormat object with the factory default settings: + \list + \i \link setDoubleBuffer() Double buffer:\endlink Enabled. + \i \link setDepth() Depth buffer:\endlink Enabled. + \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled). + \i \link setAlpha() Alpha channel:\endlink Disabled. + \i \link setAccum() Accumulator buffer:\endlink Disabled. + \i \link setStencil() Stencil buffer:\endlink Disabled. + \i \link setStereo() Stereo:\endlink Disabled. + \i \link setDirectRendering() Direct rendering:\endlink Enabled. + \i \link setOverlay() Overlay:\endlink Disabled. + \i \link setPlane() Plane:\endlink 0 (i.e., normal plane). + \endlist +*/ + +TQGLFormat::TQGLFormat() +{ + opts = DoubleBuffer | DepthBuffer | Rgba | DirectRendering; + pln = 0; +} + + +/*! + Creates a TQGLFormat object that is a copy of the current \link + defaultFormat() application default format\endlink. + + If \a options is not 0, this copy is modified by these format + options. The \a options parameter should be \c FormatOption values + OR'ed together. + + This constructor makes it easy to specify a certain desired format + in classes derived from TQGLWidget, for example: + \code + // The rendering in MyGLWidget depends on using + // stencil buffer and alpha channel + MyGLWidget::MyGLWidget( TQWidget* parent, const char* name ) + : TQGLWidget( TQGLFormat( StencilBuffer | AlphaChannel ), parent, name ) + { + if ( !format().stencil() ) + tqWarning( "Could not get stencil buffer; results will be suboptimal" ); + if ( !format().alphaChannel() ) + tqWarning( "Could not get alpha channel; results will be suboptimal" ); + ... + } + \endcode + + Note that there are \c FormatOption values to turn format settings + both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer, + \c DirectRendering and \c IndirectRendering, etc. + + The \a plane parameter defaults to 0 and is the plane which this + format should be associated with. Not all OpenGL implmentations + supports overlay/underlay rendering planes. + + \sa defaultFormat(), setOption() +*/ + +TQGLFormat::TQGLFormat( int options, int plane ) +{ + uint newOpts = options; + opts = defaultFormat().opts; + opts |= ( newOpts & 0xffff ); + opts &= ~( newOpts >> 16 ); + pln = plane; +} + + +/*! + \fn bool TQGLFormat::doubleBuffer() const + + Returns TRUE if double buffering is enabled; otherwise returns + FALSE. Double buffering is enabled by default. + + \sa setDoubleBuffer() +*/ + +/*! + If \a enable is TRUE sets double buffering; otherwise sets single + buffering. + + Double buffering is enabled by default. + + Double buffering is a technique where graphics are rendered on an + off-screen buffer and not directly to the screen. When the drawing + has been completed, the program calls a swapBuffers() function to + exchange the screen contents with the buffer. The result is + flicker-free drawing and often better performance. + + \sa doubleBuffer(), TQGLContext::swapBuffers(), + TQGLWidget::swapBuffers() +*/ + +void TQGLFormat::setDoubleBuffer( bool enable ) +{ + setOption( enable ? DoubleBuffer : SingleBuffer ); +} + + +/*! + \fn bool TQGLFormat::depth() const + + Returns TRUE if the depth buffer is enabled; otherwise returns + FALSE. The depth buffer is enabled by default. + + \sa setDepth() +*/ + +/*! + If \a enable is TRUE enables the depth buffer; otherwise disables + the depth buffer. + + The depth buffer is enabled by default. + + The purpose of a depth buffer (or Z-buffering) is to remove hidden + surfaces. Pixels are assigned Z values based on the distance to + the viewer. A pixel with a high Z value is closer to the viewer + than a pixel with a low Z value. This information is used to + decide whether to draw a pixel or not. + + \sa depth() +*/ + +void TQGLFormat::setDepth( bool enable ) +{ + setOption( enable ? DepthBuffer : NoDepthBuffer ); +} + + +/*! + \fn bool TQGLFormat::rgba() const + + Returns TRUE if RGBA color mode is set. Returns FALSE if color + index mode is set. The default color mode is RGBA. + + \sa setRgba() +*/ + +/*! + If \a enable is TRUE sets RGBA mode. If \a enable is FALSE sets + color index mode. + + The default color mode is RGBA. + + RGBA is the preferred mode for most OpenGL applications. In RGBA + color mode you specify colors as red + green + blue + alpha + quadruplets. + + In color index mode you specify an index into a color lookup + table. + + \sa rgba() +*/ + +void TQGLFormat::setRgba( bool enable ) +{ + setOption( enable ? Rgba : ColorIndex ); +} + + +/*! + \fn bool TQGLFormat::alpha() const + + Returns TRUE if the alpha channel of the framebuffer is enabled; + otherwise returns FALSE. The alpha channel is disabled by default. + + \sa setAlpha() +*/ + +/*! + If \a enable is TRUE enables the alpha channel; otherwise disables + the alpha channel. + + The alpha buffer is disabled by default. + + The alpha channel is typically used for implementing transparency + or translucency. The A in RGBA specifies the transparency of a + pixel. + + \sa alpha() +*/ + +void TQGLFormat::setAlpha( bool enable ) +{ + setOption( enable ? AlphaChannel : NoAlphaChannel ); +} + + +/*! + \fn bool TQGLFormat::accum() const + + Returns TRUE if the accumulation buffer is enabled; otherwise + returns FALSE. The accumulation buffer is disabled by default. + + \sa setAccum() +*/ + +/*! + If \a enable is TRUE enables the accumulation buffer; otherwise + disables the accumulation buffer. + + The accumulation buffer is disabled by default. + + The accumulation buffer is used to create blur effects and + multiple exposures. + + \sa accum() +*/ + +void TQGLFormat::setAccum( bool enable ) +{ + setOption( enable ? AccumBuffer : NoAccumBuffer ); +} + + +/*! + \fn bool TQGLFormat::stencil() const + + Returns TRUE if the stencil buffer is enabled; otherwise returns + FALSE. The stencil buffer is disabled by default. + + \sa setStencil() +*/ + +/*! + If \a enable is TRUE enables the stencil buffer; otherwise + disables the stencil buffer. + + The stencil buffer is disabled by default. + + The stencil buffer masks certain parts of the drawing area so that + masked parts are not drawn on. + + \sa stencil() +*/ + +void TQGLFormat::setStencil( bool enable ) +{ + setOption( enable ? StencilBuffer: NoStencilBuffer ); +} + + +/*! + \fn bool TQGLFormat::stereo() const + + Returns TRUE if stereo buffering is enabled; otherwise returns + FALSE. Stereo buffering is disabled by default. + + \sa setStereo() +*/ + +/*! + If \a enable is TRUE enables stereo buffering; otherwise disables + stereo buffering. + + Stereo buffering is disabled by default. + + Stereo buffering provides extra color buffers to generate left-eye + and right-eye images. + + \sa stereo() +*/ + +void TQGLFormat::setStereo( bool enable ) +{ + setOption( enable ? StereoBuffers : NoStereoBuffers ); +} + + +/*! + \fn bool TQGLFormat::directRendering() const + + Returns TRUE if direct rendering is enabled; otherwise returns + FALSE. + + Direct rendering is enabled by default. + + \sa setDirectRendering() +*/ + +/*! + If \a enable is TRUE enables direct rendering; otherwise disables + direct rendering. + + Direct rendering is enabled by default. + + Enabling this option will make OpenGL bypass the underlying window + system and render directly from hardware to the screen, if this is + supported by the system. + + \sa directRendering() +*/ + +void TQGLFormat::setDirectRendering( bool enable ) +{ + setOption( enable ? DirectRendering : IndirectRendering ); +} + + +/*! + \fn bool TQGLFormat::hasOverlay() const + + Returns TRUE if overlay plane is enabled; otherwise returns FALSE. + + Overlay is disabled by default. + + \sa setOverlay() +*/ + +/*! + If \a enable is TRUE enables an overlay plane; otherwise disables + the overlay plane. + + Enabling the overlay plane will cause TQGLWidget to create an + additional context in an overlay plane. See the TQGLWidget + documentation for further information. + + \sa hasOverlay() +*/ + +void TQGLFormat::setOverlay( bool enable ) +{ + setOption( enable ? HasOverlay : NoOverlay ); +} + +/*! + Returns the plane of this format. The default for normal formats + is 0, which means the normal plane. The default for overlay + formats is 1, which is the first overlay plane. + + \sa setPlane() +*/ +int TQGLFormat::plane() const +{ + return pln; +} + +/*! + Sets the requested plane to \a plane. 0 is the normal plane, 1 is + the first overlay plane, 2 is the second overlay plane, etc.; -1, + -2, etc. are underlay planes. + + Note that in contrast to other format specifications, the plane + specifications will be matched exactly. This means that if you + specify a plane that the underlying OpenGL system cannot provide, + an \link TQGLWidget::isValid() invalid\endlink TQGLWidget will be + created. + + \sa plane() +*/ +void TQGLFormat::setPlane( int plane ) +{ + pln = plane; +} + +/*! + Sets the format option to \a opt. + + \sa testOption() +*/ + +void TQGLFormat::setOption( FormatOption opt ) +{ + if ( opt & 0xffff ) + opts |= opt; + else + opts &= ~( opt >> 16 ); +} + + + +/*! + Returns TRUE if format option \a opt is set; otherwise returns FALSE. + + \sa setOption() +*/ + +bool TQGLFormat::testOption( FormatOption opt ) const +{ + if ( opt & 0xffff ) + return ( opts & opt ) != 0; + else + return ( opts & ( opt >> 16 ) ) == 0; +} + + + +/*! + \fn bool TQGLFormat::hasOpenGL() + + Returns TRUE if the window system has any OpenGL support; + otherwise returns FALSE. + + \warning This function must not be called until the TQApplication + object has been created. +*/ + + + +/*! + \fn bool TQGLFormat::hasOpenGLOverlays() + + Returns TRUE if the window system supports OpenGL overlays; + otherwise returns FALSE. + + \warning This function must not be called until the TQApplication + object has been created. +*/ + +/*! + Returns the default TQGLFormat for the application. All TQGLWidgets + that are created use this format unless another format is + specified, e.g. when they are constructed. + + If no special default format has been set using + setDefaultFormat(), the default format is the same as that created + with TQGLFormat(). + + \sa setDefaultFormat() +*/ + +TQGLFormat TQGLFormat::defaultFormat() +{ + if ( !qgl_default_format ) { + qgl_default_format = new TQGLFormat; + qgl_cleanup_format.add( &qgl_default_format ); + } + return *qgl_default_format; +} + +/*! + Sets a new default TQGLFormat for the application to \a f. For + example, to set single buffering as the default instead of double + buffering, your main() might contain code like this: + \code + TQApplication a(argc, argv); + TQGLFormat f; + f.setDoubleBuffer( FALSE ); + TQGLFormat::setDefaultFormat( f ); + \endcode + + \sa defaultFormat() +*/ + +void TQGLFormat::setDefaultFormat( const TQGLFormat &f ) +{ + if ( !qgl_default_format ) { + qgl_default_format = new TQGLFormat; + qgl_cleanup_format.add( &qgl_default_format ); + } + *qgl_default_format = f; +} + + +/*! + Returns the default TQGLFormat for overlay contexts. + + The factory default overlay format is: + \list + \i \link setDoubleBuffer() Double buffer:\endlink Disabled. + \i \link setDepth() Depth buffer:\endlink Disabled. + \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled). + \i \link setAlpha() Alpha channel:\endlink Disabled. + \i \link setAccum() Accumulator buffer:\endlink Disabled. + \i \link setStencil() Stencil buffer:\endlink Disabled. + \i \link setStereo() Stereo:\endlink Disabled. + \i \link setDirectRendering() Direct rendering:\endlink Enabled. + \i \link setOverlay() Overlay:\endlink Disabled. + \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane). + \endlist + + \sa setDefaultFormat() +*/ + +TQGLFormat TQGLFormat::defaultOverlayFormat() +{ + if ( !qgl_default_overlay_format ) { + qgl_default_overlay_format = new TQGLFormat; + qgl_default_overlay_format->opts = DirectRendering; + qgl_default_overlay_format->pln = 1; + qgl_cleanup_format.add( &qgl_default_overlay_format ); + } + return *qgl_default_overlay_format; +} + +/*! + Sets a new default TQGLFormat for overlay contexts to \a f. This + format is used whenever a TQGLWidget is created with a format that + hasOverlay() enabled. + + For example, to get a double buffered overlay context (if + available), use code like this: + + \code + TQGLFormat f = TQGLFormat::defaultOverlayFormat(); + f.setDoubleBuffer( TRUE ); + TQGLFormat::setDefaultOverlayFormat( f ); + \endcode + + As usual, you can find out after widget creation whether the + underlying OpenGL system was able to provide the requested + specification: + + \code + // ...continued from above + MyGLWidget* myWidget = new MyGLWidget( TQGLFormat( TQGL::HasOverlay ), ... ); + if ( myWidget->format().hasOverlay() ) { + // Yes, we got an overlay, let's check _its_ format: + TQGLContext* olContext = myWidget->overlayContext(); + if ( olContext->format().doubleBuffer() ) + ; // yes, we got a double buffered overlay + else + ; // no, only single buffered overlays are available + } + \endcode + + \sa defaultOverlayFormat() +*/ + +void TQGLFormat::setDefaultOverlayFormat( const TQGLFormat &f ) +{ + if ( !qgl_default_overlay_format ) { + qgl_default_overlay_format = new TQGLFormat; + qgl_cleanup_format.add( &qgl_default_overlay_format ); + } + *qgl_default_overlay_format = f; + // Make sure the user doesn't request that the overlays themselves + // have overlays, since it is unlikely that the system supports + // infinitely many planes... + qgl_default_overlay_format->setOverlay( FALSE ); +} + + +/*! + Returns TRUE if all the options of the two TQGLFormats are equal; + otherwise returns FALSE. +*/ + +bool operator==( const TQGLFormat& a, const TQGLFormat& b ) +{ + return (a.opts == b.opts) && (a.pln == b.pln); +} + + +/*! + Returns FALSE if all the options of the two TQGLFormats are equal; + otherwise returns TRUE. +*/ + +bool operator!=( const TQGLFormat& a, const TQGLFormat& b ) +{ + return !( a == b ); +} + + + +/***************************************************************************** + TQGLContext implementation + *****************************************************************************/ + +TQGLContext* TQGLContext::currentCtx = 0; + +/*! + \class TQGLContext tqgl.h + \brief The TQGLContext class encapsulates an OpenGL rendering context. +\if defined(commercial) + It is part of the TQt Enterprise Edition. +\endif + + \ingroup graphics + \ingroup images + \module OpenGL + + An OpenGL* rendering context is a complete set of + OpenGL state variables. + + The context's \link TQGL::FormatOption format\endlink is set in the + constructor or later with setFormat(). The format options that are + actually set are returned by format(); the options you asked for + are returned by requestedFormat(). Note that after a TQGLContext + object has been constructed, the actual OpenGL context must be + created by explicitly calling the \link create() create()\endlink + function. The makeCurrent() function makes this context the + current rendering context. You can make \e no context current + using doneCurrent(). The reset() function will reset the context + and make it invalid. + + You can examine properties of the context with, e.g. isValid(), + isSharing(), initialized(), windowCreated() and + overlayTransparentColor(). + + If you're using double buffering you can swap the screen contents + with the off-screen buffer using swapBuffers(). + + Please note that TQGLContext is not thread safe. + + * OpenGL is a trademark of Silicon Graphics, Inc. in the + United States and other countries. + +*/ + + +/*! + Constructs an OpenGL context for the paint device \a device, which + can be a widget or a pixmap. The \a format specifies several + display options for the context. + + If the underlying OpenGL/Window system cannot satisfy all the + features requested in \a format, the nearest subset of features + will be used. After creation, the format() method will return the + actual format obtained. + + Note that after a TQGLContext object has been constructed, \link + create() create()\endlink must be called explicitly to create + the actual OpenGL context. The context will be \link isValid() + invalid\endlink if it was not possible to obtain a GL context at + all. + + \sa format(), isValid() +*/ + +TQGLContext::TQGLContext( const TQGLFormat &format, TQPaintDevice *device ) + : glFormat(format), reqFormat(format) +{ + init( device ); +} + +/*! + \overload + \internal +*/ +TQGLContext::TQGLContext( const TQGLFormat &format ) + : glFormat( format ), reqFormat(format) +{ + init(); +} + +/*! + Destroys the OpenGL context and frees its resources. +*/ + +TQGLContext::~TQGLContext() +{ + reset(); + if ( d ) + delete d; +} + + +/*! + \fn TQGLFormat TQGLContext::format() const + + Returns the frame buffer format that was obtained (this may be a + subset of what was requested). + + \sa requestedFormat() +*/ + +/*! + \fn TQGLFormat TQGLContext::requestedFormat() const + + Returns the frame buffer format that was originally requested in + the constructor or setFormat(). + + \sa format() +*/ + +/*! + Sets a \a format for this context. The context is \link reset() + reset\endlink. + + Call create() to create a new GL context that tries to match the + new format. + + \code + TQGLContext *cx; + // ... + TQGLFormat f; + f.setStereo( TRUE ); + cx->setFormat( f ); + if ( !cx->create() ) + exit(); // no OpenGL support, or cannot render on the specified paintdevice + if ( !cx->format().stereo() ) + exit(); // could not create stereo context + \endcode + + \sa format(), reset(), create() +*/ + +void TQGLContext::setFormat( const TQGLFormat &format ) +{ + reset(); + glFormat = reqFormat = format; +} + +/*! + \internal +*/ +void TQGLContext::setDevice( TQPaintDevice *pDev ) +{ + if ( isValid() ) + reset(); + d->paintDevice = pDev; + if ( d->paintDevice && (d->paintDevice->devType() != TQInternal::Widget + && d->paintDevice->devType() != TQInternal::Pixmap) ) { +#if defined(QT_CHECK_RANGE) + tqWarning( "TQGLContext: Unsupported paint device type" ); +#endif + } +} + +void TQGLContext::init( TQPaintDevice *dev ) +{ + d = new Private; + d->valid = FALSE; +#if defined(TQ_WS_X11) + qt_resolve_gl_symbols(); + gpm = 0; +#endif + setDevice( dev ); +#if defined(TQ_WS_WIN) + dc = 0; + win = 0; + pixelFormatId = 0; + cmap = 0; +#endif +#if defined(TQ_WS_MAC) + d->oldR = TQRect(1, 1, 1, 1); +#endif + d->crWin = FALSE; + d->initDone = FALSE; + d->sharing = FALSE; +} + +/*! + \fn bool TQGLContext::isValid() const + + Returns TRUE if a GL rendering context has been successfully + created; otherwise returns FALSE. +*/ + +/*! + \fn void TQGLContext::setValid( bool valid ) + \internal + + Forces the GL rendering context to be valid. +*/ + +/*! + \fn bool TQGLContext::isSharing() const + + Returns TRUE if display list sharing with another context was + requested in the create() call and the GL system was able to + fulfill this request; otherwise returns FALSE. Note that display + list sharing might not be supported between contexts with + different formats. +*/ + +/*! + \fn bool TQGLContext::deviceIsPixmap() const + + Returns TRUE if the paint device of this context is a pixmap; + otherwise returns FALSE. +*/ + +/*! + \fn bool TQGLContext::windowCreated() const + + Returns TRUE if a window has been created for this context; + otherwise returns FALSE. + + \sa setWindowCreated() +*/ + +/*! + \fn void TQGLContext::setWindowCreated( bool on ) + + If \a on is TRUE the context has had a window created for it. If + \a on is FALSE no window has been created for the context. + + \sa windowCreated() +*/ + +/*! + \fn uint TQGLContext::colorIndex( const TQColor& c ) const + + \internal + + Returns a colormap index for the color c, in ColorIndex mode. Used + by qglColor() and qglClearColor(). +*/ + + +/*! + \fn bool TQGLContext::initialized() const + + Returns TRUE if this context has been initialized, i.e. if + TQGLWidget::initializeGL() has been performed on it; otherwise + returns FALSE. + + \sa setInitialized() +*/ + +/*! + \fn void TQGLContext::setInitialized( bool on ) + + If \a on is TRUE the context has been initialized, i.e. + TQGLContext::setInitialized() has been called on it. If \a on is + FALSE the context has not been initialized. + + \sa initialized() +*/ + +/*! + \fn const TQGLContext* TQGLContext::currentContext() + + Returns the current context, i.e. the context to which any OpenGL + commands will currently be directed. Returns 0 if no context is + current. + + \sa makeCurrent() +*/ + +/*! + \fn TQColor TQGLContext::overlayTransparentColor() const + + If this context is a valid context in an overlay plane, returns + the plane's transparent color. Otherwise returns an \link + TQColor::isValid() invalid \endlink color. + + The returned color's \link TQColor::pixel() pixel \endlink value is + the index of the transparent color in the colormap of the overlay + plane. (Naturally, the color's RGB values are meaningless.) + + The returned TQColor object will generally work as expected only + when passed as the argument to TQGLWidget::qglColor() or + TQGLWidget::qglClearColor(). Under certain circumstances it can + also be used to draw transparent graphics with a TQPainter. See the + examples/opengl/overlay_x11 example for details. +*/ + + +/*! + Creates the GL context. Returns TRUE if it was successful in + creating a valid GL rendering context on the paint device + specified in the constructor; otherwise returns FALSE (i.e. the + context is invalid). + + After successful creation, format() returns the set of features of + the created GL rendering context. + + If \a shareContext points to a valid TQGLContext, this method will + try to establish OpenGL display list sharing between this context + and the \a shareContext. Note that this may fail if the two + contexts have different formats. Use isSharing() to see if sharing + succeeded. + + \warning Implementation note: initialization of C++ class + members usually takes place in the class constructor. TQGLContext + is an exception because it must be simple to customize. The + virtual functions chooseContext() (and chooseVisual() for X11) can + be reimplemented in a subclass to select a particular context. The + problem is that virtual functions are not properly called during + construction (even though this is correct C++) because C++ + constructs class hierarchies from the bottom up. For this reason + we need a create() function. + + \sa chooseContext(), format(), isValid() +*/ + +bool TQGLContext::create( const TQGLContext* shareContext ) +{ + reset(); + d->valid = chooseContext( shareContext ); + return d->valid; +} + + + +/*! + \fn bool TQGLContext::chooseContext( const TQGLContext* shareContext = 0 ) + + This semi-internal function is called by create(). It creates a + system-dependent OpenGL handle that matches the format() of \a + shareContext as closely as possible. + + On Windows, it calls the virtual function choosePixelFormat(), + which finds a matching pixel format identifier. On X11, it calls + the virtual function chooseVisual() which finds an appropriate X + visual. On other platforms it may work differently. +*/ + + +/*! + \fn void TQGLContext::reset() + + Resets the context and makes it invalid. + + \sa create(), isValid() +*/ + + +/*! + \fn void TQGLContext::makeCurrent() + + Makes this context the current OpenGL rendering context. All GL + functions you call operate on this context until another context + is made current. + + In some very rare cases the underlying call may fail. If this + occurs an error message is output to stderr. +*/ + + +/*! + \fn void TQGLContext::swapBuffers() const + + Swaps the screen contents with an off-screen buffer. Only works if + the context is in double buffer mode. + + \sa TQGLFormat::setDoubleBuffer() +*/ + + +/*! + \fn void TQGLContext::doneCurrent() + + Makes no GL context the current context. Normally, you do not need + to call this function; TQGLContext calls it as necessary. +*/ + + +/*! + \fn TQPaintDevice* TQGLContext::device() const + + Returns the paint device set for this context. + + \sa TQGLContext::TQGLContext() +*/ + +/*! + \fn void TQGLContext::generateFontDisplayLists( const TQFont& font, int listBase ) + + Generates a set of 256 display lists for the 256 first characters + in the font \a font. The first list will start at index \a listBase. + + \sa TQGLWidget::renderText() +*/ + + +/***************************************************************************** + TQGLWidget implementation + *****************************************************************************/ + + +/*! + \class TQGLWidget tqgl.h + \brief The TQGLWidget class is a widget for rendering OpenGL graphics. +\if defined(commercial) + It is part of the TQt Enterprise Edition. +\endif + + \ingroup graphics + \ingroup images + \mainclass + \module OpenGL + + TQGLWidget provides functionality for displaying OpenGL* + graphics integrated into a TQt application. It is very simple to + use. You inherit from it and use the subclass like any other + TQWidget, except that instead of drawing the widget's contents + using TQPainter etc. you use the standard OpenGL rendering + commands. + + TQGLWidget provides three convenient virtual functions that you can + reimplement in your subclass to perform the typical OpenGL tasks: + + \list + \i paintGL() - Renders the OpenGL scene. Gets called whenever the widget + needs to be updated. + \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets + called whenever the the widget has been resized (and also when it + is shown for the first time because all newly created widgets get a + resize event automatically). + \i initializeGL() - Sets up the OpenGL rendering context, defines display + lists, etc. Gets called once before the first time resizeGL() or + paintGL() is called. + \endlist + + Here is a rough outline of how a TQGLWidget subclass might look: + + \code + class MyGLDrawer : public TQGLWidget + { + TQ_OBJECT // must include this if you use TQt signals/slots + + public: + MyGLDrawer( TQWidget *parent, const char *name ) + : TQGLWidget(parent, name) {} + + protected: + + void initializeGL() + { + // Set up the rendering context, define display lists etc.: + ... + glClearColor( 0.0, 0.0, 0.0, 0.0 ); + glEnable(GL_DEPTH_TEST); + ... + } + + void resizeGL( int w, int h ) + { + // setup viewport, projection etc.: + glViewport( 0, 0, (GLint)w, (GLint)h ); + ... + glFrustum( ... ); + ... + } + + void paintGL() + { + // draw the scene: + ... + glRotatef( ... ); + glMaterialfv( ... ); + glBegin( GL_QUADS ); + glVertex3f( ... ); + glVertex3f( ... ); + ... + glEnd(); + ... + } + + }; + \endcode + + If you need to trigger a repaint from places other than paintGL() + (a typical example is when using \link TQTimer timers\endlink to + animate scenes), you should call the widget's updateGL() function. + + Your widget's OpenGL rendering context is made current when + paintGL(), resizeGL(), or initializeGL() is called. If you need to + call the standard OpenGL API functions from other places (e.g. in + your widget's constructor or in your own paint functions), you + must call makeCurrent() first. + + TQGLWidget provides functions for requesting a new display \link + TQGLFormat format\endlink and you can also create widgets with + customized rendering \link TQGLContext contexts\endlink. + + You can also share OpenGL display lists between TQGLWidgets (see + the documentation of the TQGLWidget constructors for details). + + \section1 Overlays + + The TQGLWidget creates a GL overlay context in addition to the + normal context if overlays are supported by the underlying system. + + If you want to use overlays, you specify it in the \link TQGLFormat + format\endlink. (Note: Overlay must be requested in the format + passed to the TQGLWidget constructor.) Your GL widget should also + implement some or all of these virtual methods: + + \list + \i paintOverlayGL() + \i resizeOverlayGL() + \i initializeOverlayGL() + \endlist + + These methods work in the same way as the normal paintGL() etc. + functions, except that they will be called when the overlay + context is made current. You can explicitly make the overlay + context current by using makeOverlayCurrent(), and you can access + the overlay context directly (e.g. to ask for its transparent + color) by calling overlayContext(). + + On X servers in which the default visual is in an overlay plane, + non-GL TQt windows can also be used for overlays. See the + examples/opengl/overlay_x11 example program for details. + + * OpenGL is a trademark of Silicon Graphics, Inc. in the + United States and other countries. +*/ + +// ### BCI - fix in 4.0 + +// the display list cache can't be global because display lists are +// tied to the GL contexts for each individual widget + +class TQGLWidgetPrivate +{ +public: + TQMap displayListCache; +}; + +static TQPtrDict * qgl_d_ptr = 0; +static TQSingleCleanupHandler< TQPtrDict > qgl_cleanup_d_ptr; + +static TQGLWidgetPrivate * qgl_d( const TQGLWidget * w ) +{ + if ( !qgl_d_ptr ) { + qgl_d_ptr = new TQPtrDict; + qgl_cleanup_d_ptr.set( &qgl_d_ptr ); + qgl_d_ptr->setAutoDelete( TRUE ); + } + TQGLWidgetPrivate * ret = qgl_d_ptr->find( (void *) w ); + if ( !ret ) { + ret = new TQGLWidgetPrivate; + qgl_d_ptr->replace( (void *) w, ret ); + } + return ret; +} + +void qgl_delete_d( const TQGLWidget * w ) +{ + if ( qgl_d_ptr ) + qgl_d_ptr->remove( (void *) w ); +} + +/*! + Constructs an OpenGL widget with a \a parent widget and a \a name. + + The \link TQGLFormat::defaultFormat() default format\endlink is + used. The widget will be \link isValid() invalid\endlink if the + system has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. + + The \a parent, \a name and widget flag, \a f, arguments are passed + to the TQWidget constructor. + + If the \a shareWidget parameter points to a valid TQGLWidget, this + widget will share OpenGL display lists with \a shareWidget. If + this widget and \a shareWidget have different \link format() + formats\endlink, display list sharing may fail. You can check + whether display list sharing succeeded by calling isSharing(). + + The initialization of OpenGL rendering state, etc. should be done + by overriding the initializeGL() function, rather than in the + constructor of your TQGLWidget subclass. + + \sa TQGLFormat::defaultFormat() +*/ + +TQGLWidget::TQGLWidget( TQWidget *parent, const char *name, + const TQGLWidget* shareWidget, WFlags f ) + : TQWidget( parent, name, f | TQt::WWinOwnDC | TQt::WNoAutoErase ) +{ + init( new TQGLContext(TQGLFormat::defaultFormat(), this), shareWidget ); +} + + +/*! + Constructs an OpenGL widget with parent \a parent, called \a name. + + The \a format argument specifies the desired \link TQGLFormat + rendering options \endlink. If the underlying OpenGL/Window system + cannot satisfy all the features requested in \a format, the + nearest subset of features will be used. After creation, the + format() method will return the actual format obtained. + + The widget will be \link isValid() invalid\endlink if the system + has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. + + The \a parent, \a name and widget flag, \a f, arguments are passed + to the TQWidget constructor. + + If the \a shareWidget parameter points to a valid TQGLWidget, this + widget will share OpenGL display lists with \a shareWidget. If + this widget and \a shareWidget have different \link format() + formats\endlink, display list sharing may fail. You can check + whether display list sharing succeeded by calling isSharing(). + + The initialization of OpenGL rendering state, etc. should be done + by overriding the initializeGL() function, rather than in the + constructor of your TQGLWidget subclass. + + \sa TQGLFormat::defaultFormat(), isValid() +*/ + +TQGLWidget::TQGLWidget( const TQGLFormat &format, TQWidget *parent, + const char *name, const TQGLWidget* shareWidget, + WFlags f ) + : TQWidget( parent, name, f | TQt::WWinOwnDC | TQt::WNoAutoErase ) +{ + init( new TQGLContext(format, this), shareWidget ); +} + +/*! + Constructs an OpenGL widget with parent \a parent, called \a name. + + The \a context argument is a pointer to the TQGLContext that + you wish to be bound to this widget. This allows you to pass in + your own TQGLContext sub-classes. + + The widget will be \link isValid() invalid\endlink if the system + has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. + + The \a parent, \a name and widget flag, \a f, arguments are passed + to the TQWidget constructor. + + If the \a shareWidget parameter points to a valid TQGLWidget, this + widget will share OpenGL display lists with \a shareWidget. If + this widget and \a shareWidget have different \link format() + formats\endlink, display list sharing may fail. You can check + whether display list sharing succeeded by calling isSharing(). + + The initialization of OpenGL rendering state, etc. should be done + by overriding the initializeGL() function, rather than in the + constructor of your TQGLWidget subclass. + + \sa TQGLFormat::defaultFormat(), isValid() +*/ +TQGLWidget::TQGLWidget( TQGLContext *context, TQWidget *parent, + const char *name, const TQGLWidget *shareWidget, WFlags f ) + : TQWidget( parent, name, f | TQt::WWinOwnDC | TQt::WNoAutoErase ) +{ + init( context, shareWidget ); +} + +/*! + Destroys the widget. +*/ + +TQGLWidget::~TQGLWidget() +{ +#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT) + bool doRelease = ( glcx && glcx->windowCreated() ); +#endif + qgl_delete_d( this ); + delete glcx; +#if defined(Q_WGL) + delete olcx; +#endif +#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT) + if ( doRelease ) + glXReleaseBuffersMESA( x11Display(), winId() ); +#endif +#if defined(TQ_WS_MAC) + if(gl_pix) { + delete gl_pix; + gl_pix = NULL; + } +#endif + cleanupColormaps(); +} + + + + + +/*! + \fn TQGLFormat TQGLWidget::format() const + + Returns the format of the contained GL rendering context. +*/ + +/*! + \fn bool TQGLWidget::doubleBuffer() const + + Returns TRUE if the contained GL rendering context has double + buffering; otherwise returns FALSE. + + \sa TQGLFormat::doubleBuffer() +*/ + +/*! + \fn void TQGLWidget::setAutoBufferSwap( bool on ) + + If \a on is TRUE automatic GL buffer swapping is switched on; + otherwise it is switched off. + + If \a on is TRUE and the widget is using a double-buffered format, + the background and foreground GL buffers will automatically be + swapped after each paintGL() call. + + The buffer auto-swapping is on by default. + + \sa autoBufferSwap(), doubleBuffer(), swapBuffers() +*/ + +/*! + \fn bool TQGLWidget::autoBufferSwap() const + + Returns TRUE if the widget is doing automatic GL buffer swapping; + otherwise returns FALSE. + + \sa setAutoBufferSwap() +*/ + +/*! + \fn bool TQGLWidget::isValid() const + + Returns TRUE if the widget has a valid GL rendering context; + otherwise returns FALSE. A widget will be invalid if the system + has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink. +*/ + +bool TQGLWidget::isValid() const +{ + return glcx->isValid(); +} + +/*! + \fn bool TQGLWidget::isSharing() const + + Returns TRUE if display list sharing with another TQGLWidget was + requested in the constructor, and the GL system was able to + provide it; otherwise returns FALSE. The GL system may fail to + provide display list sharing if the two TQGLWidgets use different + formats. + + \sa format() +*/ + +bool TQGLWidget::isSharing() const +{ + return glcx->isSharing(); +} + +/*! + \fn void TQGLWidget::makeCurrent() + + Makes this widget the current widget for OpenGL operations, i.e. + makes the widget's rendering context the current OpenGL rendering + context. +*/ + +void TQGLWidget::makeCurrent() +{ +#if defined( TQ_WS_MAC ) + macInternalDoubleBuffer(); //make sure the correct context is used +#endif + glcx->makeCurrent(); +} + +/*! + \fn void TQGLWidget::doneCurrent() + + Makes no GL context the current context. Normally, you do not need + to call this function; TQGLContext calls it as necessary. However, + it may be useful in multithreaded environments. +*/ + +void TQGLWidget::doneCurrent() +{ + glcx->doneCurrent(); +} + +/*! + \fn void TQGLWidget::swapBuffers() + + Swaps the screen contents with an off-screen buffer. This only + works if the widget's format specifies double buffer mode. + + Normally, there is no need to explicitly call this function + because it is done automatically after each widget repaint, i.e. + each time after paintGL() has been executed. + + \sa doubleBuffer(), setAutoBufferSwap(), TQGLFormat::setDoubleBuffer() +*/ + +void TQGLWidget::swapBuffers() +{ + glcx->swapBuffers(); +#if defined(TQ_WS_MAC) + if(macInternalDoubleBuffer() && gl_pix) + bitBlt(this, 0, 0, gl_pix); +#endif +} + + +/*! + \fn const TQGLContext* TQGLWidget::overlayContext() const + + Returns the overlay context of this widget, or 0 if this widget + has no overlay. + + \sa context() +*/ + + + +/*! + \fn void TQGLWidget::makeOverlayCurrent() + + Makes the overlay context of this widget current. Use this if you + need to issue OpenGL commands to the overlay context outside of + initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL(). + + Does nothing if this widget has no overlay. + + \sa makeCurrent() +*/ + + +/* + \obsolete + + Sets a new format for this widget. + + If the underlying OpenGL/Window system cannot satisfy all the + features requested in \a format, the nearest subset of features will + be used. After creation, the format() method will return the actual + rendering context format obtained. + + The widget will be assigned a new TQGLContext, and the initializeGL() + function will be executed for this new context before the first + resizeGL() or paintGL(). + + This method will try to keep any existing display list sharing with + other TQGLWidgets, but it may fail. Use isSharing() to test. + + \sa format(), isSharing(), isValid() +*/ + +void TQGLWidget::setFormat( const TQGLFormat &format ) +{ + setContext( new TQGLContext(format,this) ); +} + + + + +/*! + \fn const TQGLContext *TQGLWidget::context() const + + Returns the context of this widget. + + It is possible that the context is not valid (see isValid()), for + example, if the underlying hardware does not support the format + attributes that were requested. +*/ + +/* + \obsolete + + \fn void TQGLWidget::setContext( TQGLContext *context, + const TQGLContext* shareContext, + bool deleteOldContext ) + + Sets a new context for this widget. The TQGLContext \a context must + be created using \e new. TQGLWidget will delete \a context when + another context is set or when the widget is destroyed. + + If \a context is invalid, TQGLContext::create() is performed on + it. The initializeGL() function will then be executed for the new + context before the first resizeGL() or paintGL(). + + If \a context is invalid, this method will try to keep any existing + display list sharing with other TQGLWidgets this widget currently + has, or (if \a shareContext points to a valid context) start display + list sharing with that context, but it may fail. Use isSharing() to + test. + + If \a deleteOldContext is TRUE (the default), the existing context + will be deleted. You may use FALSE here if you have kept a pointer + to the old context (as returned by context()), and want to restore + that context later. + + \sa context(), isSharing() +*/ + + + +/*! + \fn void TQGLWidget::updateGL() + + Updates the widget by calling glDraw(). +*/ + +void TQGLWidget::updateGL() +{ + glDraw(); +} + + +/*! + \fn void TQGLWidget::updateOverlayGL() + + Updates the widget's overlay (if any). Will cause the virtual + function paintOverlayGL() to be executed. + + The widget's rendering context will become the current context and + initializeGL() will be called if it hasn't already been called. +*/ + + +/*! + This virtual function is called once before the first call to + paintGL() or resizeGL(), and then once whenever the widget has + been assigned a new TQGLContext. Reimplement it in a subclass. + + This function should set up any required OpenGL context rendering + flags, defining display lists, etc. + + There is no need to call makeCurrent() because this has already + been done when this function is called. +*/ + +void TQGLWidget::initializeGL() +{ +} + + +/*! + This virtual function is called whenever the widget needs to be + painted. Reimplement it in a subclass. + + There is no need to call makeCurrent() because this has already + been done when this function is called. +*/ + +void TQGLWidget::paintGL() +{ +} + + +/*! + \fn void TQGLWidget::resizeGL( int width , int height ) + + This virtual function is called whenever the widget has been + resized. The new size is passed in \a width and \a height. + Reimplement it in a subclass. + + There is no need to call makeCurrent() because this has already + been done when this function is called. +*/ + +void TQGLWidget::resizeGL( int, int ) +{ +} + + + +/*! + This virtual function is used in the same manner as initializeGL() + except that it operates on the widget's overlay context instead of + the widget's main context. This means that initializeOverlayGL() + is called once before the first call to paintOverlayGL() or + resizeOverlayGL(). Reimplement it in a subclass. + + This function should set up any required OpenGL context rendering + flags, defining display lists, etc. for the overlay context. + + There is no need to call makeOverlayCurrent() because this has + already been done when this function is called. +*/ + +void TQGLWidget::initializeOverlayGL() +{ +} + + +/*! + This virtual function is used in the same manner as paintGL() + except that it operates on the widget's overlay context instead of + the widget's main context. This means that paintOverlayGL() is + called whenever the widget's overlay needs to be painted. + Reimplement it in a subclass. + + There is no need to call makeOverlayCurrent() because this has + already been done when this function is called. +*/ + +void TQGLWidget::paintOverlayGL() +{ +} + + +/*! + \fn void TQGLWidget::resizeOverlayGL( int width , int height ) + + This virtual function is used in the same manner as paintGL() + except that it operates on the widget's overlay context instead of + the widget's main context. This means that resizeOverlayGL() is + called whenever the widget has been resized. The new size is + passed in \a width and \a height. Reimplement it in a subclass. + + There is no need to call makeOverlayCurrent() because this has + already been done when this function is called. +*/ + +void TQGLWidget::resizeOverlayGL( int, int ) +{ +} + + + + +/*! + Handles paint events. Will cause the virtual paintGL() function to + be called. + + The widget's rendering context will become the current context and + initializeGL() will be called if it hasn't already been called. +*/ + +void TQGLWidget::paintEvent( TQPaintEvent * ) +{ + glDraw(); + updateOverlayGL(); +} + + +/*! + \fn void TQGLWidget::resizeEvent( TQResizeEvent * ) + + Handles resize events. Calls the virtual function resizeGL(). +*/ + + +/*! + \fn void TQGLWidget::setMouseTracking( bool enable ) + + \reimp +*/ + + +/*! + Renders the current scene on a pixmap and returns the pixmap. + + You can use this method on both visible and invisible TQGLWidgets. + + This method will create a pixmap and a temporary TQGLContext to + render on the pixmap. It will then call initializeGL(), + resizeGL(), and paintGL() on this context. Finally, the widget's + original GL context is restored. + + The size of the pixmap will be \a w pixels wide and \a h pixels + high unless one of these parameters is 0 (the default), in which + case the pixmap will have the same size as the widget. + + If \a useContext is TRUE, this method will try to be more + efficient by using the existing GL context to render the pixmap. + The default is FALSE. Only use TRUE if you understand the risks. + + Overlays are not rendered onto the pixmap. + + If the GL rendering context and the desktop have different bit + depths, the result will most likely look surprising. + + Note that the creation of display lists, modifications of the view + frustum etc. should be done from within initializeGL(). If this is + not done, the temporary TQGLContext will not be initialized + properly, and the rendered pixmap may be incomplete/corrupted. +*/ + +TQPixmap TQGLWidget::renderPixmap( int w, int h, bool useContext ) +{ + TQSize sz = size(); + if ( (w > 0) && (h > 0) ) + sz = TQSize( w, h ); + +#if defined(TQ_WS_X11) + TQPixmap pm( sz.width(), sz.height(), x11Depth() ); + bool needConversion = x11Visual() != TQPaintDevice::x11AppVisual(); + + // make sure the pixmap uses the same visual as the widget itself + if ( needConversion ) { + TQPaintDeviceX11Data* xd = pm.getX11Data( TRUE ); + xd->x_depth = x11Depth(); + xd->x_visual = (Visual *) x11Visual(); + pm.setX11Data( xd ); + } +#else + TQPixmap pm; + pm.resize( sz ); +#endif + + glcx->doneCurrent(); + + bool success = TRUE; + + if ( useContext && isValid() && renderCxPm( &pm ) ) + return pm; + + TQGLFormat fmt = glcx->requestedFormat(); + fmt.setDirectRendering( FALSE ); // Direct is unlikely to work + fmt.setDoubleBuffer( FALSE ); // We don't need dbl buf + + TQGLContext* ocx = glcx; + bool wasCurrent = (TQGLContext::currentContext() == ocx ); + ocx->doneCurrent(); + glcx = new TQGLContext( fmt, &pm ); + glcx->create(); + + if ( glcx->isValid() ) + updateGL(); + else + success = FALSE; + + delete glcx; + glcx = ocx; + + if ( wasCurrent ) + ocx->makeCurrent(); + + if ( success ) { +#if defined(TQ_WS_X11) + if ( needConversion ) { + TQImage image = pm.convertToImage(); + TQPixmap p; + p = image; + return p; + } +#endif + return pm; + } else + return TQPixmap(); +} + + + +/*! + Returns an image of the frame buffer. If \a withAlpha is TRUE the + alpha channel is included. + + Depending on your hardware, you can explicitly select which color + buffer to grab with a glReadBuffer() call before calling this + function. +*/ +TQImage TQGLWidget::grabFrameBuffer( bool withAlpha ) +{ +#if defined( TQ_WS_MAC ) + if(dblbuf == macInternalDoubleBuffer(FALSE) && gl_pix) //why not optimize? + return ((TQPixmap*)gl_pix)->convertToImage(); +#endif + makeCurrent(); + TQImage res; + int w = width(); + int h = height(); + if ( format().rgba() ) { + res = TQImage( w, h, 32 ); + glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, res.bits() ); + if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { + // OpenGL gives RGBA; TQt wants ARGB + uint *p = (uint*)res.bits(); + uint *end = p + w*h; + if ( withAlpha && format().alpha() ) { + while ( p < end ) { + uint a = *p << 24; + *p = (*p >> 8) | a; + p++; + } + } + else { + while ( p < end ) + *p++ >>= 8; + } + } + else { + // OpenGL gives ABGR (i.e. RGBA backwards); TQt wants ARGB + res = res.swapRGB(); + } + res.setAlphaBuffer( withAlpha && format().alpha() ); + } + else { +#if defined (TQ_WS_WIN) + res = TQImage( w, h, 8 ); + glReadPixels( 0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, + res.bits() ); + int palSize = 0; + const TQRgb* pal = TQColor::palette( &palSize ); + if ( pal && palSize ) { + res.setNumColors( palSize ); + for ( int i = 0; i < palSize; i++ ) + res.setColor( i, pal[i] ); + } +#endif + } + + return res.mirror(); +} + + + +/*! + Initializes OpenGL for this widget's context. Calls the virtual + function initializeGL(). +*/ + +void TQGLWidget::glInit() +{ + if ( !isValid() ) + return; + makeCurrent(); + initializeGL(); + glcx->setInitialized( TRUE ); +} + + +/*! + Executes the virtual function paintGL(). + + The widget's rendering context will become the current context and + initializeGL() will be called if it hasn't already been called. +*/ + +void TQGLWidget::glDraw() +{ + if ( !isValid() ) + return; + makeCurrent(); + if ( glcx->deviceIsPixmap() ) + glDrawBuffer( GL_FRONT ); + if ( !glcx->initialized() ) { + glInit(); + TQPaintDeviceMetrics dm( glcx->device() ); + resizeGL( dm.width(), dm.height() ); // New context needs this "resize" + } + paintGL(); + if ( doubleBuffer() ) { + if ( autoSwap ) + swapBuffers(); + } else { + glFlush(); +#if defined( TQ_WS_MAC ) + if(dblbuf && gl_pix) + bitBlt(this, 0, 0, gl_pix); +#endif + } +} + + +/*! + Convenience function for specifying a drawing color to OpenGL. + Calls glColor3 (in RGBA mode) or glIndex (in color-index mode) + with the color \a c. Applies to the current GL context. + + \sa qglClearColor(), TQGLContext::currentContext(), TQColor +*/ + +void TQGLWidget::qglColor( const TQColor& c ) const +{ + const TQGLContext* ctx = TQGLContext::currentContext(); + if ( ctx ) { + if ( ctx->format().rgba() ) + glColor3ub( c.red(), c.green(), c.blue() ); + + else if ( ctx->device() == context()->device() + && !cmap.isEmpty() ) { // TQGLColormap in use? + int i = cmap.find( c.rgb() ); + if ( i < 0 ) + i = cmap.findNearest( c.rgb() ); + glIndexi( i ); + } else + glIndexi( ctx->colorIndex( c ) ); + } +} + +/*! + Convenience function for specifying the clearing color to OpenGL. + Calls glClearColor (in RGBA mode) or glClearIndex (in color-index + mode) with the color \a c. Applies to the current GL context. + + \sa qglColor(), TQGLContext::currentContext(), TQColor +*/ + +void TQGLWidget::qglClearColor( const TQColor& c ) const +{ + const TQGLContext* ctx = TQGLContext::currentContext(); + if ( ctx ) { + if ( ctx->format().rgba() ) + glClearColor( (GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0, + (GLfloat)c.blue() / 255.0, (GLfloat) 0.0 ); + else if ( ctx->device() == context()->device() + && !cmap.isEmpty() ) { // TQGLColormap in use? + int i = cmap.find( c.rgb() ); + if ( i < 0 ) + i = cmap.findNearest( c.rgb() ); + glClearIndex( i ); + } else + glClearIndex( ctx->colorIndex( c ) ); + } +} + + +/*! + Converts the image \a img into the unnamed format expected by + OpenGL functions such as glTexImage2D(). The returned image is not + usable as a TQImage, but TQImage::width(), TQImage::height() and + TQImage::bits() may be used with OpenGL. The following few lines + are from the texture example. Most of the code is irrelevant, so + we just quote the relevant bits: + + \quotefile opengl/texture/gltexobj.cpp + \skipto tex1 + \printline tex1 + \printline gllogo.bmp + + We create \e tex1 (and another variable) for OpenGL, and load a real + image into \e buf. + + \skipto convertToGLFormat + \printline convertToGLFormat + + A few lines later, we convert \e buf into OpenGL format and store it + in \e tex1. + + \skipto glTexImage2D + \printline glTexImage2D + \printline tex1.bits + + Note the dimension restrictions for texture images as described in + the glTexImage2D() documentation. The width must be 2^m + 2*border + and the height 2^n + 2*border where m and n are integers and + border is either 0 or 1. + + Another function in the same example uses \e tex1 with OpenGL. +*/ + + +TQImage TQGLWidget::convertToGLFormat( const TQImage& img ) +{ + TQImage res = img.convertDepth( 32 ); + res = res.mirror(); + + if ( TQImage::systemByteOrder() == TQImage::BigEndian ) { + // TQt has ARGB; OpenGL wants RGBA + for ( int i=0; i < res.height(); i++ ) { + uint *p = (uint*)res.scanLine( i ); + uint *end = p + res.width(); + while ( p < end ) { + *p = (*p << 8) | ((*p >> 24) & 0xFF); + p++; + } + } + } + else { + // TQt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards) + res = res.swapRGB(); + } + return res; +} + + +/*! + \fn TQGLColormap & TQGLWidget::colormap() const + + Returns the colormap for this widget. + + Usually it is only top-level widgets that can have different + colormaps installed. Asking for the colormap of a child widget + will return the colormap for the child's top-level widget. + + If no colormap has been set for this widget, the TQColormap + returned will be empty. + + \sa setColormap() +*/ + +/*! + \fn void TQGLWidget::setColormap( const TQGLColormap & cmap ) + + Set the colormap for this widget to \a cmap. Usually it is only + top-level widgets that can have colormaps installed. + + \sa colormap() +*/ + +int TQGLWidget::displayListBase( const TQFont & fnt, int listBase ) +{ + int base; + + TQGLWidgetPrivate * d = qgl_d( this ); + if ( !d || !glcx ) { // this can't happen unless we run out of mem + return 0; + } + + // always regenerate font disp. lists for pixmaps - hw accelerated + // contexts can't handle this otherwise + bool regenerate = glcx->deviceIsPixmap(); + +#if 0 // TQT_NO_XFTFREETYPE + // font color needs to be part of the font cache key when using + // antialiased fonts since one set of glyphs needs to be generated + // for each font color + TQString color_key; + if (fnt.styleStrategy() != TQFont::NoAntialias) { + GLfloat color[4]; + glGetFloatv(GL_CURRENT_COLOR, color); + color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]); + } + TQString key = fnt.key() + color_key + TQString::number((int) regenerate); +#else + TQString key = fnt.key() + TQString::number((int) regenerate); +#endif + + if ( !regenerate && (d->displayListCache.find( key ) != d->displayListCache.end()) ) { + base = d->displayListCache[ key ]; + } else { + int maxBase = listBase - 256; + TQMapConstIterator it; + for ( it = d->displayListCache.begin(); it != d->displayListCache.end(); ++it ) { + if ( maxBase < it.data() ) { + maxBase = it.data(); + } + } + maxBase += 256; + glcx->generateFontDisplayLists( fnt, maxBase ); + d->displayListCache[ key ] = maxBase; + base = maxBase; + } + return base; +} + +/*! + Renders the string \a str into the GL context of this widget. + + \a x and \a y are specified in window coordinates, with the origin + in the upper left-hand corner of the window. If \a fnt is not + specified, the currently set application font will be used to + render the string. To change the color of the rendered text you can + use the glColor() call (or the qglColor() convenience function), + just before the renderText() call. Note that if you have + GL_LIGHTING enabled, the string will not appear in the color you + want. You should therefore switch lighting off before using + renderText(). + + \a listBase specifies the index of the first display list that is + generated by this function. The default value is 2000. 256 display + lists will be generated, one for each of the first 256 characters + in the font that is used to render the string. If several fonts are + used in the same widget, the display lists for these fonts will + follow the last generated list. You would normally not have to + change this value unless you are using lists in the same range. The + lists are deleted when the widget is destroyed. + + Note: This function only works reliably with ASCII strings. +*/ + +void TQGLWidget::renderText( int x, int y, const TQString & str, const TQFont & fnt, int listBase ) +{ + if (str.isEmpty()) + return; + makeCurrent(); + glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT | GL_CURRENT_BIT ); + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0, width(), height(), 0, -1, 1 ); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glRasterPos2i( 0, 0 ); + glBitmap(0, 0, 0, 0, x, -y, NULL); + glListBase( displayListBase( fnt, listBase ) ); + const char *cstr = str.latin1(); + glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr ); + + // restore the matrix stacks and GL state + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glPopAttrib(); +} + +/*! \overload + + \a x, \a y and \a z are specified in scene or object coordinates + relative to the currently set projection and model matrices. This + can be useful if you want to annotate models with text labels and + have the labels move with the model as it is rotated etc. +*/ +void TQGLWidget::renderText( double x, double y, double z, const TQString & str, const TQFont & fnt, + int listBase ) +{ + if (str.isEmpty()) + return; + makeCurrent(); + glRasterPos3d( x, y, z ); + glPushAttrib( GL_LIST_BIT ); + glListBase( displayListBase( fnt, listBase ) ); + const char *cstr = str.latin1(); + glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr ); + glPopAttrib(); +} + +/***************************************************************************** + TQGL classes overview documentation. + *****************************************************************************/ + +/*! + +\page opengl.html + +\title TQt OpenGL 3D Graphics + +\if defined(commercial) +This module is part of the \link commercialeditions.html TQt Enterprise +Edition\endlink. +\endif + +\section1 Introduction + +OpenGL is a standard API for rendering 3D graphics. + +OpenGL only deals with 3D rendering and provides little or no support +for GUI programming issues. The user interface for an +OpenGL* application must be created with another toolkit, +such as Motif on the X platform, Microsoft Foundation Classes (MFC) +under Windows, or TQt on \e both platforms. + +The TQt OpenGL module makes it easy to use OpenGL in TQt applications. +It provides an OpenGL widget class that can be used just like any +other TQt widget, except that it opens an OpenGL display buffer where +you can use the OpenGL API to render the contents. + +The TQt OpenGL module is implemented as a platform-independent TQt/C++ +wrapper around the platform-dependent GLX, WGL, or AGL C APIs. The +functionality provided is very similar to Mark Kilgard's GLUT library, +but with much more non-OpenGL-specific GUI functionality, i.e. the +whole TQt API. + +\section1 Installation + +When you install TQt for X11, the configure script will autodetect if +OpenGL headers and libraries are installed on your system, and if so, +it will include the TQt OpenGL module in the TQt library. (If your +OpenGL headers or libraries are placed in a non-standard directory, +you may need to change the QMAKE_INCDIR_OPENGL and/or +QMAKE_LIBDIR_OPENGL in the config file for your system). Some +configurations require threading to be enabled for OpenGL, so if +OpenGL is not detected, try \c{configure -thread}. + +When you install TQt for Windows, the TQt OpenGL module is always +included. + +The TQt OpenGL module is not licensed for use with the TQt Professional +Edition. Consider upgrading to the TQt Enterprise Edition if you +require OpenGL support. + +Note about using Mesa on X11: Mesa versions earlier than 3.1 would use +the name "MesaGL" and "MesaGLU" for the libraries, instead of "GL" and +"GLU". If you want to use a pre-3.1 version of Mesa, you must change +the Makefiles to use these library names instead. The easiest way to +do this is to edit the QMAKE_LIBS_OPENGL line in the config file you +are using, changing "-lGL -lGLU" to "-lMesaGL -lMesaGLU"; then run +"configure" again. + +\section1 The TQGL Classes + +The OpenGL support classes in TQt are: +\list +\i \link TQGLWidget TQGLWidget\endlink: An easy-to-use TQt + widget for rendering OpenGL scenes. +\i \link TQGLContext TQGLContext\endlink: Encapsulates an OpenGL rendering context. +\i \link TQGLFormat TQGLFormat\endlink: Specifies the +display format of a rendering context. +\i \link TQGLColormap TQGLColormap\endlink: Handles indexed +colormaps in GL-index mode. +\endlist + +Many applications only need the high-level TQGLWidget class. The other +TQGL classes provide advanced features. X11 users might like to read +the notes on \link opengl-x11-overlays.html overlays\endlink. + +See also the \link opengl-examples.html OpenGL examples\endlink. + +The TQGL documentation assumes that you are familiar with OpenGL +programming. If you're new to the subject a good starting point is +\l{http://www.opengl.org/}. + + +* OpenGL is a trademark of Silicon Graphics, Inc. in the +United States and other countries. + +*/ + +/*! + \enum TQGL::FormatOption + + This enum specifies the format options. + + \value DoubleBuffer + \value DepthBuffer + \value Rgba + \value AlphaChannel + \value AccumBuffer + \value StencilBuffer + \value StereoBuffers + \value DirectRendering + \value HasOverlay + \value SingleBuffer + \value NoDepthBuffer + \value ColorIndex + \value NoAlphaChannel + \value NoAccumBuffer + \value NoStencilBuffer + \value NoStereoBuffers + \value IndirectRendering + \value NoOverlay +*/ diff --git a/src/opengl/tqgl.h b/src/opengl/tqgl.h new file mode 100644 index 000000000..53bdd0e5a --- /dev/null +++ b/src/opengl/tqgl.h @@ -0,0 +1,541 @@ +/**************************************************************************** +** +** Definition of OpenGL classes for TQt +** +** Created : 970112 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the opengl 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 TQGL_H +#define TQGL_H + +#ifndef QT_H +#include "tqwidget.h" +#include "tqglcolormap.h" +#endif // QT_H + +#if !defined( TQT_MODULE_OPENGL ) || defined( QT_LICENSE_PROFESSIONAL ) +#define TQM_EXPORT_OPENGL +#else +#define TQM_EXPORT_OPENGL TQ_EXPORT +#endif + +#ifndef TQT_NO_COMPAT +#define TQGL_VERSION 450 +#define TQGL_VERSION_STR "4.5" +TQM_EXPORT_OPENGL inline const char *qGLVersion() { + tqObsolete( 0, "qGLVersion", "qVersion" ); + return TQGL_VERSION_STR; +} +#endif + +#if defined(TQ_WS_WIN) +# include "qt_windows.h" +#endif + +#if defined(TQ_WS_MAC) +#if !defined( TQMAC_OPENGL_DOUBLEBUFFER ) +/* This macro is different now. If the macro is not defined TQGLWidget will + * try to determine when you need double buffering. If set to 0 it will + * never double buffer and *can* be acclerated. If set to 1 (the default) + * it will always double buffer. Unlike before the value of this macro does + * not upset binary compatability either. */ +#if QT_MACOSX_VERSION >= 0x1020 +# define TQMAC_OPENGL_DOUBLEBUFFER 0 +#endif +#endif +# include +# include +#else +# include +# include +#endif + +#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC) +class TQGLCmap; +#endif + +class TQPixmap; +#if defined(TQ_WS_X11) +class TQGLOverlayWidget; +#endif + +// Namespace class: +class TQM_EXPORT_OPENGL TQGL +{ +public: + enum FormatOption { + DoubleBuffer = 0x0001, + DepthBuffer = 0x0002, + Rgba = 0x0004, + AlphaChannel = 0x0008, + AccumBuffer = 0x0010, + StencilBuffer = 0x0020, + StereoBuffers = 0x0040, + DirectRendering = 0x0080, + HasOverlay = 0x0100, + SingleBuffer = DoubleBuffer << 16, + NoDepthBuffer = DepthBuffer << 16, + ColorIndex = Rgba << 16, + NoAlphaChannel = AlphaChannel << 16, + NoAccumBuffer = AccumBuffer << 16, + NoStencilBuffer = StencilBuffer << 16, + NoStereoBuffers = StereoBuffers << 16, + IndirectRendering = DirectRendering << 16, + NoOverlay = HasOverlay << 16 + }; +}; + + + +class TQM_EXPORT_OPENGL TQGLFormat : public TQGL +{ +public: + TQGLFormat(); + TQGLFormat( int options, int plane = 0 ); + + bool doubleBuffer() const; + void setDoubleBuffer( bool enable ); + bool depth() const; + void setDepth( bool enable ); + bool rgba() const; + void setRgba( bool enable ); + bool alpha() const; + void setAlpha( bool enable ); + bool accum() const; + void setAccum( bool enable ); + bool stencil() const; + void setStencil( bool enable ); + bool stereo() const; + void setStereo( bool enable ); + bool directRendering() const; + void setDirectRendering( bool enable ); + bool hasOverlay() const; + void setOverlay( bool enable ); + + int plane() const; + void setPlane( int plane ); + + void setOption( FormatOption opt ); + bool testOption( FormatOption opt ) const; + + static TQGLFormat defaultFormat(); + static void setDefaultFormat( const TQGLFormat& f ); + + static TQGLFormat defaultOverlayFormat(); + static void setDefaultOverlayFormat( const TQGLFormat& f ); + + static bool hasOpenGL(); + static bool hasOpenGLOverlays(); + + friend TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&, + const TQGLFormat& ); + friend TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&, + const TQGLFormat& ); +private: + uint opts; + int pln; +}; + + +TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&, const TQGLFormat& ); +TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&, const TQGLFormat& ); + +class TQM_EXPORT_OPENGL TQGLContext : public TQGL +{ +public: + TQGLContext( const TQGLFormat& format, TQPaintDevice* device ); + TQGLContext( const TQGLFormat& format ); + virtual ~TQGLContext(); + + virtual bool create( const TQGLContext* shareContext = 0 ); + bool isValid() const; + bool isSharing() const; + virtual void reset(); + + TQGLFormat format() const; + TQGLFormat requestedFormat() const; + virtual void setFormat( const TQGLFormat& format ); + + virtual void makeCurrent(); + virtual void swapBuffers() const; + + TQPaintDevice* device() const; + + TQColor overlayTransparentColor() const; + + static const TQGLContext* currentContext(); + +protected: + virtual bool chooseContext( const TQGLContext* shareContext = 0 ); + virtual void doneCurrent(); // ### 4.0: make this public - needed for multithreading stuff + +#if defined(TQ_WS_WIN) + virtual int choosePixelFormat( void* pfd, HDC pdc ); +#endif +#if defined(TQ_WS_X11) + virtual void* tryVisual( const TQGLFormat& f, int bufDepth = 1 ); + virtual void* chooseVisual(); +#endif +#if defined(TQ_WS_MAC) + virtual void* chooseMacVisual(GDHandle); +#endif + + bool deviceIsPixmap() const; + bool windowCreated() const; + void setWindowCreated( bool on ); + bool initialized() const; + void setInitialized( bool on ); + void generateFontDisplayLists( const TQFont & fnt, int listBase ); + + uint colorIndex( const TQColor& c ) const; + void setValid( bool valid ); + void setDevice( TQPaintDevice *pDev ); + +protected: +#if defined(TQ_WS_WIN) + HGLRC rc; + HDC dc; + WId win; + int pixelFormatId; + TQGLCmap* cmap; +#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC) + void* vi; + void* cx; +#if defined(TQ_WS_X11) + TQ_UINT32 gpm; +#endif +#endif + TQGLFormat glFormat; + TQGLFormat reqFormat; + static TQGLContext* currentCtx; + +private: + void init( TQPaintDevice *dev = 0 ); + class Private { + public: + bool valid; + bool sharing; + bool initDone; + bool crWin; + TQPaintDevice* paintDevice; + TQColor transpColor; +#ifdef TQ_WS_MAC + TQRect oldR; +#endif + }; + Private* d; + + friend class TQGLWidget; +#ifdef TQ_WS_MAC + void fixBufferRect(); +#endif + +private: // Disabled copy constructor and operator= + TQGLContext() {} + TQGLContext( const TQGLContext& ) {} + TQGLContext& operator=( const TQGLContext& ) { return *this; } +}; + + + + +class TQM_EXPORT_OPENGL TQGLWidget : public TQWidget, public TQGL +{ + TQ_OBJECT +public: + TQGLWidget( TQWidget* parent=0, const char* name=0, + const TQGLWidget* shareWidget = 0, WFlags f=0 ); + TQGLWidget( TQGLContext *context, TQWidget* parent, const char* name=0, + const TQGLWidget* shareWidget = 0, WFlags f=0 ); + TQGLWidget( const TQGLFormat& format, TQWidget* parent=0, const char* name=0, + const TQGLWidget* shareWidget = 0, WFlags f=0 ); + ~TQGLWidget(); + + void qglColor( const TQColor& c ) const; + void qglClearColor( const TQColor& c ) const; + + bool isValid() const; + bool isSharing() const; + virtual void makeCurrent(); + void doneCurrent(); + + bool doubleBuffer() const; + virtual void swapBuffers(); + + TQGLFormat format() const; +#ifndef Q_QDOC + virtual void setFormat( const TQGLFormat& format ); +#endif + + const TQGLContext* context() const; +#ifndef Q_QDOC + virtual void setContext( TQGLContext* context, + const TQGLContext* shareContext = 0, + bool deleteOldContext = TRUE ); +#endif + + virtual TQPixmap renderPixmap( int w = 0, int h = 0, + bool useContext = FALSE ); + virtual TQImage grabFrameBuffer( bool withAlpha = FALSE ); + + virtual void makeOverlayCurrent(); + const TQGLContext* overlayContext() const; + + static TQImage convertToGLFormat( const TQImage& img ); + + void setMouseTracking( bool enable ); + virtual void reparent( TQWidget* parent, WFlags f, const TQPoint& p, + bool showIt = FALSE ); + + const TQGLColormap & colormap() const; + void setColormap( const TQGLColormap & map ); + + void renderText( int x, int y, const TQString & str, + const TQFont & fnt = TQFont(), int listBase = 2000 ); + void renderText( double x, double y, double z, const TQString & str, + const TQFont & fnt = TQFont(), int listBase = 2000 ); +public slots: + virtual void updateGL(); + virtual void updateOverlayGL(); + +protected: + virtual void initializeGL(); + virtual void resizeGL( int w, int h ); + virtual void paintGL(); + + virtual void initializeOverlayGL(); + virtual void resizeOverlayGL( int w, int h ); + virtual void paintOverlayGL(); + + void setAutoBufferSwap( bool on ); + bool autoBufferSwap() const; + + void paintEvent( TQPaintEvent* ); + void resizeEvent( TQResizeEvent* ); + + virtual void glInit(); + virtual void glDraw(); + +private: + int displayListBase( const TQFont & fnt, int listBase ); + void cleanupColormaps(); + void init( TQGLContext *context, const TQGLWidget* shareWidget ); + bool renderCxPm( TQPixmap* pm ); + TQGLContext* glcx; + bool autoSwap; + + TQGLColormap cmap; + +#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC) + TQGLContext* olcx; +#elif defined(TQ_WS_X11) + TQGLOverlayWidget* olw; + friend class TQGLOverlayWidget; +#endif + +private: // Disabled copy constructor and operator= +#if defined(TQ_DISABLE_COPY) + TQGLWidget( const TQGLWidget& ); + TQGLWidget& operator=( const TQGLWidget& ); +#endif + +#if defined(TQ_WS_MAC) +private: + const TQGLContext *slcx; + uint pending_fix : 1, + glcx_dblbuf : 2, + dblbuf : 1, + clp_serial : 15; + TQPixmap *gl_pix; + TQGLFormat req_format; + + void macInternalRecreateContext( TQGLContext *ctx, + const TQGLContext* = NULL, + bool update = TRUE ); + bool macInternalDoubleBuffer( bool fix = TRUE ); + virtual void setRegionDirty( bool ); + virtual void macWidgetChangedWindow(); +#endif +private slots: + void macInternalFixBufferRect(); +}; + + +// +// TQGLFormat inline functions +// + +inline bool TQGLFormat::doubleBuffer() const +{ + return testOption( DoubleBuffer ); +} + +inline bool TQGLFormat::depth() const +{ + return testOption( DepthBuffer ); +} + +inline bool TQGLFormat::rgba() const +{ + return testOption( Rgba ); +} + +inline bool TQGLFormat::alpha() const +{ + return testOption( AlphaChannel ); +} + +inline bool TQGLFormat::accum() const +{ + return testOption( AccumBuffer ); +} + +inline bool TQGLFormat::stencil() const +{ + return testOption( StencilBuffer ); +} + +inline bool TQGLFormat::stereo() const +{ + return testOption( StereoBuffers ); +} + +inline bool TQGLFormat::directRendering() const +{ + return testOption( DirectRendering ); +} + +inline bool TQGLFormat::hasOverlay() const +{ + return testOption( HasOverlay ); +} + +// +// TQGLContext inline functions +// + +inline bool TQGLContext::isValid() const +{ + return d->valid; +} + +inline void TQGLContext::setValid( bool valid ) +{ + d->valid = valid; +} + +inline bool TQGLContext::isSharing() const +{ + return d->sharing; +} + +inline TQGLFormat TQGLContext::format() const +{ + return glFormat; +} + +inline TQGLFormat TQGLContext::requestedFormat() const +{ + return reqFormat; +} + +inline TQPaintDevice* TQGLContext::device() const +{ + return d->paintDevice; +} + +inline bool TQGLContext::deviceIsPixmap() const +{ + return d->paintDevice->devType() == TQInternal::Pixmap; +} + + +inline bool TQGLContext::windowCreated() const +{ + return d->crWin; +} + + +inline void TQGLContext::setWindowCreated( bool on ) +{ + d->crWin = on; +} + +inline bool TQGLContext::initialized() const +{ + return d->initDone; +} + +inline void TQGLContext::setInitialized( bool on ) +{ + d->initDone = on; +} + +inline const TQGLContext* TQGLContext::currentContext() +{ + return currentCtx; +} + +// +// TQGLWidget inline functions +// + +inline TQGLFormat TQGLWidget::format() const +{ + return glcx->format(); +} + +inline const TQGLContext *TQGLWidget::context() const +{ + return glcx; +} + +inline bool TQGLWidget::doubleBuffer() const +{ + return glcx->format().doubleBuffer(); +} + +inline void TQGLWidget::setAutoBufferSwap( bool on ) +{ + autoSwap = on; +} + +inline bool TQGLWidget::autoBufferSwap() const +{ + return autoSwap; +} + +#endif diff --git a/src/opengl/tqgl_x11.cpp b/src/opengl/tqgl_x11.cpp new file mode 100644 index 000000000..e3fdfc504 --- /dev/null +++ b/src/opengl/tqgl_x11.cpp @@ -0,0 +1,1406 @@ +/**************************************************************************** +** +** Implementation of OpenGL classes for TQt +** +** Created : 970112 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the opengl 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 "tqgl.h" + +#if defined(TQ_WS_X11) + +#include "tqmap.h" +#include "tqpixmap.h" +#include "ntqapplication.h" + +#include "tqintdict.h" +#include "private/tqfontengine_p.h" + +#define INT8 dummy_INT8 +#define INT32 dummy_INT32 +#include +#undef INT8 +#undef INT32 +#include +#include +#include +#include + +// POSIX Large File Support redefines truncate -> truncate64 +#if defined(truncate) +# undef truncate +#endif + +#ifndef QT_DLOPEN_OPENGL +extern "C" { + Status XmuLookupStandardColormap( Display *dpy, int screen, VisualID visualid, + unsigned int depth, Atom property, + Bool replace, Bool retain ); +} +#endif + +#include "tqgl_x11_p.h" +#ifdef QT_DLOPEN_OPENGL +#include "ntqlibrary.h" + +extern "C" { +_glCallLists qt_glCallLists; +_glClearColor qt_glClearColor; +_glClearIndex qt_glClearIndex; +_glColor3ub qt_glColor3ub; +_glDeleteLists qt_glDeleteLists; +_glDrawBuffer qt_glDrawBuffer; +_glFlush qt_glFlush; +_glIndexi qt_glIndexi; +_glListBase qt_glListBase; +_glLoadIdentity qt_glLoadIdentity; +_glMatrixMode qt_glMatrixMode; +_glOrtho qt_glOrtho; +_glPopAttrib qt_glPopAttrib; +_glPopMatrix qt_glPopMatrix; +_glPushAttrib qt_glPushAttrib; +_glPushMatrix qt_glPushMatrix; +_glRasterPos2i qt_glRasterPos2i; +_glRasterPos3d qt_glRasterPos3d; +_glReadPixels qt_glReadPixels; +_glViewport qt_glViewport; +_glPixelStorei qt_glPixelStorei; +_glBitmap qt_glBitmap; +_glDrawPixels qt_glDrawPixels; +_glNewList qt_glNewList; +_glGetFloatv qt_glGetFloatv; +_glGetIntegerv qt_glGetIntegerv; +_glEndList qt_glEndList; + +_glXChooseVisual qt_glXChooseVisual; +_glXCreateContext qt_glXCreateContext; +_glXCreateGLXPixmap qt_glXCreateGLXPixmap; +_glXDestroyContext qt_glXDestroyContext; +_glXDestroyGLXPixmap qt_glXDestroyGLXPixmap; +_glXGetClientString qt_glXGetClientString; +_glXGetConfig qt_glXGetConfig; +_glXIsDirect qt_glXIsDirect; +_glXMakeCurrent qt_glXMakeCurrent; +_glXQueryExtension qt_glXQueryExtension; +_glXQueryExtensionsString qt_glXQueryExtensionsString; +_glXQueryServerString qt_glXQueryServerString; +_glXSwapBuffers qt_glXSwapBuffers; +_glXUseXFont qt_glXUseXFont; +_glXWaitX qt_glXWaitX; +}; + +bool qt_resolve_gl_symbols(bool fatal) +{ + static bool gl_syms_resolved = FALSE; + if (gl_syms_resolved) + return TRUE; + + TQLibrary gl("GL.so.1"); + gl.setAutoUnload(FALSE); + + qt_glCallLists = (_glCallLists) gl.resolve("glCallLists"); + + if (!qt_glCallLists) { // if this fails the rest will surely fail + if (fatal) + tqFatal("Unable to resolve GL/GLX symbols - please check your GL library installation."); + return FALSE; + } + + qt_glClearColor = (_glClearColor) gl.resolve("glClearColor"); + qt_glClearIndex = (_glClearIndex) gl.resolve("glClearIndex"); + qt_glColor3ub = (_glColor3ub) gl.resolve("glColor3ub"); + qt_glDeleteLists = (_glDeleteLists) gl.resolve("glDeleteLists"); + qt_glDrawBuffer = (_glDrawBuffer) gl.resolve("glDrawBuffer"); + qt_glFlush = (_glFlush) gl.resolve("glFlush"); + qt_glIndexi = (_glIndexi) gl.resolve("glIndexi"); + qt_glListBase = (_glListBase) gl.resolve("glListBase"); + qt_glLoadIdentity = (_glLoadIdentity) gl.resolve("glLoadIdentity"); + qt_glMatrixMode = (_glMatrixMode) gl.resolve("glMatrixMode"); + qt_glOrtho = (_glOrtho) gl.resolve("glOrtho"); + qt_glPopAttrib = (_glPopAttrib) gl.resolve("glPopAttrib"); + qt_glPopMatrix = (_glPopMatrix) gl.resolve("glPopMatrix"); + qt_glPushAttrib = (_glPushAttrib) gl.resolve("glPushAttrib"); + qt_glPushMatrix = (_glPushMatrix) gl.resolve("glPushMatrix"); + qt_glRasterPos2i = (_glRasterPos2i) gl.resolve("glRasterPos2i"); + qt_glRasterPos3d = (_glRasterPos3d) gl.resolve("glRasterPos3d"); + qt_glReadPixels = (_glReadPixels) gl.resolve("glReadPixels"); + qt_glViewport = (_glViewport) gl.resolve("glViewport"); + qt_glPixelStorei = (_glPixelStorei) gl.resolve("glPixelStorei"); + qt_glBitmap = (_glBitmap) gl.resolve("glBitmap"); + qt_glDrawPixels = (_glDrawPixels) gl.resolve("glDrawPixels"); + qt_glNewList = (_glNewList) gl.resolve("glNewList"); + qt_glGetFloatv = (_glGetFloatv) gl.resolve("glGetFloatv"); + qt_glGetIntegerv = (_glGetIntegerv) gl.resolve("glGetIntegerv"); + qt_glEndList = (_glEndList) gl.resolve("glEndList"); + + qt_glXChooseVisual = (_glXChooseVisual) gl.resolve("glXChooseVisual"); + qt_glXCreateContext = (_glXCreateContext) gl.resolve("glXCreateContext"); + qt_glXCreateGLXPixmap = (_glXCreateGLXPixmap) gl.resolve("glXCreateGLXPixmap"); + qt_glXDestroyContext = (_glXDestroyContext) gl.resolve("glXDestroyContext"); + qt_glXDestroyGLXPixmap = (_glXDestroyGLXPixmap) gl.resolve("glXDestroyGLXPixmap"); + qt_glXGetClientString = (_glXGetClientString) gl.resolve("glXGetClientString"); + qt_glXGetConfig = (_glXGetConfig) gl.resolve("glXGetConfig"); + qt_glXIsDirect = (_glXIsDirect) gl.resolve("glXIsDirect"); + qt_glXMakeCurrent = (_glXMakeCurrent) gl.resolve("glXMakeCurrent"); + qt_glXQueryExtension = (_glXQueryExtension) gl.resolve("glXQueryExtension"); + qt_glXQueryExtensionsString = (_glXQueryExtensionsString) gl.resolve("glXQueryExtensionsString"); + qt_glXQueryServerString = (_glXQueryServerString) gl.resolve("glXQueryServerString"); + qt_glXSwapBuffers = (_glXSwapBuffers) gl.resolve("glXSwapBuffers"); + qt_glXUseXFont = (_glXUseXFont) gl.resolve("glXUseXFont"); + qt_glXWaitX = (_glXWaitX) gl.resolve("glXWaitX"); + gl_syms_resolved = TRUE; + return TRUE; +} +#endif // QT_DLOPEN_OPENGL + + +/* + The choose_cmap function is internal and used by TQGLWidget::setContext() + and GLX (not Windows). If the application can't find any sharable + colormaps, it must at least create as few colormaps as possible. The + dictionary solution below ensures only one colormap is created per visual. + Colormaps are also deleted when the application terminates. +*/ + +struct CMapEntry { + CMapEntry(); + ~CMapEntry(); + Colormap cmap; + bool alloc; + XStandardColormap scmap; +}; + +CMapEntry::CMapEntry() +{ + cmap = 0; + alloc = FALSE; + scmap.colormap = 0; +} + +CMapEntry::~CMapEntry() +{ + if ( alloc ) + XFreeColormap( TQPaintDevice::x11AppDisplay(), cmap ); +} + +static TQIntDict *cmap_dict = 0; +static bool mesa_gl = FALSE; +static TQIntDict< TQMap > *qglcmap_dict = 0; + +static void cleanup_cmaps() +{ + if (cmap_dict) { + cmap_dict->setAutoDelete(TRUE); + delete cmap_dict; + cmap_dict = 0; + } + if (qglcmap_dict) { + qglcmap_dict->setAutoDelete(TRUE); + delete qglcmap_dict; + qglcmap_dict = 0; + } +} + +static Colormap choose_cmap( Display *dpy, XVisualInfo *vi ) +{ + if ( !cmap_dict ) { + cmap_dict = new TQIntDict; + const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION ); + if ( v ) + mesa_gl = strstr(v,"Mesa") != 0; + tqAddPostRoutine( cleanup_cmaps ); + } + + CMapEntry *x = cmap_dict->find( (long) vi->visualid + ( vi->screen * 256 ) ); + if ( x ) // found colormap for visual + return x->cmap; + + x = new CMapEntry(); + + XStandardColormap *c; + int n, i; + + // tqDebug( "Choosing cmap for vID %0x", vi->visualid ); + + if ( vi->visualid == + XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( vi->screen ) ) ) { + // tqDebug( "Using x11AppColormap" ); + return TQPaintDevice::x11AppColormap( vi->screen ); + } + + if ( mesa_gl ) { // we're using MesaGL + Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", TRUE ); + if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 ) { + if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n, + hp_cmaps) ) { + i = 0; + while ( i < n && x->cmap == 0 ) { + if ( c[i].visualid == vi->visual->visualid ) { + x->cmap = c[i].colormap; + x->scmap = c[i]; + //tqDebug( "Using HP_RGB scmap" ); + + } + i++; + } + XFree( (char *)c ); + } + } + } +#if !defined(Q_OS_SOLARIS) + if ( !x->cmap ) { +#ifdef QT_DLOPEN_OPENGL + typedef Status (*_XmuLookupStandardColormap)( Display *dpy, int screen, VisualID visualid, unsigned int depth, + Atom property, Bool replace, Bool retain ); + _XmuLookupStandardColormap qt_XmuLookupStandardColormap; + qt_XmuLookupStandardColormap = (_XmuLookupStandardColormap) TQLibrary::resolve("Xmu.so.6", "XmuLookupStandardColormap"); + if (!qt_XmuLookupStandardColormap) + tqFatal("Unable to resolve Xmu symbols - please check your Xmu library installation."); +#define XmuLookupStandardColormap qt_XmuLookupStandardColormap + +#endif + + if ( XmuLookupStandardColormap(dpy,vi->screen,vi->visualid,vi->depth, + XA_RGB_DEFAULT_MAP,FALSE,TRUE) ) { + if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n, + XA_RGB_DEFAULT_MAP) ) { + i = 0; + while ( i < n && x->cmap == 0 ) { + if ( c[i].visualid == vi->visualid ) { + x->cmap = c[i].colormap; + x->scmap = c[i]; + //tqDebug( "Using RGB_DEFAULT scmap" ); + } + i++; + } + XFree( (char *)c ); + } + } + } +#endif + if ( !x->cmap ) { // no shared cmap found + x->cmap = XCreateColormap( dpy, RootWindow(dpy,vi->screen), vi->visual, + AllocNone ); + x->alloc = TRUE; + // tqDebug( "Allocating cmap" ); + } + + // associate cmap with visualid + cmap_dict->insert( (long) vi->visualid + ( vi->screen * 256 ), x ); + return x->cmap; +} + +struct TransColor +{ + VisualID vis; + int screen; + long color; +}; + +static TQMemArray trans_colors; +static int trans_colors_init = FALSE; + + +static void find_trans_colors() +{ + struct OverlayProp { + long visual; + long type; + long value; + long layer; + }; + + trans_colors_init = TRUE; + + Display* appDisplay = TQPaintDevice::x11AppDisplay(); + + int scr; + int lastsize = 0; + for ( scr = 0; scr < ScreenCount( appDisplay ); scr++ ) { + TQWidget* rootWin = TQApplication::desktop()->screen( scr ); + if ( !rootWin ) + return; // Should not happen + Atom overlayVisualsAtom = XInternAtom( appDisplay, + "SERVER_OVERLAY_VISUALS", True ); + if ( overlayVisualsAtom == None ) + return; // Server has no overlays + + Atom actualType; + int actualFormat; + ulong nItems; + ulong bytesAfter; + OverlayProp* overlayProps = 0; + int res = XGetWindowProperty( appDisplay, rootWin->winId(), + overlayVisualsAtom, 0, 10000, False, + overlayVisualsAtom, &actualType, + &actualFormat, &nItems, &bytesAfter, + (uchar**)&overlayProps ); + + if ( res != Success || actualType != overlayVisualsAtom + || actualFormat != 32 || nItems < 4 || !overlayProps ) + return; // Error reading property + + int numProps = nItems / 4; + trans_colors.resize( lastsize + numProps ); + int j = lastsize; + for ( int i = 0; i < numProps; i++ ) { + if ( overlayProps[i].type == 1 ) { + trans_colors[j].vis = (VisualID)overlayProps[i].visual; + trans_colors[j].screen = scr; + trans_colors[j].color = (int)overlayProps[i].value; + j++; + } + } + XFree( overlayProps ); + lastsize = j; + trans_colors.truncate( lastsize ); + } +} + + +/***************************************************************************** + TQGLFormat UNIX/GLX-specific code + *****************************************************************************/ + +bool TQGLFormat::hasOpenGL() +{ + if (!qt_resolve_gl_symbols(FALSE)) + return FALSE; + return glXQueryExtension(tqt_xdisplay(),0,0) != 0; +} + + +bool TQGLFormat::hasOpenGLOverlays() +{ + qt_resolve_gl_symbols(); + if ( !trans_colors_init ) + find_trans_colors(); + return trans_colors.size() > 0; +} + + + +/***************************************************************************** + TQGLContext UNIX/GLX-specific code + *****************************************************************************/ + +bool TQGLContext::chooseContext( const TQGLContext* shareContext ) +{ + Display* disp = d->paintDevice->x11Display(); + vi = chooseVisual(); + if ( !vi ) + return FALSE; + + if ( deviceIsPixmap() && + (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() || + ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) ) + { + XFree( vi ); + XVisualInfo appVisInfo; + memset( &appVisInfo, 0, sizeof(XVisualInfo) ); + appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() ); + appVisInfo.screen = d->paintDevice->x11Screen(); + int nvis; + vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis ); + if ( !vi ) + return FALSE; + + int useGL; + glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL ); + if ( !useGL ) + return FALSE; //# Chickening out already... + } + int res; + glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res ); + glFormat.setPlane( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res ); + glFormat.setDoubleBuffer( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res ); + glFormat.setDepth( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res ); + glFormat.setRgba( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res ); + glFormat.setAlpha( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res ); + glFormat.setAccum( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res ); + glFormat.setStencil( res ); + glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res ); + glFormat.setStereo( res ); + + Bool direct = format().directRendering() ? True : False; + + if ( shareContext && + ( !shareContext->isValid() || !shareContext->cx ) ) { +#if defined(QT_CHECK_NULL) + tqWarning("TQGLContext::chooseContext(): Cannot share with invalid context"); +#endif + shareContext = 0; + } + + // 1. Sharing between rgba and color-index will give wrong colors. + // 2. Contexts cannot be shared btw. direct/non-direct renderers. + // 3. Pixmaps cannot share contexts that are set up for direct rendering. + if ( shareContext && (format().rgba() != shareContext->format().rgba() || + (deviceIsPixmap() && + glXIsDirect( disp, (GLXContext)shareContext->cx )))) + shareContext = 0; + + cx = 0; + if ( shareContext ) { + cx = glXCreateContext( disp, (XVisualInfo *)vi, + (GLXContext)shareContext->cx, direct ); + if ( cx ) + d->sharing = TRUE; + } + if ( !cx ) + cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct ); + if ( !cx ) + return FALSE; + glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) ); + if ( deviceIsPixmap() ) { +#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT) + gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi, + d->paintDevice->handle(), + choose_cmap( disp, (XVisualInfo *)vi ) ); +#else + gpm = (TQ_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi, + d->paintDevice->handle() ); +#endif + if ( !gpm ) + return FALSE; + } + return TRUE; +} + + +/*! + X11 only: This virtual function tries to find a + visual that matches the format, reducing the demands if the original + request cannot be met. + + The algorithm for reducing the demands of the format is quite + simple-minded, so override this method in your subclass if your + application has spcific requirements on visual selection. + + \sa chooseContext() +*/ + +void *TQGLContext::chooseVisual() +{ + static int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also? + //todo: if pixmap, also make sure that vi->depth == pixmap->depth + void* vis = 0; + int i = 0; + bool fail = FALSE; + TQGLFormat fmt = format(); + bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double + bool triedDouble = FALSE; + while( !fail && !( vis = tryVisual( fmt, bufDepths[i] ) ) ) { + if ( !fmt.rgba() && bufDepths[i] > 1 ) { + i++; + continue; + } + if ( tryDouble ) { + fmt.setDoubleBuffer( TRUE ); + tryDouble = FALSE; + triedDouble = TRUE; + continue; + } + else if ( triedDouble ) { + fmt.setDoubleBuffer( FALSE ); + triedDouble = FALSE; + } + if ( fmt.stereo() ) { + fmt.setStereo( FALSE ); + continue; + } + if ( fmt.accum() ) { + fmt.setAccum( FALSE ); + continue; + } + if ( fmt.stencil() ) { + fmt.setStencil( FALSE ); + continue; + } + if ( fmt.alpha() ) { + fmt.setAlpha( FALSE ); + continue; + } + if ( fmt.depth() ) { + fmt.setDepth( FALSE ); + continue; + } + if ( fmt.doubleBuffer() ) { + fmt.setDoubleBuffer( FALSE ); + continue; + } + fail = TRUE; + } + glFormat = fmt; + return vis; +} + + +/*! + + \internal + + X11 only: This virtual function chooses a visual + that matches the OpenGL \link format() format\endlink. Reimplement this + function in a subclass if you need a custom visual. + + \sa chooseContext() +*/ + +void *TQGLContext::tryVisual( const TQGLFormat& f, int bufDepth ) +{ + int spec[40]; + int i = 0; + spec[i++] = GLX_LEVEL; + spec[i++] = f.plane(); + +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + static bool useTranspExt = FALSE; + static bool useTranspExtChecked = FALSE; + if ( f.plane() && !useTranspExtChecked && d->paintDevice ) { + TQCString estr( glXQueryExtensionsString( d->paintDevice->x11Display(), + d->paintDevice->x11Screen() ) ); + useTranspExt = estr.contains( "GLX_EXT_visual_info" ); + //# (A bit simplistic; that could theoretically be a substring) + if ( useTranspExt ) { + TQCString cstr( glXGetClientString( d->paintDevice->x11Display(), + GLX_VENDOR ) ); + useTranspExt = !cstr.contains( "Xi Graphics" ); // bug workaround + if ( useTranspExt ) { + // bug workaround - some systems (eg. FireGL) refuses to return an overlay + // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specfied, even if + // the implementation supports transparent overlays + int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, + f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, + None }; + XVisualInfo * vinf = glXChooseVisual( d->paintDevice->x11Display(), + d->paintDevice->x11Screen(), tmpSpec ); + if ( !vinf ) { + useTranspExt = FALSE; + } + } + } + + useTranspExtChecked = TRUE; + } + if ( f.plane() && useTranspExt ) { + // Required to avoid non-transparent overlay visual(!) on some systems + spec[i++] = GLX_TRANSPARENT_TYPE_EXT; + spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; + } +#endif + + if ( f.doubleBuffer() ) + spec[i++] = GLX_DOUBLEBUFFER; + if ( f.depth() ) { + spec[i++] = GLX_DEPTH_SIZE; + spec[i++] = 1; + } + if ( f.stereo() ) { + spec[i++] = GLX_STEREO; + } + if ( f.stencil() ) { + spec[i++] = GLX_STENCIL_SIZE; + spec[i++] = 1; + } + if ( f.rgba() ) { + spec[i++] = GLX_RGBA; + spec[i++] = GLX_RED_SIZE; + spec[i++] = 1; + spec[i++] = GLX_GREEN_SIZE; + spec[i++] = 1; + spec[i++] = GLX_BLUE_SIZE; + spec[i++] = 1; + if ( f.alpha() ) { + spec[i++] = GLX_ALPHA_SIZE; + spec[i++] = 1; + } + if ( f.accum() ) { + spec[i++] = GLX_ACCUM_RED_SIZE; + spec[i++] = 1; + spec[i++] = GLX_ACCUM_GREEN_SIZE; + spec[i++] = 1; + spec[i++] = GLX_ACCUM_BLUE_SIZE; + spec[i++] = 1; + if ( f.alpha() ) { + spec[i++] = GLX_ACCUM_ALPHA_SIZE; + spec[i++] = 1; + } + } + } + else { + spec[i++] = GLX_BUFFER_SIZE; + spec[i++] = bufDepth; + } + + spec[i] = None; + return glXChooseVisual( d->paintDevice->x11Display(), + d->paintDevice->x11Screen(), spec ); +} + + +void TQGLContext::reset() +{ + if ( !d->valid ) + return; + doneCurrent(); + if ( gpm ) + glXDestroyGLXPixmap( d->paintDevice->x11Display(), (GLXPixmap)gpm ); + gpm = 0; + glXDestroyContext( d->paintDevice->x11Display(), (GLXContext)cx ); + if ( vi ) + XFree( vi ); + vi = 0; + cx = 0; + d->crWin = FALSE; + d->sharing = FALSE; + d->valid = FALSE; + d->transpColor = TQColor(); + d->initDone = FALSE; +} + + +void TQGLContext::makeCurrent() +{ + if ( !d->valid ) { +#if defined(QT_CHECK_STATE) + tqWarning("TQGLContext::makeCurrent(): Cannot make invalid context current."); +#endif + return; + } + bool ok = TRUE; + if ( deviceIsPixmap() ) + ok = glXMakeCurrent( d->paintDevice->x11Display(), + (GLXPixmap)gpm, + (GLXContext)cx ); + + else + ok = glXMakeCurrent( d->paintDevice->x11Display(), + ((TQWidget *)d->paintDevice)->winId(), + (GLXContext)cx ); +#if defined(QT_CHECK_NULL) + // tqDebug("makeCurrent: %i, vi=%i, vi->vi=%i, vi->id=%i", (int)this, (int)vi, (int)((XVisualInfo*)vi)->visual, (int)((XVisualInfo*)vi)->visualid ); + if ( !ok ) + tqWarning("TQGLContext::makeCurrent(): Failed."); +#endif + if ( ok ) + currentCtx = this; +} + +void TQGLContext::doneCurrent() +{ + glXMakeCurrent( d->paintDevice->x11Display(), 0, 0 ); + currentCtx = 0; +} + + +void TQGLContext::swapBuffers() const +{ + if ( !d->valid ) + return; + if ( !deviceIsPixmap() ) + glXSwapBuffers( d->paintDevice->x11Display(), + ((TQWidget *)d->paintDevice)->winId() ); +} + +TQColor TQGLContext::overlayTransparentColor() const +{ + //### make more efficient using the transpColor member + if ( isValid() ) { + if ( !trans_colors_init ) + find_trans_colors(); + + VisualID myVisualId = ((XVisualInfo*)vi)->visualid; + int myScreen = ((XVisualInfo*)vi)->screen; + for ( int i = 0; i < (int)trans_colors.size(); i++ ) { + if ( trans_colors[i].vis == myVisualId && + trans_colors[i].screen == myScreen ) { + XColor col; + col.pixel = trans_colors[i].color; + col.red = col.green = col.blue = 0; + col.flags = 0; + Display *dpy = d->paintDevice->x11Display(); + if (col.pixel > (uint) ((XVisualInfo *)vi)->colormap_size - 1) + col.pixel = ((XVisualInfo *)vi)->colormap_size - 1; + XQueryColor(dpy, choose_cmap(dpy, (XVisualInfo *) vi), &col); + uchar r = (uchar)((col.red / 65535.0) * 255.0 + 0.5); + uchar g = (uchar)((col.green / 65535.0) * 255.0 + 0.5); + uchar b = (uchar)((col.blue / 65535.0) * 255.0 + 0.5); + return TQColor(tqRgb(r,g,b), trans_colors[i].color); + } + } + } + return TQColor(); // Invalid color +} + + +uint TQGLContext::colorIndex( const TQColor& c ) const +{ + int screen = ((XVisualInfo *)vi)->screen; + if ( isValid() ) { + if ( format().plane() + && c.pixel( screen ) == overlayTransparentColor().pixel( screen ) ) + return c.pixel( screen ); // Special; don't look-up + if ( ((XVisualInfo*)vi)->visualid == + XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( screen ) ) ) + return c.pixel( screen ); // We're using TQColor's cmap + + XVisualInfo *info = (XVisualInfo *) vi; + CMapEntry *x = cmap_dict->find( (long) info->visualid + ( info->screen * 256 ) ); + if ( x && !x->alloc) { // It's a standard colormap + int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0); + int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0); + int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0); + uint p = x->scmap.base_pixel + + ( rf * x->scmap.red_mult ) + + ( gf * x->scmap.green_mult ) + + ( bf * x->scmap.blue_mult ); + return p; + } else { + if (!qglcmap_dict) { + qglcmap_dict = new TQIntDict< TQMap >; + } + TQMap *cmap; + if ((cmap = qglcmap_dict->find((long) info->visualid)) == 0) { + cmap = new TQMap; + qglcmap_dict->insert((long) info->visualid, cmap); + } + + // already in the map? + TQRgb target = c.rgb(); + TQMap::Iterator it = cmap->begin(); + for (; it != cmap->end(); ++it) { + if ((*it) == target) + return it.key(); + } + + // need to alloc color + unsigned long plane_mask[2]; + unsigned long color_map_entry; + if (!XAllocColorCells (TQPaintDevice::x11AppDisplay(), x->cmap, TRUE, plane_mask, 0, + &color_map_entry, 1)) + return c.pixel(screen); + + XColor col; + col.flags = DoRed | DoGreen | DoBlue; + col.pixel = color_map_entry; + col.red = (ushort)((tqRed(c.rgb()) / 255.0) * 65535.0 + 0.5); + col.green = (ushort)((tqGreen(c.rgb()) / 255.0) * 65535.0 + 0.5); + col.blue = (ushort)((tqBlue(c.rgb()) / 255.0) * 65535.0 + 0.5); + XStoreColor(TQPaintDevice::x11AppDisplay(), x->cmap, &col); + + cmap->insert(color_map_entry, target); + return color_map_entry; + } + } + return 0; +} + +#ifndef TQT_NO_XFTFREETYPE +/*! \internal + This is basically a substitute for glxUseXFont() which can only + handle XLFD fonts. This version relies on XFT v2 to render the + glyphs, but it works with all fonts that XFT2 provides - both + antialiased and aliased bitmap and outline fonts. +*/ +void qgl_use_font(TQFontEngineXft *engine, int first, int count, int listBase) +{ + GLfloat color[4]; + glGetFloatv(GL_CURRENT_COLOR, color); + + // save the pixel unpack state + GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment; + glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes); + glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst); + glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength); + glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows); + glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels); + glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + Bool antialiased = False; +#if 0 // disable antialias support for now + XftPatternGetBool(engine->pattern(), XFT_ANTIALIAS, 0, &antialiased); +#endif +#ifdef QT_XFT2 + FT_Face face = XftLockFace(engine->font()); +#else + FT_Face face = engine->face(); +#endif + // start generating font glyphs + for (int i = first; i < count; ++i) { + int list = listBase + i; + GLfloat x0, y0, dx, dy; + + FT_Error err; + + err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT); + if (err) { + tqDebug("failed loading glyph %d from font", i); + Q_ASSERT(!err); + } + err = FT_Render_Glyph(face->glyph, (antialiased ? ft_render_mode_normal + : ft_render_mode_mono)); + if (err) { + tqDebug("failed rendering glyph %d from font", i); + Q_ASSERT(!err); + } + + FT_Bitmap bm = face->glyph->bitmap; + x0 = face->glyph->metrics.horiBearingX >> 6; + y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6; + dx = face->glyph->metrics.horiAdvance >> 6; + dy = 0; + int sz = bm.pitch * bm.rows; + uint *aa_glyph = 0; + uchar *ua_glyph = 0; + + if (antialiased) + aa_glyph = new uint[sz]; + else + ua_glyph = new uchar[sz]; + + // convert to GL format + for (int y = 0; y < bm.rows; ++y) { + for (int x = 0; x < bm.pitch; ++x) { + int c1 = y*bm.pitch + x; + int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x; + if (antialiased) { + aa_glyph[c1] = (int(color[0]*255) << 24) + | (int(color[1]*255) << 16) + | (int(color[2]*255) << 8) | bm.buffer[c2]; + } else { + ua_glyph[c1] = bm.buffer[c2]; + } + } + } + + glNewList(list, GL_COMPILE); + if (antialiased) { + // calling glBitmap() is just a trick to move the current + // raster pos, since glGet*() won't work in display lists + glBitmap(0, 0, 0, 0, x0, -y0, 0); + glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph); + glBitmap(0, 0, 0, 0, dx-x0, y0, 0); + } else { + glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph); + } + glEndList(); + antialiased ? delete[] aa_glyph : delete[] ua_glyph; + } + +#ifdef QT_XFT2 + XftUnlockFace(engine->font()); +#endif + + // restore pixel unpack settings + glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes); + glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst); + glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength); + glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels); + glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment); +} +#endif + +void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase ) +{ + TQFont f(fnt); + TQFontEngine *engine = f.d->engineForScript(TQFont::Latin); + +#ifndef TQT_NO_XFTFREETYPE + if(engine->type() == TQFontEngine::Xft) { + qgl_use_font((TQFontEngineXft *) engine, 0, 256, listBase); + return; + } +#endif + // glXUseXFont() only works with XLFD font structures and a few GL + // drivers crash if 0 is passed as the font handle + f.setStyleStrategy(TQFont::OpenGLCompatible); + if (f.handle() && (engine->type() == TQFontEngine::XLFD + || engine->type() == TQFontEngine::LatinXLFD)) { + glXUseXFont((Font) f.handle(), 0, 256, listBase); + } +} + +/***************************************************************************** + TQGLOverlayWidget (Internal overlay class for X11) + *****************************************************************************/ + +class TQGLOverlayWidget : public TQGLWidget +{ + TQ_OBJECT +public: + TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* parent, + const char* name=0, const TQGLWidget* shareWidget=0 ); + +protected: + void initializeGL(); + void paintGL(); + void resizeGL( int w, int h ); + +private: + TQGLWidget* realWidget; + +private: // Disabled copy constructor and operator= +#if defined(TQ_DISABLE_COPY) + TQGLOverlayWidget( const TQGLOverlayWidget& ); + TQGLOverlayWidget& operator=( const TQGLOverlayWidget& ); +#endif +}; + + +TQGLOverlayWidget::TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* parent, + const char* name, + const TQGLWidget* shareWidget ) + : TQGLWidget( format, parent, name, shareWidget ? shareWidget->olw : 0 ) +{ + realWidget = parent; +} + + + +void TQGLOverlayWidget::initializeGL() +{ + TQColor transparentColor = context()->overlayTransparentColor(); + if ( transparentColor.isValid() ) + qglClearColor( transparentColor ); + else + tqWarning( "TQGLOverlayWidget::initializeGL(): Could not get transparent color" ); + realWidget->initializeOverlayGL(); +} + + +void TQGLOverlayWidget::resizeGL( int w, int h ) +{ + glViewport( 0, 0, w, h ); + realWidget->resizeOverlayGL( w, h ); +} + + +void TQGLOverlayWidget::paintGL() +{ + realWidget->paintOverlayGL(); +} + +#undef Bool +#include "tqgl_x11.moc" + +/***************************************************************************** + TQGLWidget UNIX/GLX-specific code + *****************************************************************************/ +void TQGLWidget::init( TQGLContext *context, const TQGLWidget *shareWidget ) +{ + qt_resolve_gl_symbols(); + + glcx = 0; + olw = 0; + autoSwap = TRUE; + if ( !context->device() ) + context->setDevice( this ); + + if ( shareWidget ) + setContext( context, shareWidget->context() ); + else + setContext( context ); + setBackgroundMode( NoBackground ); + + if ( isValid() && context->format().hasOverlay() ) { + TQCString olwName( name() ); + olwName += "-TQGL_internal_overlay_widget"; + olw = new TQGLOverlayWidget( TQGLFormat::defaultOverlayFormat(), + this, olwName, shareWidget ); + if ( olw->isValid() ) { + olw->setAutoBufferSwap( FALSE ); + olw->setFocusProxy( this ); + } + else { + delete olw; + olw = 0; + glcx->glFormat.setOverlay( FALSE ); + } + } +} + +/*! \reimp */ +void TQGLWidget::reparent( TQWidget* parent, WFlags f, const TQPoint& p, + bool showIt ) +{ + if (glcx) + glcx->doneCurrent(); + TQWidget::reparent( parent, f, p, FALSE ); + if ( showIt ) + show(); +} + + +void TQGLWidget::setMouseTracking( bool enable ) +{ + if ( olw ) + olw->setMouseTracking( enable ); + TQWidget::setMouseTracking( enable ); +} + + +void TQGLWidget::resizeEvent( TQResizeEvent * ) +{ + if ( !isValid() ) + return; + makeCurrent(); + if ( !glcx->initialized() ) + glInit(); + glXWaitX(); + resizeGL( width(), height() ); + if ( olw ) + olw->setGeometry( rect() ); +} + +const TQGLContext* TQGLWidget::overlayContext() const +{ + if ( olw ) + return olw->context(); + else + return 0; +} + + +void TQGLWidget::makeOverlayCurrent() +{ + if ( olw ) + olw->makeCurrent(); +} + + +void TQGLWidget::updateOverlayGL() +{ + if ( olw ) + olw->updateGL(); +} + +void TQGLWidget::setContext( TQGLContext *context, + const TQGLContext* shareContext, + bool deleteOldContext ) +{ + if ( context == 0 ) { +#if defined(QT_CHECK_NULL) + tqWarning( "TQGLWidget::setContext: Cannot set null context" ); +#endif + return; + } + if ( !context->deviceIsPixmap() && context->device() != this ) { +#if defined(QT_CHECK_STATE) + tqWarning( "TQGLWidget::setContext: Context must refer to this widget" ); +#endif + return; + } + + if ( glcx ) + glcx->doneCurrent(); + TQGLContext* oldcx = glcx; + glcx = context; + + bool createFailed = FALSE; + if ( !glcx->isValid() ) { + if ( !glcx->create( shareContext ? shareContext : oldcx ) ) + createFailed = TRUE; + } + if ( createFailed ) { + if ( deleteOldContext ) + delete oldcx; + return; + } + + if ( glcx->windowCreated() || glcx->deviceIsPixmap() ) { + if ( deleteOldContext ) + delete oldcx; + return; + } + + bool visible = isVisible(); + if ( visible ) + hide(); + + XVisualInfo *vi = (XVisualInfo*)glcx->vi; + XSetWindowAttributes a; + + a.colormap = choose_cmap( x11Display(), vi ); // find best colormap + a.background_pixel = backgroundColor().pixel( vi->screen ); + a.border_pixel = black.pixel( vi->screen ); + Window p = RootWindow( x11Display(), vi->screen ); + if ( parentWidget() ) + p = parentWidget()->winId(); + + Window w = XCreateWindow( x11Display(), p, x(), y(), width(), height(), + 0, vi->depth, InputOutput, vi->visual, + CWBackPixel|CWBorderPixel|CWColormap, &a ); + + Window *cmw; + Window *cmwret; + int count; + if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), + &cmwret, &count ) ) { + cmw = new Window[count+1]; + memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count ); + XFree( (char *)cmwret ); + int i; + for ( i=0; i= count ) // append new window + cmw[count++] = w; + } else { + count = 1; + cmw = new Window[count]; + cmw[0] = w; + } + +#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT) + if ( oldcx && oldcx->windowCreated() ) + glXReleaseBuffersMESA( x11Display(), winId() ); +#endif + if ( deleteOldContext ) + delete oldcx; + oldcx = 0; + + create( w ); + + XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, + count ); + delete [] cmw; + + if ( visible ) + show(); + XFlush( x11Display() ); + glcx->setWindowCreated( TRUE ); +} + + +bool TQGLWidget::renderCxPm( TQPixmap* pm ) +{ + if ( ((XVisualInfo*)glcx->vi)->depth != pm->depth() ) + return FALSE; + + GLXPixmap glPm; +#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT) + glPm = glXCreateGLXPixmapMESA( x11Display(), + (XVisualInfo*)glcx->vi, + (Pixmap)pm->handle(), + choose_cmap( pm->x11Display(), + (XVisualInfo*)glcx->vi ) ); +#else + glPm = (TQ_UINT32)glXCreateGLXPixmap( x11Display(), + (XVisualInfo*)glcx->vi, + (Pixmap)pm->handle() ); +#endif + + if ( !glXMakeCurrent( x11Display(), glPm, (GLXContext)glcx->cx ) ) { + glXDestroyGLXPixmap( x11Display(), glPm ); + return FALSE; + } + + glDrawBuffer( GL_FRONT ); + if ( !glcx->initialized() ) + glInit(); + resizeGL( pm->width(), pm->height() ); + paintGL(); + glFlush(); + makeCurrent(); + glXDestroyGLXPixmap( x11Display(), glPm ); + resizeGL( width(), height() ); + return TRUE; +} + +const TQGLColormap & TQGLWidget::colormap() const +{ + return cmap; +} + +/*\internal + Store color values in the given colormap. +*/ +static void qStoreColors( TQWidget * tlw, Colormap cmap, + const TQGLColormap & cols ) +{ + XColor c; + TQRgb color; + + for ( int i = 0; i < cols.size(); i++ ) { + color = cols.entryRgb( i ); + c.pixel = i; + c.red = (ushort)( (tqRed( color ) / 255.0) * 65535.0 + 0.5 ); + c.green = (ushort)( (tqGreen( color ) / 255.0) * 65535.0 + 0.5 ); + c.blue = (ushort)( (tqBlue( color ) / 255.0) * 65535.0 + 0.5 ); + c.flags = DoRed | DoGreen | DoBlue; + XStoreColor( tlw->x11Display(), cmap, &c ); + } +} + +/*\internal + Check whether the given visual supports dynamic colormaps or not. +*/ +static bool qCanAllocColors( TQWidget * w ) +{ + bool validVisual = FALSE; + int numVisuals; + long mask; + XVisualInfo templ; + XVisualInfo * visuals; + VisualID id = XVisualIDFromVisual( (Visual *) + w->topLevelWidget()->x11Visual() ); + + mask = VisualScreenMask; + templ.screen = w->x11Screen(); + visuals = XGetVisualInfo( w->x11Display(), mask, &templ, &numVisuals ); + + for ( int i = 0; i < numVisuals; i++ ) { + if ( visuals[i].visualid == id ) { + switch ( visuals[i].c_class ) { + case TrueColor: + case StaticColor: + case StaticGray: + case GrayScale: + validVisual = FALSE; + break; + case DirectColor: + case PseudoColor: + validVisual = TRUE; + break; + } + break; + } + } + XFree( visuals ); + + if ( !validVisual ) + return FALSE; + return TRUE; +} + +void TQGLWidget::setColormap( const TQGLColormap & c ) +{ + TQWidget * tlw = topLevelWidget(); // must return a valid widget + + cmap = c; + if ( !cmap.d ) + return; + + if ( !cmap.d->cmapHandle && !qCanAllocColors( this ) ) { + tqWarning( "TQGLWidget::setColormap: Cannot create a read/write " + "colormap for this visual" ); + return; + } + + // If the child GL widget is not of the same visual class as the + // toplevel widget we will get in trouble.. + Window wid = tlw->winId(); + Visual * vis = (Visual *) tlw->x11Visual();; + VisualID cvId = XVisualIDFromVisual( (Visual *) x11Visual() ); + VisualID tvId = XVisualIDFromVisual( (Visual *) tlw->x11Visual() ); + if ( cvId != tvId ) { + wid = winId(); + vis = (Visual *) x11Visual(); + } + + if ( !cmap.d->cmapHandle ) // allocate a cmap if necessary + cmap.d->cmapHandle = XCreateColormap( x11Display(), wid, vis, + AllocAll ); + + qStoreColors( this, (Colormap) cmap.d->cmapHandle, c ); + XSetWindowColormap( x11Display(), wid, (Colormap) cmap.d->cmapHandle ); + + // tell the wm that this window has a special colormap + Window * cmw; + Window * cmwret; + int count; + if ( XGetWMColormapWindows( x11Display(), tlw->winId(), &cmwret, + &count ) ) + { + cmw = new Window[count+1]; + memcpy( (char *) cmw, (char *) cmwret, sizeof(Window) * count ); + XFree( (char *) cmwret ); + int i; + for ( i = 0; i < count; i++ ) { + if ( cmw[i] == winId() ) { + break; + } + } + if ( i >= count ) // append new window only if not in the list + cmw[count++] = winId(); + } else { + count = 1; + cmw = new Window[count]; + cmw[0] = winId(); + } + XSetWMColormapWindows( x11Display(), tlw->winId(), cmw, count ); + delete [] cmw; +} + +/*! \internal + Free up any allocated colormaps. This fn is only called for + top-level widgets. +*/ +void TQGLWidget::cleanupColormaps() +{ + if ( !cmap.d ) + return; + + if ( cmap.d->cmapHandle ) { + XFreeColormap( topLevelWidget()->x11Display(), + (Colormap) cmap.d->cmapHandle ); + cmap.d->cmapHandle = 0; + } +} + +void TQGLWidget::macInternalFixBufferRect() +{ +} + +#endif diff --git a/src/opengl/tqgl_x11_p.h b/src/opengl/tqgl_x11_p.h new file mode 100644 index 000000000..cbcd741b9 --- /dev/null +++ b/src/opengl/tqgl_x11_p.h @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Definitions needed for resolving GL/GLX symbols using dlopen() +** under X11. +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the OpenGL 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. +** +** 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 TQGL_P_H +#define TQGL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the TQt API. This header file may +// change from version to version without notice, or even be +// removed. +// +// We mean it. +// +// + +#ifdef QT_DLOPEN_OPENGL +// resolve the GL symbols we use ourselves +bool qt_resolve_gl_symbols(bool = TRUE); +extern "C" { +// GL symbols +typedef void (*_glCallLists)( GLsizei n, GLenum type, const GLvoid *lists ); +typedef void (*_glClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); +typedef void (*_glClearIndex)( GLfloat c ); +typedef void (*_glColor3ub)( GLubyte red, GLubyte green, GLubyte blue ); +typedef void (*_glDeleteLists)( GLuint list, GLsizei range ); +typedef void (*_glDrawBuffer)( GLenum mode ); +typedef void (*_glFlush)( void ); +typedef void (*_glIndexi)( GLint c ); +typedef void (*_glListBase)( GLuint base ); +typedef void (*_glLoadIdentity)( void ); +typedef void (*_glMatrixMode)( GLenum mode ); +typedef void (*_glOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +typedef void (*_glPopAttrib)( void ); +typedef void (*_glPopMatrix)( void ); +typedef void (*_glPushAttrib)( GLbitfield mask ); +typedef void (*_glPushMatrix)( void ); +typedef void (*_glRasterPos2i)( GLint x, GLint y ); +typedef void (*_glRasterPos3d)( GLdouble x, GLdouble y, GLdouble z ); +typedef void (*_glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); +typedef void (*_glViewport)( GLint x, GLint y, GLsizei width, GLsizei height ); +typedef void (*_glPixelStorei)( GLenum pname, GLint param ); +typedef void (*_glBitmap)( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); +typedef void (*_glDrawPixels)( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); +typedef void (*_glNewList)( GLuint list, GLenum mode ); +typedef void (*_glGetFloatv)( GLenum pname, GLfloat *params ); +typedef void (*_glGetIntegerv)( GLenum pname, GLint *params ); +typedef void (*_glEndList)( void ); + + +// GLX symbols - should be in the GL lib as well +typedef XVisualInfo* (*_glXChooseVisual)(Display *dpy, int screen, int *attribList); +typedef GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +typedef GLXPixmap (*_glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap); +typedef void (*_glXDestroyContext)(Display *dpy, GLXContext ctx); +typedef void (*_glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix); +typedef const char* (*_glXGetClientString)(Display *dpy, int name ); +typedef int (*_glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value); +typedef Bool (*_glXIsDirect)(Display *dpy, GLXContext ctx); +typedef Bool (*_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx); +typedef Bool (*_glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase); +typedef const char* (*_glXQueryExtensionsString)(Display *dpy, int screen); +typedef const char* (*_glXQueryServerString)(Display *dpy, int screen, int name); +typedef void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable); +typedef void (*_glXUseXFont)(Font font, int first, int count, int listBase); +typedef void (*_glXWaitX)(void); + +extern _glCallLists qt_glCallLists; +extern _glClearColor qt_glClearColor; +extern _glClearIndex qt_glClearIndex; +extern _glColor3ub qt_glColor3ub; +extern _glDeleteLists qt_glDeleteLists; +extern _glDrawBuffer qt_glDrawBuffer; +extern _glFlush qt_glFlush; +extern _glIndexi qt_glIndexi; +extern _glListBase qt_glListBase; +extern _glLoadIdentity qt_glLoadIdentity; +extern _glMatrixMode qt_glMatrixMode; +extern _glOrtho qt_glOrtho; +extern _glPopAttrib qt_glPopAttrib; +extern _glPopMatrix qt_glPopMatrix; +extern _glPushAttrib qt_glPushAttrib; +extern _glPushMatrix qt_glPushMatrix; +extern _glRasterPos2i qt_glRasterPos2i; +extern _glRasterPos3d qt_glRasterPos3d; +extern _glReadPixels qt_glReadPixels; +extern _glViewport qt_glViewport; +extern _glPixelStorei qt_glPixelStorei; +extern _glBitmap qt_glBitmap; +extern _glDrawPixels qt_glDrawPixels; +extern _glNewList qt_glNewList; +extern _glGetFloatv qt_glGetFloatv; +extern _glGetIntegerv qt_glGetIntegerv; +extern _glEndList qt_glEndList; + +extern _glXChooseVisual qt_glXChooseVisual; +extern _glXCreateContext qt_glXCreateContext; +extern _glXCreateGLXPixmap qt_glXCreateGLXPixmap; +extern _glXDestroyContext qt_glXDestroyContext; +extern _glXDestroyGLXPixmap qt_glXDestroyGLXPixmap; +extern _glXGetClientString qt_glXGetClientString; +extern _glXGetConfig qt_glXGetConfig; +extern _glXIsDirect qt_glXIsDirect; +extern _glXMakeCurrent qt_glXMakeCurrent; +extern _glXQueryExtension qt_glXQueryExtension; +extern _glXQueryExtensionsString qt_glXQueryExtensionsString; +extern _glXQueryServerString qt_glXQueryServerString; +extern _glXSwapBuffers qt_glXSwapBuffers; +extern _glXUseXFont qt_glXUseXFont; +extern _glXWaitX qt_glXWaitX; +}; // extern "C" + +#define glCallLists qt_glCallLists +#define glClearColor qt_glClearColor +#define glClearIndex qt_glClearIndex +#define glColor3ub qt_glColor3ub +#define glDeleteLists qt_glDeleteLists +#define glDrawBuffer qt_glDrawBuffer +#define glFlush qt_glFlush +#define glIndexi qt_glIndexi +#define glListBase qt_glListBase +#define glLoadIdentity qt_glLoadIdentity +#define glMatrixMode qt_glMatrixMode +#define glOrtho qt_glOrtho +#define glPopAttrib qt_glPopAttrib +#define glPopMatrix qt_glPopMatrix +#define glPushAttrib qt_glPushAttrib +#define glPushMatrix qt_glPushMatrix +#define glRasterPos2i qt_glRasterPos2i +#define glRasterPos3d qt_glRasterPos3d +#define glReadPixels qt_glReadPixels +#define glViewport qt_glViewport +#define glPixelStorei qt_glPixelStorei +#define glBitmap qt_glBitmap +#define glDrawPixels qt_glDrawPixels +#define glNewList qt_glNewList +#define glGetFloatv qt_glGetFloatv +#define glGetIntegerv qt_glGetIntegerv +#define glEndList qt_glEndList + +#define glXChooseVisual qt_glXChooseVisual +#define glXCreateContext qt_glXCreateContext +#define glXCreateGLXPixmap qt_glXCreateGLXPixmap +#define glXDestroyContext qt_glXDestroyContext +#define glXDestroyGLXPixmap qt_glXDestroyGLXPixmap +#define glXGetClientString qt_glXGetClientString +#define glXGetConfig qt_glXGetConfig +#define glXIsDirect qt_glXIsDirect +#define glXMakeCurrent qt_glXMakeCurrent +#define glXQueryExtension qt_glXQueryExtension +#define glXQueryExtensionsString qt_glXQueryExtensionsString +#define glXQueryServerString qt_glXQueryServerString +#define glXSwapBuffers qt_glXSwapBuffers +#define glXUseXFont qt_glXUseXFont +#define glXWaitX qt_glXWaitX + +#else +inline bool qt_resolve_gl_symbols(bool = TRUE) { return TRUE; } +#endif // QT_DLOPEN_OPENGL +#endif // TQGL_P_H diff --git a/src/opengl/tqglcolormap.cpp b/src/opengl/tqglcolormap.cpp new file mode 100644 index 000000000..a9f176b96 --- /dev/null +++ b/src/opengl/tqglcolormap.cpp @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Implementation of TQGLColormap class +** +** Created : 20010326 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the opengl 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. +** +**********************************************************************/ + +/*! + \class TQGLColormap tqglcolormap.h + \brief The TQGLColormap class is used for installing custom colormaps into + TQGLWidgets. +\if defined(commercial) + It is part of the TQt Enterprise Edition. +\endif + + \module OpenGL + \ingroup graphics + \ingroup images + + TQGLColormap provides a platform independent way of specifying and + installing indexed colormaps into TQGLWidgets. TQGLColormap is + especially useful when using the \link opengl.html OpenGL\endlink + color-index mode. + + Under X11 you must use an X server that supports either a \c + PseudoColor or \c DirectColor visual class. If your X server + currently only provides a \c GrayScale, \c TrueColor, \c + StaticColor or \c StaticGray visual, you will not be able to + allocate colorcells for writing. If this is the case, try setting + your X server to 8 bit mode. It should then provide you with at + least a \c PseudoColor visual. Note that you may experience + colormap flashing if your X server is running in 8 bit mode. + + Under Windows the size of the colormap is always set to 256 + colors. Note that under Windows you can also install colormaps + in child widgets. + + This class uses explicit sharing (see \link shclass.html Shared + Classes\endlink). + + Example of use: + \code + #include + #include + + int main() + { + TQApplication a( argc, argv ); + + MySuperGLWidget widget( 0 ); // A TQGLWidget in color-index mode + TQGLColormap colormap; + + // This will fill the colormap with colors ranging from + // black to white. + for ( int i = 0; i < colormap.size(); i++ ) + colormap.setEntry( i, tqRgb( i, i, i ) ); + + widget.setColormap( colormap ); + widget.show(); + return a.exec(); + } + \endcode + + \sa TQGLWidget::setColormap(), TQGLWidget::colormap() +*/ + +#include "tqglcolormap.h" +#include "tqmemarray.h" + + +/*! + Construct a TQGLColormap. +*/ +TQGLColormap::TQGLColormap() +{ + d = 0; +} + + +/*! + Construct a shallow copy of \a map. +*/ +TQGLColormap::TQGLColormap( const TQGLColormap & map ) +{ + d = map.d; + if ( d ) + d->ref(); +} + +/*! + Dereferences the TQGLColormap and deletes it if this was the last + reference to it. +*/ +TQGLColormap::~TQGLColormap() +{ + if ( d && d->deref() ) { + delete d; + d = 0; + } +} + +/*! + Assign a shallow copy of \a map to this TQGLColormap. +*/ +TQGLColormap & TQGLColormap::operator=( const TQGLColormap & map ) +{ + if ( map.d != 0 ) + map.d->ref(); + + if ( d && d->deref() ) + delete d; + d = map.d; + + return *this; +} + +/*! + Detaches this TQGLColormap from the shared block. +*/ +void TQGLColormap::detach() +{ + if ( d && d->count != 1 ) { + // ### What about the actual colormap handle? + Private * newd = new Private(); + newd->cells = d->cells; + newd->cells.detach(); + if ( d->deref() ) + delete d; + d = newd; + } +} + +/*! + Set cell at index \a idx in the colormap to color \a color. +*/ +void TQGLColormap::setEntry( int idx, TQRgb color ) +{ + if ( !d ) + d = new Private(); + +#if defined(QT_CHECK_RANGE) + if ( idx < 0 || idx > (int) d->cells.size() ) { + tqWarning( "TQGLColormap::setRgb: Index out of range." ); + return; + } +#endif + d->cells[ idx ] = color; +} + +/*! + Set an array of cells in this colormap. \a count is the number of + colors that should be set, \a colors is the array of colors, and + \a base is the starting index. +*/ +void TQGLColormap::setEntries( int count, const TQRgb * colors, int base ) +{ + if ( !d ) + d = new Private(); + + if ( !colors || base < 0 || base >= (int) d->cells.size() ) + return; + + for( int i = base; i < base + count; i++ ) { + if ( i < (int) d->cells.size() ) + setEntry( i, colors[i] ); + else + break; + } +} + +/*! + Returns the TQRgb value in the colorcell with index \a idx. +*/ +TQRgb TQGLColormap::entryRgb( int idx ) const +{ + if ( !d || idx < 0 || idx > (int) d->cells.size() ) + return 0; + else + return d->cells[ idx ]; +} + +/*! + \overload + + Set the cell with index \a idx in the colormap to color \a color. +*/ +void TQGLColormap::setEntry( int idx, const TQColor & color ) +{ + setEntry( idx, color.rgb() ); +} + +/*! + Returns the TQRgb value in the colorcell with index \a idx. +*/ +TQColor TQGLColormap::entryColor( int idx ) const +{ + if ( !d || idx < 0 || idx > (int) d->cells.size() ) + return TQColor(); + else + return TQColor( d->cells[ idx ] ); +} + +/*! + Returns TRUE if the colormap is empty; otherwise returns FALSE. A + colormap with no color values set is considered to be empty. +*/ +bool TQGLColormap::isEmpty() const +{ + return (d == 0) || (d->cells.size() == 0) || (d->cmapHandle == 0); +} + + +/*! + Returns the number of colorcells in the colormap. +*/ +int TQGLColormap::size() const +{ + return d != 0 ? d->cells.size() : 0; +} + +/*! + Returns the index of the color \a color. If \a color is not in the + map, -1 is returned. +*/ +int TQGLColormap::find( TQRgb color ) const +{ + if ( d ) + return d->cells.find( color ); + return -1; +} + +/*! + Returns the index of the color that is the closest match to color + \a color. +*/ +int TQGLColormap::findNearest( TQRgb color ) const +{ + int idx = find( color ); + if ( idx >= 0 ) + return idx; + int mapSize = size(); + int mindist = 200000; + int r = tqRed( color ); + int g = tqGreen( color ); + int b = tqBlue( color ); + int rx, gx, bx, dist; + for ( int i=0; i < mapSize; i++ ) { + TQRgb ci = d->cells[i]; + rx = r - tqRed( ci ); + gx = g - tqGreen( ci ); + bx = b - tqBlue( ci ); + dist = rx*rx + gx*gx + bx*bx; // calculate distance + if ( dist < mindist ) { // minimal? + mindist = dist; + idx = i; + } + } + return idx; +} diff --git a/src/opengl/tqglcolormap.h b/src/opengl/tqglcolormap.h new file mode 100644 index 000000000..61fbd7c79 --- /dev/null +++ b/src/opengl/tqglcolormap.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Definition of TQGLColormap class +** +** Created : 20010326 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the opengl 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 TQGLCOLORMAP_H +#define TQGLCOLORMAP_H + +#ifndef QT_H +#include "tqcolor.h" +#include "tqmemarray.h" +#include "ntqshared.h" +#endif // QT_H + +#if !defined( TQT_MODULE_OPENGL ) || defined( QT_LICENSE_PROFESSIONAL ) +#define TQM_EXPORT_OPENGL +#else +#define TQM_EXPORT_OPENGL TQ_EXPORT +#endif + +class TQWidget; +class TQM_EXPORT_OPENGL TQGLColormap +{ +public: + TQGLColormap(); + TQGLColormap( const TQGLColormap & ); + ~TQGLColormap(); + + TQGLColormap &operator=( const TQGLColormap & ); + + bool isEmpty() const; + int size() const; + void detach(); + + void setEntries( int count, const TQRgb * colors, int base = 0 ); + void setEntry( int idx, TQRgb color ); + void setEntry( int idx, const TQColor & color ); + TQRgb entryRgb( int idx ) const; + TQColor entryColor( int idx ) const; + int find( TQRgb color ) const; + int findNearest( TQRgb color ) const; + +private: + class Private : public TQShared + { + public: + Private() { + cells.resize( 256 ); // ### hardcoded to 256 entries for now + cmapHandle = 0; + } + + ~Private() { + } + + TQMemArray cells; + TQt::HANDLE cmapHandle; + }; + + Private * d; + + friend class TQGLWidget; +}; + +#endif diff --git a/src/sql/drivers/psql/tqsql_psql.cpp b/src/sql/drivers/psql/tqsql_psql.cpp index b40d38447..df79ac2fd 100644 --- a/src/sql/drivers/psql/tqsql_psql.cpp +++ b/src/sql/drivers/psql/tqsql_psql.cpp @@ -43,7 +43,7 @@ #include -#include +#include #include #include #include diff --git a/src/styles/ntqinterlacestyle.h b/src/styles/ntqinterlacestyle.h index 61a0ed054..c2d22bf8e 100644 --- a/src/styles/ntqinterlacestyle.h +++ b/src/styles/ntqinterlacestyle.h @@ -48,7 +48,7 @@ #if !defined(TQT_NO_STYLE_INTERLACE) || defined(QT_PLUGIN) -#include "ntqpalette.h" +#include "tqpalette.h" class TQ_EXPORT TQInterlaceStyle : public TQMotifStyle { diff --git a/src/styles/qcommonstyle.cpp b/src/styles/qcommonstyle.cpp index bf3d03f7f..5f16b5b0e 100644 --- a/src/styles/qcommonstyle.cpp +++ b/src/styles/qcommonstyle.cpp @@ -47,7 +47,7 @@ #include "ntqapplication.h" #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqpushbutton.h" #include "ntqtabbar.h" #include "ntqtabwidget.h" @@ -70,7 +70,7 @@ #include "ntqlistbox.h" #include "private/qdialogbuttons_p.h" #include -#include +#include #include "../widgets/qtitlebar_p.h" #include diff --git a/src/styles/qcompactstyle.cpp b/src/styles/qcompactstyle.cpp index 32dcdb217..f2e9b1fc7 100644 --- a/src/styles/qcompactstyle.cpp +++ b/src/styles/qcompactstyle.cpp @@ -43,7 +43,7 @@ #if !defined(TQT_NO_STYLE_COMPACT) || defined(QT_PLUGIN) #include "tqfontmetrics.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "tqpainter.h" #include "ntqdrawutil.h" #include "tqmenudata.h" diff --git a/src/styles/qinterlacestyle.cpp b/src/styles/qinterlacestyle.cpp index cb6aa1124..5322c68ba 100644 --- a/src/styles/qinterlacestyle.cpp +++ b/src/styles/qinterlacestyle.cpp @@ -47,7 +47,7 @@ #include "ntqapplication.h" #include "tqpainter.h" #include "ntqdrawutil.h" // for now -#include "ntqpalette.h" // for now +#include "tqpalette.h" // for now #include "tqwidget.h" #include "ntqlabel.h" #include "ntqpushbutton.h" diff --git a/src/styles/qmotifplusstyle.cpp b/src/styles/qmotifplusstyle.cpp index 08308f1ff..4b0da7c8b 100644 --- a/src/styles/qmotifplusstyle.cpp +++ b/src/styles/qmotifplusstyle.cpp @@ -45,7 +45,7 @@ #include "tqmenubar.h" #include "ntqapplication.h" #include "tqpainter.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "ntqframe.h" #include "ntqpushbutton.h" #include "ntqcheckbox.h" diff --git a/src/styles/qmotifstyle.cpp b/src/styles/qmotifstyle.cpp index 05424c3f4..87d310127 100644 --- a/src/styles/qmotifstyle.cpp +++ b/src/styles/qmotifstyle.cpp @@ -46,8 +46,8 @@ #include "ntqapplication.h" #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" -#include "ntqpalette.h" +#include "tqpixmap.h" +#include "tqpalette.h" #include "tqwidget.h" #include "ntqpushbutton.h" #include "ntqscrollbar.h" diff --git a/src/styles/qplatinumstyle.cpp b/src/styles/qplatinumstyle.cpp index ebaf85229..ee2823a26 100644 --- a/src/styles/qplatinumstyle.cpp +++ b/src/styles/qplatinumstyle.cpp @@ -46,8 +46,8 @@ #include "ntqcombobox.h" #include "ntqdrawutil.h" #include "tqpainter.h" -#include "ntqpalette.h" -#include "ntqpixmap.h" +#include "tqpalette.h" +#include "tqpixmap.h" #include "ntqpushbutton.h" #include "ntqscrollbar.h" #include "ntqslider.h" diff --git a/src/styles/qsgistyle.cpp b/src/styles/qsgistyle.cpp index 2b273eeaf..ef4a6183d 100644 --- a/src/styles/qsgistyle.cpp +++ b/src/styles/qsgistyle.cpp @@ -47,8 +47,8 @@ #include "ntqbutton.h" #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" -#include "ntqpalette.h" +#include "tqpixmap.h" +#include "tqpalette.h" #include "tqwidget.h" #include "ntqpushbutton.h" #include "ntqscrollbar.h" diff --git a/src/styles/qwindowsstyle.cpp b/src/styles/qwindowsstyle.cpp index efc2597d9..1a9fff5e9 100644 --- a/src/styles/qwindowsstyle.cpp +++ b/src/styles/qwindowsstyle.cpp @@ -46,7 +46,7 @@ #include "ntqapplication.h" #include "tqpainter.h" #include "ntqdrawutil.h" // for now -#include "ntqpixmap.h" // for now +#include "tqpixmap.h" // for now #include "tqwidget.h" #include "ntqlabel.h" #include "tqimage.h" diff --git a/src/table/ntqtable.h b/src/table/ntqtable.h index 23bfd9337..dc2c2c0b8 100644 --- a/src/table/ntqtable.h +++ b/src/table/ntqtable.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "ntqscrollview.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqptrvector.h" #include "ntqheader.h" #include "tqmemarray.h" diff --git a/src/tools/qfeatures.txt b/src/tools/qfeatures.txt index e6c69180d..323f38109 100644 --- a/src/tools/qfeatures.txt +++ b/src/tools/qfeatures.txt @@ -13,7 +13,7 @@ SeeAlso: ??? Feature: WMATRIX Section: Data structures Requires: -Name: QWMatrix +Name: TQWMatrix SeeAlso: ??? Feature: STL @@ -549,7 +549,7 @@ SeeAlso: ??? Feature: PICTURE Section: Painting Requires: DATASTREAM IMAGEIO -Name: QPicture +Name: TQPicture SeeAlso: ??? Feature: LAYOUT diff --git a/src/tools/qwinexport.cpp b/src/tools/qwinexport.cpp index 64422497e..3356c5b67 100644 --- a/src/tools/qwinexport.cpp +++ b/src/tools/qwinexport.cpp @@ -5,8 +5,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/src/widgets/ntqlistbox.h b/src/widgets/ntqlistbox.h index a0eba4324..39a9b75de 100644 --- a/src/widgets/ntqlistbox.h +++ b/src/widgets/ntqlistbox.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "ntqscrollview.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #endif // QT_H #ifndef TQT_NO_LISTBOX diff --git a/src/widgets/ntqsplashscreen.h b/src/widgets/ntqsplashscreen.h index 9670a1476..99b625f9f 100644 --- a/src/widgets/ntqsplashscreen.h +++ b/src/widgets/ntqsplashscreen.h @@ -40,7 +40,7 @@ #define TQSPLASHSCREEN_H #ifndef QT_H -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqwidget.h" #endif // QT_H diff --git a/src/widgets/qbutton.cpp b/src/widgets/qbutton.cpp index a74074121..31fbe6349 100644 --- a/src/widgets/qbutton.cpp +++ b/src/widgets/qbutton.cpp @@ -45,7 +45,7 @@ #include "tqpainter.h" #include "tqtimer.h" #include "ntqaccel.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "ntqapplication.h" #include "ntqpushbutton.h" #include "ntqradiobutton.h" diff --git a/src/widgets/qcheckbox.cpp b/src/widgets/qcheckbox.cpp index 00e87041c..4e4d913ba 100644 --- a/src/widgets/qcheckbox.cpp +++ b/src/widgets/qcheckbox.cpp @@ -42,8 +42,8 @@ #ifndef TQT_NO_CHECKBOX #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmap.h" +#include "tqpixmapcache.h" #include "tqbitmap.h" #include "tqtextstream.h" #include "ntqapplication.h" diff --git a/src/widgets/qcombobox.cpp b/src/widgets/qcombobox.cpp index 3a7153f23..a491e7ca6 100644 --- a/src/widgets/qcombobox.cpp +++ b/src/widgets/qcombobox.cpp @@ -45,7 +45,7 @@ #include "tqpainter.h" #include "ntqdrawutil.h" #include "tqstrlist.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqtimer.h" #include "ntqapplication.h" #include "ntqlineedit.h" diff --git a/src/widgets/qdial.cpp b/src/widgets/qdial.cpp index 8e2a63b5a..f11218bf3 100644 --- a/src/widgets/qdial.cpp +++ b/src/widgets/qdial.cpp @@ -43,10 +43,10 @@ #ifndef TQT_NO_DIAL #include "tqpainter.h" -#include "ntqpointarray.h" +#include "tqpointarray.h" #include "tqcolor.h" #include "ntqapplication.h" -#include "ntqregion.h" +#include "tqregion.h" #include "tqbitmap.h" #include "tqstyle.h" #if defined(QT_ACCESSIBILITY_SUPPORT) diff --git a/src/widgets/qeffects.cpp b/src/widgets/qeffects.cpp index e81144261..6f9176175 100644 --- a/src/widgets/qeffects.cpp +++ b/src/widgets/qeffects.cpp @@ -42,7 +42,7 @@ #ifndef TQT_NO_EFFECTS #include "tqwidget.h" #include "qeffects_p.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqimage.h" #include "tqtimer.h" #include "tqdatetime.h" diff --git a/src/widgets/qheader.cpp b/src/widgets/qheader.cpp index c01ae5cc5..54d39ae35 100644 --- a/src/widgets/qheader.cpp +++ b/src/widgets/qheader.cpp @@ -42,7 +42,7 @@ #ifndef TQT_NO_HEADER #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqbitarray.h" #include "tqptrvector.h" #include "ntqapplication.h" diff --git a/src/widgets/qlabel.cpp b/src/widgets/qlabel.cpp index 87ba9da9e..7f2c5cbae 100644 --- a/src/widgets/qlabel.cpp +++ b/src/widgets/qlabel.cpp @@ -46,7 +46,7 @@ #include "tqmovie.h" #include "tqimage.h" #include "tqbitmap.h" -#include "ntqpicture.h" +#include "tqpicture.h" #include "ntqapplication.h" #include "ntqsimplerichtext.h" #include "tqstylesheet.h" diff --git a/src/widgets/qlineedit.cpp b/src/widgets/qlineedit.cpp index 5a3a43ae7..75570cc09 100644 --- a/src/widgets/qlineedit.cpp +++ b/src/widgets/qlineedit.cpp @@ -49,7 +49,7 @@ #include "tqpainter.h" #include "ntqdrawutil.h" #include "tqfontmetrics.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqclipboard.h" #include "ntqapplication.h" #include "ntqvalidator.h" diff --git a/src/widgets/qlistbox.cpp b/src/widgets/qlistbox.cpp index e9167ed62..ba0cd7b2a 100644 --- a/src/widgets/qlistbox.cpp +++ b/src/widgets/qlistbox.cpp @@ -50,7 +50,7 @@ #include "tqfontmetrics.h" #include "tqpainter.h" #include "tqstrlist.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqapplication.h" #include "tqptrdict.h" #include "tqtimer.h" diff --git a/src/widgets/qlistview.cpp b/src/widgets/qlistview.cpp index 0ad2bc374..5ee18d929 100644 --- a/src/widgets/qlistview.cpp +++ b/src/widgets/qlistview.cpp @@ -54,7 +54,7 @@ #include "tqptrvector.h" #include "tqiconset.h" #include "ntqcleanuphandler.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "tqpopupmenu.h" #include "ntqtl.h" #include "tqdragobject.h" diff --git a/src/widgets/qmultilineedit.cpp b/src/widgets/qmultilineedit.cpp index a0a7ebee3..85254a314 100644 --- a/src/widgets/qmultilineedit.cpp +++ b/src/widgets/qmultilineedit.cpp @@ -44,7 +44,7 @@ #include "ntqscrollbar.h" #include "ntqcursor.h" #include "tqclipboard.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqregexp.h" #include "ntqapplication.h" #include "tqdragobject.h" diff --git a/src/widgets/qprogressbar.cpp b/src/widgets/qprogressbar.cpp index c40bb19e9..b480ceb43 100644 --- a/src/widgets/qprogressbar.cpp +++ b/src/widgets/qprogressbar.cpp @@ -42,9 +42,9 @@ #ifndef TQT_NO_PROGRESSBAR #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqstyle.h" -#include "ntqwmatrix.h" +#include "tqwmatrix.h" #include "../kernel/qinternal_p.h" #if defined(QT_ACCESSIBILITY_SUPPORT) #include "ntqaccessible.h" diff --git a/src/widgets/qpushbutton.cpp b/src/widgets/qpushbutton.cpp index d87473237..37cbccd9d 100644 --- a/src/widgets/qpushbutton.cpp +++ b/src/widgets/qpushbutton.cpp @@ -44,7 +44,7 @@ #include "tqfontmetrics.h" #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqbitmap.h" #include "tqpopupmenu.h" #include "ntqguardedptr.h" diff --git a/src/widgets/qradiobutton.cpp b/src/widgets/qradiobutton.cpp index a0baddeee..dead844e5 100644 --- a/src/widgets/qradiobutton.cpp +++ b/src/widgets/qradiobutton.cpp @@ -43,8 +43,8 @@ #include "ntqbuttongroup.h" #include "tqpainter.h" #include "ntqdrawutil.h" -#include "ntqpixmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmap.h" +#include "tqpixmapcache.h" #include "tqbitmap.h" #include "tqtextstream.h" #include "ntqapplication.h" diff --git a/src/widgets/qscrollview.cpp b/src/widgets/qscrollview.cpp index 939f4da12..9c3bc060b 100644 --- a/src/widgets/qscrollview.cpp +++ b/src/widgets/qscrollview.cpp @@ -43,7 +43,7 @@ #include "ntqscrollbar.h" #include "tqobjectlist.h" #include "tqpainter.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqcursor.h" #include "ntqfocusdata.h" #include "ntqscrollview.h" diff --git a/src/widgets/qspinbox.cpp b/src/widgets/qspinbox.cpp index f11d42c8c..d6d85beef 100644 --- a/src/widgets/qspinbox.cpp +++ b/src/widgets/qspinbox.cpp @@ -47,7 +47,7 @@ #include "tqbitmap.h" #include "ntqlineedit.h" #include "ntqvalidator.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "ntqapplication.h" #include "tqstyle.h" #if defined(QT_ACCESSIBILITY_SUPPORT) diff --git a/src/widgets/qspinwidget.cpp b/src/widgets/qspinwidget.cpp index f46dfc40f..c5b237d41 100644 --- a/src/widgets/qspinwidget.cpp +++ b/src/widgets/qspinwidget.cpp @@ -40,7 +40,7 @@ #ifndef TQT_NO_SPINWIDGET -#include "ntqrect.h" +#include "tqrect.h" #include "tqtimer.h" #include "tqstyle.h" #include "tqpainter.h" diff --git a/src/widgets/qsplashscreen.cpp b/src/widgets/qsplashscreen.cpp index fa9e6a49d..b4ed5241e 100644 --- a/src/widgets/qsplashscreen.cpp +++ b/src/widgets/qsplashscreen.cpp @@ -42,7 +42,7 @@ #include "ntqapplication.h" #include "tqpainter.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" class TQSplashScreenPrivate { diff --git a/src/widgets/qwhatsthis.cpp b/src/widgets/qwhatsthis.cpp index 82f645830..65df04e7b 100644 --- a/src/widgets/qwhatsthis.cpp +++ b/src/widgets/qwhatsthis.cpp @@ -40,7 +40,7 @@ #ifndef TQT_NO_WHATSTHIS #include "ntqapplication.h" #include "tqpaintdevicemetrics.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqpainter.h" #include "tqtimer.h" #include "tqptrdict.h" diff --git a/src/widgets/tqdatetimeedit.cpp b/src/widgets/tqdatetimeedit.cpp index 0d21eee75..203d310de 100644 --- a/src/widgets/tqdatetimeedit.cpp +++ b/src/widgets/tqdatetimeedit.cpp @@ -46,7 +46,7 @@ #include "../kernel/qrichtext_p.h" #include "ntqrangecontrol.h" #include "ntqapplication.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "ntqapplication.h" #include "tqvaluelist.h" #include "tqstring.h" diff --git a/src/widgets/tqiconview.cpp b/src/widgets/tqiconview.cpp index f79ac974a..703912df9 100644 --- a/src/widgets/tqiconview.cpp +++ b/src/widgets/tqiconview.cpp @@ -51,10 +51,10 @@ #include "tqfontmetrics.h" #include "tqpainter.h" #include "ntqevent.h" -#include "ntqpalette.h" +#include "tqpalette.h" #include "tqmime.h" #include "tqimage.h" -#include "ntqpen.h" +#include "tqpen.h" #include "tqbrush.h" #include "tqtimer.h" #include "ntqcursor.h" @@ -65,7 +65,7 @@ #include "ntqvbox.h" #include "tqtooltip.h" #include "tqbitmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmapcache.h" #include "tqptrdict.h" #include "tqstringlist.h" #include "ntqcleanuphandler.h" diff --git a/src/widgets/tqiconview.h b/src/widgets/tqiconview.h index 625f18d54..bffaad207 100644 --- a/src/widgets/tqiconview.h +++ b/src/widgets/tqiconview.h @@ -44,13 +44,13 @@ #ifndef QT_H #include "ntqscrollview.h" #include "tqstring.h" -#include "ntqrect.h" -#include "ntqpoint.h" +#include "tqrect.h" +#include "tqpoint.h" #include "tqsize.h" #include "tqfont.h" // TQString->TQFont conversion #include "tqdragobject.h" #include "tqbitmap.h" -#include "ntqpicture.h" +#include "tqpicture.h" #endif // QT_H #ifndef TQT_NO_ICONVIEW diff --git a/src/widgets/tqpopupmenu.cpp b/src/widgets/tqpopupmenu.cpp index 5be453508..09961bf03 100644 --- a/src/widgets/tqpopupmenu.cpp +++ b/src/widgets/tqpopupmenu.cpp @@ -45,8 +45,8 @@ #include "tqpainter.h" #include "ntqdrawutil.h" #include "ntqapplication.h" -#include "ntqpixmap.h" -#include "ntqpixmapcache.h" +#include "tqpixmap.h" +#include "tqpixmapcache.h" #include "tqtimer.h" #include "ntqwhatsthis.h" #include "tqobjectlist.h" diff --git a/src/widgets/tqtextbrowser.h b/src/widgets/tqtextbrowser.h index 659ff5d15..33648fee2 100644 --- a/src/widgets/tqtextbrowser.h +++ b/src/widgets/tqtextbrowser.h @@ -43,7 +43,7 @@ #ifndef QT_H #include "tqptrlist.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqcolor.h" #include "tqtextedit.h" #endif // QT_H diff --git a/src/widgets/tqtextedit.cpp b/src/widgets/tqtextedit.cpp index a966110ce..a0887cb5d 100644 --- a/src/widgets/tqtextedit.cpp +++ b/src/widgets/tqtextedit.cpp @@ -49,9 +49,9 @@ #include "../kernel/qrichtext_p.h" #include "tqpainter.h" -#include "ntqpen.h" +#include "tqpen.h" #include "tqbrush.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqfont.h" #include "tqcolor.h" #include "tqstyle.h" diff --git a/src/widgets/tqtoolbutton.cpp b/src/widgets/tqtoolbutton.cpp index 78becfbe3..9872936e1 100644 --- a/src/widgets/tqtoolbutton.cpp +++ b/src/widgets/tqtoolbutton.cpp @@ -43,8 +43,8 @@ #include "ntqdrawutil.h" #include "tqpainter.h" -#include "ntqpixmap.h" -#include "ntqwmatrix.h" +#include "tqpixmap.h" +#include "tqwmatrix.h" #include "ntqapplication.h" #include "tqstyle.h" #include "tqmainwindow.h" diff --git a/src/widgets/tqtoolbutton.h b/src/widgets/tqtoolbutton.h index 98211e251..294cb4571 100644 --- a/src/widgets/tqtoolbutton.h +++ b/src/widgets/tqtoolbutton.h @@ -44,7 +44,7 @@ #ifndef QT_H #include "ntqbutton.h" #include "tqstring.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include "tqiconset.h" #endif // QT_H diff --git a/src/workspace/tqworkspace.cpp b/src/workspace/tqworkspace.cpp index 5ced56cef..bf4fe9de0 100644 --- a/src/workspace/tqworkspace.cpp +++ b/src/workspace/tqworkspace.cpp @@ -57,7 +57,7 @@ #include "ntqfocusdata.h" #include "tqdatetime.h" #include "tqtooltip.h" -#include "ntqwmatrix.h" +#include "tqwmatrix.h" #include "tqimage.h" #include "ntqscrollbar.h" #include "tqstyle.h" diff --git a/src/xml/qsvgdevice.cpp b/src/xml/qsvgdevice.cpp index 4de514c42..e6dfb86a0 100644 --- a/src/xml/qsvgdevice.cpp +++ b/src/xml/qsvgdevice.cpp @@ -48,7 +48,7 @@ #include "tqvaluelist.h" #include "tqtextstream.h" #include "tqimage.h" -#include "ntqpixmap.h" +#include "tqpixmap.h" #include diff --git a/src/xml/qsvgdevice_p.h b/src/xml/qsvgdevice_p.h index c70fbe43d..ffdec75fd 100644 --- a/src/xml/qsvgdevice_p.h +++ b/src/xml/qsvgdevice_p.h @@ -55,7 +55,7 @@ #ifndef QT_H #include "tqpaintdevice.h" -#include "ntqrect.h" +#include "tqrect.h" #include "tqdom.h" #endif // QT_H -- cgit v1.2.3