#include "qpaintengineex_p.h"
#include "qpainter_p.h"
#include "qstroker_p.h"
#include "qbezier_p.h"
#include <private/qpainterpath_p.h>
#include <qvarlengtharray.h>
#include <qdebug.h>
QT_BEGIN_NAMESPACE
/*******************************************************************************
*
* class QVectorPath
*
*/
QVectorPath::~QVectorPath()
{
if (m_hints & ShouldUseCacheHint) {
CacheEntry *e = m_cache;
while (e) {
if (e->data)
e->cleanup(e->engine, e->data);
CacheEntry *n = e->next;
delete e;
e = n;
}
}
}
QRectF QVectorPath::controlPointRect() const
{
if (m_hints & ControlPointRect)
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
if (m_count == 0) {
m_cp_rect.x1 = m_cp_rect.x2 = m_cp_rect.y1 = m_cp_rect.y2 = 0;
m_hints |= ControlPointRect;
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
}
Q_ASSERT(m_points && m_count > 0);
const qreal *pts = m_points;
m_cp_rect.x1 = m_cp_rect.x2 = *pts;
++pts;
m_cp_rect.y1 = m_cp_rect.y2 = *pts;
++pts;
const qreal *epts = m_points + (m_count << 1);
while (pts < epts) {
qreal x = *pts;
if (x < m_cp_rect.x1) m_cp_rect.x1 = x;
else if (x > m_cp_rect.x2) m_cp_rect.x2 = x;
++pts;
qreal y = *pts;
if (y < m_cp_rect.y1) m_cp_rect.y1 = y;
else if (y > m_cp_rect.y2) m_cp_rect.y2 = y;
++pts;
}
m_hints |= ControlPointRect;
return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
}
QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data,
qvectorpath_cache_cleanup cleanup) const{
Q_ASSERT(!lookupCacheData(engine));
if ((m_hints & IsCachedHint) == 0) {
m_cache = 0;
m_hints |= IsCachedHint;
}
CacheEntry *e = new CacheEntry;
e->engine = engine;
e->data = data;
e->cleanup = cleanup;
e->next = m_cache;
m_cache = e;
return m_cache;
}
const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
{
Q_ASSERT(path.d_func());
return path.d_func()->vectorPath();
}
#ifndef QT_NO_DEBUG_STREAM
QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path)
{
QRectF rf = path.controlPointRect();
s << "QVectorPath(size:" << path.elementCount()
<< " hints:" << hex << path.hints()
<< rf << ')';
return s;
}
#endif
/*******************************************************************************
*
* class QPaintEngineExPrivate:
*
*/
struct StrokeHandler {
StrokeHandler(int reserve) : pts(reserve), types(reserve) {}
QDataBuffer<qreal> pts;
QDataBuffer<QPainterPath::ElementType> types;
};
QPaintEngineExPrivate::QPaintEngineExPrivate()
: dasher(&stroker),
strokeHandler(0),
activeStroker(0),
strokerPen(Qt::NoPen)
{
}
QPaintEngineExPrivate::~QPaintEngineExPrivate()
{
delete strokeHandler;
}
void QPaintEngineExPrivate::replayClipOperations()
{
Q_Q(QPaintEngineEx);
QPainter *p = q->painter();
if (!p || !p->d_ptr)
return;
QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo;
QTransform transform = q->state()->matrix;
for (int i = 0; i < clipInfo.size(); ++i) {
const QPainterClipInfo &info = clipInfo.at(i);
if (info.matrix != q->state()->matrix) {
q->state()->matrix = info.matrix;
q->transformChanged();
}
switch (info.clipType) {
case QPainterClipInfo::RegionClip:
q->clip(info.region, info.operation);
break;
case QPainterClipInfo::PathClip:
q->clip(info.path, info.operation);
break;
case QPainterClipInfo::RectClip:
q->clip(info.rect, info.operation);
break;
case QPainterClipInfo::RectFClip: {
qreal right = info.rectf.x() + info.rectf.width();
qreal bottom = info.rectf.y() + info.rectf.height();
qreal pts[] = { info.rectf.x(), info.rectf.y(),
right, info.rectf.y(),
right, bottom,
info.rectf.x(), bottom };
QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
q->clip(vp, info.operation);
break;
}
}
}
if (transform != q->state()->matrix) {
q->state()->matrix = transform;
q->transformChanged();
}
}
bool QPaintEngineExPrivate::hasClipOperations() const
{
Q_Q(const QPaintEngineEx);
QPainter *p = q->painter();
if (!p || !p->d_ptr)
return false;
QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo;
return !clipInfo.isEmpty();
}
/*******************************************************************************
*
* class QPaintEngineEx:
*
*/
static QPainterPath::ElementType qpaintengineex_ellipse_types[] = {
QPainterPath::MoveToElement,
QPainterPath::CurveToElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToElement,
QPainterPath::CurveToDataElement,
QPainterPath::CurveToDataElement
};
static QPainterPath::ElementType qpaintengineex_line_types_16[] = {
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement,
QPainterPath::MoveToElement, QPainterPath::LineToElement
};
static QPainterPath::ElementType qpaintengineex_rect4_types_32[] = {
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 1
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 2
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 3
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 4
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 5
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 6
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 7
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 8
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 9
QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 10
QPain