Source Code (Use browser search to find items of interest.)
Class Index
qt'QPainter (./qt-2.1.0/src/kernel/qpainter.h:46)
class Q_EXPORT QPainter : public Qt
{
public:
QPainter();
QPainter( const QPaintDevice * );
QPainter( const QPaintDevice *, const QWidget * );
~QPainter();
bool begin( const QPaintDevice * );
bool begin( const QPaintDevice *, const QWidget * );
bool end();
QPaintDevice *device() const;
static void redirect( QPaintDevice *pdev, QPaintDevice *replacement );
bool isActive() const;
void flush();
void save();
void restore();
// Drawing tools
QFontMetrics fontMetrics() const;
QFontInfo fontInfo() const;
const QFont &font() const;
void setFont( const QFont & );
const QPen &pen() const;
void setPen( const QPen & );
void setPen( PenStyle );
void setPen( const QColor & );
const QBrush &brush() const;
void setBrush( const QBrush & );
void setBrush( BrushStyle );
void setBrush( const QColor & );
QPoint pos() const;
// Drawing attributes/modes
const QColor &backgroundColor() const;
void setBackgroundColor( const QColor & );
BGMode backgroundMode() const;
void setBackgroundMode( BGMode );
RasterOp rasterOp() const;
void setRasterOp( RasterOp );
const QPoint &brushOrigin() const;
void setBrushOrigin( int x, int y );
void setBrushOrigin( const QPoint & );
// Scaling and transformations
// PaintUnit unit() const; // get set painter unit
// void setUnit( PaintUnit ); // NOT IMPLEMENTED!!!
void setViewXForm( bool ); // set xform on/off
bool hasViewXForm() const;
QRect window() const; // get window
void setWindow( const QRect & ); // set window
void setWindow( int x, int y, int w, int h );
QRect viewport() const; // get viewport
void setViewport( const QRect & ); // set viewport
void setViewport( int x, int y, int w, int h );
void setWorldXForm( bool ); // set world xform on/off
bool hasWorldXForm() const;
const QWMatrix &worldMatrix() const; // get/set world xform matrix
void setWorldMatrix( const QWMatrix &, bool combine=FALSE );
void saveWorldMatrix();
void restoreWorldMatrix();
void translate( double dx, double dy );
void scale( double sx, double sy );
void shear( double sh, double sv );
void rotate( double a );
void resetXForm();
QPoint xForm( const QPoint & ) const; // map virtual -> device
QRect xForm( const QRect & ) const;
QPointArray xForm( const QPointArray & ) const;
QPointArray xForm( const QPointArray &, int index, int npoints ) const;
QPoint xFormDev( const QPoint & ) const; // map device -> virtual
QRect xFormDev( const QRect & ) const;
QPointArray xFormDev( const QPointArray & ) const;
QPointArray xFormDev( const QPointArray &, int index, int npoints ) const;
// Clipping
void setClipping( bool ); // set clipping on/off
bool hasClipping() const;
const QRegion &clipRegion() const;
void setClipRect( const QRect & ); // set clip rectangle
void setClipRect( int x, int y, int w, int h );
void setClipRegion( const QRegion &);// set clip region
// Graphics drawing functions
void drawPoint( int x, int y );
void drawPoint( const QPoint & );
void drawPoints( const QPointArray& a,
int index=0, int npoints=-1 );
void moveTo( int x, int y );
void moveTo( const QPoint & );
void lineTo( int x, int y );
void lineTo( const QPoint & );
void drawLine( int x1, int y1, int x2, int y2 );
void drawLine( const QPoint &, const QPoint & );
void drawRect( int x, int y, int w, int h );
void drawRect( const QRect & );
void drawWinFocusRect( int x, int y, int w, int h );
void drawWinFocusRect( int x, int y, int w, int h,
const QColor &bgColor );
void drawWinFocusRect( const QRect & );
void drawWinFocusRect( const QRect &,
const QColor &bgColor );
void drawRoundRect( int x, int y, int w, int h, int, int );
void drawRoundRect( const QRect &, int, int );
void drawRoundRect( int x, int y, int w, int h );
void drawRoundRect( const QRect & );
void drawEllipse( int x, int y, int w, int h );
void drawEllipse( const QRect & );
void drawArc( int x, int y, int w, int h, int a, int alen );
void drawArc( const QRect &, int a, int alen );
void drawPie( int x, int y, int w, int h, int a, int alen );
void drawPie( const QRect &, int a, int alen );
void drawChord( int x, int y, int w, int h, int a, int alen );
void drawChord( const QRect &, int a, int alen );
void drawLineSegments( const QPointArray &,
int index=0, int nlines=-1 );
void drawPolyline( const QPointArray &,
int index=0, int npoints=-1 );
void drawPolygon( const QPointArray &, bool winding=FALSE,
int index=0, int npoints=-1 );
void drawQuadBezier( const QPointArray &, int index=0 );
void drawPixmap( int x, int y, const QPixmap &,
int sx=0, int sy=0, int sw=-1, int sh=-1 );
void drawPixmap( const QPoint &, const QPixmap &,
const QRect &sr );
void drawPixmap( const QPoint &, const QPixmap & );
void drawImage( int x, int y, const QImage &,
int sx=0, int sy=0, int sw=-1, int sh=-1 );
void drawImage( const QPoint &, const QImage &,
const QRect &sr );
void drawImage( const QPoint &, const QImage & );
void drawTiledPixmap( int x, int y, int w, int h, const QPixmap &,
int sx=0, int sy=0 );
void drawTiledPixmap( const QRect &, const QPixmap &,
const QPoint & );
void drawTiledPixmap( const QRect &, const QPixmap & );
void drawPicture( const QPicture & );
void fillRect( int x, int y, int w, int h, const QBrush & );
void fillRect( const QRect &, const QBrush & );
void eraseRect( int x, int y, int w, int h );
void eraseRect( const QRect & );
// Text drawing functions
void drawText( int x, int y, const QString &, int len = -1 );
void drawText( const QPoint &, const QString &, int len = -1 );
void drawText( int x, int y, int w, int h, int flags,
const QString&, int len = -1, QRect *br=0,
char **internal=0 );
void drawText( const QRect &, int flags,
const QString&, int len = -1, QRect *br=0,
char **internal=0 );
//##### void drawText( const QPoint &, const QString &, int flags, int rotation = 0);
// Text drawing functions
QRect boundingRect( int x, int y, int w, int h, int flags,
const QString&, int len = -1, char **intern=0 );
QRect boundingRect( const QRect &, int flags,
const QString&, int len = -1, char **intern=0 );
int tabStops() const;
void setTabStops( int );
int *tabArray() const;
void setTabArray( int * );
// Other functions
#if defined(_WS_WIN_)
HDC handle() const;
#elif defined(_WS_X11_)
HANDLE handle() const;
#endif
static void initialize();
static void cleanup();
private:
void init();
void updateFont();
void updatePen();
void updateBrush();
void updateXForm();
void updateInvXForm();
void map( int, int, int *rx, int *ry ) const;
void map( int, int, int, int, int *, int *, int *, int * ) const;
void mapInv( int, int, int *, int * ) const;
void mapInv( int, int, int, int, int *, int *, int *, int * ) const;
void drawPolyInternal( const QPointArray &, bool close=TRUE );
void drawWinFocusRect( int x, int y, int w, int h, bool xorPaint,
const QColor &penColor );
enum { IsActive=0x01, ExtDev=0x02, IsStartingUp=0x04, NoCache=0x08,
VxF=0x10, WxF=0x20, ClipOn=0x40, SafePolygon=0x80, MonoDev=0x100,
DirtyFont=0x200, DirtyPen=0x400, DirtyBrush=0x800,
RGBColor=0x1000, FontMet=0x2000, FontInf=0x4000, CtorBegin=0x8000,
UsePrivateCx = 0x10000, VolatileDC = 0x20000 };
uint flags;
bool testf( uint b ) const { return (flags&b)!=0; }
void setf( uint b ) { flags |= b; }
void setf( uint b, bool v );
void clearf( uint b ) { flags &= (uint)(~b); }
void fix_neg_rect( int *x, int *y, int *w, int *h );
QPaintDevice *pdev;
QColor bg_col;
uchar bg_mode;
uchar rop;
uchar pu;
QPoint bro;
QFont cfont;
QPen cpen;
QBrush cbrush;
QRegion crgn;
int tabstops;
int *tabarray;
int tabarraylen;
// Transformations
QCOORD wx, wy, ww, wh;
QCOORD vx, vy, vw, vh;
QWMatrix wxmat;
// Cached composition (and inverse) of transformations
QWMatrix xmat;
QWMatrix ixmat;
double m11() const { return xmat.m11(); }
double m12() const { return xmat.m12(); }
double m21() const { return xmat.m21(); }
double m22() const { return xmat.m22(); }
double dx() const { return xmat.dx(); }
double dy() const { return xmat.dy(); }
double im11() const { return ixmat.m11(); }
double im12() const { return ixmat.m12(); }
double im21() const { return ixmat.m21(); }
double im22() const { return ixmat.m22(); }
double idx() const { return ixmat.dx(); }
double idy() const { return ixmat.dy(); }
int txop;
bool txinv;
void *penRef; // pen cache ref
void *brushRef; // brush cache ref
void *ps_stack;
void *wm_stack;
void killPStack();
protected:
#if defined(_WS_WIN_)
HDC hdc; // device context
HPEN hpen; // current pen
HBRUSH hbrush; // current brush
HBITMAP hbrushbm; // current brush bitmap
HFONT hfont; // current font
HPALETTE holdpal;
void *textmet; // text metrics
uint pixmapBrush : 1;
uint nocolBrush : 1;
uint killFont : 1;
void *textMetric();
void nativeXForm( bool );
#elif defined(_WS_X11_)
Display *dpy; // current display
WId hd; // handle to drawable
GC gc; // graphics context (standard)
GC gc_brush; // graphics contect for brush
QPoint curPt; // current point
#elif defined(_WS_MAC_)
int penx;
int peny;
void * hd;
#endif
friend class QFontMetrics;
friend class QFontInfo;
friend void qt_format_text( const QFontMetrics& fm, int x, int y, int w, int h,
int tf, const QString& str, int len, QRect *brect,
int tabstops, int* tabarray, int tabarraylen,
char **internal, QPainter* painter );
private: // Disabled copy constructor and operator=
#if defined(Q_DISABLE_COPY)
QPainter( const QPainter & );
QPainter &operator=( const QPainter & );
#endif
};
/*****************************************************************************
QPainter member functions
*****************************************************************************/
inline QPaintDevice *QPainter::device() const
{
return pdev;
}
inline bool QPainter::isActive() const
{
return testf(IsActive);
}
inline const QFont &QPainter::font() const
{
return cfont;
}
inline const QPen &QPainter::pen() const
{
return cpen;
}
inline const QBrush &QPainter::brush() const
{
return cbrush;
}
/*
inline PaintUnit QPainter::unit() const
{
return (PaintUnit)pu;
}
*/
inline const QColor &QPainter::backgroundColor() const
{
return bg_col;
}
inline Qt::BGMode QPainter::backgroundMode() const
{
return (BGMode)bg_mode;
}
inline Qt::RasterOp QPainter::rasterOp() const
{
return (RasterOp)rop;
}
inline const QPoint &QPainter::brushOrigin() const
{
return bro;
}
inline bool QPainter::hasViewXForm() const
{
return testf(VxF);
}
inline bool QPainter::hasWorldXForm() const
{
return testf(WxF);
}
inline bool QPainter::hasClipping() const
{
return testf(ClipOn);
}
inline const QRegion &QPainter::clipRegion() const
{
return crgn;
}
inline int QPainter::tabStops() const
{
return tabstops;
}
inline int *QPainter::tabArray() const
{
return tabarray;
}
#if defined(_WS_WIN_)
inline HDC QPainter::handle() const
{
return hdc;
}
#elif defined(_WS_X11_)
inline HANDLE QPainter::handle() const
{
return hd;
}
#endif
inline void QPainter::setBrushOrigin( const QPoint &p )
{
setBrushOrigin( p.x(), p.y() );
}
inline void QPainter::setWindow( const QRect &r )
{
setWindow( r.x(), r.y(), r.width(), r.height() );
}
inline void QPainter::setViewport( const QRect &r )
{
setViewport( r.x(), r.y(), r.width(), r.height() );
}
inline void QPainter::setClipRect( int x, int y, int w, int h )
{
setClipRect( QRect(x,y,w,h) );
}
inline void QPainter::drawPoint( const QPoint &p )
{
drawPoint( p.x(), p.y() );
}
inline void QPainter::moveTo( const QPoint &p )
{
moveTo( p.x(), p.y() );
}
inline void QPainter::lineTo( const QPoint &p )
{
lineTo( p.x(), p.y() );
}
inline void QPainter::drawLine( const QPoint &p1, const QPoint &p2 )
{
drawLine( p1.x(), p1.y(), p2.x(), p2.y() );
}
inline void QPainter::drawRect( const QRect &r )
{
drawRect( r.x(), r.y(), r.width(), r.height() );
}
inline void QPainter::drawWinFocusRect( const QRect &r )
{
drawWinFocusRect( r.x(), r.y(), r.width(), r.height() );
}
inline void QPainter::drawWinFocusRect( const QRect &r,const QColor &penColor )
{
drawWinFocusRect( r.x(), r.y(), r.width(), r.height(), penColor );
}
inline void QPainter::drawRoundRect( const QRect &r, int xRnd, int yRnd )
{
drawRoundRect( r.x(), r.y(), r.width(), r.height(), xRnd, yRnd );
}
inline void QPainter::drawRoundRect( const QRect &r )
{
// ### Qt 3.0 make one func. with def. args.
drawRoundRect( r.x(), r.y(), r.width(), r.height(), 25, 25 );
}
inline void QPainter::drawRoundRect( int x, int y, int w, int h )
{
// ### Qt 3.0 make one func. with def. args.
drawRoundRect( x, y, w, h, 25, 25 );
}
inline void QPainter::drawEllipse( const QRect &r )
{
drawEllipse( r.x(), r.y(), r.width(), r.height() );
}
inline void QPainter::drawArc( const QRect &r, int a, int alen )
{
drawArc( r.x(), r.y(), r.width(), r.height(), a, alen );
}
inline void QPainter::drawPie( const QRect &r, int a, int alen )
{
drawPie( r.x(), r.y(), r.width(), r.height(), a, alen );
}
inline void QPainter::drawChord( const QRect &r, int a, int alen )
{
drawChord( r.x(), r.y(), r.width(), r.height(), a, alen );
}
inline void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm,
const QRect &sr )
{
drawPixmap( p.x(), p.y(), pm, sr.x(), sr.y(), sr.width(), sr.height() );
}
inline void QPainter::drawImage( const QPoint &p, const QImage &pm,
const QRect &sr )
{
drawImage( p.x(), p.y(), pm, sr.x(), sr.y(), sr.width(), sr.height() );
}
inline void QPainter::drawTiledPixmap( const QRect &r, const QPixmap &pm,
const QPoint &sp )
{
drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), pm, sp.x(), sp.y() );
}
inline void QPainter::drawTiledPixmap( const QRect &r, const QPixmap &pm )
{
drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), pm, 0, 0 );
}
inline void QPainter::fillRect( const QRect &r, const QBrush &brush )
{
fillRect( r.x(), r.y(), r.width(), r.height(), brush );
}
inline void QPainter::eraseRect( int x, int y, int w, int h )
{
fillRect( x, y, w, h, backgroundColor() );
}
inline void QPainter::eraseRect( const QRect &r )
{
fillRect( r.x(), r.y(), r.width(), r.height(), backgroundColor() );
}
inline void QPainter::drawText( const QPoint &p, const QString &s, int len )
{
drawText( p.x(), p.y(), s, len );
}
inline void QPainter::drawText( const QRect &r, int tf,
const QString& str, int len, QRect *br, char **i )
{
drawText( r.x(), r.y(), r.width(), r.height(), tf, str, len, br, i );
}
inline QRect QPainter::boundingRect( const QRect &r, int tf,
const QString& str, int len, char **i )
{
return boundingRect( r.x(), r.y(), r.width(), r.height(), tf, str, len,
i );
}
#if defined(_WS_WIN_)
inline void *QPainter::textMetric()
{
if ( testf(DirtyFont) )
updateFont();
return textmet;
}
#endif
qt'QPainter::textMetric() (./qt-2.1.0/include/qpainter.h:605)
inline void *QPainter::textMetric()
{
if ( testf(DirtyFont) )
updateFont();
return textmet;
}
#endif
qt'QPainter::QPainter() (./qt-2.1.0/src/kernel/qpainter.cpp:247)
QPainter::QPainter()
{
init();
}
/*!
Constructs a painter that begins painting the paint device \a pd
immediately.
This constructor is convenient for short-lived painters, e.g. in
a \link QWidget::paintEvent() paint event\endlink and should be
used only once. The constructor calls begin() for you and the QPainter
destructor automatically calls end().
Example using begin() and end():
\code
void MyWidget::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.drawLine( ... ); // drawing code
}
\endcode
Example using this constructor:
\code
void MyWidget::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.drawLine( ... ); // drawing code
}
\endcode
\sa begin(), end()
*/
qt'QPainter::QPainter() (./qt-2.1.0/src/kernel/qpainter.cpp:283)
QPainter::QPainter( const QPaintDevice *pd )
{
init();
begin( pd );
flags |= CtorBegin;
}
/*!
Constructs a painter that begins painting the paint device \a pd
immediately, with the default arguments taken from \a copyAttributes.
\sa begin()
*/
qt'QPainter::QPainter() (./qt-2.1.0/src/kernel/qpainter.cpp:298)
QPainter::QPainter( const QPaintDevice *pd,
const QWidget *copyAttributes )
{
init();
begin( pd, copyAttributes );
flags |= CtorBegin;
}
/*!
Destructs the painter.
*/
qt'QPainter::~QPainter() (./qt-2.1.0/src/kernel/qpainter.cpp:311)
QPainter::~QPainter()
{
if ( isActive() )
end();
if ( tabarray ) // delete tab array
delete [] tabarray;
if ( ps_stack )
killPStack();
if (wm_stack )
delete (QWMatrixStack *)wm_stack;
}
/*!
\overload bool QPainter::begin( const QPaintDevice *pd, const QWidget *copyAttributes )
This version opens the painter on a paint device \a pd and sets the initial
pen, background color and font from \a copyAttributes. This is equivalent
with:
\code
QPainter p;
p.begin( pd );
p.setPen( copyAttributes->foregroundColor() );
p.setBackgroundColor( copyAttributes->backgroundColor() );
p.setFont( copyAttributes->font() );
\endcode
This begin function is convenient for double buffering. When you
draw in a pixmap instead of directly in a widget (to later bitBlt
the pixmap into the widget) you will need to set the widgets's
font etc. This function does exactly that.
Example:
\code
void MyWidget::paintEvent( QPaintEvent * )
{
QPixmap pm(size());
QPainter p;
p.begin(&pm, this);
// ... potential flickering paint operation ...
p.end();
bitBlt(this, 0, 0, &pm);
}
\endcode
\sa end()
*/
qt'QPainter::begin() (./qt-2.1.0/src/kernel/qpainter.cpp:359)
bool QPainter::begin( const QPaintDevice *pd, const QWidget *copyAttributes )
{
if ( copyAttributes == 0 ) {
#if defined(CHECK_NULL)
qWarning( "QPainter::begin: The widget to copy attributes from cannot "
"be null" );
#endif
return FALSE;
}
if ( begin(pd) ) {
setPen( copyAttributes->foregroundColor() );
setBackgroundColor( copyAttributes->backgroundColor() );
setFont( copyAttributes->font() );
return TRUE;
}
return FALSE;
}
/*!
\internal
Sets or clears a pointer flag.
*/
qt'QPainter::setf() (./qt-2.1.0/src/kernel/qpainter.cpp:383)
void QPainter::setf( uint b, bool v )
{
if ( v )
setf( b );
else
clearf( b );
}
/*!
\fn bool QPainter::isActive() const
Returns TRUE if the painter is active painting, i.e. begin() has
been called and end() has not yet been called.
\sa QPaintDevice::paintingActive()
*/
/*!
\fn QPaintDevice *QPainter::device() const
Returns the paint device on which this painter is currently
painting, or null if the painter is not active.
\sa QPaintDevice::paintingActive()
*/
qt'QPainter::killPStack() (./qt-2.1.0/src/kernel/qpainter.cpp:436)
void QPainter::killPStack()
{
delete (QPStateStack *)ps_stack;
ps_stack = 0;
}
/*!
Saves the current painter state (pushes the state onto a stack).
A save() must have a corresponding restore().
\sa restore()
*/
qt'QPainter::save() (./qt-2.1.0/src/kernel/qpainter.cpp:450)
void QPainter::save()
{
if ( testf(ExtDev) ) {
if ( testf(DirtyFont) )
updateFont();
if ( testf(DirtyPen) )
updatePen();
if ( testf(DirtyBrush) )
updateBrush();
pdev->cmd( QPaintDevice::PdcSave, this, 0 );
}
QPStateStack *pss = (QPStateStack *)ps_stack;
if ( pss == 0 ) {
pss = new QStack<QPState>;
CHECK_PTR( pss );
pss->setAutoDelete( TRUE );
ps_stack = pss;
}
QPState *ps = new QPState;
CHECK_PTR( ps );
ps->font = cfont;
ps->pen = cpen;
ps->brush = cbrush;
ps->bgc = bg_col;
ps->bgm = bg_mode;
ps->rop = rop;
ps->bro = bro;
#if 0
ps->pu = pu; // !!!not used
#endif
ps->wr = QRect( wx, wy, ww, wh );
ps->vr = QRect( vx, vy, vw, vh );
ps->wm = wxmat;
ps->vxf = testf(VxF);
ps->wxf = testf(WxF);
ps->rgn = crgn;
ps->clip = testf(ClipOn);
ps->ts = tabstops;
ps->ta = tabarray;
ps->wm_stack = wm_stack;
wm_stack = 0;
pss->push( ps );
}
/*!
Restores the current painter state (pops a saved state off the stack).
\sa save()
*/
qt'QPainter::restore() (./qt-2.1.0/src/kernel/qpainter.cpp:499)
void QPainter::restore()
{
if ( testf(ExtDev) ) {
pdev->cmd( QPaintDevice::PdcRestore, this, 0 );
}
QPStateStack *pss = (QPStateStack *)ps_stack;
if ( pss == 0 || pss->isEmpty() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::restore: Empty stack error" );
#endif
return;
}
QPState *ps = pss->pop();
bool hardRestore = testf(VolatileDC);
if ( ps->font != cfont || hardRestore )
setFont( ps->font );
if ( ps->pen != cpen || hardRestore )
setPen( ps->pen );
if ( ps->brush != cbrush || hardRestore )
setBrush( ps->brush );
if ( ps->bgc != bg_col || hardRestore )
setBackgroundColor( ps->bgc );
if ( ps->bgm != bg_mode || hardRestore )
setBackgroundMode( (BGMode)ps->bgm );
if ( ps->rop != rop || hardRestore )
setRasterOp( (RasterOp)ps->rop );
#if 0
if ( ps->pu != pu ) // !!!not used
pu = ps->pu;
#endif
QRect wr( wx, wy, ww, wh );
QRect vr( vx, vy, vw, vh );
if ( ps->wr != wr || hardRestore )
setWindow( ps->wr );
if ( ps->vr != vr || hardRestore )
setViewport( ps->vr );
if ( ps->wm != wxmat || hardRestore )
setWorldMatrix( ps->wm );
if ( ps->vxf != testf(VxF) || hardRestore )
setViewXForm( ps->vxf );
if ( ps->wxf != testf(WxF) || hardRestore )
setWorldXForm( ps->wxf );
if ( ps->rgn != crgn || hardRestore )
setClipRegion( ps->rgn );
if ( ps->clip != testf(ClipOn) || hardRestore )
setClipping( ps->clip );
tabstops = ps->ts;
tabarray = ps->ta;
if (wm_stack )
delete (QWMatrixStack *)wm_stack;
wm_stack = ps->wm_stack;
delete ps;
}
/*!
Returns the font metrics for the painter.
Font metrics can only be obtained when the painter is active.
\sa fontInfo(), isActive()
*/
qt'QPainter::fontMetrics() (./qt-2.1.0/src/kernel/qpainter.cpp:562)
QFontMetrics QPainter::fontMetrics() const
{
if ( pdev && pdev->devType() == QInternal::Picture )
return QFontMetrics( cfont );
return QFontMetrics(this);
}
/*!
Returns the font info for the painter.
Font info can only be obtained when the painter is active.
\sa fontMetrics(), isActive()
*/
qt'QPainter::fontInfo() (./qt-2.1.0/src/kernel/qpainter.cpp:576)
QFontInfo QPainter::fontInfo() const
{
if ( pdev && pdev->devType() == QInternal::Picture )
return QFontInfo( cfont );
return QFontInfo(this);
}
/*!
\fn const QPen &QPainter::pen() const
Returns the current pen for the painter.
\sa setPen()
*/
/*!
Sets a new painter pen.
The pen defines how to draw lines and outlines, and it also defines
the text color.
\sa pen()
*/
qt'QPainter::setPen() (./qt-2.1.0/src/kernel/qpainter.cpp:600)
void QPainter::setPen( const QPen &pen )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setPen: Will be reset by begin()" );
#endif
cpen = pen;
updatePen();
}
/*!
Sets a new painter pen with style \c style, width 0 and black color.
\sa pen(), QPen
*/
qt'QPainter::setPen() (./qt-2.1.0/src/kernel/qpainter.cpp:615)
void QPainter::setPen( PenStyle style )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setPen: Will be reset by begin()" );
#endif
QPen::QPenData *d = cpen.data; // low level access
if ( d->count != 1 ) {
cpen.detach();
d = cpen.data;
}
d->style = style;
d->width = 0;
d->color = Qt::black;
d->linest = style;
updatePen();
}
/*!
Sets a new painter pen with style \c SolidLine, width 0 and the specified
\e color.
\sa pen(), QPen
*/
qt'QPainter::setPen() (./qt-2.1.0/src/kernel/qpainter.cpp:639)
void QPainter::setPen( const QColor &color )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setPen: Will be reset by begin()" );
#endif
QPen::QPenData *d = cpen.data; // low level access
if ( d->count != 1 ) {
cpen.detach();
d = cpen.data;
}
d->style = SolidLine;
d->width = 0;
d->color = color;
d->linest = SolidLine;
updatePen();
}
/*!
\fn const QBrush &QPainter::brush() const
Returns the current painter brush.
\sa QPainter::setBrush()
*/
/*!
Sets a new painter brush.
The brush defines how to fill shapes.
\sa brush()
*/
qt'QPainter::setBrush() (./qt-2.1.0/src/kernel/qpainter.cpp:671)
void QPainter::setBrush( const QBrush &brush )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setBrush: Will be reset by begin()" );
#endif
cbrush = brush;
updateBrush();
}
/*!
Sets a new painter brush with black color and the specified \e style.
\sa brush(), QBrush
*/
qt'QPainter::setBrush() (./qt-2.1.0/src/kernel/qpainter.cpp:686)
void QPainter::setBrush( BrushStyle style )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setBrush: Will be reset by begin()" );
#endif
QBrush::QBrushData *d = cbrush.data; // low level access
if ( d->count != 1 ) {
cbrush.detach();
d = cbrush.data;
}
d->style = style;
d->color = Qt::black;
if ( d->pixmap ) {
delete d->pixmap;
d->pixmap = 0;
}
updateBrush();
}
/*!
Sets a new painter brush with the style \c SolidPattern and the specified
\e color.
\sa brush(), QBrush
*/
qt'QPainter::setBrush() (./qt-2.1.0/src/kernel/qpainter.cpp:712)
void QPainter::setBrush( const QColor &color )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setBrush: Will be reset by begin()" );
#endif
QBrush::QBrushData *d = cbrush.data; // low level access
if ( d->count != 1 ) {
cbrush.detach();
d = cbrush.data;
}
d->style = SolidPattern;
d->color = color;
if ( d->pixmap ) {
delete d->pixmap;
d->pixmap = 0;
}
updateBrush();
}
/*!
\fn const QColor &QPainter::backgroundColor() const
Returns the background color currently set.
\sa setBackgroundColor()
*/
/*!
\fn BGMode QPainter::backgroundMode() const
Returns the background mode currently set.
\sa setBackgroundMode()
*/
/*!
\fn RasterOp QPainter::rasterOp() const
Returns the raster operation currently set.
\sa setRasterOp()
*/
/*!
\fn const QPoint &QPainter::brushOrigin() const
Returns the brush origin currently set.
\sa setBrushOrigin()
*/
/*!
\fn int QPainter::tabStops() const
Returns the tab stop setting.
\sa setTabStops()
*/
/*!
Set the number of pixels per tab stop to a fixed number.
Tab stops are used when drawing formatted text with \c ExpandTabs set.
This fixed tab stop value has lower precedence than tab array
settings.
\sa tabStops(), setTabArray(), drawText(), fontMetrics()
*/
qt'QPainter::setTabStops() (./qt-2.1.0/src/kernel/qpainter.cpp:774)
void QPainter::setTabStops( int ts )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setTabStops: Will be reset by begin()" );
#endif
tabstops = ts;
if ( isActive() && testf(ExtDev) ) { // tell extended device
QPDevCmdParam param[1];
param[0].ival = ts;
pdev->cmd( QPaintDevice::PdcSetTabStops, this, param );
}
}
/*!
\fn int *QPainter::tabArray() const
Returns the tab stop array currently set.
\sa setTabArray()
*/
/*!
Set an array containing the tab stops.
Tab stops are used when drawing formatted text with \c ExpandTabs set.
The last tab stop must be 0 (terminates the array).
Notice that setting a tab array overrides any fixed tabulator stop
that is set using setTabStops().
\sa tabArray(), setTabStops(), drawText(), fontMetrics()
*/
qt'QPainter::setTabArray() (./qt-2.1.0/src/kernel/qpainter.cpp:807)
void QPainter::setTabArray( int *ta )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setTabArray: Will be reset by begin()" );
#endif
if ( ta != tabarray ) {
tabarraylen = 0;
if ( tabarray ) // Avoid purify complaint
delete [] tabarray; // delete old array
if ( ta ) { // tabarray = copy of 'ta'
while ( ta[tabarraylen] )
tabarraylen++;
tabarraylen++; // and 0 terminator
tabarray = new int[tabarraylen]; // duplicate ta
memcpy( tabarray, ta, sizeof(int)*tabarraylen );
} else {
tabarray = 0;
}
}
if ( isActive() && testf(ExtDev) ) { // tell extended device
QPDevCmdParam param[2];
param[0].ival = tabarraylen;
param[1].ivec = tabarray;
pdev->cmd( QPaintDevice::PdcSetTabArray, this, param );
}
}
/*!
\fn HANDLE QPainter::handle() const
Returns the platform-dependent handle used for drawing.
*/
/*****************************************************************************
QPainter xform settings
*****************************************************************************/
/*!
Enables view transformations if \e enable is TRUE, or disables view
transformations if \e enable is FALSE.
\sa hasViewXForm(), setWindow(), setViewport(), setWorldMatrix(),
setWorldXForm(), xForm()
*/
qt'QPainter::setViewXForm() (./qt-2.1.0/src/kernel/qpainter.cpp:853)
void QPainter::setViewXForm( bool enable )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setViewXForm: Will be reset by begin()" );
#endif
if ( !isActive() || enable == testf(VxF) )
return;
setf( VxF, enable );
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].ival = enable;
pdev->cmd( QPaintDevice::PdcSetVXform, this, param );
}
updateXForm();
}
/*!
\fn bool QPainter::hasViewXForm() const
Returns TRUE if view transformation is enabled, otherwise FALSE.
\sa setViewXForm(), xForm()
*/
/*!
Returns the window rectangle.
\sa setWindow(), setViewXForm()
*/
qt'QPainter::window() (./qt-2.1.0/src/kernel/qpainter.cpp:881)
QRect QPainter::window() const
{
return QRect( wx, wy, ww, wh );
}
/*!
Sets the window rectangle view transformation for the painter and
enables view transformation.
The window rectangle is part of the view transformation. The window
specifies the logical coordinate system.
The window and the \link setViewport() viewport\endlink are initially set
to \e (0,0,width,height), where \e (width,height) is the pixel size of the
paint device.
You can use this method to normalize the coordinate system of the
painter. The following example will draw a vertical line, from top to
bottom, at the center of a pixmap, independent of the size of the pixmap:
\code
int width, height;
...
QPixmap icon( width, height );
QPainter p( icon );
p.setWindow( 0, 0, 100, 100 );
p.drawLine( 50, 0, 50, 100 ); // draw center line
\endcode
The setWindow() method is often used in conjunction with
setViewport(), as in this example:
\code
QPainter p( myWidget );
p.setWindow( 0, 0, 1000, 2000 );
p.setViewport( 100,100, 200,200 );
p.drawPoint( 500, 500 ); // draws pixel at (150,125)
\endcode
The preceding example sets up a transformation that maps the logical
coordinates (0,0,1000,2000) into a (200,200) rectangle at (100,100).
View transformations can be combined with world transformations.
World transformations are applied after the view transformations.
\sa window(), setViewport(), setViewXForm(), setWorldMatrix(),
setWorldXForm()
*/
qt'QPainter::setWindow() (./qt-2.1.0/src/kernel/qpainter.cpp:930)
void QPainter::setWindow( int x, int y, int w, int h )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setWindow: Will be reset by begin()" );
#endif
wx = x;
wy = y;
ww = w;
wh = h;
if ( testf(ExtDev) ) {
QRect r( x, y, w, h );
QPDevCmdParam param[1];
param[0].rect = (QRect*)&r;
pdev->cmd( QPaintDevice::PdcSetWindow, this, param );
}
if ( testf(VxF) )
updateXForm();
else
setViewXForm( TRUE );
}
/*!
Returns the viewport rectangle.
\sa setViewport(), setViewXForm()
*/
qt'QPainter::viewport() (./qt-2.1.0/src/kernel/qpainter.cpp:957)
QRect QPainter::viewport() const // get viewport
{
return QRect( vx, vy, vw, vh );
}
/*!
Sets the viewport rectangle view transformation for the painter and
enables view transformation.
The viewport rectangle is part of the view transformation. The viewport
specifies the device coordinate system.
The viewport and the \link setWindow() window\endlink are initially set
to \e (0,0,width,height), where \e (width,height) is the pixel size of
the paint device.
You can use this method to normalize the coordinate system of the
painter when drawing on a part of a paint device. The following example
will draw a line from the top left to the bottom right corner of a page,
excluding margins:
\code
QPrinter page;
int margin, pageWidth, pageHeight;
...
QPainter p( page );
p.setViewPort( margin, margin, pageWidth - margin, pageHeight - margin );
p.drawLine( 0, 0, pageWidth - 2*margin, pageHeight - 2*margin );
\endcode
The setViewPort() method is often used in conjunction with
setWindow(), as in this example:
\code
QPainter p( myWidget );
p.setWindow( 0, 0, 1000, 2000 );
p.setViewport( 100,100, 200,200 );
p.drawPoint( 500, 500 ); // draws pixel at (150,125)
\endcode
The preceding example sets up a transformation that maps the logical
coordinates (0,0,1000,2000) into a (200,200) rectangle at (100,100).
View transformations can be combined with world transformations.
World transformations are applied after the view transformations.
\sa viewport(), setWindow(), setViewXForm(), setWorldMatrix(),
setWorldXForm(), xForm()
*/
qt'QPainter::setViewport() (./qt-2.1.0/src/kernel/qpainter.cpp:1007)
void QPainter::setViewport( int x, int y, int w, int h )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setViewport: Will be reset by begin()" );
#endif
vx = x;
vy = y;
vw = w;
vh = h;
if ( testf(ExtDev) ) {
QRect r( x, y, w, h );
QPDevCmdParam param[1];
param[0].rect = (QRect*)&r;
pdev->cmd( QPaintDevice::PdcSetViewport, this, param );
}
if ( testf(VxF) )
updateXForm();
else
setViewXForm( TRUE );
}
/*!
Enables world transformations if \e enable is TRUE, or disables
world transformations if \e enable is FALSE.
\sa setWorldMatrix(), setWindow(), setViewport(), setViewXForm(), xForm()
*/
qt'QPainter::setWorldXForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1036)
void QPainter::setWorldXForm( bool enable )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setWorldXForm: Will be reset by begin()" );
#endif
if ( !isActive() || enable == testf(WxF) )
return;
setf( WxF, enable );
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].ival = enable;
pdev->cmd( QPaintDevice::PdcSetWXform, this, param );
}
updateXForm();
}
/*!
\fn bool QPainter::hasWorldXForm() const
Returns TRUE if world transformation is enabled, otherwise FALSE.
\sa setWorldXForm()
*/
/*!
Returns the world transformation matrix.
\sa setWorldMatrix()
*/
qt'QPainter::worldMatrix() (./qt-2.1.0/src/kernel/qpainter.cpp:1064)
const QWMatrix &QPainter::worldMatrix() const
{
return wxmat;
}
/*!
Sets the world transformation matrix to \e m and enables world
transformation.
If \e combine is TRUE, then \e m is combined with the current
transformation matrix, otherwise \e m will replace the current
transformation matrix.
World transformations are applied after the view transformations
(i.e. \link setWindow window\endlink and \link setViewport viewport\endlink).
If the matrix set is the identity matrix (\link QWMatrix::m11()
m11\endlink and \link QWMatrix::m22() m22\endlink are 1.0 and the
rest are 0.0), this function calls setWorldXForm(FALSE).
The following functions can transform the coordinate system without using
a QWMatrix:
<ul>
<li>translate()
<li>scale()
<li>shear()
<li>rotate()
</ul>
They operate on the painter's \link worldMatrix() world matrix\endlink
and are implemented like this:
\code
void QPainter::rotate( double a )
{
QWMatrix m;
m.rotate( a );
setWorldMatrix( m, TRUE );
}
\endcode
Note that you should always use combine when you are drawing into a
QPicture. Otherwise the picture may not be completely encapsulated
and cannot be replayed with additional transformations. Using the
translate(), scale(), etc. functions is safe.
Furthermore, you can easily save and restore the current world
transformation matrix with the convenient functions
saveWorldMatrix() and restoreWorldMatrix(), respectively. If you
need to draw some top-to-bottom text at the position (x y), for
instance, but everything else shall remain unrotated, you can easily
achieve this with:
\code
void MyWidget::paintEvent()
{
QPainter paint( this );
...
paint.saveWorldMatrix();
paint.translate( x, y );
paint.rotate( 90 );
paint.drawText( 0, 0, "top-to-bottom text" );
paint.restoreWorldMatrix();
....
}
\endcode
See the \link QWMatrix QWMatrix documentation\endlink for a general
discussion on coordinate system transformations.
\sa worldMatrix(), setWorldXForm(), setWindow(), setViewport(),
setViewXForm(), xForm()
*/
qt'QPainter::setWorldMatrix() (./qt-2.1.0/src/kernel/qpainter.cpp:1138)
void QPainter::setWorldMatrix( const QWMatrix &m, bool combine )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setWorldMatrix: Will be reset by begin()" );
#endif
if ( combine )
wxmat = m * wxmat; // combines
else
wxmat = m; // set new matrix
bool identity = wxmat.m11() == 1.0F && wxmat.m22() == 1.0F &&
wxmat.m12() == 0.0F && wxmat.m21() == 0.0F &&
wxmat.dx() == 0.0F && wxmat.dy() == 0.0F;
if ( testf(ExtDev) ) {
QPDevCmdParam param[2];
param[0].matrix = &m;
param[1].ival = combine;
pdev->cmd( QPaintDevice::PdcSetWMatrix, this, param );
}
if ( identity )
setWorldXForm( FALSE );
else if ( !testf(WxF) )
setWorldXForm( TRUE );
else
updateXForm();
}
/*!
Saves the current world matrix (pushes the matrix onto a stack).
In sane code a save() has a corresponding restoreWorldMatrix().
\sa restoreWorldMatrix()
*/
qt'QPainter::saveWorldMatrix() (./qt-2.1.0/src/kernel/qpainter.cpp:1173)
void QPainter::saveWorldMatrix()
{
QWMatrixStack *stack = (QWMatrixStack *)wm_stack;
if ( stack == 0 ) {
stack = new QStack<QWMatrix>;
CHECK_PTR( stack );
stack->setAutoDelete( TRUE );
wm_stack = stack;
}
stack->push( new QWMatrix( wxmat ) );
}
/*!
Restores the current world matrix (pops a saved matrix off the stack).
\sa saveWorldMatrix()
*/
qt'QPainter::restoreWorldMatrix() (./qt-2.1.0/src/kernel/qpainter.cpp:1192)
void QPainter::restoreWorldMatrix()
{
QWMatrixStack *stack = (QWMatrixStack *)wm_stack;
if ( stack == 0 || stack->isEmpty() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::restoreWorldMatrix: Empty stack error" );
#endif
return;
}
QWMatrix* m = stack->pop();
setWorldMatrix( *m );
delete m;
}
/*!
Translates the coordinate system by \e (dx,dy).
For example, the following code draws a single vertical line 20 pixels high.
\code
void MyWidget::paintEvent()
{
QPainter paint( this );
paint.drawLine(10,0,10,20);
paint.translate(100.0,100.0);
paint.drawLine(-90,-80,-90,-70);
}
\endcode
\sa scale(), shear(), rotate(), resetXForm(), setWorldMatrix(), xForm()
*/
qt'QPainter::translate() (./qt-2.1.0/src/kernel/qpainter.cpp:1224)
void QPainter::translate( double dx, double dy )
{
QWMatrix m;
m.translate( dx, dy );
setWorldMatrix( m, TRUE );
}
/*!
Scales the coordinate system by \e (sx,sy).
\sa translate(), shear(), rotate(), resetXForm(), setWorldMatrix(),
xForm()
*/
qt'QPainter::scale() (./qt-2.1.0/src/kernel/qpainter.cpp:1237)
void QPainter::scale( double sx, double sy )
{
QWMatrix m;
m.scale( sx, sy );
setWorldMatrix( m, TRUE );
}
/*!
Shears the coordinate system \e (sh,sv).
\sa translate(), scale(), rotate(), resetXForm(), setWorldMatrix(),
xForm()
*/
qt'QPainter::shear() (./qt-2.1.0/src/kernel/qpainter.cpp:1250)
void QPainter::shear( double sh, double sv )
{
QWMatrix m;
m.shear( sv, sh );
setWorldMatrix( m, TRUE );
}
/*!
Rotates the coordinate system \e a degrees.
\sa translate(), scale(), shear(), resetXForm(), setWorldMatrix(),
xForm()
*/
qt'QPainter::rotate() (./qt-2.1.0/src/kernel/qpainter.cpp:1263)
void QPainter::rotate( double a )
{
QWMatrix m;
m.rotate( a );
setWorldMatrix( m, TRUE );
}
/*!
Resets any transformations that were made using translate(), scale(),
shear(), rotate(), setWorldMatrix(), setViewport() and setWindow()
\sa worldMatrix(), viewport(), window()
*/
qt'QPainter::resetXForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1276)
void QPainter::resetXForm()
{
if ( !isActive() )
return;
wx = wy = vx = vy = 0; // default view origins
ww = vw = pdev->metric( QPaintDeviceMetrics::PdmWidth );
wh = vh = pdev->metric( QPaintDeviceMetrics::PdmHeight );
wxmat = QWMatrix();
setWorldXForm( FALSE );
}
qt'QPainter::updateXForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1299)
void QPainter::updateXForm()
{
QWMatrix m;
if ( testf(VxF) ) {
m.translate( vx, vy );
m.scale( 1.0*vw/ww, 1.0*vh/wh );
m.translate( -wx, -wy );
}
if ( testf(WxF) ) {
if ( testf(VxF) )
m = wxmat * m;
else
m = wxmat;
}
xmat = m;
txinv = FALSE; // no inverted matrix
txop = TxNone;
const double eps = 0.0; // ##### can we get away with this?
//#define FZ(x) ((x)<eps&&(x)>-eps) ###nonsense if eps==0.0!!!
qt'QPainter::updateInvXForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1348)
void QPainter::updateInvXForm()
{
#if defined(CHECK_STATE)
ASSERT( txinv == FALSE );
#endif
txinv = TRUE; // creating inverted matrix
bool invertible;
QWMatrix m;
if ( testf(VxF) ) {
m.translate( vx, vy );
m.scale( 1.0*vw/ww, 1.0*vh/wh );
m.translate( -wx, -wy );
}
if ( testf(WxF) ) {
if ( testf(VxF) )
m = wxmat * m;
else
m = wxmat;
}
ixmat = m.invert( &invertible ); // invert matrix
}
/*!
\internal
Maps a point from logical coordinates to device coordinates.
*/
qt'QPainter::map() (./qt-2.1.0/src/kernel/qpainter.cpp:1376)
void QPainter::map( int x, int y, int *rx, int *ry ) const
{
switch ( txop ) {
case TxNone:
*rx = x; *ry = y;
break;
case TxTranslate:
// #### "Why no rounding here?", Warwick asked of Haavard.
*rx = int(x + dx());
*ry = int(y + dy());
break;
case TxScale: {
double tx = m11()*x + dx();
double ty = m22()*y + dy();
*rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
*ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
} break;
default: {
double tx = m11()*x + m21()*y+dx();
double ty = m12()*x + m22()*y+dy();
*rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
*ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
} break;
}
}
/*!
\internal
Maps a rectangle from logical coordinates to device coordinates.
This internal function does not handle rotation and/or shear.
*/
qt'QPainter::map() (./qt-2.1.0/src/kernel/qpainter.cpp:1408)
void QPainter::map( int x, int y, int w, int h,
int *rx, int *ry, int *rw, int *rh ) const
{
switch ( txop ) {
case TxNone:
*rx = x; *ry = y;
*rw = w; *rh = h;
break;
case TxTranslate:
// #### "Why no rounding here?", Warwick asked of Haavard.
*rx = int(x + dx());
*ry = int(y + dy());
*rw = w; *rh = h;
break;
case TxScale: {
double tx = m11()*x + dx();
double ty = m22()*y + dy();
double tw = m11()*w;
double th = m22()*h;
*rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
*ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
*rw = tw >= 0 ? int(tw + 0.5) : int(tw - 0.5);
*rh = th >= 0 ? int(th + 0.5) : int(th - 0.5);
} break;
default:
#if defined(CHECK_STATE)
qWarning( "QPainter::map: Internal error" );
#endif
break;
}
}
/*!
\internal
Maps a point from device coordinates to logical coordinates.
*/
qt'QPainter::mapInv() (./qt-2.1.0/src/kernel/qpainter.cpp:1445)
void QPainter::mapInv( int x, int y, int *rx, int *ry ) const
{
#if defined(CHECK_STATE)
if ( !txinv )
qWarning( "QPainter::mapInv: Internal error" );
#endif
double tx = im11()*x + im21()*y+idx();
double ty = im12()*x + im22()*y+idy();
*rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
*ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
}
/*!
\internal
Maps a rectangle from device coordinates to logical coordinates.
Cannot handle rotation and/or shear.
*/
qt'QPainter::mapInv() (./qt-2.1.0/src/kernel/qpainter.cpp:1463)
void QPainter::mapInv( int x, int y, int w, int h,
int *rx, int *ry, int *rw, int *rh ) const
{
#if defined(CHECK_STATE)
if ( !txinv || txop == TxRotShear )
qWarning( "QPainter::mapInv: Internal error" );
#endif
double tx = im11()*x + idx();
double ty = im22()*y + idy();
double tw = im11()*w;
double th = im22()*h;
*rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
*ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
*rw = tw >= 0 ? int(tw + 0.5) : int(tw - 0.5);
*rh = th >= 0 ? int(th + 0.5) : int(th - 0.5);
}
/*!
Returns the point \e pv transformed from user coordinates to device
coordinates.
\sa xFormDev(), QWMatrix::map()
*/
qt'QPainter::xForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1488)
QPoint QPainter::xForm( const QPoint &pv ) const
{
if ( txop == TxNone )
return pv;
int x=pv.x(), y=pv.y();
map( x, y, &x, &y );
return QPoint( x, y );
}
/*!
Returns the rectangle \e rv transformed from user coordinates to device
coordinates.
If world transformation is enabled and rotation or shearing has been
specified, then the bounding rectangle is returned.
\sa xFormDev(), QWMatrix::map()
*/
qt'QPainter::xForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1507)
QRect QPainter::xForm( const QRect &rv ) const
{
if ( txop == TxNone )
return rv;
if ( txop == TxRotShear ) { // rotation/shear
QPointArray a( rv );
a = xForm( a );
return a.boundingRect();
}
// Just translation/scale
int x, y, w, h;
rv.rect( &x, &y, &w, &h );
map( x, y, w, h, &x, &y, &w, &h );
return QRect( x, y, w, h );
}
/*!
Returns the point array \e av transformed from user coordinates to device
coordinates.
\sa xFormDev(), QWMatrix::map()
*/
qt'QPainter::xForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1531)
QPointArray QPainter::xForm( const QPointArray &av ) const
{
QPointArray a = av;
if ( txop != TxNone ) {
a = a.copy();
int x, y, i;
for ( i=0; i<(int)a.size(); i++ ) {
a.point( i, &x, &y );
map( x, y, &x, &y );
a.setPoint( i, x, y );
}
}
return a;
}
/*!
Returns the point array \a av transformed from user coordinates to device
coordinates. The \a index is the first point in the array and \a npoints
denotes the number of points to be transformed. If \a npoints is negative,
all points from \a av[index] until the last point in the array are
transformed.
The returned point array consists of the number of points that were
transformed.
Example:
\code
QPointArray a(10);
QPointArray b;
b = painter.xForm(a,2,4); // b.size() == 4
b = painter.xForm(a,2,-1); // b.size() == 8
\endcode
\sa xFormDev(), QWMatrix::map()
*/
qt'QPainter::xForm() (./qt-2.1.0/src/kernel/qpainter.cpp:1567)
QPointArray QPainter::xForm( const QPointArray &av, int index,
int npoints ) const
{
int lastPoint = npoints < 0 ? av.size() : index+npoints;
QPointArray a( lastPoint-index );
int x, y, i=index, j=0;
while ( i<lastPoint ) {
av.point( i++, &x, &y );
map( x, y, &x, &y );
a.setPoint( j++, x, y );
}
return a;
}
/*!
Returns the point \e pv transformed from device coordinates to user
coordinates.
\sa xForm(), QWMatrix::map()
*/
qt'QPainter::xFormDev() (./qt-2.1.0/src/kernel/qpainter.cpp:1587)
QPoint QPainter::xFormDev( const QPoint &pd ) const
{
if ( txop == TxNone )
return pd;
if ( !txinv ) {
QPainter *that = (QPainter*)this; // mutable
that->updateInvXForm();
}
int x=pd.x(), y=pd.y();
mapInv( x, y, &x, &y );
return QPoint( x, y );
}
/*!
Returns the rectangle \e rv transformed from device coordinates to user
coordinates.
If world transformation is enabled and rotation or shearing is used,
then the bounding rectangle is returned.
\sa xForm(), QWMatrix::map()
*/
qt'QPainter::xFormDev() (./qt-2.1.0/src/kernel/qpainter.cpp:1610)
QRect QPainter::xFormDev( const QRect &rd ) const
{
if ( txop == TxNone )
return rd;
if ( !txinv ) {
QPainter *that = (QPainter*)this; // mutable
that->updateInvXForm();
}
if ( txop == TxRotShear ) { // rotation/shear
QPointArray a( rd );
a = xFormDev( a );
return a.boundingRect();
}
// Just translation/scale
int x, y, w, h;
rd.rect( &x, &y, &w, &h );
mapInv( x, y, w, h, &x, &y, &w, &h );
return QRect( x, y, w, h );
}
/*!
Returns the point array \e av transformed from device coordinates to user
coordinates.
\sa xForm(), QWMatrix::map()
*/
qt'QPainter::xFormDev() (./qt-2.1.0/src/kernel/qpainter.cpp:1637)
QPointArray QPainter::xFormDev( const QPointArray &ad ) const
{
QPointArray a = ad;
if ( txop != TxNone ) {
a = a.copy();
int x, y, i;
for ( i=0; i<(int)a.size(); i++ ) {
a.point( i, &x, &y );
mapInv( x, y, &x, &y );
a.setPoint( i, x, y );
}
}
return a;
}
/*!
Returns the point array \a ad transformed from device coordinates to user
coordinates. The \a index is the first point in the array and \a npoints
denotes the number of points to be transformed. If \a npoints is negative,
all points from \a av[index] until the last point in the array are
transformed.
The returned point array consists of the number of points that were
transformed.
Example:
\code
QPointArray a(10);
QPointArray b;
b = painter.xFormDev(a,1,3); // b.size() == 3
b = painter.xFormDev(a,1,-1); // b.size() == 9
\endcode
\sa xForm(), QWMatrix::map()
*/
qt'QPainter::xFormDev() (./qt-2.1.0/src/kernel/qpainter.cpp:1673)
QPointArray QPainter::xFormDev( const QPointArray &ad, int index,
int npoints ) const
{
int lastPoint = npoints < 0 ? ad.size() : index+npoints;
QPointArray a( lastPoint-index );
int x, y, i=index, j=0;
while ( i<lastPoint ) {
ad.point( i++, &x, &y );
map( x, y, &x, &y );
a.setPoint( j++, x, y );
}
return a;
}
/*!
Fills the rectangle \e (x,y,w,h) with the \e brush.
You can specify a QColor as \e brush, since there is a QBrush constructor
that takes a QColor argument and creates a solid pattern brush.
\sa drawRect()
*/
qt'QPainter::fillRect() (./qt-2.1.0/src/kernel/qpainter.cpp:1697)
void QPainter::fillRect( int x, int y, int w, int h, const QBrush &brush )
{
QPen oldPen = pen(); // save pen
QBrush oldBrush = this->brush(); // save brush
setPen( NoPen );
setBrush( brush );
drawRect( x, y, w, h ); // draw filled rect
setBrush( oldBrush ); // restore brush
setPen( oldPen ); // restore pen
}
/*!
\overload void QPainter::setBrushOrigin( const QPoint &p )
*/
/*!
\overload void QPainter::setWindow( const QRect &r )
*/
/*!
\overload void QPainter::setViewport( const QRect &r )
*/
/*!
\fn bool QPainter::hasClipping() const
Returns TRUE if clipping has been set, otherwise FALSE.
\sa setClipping()
*/
/*!
\fn const QRegion &QPainter::clipRegion() const
Returns the clip region currently set. Note that the clip region is
given in physical device coordinates and \e not subject to any
\link setWorldMatrix() coordinate transformation\endlink.
\sa setClipRegion(), setClipRect(), setClipping()
*/
/*!
\fn void QPainter::setClipRect( int x, int y, int w, int h )
Sets the clip region to \e (x,y,w,h) and enables clipping.
Note that the clip rectangle is given in physical device coordinates and
\e not subject to any \link setWorldMatrix() coordinate
transformation\endlink.
\sa setClipRegion(), clipRegion(), setClipping()
*/
/*!
\overload void QPainter::drawPoint( const QPoint &p )
*/
/*!
\overload void QPainter::moveTo( const QPoint &p )
*/
/*!
\overload void QPainter::lineTo( const QPoint &p )
*/
/*!
\overload void QPainter::drawLine( const QPoint &p1, const QPoint &p2 )
*/
/*!
\overload void QPainter::drawRect( const QRect &r )
*/
/*!
\overload void QPainter::drawWinFocusRect( const QRect &r )
*/
/*!
\overload void QPainter::drawWinFocusRect( const QRect &r, const QColor &bgColor )
*/
#if !defined(_WS_X11_)
// The doc and X implementation of this functions is in qpainter_x11.cpp
qt'QPainter::drawWinFocusRect() (./qt-2.1.0/src/kernel/qpainter.cpp:1783)
void QPainter::drawWinFocusRect( int, int, int, int,
bool, const QColor & )
{
// do nothing, only called from X11 specific functions
}
#endif
/*!
\overload void QPainter::drawRoundRect( const QRect &r, int xRnd, int yRnd )
*/
/*!
\overload void QPainter::drawEllipse( const QRect &r )
*/
/*!
\overload void QPainter::drawArc( const QRect &r, int a, int alen )
*/
/*!
\overload void QPainter::drawPie( const QRect &r, int a, int alen )
*/
/*!
\overload void QPainter::drawChord( const QRect &r, int a, int alen )
*/
/*!
\overload void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm, const QRect &sr )
*/
/*!
\overload void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm )
This version of the call draws the entire pixmap.
*/
qt'QPainter::drawPixmap() (./qt-2.1.0/src/kernel/qpainter.cpp:1821)
void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm )
{
drawPixmap( p.x(), p.y(), pm, 0, 0, pm.width(), pm.height() );
}
/*!
Draws at (\a x, \a y) the \a sw by \a sh area of pixels
from (\a sx, \a sy) in \a image.
This function simply converts \a image to a QPixmap and draws it.
\sa drawPixmap() QPixmap::convertFromImage()
*/
qt'QPainter::drawImage() (./qt-2.1.0/src/kernel/qpainter.cpp:1835)
void QPainter::drawImage( int x, int y, const QImage & image,
int sx, int sy, int sw, int sh )
{
if ( !isActive() || image.isNull() )
return;
// right/bottom
if ( sw < 0 )
sw = image.width() - sx;
if ( sh < 0 )
sh = image.height() - sy;
// Sanity-check clipping
if ( sx < 0 ) {
x -= sx;
sw += sx;
sx = 0;
}
if ( sw + sx > image.width() )
sw = image.width() - sx;
if ( sy < 0 ) {
y -= sy;
sh += sy;
sy = 0;
}
if ( sh + sy > image.height() )
sh = image.height() - sy;
if ( sw <= 0 || sh <= 0 )
return;
bool all = image.rect().intersect(QRect(sx,sy,sw,sh)) == image.rect();
QImage subimage = all ? image : image.copy(sx,sy,sw,sh);
if ( testf(ExtDev) ) {
QPDevCmdParam param[2];
QPoint p(x,y);
param[0].point = &p;
param[1].image = &subimage;
#if defined(_WS_WIN_)
if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hdc )
#else
if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hd )
#endif
return;
}
QPixmap pm;
pm.convertFromImage( subimage );
drawPixmap( x, y, pm );
}
/*!
\overload void QPainter::drawImage( const QPoint &, const QImage &, const QRect &sr )
*/
/*!
\overload void QPainter::drawImage( const QPoint &, const QImage & )
*/
qt'QPainter::drawImage() (./qt-2.1.0/src/kernel/qpainter.cpp:1894)
void QPainter::drawImage( const QPoint & p, const QImage & i )
{
drawImage(p, i, i.rect());
}
qt'QPainter::fix_neg_rect() (./qt-2.1.0/src/kernel/qpainter.cpp:1963)
void QPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
{
::fix_neg_rect(x,y,w,h);
}
//
// The drawText function takes two special parameters; 'internal' and 'brect'.
//
// The 'internal' parameter contains a pointer to an array of encoded
// information that keeps internal geometry data.
// If the drawText function is called repeatedly to display the same text,
// it makes sense to calculate text width and linebreaks the first time,
// and use these parameters later to print the text because we save a lot of
// CPU time.
// The 'internal' parameter will not be used if it is a null pointer.
// The 'internal' parameter will be generated if it is not null, but points
// to a null pointer, i.e. internal != 0 && *internal == 0.
// The 'internal' parameter will be used if it contains a non-null pointer.
//
// If the 'brect parameter is a non-null pointer, then the bounding rectangle
// of the text will be returned in 'brect'.
//
/*!
Draws at most \e len characters from \e str in the rectangle \e (x,y,w,h).
Note that the meaning of \a y is not the same for the two drawText()
varieties.
This function draws formatted text. The \e tf text formatting is
the bitwise OR of the following flags: <ul>
<li> \c AlignLeft aligns to the left border.
<li> \c AlignRight aligns to the right border.
<li> \c AlignHCenter aligns horizontally centered.
<li> \c AlignTop aligns to the top border.
<li> \c AlignBottom aligns to the bottom border.
<li> \c AlignVCenter aligns vertically centered
<li> \c AlignCenter (= \c AlignHCenter | AlignVCenter)
<li> \c SingleLine ignores newline characters in the text.
<li> \c DontClip never clips the text to the rectangle.
<li> \c ExpandTabs expands tabulators.
<li> \c ShowPrefix displays "&x" as "x" underlined.
<li> \c WordBreak breaks the text to fit the rectangle.
</ul>
Horizontal alignment defaults to AlignLeft and vertical alignment
defaults to AlignTop.
If several of the horizontal or several of the vertical alignment flags
are set, the resulting alignment is undefined.
If ExpandTabs is set and no \link setTabStops() tab stops \endlink or
\link setTabArray() tab array \endlink have been set tabs will expand to
the closest reasonable tab stop based on the current font. For \link
QFont::setFixedPitch() fixed pitch\endlink (fixed width) fonts you are
guaranteed that each tab stop will be at a multiple of eight of the
width of the characters in the font.
\a brect (if non-null) is set to the actual bounding rectangle of
the output. \a internal is, yes, internal.
These flags are defined in qnamespace.h.
\sa boundingRect()
*/
qt'QPainter::drawText() (./qt-2.1.0/src/kernel/qpainter.cpp:2029)
void QPainter::drawText( int x, int y, int w, int h, int tf,
const QString& str, int len, QRect *brect,
char **internal )
{
if ( !isActive() )
return;
if ( len < 0 )
len = str.length();
if ( len == 0 ) // empty string
return;
if ( testf(DirtyFont|ExtDev) ) {
if ( testf(DirtyFont) )
updateFont();
if ( testf(ExtDev) && (tf & DontPrint) == 0 ) {
QPDevCmdParam param[3];
QRect r( x, y, w, h );
QString newstr = str;
newstr.truncate( len );
param[0].rect = &r;
param[1].ival = tf;
param[2].str = &newstr;
if ( pdev->devType() != QInternal::Printer ) {
#if defined(_WS_WIN_)
if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
this, param) ||
!hdc )
#else
if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
this, param) ||
!hd )
#endif
return; // QPrinter wants PdcDrawText2
}
}
}
const QFontMetrics & fm = fontMetrics(); // get font metrics
qt_format_text(fm, x, y, w, h, tf, str, len, brect,
tabstops, tabarray, tabarraylen, internal, this);
}
qt'QPainter::boundingRect() (./qt-2.1.0/src/kernel/qpainter.cpp:2559)
QRect QPainter::boundingRect( int x, int y, int w, int h, int tf,
const QString& str, int len, char **internal )
{
QRect brect;
if ( str.isEmpty() )
brect.setRect( x,y, 0,0 );
else
drawText( x, y, w, h, tf | DontPrint, str, len, &brect, internal );
return brect;
}
/*****************************************************************************
QPen member functions
*****************************************************************************/
/*!
\class QPen qpen.h
\brief The QPen class defines how a QPainter should draw lines and outlines
of shapes.
\ingroup drawing
\ingroup shared
A pen has a style, a width, a color, a cap style and a join style.
The pen style defines the line type. The default pen style is \c
Qt::SolidLine. Setting the style to \c NoPen tells the painter to
not draw lines or outlines.
The pen width defines the line width. The default line width is 0,
which draws a 1-pixel line very fast, but with lower precision than
with a line width of 1. Setting the line width to 1 or more draws
lines that are precise, but drawing is slower.
The pen color defines the color of lines and text. The default line
color is black. The QColor documentation lists predefined colors.
The cap style defines how the end points of lines are drawn. The
join style defines how the joins between two lines drawn when
multiple, conncted lines are drawn (QPainter::drawPolyLine() etc.).
The cap and join styles apply only to wide lines, i.e. when the
width is 1 or greater.
Use the QBrush class for specifying fill styles.
Example:
\code
QPainter painter;
QPen pen( red, 2 ); // red solid line, 2 pixel width
painter.begin( &anyPaintDevice ); // paint something
painter.setPen( pen ); // set the red, fat pen
painter.drawRect( 40,30, 200,100 ); // draw rectangle
painter.setPen( blue ); // set blue pen, 0 pixel width
painter.drawLine( 40,30, 240,130 ); // draw diagonal in rectangle
painter.end(); // painting done
\endcode
See the setStyle() function for a complete list of pen styles.
About the end point of lines: For wide (non-0-width) pens, it
depends on the cap style whether the end point is drawn or not. For
0-width pens, QPainter will try to make sure that the end point is
drawn, but this cannot be absolutely guaranteed, since the underlying
drawing engine is free to use any (typically accellerated) algorithm
for drawing 0-width lines. On all tested systems, however, the
endpoint of at least all non-diagonal lines are drawn.
\sa QPainter, QPainter::setPen()
*/
/*!
\internal
Initializes the pen.
*/
qt'QPainter::textMetric() (./qt-2.1.0/src/kernel/qpainter.h:605)
inline void *QPainter::textMetric()
{
if ( testf(DirtyFont) )
updateFont();
return textmet;
}
#endif
qt'QPainter::initialize() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:472)
void QPainter::initialize()
{
init_gc_array();
init_gc_cache();
}
/*!
Internal function that cleans up the painter.
*/
qt'QPainter::cleanup() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:482)
void QPainter::cleanup()
{
cleanup_gc_cache();
cleanup_gc_array( qt_xdisplay() );
QPointArray::cleanBuffers();
}
qt'QPainter::redirect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:509)
void QPainter::redirect( QPaintDevice *pdev, QPaintDevice *replacement )
{
if ( pdev_dict == 0 ) {
if ( replacement == 0 )
return;
pdev_dict = new QPaintDeviceDict;
CHECK_PTR( pdev_dict );
}
#if defined(CHECK_NULL)
if ( pdev == 0 )
qWarning( "QPainter::redirect: The pdev argument cannot be 0" );
#endif
if ( replacement ) {
pdev_dict->insert( (long)pdev, replacement );
} else {
pdev_dict->remove( (long)pdev );
if ( pdev_dict->count() == 0 ) {
delete pdev_dict;
pdev_dict = 0;
}
}
}
qt'QPainter::init() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:533)
void QPainter::init()
{
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;
}
/*!
\fn const QFont &QPainter::font() const
Returns the current painter font.
\sa setFont(), QFont
*/
/*!
Sets a new painter font.
This font is used by all subsequent drawText() functions.
The text color is the same as the pen color.
\sa font(), drawText()
*/
qt'QPainter::setFont() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:567)
void QPainter::setFont( const QFont &font )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setFont: Will be reset by begin()" );
#endif
if ( cfont.d != font.d ) {
cfont = font;
setf(DirtyFont);
}
}
qt'QPainter::updateFont() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:580)
void QPainter::updateFont()
{
clearf(DirtyFont);
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].font = &cfont;
if ( !pdev->cmd( QPaintDevice::PdcSetFont, this, param ) || !hd )
return;
}
setf(NoCache);
if ( penRef )
updatePen(); // force a non-cached GC
HANDLE h = cfont.handle();
if ( h ) {
XSetFont( dpy, gc, cfont.handle() );
}
}
qt'QPainter::updatePen() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:599)
void QPainter::updatePen()
{
static char dash_line[] = { 7, 3 };
static char dot_line[] = { 1, 3 };
static char dash_dot_line[] = { 7, 3, 2, 3 };
static char dash_dot_dot_line[] = { 7, 3, 2, 3, 2, 3 };
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].pen = &cpen;
if ( !pdev->cmd( QPaintDevice::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(), dpy, hd);
if ( !obtained && !penRef )
gc = alloc_gc( dpy, hd, FALSE );
} else {
if ( gc ) {
if ( penRef ) {
release_gc( penRef );
penRef = 0;
gc = alloc_gc( dpy, hd, testf(MonoDev) );
} else {
internclipok = TRUE;
}
} else {
gc = alloc_gc( dpy, hd, testf(MonoDev), testf(UsePrivateCx) );
}
}
if ( !internclipok ) {
if ( pdev == paintEventDevice ) {
if ( penRef &&((QGCC*)penRef)->clip_serial < gc_cache_clip_serial ) {
XSetRegion( dpy, gc, paintEventClipRegion->handle() );
((QGCC*)penRef)->clip_serial = gc_cache_clip_serial;
} else if ( !penRef ) {
XSetRegion( dpy, gc, paintEventClipRegion->handle() );
}
} else if (penRef && ((QGCC*)penRef)->clip_serial ) {
XSetClipMask( dpy, gc, None );
((QGCC*)penRef)->clip_serial = 0;
}
}
if ( obtained )
return;
char *dashes = 0; // custom pen dashes
int dash_len = 0; // length of dash list
int s = LineSolid;
int cp = CapButt;
int jn = JoinMiter;
switch( ps ) {
case NoPen:
case SolidLine:
s = LineSolid;
break;
case DashLine:
dashes = dash_line;
dash_len = sizeof(dash_line);
break;
case DotLine:
dashes = dot_line;
dash_len = sizeof(dot_line);
break;
case DashDotLine:
dashes = dash_dot_line;
dash_len = sizeof(dash_dot_line);
break;
case DashDotDotLine:
dashes = dash_dot_dot_line;
dash_len = sizeof(dash_dot_dot_line);
break;
}
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() );
XSetBackground( dpy, gc, bg_col.pixel() );
if ( dash_len ) { // make dash list
XSetDashes( dpy, gc, 0, dashes, dash_len );
s = bg_mode == TransparentMode ? LineOnOffDash : LineDoubleDash;
}
XSetLineAttributes( dpy, gc, cpen.width(), s, cp, jn );
}
qt'QPainter::updateBrush() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:727)
void QPainter::updateBrush()
{
static uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
static uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
static uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
static uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
static uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
static uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
static uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
static 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 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 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 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 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 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 uchar *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) ) {
QPDevCmdParam param[1];
param[0].brush = &cbrush;
if ( !pdev->cmd( QPaintDevice::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(), dpy, hd);
if ( !obtained && !brushRef )
gc_brush = alloc_gc( dpy, hd, FALSE );
} else {
if ( gc_brush ) {
if ( brushRef ) {
release_gc( brushRef );
brushRef = 0;
gc_brush = alloc_gc( dpy, hd, testf(MonoDev) );
} else {
internclipok = TRUE;
}
} else {
gc_brush = alloc_gc( dpy, hd, testf(MonoDev), testf(UsePrivateCx));
}
}
if ( !internclipok ) {
if ( pdev == paintEventDevice ) {
if ( brushRef &&((QGCC*)brushRef)->clip_serial < gc_cache_clip_serial ) {
XSetRegion( dpy, gc_brush, paintEventClipRegion->handle() );
((QGCC*)brushRef)->clip_serial = gc_cache_clip_serial;
} else if ( !brushRef ){
XSetRegion( dpy, gc_brush, paintEventClipRegion->handle() );
}
} else if (brushRef && ((QGCC*)brushRef)->clip_serial ) {
XSetClipMask( dpy, gc_brush, None );
((QGCC*)brushRef)->clip_serial = 0;
}
}
if ( obtained )
return;
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() );
XSetBackground( dpy, gc_brush, bg_col.pixel() );
if ( bs == CustomPattern || pat ) {
QPixmap *pm;
if ( pat ) {
QString key;
key.sprintf( "$qt-brush$%d", bs );
pm = QPixmapCache::find( key );
bool del = FALSE;
if ( !pm ) { // not already in pm dict
pm = new QBitmap( d, d, pat, TRUE );
CHECK_PTR( pm );
del = !QPixmapCache::insert( key, pm );
}
if ( cbrush.data->pixmap )
delete cbrush.data->pixmap;
cbrush.data->pixmap = new QPixmap( *pm );
if (del) delete pm;
}
pm = cbrush.data->pixmap;
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 device \a pd and returns TRUE if successful,
or FALSE if it cannot begin painting. Call end() when you have finished
painting.
On the X Window System, paint commands are buffered and may not appear
on the screen immediately. The flush() function flushes the buffer.
As an alternative to calling begin() and end(), you can use the QPainter
constructor that takes a paint device argument. This is for short-lived
painters, for example in \link QWidget::paintEvent() paint events\endlink.
This function initializes all painter settings:
<ul>
<li>The \link setFont() font\endlink is set to the default \link
QApplication::setFont() application font\endlink, or to the \link
QWidget::setFont() widget's font\endlink if \e pd is a widget.
<li>The \link setPen() pen\endlink is set to QPen(black,0,SolidLine),
or to QPen(\link QWidget::foregroundColor() widget->foreground()\endlink,
0,SolidLine) if \e pd is a widget.
<li>The \link setBrush() brush\endlink is set to QBrush(NoBrush).
<li>The \link setBackgroundColor() background color\endlink is set
to white, or to the \link QWidget::setBackgroundColor() widget's
background color\endlink if \e pd is a widget.
<li>The \link setBackgroundMode() background mode\endlink is set
to \c TransparentMode.
<li>The \link setRasterOp() raster operation\endlink is set to
\c CopyROP.
<li>The \link setBrushOrigin() brush origin\endlink is set to (0,0).
<li>The \link setViewXForm() view transformation\endlink setting
is turned off.
<li>The \link setWindow() window\endlink is set to the paint device
rectangle; (0,0,pd->width(),pd->height()).
<li>The \link setViewport() viewport\endlink is set to the paint device
rectangle; (0,0,pd->width(),pd->height()).
<li>The \link setWorldXForm() world transformation\endlink setting
is turned off.
<li>The \link setWorldMatrix() world matrix\endlink is set to the
\link QWMatrix::reset() identify matrix\endlink.
<li>\link setClipping() Clipping\endlink is disabled.
<li>The \link setClipRegion() clip region\endlink is set to an empty region.
</ul>
\warning A paint device can only be painted by one painter at a time.
\sa end(), flush(), setFont(), setPen(), setBrush(), setBackgroundColor(),
setBackgroundMode(), setRasterOp(), setBrushOrigin(), setViewXForm(),
setWindow(), setViewport(), setWorldXForm(), setWorldMatrix(),
setClipRegion()
*/
qt'QPainter::begin() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:927)
bool QPainter::begin( const QPaintDevice *pd )
{
if ( isActive() ) { // already active painting
#if defined(CHECK_STATE)
qWarning( "QPainter::begin: Painter is already active."
"\n\tYou must end() the painter before a second begin()" );
#endif
return FALSE;
}
if ( pd == 0 ) {
#if defined(CHECK_NULL)
qWarning( "QPainter::begin: Paint device cannot be null" );
#endif
return FALSE;
}
QWidget *copyFrom = 0;
if ( pdev_dict ) { // redirected paint device?
pdev = pdev_dict->find( (long)pd );
if ( pdev ) {
if ( pd->devType() == QInternal::Widget )
copyFrom = (QWidget *)pd; // copy widget settings
} else {
pdev = (QPaintDevice *)pd;
}
} else {
pdev = (QPaintDevice *)pd;
}
if ( pdev->isExtDev() && pdev->paintingActive() ) {
// somebody else is already painting
#if defined(CHECK_STATE)
qWarning( "QPainter::begin: Another QPainter is already painting "
"this device;\n\tAn extended paint device can only be painted "
"by one QPainter 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 device type
if ( (pdev->devFlags & QInternal::ExternalDevice) != 0 ) // this is an extended device
setf(ExtDev);
else if ( dt == QInternal::Pixmap ) // device is a pixmap
((QPixmap*)pdev)->detach(); // will modify it
dpy = pdev->x11Display(); // get display variable
hd = pdev->handle(); // get handle to drawable
if ( testf(ExtDev) ) { // external device
if ( !pdev->cmd( QPaintDevice::PdcBegin, this, 0 ) ) {
// could not begin painting
pdev = 0;
return FALSE;
}
if ( tabstops ) // update tabstops for device
setTabStops( tabstops );
if ( tabarray ) // update tabarray for device
setTabArray( tabarray );
}
if ( pdev->x11Depth() != pdev->x11AppDepth() ) { // non-standard depth
setf(NoCache);
setf(UsePrivateCx);
}
pdev->painters++; // also tell paint device
bro = curPt = QPoint( 0, 0 );
if ( reinit ) {
bg_mode = TransparentMode; // default background mode
rop = CopyROP; // default ROP
wxmat.reset(); // reset world xform matrix
txop = txinv = 0;
if ( dt != QInternal::Widget ) {
QFont defaultFont; // default drawing tools
QPen defaultPen;
QBrush 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 == QInternal::Widget ) { // device is a widget
QWidget *w = (QWidget*)pdev;
cfont = w->font(); // use widget font
cpen = QPen( w->foregroundColor() ); // use widget fg color
if ( reinit ) {
QBrush defaultBrush;
cbrush = defaultBrush;
}
bg_col = w->backgroundColor(); // use widget bg color
ww = vw = w->width(); // default view size
wh = vh = w->height();
if ( w->testWFlags(WPaintUnclipped) ) { // paint direct on device
setf( NoCache );
setf(UsePrivateCx);
updatePen();
updateBrush();
XSetSubwindowMode( dpy, gc, IncludeInferiors );
XSetSubwindowMode( dpy, gc_brush, IncludeInferiors );
}
} else if ( dt == QInternal::Pixmap ) { // device is a pixmap
QPixmap *pm = (QPixmap*)pdev;
if ( pm->isNull() ) {
#if defined(CHECK_NULL)
qWarning( "QPainter::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 device
ww = vw = pdev->metric( QPaintDeviceMetrics::PdmWidth );
wh = vh = pdev->metric( QPaintDeviceMetrics::PdmHeight );
}
if ( ww == 0 )
ww = wh = vw = vh = 1024;
if ( copyFrom ) { // copy redirected widget
cfont = copyFrom->font();
cpen = QPen( copyFrom->foregroundColor() );
bg_col = copyFrom->backgroundColor();
}
if ( testf(ExtDev) ) { // external device
setBackgroundColor( bg_col ); // default background color
setBackgroundMode( TransparentMode ); // default background mode
setRasterOp( CopyROP ); // default raster operation
}
gc_cache_clip_serial++;
updateBrush();
updatePen();
return TRUE;
}
/*!
Ends painting. Any resources used while painting are released.
\sa begin()
*/
qt'QPainter::end() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1077)
bool QPainter::end() // end painting
{
if ( !isActive() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::end: Missing begin() or begin() failed" );
#endif
return FALSE;
}
if ( testf(FontMet) ) // remove references to this
QFontMetrics::reset( this );
if ( testf(FontInf) ) // remove references to this
QFontInfo::reset( this );
//#### This should not be necessary:
if ( pdev->devType() == QInternal::Widget &&
((QWidget*)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( QPaintDevice::PdcEnd, this, 0 );
flags = 0;
pdev->painters--;
pdev = 0;
dpy = 0;
return TRUE;
}
/*!
Flushes any buffered drawing operations.
*/
qt'QPainter::flush() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1134)
void QPainter::flush()
{
if ( isActive() && dpy )
XFlush( dpy );
}
/*!
Sets the background color of the painter to \e 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 when transparent background mode
is set.
\sa backgroundColor(), setBackgroundMode()
*/
qt'QPainter::setBackgroundColor() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1152)
void QPainter::setBackgroundColor( const QColor &c )
{
if ( !isActive() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::setBackgroundColor: Call begin() first" );
#endif
return;
}
bg_col = c;
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].color = &bg_col;
if ( !pdev->cmd( QPaintDevice::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 \e m, which must be one of:
<ul>
<li> \c TransparentMode (default)
<li> \c OpaqueMode
</ul>
Transparent mode draws stippled lines and text without setting the
background pixels. Opaque mode fills these space with the current
background color.
In order to draw a bitmap or pixmap transparently, you must use
QPixmap::setMask().
\sa backgroundMode(), setBackgroundColor() */
qt'QPainter::setBackgroundMode() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1189)
void QPainter::setBackgroundMode( BGMode m )
{
if ( !isActive() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::setBackgroundMode: Call begin() first" );
#endif
return;
}
if ( m != TransparentMode && m != OpaqueMode ) {
#if defined(CHECK_RANGE)
qWarning( "QPainter::setBackgroundMode: Invalid mode" );
#endif
return;
}
bg_mode = m;
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].ival = m;
if ( !pdev->cmd( QPaintDevice::PdcSetBkMode, this, param ) || !hd )
return;
}
if ( !penRef )
updatePen(); // update pen setting
if ( !brushRef )
updateBrush(); // update brush setting
}
qt'QPainter::setRasterOp() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1249)
void QPainter::setRasterOp( RasterOp r )
{
if ( !isActive() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::setRasterOp: Call begin() first" );
#endif
return;
}
if ( (uint)r > LastROP ) {
#if defined(CHECK_RANGE)
qWarning( "QPainter::setRasterOp: Invalid ROP code" );
#endif
return;
}
rop = r;
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].ival = r;
if ( !pdev->cmd( QPaintDevice::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] );
}
/*!
Sets the brush origin to \e (x,y).
The brush origin specifies the (0,0) coordinate of the painter's brush.
This setting is only necessary for pattern brushes or pixmap brushes.
\sa brushOrigin()
*/
qt'QPainter::setBrushOrigin() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1288)
void QPainter::setBrushOrigin( int x, int y )
{
if ( !isActive() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::setBrushOrigin: Call begin() first" );
#endif
return;
}
bro = QPoint(x,y);
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].point = &bro;
if ( !pdev->cmd( QPaintDevice::PdcSetBrushOrigin, this, param ) ||
!hd )
return;
}
if ( brushRef )
updateBrush(); // get non-cached brush GC
XSetTSOrigin( dpy, gc_brush, x, y );
}
/*!
Enables clipping if \e enable is TRUE, or disables clipping if \e enable
is FALSE.
\sa hasClipping(), setClipRect(), setClipRegion()
*/
qt'QPainter::setClipping() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1316)
void QPainter::setClipping( bool enable )
{
if ( !isActive() ) {
#if defined(CHECK_STATE)
qWarning( "QPainter::setClipping: Will be reset by begin()" );
#endif
return;
}
if ( !isActive() || enable == testf(ClipOn) )
return;
setf( ClipOn, enable );
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].ival = enable;
if ( !pdev->cmd( QPaintDevice::PdcSetClip, this, param ) || !hd )
return;
}
if ( enable ) {
QRegion rgn = crgn;
if ( pdev == paintEventDevice )
rgn = rgn.intersect( *paintEventClipRegion );
if ( penRef )
updatePen();
XSetRegion( dpy, gc, rgn.handle() );
if ( brushRef )
updateBrush();
XSetRegion( dpy, gc_brush, rgn.handle() );
} else {
if ( pdev == paintEventDevice ) {
XSetRegion( dpy, gc, paintEventClipRegion->handle() );
XSetRegion( dpy, gc_brush, paintEventClipRegion->handle() );
} else {
XSetClipMask( dpy, gc, None );
XSetClipMask( dpy, gc_brush, None );
}
}
}
/*!
\overload void QPainter::setClipRect( const QRect &r )
*/
qt'QPainter::setClipRect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1361)
void QPainter::setClipRect( const QRect &r )
{
QRegion rgn( r );
setClipRegion( rgn );
}
/*!
Sets the clip region to \e rgn and enables clipping.
Note that the clip region is given in physical device coordinates and
\e not subject to any \link setWorldMatrix() coordinate
transformation\endlink.
\sa setClipRect(), clipRegion(), setClipping()
*/
qt'QPainter::setClipRegion() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1377)
void QPainter::setClipRegion( const QRegion &rgn )
{
#if defined(CHECK_STATE)
if ( !isActive() )
qWarning( "QPainter::setClipRegion: Will be reset by begin()" );
#endif
crgn = rgn;
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].rgn = &crgn;
if ( !pdev->cmd( QPaintDevice::PdcSetClipRegion, this, param ) )
return; // device cannot clip
}
clearf( ClipOn ); // be sure to update clip rgn
setClipping( TRUE );
}
/*!
Internal function for drawing a polygon.
*/
qt'QPainter::drawPolyInternal() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1400)
void QPainter::drawPolyInternal( const QPointArray &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 \e (x,y) using the current pen.
\sa QPen
*/
qt'QPainter::drawPoint() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1435)
void QPainter::drawPoint( int x, int y )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
QPoint p( x, y );
param[0].point = &p;
if ( !pdev->cmd( QPaintDevice::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 using the current pen. The
\a index and \a npoints arguments allow a subsequence of the
array to be drawn.
*/
qt'QPainter::drawPoints() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1461)
void QPainter::drawPoints( const QPointArray& 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;
QPointArray pa = a;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
for (int i=0; i<npoints; i++) {
QPoint p( pa[index+i].x(), pa[index+i].y() );
param[0].point = &p;
if ( !pdev->cmd( QPaintDevice::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 );
}
/*!
Sets the current pen position to \a (x,y)
\sa lineTo(), pos()
*/
qt'QPainter::moveTo() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1500)
void QPainter::moveTo( int x, int y )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
QPoint p( x, y );
param[0].point = &p;
if ( !pdev->cmd( QPaintDevice::PdcMoveTo, this, param ) || !hd )
return;
}
map( x, y, &x, &y );
}
curPt = QPoint( x, y );
}
/*!
Draws a line from the current pen position to \a (x,y) and sets this to the new
current pen position.
\sa QPen moveTo(), drawLine(), pos()
*/
qt'QPainter::lineTo() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1524)
void QPainter::lineTo( int x, int y )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
QPoint p( x, y );
param[0].point = &p;
if ( !pdev->cmd( QPaintDevice::PdcLineTo, this, param ) || !hd )
return;
}
map( x, y, &x, &y );
}
if ( cpen.style() != NoPen )
XDrawLine( dpy, hd, gc, curPt.x(), curPt.y(), x, y );
curPt = QPoint( x, y );
}
/*!
Draws a line from \e (x1,y2) to \e (x2,y2).
\sa QPen
*/
qt'QPainter::drawLine() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1549)
void QPainter::drawLine( int x1, int y1, int x2, int y2 )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[2];
QPoint p1(x1, y1), p2(x2, y2);
param[0].point = &p1;
param[1].point = &p2;
if ( !pdev->cmd( QPaintDevice::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 );
curPt = QPoint( x2, y2 );
}
/*!
Draws a rectangle with upper left corner at \e (x,y) and with
width \e w and height \e h.
\sa QPen, drawRoundRect()
*/
qt'QPainter::drawRect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1579)
void QPainter::drawRect( int x, int y, int w, int h )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
QRect r( x, y, w, h );
param[0].rect = &r;
if ( !pdev->cmd( QPaintDevice::PdcDrawRect, this, param ) || !hd )
return;
}
if ( txop == TxRotShear ) { // rotate/shear polygon
QPointArray a( QRect(x,y,w,h), TRUE );
drawPolyInternal( xForm(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 ( cbrush.style() != NoBrush ) {
if ( cpen.style() == NoPen ) {
XFillRectangle( dpy, hd, gc_brush, x, y, w, h );
return;
}
if ( w > 2 && h > 2 )
XFillRectangle( dpy, hd, gc_brush, x+1, y+1, w-2, h-2 );
}
if ( cpen.style() != NoPen )
XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
}
/*!
Draws a Windows focus rectangle with upper left corner at \e (x,y) and with
width \e w and height \e h.
This function draws a stippled XOR rectangle that is used to indicate
keyboard focus (when the \link QApplication::style() GUI style\endlink
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(), QApplication::style()
*/
qt'QPainter::drawWinFocusRect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1629)
void QPainter::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 \e (x,y) and with
width \e w and height \e h using a pen color that contrasts with \e bgColor.
This function draws a stippled rectangle (XOR is not used) that is used
to indicate keyboard focus (when the \link QApplication::style() GUI
style\endlink is \c WindowStyle).
The pen color used to draw the rectangle is either white or black
depending on the grayness of \e bgColor (see QColor::gray()).
\warning This function draws nothing if the coordinate system has been
\link rotate() rotated\endlink or \link shear() sheared\endlink.
\sa drawRect(), QApplication::style()
*/
qt'QPainter::drawWinFocusRect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1651)
void QPainter::drawWinFocusRect( int x, int y, int w, int h,
const QColor &bgColor )
{
drawWinFocusRect( x, y, w, h, FALSE, bgColor );
}
/*!
\internal
*/
qt'QPainter::drawWinFocusRect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1662)
void QPainter::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 };
QPen old_pen = cpen;
RasterOp old_rop = (RasterOp)rop;
if ( xorPaint ) {
if ( QColor::numBitPlanes() <= 8 )
setPen( color1 );
else
setPen( white );
setRasterOp( XorROP );
} else {
if ( qGray( bgColor.rgb() ) < 128 )
setPen( white );
else
setPen( black );
}
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
QRect r( x, y, w, h );
param[0].rect = &r;
if ( !pdev->cmd( QPaintDevice::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, 0, 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 );
}
/*! \overload void QPainter::drawRoundRect( int x, int y, int w, int h )
As the main version of the function, but with the roundness
arguments fixed at 25.
*/
/*! \overload void QPainter::drawRoundRect( const QRect & )
As the main version of the function, but with the roundness
arguments fixed at 25.
*/
/*!
Draws a rectangle with round corners at \e (x,y), with width \e w
and height \e h.
The \e xRnd and \e 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(), QPen
*/
qt'QPainter::drawRoundRect() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1739)
void QPainter::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) ) {
QPDevCmdParam param[3];
QRect r( x, y, w, h );
param[0].rect = &r;
param[1].ival = xRnd;
param[2].ival = yRnd;
if ( !pdev->cmd( QPaintDevice::PdcDrawRoundRect, this, param ) ||
!hd )
return;
}
if ( txop == TxRotShear ) { // rotate/shear polygon
QPointArray a;
if ( w <= 0 || h <= 0 )
fix_neg_rect( &x, &y, &w, &h );
w--;
h--;
int rxx = w*xRnd/200;
int ryy = h*yRnd/200;
int rxx2 = 2*rxx;
int ryy2 = 2*ryy;
int xx, yy;
// ###### WWA: this should use the new makeArc (with xmat)
a.makeEllipse( x, y, rxx2, ryy2 );
int s = a.size()/4;
int i = 0;
while ( i < s ) {
a.point( i, &xx, &yy );
xx += w - rxx2;
a.setPoint( i++, xx, yy );
}
i = 2*s;
while ( i < 3*s ) {
a.point( i, &xx, &yy );
yy += h - ryy2;
a.setPoint( i++, xx, yy );
}
while ( i < 4*s ) {
a.point( i, &xx, &yy );
xx += w - rxx2;
yy += h - ryy2;
a.setPoint( i++, xx, yy );
}
drawPolyInternal( xForm(a) );
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;
}
qt'QPainter::drawEllipse() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1870)
void QPainter::drawEllipse( int x, int y, int w, int h )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
QRect r( x, y, w, h );
param[0].rect = &r;
if ( !pdev->cmd( QPaintDevice::PdcDrawEllipse, this, param ) ||
!hd )
return;
}
if ( txop == TxRotShear ) { // rotate/shear polygon
QPointArray a;
a.makeArc( x, y, w, h, 0, 360*16, xmat );
drawPolyInternal( a );
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 ( 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 \e (x,y,w,h), the start
angle \e a and the arc length \e alen.
The angles \e a and \e alen are 1/16th of a degree, i.e. a full
circle equals 5760 (16*360). Positive values of \e a and \e alen mean
counter-clockwise while negative values mean clockwise direction.
Zero degrees is at the 3'o clock position.
Example:
\code
QPainter p;
p.begin( myWidget );
p.drawArc( 10,10, 70,100, 100*16, 160*16 ); // draws a "(" arc
p.end();
\endcode
\sa drawPie(), drawChord()
*/
qt'QPainter::drawArc() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1930)
void QPainter::drawArc( int x, int y, int w, int h, int a, int alen )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[3];
QRect r( x, y, w, h );
param[0].rect = &r;
param[1].ival = a;
param[2].ival = alen;
if ( !pdev->cmd( QPaintDevice::PdcDrawArc, this, param ) ||
!hd )
return;
}
if ( txop == TxRotShear ) { // rotate/shear
QPointArray 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 \e (x,y,w,h), the start
angle \e a and the arc length \e alen.
The pie is filled with the current \link setBrush() brush\endlink.
The angles \e a and \e alen are 1/16th of a degree, i.e. a full
circle equals 5760 (16*360). Positive values of \e a and \e alen mean
counter-clockwise while negative values mean clockwise direction.
Zero degrees is at the 3'o clock position.
\sa drawArc(), drawChord()
*/
qt'QPainter::drawPie() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:1979)
void QPainter::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) ) {
QPDevCmdParam param[3];
QRect r( x, y, w, h );
param[0].rect = &r;
param[1].ival = a;
param[2].ival = alen;
if ( !pdev->cmd( QPaintDevice::PdcDrawPie, this, param ) || !hd )
return;
}
if ( txop == TxRotShear ) { // rotate/shear
QPointArray 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 = Q_PI/2880.0*a; // convert a,alen to radians
double ra2 = ra1 + Q_PI/2880.0*alen;
int xic = qRound(xc);
int yic = qRound(yc);
XDrawLine( dpy, hd, g, xic, yic,
qRound(xc + qcos(ra1)*w2), qRound(yc - qsin(ra1)*h2));
XDrawLine( dpy, hd, g, xic, yic,
qRound(xc + qcos(ra2)*w2), qRound(yc - qsin(ra2)*h2));
XDrawArc( dpy, hd, g, x, y, w, h, a*4, alen*4 );
}
}
/*!
Draws a chord defined by the rectangle \e (x,y,w,h), the start
angle \e a and the arc length \e alen.
The chord is filled with the current \link setBrush() brush\endlink.
The angles \e a and \e alen are 1/16th of a degree, i.e. a full
circle equals 5760 (16*360). Positive values of \e a and \e alen mean
counter-clockwise while negative values mean clockwise direction.
Zero degrees is at the 3'o clock position.
\sa drawArc(), drawPie()
*/
qt'QPainter::drawChord() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2066)
void QPainter::drawChord( int x, int y, int w, int h, int a, int alen )
{
if ( !isActive() )
return;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[3];
QRect r( x, y, w, h );
param[0].rect = &r;
param[1].ival = a;
param[2].ival = alen;
if ( !pdev->cmd(QPaintDevice::PdcDrawChord,this,param) || !hd )
return;
}
if ( txop == TxRotShear ) { // rotate/shear
QPointArray 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 = Q_PI/2880.0*a; // convert a,alen to radians
double ra2 = ra1 + Q_PI/2880.0*alen;
XDrawLine( dpy, hd, g,
qRound(xc + qcos(ra1)*w2), qRound(yc - qsin(ra1)*h2),
qRound(xc + qcos(ra2)*w2), qRound(yc - qsin(ra2)*h2));
XDrawArc( dpy, hd, g, x, y, w, h, a*4, alen*4 );
}
XSetArcMode( dpy, gc_brush, ArcPieSlice );
}
/*!
Draws \e nlines separate lines from points defined in \e a, starting at
a[\e index]. If \e nlines is -1 all points until the end of the array
are used (i.e. (a.size()-index)/2 lines are drawn).
Draws the 1st line from \e a[index] to \e a[index+1].
Draws the 2nd line from \e a[index+2] to \e a[index+3] etc.
\sa drawPolyline(), drawPolygon(), QPen
*/
qt'QPainter::drawLineSegments() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2137)
void QPainter::drawLineSegments( const QPointArray &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;
QPointArray pa = a;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
if ( nlines != (int)pa.size()/2 ) {
pa = QPointArray( nlines*2 );
for ( int i=0; i<nlines*2; i++ )
pa.setPoint( i, a.point(index+i) );
index = 0;
}
QPDevCmdParam param[1];
param[0].ptarr = (QPointArray*)&pa;
if ( !pdev->cmd(QPaintDevice::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 \e npoints points in \e a starting
at \e a[index].
If \e npoints is -1 all points until the end of the array are used
(i.e. a.size()-index-1 line segments are drawn).
\sa drawLineSegments(), drawPolygon(), QPen
*/
qt'QPainter::drawPolyline() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2183)
void QPainter::drawPolyline( const QPointArray &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;
QPointArray pa = a;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
if ( npoints != (int)pa.size() ) {
pa = QPointArray( npoints );
for ( int i=0; i<npoints; i++ )
pa.setPoint( i, a.point(index+i) );
index = 0;
}
QPDevCmdParam param[1];
param[0].ptarr = (QPointArray*)&pa;
if ( !pdev->cmd(QPaintDevice::PdcDrawPolyline,this,param) || !hd )
return;
}
if ( txop != TxNone ) {
pa = xForm( a, index, npoints );
if ( pa.size() != a.size() ) {
index = 0;
npoints = pa.size();
}
}
}
if ( cpen.style() != NoPen )
XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
npoints, CoordModeOrigin );
}
/*!
Draws the polygon defined by the \e npoints points in \e a starting at
\e a[index].
If \e npoints is -1 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 \link setBrush() brush\endlink.
If \e winding is TRUE, the polygon is filled using the winding
fill algorithm. If \e winding is FALSE, the polygon is filled using the
even-odd (alternative) fill algorithm.
\sa drawLineSegments(), drawPolyline(), QPen
*/
qt'QPainter::drawPolygon() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2236)
void QPainter::drawPolygon( const QPointArray &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;
QPointArray pa = a;
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
if ( npoints != (int)a.size() ) {
pa = QPointArray( npoints );
for ( int i=0; i<npoints; i++ )
pa.setPoint( i, a.point(index+i) );
index = 0;
}
QPDevCmdParam param[2];
param[0].ptarr = (QPointArray*)&pa;
param[1].ival = winding;
if ( !pdev->cmd(QPaintDevice::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 );
int x1, y1, x2, y2; // connect last to first point
pa.point( index+npoints-1, &x1, &y1 );
pa.point( index, &x2, &y2 );
bool closed = x1 == x2 && y1 == y2;
if ( cbrush.style() != NoBrush ) { // draw filled polygon
XFillPolygon( dpy, hd, gc_brush,
(XPoint*)(pa.shortPoints( index, npoints )),
npoints, Complex, CoordModeOrigin );
}
if ( cpen.style() != NoPen ) { // draw outline
XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
npoints, CoordModeOrigin );
if ( !closed )
XDrawLine( dpy, hd, gc, x1, y1, x2, y2 );
}
if ( winding ) // set to normal fill rule
XSetFillRule( dpy, gc_brush, EvenOddRule );
}
/*!
Draws a cubic Bezier curve defined by the control points in \e a,
starting at \e a[index].
\e a must have 4 points or more. The control point \e a[index+4] and
beyond are ignored.
*/
qt'QPainter::drawQuadBezier() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2300)
void QPainter::drawQuadBezier( const QPointArray &a, int index )
{
if ( !isActive() )
return;
if ( a.size() - index < 4 ) {
#if defined(CHECK_RANGE)
qWarning( "QPainter::drawQuadBezier: Cubic Bezier needs 4 control "
"points" );
#endif
return;
}
QPointArray pa( a );
if ( index != 0 || a.size() > 4 ) {
pa = QPointArray( 4 );
for ( int i=0; i<4; i++ )
pa.setPoint( i, a.point(index+i) );
}
if ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) ) {
QPDevCmdParam param[1];
param[0].ptarr = (QPointArray*)&pa;
if ( !pdev->cmd(QPaintDevice::PdcDrawQuadBezier,this,param) || !hd )
return;
}
if ( txop != TxNone )
pa = xForm( pa );
}
if ( cpen.style() != NoPen ) {
pa = pa.quadBezier();
XDrawLines( dpy, hd, gc, (XPoint*)pa.shortPoints(), pa.size(),
CoordModeOrigin);
}
}
/*!
Draws a pixmap at \e (x,y) by copying a part of the pixmap into the
paint device.
\arg \e (x,y) specify the point in the paint device.
\arg \e (sx,sy) specify an offset in the pixmap.
\arg \e (sw,sh) specify the area of the area of the pixmap to
be copied. The value -1 means to the right/bottom of the
pixmap.
The pixmap is clipped if a \link QPixmap::setMask() mask\endlink has
been set.
\sa bitBlt(), QPixmap::setMask()
*/
qt'QPainter::drawPixmap() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2351)
void QPainter::drawPixmap( int x, int y, const QPixmap &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 ( testf(ExtDev|VxF|WxF) ) {
if ( testf(ExtDev) || txop == TxScale || txop == TxRotShear ) {
if ( sx != 0 || sy != 0 ||
sw != pixmap.width() || sh != pixmap.height() ) {
QPixmap tmp( sw, sh, pixmap.depth() );
bitBlt( &tmp, 0, 0, &pixmap, sx, sy, sw, sh, CopyROP, TRUE );
if ( pixmap.mask() ) {
QBitmap 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) ) {
QPDevCmdParam param[2];
QPoint p(x,y);
param[0].point = &p;
param[1].pixmap = &pixmap;
if ( !pdev->cmd(QPaintDevice::PdcDrawPixmap,this,param) || !hd )
return;
}
if ( txop == TxScale || txop == TxRotShear ) {
QWMatrix mat( m11(), m12(),
m21(), m22(),
dx(), dy() );
mat = QPixmap::trueMatrix( mat, sw, sh );
QPixmap pm = pixmap.xForm( mat );
if ( !pm.mask() && txop == TxRotShear ) {
QBitmap 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 );
}
QBitmap *mask = (QBitmap *)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 ) {
XSetClipOrigin( dpy, gc, 0, 0 );
if ( pdev == paintEventDevice )
XSetRegion( dpy, gc, paintEventClipRegion->handle() );
else
XSetClipMask( dpy, gc, None );
}
} else {
bitBlt( pdev, x, y, &pixmap, sx, sy, sw, sh, (RasterOp)rop );
}
return;
}
QRegion 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 ) {
if ( hasClipping() )
rgn = rgn.intersect( *paintEventClipRegion );
else
rgn = *paintEventClipRegion;
}
QBitmap *comb = new QBitmap( sw, sh );
comb->detach();
GC cgc = qt_xget_temp_gc( 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 );
XSetRegion( dpy, cgc, rgn.handle() );
XSetClipOrigin( dpy, cgc, -x, -y );
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 );
XSetClipOrigin( dpy, cgc, 0, 0 );
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() );
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 {
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 */
qt'QPainter::drawTiledPixmap() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2578)
void QPainter::drawTiledPixmap( int x, int y, int w, int h,
const QPixmap &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 device
- not scale or rotshear
- not mono pixmap
- no mask
*/
QBitmap *mask = (QBitmap *)pixmap.mask();
if ( !testf(ExtDev) && txop <= TxTranslate && pixmap.depth() > 1 &&
mask == 0 ) {
if ( txop == TxTranslate )
map( x, y, &x, &y );
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;
}
QPixmap tile( tw, th, pixmap.depth(), QPixmap::NormalOptim );
fillTile( &tile, pixmap );
if ( mask ) {
QBitmap tilemask( tw, th, QPixmap::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
}
//
// Generate a string that describes a transformed bitmap. This string is used
// to insert and find bitmaps in the global pixmap cache.
//
qt'QPainter::drawText() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2695)
void QPainter::drawText( int x, int y, const QString &str, int len )
{
if ( !isActive() )
return;
if ( len < 0 )
len = str.length();
if ( len == 0 ) // empty string
return;
if ( testf(DirtyFont|ExtDev|VxF|WxF) ) {
if ( testf(DirtyFont) )
updateFont();
if ( testf(ExtDev) ) {
QPDevCmdParam param[2];
QPoint p( x, y );
QString newstr = str.left(len);
param[0].point = &p;
param[1].str = &newstr;
if ( !pdev->cmd(QPaintDevice::PdcDrawText2,this,param) || !hd )
return;
}
if ( txop >= TxScale ) {
QFontMetrics fm = fontMetrics();
QFontInfo fi = fontInfo();
QRect bbox = fm.boundingRect( str, len );
int w=bbox.width(), h=bbox.height();
int aw, ah;
int tx=-bbox.x(), ty=-bbox.y(); // text position
QWMatrix mat1( m11(), m12(), m21(), m22(), dx(), dy() );
QFont dfont( cfont );
QWMatrix mat2;
if ( txop == TxScale ) {
double newSize = m22() * cfont.pointSizeFloat();
newSize = QMAX( 6.0, QMIN( newSize, 72.0 ) ); // empirical values
dfont.setPointSizeFloat( newSize );
QFontMetrics fm2( dfont );
QRect abbox = fm2.boundingRect( str, len );
aw = abbox.width();
ah = abbox.height();
tx = -abbox.x();
ty = -abbox.y(); // text position - off-by-one?
if ( aw == 0 || ah == 0 )
return;
double rx = mat1.m11() * cfont.pointSizeFloat() / newSize;
double ry = mat1.m22() * cfont.pointSizeFloat() / newSize;
mat2 = QWMatrix( rx, 0, 0, ry, 0, 0 );
} else {
mat2 = QPixmap::trueMatrix( mat1, w, h );
aw = w;
ah = h;
}
bool empty = aw == 0 || ah == 0;
QString bm_key = gen_text_bitmap_key( mat2, dfont, str, len );
QBitmap *wx_bm = get_text_bitmap( bm_key );
bool create_new_bm = wx_bm == 0;
if ( create_new_bm && !empty ) { // no such cached bitmap
QBitmap bm( aw, ah, TRUE ); // create bitmap
QPainter paint;
paint.begin( &bm ); // draw text in bitmap
paint.setFont( dfont );
paint.drawText( tx, ty, str, len );
paint.end();
wx_bm = new QBitmap( bm.xForm(mat2) ); // transform bitmap
if ( wx_bm->isNull() ) {
delete wx_bm; // nothing to draw
return;
}
}
if ( bg_mode == OpaqueMode ) { // opaque fill
// ### WWA: not sure on this, but the previous
// ### was totally non-Unicode.
int fx = x;
int fy = y - fm.ascent();
int fw = fm.width(str,len);
int fh = fm.ascent() + fm.descent();
int m, n;
QPointArray a(5);
mat2.map( fx, fy, &m, &n ); a.setPoint( 0, m, n );
a.setPoint( 4, m, n );
mat2.map( fx+fw, fy, &m, &n ); a.setPoint( 1, m, n );
mat2.map( fx+fw, fy+fh, &m, &n ); a.setPoint( 2, m, n );
mat2.map( fx, fy+fh, &m, &n ); a.setPoint( 3, m, n );
QBrush oldBrush = cbrush;
setBrush( backgroundColor() );
updateBrush();
XFillPolygon( dpy, hd, gc_brush, (XPoint*)a.shortPoints(), 4,
Nonconvex, CoordModeOrigin );
XDrawLines( dpy, hd, gc_brush, (XPoint*)a.shortPoints(), 5,
CoordModeOrigin );
setBrush( oldBrush );
}
if ( empty )
return;
double fx=x, fy=y, nfx, nfy;
mat1.map( fx,fy, &nfx,&nfy );
double tfx=tx, tfy=ty, dx, dy;
mat2.map( tfx, tfy, &dx, &dy ); // compute position of bitmap
x = qRound(nfx-dx);
y = qRound(nfy-dy);
XSetFillStyle( dpy, gc, FillStippled );
XSetStipple( dpy, gc, wx_bm->handle() );
XSetTSOrigin( dpy, gc, x, y );
XFillRectangle( dpy, hd, gc, x, y,wx_bm->width(),wx_bm->height() );
XSetTSOrigin( dpy, gc, 0, 0 );
XSetFillStyle( dpy, gc, FillSolid );
if ( create_new_bm )
ins_text_bitmap( bm_key, wx_bm );
return;
}
if ( txop == TxTranslate )
map( x, y, &x, &y );
}
QCString mapped;
const QTextCodec* mapper = cfont.d->mapper();
if ( mapper ) {
// translate from Unicode to font charset encoding here
mapped = mapper->fromUnicode(str,len);
}
if ( !cfont.handle() ) {
if ( mapped.isNull() )
qWarning("Fontsets only apply to mapped encodings");
else {
XFontSet set = (XFontSet)cfont.d->fontSet();
if ( bg_mode == TransparentMode )
XmbDrawString( dpy, hd, set, gc, x, y, mapped, len );
else
XmbDrawImageString( dpy, hd, set, gc, x, y, mapped, len );
}
} else {
if ( !mapped.isNull() ) {
if ( bg_mode == TransparentMode )
XDrawString( dpy, hd, gc, x, y, mapped, len );
else
XDrawImageString( dpy, hd, gc, x, y, mapped, len );
} else {
// Unicode font
QString v = str;
#ifdef QT_BIDI
v.compose(); // apply ligatures (for arabic, etc...)
v = v.visual(); // visual ordering
len = v.length();
#endif
if ( bg_mode == TransparentMode )
XDrawString16( dpy, hd, gc, x, y, (XChar2b*)v.unicode(), len );
else
XDrawImageString16( dpy, hd, gc, x, y, (XChar2b*)v.unicode(), len );
}
}
if ( cfont.underline() || cfont.strikeOut() ) {
QFontMetrics fm = fontMetrics();
int lw = fm.lineWidth();
int tw = fm.width( str, len );
if ( cfont.underline() ) // draw underline effect
XFillRectangle( dpy, hd, gc, x, y+fm.underlinePos(),
tw, lw );
if ( cfont.strikeOut() ) // draw strikeout effect
XFillRectangle( dpy, hd, gc, x, y-fm.strikeOutPos(),
tw, lw );
}
}
/*!
Returns the current position of the pen.
\sa moveTo()
*/
qt'QPainter::pos() (./qt-2.1.0/src/kernel/qpainter_x11.cpp:2869)
QPoint QPainter::pos() const
{
return curPt;
}
qt'QPainter::drawPicture() (./qt-2.1.0/src/kernel/qpicture.cpp:737)
void QPainter::drawPicture( const QPicture &pic )
{
((QPicture*)&pic)->play( (QPainter*)this );
}
/*!
Makes this picture be a deep copy of \a p.
*/