diff options
Diffstat (limited to 'src/gui/painting/qpaintengineex.cpp')
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 217 |
1 files changed, 155 insertions, 62 deletions
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 88505fc07..9a0e31950 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -9,8 +10,8 @@ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** contained in the Technology Preview License Agreement accompanying +** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -20,21 +21,20 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -56,6 +56,20 @@ 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 { @@ -92,40 +106,24 @@ QRectF QVectorPath::controlPointRect() const return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2)); } -QPainterPath QVectorPath::convertToPainterPath() const -{ - QPainterPath path; - - if (m_count == 0) - return path; - - const QPointF *points = (const QPointF *) m_points; - if (m_elements) { - for (int i=0; i<m_count; ++i) { - switch (m_elements[i]) { - case QPainterPath::MoveToElement: - path.moveTo(points[i]); - break; - case QPainterPath::LineToElement: - path.lineTo(points[i]); - break; - case QPainterPath::CurveToElement: - path.cubicTo(points[i], points[i+1], points[i+2]); - break; - default: - break; - } - } - } else { - path.moveTo(points[0]); - for (int i=1; i<m_count; ++i) - path.lineTo(points[i]); +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; } - - return path; + 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()); @@ -179,8 +177,7 @@ void QPaintEngineExPrivate::replayClipOperations() if (!p || !p->d_ptr) return; - QPainterPrivate *pp = p->d_ptr; - QList<QPainterClipInfo> clipInfo = pp->state->clipInfo; + QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo; QTransform transform = q->state()->matrix; @@ -231,8 +228,7 @@ bool QPaintEngineExPrivate::hasClipOperations() const if (!p || !p->d_ptr) return false; - QPainterPrivate *pp = p->d_ptr; - QList<QPainterClipInfo> clipInfo = pp->state->clipInfo; + QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo; return !clipInfo.isEmpty(); } @@ -316,6 +312,29 @@ static QPainterPath::ElementType qpaintengineex_rect4_types_32[] = { QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 32 }; + +static QPainterPath::ElementType qpaintengineex_roundedrect_types[] = { + QPainterPath::MoveToElement, + QPainterPath::LineToElement, + QPainterPath::CurveToElement, + QPainterPath::CurveToDataElement, + QPainterPath::CurveToDataElement, + QPainterPath::LineToElement, + QPainterPath::CurveToElement, + QPainterPath::CurveToDataElement, + QPainterPath::CurveToDataElement, + QPainterPath::LineToElement, + QPainterPath::CurveToElement, + QPainterPath::CurveToDataElement, + QPainterPath::CurveToDataElement, + QPainterPath::LineToElement, + QPainterPath::CurveToElement, + QPainterPath::CurveToDataElement, + QPainterPath::CurveToDataElement +}; + + + static void qpaintengineex_moveTo(qreal x, qreal y, void *data) { ((StrokeHandler *) data)->pts.add(x); ((StrokeHandler *) data)->pts.add(y); @@ -426,11 +445,15 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) // Some engines might decide to optimize for the non-shape hint later on... uint flags = QVectorPath::WindingFill; + + if (path.elementCount() > 2) + flags |= QVectorPath::NonConvexShapeMask; + if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin) - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; - qreal txscale = 1; - if (!(pen.isCosmetic() || (qt_scaleForTransform(state()->matrix, &txscale) && txscale != 1))) { + // ### Perspective Xforms are currently not supported... + if (!pen.isCosmetic()) { // We include cosmetic pens in this case to avoid having to // change the current transform. Normal transformed, // non-cosmetic pens will be transformed as part of fill @@ -455,7 +478,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) points[4], points[5]); points += 6; types += 3; - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; break; default: break; @@ -487,8 +510,6 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) flags); fill(strokePath, pen.brush()); } else { - const qreal strokeWidth = d->stroker.strokeWidth(); - d->stroker.setStrokeWidth(strokeWidth * txscale); // For cosmetic pens we need a bit of trickery... We to process xform the input points if (state()->matrix.type() >= QTransform::TxProject) { QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); @@ -519,7 +540,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y()); points += 6; types += 3; - flags |= QVectorPath::CurvedShapeHint; + flags |= QVectorPath::CurvedShapeMask; break; } default: @@ -548,7 +569,6 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->activeStroker->end(); } - d->stroker.setStrokeWidth(strokeWidth); QVectorPath strokePath(d->strokeHandler->pts.data(), d->strokeHandler->types.size(), d->strokeHandler->types.data(), @@ -571,8 +591,13 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) void QPaintEngineEx::draw(const QVectorPath &path) { - fill(path, state()->brush); - stroke(path, state()->pen); + const QBrush &brush = state()->brush; + if (qbrush_style(brush) != Qt::NoBrush) + fill(path, brush); + + const QPen &pen = state()->pen; + if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) + stroke(path, pen); } @@ -591,7 +616,7 @@ void QPaintEngineEx::clip(const QRect &r, Qt::ClipOperation op) void QPaintEngineEx::clip(const QRegion ®ion, Qt::ClipOperation op) { - if (region.numRects() == 1) + if (region.rectCount() == 1) clip(region.boundingRect(), op); QVector<QRect> rects = region.rects(); @@ -710,6 +735,49 @@ void QPaintEngineEx::drawRects(const QRectF *rects, int rectCount) } } + +void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, + Qt::SizeMode mode) +{ + qreal x1 = rect.left(); + qreal x2 = rect.right(); + qreal y1 = rect.top(); + qreal y2 = rect.bottom(); + + if (mode == Qt::RelativeSize) { + xRadius = xRadius * rect.width() / 200.; + yRadius = yRadius * rect.height() / 200.; + } + + xRadius = qMin(xRadius, rect.width() / 2); + yRadius = qMin(yRadius, rect.height() / 2); + + qreal pts[] = { + x1 + xRadius, y1, // MoveTo + x2 - xRadius, y1, // LineTo + x2 - (1 - KAPPA) * xRadius, y1, // CurveTo + x2, y1 + (1 - KAPPA) * yRadius, + x2, y1 + yRadius, + x2, y2 - yRadius, // LineTo + x2, y2 - (1 - KAPPA) * yRadius, // CurveTo + x2 - (1 - KAPPA) * xRadius, y2, + x2 - xRadius, y2, + x1 + xRadius, y2, // LineTo + x1 + (1 - KAPPA) * xRadius, y2, // CurveTo + x1, y2 - (1 - KAPPA) * yRadius, + x1, y2 - yRadius, + x1, y1 + yRadius, // LineTo + x1, y1 + KAPPA * yRadius, // CurveTo + x1 + (1 - KAPPA) * xRadius, y1, + x1 + xRadius, y1 + }; + + QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint); + draw(path); +} + + + void QPaintEngineEx::drawLines(const QLine *lines, int lineCount) { int elementCount = lineCount << 1; @@ -795,7 +863,7 @@ void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount) pts[++oset] = points[i].x() + 0.001; pts[++oset] = points[i].y(); } - QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint); + QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, pen); pointCount -= 16; points += 16; @@ -826,7 +894,7 @@ void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount) pts[++oset] = points[i].x() + 0.001; pts[++oset] = points[i].y(); } - QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint); + QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint); stroke(path, pen); pointCount -= 16; points += 16; @@ -900,6 +968,31 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con fill(path, brush); } +void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/) +{ + qreal oldOpacity = state()->opacity; + QTransform oldTransform = state()->matrix; + + for (int i = 0; i < dataCount; ++i) { + QTransform transform = oldTransform; + transform.translate(drawingData[i].point.x(), drawingData[i].point.y()); + transform.rotate(drawingData[i].rotation); + state()->opacity = oldOpacity * drawingData[i].opacity; + state()->matrix = transform; + opacityChanged(); + transformChanged(); + + qreal w = drawingData[i].scaleX * drawingData[i].source.width(); + qreal h = drawingData[i].scaleY * drawingData[i].source.height(); + drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source); + } + + state()->opacity = oldOpacity; + state()->matrix = oldTransform; + opacityChanged(); + transformChanged(); +} + void QPaintEngineEx::setState(QPainterState *s) { QPaintEngine::state = s; |