summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqpainter_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter_x11.cpp3410
1 files changed, 0 insertions, 3410 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp b/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp
deleted file mode 100644
index f5ad348..0000000
--- a/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp
+++ /dev/null
@@ -1,3410 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQPainter class for X11
-**
-** Created : 940112
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the kernel module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqplatformdefs.h"
-
-#ifdef USE_QT4
-#include <Qt/qtextstream.h>
-#endif // USE_QT4
-
-#include "tqfont.h"
-#include "tqpainter.h"
-#include "tqwidget.h"
-#include "tqbitmap.h"
-#include "tqpixmapcache.h"
-#include "tqtextcodec.h"
-#include "tqpaintdevicemetrics.h"
-
-#include "tqt_x11_p.h"
-
-#include "tqtextlayout_p.h"
-#include "tqfontdata_p.h"
-#include "tqfontengine_p.h"
-#include "tqtextengine_p.h"
-
-#include <math.h>
-
-#ifdef USE_QT4
-
-/*! \internal
- Draws the text item \a ti at position \a (x, y ).
-
- This method ignores the painters background mode and
- color. drawText and qt_format_text have to do it themselves, as
- only they know the extents of the complete string.
-
- It ignores the font set on the painter as the text item has one of its own.
-
- The underline and strikeout parameters of the text items font are
- ignored as well. You'll need to pass in the correct flags to get
- underlining and strikeout.
-*/
-void TQPainter::tqdrawTextItem( int x, int y, const TQTextItem &ti, int textFlags )
-{
- ti.tqt_tqdrawTextItem( const_cast<TQPainter*>(this), x, y, ti, textFlags );
-}
-
-/*!
- Sets the \link TQt::RasterOp raster operation \endlink to \a r.
- The default is \c CopyROP.
-
- \sa rasterOp() TQt::RasterOp
-*/
-
-void TQPainter::setRasterOp( TQt::RasterOp r )
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::setRasterOp: Call begin() first" );
-#endif
- return;
- }
- if ( (uint)r > TQt::LastROP ) {
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPainter::setRasterOp: Invalid ROP code" );
-#endif
- return;
- }
- rop = r;
-
-// [FIXME]
-// This needs to be implemented for Qt4
-// See http://lists.trolltech.com/qt-interest/2007-05/thread00975-0.html
-// printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
-
-// An attempt to work around this on X11 only
-// See http://doc.qt.nokia.com/latest/qpainter.html#CompositionMode-enum
-
- QPainter::CompositionMode cm;
- switch (rop) {
- case CopyROP:
- cm=QPainter::CompositionMode_SourceOver;
- break;
- case OrROP:
- cm=QPainter::RasterOp_SourceOrDestination;
- break;
- case XorROP:
- cm=QPainter::RasterOp_SourceXorDestination;
- break;
- case NotAndROP:
- cm=QPainter::RasterOp_NotSourceAndDestination;
- break;
-// case EraseROP:
-// cm=QPainter::RasterOp_NotSourceAndDestination;
-// break;
- case NotCopyROP:
- cm=QPainter::RasterOp_NotSource;
- break;
- case NotOrROP:
- printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
- return;
- break;
- case NotXorROP:
- cm=QPainter::RasterOp_NotSourceXorDestination;
- break;
- case AndROP:
- cm=QPainter::RasterOp_SourceAndDestination;
- break;
-// case NotEraseROP:
-// cm=QPainter::RasterOp_SourceAndDestination;
-// break;
- case NotROP:
- cm=QPainter::RasterOp_SourceAndNotDestination; // [WARNING] This may not be a correct substitute for NotROP!
- break;
- case ClearROP:
- cm=QPainter::CompositionMode_Clear;
- break;
- case SetROP:
- printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
- return;
- break;
- case NopROP:
- cm=QPainter::CompositionMode_Destination;
- break;
- case AndNotROP:
- cm=QPainter::RasterOp_SourceAndNotDestination;
- break;
- case OrNotROP:
- printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
- return;
- break;
- case NandROP:
- cm=QPainter::RasterOp_NotSourceOrNotDestination;
- break;
- case NorROP:
- cm=QPainter::RasterOp_NotSourceAndNotDestination;
- break;
- }
-
- setCompositionMode(cm);
-
-// if ( testf(ExtDev) ) {
-// TQPDevCmdParam param[1];
-// param[0].ival = r;
-// if ( !pdev->cmd( TQPaintDevice::PdcSetROP, this, param ) || !hd )
-// return;
-// }
-// if ( penRef )
-// updatePen(); // get non-cached pen GC
-// if ( brushRef )
-// updateBrush(); // get non-cached brush GC
-// XSetFunction( dpy, gc, ropCodes[rop] );
-// XSetFunction( dpy, gc_brush, ropCodes[rop] );
-}
-
-/*!
- \internal
-*/
-
-void TQPainter::drawWinFocusRect( int x, int y, int w, int h, bool xorPaint, const QColor &bgColor )
-{
- if ( !isActive() /*|| txop == TxRotShear*/ )
- return;
- static char winfocus_line[] = { 1, 1 };
-
- TQPen old_pen = pen();
- RasterOp old_rop = (RasterOp)rasterOp();
-
- if ( xorPaint ) {
- if ( TQColor::numBitPlanes() <= 8 )
- setPen( color1 );
- else
- setPen( white );
- setRasterOp( XorROP );
- } else {
- if ( tqGray( bgColor.rgb() ) < 128 )
- setPen( white );
- else
- setPen( black );
- }
-
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
-// TQPDevCmdParam param[1];
-// TQRect r( x, y, w, h );
-// param[0].rect = &r;
-// if ( !pdev->cmd( TQPaintDevice::PdcDrawRect, this, param ) || !hd) {
-// setRasterOp( old_rop );
-// setPen( old_pen );
-// return;
-// }
- printf("[FIXME] TQPainter::drawWinFocusRect not yet supported on external paint devices\n\r");
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
-// if ( w <= 0 || h <= 0 ) {
-// if ( w == 0 || h == 0 )
-// return;
-// fix_neg_rect( &x, &y, &w, &h );
-// }
-
-// XSetDashes( dpy, gc, 0, winfocus_line, 2 );
-// XSetLineAttributes( dpy, gc, 1, LineOnOffDash, CapButt, JoinMiter );
-// XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
-// XSetLineAttributes( dpy, gc, 0, LineSolid, CapButt, JoinMiter );
-
- printf("[WARNING] TQPainter::drawWinFocusRect may not draw the correct rectangle in all cases [due to shift from Xorg to Qt painting]\n\r");
-// drawRect( x, y, w-1, h-1 );
- drawRect( x, y, w, h );
-
- setRasterOp( old_rop );
- setPen( old_pen );
-}
-
-/*!
- Draws the polyline defined by the \a npoints points in \a a
- starting at \a a[index]. (\a index defaults to 0.)
-
- If \a npoints is -1 (the default) all points until the end of the
- array are used (i.e. a.size()-index-1 line segments are drawn).
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-
- \sa drawLineSegments(), drawPolygon(), TQPen
-*/
-
-void TQPainter::tqdrawPolyline( const TQPointArray &a, int index, int npoints )
-{
- if ( npoints < 0 )
- npoints = a.size() - index;
- if ( index + npoints > (int)a.size() )
- npoints = a.size() - index;
- if ( !isActive() || npoints < 2 || index < 0 )
- return;
- TQPointArray pa = a;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
-// if ( npoints != (int)pa.size() ) {
-// pa = TQPointArray( npoints );
-// for ( int i=0; i<npoints; i++ )
-// pa.setPoint( i, a.point(index+i) );
-// index = 0;
-// }
-// TQPDevCmdParam param[1];
-// param[0].ptarr = (TQPointArray*)&pa;
-// if ( !pdev->cmd(TQPaintDevice::PdcDrawPolyline, this, param) || !hd )
-// return;
- printf("[FIXME] TQPainter::drawPolyline not yet supported on external paint devices\n\r");
- }
-#if 0
- if ( txop != TxNone ) {
- pa = xForm( pa, index, npoints );
- if ( pa.size() != a.size() ) {
- index = 0;
- npoints = pa.size();
- }
- }
- }
- if ( cpen.style() != Qt::NoPen ) {
- while(npoints>65535) {
- XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, 65535 )),
- 65535, CoordModeOrigin );
- npoints-=65535;
- index+=65535;
- }
- XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
- npoints, CoordModeOrigin );
- }
-#else
- }
- printf("[WARNING] TQPainter::tqdrawPolyline UNIMPLEMENTED\n\r");
-#endif
-}
-
-#else // USE_QT4
-
-// paintevent magic to provide Windows semantics on X11
-static TQRegion* paintEventClipRegion = 0;
-static TQPaintDevice* paintEventDevice = 0;
-
-void qt_set_paintevent_clipping( TQPaintDevice* dev, const TQRegion& region)
-{
- if ( !paintEventClipRegion )
- paintEventClipRegion = new TQRegion( region );
- else
- *paintEventClipRegion = region;
- paintEventDevice = dev;
-}
-
-void qt_clear_paintevent_clipping()
-{
- delete paintEventClipRegion;
- paintEventClipRegion = 0;
- paintEventDevice = 0;
-}
-
-class TQWFlagWidget : public TQWidget
-{
-public:
- void setWState( WFlags f ) { TQWidget::setWState(f); }
- void clearWState( WFlags f ) { TQWidget::clearWState(f); }
- void setWFlags( WFlags f ) { TQWidget::setWFlags(f); }
- void clearWFlags( WFlags f ) { TQWidget::clearWFlags(f); }
-};
-
-void qt_erase_region( TQWidget* w, const TQRegion& region)
-{
- TQRegion reg = region;
-
- if ( TQPainter::redirect(w) || (!w->isTopLevel() && w->backgroundPixmap()
- && w->backgroundOrigin() != TQWidget::WidgetOrigin) ) {
- TQPoint offset = w->backgroundOffset();
- int ox = offset.x();
- int oy = offset.y();
-
- bool unclipped = w->testWFlags( TQt::WPaintUnclipped );
- if ( unclipped )
- ((TQWFlagWidget*)w)->clearWFlags( TQt::WPaintUnclipped );
- TQPainter p( w );
- p.setClipRegion( region ); // automatically includes paintEventDevice if required
- if ( w->backgroundPixmap() )
- p.drawTiledPixmap( 0, 0, w->width(), w->height(),
- *w->backgroundPixmap(), ox, oy );
- else
- p.fillRect( w->rect(), w->eraseColor() );
- if ( unclipped )
- ((TQWFlagWidget*)w)->setWFlags( TQt::WPaintUnclipped );
- return;
- }
-
- if ( w == paintEventDevice && paintEventClipRegion )
- reg = paintEventClipRegion->intersect( reg );
-
- TQMemArray<TQRect> r = reg.rects();
- for (uint i=0; i<r.size(); i++) {
- const TQRect& rr = r[(int)i];
- XClearArea( w->x11Display(), w->winId(),
- rr.x(), rr.y(), rr.width(), rr.height(), False );
- }
-}
-
-void qt_erase_rect( TQWidget* w, const TQRect& r)
-{
- if ( TQPainter::redirect(w) || w == paintEventDevice
- || w->backgroundOrigin() != TQWidget::WidgetOrigin )
- qt_erase_region( w, r );
- else
- XClearArea( w->x11Display(), w->winId(), r.x(), r.y(), r.width(), r.height(), False );
-
-}
-
-#ifdef TQT_NO_XFTFREETYPE
-static const TQt::HANDLE rendhd = 0;
-#endif
-
-// hack, so we don't have to make TQRegion::clipRectangles() public or include
-// X11 headers in tqregion.h
-inline void *qt_getClipRects( const TQRegion &r, int &num )
-{
- return r.clipRectangles( num );
-}
-
-static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2, TQt::HANDLE draw, const TQRegion &r)
-{
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects( r, num );
-
- if (gc)
- XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );
- if (gc2)
- XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );
-
-#ifndef TQT_NO_XFTFREETYPE
- if (draw)
- XftDrawSetClipRectangles((XftDraw *) draw, 0, 0, rects, num);
-#else
- TQ_UNUSED(draw);
-#endif // TQT_NO_XFTFREETYPE
-}
-
-static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2, TQt::HANDLE draw)
-{
- if (gc)
- XSetClipMask(dpy, gc, None);
- if (gc2)
- XSetClipMask(dpy, gc2, None);
-
-#ifndef TQT_NO_XFTFREETYPE
- if (draw) {
-# ifdef TQT_XFT2
- XftDrawSetClip((XftDraw *) draw, None);
-# else
- // stupid Xft1
- Picture pict = XftDrawPicture((XftDraw *) draw);
- XRenderPictureAttributes pattr;
- pattr.clip_mask = None;
- XRenderChangePicture(dpy, pict, CPClipMask, &pattr);
-# endif // TQT_XFT2
- }
-#else
- TQ_UNUSED(draw);
-#endif // TQT_NO_XFTFREETYPE
-}
-
-
-/*****************************************************************************
- Trigonometric function for TQPainter
-
- We have implemented simple sine and cosine function that are called from
- TQPainter::drawPie() and TQPainter::drawChord() when drawing the outline of
- pies and chords.
- These functions are slower and less accurate than math.h sin() and cos(),
- but with still around 1/70000th sec. execution time (on a 486DX2-66) and
- 8 digits accuracy, it should not be the bottleneck in drawing these tqshapes.
- The advantage is that you don't have to link in the math library.
- *****************************************************************************/
-
-const double TQ_PI = 3.14159265358979323846; // pi
-const double TQ_2PI = 6.28318530717958647693; // 2*pi
-const double TQ_PI2 = 1.57079632679489661923; // pi/2
-
-
-#if defined(TQ_CC_GNU) && defined(TQ_OS_AIX)
-// AIX 4.2 gcc 2.7.2.3 gets internal error.
-static int tqRoundAIX( double d )
-{
- return tqRound(d);
-}
-#define tqRound tqRoundAIX
-#endif
-
-
-#if defined(TQ_CC_GNU) && defined(__i386__)
-
-inline double qcos( double a )
-{
- double r;
- __asm__ (
- "fcos"
- : "=t" (r) : "0" (a) );
- return(r);
-}
-
-inline double qsin( double a )
-{
- double r;
- __asm__ (
- "fsin"
- : "=t" (r) : "0" (a) );
- return(r);
-}
-
-double qsincos( double a, bool calcCos=FALSE )
-{
- return calcCos ? qcos(a) : qsin(a);
-}
-
-#else
-
-double qsincos( double a, bool calcCos=FALSE )
-{
- if ( calcCos ) // calculate cosine
- a -= TQ_PI2;
- if ( a >= TQ_2PI || a <= -TQ_2PI ) { // fix range: -2*pi < a < 2*pi
- int m = (int)(a/TQ_2PI);
- a -= TQ_2PI*m;
- }
- if ( a < 0.0 ) // 0 <= a < 2*pi
- a += TQ_2PI;
- int sign = a > TQ_PI ? -1 : 1;
- if ( a >= TQ_PI )
- a = TQ_2PI - a;
- if ( a >= TQ_PI2 )
- a = TQ_PI - a;
- if ( calcCos )
- sign = -sign;
- double a2 = a*a; // here: 0 <= a < pi/4
- double a3 = a2*a; // make taylor sin sum
- double a5 = a3*a2;
- double a7 = a5*a2;
- double a9 = a7*a2;
- double a11 = a9*a2;
- return (a-a3/6+a5/120-a7/5040+a9/362880-a11/39916800)*sign;
-}
-
-inline double qsin( double a ) { return qsincos(a, FALSE); }
-inline double qcos( double a ) { return qsincos(a, TRUE); }
-
-#endif
-
-
-/*****************************************************************************
- TQPainter internal GC (Graphics Context) allocator.
-
- The GC allocator offers two functions; alloc_gc() and free_gc() that
- reuse GC objects instead of calling XCreateGC() and XFreeGC(), which
- are a whole lot slower.
- *****************************************************************************/
-
-struct TQGC
-{
- GC gc;
- char in_use;
- bool mono;
- int scrn;
-};
-
-const int gc_array_size = 256;
-static TQGC gc_array[gc_array_size]; // array of GCs
-static bool gc_array_init = FALSE;
-
-
-static void init_gc_array()
-{
- if ( !gc_array_init ) {
- memset( gc_array, 0, gc_array_size*sizeof(TQGC) );
- gc_array_init = TRUE;
- }
-}
-
-static void cleanup_gc_array( Display *dpy )
-{
- register TQGC *p = gc_array;
- int i = gc_array_size;
- if ( gc_array_init ) {
- while ( i-- ) {
- if ( p->gc ) // destroy GC
- XFreeGC( dpy, p->gc );
- p++;
- }
- gc_array_init = FALSE;
- }
-}
-
-// #define DONT_USE_GC_ARRAY
-
-static GC alloc_gc( Display *dpy, int scrn, Drawable hd, bool monochrome=FALSE,
- bool privateGC = FALSE )
-{
-#if defined(DONT_USE_GC_ARRAY)
- privateGC = TRUE; // will be slower
-#endif
- if ( privateGC ) {
- GC gc = XCreateGC( dpy, hd, 0, 0 );
- XSetGraphicsExposures( dpy, gc, False );
- return gc;
- }
- register TQGC *p = gc_array;
- int i = gc_array_size;
- if ( !gc_array_init ) // not initialized
- init_gc_array();
- while ( i-- ) {
- if ( !p->gc ) { // create GC (once)
- p->gc = XCreateGC( dpy, hd, 0, 0 );
- p->scrn = scrn;
- XSetGraphicsExposures( dpy, p->gc, False );
- p->in_use = FALSE;
- p->mono = monochrome;
- }
- if ( !p->in_use && p->mono == monochrome && p->scrn == scrn ) {
- p->in_use = TRUE; // available/compatible GC
- return p->gc;
- }
- p++;
- }
-#if defined(TQT_CHECK_NULL)
- qWarning( "TQPainter: Internal error; no available GC" );
-#endif
- GC gc = XCreateGC( dpy, hd, 0, 0 );
- XSetGraphicsExposures( dpy, gc, False );
- return gc;
-}
-
-static void free_gc( Display *dpy, GC gc, bool privateGC = FALSE )
-{
-#if defined(DONT_USE_GC_ARRAY)
- privateGC = TRUE; // will be slower
-#endif
- if ( privateGC ) {
- TQ_ASSERT( dpy != 0 );
- XFreeGC( dpy, gc );
- return;
- }
- register TQGC *p = gc_array;
- int i = gc_array_size;
- if ( gc_array_init ) {
- while ( i-- ) {
- if ( p->gc == gc ) {
- p->in_use = FALSE; // set available
- XSetClipMask( dpy, gc, None ); // make it reusable
- XSetFunction( dpy, gc, GXcopy );
- XSetFillStyle( dpy, gc, FillSolid );
- XSetTSOrigin( dpy, gc, 0, 0 );
- return;
- }
- p++;
- }
- }
-
- // not found in gc_array
- XFreeGC(dpy, gc);
-}
-
-
-/*****************************************************************************
- TQPainter internal GC (Graphics Context) cache for solid pens and
- brushes.
-
- The GC cache makes a significant contribution to speeding up
- drawing. Setting new pen and brush colors will make the painter
- look for another GC with the same color instead of changing the
- color value of the GC currently in use. The cache structure is
- optimized for fast lookup. Only solid line pens with line width 0
- and solid brushes are cached.
-
- In addition, stored GCs may have an implicit clipping region
- set. This prevents any drawing outside paint events. Both
- updatePen() and updateBrush() keep track of the validity of this
- clipping region by storing the clip_serial number in the cache.
-
-*****************************************************************************/
-
-struct TQGCC // cached GC
-{
- GC gc;
- uint pix;
- int count;
- int hits;
- uint clip_serial;
- int scrn;
-};
-
-const int gc_cache_size = 29; // multiply by 4
-static TQGCC *gc_cache_buf;
-static TQGCC *gc_cache[4*gc_cache_size];
-static bool gc_cache_init = FALSE;
-static uint gc_cache_clip_serial = 0;
-
-
-static void init_gc_cache()
-{
- if ( !gc_cache_init ) {
- gc_cache_init = TRUE;
- gc_cache_clip_serial = 0;
- TQGCC *g = gc_cache_buf = new TQGCC[4*gc_cache_size];
- memset( g, 0, 4*gc_cache_size*sizeof(TQGCC) );
- for ( int i=0; i<4*gc_cache_size; i++ )
- gc_cache[i] = g++;
- }
-}
-
-
-// #define GC_CACHE_STAT
-#if defined(GC_CACHE_STAT)
-#include "tqtextstream.h"
-#include "tqbuffer.h"
-
-static int g_numhits = 0;
-static int g_numcreates = 0;
-static int g_numfaults = 0;
-#endif
-
-
-static void cleanup_gc_cache()
-{
- if ( !gc_cache_init )
- return;
-#if defined(GC_CACHE_STAT)
- qDebug( "Number of cache hits = %d", g_numhits );
- qDebug( "Number of cache creates = %d", g_numcreates );
- qDebug( "Number of cache faults = %d", g_numfaults );
- for ( int i=0; i<gc_cache_size; i++ ) {
- TQCString str;
- TQBuffer buf( str );
- buf.open(IO_ReadWrite);
- TQTextStream s(&buf);
- s << i << ": ";
- for ( int j=0; j<4; j++ ) {
- TQGCC *g = gc_cache[i*4+j];
- s << (g->gc ? 'X' : '-') << ',' << g->hits << ','
- << g->count << '\t';
- }
- s << '\0';
- qDebug( str );
- buf.close();
- }
-#endif
- delete [] gc_cache_buf;
- gc_cache_init = FALSE;
-}
-
-
-static bool obtain_gc( void **ref, GC *gc, uint pix, Display *dpy, int scrn,
- TQt::HANDLE hd, uint painter_clip_serial )
-{
- if ( !gc_cache_init )
- init_gc_cache();
-
- int k = (pix % gc_cache_size) * 4;
- TQGCC *g = gc_cache[k];
- TQGCC *prev = 0;
-
-#define NOMATCH (g->gc && (g->pix != pix || g->scrn != scrn || \
- (g->clip_serial > 0 && g->clip_serial != painter_clip_serial)))
-
- if ( NOMATCH ) {
- prev = g;
- g = gc_cache[++k];
- if ( NOMATCH ) {
- prev = g;
- g = gc_cache[++k];
- if ( NOMATCH ) {
- prev = g;
- g = gc_cache[++k];
- if ( NOMATCH ) {
- if ( g->count == 0 && g->scrn == scrn) { // steal this GC
- g->pix = pix;
- g->count = 1;
- g->hits = 1;
- g->clip_serial = 0;
- XSetForeground( dpy, g->gc, pix );
- XSetClipMask(dpy, g->gc, None);
- gc_cache[k] = prev;
- gc_cache[k-1] = g;
- *ref = (void *)g;
- *gc = g->gc;
- return TRUE;
- } else { // all GCs in use
-#if defined(GC_CACHE_STAT)
- g_numfaults++;
-#endif
- *ref = 0;
- return FALSE;
- }
- }
- }
- }
- }
-
-#undef NOMATCH
-
- *ref = (void *)g;
-
- if ( g->gc ) { // reuse existing GC
-#if defined(GC_CACHE_STAT)
- g_numhits++;
-#endif
- *gc = g->gc;
- g->count++;
- g->hits++;
- if ( prev && g->hits > prev->hits ) { // maintain LRU order
- gc_cache[k] = prev;
- gc_cache[k-1] = g;
- }
- return TRUE;
- } else { // create new GC
-#if defined(GC_CACHE_STAT)
- g_numcreates++;
-#endif
- g->gc = alloc_gc( dpy, scrn, hd, FALSE );
- g->scrn = scrn;
- g->pix = pix;
- g->count = 1;
- g->hits = 1;
- g->clip_serial = 0;
- *gc = g->gc;
- return FALSE;
- }
-}
-
-static inline void release_gc( void *ref )
-{
- ((TQGCC*)ref)->count--;
-}
-
-/*****************************************************************************
- TQPainter member functions
- *****************************************************************************/
-
-/*!
- \internal
-
- Internal function that initializes the painter.
-*/
-
-void TQPainter::initialize()
-{
- init_gc_array();
- init_gc_cache();
-}
-
-/*!
- \internal
-
- Internal function that cleans up the painter.
-*/
-
-void TQPainter::cleanup()
-{
- cleanup_gc_cache();
- cleanup_gc_array( TQPaintDevice::x11AppDisplay() );
- TQPointArray::cleanBuffers();
-}
-
-/*!
- \internal
-
- Internal function that destroys up the painter.
-*/
-
-void TQPainter::destroy()
-{
-
-}
-
-void TQPainter::init()
-{
- d = 0;
- flags = IsStartingUp;
- bg_col = white; // default background color
- bg_mode = TransparentMode; // default background mode
- rop = CopyROP; // default ROP
- tabstops = 0; // default tabbing
- tabarray = 0;
- tabarraylen = 0;
- ps_stack = 0;
- wm_stack = 0;
- gc = gc_brush = 0;
- pdev = 0;
- dpy = 0;
- txop = txinv = 0;
- penRef = brushRef = 0;
- clip_serial = 0;
- pfont = 0;
- block_ext = FALSE;
-}
-
-
-/*!
- \fn const TQFont &TQPainter::font() const
-
- Returns the currently set painter font.
-
- \sa setFont(), TQFont
-*/
-
-/*!
- Sets the painter's font to \a font.
-
- This font is used by subsequent drawText() functions. The text
- color is the same as the pen color.
-
- \sa font(), drawText()
-*/
-
-void TQPainter::setFont( const TQFont &font )
-{
-#if defined(TQT_CHECK_STATE)
- if ( !isActive() )
- qWarning( "TQPainter::setFont: Will be reset by begin()" );
-#endif
- if ( cfont.d != font.d ) {
- cfont = font;
- cfont.x11SetScreen( scrn );
- setf(DirtyFont);
- }
-}
-
-
-void TQPainter::updateFont()
-{
- if (!isActive())
- return;
-
- clearf(DirtyFont);
- if ( testf(ExtDev) ) {
- if (pdev->devType() == TQInternal::Printer) {
- if ( pfont ) delete pfont;
- pfont = new TQFont( cfont.d, pdev );
- }
- TQPDevCmdParam param[1];
- param[0].font = &cfont;
- if ( !pdev->cmd( TQPaintDevice::PdcSetFont, this, param ) || !hd )
- return;
- }
- setf(NoCache);
- if ( penRef )
- updatePen(); // force a non-cached GC
-}
-
-
-void TQPainter::updatePen()
-{
- if (!isActive())
- return;
-
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].pen = &cpen;
- if ( !pdev->cmd( TQPaintDevice::PdcSetPen, this, param ) || !hd )
- return;
- }
-
- int ps = cpen.style();
- bool cacheIt = !testf(ClipOn|MonoDev|NoCache) &&
- (ps == NoPen || ps == SolidLine) &&
- cpen.width() == 0 && rop == CopyROP;
-
- bool obtained = FALSE;
- bool internclipok = hasClipping();
- if ( cacheIt ) {
- if ( gc ) {
- if ( penRef )
- release_gc( penRef );
- else
- free_gc( dpy, gc );
- }
- obtained = obtain_gc(&penRef, &gc, cpen.color().pixel(scrn), dpy, scrn,
- hd, clip_serial);
- if ( !obtained && !penRef )
- gc = alloc_gc( dpy, scrn, hd, FALSE );
- } else {
- if ( gc ) {
- if ( penRef ) {
- release_gc( penRef );
- penRef = 0;
- gc = alloc_gc( dpy, scrn, hd, testf(MonoDev) );
- } else {
- internclipok = TRUE;
- }
- } else {
- gc = alloc_gc( dpy, scrn, hd, testf(MonoDev), testf(UsePrivateCx) );
- }
- }
-
- if ( !internclipok ) {
- if ( pdev == paintEventDevice && paintEventClipRegion ) {
- if ( penRef &&((TQGCC*)penRef)->clip_serial < gc_cache_clip_serial ) {
- x11SetClipRegion( dpy, gc, 0, rendhd, *paintEventClipRegion );
- ((TQGCC*)penRef)->clip_serial = gc_cache_clip_serial;
- } else if ( !penRef ) {
- x11SetClipRegion( dpy, gc, 0, rendhd, *paintEventClipRegion );
- }
- } else if (penRef && ((TQGCC*)penRef)->clip_serial ) {
- x11ClearClipRegion(dpy, gc, 0, rendhd);
- ((TQGCC*)penRef)->clip_serial = 0;
- }
- }
-
- if ( obtained )
- return;
-
- char dashes[10]; // custom pen dashes
- int dash_len = 0; // length of dash list
- int s = LineSolid;
- int cp = CapButt;
- int jn = JoinMiter;
-
- /*
- We are emulating Windows here. Windows treats cpen.width() == 1
- (or 0) as a very special case. The fudge variable unifies this
- case with the general case.
- */
- int dot = cpen.width(); // width of a dot
- int fudge = 1;
- bool allow_zero_lw = TRUE;
- if ( dot <= 1 ) {
- dot = 3;
- fudge = 2;
- }
-
- switch( ps ) {
- case NoPen:
- case SolidLine:
- s = LineSolid;
- break;
- case DashLine:
- dashes[0] = fudge * 3 * dot;
- dashes[1] = fudge * dot;
- dash_len = 2;
- allow_zero_lw = FALSE;
- break;
- case DotLine:
- dashes[0] = dot;
- dashes[1] = dot;
- dash_len = 2;
- allow_zero_lw = FALSE;
- break;
- case DashDotLine:
- dashes[0] = 3 * dot;
- dashes[1] = fudge * dot;
- dashes[2] = dot;
- dashes[3] = fudge * dot;
- dash_len = 4;
- allow_zero_lw = FALSE;
- break;
- case DashDotDotLine:
- dashes[0] = 3 * dot;
- dashes[1] = dot;
- dashes[2] = dot;
- dashes[3] = dot;
- dashes[4] = dot;
- dashes[5] = dot;
- dash_len = 6;
- allow_zero_lw = FALSE;
- }
- TQ_ASSERT( dash_len <= (int) sizeof(dashes) );
-
- switch ( cpen.capStyle() ) {
- case SquareCap:
- cp = CapProjecting;
- break;
- case RoundCap:
- cp = CapRound;
- break;
- case FlatCap:
- default:
- cp = CapButt;
- break;
- }
- switch ( cpen.joinStyle() ) {
- case BevelJoin:
- jn = JoinBevel;
- break;
- case RoundJoin:
- jn = JoinRound;
- break;
- case MiterJoin:
- default:
- jn = JoinMiter;
- break;
- }
-
- XSetForeground( dpy, gc, cpen.color().pixel(scrn) );
- XSetBackground( dpy, gc, bg_col.pixel(scrn) );
-
- if ( dash_len ) { // make dash list
- XSetDashes( dpy, gc, 0, dashes, dash_len );
- s = bg_mode == TransparentMode ? LineOnOffDash : LineDoubleDash;
- }
- XSetLineAttributes( dpy, gc,
- (! allow_zero_lw && cpen.width() == 0) ? 1 : cpen.width(),
- s, cp, jn );
-}
-
-
-void TQPainter::updateBrush()
-{
- if (!isActive())
- return;
-
- static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
- static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar hor_pat[] = { // horizontal pattern
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const uchar ver_pat[] = { // vertical pattern
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20 };
- static const uchar cross_pat[] = { // cross pattern
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0xff, 0xff, 0xff,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0xff, 0xff, 0xff, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0xff, 0xff, 0xff,
- 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
- 0x08, 0x82, 0x20, 0xff, 0xff, 0xff, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20 };
- static const uchar bdiag_pat[] = { // backward diagonal pattern
- 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01,
- 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
- 0x02, 0x02, 0x01, 0x01, 0x80, 0x80, 0x40, 0x40 };
- static const uchar fdiag_pat[] = { // forward diagonal pattern
- 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
- 0x80, 0x80, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10,
- 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x01, 0x01 };
- static const uchar dcross_pat[] = { // diagonal cross pattern
- 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41, 0x41,
- 0x80, 0x80, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14,
- 0x22, 0x22, 0x41, 0x41, 0x80, 0x80, 0x41, 0x41 };
- static const uchar * const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
-
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].brush = &cbrush;
- if ( !pdev->cmd( TQPaintDevice::PdcSetBrush, this, param ) || !hd )
- return;
- }
-
- int bs = cbrush.style();
- bool cacheIt = !testf(ClipOn|MonoDev|NoCache) &&
- (bs == NoBrush || bs == SolidPattern) &&
- bro.x() == 0 && bro.y() == 0 && rop == CopyROP;
-
- bool obtained = FALSE;
- bool internclipok = hasClipping();
- if ( cacheIt ) {
- if ( gc_brush ) {
- if ( brushRef )
- release_gc( brushRef );
- else
- free_gc( dpy, gc_brush );
- }
- obtained = obtain_gc(&brushRef, &gc_brush, cbrush.color().pixel(scrn), dpy,
- scrn, hd, clip_serial);
- if ( !obtained && !brushRef )
- gc_brush = alloc_gc( dpy, scrn, hd, FALSE );
- } else {
- if ( gc_brush ) {
- if ( brushRef ) {
- release_gc( brushRef );
- brushRef = 0;
- gc_brush = alloc_gc( dpy, scrn, hd, testf(MonoDev) );
- } else {
- internclipok = TRUE;
- }
- } else {
- gc_brush = alloc_gc( dpy, scrn, hd, testf(MonoDev), testf(UsePrivateCx));
- }
- }
-
- if ( !internclipok ) {
- if ( pdev == paintEventDevice && paintEventClipRegion ) {
- if ( brushRef &&((TQGCC*)brushRef)->clip_serial < gc_cache_clip_serial ) {
- x11SetClipRegion( dpy, gc_brush, 0, rendhd, *paintEventClipRegion );
- ((TQGCC*)brushRef)->clip_serial = gc_cache_clip_serial;
- } else if ( !brushRef ){
- x11SetClipRegion( dpy, gc_brush, 0, rendhd, *paintEventClipRegion );
- }
- } else if (brushRef && ((TQGCC*)brushRef)->clip_serial ) {
- x11ClearClipRegion(dpy, gc_brush, 0, rendhd);
- ((TQGCC*)brushRef)->clip_serial = 0;
- }
- }
-
- if ( obtained )
- return;
-
- const uchar *pat = 0; // pattern
- int d = 0; // defalt pattern size: d*d
- int s = FillSolid;
- if ( bs >= Dense1Pattern && bs <= DiagCrossPattern ) {
- pat = pat_tbl[ bs-Dense1Pattern ];
- if ( bs <= Dense7Pattern )
- d = 8;
- else if ( bs <= CrossPattern )
- d = 24;
- else
- d = 16;
- }
-
- XSetLineAttributes( dpy, gc_brush, 0, LineSolid, CapButt, JoinMiter );
- XSetForeground( dpy, gc_brush, cbrush.color().pixel(scrn) );
- XSetBackground( dpy, gc_brush, bg_col.pixel(scrn) );
-
- if ( bs == CustomPattern || pat ) {
- TQPixmap *pm;
- if ( pat ) {
- TQString key;
- key.sprintf( "$qt-brush$%d", bs );
- pm = TQPixmapCache::find( key );
- bool del = FALSE;
- if ( !pm ) { // not already in pm dict
- pm = new TQBitmap( d, d, pat, TRUE );
- TQ_CHECK_PTR( pm );
- del = !TQPixmapCache::insert( key, pm );
- }
- if ( cbrush.data->pixmap )
- delete cbrush.data->pixmap;
- cbrush.data->pixmap = new TQPixmap( *pm );
- if (del) delete pm;
- }
- pm = cbrush.data->pixmap;
- pm->x11SetScreen( scrn );
- if ( pm->depth() == 1 ) {
- XSetStipple( dpy, gc_brush, pm->handle() );
- s = bg_mode == TransparentMode ? FillStippled : FillOpaqueStippled;
- } else {
- XSetTile( dpy, gc_brush, pm->handle() );
- s = FillTiled;
- }
- }
- XSetFillStyle( dpy, gc_brush, s );
-}
-
-
-/*!
- Begins painting the paint tqdevice \a pd and returns TRUE if
- successful; otherwise returns FALSE. If \a unclipped is TRUE, the
- painting will not be clipped at the paint tqdevice's boundaries,
- (although this is not supported by all platforms).
-
- The errors that can occur are serious problems, such as these:
-
- \code
- p->begin( 0 ); // impossible - paint tqdevice cannot be 0
-
- TQPixmap pm( 0, 0 );
- p->begin( pm ); // impossible - pm.isNull();
-
- p->begin( myWidget );
- p2->begin( myWidget ); // impossible - only one painter at a time
- \endcode
-
- Note that most of the time, you can use one of the constructors
- instead of begin(), and that end() is automatically done at
- destruction.
-
- \warning A paint tqdevice can only be painted by one painter at a
- time.
-
- \sa end(), flush()
-*/
-
-bool TQPainter::begin( const TQPaintDevice *pd, bool unclipped )
-{
- if ( isActive() ) { // already active painting
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::begin: Painter is already active."
- "\n\tYou must end() the painter before a second begin()" );
-#endif
- return FALSE;
- }
- if ( pd == 0 ) {
-#if defined(TQT_CHECK_NULL)
- qWarning( "TQPainter::begin: Paint tqdevice cannot be null" );
-#endif
- return FALSE;
- }
-
- TQPixmap::x11SetDefaultScreen( pd->x11Screen() );
-
- const TQWidget *copyFrom = 0;
- pdev = redirect( (TQPaintDevice*)pd );
- if ( pdev ) { // redirected paint tqdevice?
- if ( pd->devType() == TQInternal::Widget )
- copyFrom = (const TQWidget *)pd; // copy widget settings
- } else {
- pdev = (TQPaintDevice*)pd;
- }
-
- if ( pdev->isExtDev() && pdev->paintingActive() ) {
- // somebody else is already painting
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::begin: Another TQPainter is already painting "
- "this tqdevice;\n\tAn extended paint tqdevice can only be "
- "painted by one TQPainter at a time." );
-#endif
- return FALSE;
- }
-
- bool reinit = flags != IsStartingUp; // 2nd or 3rd etc. time called
- flags = IsActive | DirtyFont; // init flags
- int dt = pdev->devType(); // get the tqdevice type
-
- if ( (pdev->devFlags & TQInternal::ExternalDevice) != 0 )
- setf(ExtDev);
- else if ( dt == TQInternal::Pixmap ) // tqdevice is a pixmap
- ((TQPixmap*)pdev)->detach(); // will modify it
-
- dpy = pdev->x11Display(); // get display variable
- scrn = pdev->x11Screen(); // get screen variable
- hd = pdev->handle(); // get handle to drawable
- rendhd = pdev->rendhd;
-
- if ( testf(ExtDev) ) { // external tqdevice
- if ( !pdev->cmd( TQPaintDevice::PdcBegin, this, 0 ) ) {
- // could not begin painting
- if ( reinit )
- clearf( IsActive | DirtyFont );
- else
- flags = IsStartingUp;
- pdev = 0;
- return FALSE;
- }
- if ( tabstops ) // update tabstops for tqdevice
- setTabStops( tabstops );
- if ( tabarray ) // update tabarray for tqdevice
- setTabArray( tabarray );
- }
-
- if ( pdev->x11Depth() != pdev->x11AppDepth( scrn ) ) { // non-standard depth
- setf(NoCache);
- setf(UsePrivateCx);
- }
-
- pdev->painters++; // also tell paint tqdevice
- bro = curPt = TQPoint( 0, 0 );
- if ( reinit ) {
- bg_mode = TransparentMode; // default background mode
- rop = CopyROP; // default ROP
- wxmat.reset(); // reset world xform matrix
- xmat.reset();
- ixmat.reset();
- txop = txinv = 0;
- if ( dt != TQInternal::Widget ) {
- TQFont defaultFont; // default drawing tools
- TQPen defaultPen;
- TQBrush defaultBrush;
- cfont = defaultFont; // set these drawing tools
- cpen = defaultPen;
- cbrush = defaultBrush;
- bg_col = white; // default background color
- }
- }
- wx = wy = vx = vy = 0; // default view origins
-
- if ( dt == TQInternal::Widget ) { // tqdevice is a widget
- TQWidget *w = (TQWidget*)pdev;
- cfont = w->font(); // use widget font
- cpen = TQPen( w->foregroundColor() ); // use widget fg color
- if ( reinit ) {
- TQBrush defaultBrush;
- cbrush = defaultBrush;
- }
- bg_col = w->backgroundColor(); // use widget bg color
- ww = vw = w->width(); // default view size
- wh = vh = w->height();
- if ( unclipped || w->testWFlags( WPaintUnclipped ) ) { // paint direct on tqdevice
- setf( NoCache );
- setf(UsePrivateCx);
- updatePen();
- updateBrush();
- XSetSubwindowMode( dpy, gc, IncludeInferiors );
- XSetSubwindowMode( dpy, gc_brush, IncludeInferiors );
-#ifndef TQT_NO_XFTFREETYPE
- if (rendhd)
- XftDrawSetSubwindowMode((XftDraw *) rendhd, IncludeInferiors);
-#endif
- }
- } else if ( dt == TQInternal::Pixmap ) { // tqdevice is a pixmap
- TQPixmap *pm = (TQPixmap*)pdev;
- if ( pm->isNull() ) {
-#if defined(TQT_CHECK_NULL)
- qWarning( "TQPainter::begin: Cannot paint null pixmap" );
-#endif
- end();
- return FALSE;
- }
- bool mono = pm->depth() == 1; // monochrome bitmap
- if ( mono ) {
- setf( MonoDev );
- bg_col = color0;
- cpen.setColor( color1 );
- }
- ww = vw = pm->width(); // default view size
- wh = vh = pm->height();
- } else if ( testf(ExtDev) ) { // external tqdevice
- ww = vw = pdev->metric( TQPaintDeviceMetrics::PdmWidth );
- wh = vh = pdev->metric( TQPaintDeviceMetrics::PdmHeight );
- }
- if ( ww == 0 )
- ww = wh = vw = vh = 1024;
- if ( copyFrom ) { // copy redirected widget
- cfont = copyFrom->font();
- cpen = TQPen( copyFrom->foregroundColor() );
- bg_col = copyFrom->backgroundColor();
- }
- if ( testf(ExtDev) ) { // external tqdevice
- setBackgroundColor( bg_col ); // default background color
- setBackgroundMode( TransparentMode ); // default background mode
- setRasterOp( CopyROP ); // default raster operation
- }
- clip_serial = gc_cache_clip_serial++;
- updateBrush();
- updatePen();
- return TRUE;
-}
-
-/*!
- Ends painting. Any resources used while painting are released.
-
- Note that while you mostly don't need to call end(), the
- destructor will do it, there is at least one common case when it
- is needed, namely double buffering.
-
- \code
- TQPainter p( myPixmap, this )
- // ...
- p.end(); // stops drawing on myPixmap
- p.begin( this );
- p.drawPixmap( 0, 0, myPixmap );
- \endcode
-
- Since you can't draw a TQPixmap while it is being painted, it is
- necessary to close the active painter.
-
- \sa begin(), isActive()
-*/
-
-bool TQPainter::end() // end painting
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::end: Missing begin() or begin() failed" );
-#endif
- return FALSE;
- }
- killPStack();
-
- //#### This should not be necessary:
- if ( pdev->devType() == TQInternal::Widget && // #####
- ((TQWidget*)pdev)->testWFlags(WPaintUnclipped) ) {
- if ( gc )
- XSetSubwindowMode( dpy, gc, ClipByChildren );
- if ( gc_brush )
- XSetSubwindowMode( dpy, gc_brush, ClipByChildren );
- }
-
- if ( gc_brush ) { // restore brush gc
- if ( brushRef ) {
- release_gc( brushRef );
- brushRef = 0;
- } else {
- free_gc( dpy, gc_brush, testf(UsePrivateCx) );
- }
- gc_brush = 0;
-
- }
- if ( gc ) { // restore pen gc
- if ( penRef ) {
- release_gc( penRef );
- penRef = 0;
- } else {
- free_gc( dpy, gc, testf(UsePrivateCx) );
- }
- gc = 0;
- }
-
- if ( testf(ExtDev) )
- pdev->cmd( TQPaintDevice::PdcEnd, this, 0 );
-
-#ifndef TQT_NO_XFTFREETYPE
- if (rendhd) {
- // reset clipping/subwindow mode on our render picture
- XftDrawSetClip((XftDraw *) rendhd, None);
- XftDrawSetSubwindowMode((XftDraw *) rendhd, ClipByChildren);
- }
-#endif // TQT_NO_XFTFREETYPE
-
- if ( pfont ) {
- delete pfont;
- pfont = 0;
- }
-
- flags = 0;
- pdev->painters--;
- pdev = 0;
- dpy = 0;
- return TRUE;
-}
-
-/*!
- Flushes any buffered drawing operations inside the region \a
- region using clipping mode \a cm.
-
- The flush may update the whole tqdevice if the platform does not
- support flushing to a specified region.
-
- \sa flush() CoordinateMode
-*/
-
-void TQPainter::flush(const TQRegion &, CoordinateMode)
-{
- flush();
-}
-
-
-/*!
- \overload
-
- Flushes any buffered drawing operations.
-*/
-
-void TQPainter::flush()
-{
- if ( isActive() && dpy )
- XFlush( dpy );
-}
-
-
-/*!
- Sets the background color of the painter to \a c.
-
- The background color is the color that is filled in when drawing
- opaque text, stippled lines and bitmaps. The background color has
- no effect in transparent background mode (which is the default).
-
- \sa backgroundColor() setBackgroundMode() BackgroundMode
-*/
-
-void TQPainter::setBackgroundColor( const TQColor &c )
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::setBackgroundColor: Call begin() first" );
-#endif
- return;
- }
- bg_col = c;
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].color = &bg_col;
- if ( !pdev->cmd( TQPaintDevice::PdcSetBkColor, this, param ) || !hd )
- return;
- }
- if ( !penRef )
- updatePen(); // update pen setting
- if ( !brushRef )
- updateBrush(); // update brush setting
-}
-
-/*!
- Sets the background mode of the painter to \a m, which must be
- either \c TransparentMode (the default) or \c OpaqueMode.
-
- Transparent mode draws stippled lines and text without setting the
- background pixels. Opaque mode fills these space with the current
- background color.
-
- Note that in order to draw a bitmap or pixmap transparently, you
- must use TQPixmap::setMask().
-
- \sa backgroundMode(), setBackgroundColor()
-*/
-
-void TQPainter::setBackgroundMode( BGMode m )
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::setBackgroundMode: Call begin() first" );
-#endif
- return;
- }
- if ( m != TransparentMode && m != OpaqueMode ) {
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPainter::setBackgroundMode: Invalid mode" );
-#endif
- return;
- }
- bg_mode = m;
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].ival = m;
- if ( !pdev->cmd( TQPaintDevice::PdcSetBkMode, this, param ) || !hd )
- return;
- }
- if ( !penRef )
- updatePen(); // update pen setting
- if ( !brushRef )
- updateBrush(); // update brush setting
-}
-
-static const short ropCodes[] = { // ROP translation table
- GXcopy, // CopyROP
- GXor, // OrROP
- GXxor, // XorROP
- GXandInverted, // NotAndROP EraseROP
- GXcopyInverted, // NotCopyROP
- GXorInverted, // NotOrROP
- GXequiv, // NotXorROP
- GXand, // AndROP
- GXinvert, // NotROP
- GXclear, // ClearROP
- GXset, // SetROP
- GXnoop, // NopROP
- GXandReverse, // AndNotROP
- GXorReverse, // OrNotROP
- GXnand, // NandROP
- GXnor // NorROP
-};
-
-
-/*!
- Sets the \link TQt::RasterOp raster operation \endlink to \a r.
- The default is \c CopyROP.
-
- \sa rasterOp() TQt::RasterOp
-*/
-
-void TQPainter::setRasterOp( RasterOp r )
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::setRasterOp: Call begin() first" );
-#endif
- return;
- }
- if ( (uint)r > LastROP ) {
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPainter::setRasterOp: Invalid ROP code" );
-#endif
- return;
- }
- rop = r;
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].ival = r;
- if ( !pdev->cmd( TQPaintDevice::PdcSetROP, this, param ) || !hd )
- return;
- }
- if ( penRef )
- updatePen(); // get non-cached pen GC
- if ( brushRef )
- updateBrush(); // get non-cached brush GC
- XSetFunction( dpy, gc, ropCodes[rop] );
- XSetFunction( dpy, gc_brush, ropCodes[rop] );
-}
-
-// ### matthias - true?
-
-/*!
- Sets the brush origin to \a (x, y).
-
- The brush origin specifies the (0, 0) coordinate of the painter's
- brush. This setting only applies to pattern brushes and pixmap
- brushes.
-
- \sa brushOrigin()
-*/
-
-void TQPainter::setBrushOrigin( int x, int y )
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::setBrushOrigin: Call begin() first" );
-#endif
- return;
- }
- bro = TQPoint(x, y);
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].point = &bro;
- if ( !pdev->cmd( TQPaintDevice::PdcSetBrushOrigin, this, param ) ||
- !hd )
- return;
- }
- if ( brushRef )
- updateBrush(); // get non-cached brush GC
- XSetTSOrigin( dpy, gc_brush, x, y );
-}
-
-
-/*!
- Enables clipping if \a enable is TRUE, or disables clipping if \a
- enable is FALSE.
-
- \sa hasClipping(), setClipRect(), setClipRegion()
-*/
-
-void TQPainter::setClipping( bool enable )
-{
- if ( !isActive() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQPainter::setClipping: Will be reset by begin()" );
-#endif
- return;
- }
-
- if ( enable == testf(ClipOn) )
- return;
-
- setf( ClipOn, enable );
- if ( testf(ExtDev) ) {
- if ( block_ext )
- return;
- TQPDevCmdParam param[1];
- param[0].ival = enable;
- if ( !pdev->cmd( TQPaintDevice::PdcSetClip, this, param ) || !hd )
- return;
- }
- if ( enable ) {
- TQRegion rgn = crgn;
- if ( pdev == paintEventDevice && paintEventClipRegion )
- rgn = rgn.intersect( *paintEventClipRegion );
- if ( penRef )
- updatePen();
- if ( brushRef )
- updateBrush();
- x11SetClipRegion( dpy, gc, gc_brush, rendhd, rgn );
- } else {
- if ( pdev == paintEventDevice && paintEventClipRegion ) {
- x11SetClipRegion( dpy, gc, gc_brush , rendhd, *paintEventClipRegion );
- } else {
- x11ClearClipRegion(dpy, gc, gc_brush, rendhd);
- }
- }
-}
-
-
-/*!
- \overload
-
- Sets the clip region to the rectangle \a r and enables clipping.
- The clip mode is set to \a m.
-
- \sa CoordinateMode
-*/
-
-void TQPainter::setClipRect( const TQRect &r, CoordinateMode m )
-{
- setClipRegion( TQRegion( r ), m );
-}
-
-/*!
- Sets the clip region to \a rgn and enables clipping. The clip mode
- is set to \a m.
-
- Note that the clip region is given in physical tqdevice coordinates
- and \e not subject to any \link coordsys.html coordinate
- transformation.\endlink
-
- \sa setClipRect(), clipRegion(), setClipping() CoordinateMode
-*/
-
-void TQPainter::setClipRegion( const TQRegion &rgn, CoordinateMode m )
-{
-#if defined(TQT_CHECK_STATE)
- if ( !isActive() )
- qWarning( "TQPainter::setClipRegion: Will be reset by begin()" );
-#endif
- if ( m == CoordDevice )
- crgn = rgn;
- else
- crgn = xmat * rgn;
-
- if ( testf(ExtDev) ) {
- if ( block_ext )
- return;
- TQPDevCmdParam param[2];
- param[0].rgn = &rgn;
- param[1].ival = m;
- if ( !pdev->cmd( TQPaintDevice::PdcSetClipRegion, this, param ) )
- return; // tqdevice cannot clip
- }
- clearf( ClipOn ); // be sure to update clip rgn
- setClipping( TRUE );
-}
-
-
-/*!
- \internal
-
- Internal function for drawing a polygon.
-*/
-
-void TQPainter::drawPolyInternal( const TQPointArray &a, bool close )
-{
- if ( a.size() < 2 )
- return;
-
- int x1, y1, x2, y2; // connect last to first point
- a.point( a.size()-1, &x1, &y1 );
- a.point( 0, &x2, &y2 );
- bool do_close = close && !(x1 == x2 && y1 == y2);
-
- if ( close && cbrush.style() != NoBrush ) { // draw filled polygon
- XFillPolygon( dpy, hd, gc_brush, (XPoint*)a.shortPoints(), a.size(),
- Nonconvex, CoordModeOrigin );
- if ( cpen.style() == NoPen ) { // draw fake outline
- XDrawLines( dpy, hd, gc_brush, (XPoint*)a.shortPoints(), a.size(),
- CoordModeOrigin );
- if ( do_close )
- XDrawLine( dpy, hd, gc_brush, x1, y1, x2, y2 );
- }
- }
- if ( cpen.style() != NoPen ) { // draw outline
- XDrawLines( dpy, hd, gc, (XPoint*)a.shortPoints(), a.size(),
- CoordModeOrigin);
- if ( do_close )
- XDrawLine( dpy, hd, gc, x1, y1, x2, y2 );
- }
-}
-
-
-/*!
- Draws/plots a single point at \a (x, y) using the current pen.
-
- \sa TQPen
-*/
-
-void TQPainter::drawPoint( int x, int y )
-{
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- TQPoint p( x, y );
- param[0].point = &p;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawPoint, this, param ) ||
- !hd )
- return;
- }
- map( x, y, &x, &y );
- }
- if ( cpen.style() != NoPen )
- XDrawPoint( dpy, hd, gc, x, y );
-}
-
-
-/*!
- Draws/plots an array of points, \a a, using the current pen.
-
- If \a index is non-zero (the default is zero) only points from \a
- index are drawn. If \a npoints is negative (the default) the rest
- of the points from \a index are drawn. If \a npoints is zero or
- greater, \a npoints points are drawn.
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-*/
-
-void TQPainter::drawPoints( const TQPointArray& a, int index, int npoints )
-{
- if ( npoints < 0 )
- npoints = a.size() - index;
- if ( index + npoints > (int)a.size() )
- npoints = a.size() - index;
- if ( !isActive() || npoints < 1 || index < 0 )
- return;
- TQPointArray pa = a;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- for (int i=0; i<npoints; i++) {
- TQPoint p( pa[index+i].x(), pa[index+i].y() );
- param[0].point = &p;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawPoint, this, param ))
- return;
- }
- if ( !hd ) return;
- }
- if ( txop != TxNone ) {
- pa = xForm( a, index, npoints );
- if ( pa.size() != a.size() ) {
- index = 0;
- npoints = pa.size();
- }
- }
- }
- if ( cpen.style() != NoPen )
- XDrawPoints( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
- npoints, CoordModeOrigin );
-}
-
-
-/*! \obsolete
- Sets the current pen position to \a (x, y)
-
- \sa lineTo(), pos()
-*/
-
-void TQPainter::moveTo( int x, int y )
-{
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- TQPoint p( x, y );
- param[0].point = &p;
- if ( !pdev->cmd( TQPaintDevice::PdcMoveTo, this, param ) || !hd )
- return;
- }
- }
- curPt = TQPoint( x, y );
-}
-
-/*! \obsolete
- Use drawLine() instead.
-
- Draws a line from the current pen position to \a (x, y) and sets
- \a (x, y) to be the new current pen position.
-
- \sa TQPen moveTo(), drawLine(), pos()
-*/
-
-void TQPainter::lineTo( int x, int y )
-{
- if ( !isActive() )
- return;
- int cx = curPt.x(), cy = curPt.y();
- curPt = TQPoint( x, y );
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- TQPoint p( x, y );
- param[0].point = &p;
- if ( !pdev->cmd( TQPaintDevice::PdcLineTo, this, param ) || !hd )
- return;
- }
- map( x, y, &x, &y );
- map( cx, cy, &cx, &cy );
- }
- if ( cpen.style() != NoPen )
- XDrawLine( dpy, hd, gc, cx, cy, x, y );
-}
-
-/*!
- Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
- current pen position to (\a x2, \a y2).
-
- \sa pen()
-*/
-
-void TQPainter::drawLine( int x1, int y1, int x2, int y2 )
-{
- if ( !isActive() )
- return;
- curPt = TQPoint( x2, y2 );
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[2];
- TQPoint p1(x1, y1), p2(x2, y2);
- param[0].point = &p1;
- param[1].point = &p2;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawLine, this, param ) || !hd )
- return;
- }
- map( x1, y1, &x1, &y1 );
- map( x2, y2, &x2, &y2 );
- }
- if ( cpen.style() != NoPen )
- XDrawLine( dpy, hd, gc, x1, y1, x2, y2 );
-}
-
-
-
-/*!
- Draws a rectangle with upper left corner at \a (x, y) and with
- width \a w and height \a h.
-
- \sa TQPen, drawRoundRect()
-*/
-
-void TQPainter::drawRect( int x, int y, int w, int h )
-{
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawRect, this, param ) || !hd )
- return;
- }
- if ( txop == TxRotShear ) { // rotate/shear polygon
- TQPointArray pa = xmat.mapToPolygon( TQRect(x, y, w, h) );
- pa.resize( 5 );
- pa.setPoint( 4, pa.point( 0 ) );
- drawPolyInternal( pa );
- return;
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
- if ( cbrush.style() != NoBrush ) {
- if ( cpen.style() == NoPen ) {
- XFillRectangle( dpy, hd, gc_brush, x, y, w, h );
- return;
- }
- int lw = cpen.width();
- int lw2 = (lw+1)/2;
- if ( w > lw && h > lw )
- XFillRectangle( dpy, hd, gc_brush, x+lw2, y+lw2, w-lw-1, h-lw-1 );
- }
- if ( cpen.style() != NoPen )
- XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
-}
-
-/*!
- \overload
-
- Draws a Windows focus rectangle with upper left corner at (\a x,
- \a y) and with width \a w and height \a h.
-
- This function draws a stippled XOR rectangle that is used to
- indicate keyboard focus (when TQApplication::style() is \c
- WindowStyle).
-
- \warning This function draws nothing if the coordinate system has
- been \link rotate() rotated\endlink or \link shear()
- sheared\endlink.
-
- \sa drawRect(), TQApplication::style()
-*/
-
-void TQPainter::drawWinFocusRect( int x, int y, int w, int h )
-{
- drawWinFocusRect( x, y, w, h, TRUE, color0 );
-}
-
-/*!
- Draws a Windows focus rectangle with upper left corner at (\a x,
- \a y) and with width \a w and height \a h using a pen color that
- contrasts with \a bgColor.
-
- This function draws a stippled rectangle (XOR is not used) that is
- used to indicate keyboard focus (when the TQApplication::style() is
- \c WindowStyle).
-
- The pen color used to draw the rectangle is either white or black
- depending on the color of \a bgColor (see TQColor::gray()).
-
- \warning This function draws nothing if the coordinate system has
- been \link rotate() rotated\endlink or \link shear()
- sheared\endlink.
-
- \sa drawRect(), TQApplication::style()
-*/
-
-void TQPainter::drawWinFocusRect( int x, int y, int w, int h,
- const TQColor &bgColor )
-{
- drawWinFocusRect( x, y, w, h, FALSE, bgColor );
-}
-
-
-/*!
- \internal
-*/
-
-void TQPainter::drawWinFocusRect( int x, int y, int w, int h,
- bool xorPaint, const TQColor &bgColor )
-{
- if ( !isActive() || txop == TxRotShear )
- return;
- static char winfocus_line[] = { 1, 1 };
-
- TQPen old_pen = cpen;
- RasterOp old_rop = (RasterOp)rop;
-
- if ( xorPaint ) {
- if ( TQColor::numBitPlanes() <= 8 )
- setPen( color1 );
- else
- setPen( white );
- setRasterOp( XorROP );
- } else {
- if ( tqGray( bgColor.rgb() ) < 128 )
- setPen( white );
- else
- setPen( black );
- }
-
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawRect, this, param ) || !hd) {
- setRasterOp( old_rop );
- setPen( old_pen );
- return;
- }
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
- XSetDashes( dpy, gc, 0, winfocus_line, 2 );
- XSetLineAttributes( dpy, gc, 1, LineOnOffDash, CapButt, JoinMiter );
-
- XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
- XSetLineAttributes( dpy, gc, 0, LineSolid, CapButt, JoinMiter );
- setRasterOp( old_rop );
- setPen( old_pen );
-}
-
-
-/*!
- Draws a rectangle with rounded corners at \a (x, y), with width \a
- w and height \a h.
-
- The \a xRnd and \a yRnd arguments specify how rounded the corners
- should be. 0 is angled corners, 99 is maximum roundedness.
-
- The width and height include all of the drawn lines.
-
- \sa drawRect(), TQPen
-*/
-
-void TQPainter::drawRoundRect( int x, int y, int w, int h, int xRnd, int yRnd )
-{
- if ( !isActive() )
- return;
- if ( xRnd <= 0 || yRnd <= 0 ) {
- drawRect( x, y, w, h ); // draw normal rectangle
- return;
- }
- if ( xRnd >= 100 ) // fix ranges
- xRnd = 99;
- if ( yRnd >= 100 )
- yRnd = 99;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[3];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- param[1].ival = xRnd;
- param[2].ival = yRnd;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawRoundRect, this, param ) ||
- !hd )
- return;
- }
- if ( txop == TxRotShear ) { // rotate/shear polygon
- if ( w <= 0 || h <= 0 )
- fix_neg_rect( &x, &y, &w, &h );
- w--;
- h--;
- int rxx = w*xRnd/200;
- int ryy = h*yRnd/200;
- // were there overflows?
- if ( rxx < 0 )
- rxx = w/200*xRnd;
- if ( ryy < 0 )
- ryy = h/200*yRnd;
- int rxx2 = 2*rxx;
- int ryy2 = 2*ryy;
- TQPointArray a[4];
- a[0].makeArc( x, y, rxx2, ryy2, 1*16*90, 16*90, xmat );
- a[1].makeArc( x, y+h-ryy2, rxx2, ryy2, 2*16*90, 16*90, xmat );
- a[2].makeArc( x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*16*90, 16*90, xmat );
- a[3].makeArc( x+w-rxx2, y, rxx2, ryy2, 0*16*90, 16*90, xmat );
- // ### is there a better way to join TQPointArrays?
- TQPointArray aa;
- aa.resize( a[0].size() + a[1].size() + a[2].size() + a[3].size() );
- uint j = 0;
- for ( int k=0; k<4; k++ ) {
- for ( uint i=0; i<a[k].size(); i++ ) {
- aa.setPoint( j, a[k].point(i) );
- j++;
- }
- }
- drawPolyInternal( aa );
- return;
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- w--;
- h--;
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
- int rx = (w*xRnd)/200;
- int ry = (h*yRnd)/200;
- int rx2 = 2*rx;
- int ry2 = 2*ry;
- if ( cbrush.style() != NoBrush ) { // draw filled round rect
- int dp, ds;
- if ( cpen.style() == NoPen ) {
- dp = 0;
- ds = 1;
- }
- else {
- dp = 1;
- ds = 0;
- }
-#define SET_ARC(px, py, w, h, a1, a2) \
- a->x=px; a->y=py; a->width=w; a->height=h; a->angle1=a1; a->angle2=a2; a++
- XArc arcs[4];
- XArc *a = arcs;
- SET_ARC( x+w-rx2, y, rx2, ry2, 0, 90*64 );
- SET_ARC( x, y, rx2, ry2, 90*64, 90*64 );
- SET_ARC( x, y+h-ry2, rx2, ry2, 180*64, 90*64 );
- SET_ARC( x+w-rx2, y+h-ry2, rx2, ry2, 270*64, 90*64 );
- XFillArcs( dpy, hd, gc_brush, arcs, 4 );
-#undef SET_ARC
-#define SET_RCT(px, py, w, h) \
- r->x=px; r->y=py; r->width=w; r->height=h; r++
- XRectangle rects[3];
- XRectangle *r = rects;
- SET_RCT( x+rx, y+dp, w-rx2, ry );
- SET_RCT( x+dp, y+ry, w+ds, h-ry2 );
- SET_RCT( x+rx, y+h-ry, w-rx2, ry+ds );
- XFillRectangles( dpy, hd, gc_brush, rects, 3 );
-#undef SET_RCT
- }
- if ( cpen.style() != NoPen ) { // draw outline
-#define SET_ARC(px, py, w, h, a1, a2) \
- a->x=px; a->y=py; a->width=w; a->height=h; a->angle1=a1; a->angle2=a2; a++
- XArc arcs[4];
- XArc *a = arcs;
- SET_ARC( x+w-rx2, y, rx2, ry2, 0, 90*64 );
- SET_ARC( x, y, rx2, ry2, 90*64, 90*64 );
- SET_ARC( x, y+h-ry2, rx2, ry2, 180*64, 90*64 );
- SET_ARC( x+w-rx2, y+h-ry2, rx2, ry2, 270*64, 90*64 );
- XDrawArcs( dpy, hd, gc, arcs, 4 );
-#undef SET_ARC
-#define SET_SEG(xp1, yp1, xp2, yp2) \
- s->x1=xp1; s->y1=yp1; s->x2=xp2; s->y2=yp2; s++
- XSegment segs[4];
- XSegment *s = segs;
- SET_SEG( x+rx, y, x+w-rx, y );
- SET_SEG( x+rx, y+h, x+w-rx, y+h );
- SET_SEG( x, y+ry, x, y+h-ry );
- SET_SEG( x+w, y+ry, x+w, y+h-ry );
- XDrawSegments( dpy, hd, gc, segs, 4 );
-#undef SET_SET
- }
-}
-
-/*!
- Draws an ellipse with center at \a (x + w/2, y + h/2) and size \a
- (w, h).
-*/
-
-void TQPainter::drawEllipse( int x, int y, int w, int h )
-{
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawEllipse, this, param ) ||
- !hd )
- return;
- }
- if ( txop == TxRotShear ) { // rotate/shear polygon
- TQPointArray a;
- a.makeArc( x, y, w, h, 0, 360*16, xmat );
- drawPolyInternal( a );
- return;
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
- if ( w == 1 && h == 1 ) {
- XDrawPoint( dpy, hd, (cpen.style() == NoPen)?gc_brush:gc, x, y );
- return;
- }
- w--;
- h--;
- if ( cbrush.style() != NoBrush ) { // draw filled ellipse
- XFillArc( dpy, hd, gc_brush, x, y, w, h, 0, 360*64 );
- if ( cpen.style() == NoPen ) {
- XDrawArc( dpy, hd, gc_brush, x, y, w, h, 0, 360*64 );
- return;
- }
- }
- if ( cpen.style() != NoPen ) // draw outline
- XDrawArc( dpy, hd, gc, x, y, w, h, 0, 360*64 );
-}
-
-
-/*!
- Draws an arc defined by the rectangle \a (x, y, w, h), the start
- angle \a a and the arc length \a alen.
-
- The angles \a a and \a alen are 1/16th of a degree, i.e. a full
- circle equals 5760 (16*360). Positive values of \a a and \a alen
- mean counter-clockwise while negative values mean the clockwise
- direction. Zero degrees is at the 3 o'clock position.
-
- Example:
- \code
- TQPainter p( myWidget );
- p.drawArc( 10,10, 70,100, 100*16, 160*16 ); // draws a "(" arc
- \endcode
-
- \sa drawPie(), drawChord()
-*/
-
-void TQPainter::drawArc( int x, int y, int w, int h, int a, int alen )
-{
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[3];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- param[1].ival = a;
- param[2].ival = alen;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawArc, this, param ) ||
- !hd )
- return;
- }
- if ( txop == TxRotShear ) { // rotate/shear
- TQPointArray pa;
- pa.makeArc( x, y, w, h, a, alen, xmat ); // arc polyline
- drawPolyInternal( pa, FALSE );
- return;
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- w--;
- h--;
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
- if ( cpen.style() != NoPen )
- XDrawArc( dpy, hd, gc, x, y, w, h, a*4, alen*4 );
-}
-
-
-/*!
- Draws a pie defined by the rectangle \a (x, y, w, h), the start
- angle \a a and the arc length \a alen.
-
- The pie is filled with the current brush().
-
- The angles \a a and \a alen are 1/16th of a degree, i.e. a full
- circle equals 5760 (16*360). Positive values of \a a and \a alen
- mean counter-clockwise while negative values mean the clockwise
- direction. Zero degrees is at the 3 o'clock position.
-
- \sa drawArc(), drawChord()
-*/
-
-void TQPainter::drawPie( int x, int y, int w, int h, int a, int alen )
-{
- // Make sure "a" is 0..360*16, as otherwise a*4 may overflow 16 bits.
- if ( a > (360*16) ) {
- a = a % (360*16);
- } else if ( a < 0 ) {
- a = a % (360*16);
- if ( a < 0 ) a += (360*16);
- }
-
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[3];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- param[1].ival = a;
- param[2].ival = alen;
- if ( !pdev->cmd( TQPaintDevice::PdcDrawPie, this, param ) || !hd )
- return;
- }
- if ( txop == TxRotShear ) { // rotate/shear
- TQPointArray pa;
- pa.makeArc( x, y, w, h, a, alen, xmat ); // arc polyline
- int n = pa.size();
- int cx, cy;
- xmat.map(x+w/2, y+h/2, &cx, &cy);
- pa.resize( n+2 );
- pa.setPoint( n, cx, cy ); // add legs
- pa.setPoint( n+1, pa.at(0) );
- drawPolyInternal( pa );
- return;
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- XSetArcMode( dpy, gc_brush, ArcPieSlice );
- w--;
- h--;
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
-
- GC g = gc;
- bool nopen = cpen.style() == NoPen;
-
- if ( cbrush.style() != NoBrush ) { // draw filled pie
- XFillArc( dpy, hd, gc_brush, x, y, w, h, a*4, alen*4 );
- if ( nopen ) {
- g = gc_brush;
- nopen = FALSE;
- }
- }
- if ( !nopen ) { // draw pie outline
- double w2 = 0.5*w; // with, height in ellipsis
- double h2 = 0.5*h;
- double xc = (double)x+w2;
- double yc = (double)y+h2;
- double ra1 = TQ_PI/2880.0*a; // convert a, alen to radians
- double ra2 = ra1 + TQ_PI/2880.0*alen;
- int xic = tqRound(xc);
- int yic = tqRound(yc);
- XDrawLine( dpy, hd, g, xic, yic,
- tqRound(xc + qcos(ra1)*w2), tqRound(yc - qsin(ra1)*h2));
- XDrawLine( dpy, hd, g, xic, yic,
- tqRound(xc + qcos(ra2)*w2), tqRound(yc - qsin(ra2)*h2));
- XDrawArc( dpy, hd, g, x, y, w, h, a*4, alen*4 );
- }
-}
-
-
-/*!
- Draws a chord defined by the rectangle \a (x, y, w, h), the start
- angle \a a and the arc length \a alen.
-
- The chord is filled with the current brush().
-
- The angles \a a and \a alen are 1/16th of a degree, i.e. a full
- circle equals 5760 (16*360). Positive values of \a a and \a alen
- mean counter-clockwise while negative values mean the clockwise
- direction. Zero degrees is at the 3 o'clock position.
-
- \sa drawArc(), drawPie()
-*/
-
-void TQPainter::drawChord( int x, int y, int w, int h, int a, int alen )
-{
- if ( !isActive() )
- return;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[3];
- TQRect r( x, y, w, h );
- param[0].rect = &r;
- param[1].ival = a;
- param[2].ival = alen;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawChord, this, param) || !hd )
- return;
- }
- if ( txop == TxRotShear ) { // rotate/shear
- TQPointArray pa;
- pa.makeArc( x, y, w-1, h-1, a, alen, xmat ); // arc polygon
- int n = pa.size();
- pa.resize( n+1 );
- pa.setPoint( n, pa.at(0) ); // connect endpoints
- drawPolyInternal( pa );
- return;
- }
- map( x, y, w, h, &x, &y, &w, &h );
- }
- XSetArcMode( dpy, gc_brush, ArcChord );
- w--;
- h--;
- if ( w <= 0 || h <= 0 ) {
- if ( w == 0 || h == 0 )
- return;
- fix_neg_rect( &x, &y, &w, &h );
- }
-
- GC g = gc;
- bool nopen = cpen.style() == NoPen;
-
- if ( cbrush.style() != NoBrush ) { // draw filled chord
- XFillArc( dpy, hd, gc_brush, x, y, w, h, a*4, alen*4 );
- if ( nopen ) {
- g = gc_brush;
- nopen = FALSE;
- }
- }
- if ( !nopen ) { // draw chord outline
- double w2 = 0.5*w; // with, height in ellipsis
- double h2 = 0.5*h;
- double xc = (double)x+w2;
- double yc = (double)y+h2;
- double ra1 = TQ_PI/2880.0*a; // convert a, alen to radians
- double ra2 = ra1 + TQ_PI/2880.0*alen;
- XDrawLine( dpy, hd, g,
- tqRound(xc + qcos(ra1)*w2), tqRound(yc - qsin(ra1)*h2),
- tqRound(xc + qcos(ra2)*w2), tqRound(yc - qsin(ra2)*h2));
- XDrawArc( dpy, hd, g, x, y, w, h, a*4, alen*4 );
- }
- XSetArcMode( dpy, gc_brush, ArcPieSlice );
-}
-
-
-/*!
- Draws \a nlines separate lines from points defined in \a a,
- starting at \a a[index] (\a index defaults to 0). If \a nlines is
- -1 (the default) all points until the end of the array are used
- (i.e. (a.size()-index)/2 lines are drawn).
-
- Draws the 1st line from \a a[index] to \a a[index+1]. Draws the
- 2nd line from \a a[index+2] to \a a[index+3] etc.
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-
- \sa drawPolyline(), drawPolygon(), TQPen
-*/
-
-void TQPainter::drawLineSegments( const TQPointArray &a, int index, int nlines )
-{
- if ( nlines < 0 )
- nlines = a.size()/2 - index/2;
- if ( index + nlines*2 > (int)a.size() )
- nlines = (a.size() - index)/2;
- if ( !isActive() || nlines < 1 || index < 0 )
- return;
- TQPointArray pa = a;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- if ( 2*nlines != (int)pa.size() ) {
- pa = TQPointArray( nlines*2 );
- for ( int i=0; i<nlines*2; i++ )
- pa.setPoint( i, a.point(index+i) );
- index = 0;
- }
- TQPDevCmdParam param[1];
- param[0].ptarr = (TQPointArray*)&pa;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawLineSegments, this, param) ||
- !hd )
- return;
- }
- if ( txop != TxNone ) {
- pa = xForm( a, index, nlines*2 );
- if ( pa.size() != a.size() ) {
- index = 0;
- nlines = pa.size()/2;
- }
- }
- }
- if ( cpen.style() != NoPen )
- XDrawSegments( dpy, hd, gc,
- (XSegment*)(pa.shortPoints( index, nlines*2 )), nlines );
-}
-
-
-/*!
- Draws the polyline defined by the \a npoints points in \a a
- starting at \a a[index]. (\a index defaults to 0.)
-
- If \a npoints is -1 (the default) all points until the end of the
- array are used (i.e. a.size()-index-1 line segments are drawn).
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-
- \sa drawLineSegments(), drawPolygon(), TQPen
-*/
-
-void TQPainter::drawPolyline( const TQPointArray &a, int index, int npoints )
-{
- if ( npoints < 0 )
- npoints = a.size() - index;
- if ( index + npoints > (int)a.size() )
- npoints = a.size() - index;
- if ( !isActive() || npoints < 2 || index < 0 )
- return;
- TQPointArray pa = a;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- if ( npoints != (int)pa.size() ) {
- pa = TQPointArray( npoints );
- for ( int i=0; i<npoints; i++ )
- pa.setPoint( i, a.point(index+i) );
- index = 0;
- }
- TQPDevCmdParam param[1];
- param[0].ptarr = (TQPointArray*)&pa;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawPolyline, this, param) || !hd )
- return;
- }
- if ( txop != TxNone ) {
- pa = xForm( pa, index, npoints );
- if ( pa.size() != a.size() ) {
- index = 0;
- npoints = pa.size();
- }
- }
- }
- if ( cpen.style() != NoPen ) {
- while(npoints>65535) {
- XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, 65535 )),
- 65535, CoordModeOrigin );
- npoints-=65535;
- index+=65535;
- }
- XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
- npoints, CoordModeOrigin );
- }
-}
-
-static int global_polygon_tqshape = Complex;
-
-/*!
- Draws the polygon defined by the \a npoints points in \a a
- starting at \a a[index]. (\a index defaults to 0.)
-
- If \a npoints is -1 (the default) all points until the end of the
- array are used (i.e. a.size()-index line segments define the
- polygon).
-
- The first point is always connected to the last point.
-
- The polygon is filled with the current brush(). If \a winding is
- TRUE, the polygon is filled using the winding fill algorithm. If
- \a winding is FALSE, the polygon is filled using the even-odd
- (alternative) fill algorithm.
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-
- \sa drawLineSegments(), drawPolyline(), TQPen
-*/
-
-void TQPainter::drawPolygon( const TQPointArray &a, bool winding,
- int index, int npoints )
-{
- if ( npoints < 0 )
- npoints = a.size() - index;
- if ( index + npoints > (int)a.size() )
- npoints = a.size() - index;
- if ( !isActive() || npoints < 2 || index < 0 )
- return;
- TQPointArray pa = a;
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- if ( npoints != (int)a.size() ) {
- pa = TQPointArray( npoints );
- for ( int i=0; i<npoints; i++ )
- pa.setPoint( i, a.point(index+i) );
- index = 0;
- }
- TQPDevCmdParam param[2];
- param[0].ptarr = (TQPointArray*)&pa;
- param[1].ival = winding;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawPolygon, this, param) || !hd )
- return;
- }
- if ( txop != TxNone ) {
- pa = xForm( a, index, npoints );
- if ( pa.size() != a.size() ) {
- index = 0;
- npoints = pa.size();
- }
- }
- }
- if ( winding ) // set to winding fill rule
- XSetFillRule( dpy, gc_brush, WindingRule );
-
- if ( pa[index] != pa[index+npoints-1] ){ // close open pointarray
- pa.detach();
- pa.resize( index+npoints+1 );
- pa.setPoint( index+npoints, pa[index] );
- npoints++;
- }
-
- if ( cbrush.style() != NoBrush ) { // draw filled polygon
- XFillPolygon( dpy, hd, gc_brush,
- (XPoint*)(pa.shortPoints( index, npoints )),
- npoints, global_polygon_tqshape, CoordModeOrigin );
- }
- if ( cpen.style() != NoPen ) { // draw outline
- XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
- npoints, CoordModeOrigin );
- }
- if ( winding ) // set to normal fill rule
- XSetFillRule( dpy, gc_brush, EvenOddRule );
-}
-
-/*!
- Draws the convex polygon defined by the \a npoints points in \a pa
- starting at \a pa[index] (\a index defaults to 0).
-
- If the supplied polygon is not convex, the results are undefined.
-
- On some platforms (e.g. X Window), this is faster than
- drawPolygon().
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-*/
-void TQPainter::drawConvexPolygon( const TQPointArray &pa,
- int index, int npoints )
-{
- global_polygon_tqshape = Convex;
- drawPolygon(pa, FALSE, index, npoints);
- global_polygon_tqshape = Complex;
-}
-
-
-
-/*!
- Draws a cubic Bezier curve defined by the control points in \a a,
- starting at \a a[index] (\a index defaults to 0).
-
- Control points after \a a[index + 3] are ignored. Nothing happens
- if there aren't enough control points.
-
- \warning On X11, coordinates that do not fit into 16-bit signed
- values are truncated. This limitation is expected to go away in
- TQt 4.
-*/
-
-void TQPainter::drawCubicBezier( const TQPointArray &a, int index )
-{
- if ( !isActive() )
- return;
- if ( a.size() - index < 4 ) {
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQPainter::drawCubicBezier: Cubic Bezier needs 4 control "
- "points" );
-#endif
- return;
- }
- TQPointArray pa( a );
- if ( index != 0 || a.size() > 4 ) {
- pa = TQPointArray( 4 );
- for ( int i=0; i<4; i++ )
- pa.setPoint( i, a.point(index+i) );
- }
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[1];
- param[0].ptarr = (TQPointArray*)&pa;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawCubicBezier, this, param) ||
- !hd )
- return;
- }
- if ( txop != TxNone )
- pa = xForm( pa );
- }
- if ( cpen.style() != NoPen ) {
- pa = pa.cubicBezier();
- XDrawLines( dpy, hd, gc, (XPoint*)pa.shortPoints(), pa.size(),
- CoordModeOrigin );
- }
-}
-
-
-/*!
- Draws a pixmap at \a (x, y) by copying a part of \a pixmap into
- the paint tqdevice.
-
- \a (x, y) specifies the top-left point in the paint tqdevice that is
- to be drawn onto. \a (sx, sy) specifies the top-left point in \a
- pixmap that is to be drawn. The default is (0, 0).
-
- \a (sw, sh) specifies the size of the pixmap that is to be drawn.
- The default, (-1, -1), means all the way to the bottom right of
- the pixmap.
-
- Currently the mask of the pixmap or it's alpha channel are ignored
- when painting on a TQPrinter.
-
- \sa bitBlt(), TQPixmap::setMask()
-*/
-
-void TQPainter::drawPixmap( int x, int y, const TQPixmap &pixmap,
- int sx, int sy, int sw, int sh )
-{
- if ( !isActive() || pixmap.isNull() )
- return;
-
- // right/bottom
- if ( sw < 0 )
- sw = pixmap.width() - sx;
- if ( sh < 0 )
- sh = pixmap.height() - sy;
-
- // Sanity-check clipping
- if ( sx < 0 ) {
- x -= sx;
- sw += sx;
- sx = 0;
- }
- if ( sw + sx > pixmap.width() )
- sw = pixmap.width() - sx;
- if ( sy < 0 ) {
- y -= sy;
- sh += sy;
- sy = 0;
- }
- if ( sh + sy > pixmap.height() )
- sh = pixmap.height() - sy;
-
- if ( sw <= 0 || sh <= 0 )
- return;
-
- if ( pdev->x11Screen() != pixmap.x11Screen() ) {
- TQPixmap* p = (TQPixmap*) &pixmap;
- p->x11SetScreen( pdev->x11Screen() );
- }
-
- TQPixmap::x11SetDefaultScreen( pixmap.x11Screen() );
-
- if ( testf(ExtDev|VxF|WxF) ) {
- if ( testf(ExtDev) || txop == TxScale || txop == TxRotShear ) {
- if ( sx != 0 || sy != 0 ||
- sw != pixmap.width() || sh != pixmap.height() ) {
- TQPixmap tmp( sw, sh, pixmap.depth() );
- bitBlt( &tmp, 0, 0, &pixmap, sx, sy, sw, sh, CopyROP, TRUE );
- if ( pixmap.mask() ) {
- TQBitmap mask( sw, sh );
- bitBlt( &mask, 0, 0, pixmap.mask(), sx, sy, sw, sh,
- CopyROP, TRUE );
- tmp.setMask( mask );
- }
- drawPixmap( x, y, tmp );
- return;
- }
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[2];
- TQRect r(x, y, pixmap.width(), pixmap.height());
- param[0].rect = &r;
- param[1].pixmap = &pixmap;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawPixmap, this, param) || !hd )
- return;
- }
- if ( txop == TxScale || txop == TxRotShear ) {
- TQWMatrix mat( m11(), m12(),
- m21(), m22(),
- dx(), dy() );
- mat = TQPixmap::trueMatrix( mat, sw, sh );
- TQPixmap pm = pixmap.xForm( mat );
- if ( !pm.mask() && txop == TxRotShear ) {
- TQBitmap bm_clip( sw, sh, 1 );
- bm_clip.fill( color1 );
- pm.setMask( bm_clip.xForm(mat) );
- }
- map( x, y, &x, &y ); // compute position of pixmap
- int dx, dy;
- mat.map( 0, 0, &dx, &dy );
- uint save_flags = flags;
- flags = IsActive | (save_flags & ClipOn);
- drawPixmap( x-dx, y-dy, pm );
- flags = save_flags;
- return;
- }
- }
- map( x, y, &x, &y );
- }
-
- TQBitmap *mask = (TQBitmap *)pixmap.mask();
- bool mono = pixmap.depth() == 1;
-
- if ( mask && !hasClipping() && pdev != paintEventDevice ) {
- if ( mono ) { // needs GCs pen color
- bool selfmask = pixmap.data->selfmask;
- if ( selfmask ) {
- XSetFillStyle( dpy, gc, FillStippled );
- XSetStipple( dpy, gc, pixmap.handle() );
- } else {
- XSetFillStyle( dpy, gc, FillOpaqueStippled );
- XSetStipple( dpy, gc, pixmap.handle() );
- XSetClipMask( dpy, gc, mask->handle() );
- XSetClipOrigin( dpy, gc, x-sx, y-sy );
- }
- XSetTSOrigin( dpy, gc, x-sx, y-sy );
- XFillRectangle( dpy, hd, gc, x, y, sw, sh );
- XSetTSOrigin( dpy, gc, 0, 0 );
- XSetFillStyle( dpy, gc, FillSolid );
- if ( !selfmask ) {
- if ( pdev == paintEventDevice && paintEventClipRegion ) {
- x11SetClipRegion( dpy, gc, 0, rendhd, *paintEventClipRegion );
- } else {
- x11ClearClipRegion(dpy, gc, 0, rendhd);
- }
- }
- } else {
- bitBlt( pdev, x, y, &pixmap, sx, sy, sw, sh, (RasterOp)rop );
- }
- return;
- }
-
- TQRegion rgn = crgn;
-
- if ( mask ) { // pixmap has clip mask
- // Implies that clipping is on, either explicit or implicit
- // Create a new mask that combines the mask with the clip region
-
- if ( pdev == paintEventDevice && paintEventClipRegion ) {
- if ( hasClipping() )
- rgn = rgn.intersect( *paintEventClipRegion );
- else
- rgn = *paintEventClipRegion;
- }
-
- TQBitmap *comb = new TQBitmap( sw, sh );
- comb->detach();
- GC cgc = qt_xget_temp_gc( pixmap.x11Screen(), TRUE ); // get temporary mono GC
- XSetForeground( dpy, cgc, 0 );
- XFillRectangle( dpy, comb->handle(), cgc, 0, 0, sw, sh );
- XSetBackground( dpy, cgc, 0 );
- XSetForeground( dpy, cgc, 1 );
- int num;
- XRectangle *rects = (XRectangle *)qt_getClipRects( rgn, num );
- XSetClipRectangles( dpy, cgc, -x, -y, rects, num, YXBanded );
- XSetFillStyle( dpy, cgc, FillOpaqueStippled );
- XSetStipple( dpy, cgc, mask->handle() );
- XSetTSOrigin( dpy, cgc, -sx, -sy );
- XFillRectangle( dpy, comb->handle(), cgc, 0, 0, sw, sh );
- XSetTSOrigin( dpy, cgc, 0, 0 ); // restore cgc
- XSetFillStyle( dpy, cgc, FillSolid );
- XSetClipMask( dpy, cgc, None );
- mask = comb; // it's deleted below
-
- XSetClipMask( dpy, gc, mask->handle() );
- XSetClipOrigin( dpy, gc, x, y );
- }
-
- if ( mono ) {
- XSetBackground( dpy, gc, bg_col.pixel(scrn) );
- XSetFillStyle( dpy, gc, FillOpaqueStippled );
- XSetStipple( dpy, gc, pixmap.handle() );
- XSetTSOrigin( dpy, gc, x-sx, y-sy );
- XFillRectangle( dpy, hd, gc, x, y, sw, sh );
- XSetTSOrigin( dpy, gc, 0, 0 );
- XSetFillStyle( dpy, gc, FillSolid );
- } else {
-#if !defined(TQT_NO_XFTFREETYPE) && !defined(TQT_NO_XRENDER)
- Picture pict = rendhd ? XftDrawPicture((XftDraw *) rendhd) : None;
- TQPixmap *alpha = pixmap.data->alphapm;
-
- if ( pict && pixmap.x11RenderHandle() &&
- alpha && alpha->x11RenderHandle()) {
- XRenderComposite(dpy, PictOpOver, pixmap.x11RenderHandle(),
- alpha->x11RenderHandle(), pict,
- sx, sy, sx, sy, x, y, sw, sh);
- } else
-#endif // !TQT_NO_XFTFREETYPE && !TQT_NO_XRENDER
- {
- XCopyArea( dpy, pixmap.handle(), hd, gc, sx, sy, sw, sh, x, y );
- }
- }
-
- if ( mask ) { // restore clipping
- XSetClipOrigin( dpy, gc, 0, 0 );
- XSetRegion( dpy, gc, rgn.handle() );
- delete mask; // delete comb, created above
- }
-}
-
-
-/* Internal, used by drawTiledPixmap */
-
-static void drawTile( TQPainter *p, int x, int y, int w, int h,
- const TQPixmap &pixmap, int xOffset, int yOffset )
-{
- int yPos, xPos, drawH, drawW, yOff, xOff;
- yPos = y;
- yOff = yOffset;
- while( yPos < y + h ) {
- drawH = pixmap.height() - yOff; // Cropping first row
- if ( yPos + drawH > y + h ) // Cropping last row
- drawH = y + h - yPos;
- xPos = x;
- xOff = xOffset;
- while( xPos < x + w ) {
- drawW = pixmap.width() - xOff; // Cropping first column
- if ( xPos + drawW > x + w ) // Cropping last column
- drawW = x + w - xPos;
- p->drawPixmap( xPos, yPos, pixmap, xOff, yOff, drawW, drawH );
- xPos += drawW;
- xOff = 0;
- }
- yPos += drawH;
- yOff = 0;
- }
-}
-
-#if 0 // see comment in drawTiledPixmap
-/* Internal, used by drawTiledPixmap */
-
-static void fillTile( TQPixmap *tile, const TQPixmap &pixmap )
-{
- bitBlt( tile, 0, 0, &pixmap, 0, 0, -1, -1, TQt::CopyROP, TRUE );
- int x = pixmap.width();
- while ( x < tile->width() ) {
- bitBlt( tile, x,0, tile, 0,0, x,pixmap.height(), TQt::CopyROP, TRUE );
- x *= 2;
- }
- int y = pixmap.height();
- while ( y < tile->height() ) {
- bitBlt( tile, 0,y, tile, 0,0, tile->width(),y, TQt::CopyROP, TRUE );
- y *= 2;
- }
-}
-#endif
-
-/*!
- Draws a tiled \a pixmap in the specified rectangle.
-
- \a (x, y) specifies the top-left point in the paint tqdevice that is
- to be drawn onto; with the width and height given by \a w and \a
- h. \a (sx, sy) specifies the top-left point in \a pixmap that is
- to be drawn. The default is (0, 0).
-
- Calling drawTiledPixmap() is similar to calling drawPixmap()
- several times to fill (tile) an area with a pixmap, but is
- potentially much more efficient depending on the underlying window
- system.
-
- \sa drawPixmap()
-*/
-
-void TQPainter::drawTiledPixmap( int x, int y, int w, int h,
- const TQPixmap &pixmap, int sx, int sy )
-{
- int sw = pixmap.width();
- int sh = pixmap.height();
- if (!sw || !sh )
- return;
- if ( sx < 0 )
- sx = sw - -sx % sw;
- else
- sx = sx % sw;
- if ( sy < 0 )
- sy = sh - -sy % sh;
- else
- sy = sy % sh;
- /*
- Requirements for optimizing tiled pixmaps:
- - not an external tqdevice
- - not scale or rotshear
- - not mono pixmap
- - no mask
- */
- TQBitmap *mask = (TQBitmap *)pixmap.mask();
- if ( !testf(ExtDev) && txop <= TxTranslate && pixmap.depth() > 1 &&
- mask == 0 ) {
- if ( txop == TxTranslate )
- map( x, y, &x, &y );
-
-#if !defined(TQT_NO_XFTFREETYPE) && !defined(TQT_NO_XRENDER)
- Picture pict = rendhd ? XftDrawPicture((XftDraw *) rendhd) : None;
- TQPixmap *alpha = pixmap.data->alphapm;
-
- if (pict && pixmap.x11RenderHandle() && alpha && alpha->x11RenderHandle()) {
- // this is essentially drawTile() from above, inlined for
- // the XRenderComposite call
- int yPos, xPos, drawH, drawW, yOff, xOff;
- yPos = y;
- yOff = sy;
- while( yPos < y + h ) {
- drawH = pixmap.height() - yOff; // Cropping first row
- if ( yPos + drawH > y + h ) // Cropping last row
- drawH = y + h - yPos;
- xPos = x;
- xOff = sx;
- while( xPos < x + w ) {
- drawW = pixmap.width() - xOff; // Cropping first column
- if ( xPos + drawW > x + w ) // Cropping last column
- drawW = x + w - xPos;
- XRenderComposite(dpy, PictOpOver, pixmap.x11RenderHandle(),
- alpha->x11RenderHandle(), pict,
- xOff, yOff, xOff, yOff, xPos, yPos, drawW, drawH);
- xPos += drawW;
- xOff = 0;
- }
- yPos += drawH;
- yOff = 0;
- }
- return;
- }
-#endif // !TQT_NO_XFTFREETYPE && !TQT_NO_XRENDER
-
- XSetTile( dpy, gc, pixmap.handle() );
- XSetFillStyle( dpy, gc, FillTiled );
- XSetTSOrigin( dpy, gc, x-sx, y-sy );
- XFillRectangle( dpy, hd, gc, x, y, w, h );
- XSetTSOrigin( dpy, gc, 0, 0 );
- XSetFillStyle( dpy, gc, FillSolid );
- return;
- }
-
-#if 0
- // maybe there'll be point in this again, but for the time all it
- // does is make trouble for the postscript code.
- if ( sw*sh < 8192 && sw*sh < 16*w*h ) {
- int tw = sw;
- int th = sh;
- while( th * tw < 4096 && ( th < h || tw < w ) ) {
- if ( h/th > w/tw )
- th *= 2;
- else
- tw *= 2;
- }
- TQPixmap tile( tw, th, pixmap.depth(), TQPixmap::NormalOptim );
- fillTile( &tile, pixmap );
- if ( mask ) {
- TQBitmap tilemask( tw, th, TQPixmap::NormalOptim );
- fillTile( &tilemask, *mask );
- tile.setMask( tilemask );
- }
- drawTile( this, x, y, w, h, tile, sx, sy );
- } else {
- drawTile( this, x, y, w, h, pixmap, sx, sy );
- }
-#else
- // for now we'll just output the original and let the postscript
- // code make what it can of it. qpicture will be unhappy.
- drawTile( this, x, y, w, h, pixmap, sx, sy );
-#endif
-}
-
-#if 0
-//
-// Generate a string that describes a transformed bitmap. This string is used
-// to insert and find bitmaps in the global pixmap cache.
-//
-
-static TQString gen_text_bitmap_key( const TQWMatrix &m, const TQFont &font,
- const TQString &str, int pos, int len )
-{
- TQString fk = font.key();
- int sz = 4*2 + len*2 + fk.length()*2 + sizeof(double)*6;
- TQByteArray buf(sz);
- uchar *p = (uchar *)buf.data();
- *((double*)p)=m.m11(); p+=sizeof(double);
- *((double*)p)=m.m12(); p+=sizeof(double);
- *((double*)p)=m.m21(); p+=sizeof(double);
- *((double*)p)=m.m22(); p+=sizeof(double);
- *((double*)p)=m.dx(); p+=sizeof(double);
- *((double*)p)=m.dy(); p+=sizeof(double);
- TQChar h1( '$' );
- TQChar h2( 'q' );
- TQChar h3( 't' );
- TQChar h4( '$' );
- *((TQChar*)p)=h1; p+=2;
- *((TQChar*)p)=h2; p+=2;
- *((TQChar*)p)=h3; p+=2;
- *((TQChar*)p)=h4; p+=2;
- memcpy( (char*)p, (char*)(str.tqunicode()+pos), len*2 ); p += len*2;
- memcpy( (char*)p, (char*)fk.tqunicode(), fk.length()*2 ); p += fk.length()*2;
- return TQString( (TQChar*)buf.data(), buf.size()/2 );
-}
-
-static TQBitmap *get_text_bitmap( const TQString &key )
-{
- return (TQBitmap*)TQPixmapCache::find( key );
-}
-
-static void ins_text_bitmap( const TQString &key, TQBitmap *bm )
-{
- if ( !TQPixmapCache::insert(key, bm) ) // cannot insert pixmap
- delete bm;
-}
-#endif
-
-void qt_draw_transformed_rect( TQPainter *p, int x, int y, int w, int h, bool fill )
-{
- XPoint points[5];
- int xp = x, yp = y;
- p->map( xp, yp, &xp, &yp );
- points[0].x = xp;
- points[0].y = yp;
- xp = x + w; yp = y;
- p->map( xp, yp, &xp, &yp );
- points[1].x = xp;
- points[1].y = yp;
- xp = x + w; yp = y + h;
- p->map( xp, yp, &xp, &yp );
- points[2].x = xp;
- points[2].y = yp;
- xp = x; yp = y + h;
- p->map( xp, yp, &xp, &yp );
- points[3].x = xp;
- points[3].y = yp;
- points[4] = points[0];
-
- if ( fill )
- XFillPolygon( p->dpy, p->hd, p->gc, points, 4, Convex, CoordModeOrigin );
- else
- XDrawLines( p->dpy, p->hd, p->gc, points, 5, CoordModeOrigin );
-}
-
-void qt_draw_background( TQPainter *p, int x, int y, int w, int h )
-{
- if (p->testf(TQPainter::ExtDev)) {
- if (p->pdev->devType() == TQInternal::Printer)
- p->fillRect(x, y, w, h, p->bg_col);
- return;
- }
- XSetForeground( p->dpy, p->gc, p->bg_col.pixel(p->scrn) );
- qt_draw_transformed_rect( p, x, y, w, h, TRUE);
- XSetForeground( p->dpy, p->gc, p->cpen.color().pixel(p->scrn) );
-}
-
-/*!
- Draws at most \a len characters of the string \a str at position
- \a (x, y).
-
- \a (x, y) is the base line position. Note that the meaning of \a y
- is not the same for the two drawText() varieties.
-*/
-void TQPainter::drawText( int x, int y, const TQString &str, int len, TQPainter::TextDirection dir )
-{
- drawText( x, y, str, 0, len, dir );
-}
-
-/*!
- Draws at most \a len characters starting at position \a pos from the
- string \a str to position \a (x, y).
-
- \a (x, y) is the base line position. Note that the meaning of \a y
- is not the same for the two drawText() varieties.
-*/
-void TQPainter::drawText( int x, int y, const TQString &str, int pos, int len, TQPainter::TextDirection dir )
-{
- if ( !isActive() )
- return;
- if (len < 0)
- len = str.length() - pos;
- if ( len <= 0 || pos >= (int)str.length() ) // empty string
- return;
- if ( pos + len > (int)str.length() )
- len = str.length() - pos;
-
- if ( testf(DirtyFont) ) {
- updateFont();
- }
-
- if ( testf(ExtDev) && pdev->devType() != TQInternal::Printer ) {
- TQPDevCmdParam param[3];
- TQPoint p(x, y);
- TQString string = str.mid( pos, len );
- param[0].point = &p;
- param[1].str = &string;
- param[2].ival = TQFont::Latin;
- if ( !pdev->cmd(TQPaintDevice::PdcDrawText2, this, param) || !hd )
- return;
- }
-
- bool simple = (dir == TQPainter::Auto) && str.simpleText();
- // we can't take the complete string here as we would otherwise
- // get quadratic behaviour when drawing long strings in parts.
- // we do however need some chars around the part we paint to get arabic shaping correct.
- // ### maybe possible to remove after cursor restrictions work in TQRT
- int start;
- int end;
- if ( simple ) {
- start = pos;
- end = pos+len;
- } else {
- start = TQMAX( 0, pos - 8 );
- end = TQMIN( (int)str.length(), pos + len + 8 );
- }
- TQConstString cstr( str.tqunicode() + start, end - start );
- pos -= start;
-
- TQTextEngine engine( cstr.string(), pfont ? pfont->d : cfont.d );
- TQTextLayout tqlayout( &engine );
-
- // this is actually what beginLayout does. Inlined here, so we can
- // avoid the bidi algorithm if we don't need it.
- engine.itemize( simple ? TQTextEngine::NoBidi|TQTextEngine::SingleLine : TQTextEngine::Full|TQTextEngine::SingleLine );
- engine.currentItem = 0;
- engine.firstItemInLine = -1;
-
- if ( dir != Auto ) {
- int level = dir == RTL ? 1 : 0;
- for ( int i = engine.items.size(); i >= 0; i-- )
- engine.items[i].analysis.bidiLevel = level;
- }
-
- if ( !simple ) {
- tqlayout.setBoundary( pos );
- tqlayout.setBoundary( pos + len );
- }
-
- // small hack to force skipping of unneeded items
- start = 0;
- while ( engine.items[start].position < pos )
- ++start;
- engine.currentItem = start;
- tqlayout.beginLine( 0xfffffff );
- end = start;
- while ( !tqlayout.atEnd() && tqlayout.currentItem().from() < pos + len ) {
- tqlayout.addCurrentItem();
- end++;
- }
- TQFontMetrics fm(fontMetrics());
- int ascent = fm.ascent(), descent = fm.descent();
- int left, right;
- tqlayout.endLine( 0, 0, TQt::SingleLine|TQt::AlignLeft, &ascent, &descent, &left, &right );
-
- // do _not_ call endLayout() here, as it would clean up the tqshaped items and we would do shaping another time
- // for painting.
-
- int textFlags = 0;
- if ( cfont.d->underline ) textFlags |= TQt::Underline;
- if ( cfont.d->overline ) textFlags |= TQt::Overline;
- if ( cfont.d->strikeOut ) textFlags |= TQt::StrikeOut;
-
- if ( bg_mode == OpaqueMode )
- qt_draw_background( this, x, y-ascent, right-left, ascent+descent+1);
-
- for ( int i = start; i < end; i++ ) {
- TQTextItem ti;
- ti.item = i;
- ti.engine = &engine;
-
- tqdrawTextItem( x, y - ascent, ti, textFlags );
- }
- tqlayout.d = 0;
-}
-
-
-/*! \internal
- Draws the text item \a ti at position \a (x, y ).
-
- This method ignores the painters background mode and
- color. drawText and qt_format_text have to do it themselves, as
- only they know the extents of the complete string.
-
- It ignores the font set on the painter as the text item has one of its own.
-
- The underline and strikeout parameters of the text items font are
- ignored aswell. You'll need to pass in the correct flags to get
- underlining and strikeout.
-*/
-void TQPainter::tqdrawTextItem( int x, int y, const TQTextItem &ti, int textFlags )
-{
- if ( testf(ExtDev) ) {
- TQPDevCmdParam param[2];
- TQPoint p(x, y);
- param[0].point = &p;
- param[1].textItem = &ti;
- bool retval = pdev->cmd(TQPaintDevice::PdcDrawTextItem, this, param);
- if ( !retval || !hd )
- return;
- }
-
- TQTextEngine *engine = ti.engine;
- TQScriptItem *si = &engine->items[ti.item];
-
- engine->tqshape( ti.item );
- TQFontEngine *fe = si->fontEngine;
- assert( fe != 0 );
-
- x += si->x;
- y += si->y;
-
- fe->draw( this, x, y, engine, si, textFlags );
-}
-
-#if TQT_VERSION >= 0x040000
-#error "remove current position and associated methods"
-#endif
-/*!
- \obsolete
- Returns the current position of the pen.
-
- \sa moveTo()
- */
-TQPoint TQPainter::pos() const
-{
- return curPt;
-}
-
-#endif // USE_QT4