qwt_paint_buffer.cpp 4.39 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/


#include <qglobal.h>
#if QT_VERSION < 0x040000

#include <qwidget.h>
#include <qpainter.h>
#include "qwt_paint_buffer.h"

bool QwtPaintBuffer::d_enabled = true;

//! Default constructor
QwtPaintBuffer::QwtPaintBuffer():
    d_device(0),
    d_painter(0),
    d_devicePainter(0)
{
}

28
/*!
pixhawk's avatar
pixhawk committed
29 30 31 32 33 34 35 36 37
    Create an open paint buffer
    \param device Device to paint on
    \param rect Rect to paint on
    \param painter Painter to paint on device. In case of 0
                   QwtPaintBuffer uses an internal painter

    \sa open()
*/

38 39
QwtPaintBuffer::QwtPaintBuffer(QPaintDevice *device,
                               const QRect &rect, QPainter *painter):
pixhawk's avatar
pixhawk committed
40 41 42 43 44 45 46
    d_device(0),
    d_painter(0),
    d_devicePainter(0)
{
    open(device, rect, painter);
}

47
/*!
pixhawk's avatar
pixhawk committed
48 49 50 51 52 53 54 55
    Closes the buffer
    \sa close()
*/
QwtPaintBuffer::~QwtPaintBuffer()
{
    close();
}

56
/*!
pixhawk's avatar
pixhawk committed
57
  \return Depending on isEnabled() the painter
58
          connected to an internal pixmap buffer
pixhawk's avatar
pixhawk committed
59 60 61
          otherwise the painter connected to the device.
*/

62 63 64
QPainter *QwtPaintBuffer::painter()
{
    return d_painter;
pixhawk's avatar
pixhawk committed
65 66
}

67
/*!
pixhawk's avatar
pixhawk committed
68 69
  \return Device to paint on
*/
70 71 72
const QPaintDevice *QwtPaintBuffer::device()
{
    return d_device;
pixhawk's avatar
pixhawk committed
73 74
}

75
/*!
pixhawk's avatar
pixhawk committed
76 77 78 79
    Enable/Disable double buffering. Please note that
    this is a global switch for all QwtPaintBuffers, but
    won't change opened buffers.
*/
80 81 82
void QwtPaintBuffer::setEnabled(bool enable)
{
    d_enabled = enable;
pixhawk's avatar
pixhawk committed
83 84
}

85
/*!
pixhawk's avatar
pixhawk committed
86 87
  \return true if double buffering is enabled, false otherwise.
*/
88 89 90
bool QwtPaintBuffer::isEnabled()
{
    return d_enabled;
pixhawk's avatar
pixhawk committed
91 92
}

93
/*!
pixhawk's avatar
pixhawk committed
94 95 96 97 98 99 100
    Open the buffer
    \param device Device to paint on
    \param rect Rect to paint on
    \param painter Painter to paint on device. In case of 0
                   QwtPaintBuffer uses an internal painter
*/

101 102
void QwtPaintBuffer::open(QPaintDevice *device,
                          const QRect &rect, QPainter *painter)
pixhawk's avatar
pixhawk committed
103 104 105 106 107 108 109 110 111 112
{
    close();

    if ( device == 0 || !rect.isValid() )
        return;

    d_device = device;
    d_devicePainter = painter;
    d_rect = rect;

113
    if ( isEnabled() ) {
pixhawk's avatar
pixhawk committed
114 115 116 117 118 119 120
#ifdef Q_WS_X11
        if ( d_pixBuffer.x11Screen() != d_device->x11Screen() )
            d_pixBuffer.x11SetScreen(d_device->x11Screen());
#endif
        d_pixBuffer.resize(d_rect.size());

        d_painter = new QPainter();
121
        if ( d_device->devType() == QInternal::Widget ) {
pixhawk's avatar
pixhawk committed
122 123 124 125
            QWidget *w = (QWidget *)d_device;
            d_pixBuffer.fill(w, d_rect.topLeft());
            d_painter->begin(&d_pixBuffer, w);
            d_painter->translate(-d_rect.x(), -d_rect.y());
126
        } else {
pixhawk's avatar
pixhawk committed
127 128
            d_painter->begin(&d_pixBuffer);
        }
129
    } else {
pixhawk's avatar
pixhawk committed
130 131 132 133 134
        if ( d_devicePainter )
            d_painter = d_devicePainter;
        else
            d_painter = new QPainter(d_device);

135
        if ( d_device->devType() == QInternal::Widget ) {
pixhawk's avatar
pixhawk committed
136 137 138 139 140 141 142
            QWidget *w = (QWidget *)d_device;
            if ( w->testWFlags( Qt::WNoAutoErase ) )
                d_painter->eraseRect(d_rect);
        }
    }
}

143
/*!
pixhawk's avatar
pixhawk committed
144 145 146 147
    Flush the internal pixmap buffer to the device.
*/
void QwtPaintBuffer::flush()
{
148
    if ( d_enabled && d_device != 0 && d_rect.isValid()) {
pixhawk's avatar
pixhawk committed
149 150 151 152 153 154
        // We need a painter to find out if
        // there is a painter redirection for d_device.

        QPainter *p;
        if ( d_devicePainter == 0 )
            p = new QPainter(d_device);
155
        else
pixhawk's avatar
pixhawk committed
156 157 158 159 160 161 162 163 164 165 166 167 168
            p = d_devicePainter;

        QPaintDevice *device = p->device();
        if ( device->isExtDev() )
            d_devicePainter->drawPixmap(d_rect.topLeft(), d_pixBuffer);
        else
            bitBlt(device, d_rect.topLeft(), &d_pixBuffer );

        if ( d_devicePainter == 0 )
            delete p;
    }
}

169
/*!
pixhawk's avatar
pixhawk committed
170 171 172 173 174 175
    Flush the internal pixmap buffer to the device and close the buffer.
*/
void QwtPaintBuffer::close()
{
    flush();

176
    if ( d_painter ) {
pixhawk's avatar
pixhawk committed
177 178 179 180 181 182 183 184 185 186 187 188 189
        if ( d_painter->isActive() )
            d_painter->end();

        if ( d_painter != d_devicePainter )
            delete d_painter;
    }

    if ( !d_pixBuffer.isNull() )
        d_pixBuffer = QPixmap();

    d_device = 0;
    d_painter = 0;
    d_devicePainter = 0;
190
}
pixhawk's avatar
pixhawk committed
191 192

#endif // QT_VERSION < 0x040000