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/opengl/gl2paintengineex/qgl2pexvertexarray.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 QtOpenGL 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**
     
    4444#include <private/qbezier_p.h>
    4545
     46QT_BEGIN_NAMESPACE
     47
    4648void QGL2PEXVertexArray::clear()
    4749{
    4850    vertexArray.reset();
    49     vertexArrayStops.clear();
     51    vertexArrayStops.reset();
    5052    boundingRectDirty = true;
    5153}
     
    6062}
    6163
    62 void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale)
     64void QGL2PEXVertexArray::addRect(const QRectF &rect)
     65{
     66    vertexArray << rect.topLeft() << rect.topRight() << rect.bottomRight()
     67                << rect.bottomRight() << rect.bottomLeft() << rect.topLeft();
     68}
     69
     70void QGL2PEXVertexArray::addClosingLine(int index)
     71{
     72    if (QPointF(vertexArray.at(index)) != QPointF(vertexArray.last()))
     73        vertexArray.add(vertexArray.at(index));
     74}
     75
     76void QGL2PEXVertexArray::addCentroid(const QVectorPath &path, int subPathIndex)
     77{
     78    const QPointF *const points = reinterpret_cast<const QPointF *>(path.points());
     79    const QPainterPath::ElementType *const elements = path.elements();
     80
     81    QPointF sum = points[subPathIndex];
     82    int count = 1;
     83
     84    for (int i = subPathIndex + 1; i < path.elementCount() && (!elements || elements[i] != QPainterPath::MoveToElement); ++i) {
     85        sum += points[i];
     86        ++count;
     87    }
     88
     89    const QPointF centroid = sum / qreal(count);
     90    vertexArray.add(centroid);
     91}
     92
     93void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline)
    6394{
    6495    const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
     
    71102    }
    72103
     104    if (!outline && !path.isConvex())
     105        addCentroid(path, 0);
     106
     107    int lastMoveTo = vertexArray.size();
    73108    vertexArray.add(points[0]); // The first element is always a moveTo
    74109
     
    86121
    87122        for (int i=1; i<path.elementCount(); ++i) {
    88             const QPainterPath::ElementType elementType = elements[i];
    89             switch (elementType) {
     123            switch (elements[i]) {
    90124            case QPainterPath::MoveToElement:
     125                if (!outline)
     126                    addClosingLine(lastMoveTo);
    91127//                qDebug("element[%d] is a MoveToElement", i);
    92                 vertexArrayStops.append(vertexArray.size());
    93                 vertexArray.add(points[i]); // Add the moveTo as a new vertex
     128                vertexArrayStops.add(vertexArray.size());
     129                if (!outline) {
     130                    if (!path.isConvex()) addCentroid(path, i);
     131                    lastMoveTo = vertexArray.size();
     132                }
     133                lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex
    94134                break;
    95135            case QPainterPath::LineToElement:
     
    97137                lineToArray(points[i].x(), points[i].y());
    98138                break;
    99             case QPainterPath::CurveToElement:
    100 //                qDebug("element[%d] is a CurveToElement", i);
    101                 curveToArray(points[i], points[i+1], points[i+2], curveInverseScale);
    102                 i+=2;
    103                 break;
     139            case QPainterPath::CurveToElement: {
     140                QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1),
     141                                                points[i],
     142                                                points[i+1],
     143                                                points[i+2]);
     144                QRectF bounds = b.bounds();
     145                // threshold based on same algorithm as in qtriangulatingstroker.cpp
     146                int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6));
     147                if (threshold < 3) threshold = 3;
     148                qreal one_over_threshold_minus_1 = 1.f / (threshold - 1);
     149                for (int t=0; t<threshold; ++t) {
     150                    QPointF pt = b.pointAt(t * one_over_threshold_minus_1);
     151                    lineToArray(pt.x(), pt.y());
     152                }
     153                i += 2;
     154                break; }
    104155            default:
    105156                break;
     
    108159    } while (0);
    109160
    110     vertexArrayStops.append(vertexArray.size());
     161    if (!outline)
     162        addClosingLine(lastMoveTo);
     163    vertexArrayStops.add(vertexArray.size());
    111164}
    112165
     
    125178}
    126179
    127 void QGL2PEXVertexArray::curveToArray(const QGLPoint &cp1, const QGLPoint &cp2, const QGLPoint &ep, GLfloat inverseScale)
    128 {
    129     qreal inverseScaleHalf = inverseScale / 2;
    130 
    131     QBezier beziers[32];
    132     beziers[0] = QBezier::fromPoints(vertexArray.last(), cp1, cp2, ep);
    133     QBezier *b = beziers;
    134     while (b >= beziers) {
    135         // check if we can pop the top bezier curve from the stack
    136         qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
    137         qreal d;
    138         if (l > inverseScale) {
    139             d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) )
    140                 + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) );
    141             d /= l;
    142         } else {
    143             d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
    144                 qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
    145         }
    146         if (d < inverseScaleHalf || b == beziers + 31) {
    147             // good enough, we pop it off and add the endpoint
    148             lineToArray(b->x4, b->y4);
    149             --b;
    150         } else {
    151             // split, second half of the polygon goes lower into the stack
    152             b->split(b+1, b);
    153            ++b;
    154         }
    155     }
    156 }
     180QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.