Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/painting/qpaintengineex.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4343#include "qpainter_p.h"
    4444#include "qstroker_p.h"
     45#include "qbezier_p.h"
    4546#include <private/qpainterpath_p.h>
    4647
     
    5657 *
    5758 */
    58 
    59 const QRealRect &QVectorPath::controlPointRect() const
     59QVectorPath::~QVectorPath()
     60{
     61    if (m_hints & ShouldUseCacheHint) {
     62        CacheEntry *e = m_cache;
     63        while (e) {
     64            if (e->data)
     65                e->cleanup(e->engine, e->data);
     66            CacheEntry *n = e->next;
     67            delete e;
     68            e = n;
     69        }
     70    }
     71}
     72
     73
     74QRectF QVectorPath::controlPointRect() const
    6075{
    6176    if (m_hints & ControlPointRect)
    62         return m_cp_rect;
     77        return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
    6378
    6479    if (m_count == 0) {
    6580        m_cp_rect.x1 = m_cp_rect.x2 = m_cp_rect.y1 = m_cp_rect.y2 = 0;
    6681        m_hints |= ControlPointRect;
    67         return m_cp_rect;
     82        return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
    6883    }
    6984    Q_ASSERT(m_points && m_count > 0);
     
    89104
    90105    m_hints |= ControlPointRect;
    91     return m_cp_rect;
    92 }
     106    return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
     107}
     108
     109
     110QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data,
     111                                                   qvectorpath_cache_cleanup cleanup) const{
     112    Q_ASSERT(!lookupCacheData(engine));
     113    if ((m_hints & IsCachedHint) == 0) {
     114        m_cache = 0;
     115        m_hints |= IsCachedHint;
     116    }
     117    CacheEntry *e = new CacheEntry;
     118    e->engine = engine;
     119    e->data = data;
     120    e->cleanup = cleanup;
     121    e->next = m_cache;
     122    m_cache = e;
     123    return m_cache;
     124}
     125
    93126
    94127const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
     
    101134QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path)
    102135{
    103     QRealRect vectorPathBounds = path.controlPointRect();
    104     QRectF rf(vectorPathBounds.x1, vectorPathBounds.y1,
    105               vectorPathBounds.x2 - vectorPathBounds.x1, vectorPathBounds.y2 - vectorPathBounds.y1);
     136    QRectF rf = path.controlPointRect();
    106137    s << "QVectorPath(size:" << path.elementCount()
    107138      << " hints:" << hex << path.hints()
    108       << rf << ")";
     139      << rf << ')';
    109140    return s;
    110141}
     
    139170
    140171
     172void QPaintEngineExPrivate::replayClipOperations()
     173{
     174    Q_Q(QPaintEngineEx);
     175
     176    QPainter *p = q->painter();
     177    if (!p || !p->d_ptr)
     178        return;
     179
     180    QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo;
     181
     182    QTransform transform = q->state()->matrix;
     183
     184    for (int i = 0; i <  clipInfo.size(); ++i) {
     185        const QPainterClipInfo &info = clipInfo.at(i);
     186
     187        if (info.matrix != q->state()->matrix) {
     188            q->state()->matrix = info.matrix;
     189            q->transformChanged();
     190        }
     191
     192        switch (info.clipType) {
     193        case QPainterClipInfo::RegionClip:
     194            q->clip(info.region, info.operation);
     195            break;
     196        case QPainterClipInfo::PathClip:
     197            q->clip(info.path, info.operation);
     198            break;
     199        case QPainterClipInfo::RectClip:
     200            q->clip(info.rect, info.operation);
     201            break;
     202        case QPainterClipInfo::RectFClip: {
     203            qreal right = info.rectf.x() + info.rectf.width();
     204            qreal bottom = info.rectf.y() + info.rectf.height();
     205            qreal pts[] = { info.rectf.x(), info.rectf.y(),
     206                            right, info.rectf.y(),
     207                            right, bottom,
     208                            info.rectf.x(), bottom };
     209            QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
     210            q->clip(vp, info.operation);
     211            break;
     212            }
     213        }
     214    }
     215
     216    if (transform != q->state()->matrix) {
     217        q->state()->matrix = transform;
     218        q->transformChanged();
     219    }
     220}
     221
     222
     223bool QPaintEngineExPrivate::hasClipOperations() const
     224{
     225    Q_Q(const QPaintEngineEx);
     226
     227    QPainter *p = q->painter();
     228    if (!p || !p->d_ptr)
     229        return false;
     230
     231    QList<QPainterClipInfo> clipInfo = p->d_ptr->state->clipInfo;
     232
     233    return !clipInfo.isEmpty();
     234}
    141235
    142236/*******************************************************************************
     
    219313};
    220314
     315
     316static QPainterPath::ElementType qpaintengineex_roundedrect_types[] = {
     317    QPainterPath::MoveToElement,
     318    QPainterPath::LineToElement,
     319    QPainterPath::CurveToElement,
     320    QPainterPath::CurveToDataElement,
     321    QPainterPath::CurveToDataElement,
     322    QPainterPath::LineToElement,
     323    QPainterPath::CurveToElement,
     324    QPainterPath::CurveToDataElement,
     325    QPainterPath::CurveToDataElement,
     326    QPainterPath::LineToElement,
     327    QPainterPath::CurveToElement,
     328    QPainterPath::CurveToDataElement,
     329    QPainterPath::CurveToDataElement,
     330    QPainterPath::LineToElement,
     331    QPainterPath::CurveToElement,
     332    QPainterPath::CurveToDataElement,
     333    QPainterPath::CurveToDataElement
     334};
     335
     336
     337
    221338static void qpaintengineex_moveTo(qreal x, qreal y, void *data) {
    222339    ((StrokeHandler *) data)->pts.add(x);
     
    245362}
    246363
     364QPaintEngineEx::QPaintEngineEx()
     365    : QPaintEngine(*new QPaintEngineExPrivate, AllFeatures)
     366{
     367    extended = true;
     368}
     369
    247370QPaintEngineEx::QPaintEngineEx(QPaintEngineExPrivate &data)
    248371    : QPaintEngine(data, AllFeatures)
     
    250373    extended = true;
    251374}
    252 
    253375
    254376QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
     
    297419        } else {
    298420            // ### re-enable...
    299 //             if (pen.isCosmetic()) {
    300 //                 d->dashStroker->setClipRect(d->deviceRect);
    301 //             } else {
    302 //                 QRectF clipRect = s->matrix.inverted().mapRect(QRectF(d->deviceRect));
    303 //                 d->dashStroker->setClipRect(clipRect);
    304 //             }
     421            if (pen.isCosmetic()) {
     422                d->dasher.setClipRect(d->exDeviceRect);
     423            } else {
     424                QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
     425                d->dasher.setClipRect(clipRect);
     426            }
    305427            d->dasher.setDashPattern(pen.dashPattern());
    306428            d->dasher.setDashOffset(pen.dashOffset());
     
    319441    const qreal *lastPoint = points + (pointCount<<1);
    320442
    321     d->activeStroker->begin(d->strokeHandler);
    322443    d->strokeHandler->types.reset();
    323444    d->strokeHandler->pts.reset();
     
    325446    // Some engines might decide to optimize for the non-shape hint later on...
    326447    uint flags = QVectorPath::WindingFill;
     448
     449    if (path.elementCount() > 2)
     450        flags |= QVectorPath::NonConvexShapeMask;
     451
    327452    if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
    328         flags |= QVectorPath::CurvedShapeHint;
     453        flags |= QVectorPath::CurvedShapeMask;
    329454
    330455    // ### Perspective Xforms are currently not supported...
    331     qreal txscale = 1;
    332     if (!(pen.isCosmetic() || (qt_scaleForTransform(state()->matrix, &txscale) && txscale != 1))) {
     456    if (!pen.isCosmetic()) {
    333457        // We include cosmetic pens in this case to avoid having to
    334458        // change the current transform. Normal transformed,
    335459        // non-cosmetic pens will be transformed as part of fill
    336460        // later, so they are also covered here..
     461        d->activeStroker->begin(d->strokeHandler);
    337462        if (types) {
    338463            while (points < lastPoint) {
     
    354479                    points += 6;
    355480                    types += 3;
    356                     flags |= QVectorPath::CurvedShapeHint;
     481                    flags |= QVectorPath::CurvedShapeMask;
    357482                    break;
    358483                default:
     
    383508                               d->strokeHandler->types.size(),
    384509                               d->strokeHandler->types.data(),
    385                                QVectorPath::WindingFill);
     510                               flags);
    386511        fill(strokePath, pen.brush());
    387512    } else {
    388         const qreal strokeWidth = d->stroker.strokeWidth();
    389         d->stroker.setStrokeWidth(strokeWidth * txscale);
    390513        // For cosmetic pens we need a bit of trickery... We to process xform the input points
    391         if (types) {
    392             while (points < lastPoint) {
    393                 switch (*types) {
    394                 case QPainterPath::MoveToElement: {
    395                     QPointF pt = (*(QPointF *) points) * state()->matrix;
    396                     d->activeStroker->moveTo(pt.x(), pt.y());
     514        if (state()->matrix.type() >= QTransform::TxProject) {
     515            QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
     516            d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
     517        } else {
     518            d->activeStroker->begin(d->strokeHandler);
     519            if (types) {
     520                while (points < lastPoint) {
     521                    switch (*types) {
     522                    case QPainterPath::MoveToElement: {
     523                        QPointF pt = (*(QPointF *) points) * state()->matrix;
     524                        d->activeStroker->moveTo(pt.x(), pt.y());
     525                        points += 2;
     526                        ++types;
     527                        break;
     528                    }
     529                    case QPainterPath::LineToElement: {
     530                        QPointF pt = (*(QPointF *) points) * state()->matrix;
     531                        d->activeStroker->lineTo(pt.x(), pt.y());
     532                        points += 2;
     533                        ++types;
     534                        break;
     535                    }
     536                    case QPainterPath::CurveToElement: {
     537                        QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
     538                        QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
     539                        QPointF e =  ((QPointF *) points)[2] * state()->matrix;
     540                        d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
     541                        points += 6;
     542                        types += 3;
     543                        flags |= QVectorPath::CurvedShapeMask;
     544                        break;
     545                    }
     546                    default:
     547                        break;
     548                    }
     549                }
     550                if (path.hasImplicitClose()) {
     551                    QPointF pt = * ((QPointF *) path.points()) * state()->matrix;
     552                    d->activeStroker->lineTo(pt.x(), pt.y());
     553                }
     554
     555            } else {
     556                QPointF p = ((QPointF *)points)[0] * state()->matrix;
     557                d->activeStroker->moveTo(p.x(), p.y());
     558                points += 2;
     559                ++types;
     560                while (points < lastPoint) {
     561                    QPointF p = ((QPointF *)points)[0] * state()->matrix;
     562                    d->activeStroker->lineTo(p.x(), p.y());
    397563                    points += 2;
    398564                    ++types;
    399                     break;
    400565                }
    401                 case QPainterPath::LineToElement: {
    402                     QPointF pt = (*(QPointF *) points) * state()->matrix;
    403                     d->activeStroker->lineTo(pt.x(), pt.y());
    404                     points += 2;
    405                     ++types;
    406                     break;
    407                 }
    408                 case QPainterPath::CurveToElement: {
    409                     QPointF c1 = ((QPointF *) points)[0] * state()->matrix;
    410                     QPointF c2 = ((QPointF *) points)[1] * state()->matrix;
    411                     QPointF e =  ((QPointF *) points)[2] * state()->matrix;
    412                     d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
    413                     points += 6;
    414                     types += 3;
    415                     flags |= QVectorPath::CurvedShapeHint;
    416                     break;
    417                 }
    418                 default:
    419                     break;
    420                 }
     566                if (path.hasImplicitClose())
     567                    d->activeStroker->lineTo(p.x(), p.y());
    421568            }
    422             if (path.hasImplicitClose()) {
    423                 QPointF pt = * ((QPointF *) path.points()) * state()->matrix;
    424                 d->activeStroker->lineTo(pt.x(), pt.y());
    425             }
    426 
    427         } else {
    428             QPointF p = ((QPointF *)points)[0] * state()->matrix;
    429             d->activeStroker->moveTo(p.x(), p.y());
    430             points += 2;
    431             ++types;
    432             while (points < lastPoint) {
    433                 QPointF p = ((QPointF *)points)[0] * state()->matrix;
    434                 d->activeStroker->lineTo(p.x(), p.y());
    435                 points += 2;
    436                 ++types;
    437             }
    438             if (path.hasImplicitClose())
    439                 d->activeStroker->lineTo(p.x(), p.y());
    440         }
    441 
    442         d->activeStroker->end();
    443         d->stroker.setStrokeWidth(strokeWidth);
     569            d->activeStroker->end();
     570        }
     571
    444572        QVectorPath strokePath(d->strokeHandler->pts.data(),
    445573                               d->strokeHandler->types.size(),
    446574                               d->strokeHandler->types.data(),
    447                                QVectorPath::WindingFill);
     575                               flags);
    448576
    449577        QTransform xform = state()->matrix;
     
    464592void QPaintEngineEx::draw(const QVectorPath &path)
    465593{
    466     fill(path, state()->brush);
    467     stroke(path, state()->pen);
     594    const QBrush &brush = state()->brush;
     595    if (qbrush_style(brush) != Qt::NoBrush)
     596        fill(path, brush);
     597
     598    const QPen &pen = state()->pen;
     599    if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush)
     600        stroke(path, pen);
    468601}
    469602
     
    484617void QPaintEngineEx::clip(const QRegion &region, Qt::ClipOperation op)
    485618{
     619    if (region.rectCount() == 1)
     620        clip(region.boundingRect(), op);
     621
    486622    QVector<QRect> rects = region.rects();
    487623    if (rects.size() <= 32) {
     
    600736}
    601737
     738
     739void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius,
     740                                     Qt::SizeMode mode)
     741{
     742    qreal x1 = rect.left();
     743    qreal x2 = rect.right();
     744    qreal y1 = rect.top();
     745    qreal y2 = rect.bottom();
     746
     747    if (mode == Qt::RelativeSize) {
     748        xRadius = xRadius * rect.width() / 200.;
     749        yRadius = yRadius * rect.height() / 200.;
     750    }
     751
     752    xRadius = qMin(xRadius, rect.width() / 2);
     753    yRadius = qMin(yRadius, rect.height() / 2);
     754
     755    qreal pts[] = {
     756        x1 + xRadius, y1,                   // MoveTo
     757        x2 - xRadius, y1,                   // LineTo
     758        x2 - (1 - KAPPA) * xRadius, y1,     // CurveTo
     759        x2, y1 + (1 - KAPPA) * yRadius,
     760        x2, y1 + yRadius,
     761        x2, y2 - yRadius,                   // LineTo
     762        x2, y2 - (1 - KAPPA) * yRadius,     // CurveTo
     763        x2 - (1 - KAPPA) * xRadius, y2,
     764        x2 - xRadius, y2,
     765        x1 + xRadius, y2,                   // LineTo
     766        x1 + (1 - KAPPA) * xRadius, y2,           // CurveTo
     767        x1, y2 - (1 - KAPPA) * yRadius,
     768        x1, y2 - yRadius,
     769        x1, y1 + yRadius,                   // LineTo
     770        x1, y1 + KAPPA * yRadius,           // CurveTo
     771        x1 + (1 - KAPPA) * xRadius, y1,
     772        x1 + xRadius, y1
     773    };
     774
     775    QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint);
     776    draw(path);
     777}
     778
     779
     780
    602781void QPaintEngineEx::drawLines(const QLine *lines, int lineCount)
    603782{
     
    685864                pts[++oset] = points[i].y();
    686865            }
    687             QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint);
     866            QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
    688867            stroke(path, pen);
    689868            pointCount -= 16;
     
    716895                pts[++oset] = points[i].y();
    717896            }
    718             QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::NonCurvedShapeHint);
     897            QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
    719898            stroke(path, pen);
    720899            pointCount -= 16;
     
    778957{
    779958    QBrush brush(state()->pen.color(), pixmap);
    780     QTransform xform;
    781     xform.translate(-s.x(), -s.y());
     959    QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y());
    782960    brush.setTransform(xform);
    783961
     
    791969}
    792970
     971void QPaintEngineEx::drawPixmaps(const QDrawPixmaps::Data *drawingData, int dataCount, const QPixmap &pixmap, QDrawPixmaps::DrawingHints /*hints*/)
     972{
     973    qreal oldOpacity = state()->opacity;
     974    QTransform oldTransform = state()->matrix;
     975
     976    for (int i = 0; i < dataCount; ++i) {
     977        QTransform transform = oldTransform;
     978        transform.translate(drawingData[i].point.x(), drawingData[i].point.y());
     979        transform.rotate(drawingData[i].rotation);
     980        state()->opacity = oldOpacity * drawingData[i].opacity;
     981        state()->matrix = transform;
     982        opacityChanged();
     983        transformChanged();
     984
     985        qreal w = drawingData[i].scaleX * drawingData[i].source.width();
     986        qreal h = drawingData[i].scaleY * drawingData[i].source.height();
     987        drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, drawingData[i].source);
     988    }
     989
     990    state()->opacity = oldOpacity;
     991    state()->matrix = oldTransform;
     992    opacityChanged();
     993    transformChanged();
     994}
     995
    793996void QPaintEngineEx::setState(QPainterState *s)
    794997{
Note: See TracChangeset for help on using the changeset viewer.