⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwt_painter.cpp

📁 QWT5.01用于Qt开发的二维图形库程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*- 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
 *****************************************************************************/

// vim: expandtab

#include <qwindowdefs.h>
#include <qwidget.h>
#include <qrect.h>
#include <qpainter.h>
#include <qpalette.h>
#include <qpaintdevice.h>
#include <qpixmap.h>
#include <qstyle.h>
#if QT_VERSION < 0x040000
#include <qsimplerichtext.h>
#else
#include <qtextdocument.h>
#include <qabstracttextdocumentlayout.h>
#include <qstyleoption.h>
#endif

#include "qwt_rect.h"
#include "qwt_math.h"
#include "qwt_color_map.h"
#include "qwt_scale_map.h"
#include "qwt_painter.h"

QwtMetricsMap QwtPainter::d_metricsMap;

#if defined(Q_WS_X11)
bool QwtPainter::d_deviceClipping = true;
#else
bool QwtPainter::d_deviceClipping = false;
#endif

#if QT_VERSION < 0x040000
bool QwtPainter::d_SVGMode = false;
#endif

static inline bool needDeviceClipping(
    const QPainter *painter, bool deviceClipping)
{
    return deviceClipping && 
        (painter->device()->devType() == QInternal::Widget ||
          painter->device()->devType() == QInternal::Pixmap );
}

/*!
  \brief En/Disable device clipping. 

  On X11 the default for device clipping is enabled, 
  otherwise it is disabled.
  \sa QwtPainter::deviceClipping()
*/
void QwtPainter::setDeviceClipping(bool enable)
{
    d_deviceClipping = enable;
}

/*!
  Returns whether device clipping is enabled. On X11 the default
  is enabled, otherwise it is disabled.
  \sa QwtPainter::setDeviceClipping()
*/

bool QwtPainter::deviceClipping()
{
    return d_deviceClipping;
}

/*!
  Returns rect for device clipping
  \sa QwtPainter::setDeviceClipping()
*/
const QRect &QwtPainter::deviceClipRect()
{
    static QRect clip;

    if ( !clip.isValid() )
    {
        clip.setCoords(QWT_COORD_MIN, QWT_COORD_MIN,
            QWT_COORD_MAX, QWT_COORD_MAX);
    }
    return clip;
}

//! Clip a point array
QwtPolygon QwtPainter::clip(const QwtPolygon &pa)
{
    const QwtRect rect(deviceClipRect());
    return rect.clip(pa);
}

#if QT_VERSION < 0x040000 

/*!
  \brief En/Disable SVG mode. 

  When saving a QPicture to a SVG some texts are misaligned.
  In SVGMode QwtPainter tries to fix them. 

  \sa QwtPainter::isSVGMode()
  \note A QPicture that is created in SVG mode and saved to the
        native format, will be misaligned. Also it is not possible to
        reload and play a SVG document, that was created in SVG mode.
*/
void QwtPainter::setSVGMode(bool on)
{
    d_SVGMode = on;
}

bool QwtPainter::isSVGMode()
{
    return d_SVGMode;
}

#endif // QT_VERSION < 0x040000

/*!
  Scale all QwtPainter drawing operations using the ratio
  QwtPaintMetrics(from).logicalDpiX() / QwtPaintMetrics(to).logicalDpiX()
  and QwtPaintMetrics(from).logicalDpiY() / QwtPaintMetrics(to).logicalDpiY()

  \sa QwtPainter::resetScaleMetrics(), QwtPainter::scaleMetricsX,
        QwtPainter::scaleMetricsY()
*/
void QwtPainter::setMetricsMap(const QPaintDevice *layout,
    const QPaintDevice *device)
{
    d_metricsMap.setMetrics(layout, device);
}

/*! 
  Change the metrics map 
  \sa QwtPainter::resetMetricsMap, QwtPainter::metricsMap
*/
void QwtPainter::setMetricsMap(const QwtMetricsMap &map)
{
    d_metricsMap = map;
}

/*! 
   Reset the metrics map to the ratio 1:1
   \sa QwtPainter::setMetricsMap, QwtPainter::resetMetricsMap
*/
void QwtPainter::resetMetricsMap()
{
    d_metricsMap = QwtMetricsMap();
}

/*!
  \return Metrics map
*/
const QwtMetricsMap &QwtPainter::metricsMap()
{
    return d_metricsMap;
}

/*!
    Wrapper for QPainter::setClipRect()
*/
void QwtPainter::setClipRect(QPainter *painter, const QRect &rect)
{
    painter->setClipRect(d_metricsMap.layoutToDevice(rect, painter));
}

/*!
    Wrapper for QPainter::drawRect()
*/
void QwtPainter::drawRect(QPainter *painter, int x, int y, int w, int h) 
{
    drawRect(painter, QRect(x, y, w, h));
}

/*!
    Wrapper for QPainter::drawRect()
*/
void QwtPainter::drawRect(QPainter *painter, const QRect &rect) 
{
    QRect r = d_metricsMap.layoutToDevice(rect, painter);

    QRect clipRect;

    const bool deviceClipping = needDeviceClipping(painter, d_deviceClipping);
    if ( deviceClipping )
        clipRect = deviceClipRect();

    if ( clipRect.isValid() )
    {
        if ( !clipRect.intersects(r) )
            return;

        if ( !clipRect.contains(r) )
        {
            fillRect(painter, r & clipRect, painter->brush());

            int pw = painter->pen().width();
            pw = pw % 2 + pw / 2;

            QwtPolygon pa(5);
            pa.setPoint(0, r.left(), r.top());
            pa.setPoint(1, r.right() - pw, r.top());
            pa.setPoint(2, r.right() - pw, r.bottom() - pw);
            pa.setPoint(3, r.left(), r.bottom() - pw);
            pa.setPoint(4, r.left(), r.top());

            painter->save();
            painter->setBrush(Qt::NoBrush);
            drawPolyline(painter, pa);
            painter->restore();

            return;
        }
    }

#if QT_VERSION >= 0x040000
    if ( painter->pen().style() != Qt::NoPen && 
        painter->pen().color().isValid() )
    {
        // Qt4 adds the pen to the rect, Qt3 not.
        int pw = painter->pen().width();
        if ( pw == 0 )
            pw = 1;

        r.setWidth(r.width() - pw);
        r.setHeight(r.height() - pw);
    }
#endif
    painter->drawRect(r);
}

/*!
    Wrapper for QPainter::fillRect()
*/
void QwtPainter::fillRect(QPainter *painter, 
    const QRect &rect, const QBrush &brush)
{
    if ( !rect.isValid() )
        return;

    const bool deviceClipping = needDeviceClipping(painter, d_deviceClipping);

    QRect clipRect;
#if QT_VERSION >= 0x040000

    /*
      Performance of Qt4 is horrible for non trivial brushs. Without
      clipping expect minutes or hours for repainting large rects
      (might result from zooming)
    */

    clipRect = painter->window();
    if ( painter->hasClipping() )
        clipRect &= painter->clipRegion().boundingRect();
    if ( deviceClipping )
        clipRect &= deviceClipRect();
#else
    if ( deviceClipping )
        clipRect = deviceClipRect();
#endif

    QRect r = d_metricsMap.layoutToDevice(rect, painter);
    if ( clipRect.isValid() )
        r = r.intersect(clipRect);

    if ( r.isValid() )
        painter->fillRect(r, brush);
}

/*!
    Wrapper for QPainter::drawPie()
*/
void QwtPainter::drawPie(QPainter *painter, const QRect &rect, 
    int a, int alen)
{
    QRect r = d_metricsMap.layoutToDevice(rect, painter);

    const bool deviceClipping = needDeviceClipping(painter, d_deviceClipping);
    if ( deviceClipping && !deviceClipRect().contains(rect) )
        return;

    painter->drawPie(r, a, alen);
}

/*!
    Wrapper for QPainter::drawEllipse()
*/
void QwtPainter::drawEllipse(QPainter *painter, const QRect &rect)
{
    QRect r = d_metricsMap.layoutToDevice(rect, painter);

    const bool deviceClipping = needDeviceClipping(painter, d_deviceClipping);

    if ( deviceClipping && !deviceClipRect().contains(rect) )
        return;

#if QT_VERSION >= 0x040000
    if ( painter->pen().style() != Qt::NoPen &&
        painter->pen().color().isValid() )
    {
        // Qt4 adds the pen to the rect, Qt3 not.
        int pw = painter->pen().width();
        if ( pw == 0 )
            pw = 1;

        r.setWidth(r.width() - pw);
        r.setHeight(r.height() - pw);
    }
#endif

    painter->drawEllipse(r);
}

/*!
    Wrapper for QPainter::drawText()
*/
void QwtPainter::drawText(QPainter *painter, int x, int y, 
        const QString &text)
{
    drawText(painter, QPoint(x, y), text);
}

/*!
    Wrapper for QPainter::drawText()
*/
void QwtPainter::drawText(QPainter *painter, const QPoint &pos, 
        const QString &text)
{
    const QPoint p = d_metricsMap.layoutToDevice(pos, painter);

    const bool deviceClipping = needDeviceClipping(painter, d_deviceClipping);

    if ( deviceClipping && !deviceClipRect().contains(p) )
        return;

    painter->drawText(p, text);
}

/*!
    Wrapper for QPainter::drawText()
*/
void QwtPainter::drawText(QPainter *painter, int x, int y, int w, int h, 
        int flags, const QString &text)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -