📄 qwt_painter.cpp
字号:
/* -*- 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 + -