Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

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

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    121121{
    122122public:
    123     QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path)
    124         : m_path(path), m_pos(0), m_curve_index(-1) { }
     123    QSubpathFlatIterator(const QDataBuffer<QStrokerOps::Element> *path, qreal threshold)
     124        : m_path(path), m_pos(0), m_curve_index(-1), m_curve_threshold(threshold) { }
    125125
    126126    inline bool hasNext() const { return m_curve_index >= 0 || m_pos < m_path->size(); }
     
    153153                                                  qt_fixed_to_real(m_path->at(m_pos+1).y)),
    154154                                          QPointF(qt_fixed_to_real(m_path->at(m_pos+2).x),
    155                                                   qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon();
     155                                                  qt_fixed_to_real(m_path->at(m_pos+2).y))).toPolygon(m_curve_threshold);
    156156            m_curve_index = 1;
    157157            e.type = QPainterPath::LineToElement;
     
    170170    QPolygonF m_curve;
    171171    int m_curve_index;
     172    qreal m_curve_threshold;
    172173};
    173174
     
    188189
    189190QStrokerOps::QStrokerOps()
    190     : m_customData(0), m_moveTo(0), m_lineTo(0), m_cubicTo(0)
     191    : m_elements(0)
     192    , m_curveThreshold(qt_real_to_fixed(0.25))
     193    , m_dashThreshold(qt_real_to_fixed(0.25))
     194    , m_customData(0)
     195    , m_moveTo(0)
     196    , m_lineTo(0)
     197    , m_cubicTo(0)
    191198{
    192199}
     
    195202{
    196203}
    197 
    198204
    199205/*!
     
    239245        return;
    240246
     247    setCurveThresholdFromTransform(QTransform());
    241248    begin(customData);
    242249    int count = path.elementCount();
     
    309316    if (!pointCount)
    310317        return;
     318
     319    setCurveThresholdFromTransform(QTransform());
    311320    begin(data);
    312321    if (matrix.isIdentity()) {
     
    349358    }
    350359
     360    setCurveThresholdFromTransform(QTransform());
    351361    begin(data);
    352362    moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y()));
     
    367377    m_strokeWidth = qt_real_to_fixed(1);
    368378    m_miterLimit = qt_real_to_fixed(2);
    369     m_curveThreshold = qt_real_to_fixed(0.25);
    370379}
    371380
    372381QStroker::~QStroker()
    373382{
    374 
    375383}
    376384
     
    603611            QLineF miterLine(QPointF(qt_fixed_to_real(focal_x),
    604612                                     qt_fixed_to_real(focal_y)), isect);
    605             if (miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) {
     613            if (type == QLineF::NoIntersection || miterLine.length() > qt_fixed_to_real(m_strokeWidth * m_miterLimit) / 2) {
    606614                emitLineTo(qt_real_to_fixed(nextLine.x1()),
    607615                           qt_real_to_fixed(nextLine.y1()));
     
    10441052}
    10451053
     1054static inline bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br)
     1055{
     1056    return ((p1.x > tl.x || p2.x > tl.x) && (p1.x < br.x || p2.x < br.x)
     1057        && (p1.y > tl.y || p2.y > tl.y) && (p1.y < br.y || p2.y < br.y));
     1058}
     1059
     1060// If the line intersects the rectangle, this function will return true.
     1061static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br)
     1062{
     1063    if (!lineRectIntersectsRect(p1, p2, tl, br))
     1064        return false;
     1065    if (p1.x == p2.x || p1.y == p2.y)
     1066        return true;
     1067
     1068    if (p1.y > p2.y)
     1069        qSwap(p1, p2); // make p1 above p2
     1070    qfixed2d u;
     1071    qfixed2d v;
     1072    qfixed2d w = {p2.x - p1.x, p2.y - p1.y};
     1073    if (p1.x < p2.x) {
     1074        // backslash
     1075        u.x = tl.x - p1.x; u.y = br.y - p1.y;
     1076        v.x = br.x - p1.x; v.y = tl.y - p1.y;
     1077    } else {
     1078        // slash
     1079        u.x = tl.x - p1.x; u.y = tl.y - p1.y;
     1080        v.x = br.x - p1.x; v.y = br.y - p1.y;
     1081    }
     1082#if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16)
     1083    qint64 val1 = qint64(u.x) * qint64(w.y) - qint64(u.y) * qint64(w.x);
     1084    qint64 val2 = qint64(v.x) * qint64(w.y) - qint64(v.y) * qint64(w.x);
     1085    return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
     1086#elif defined(QFIXED_IS_32_32)
     1087    // Cannot do proper test because it may overflow.
     1088    return true;
     1089#else
     1090    qreal val1 = u.x * w.y - u.y * w.x;
     1091    qreal val2 = v.x * w.y - v.y * w.x;
     1092    return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0);
     1093#endif
     1094}
    10461095
    10471096void QDashStroker::processCurrentSubpath()
     
    10681117        return;
    10691118
     1119    qreal invSumLength = qreal(1) / sumLength;
     1120
    10701121    Q_ASSERT(dashCount > 0);
    10711122
    1072     dashCount = (dashCount / 2) * 2; // Round down to even number
     1123    dashCount = dashCount & -2; // Round down to even number
    10731124
    10741125    int idash = 0; // Index to current dash
     
    10781129
    10791130    // make sure doffset is in range [0..sumLength)
    1080     doffset -= qFloor(doffset / sumLength) * sumLength;
     1131    doffset -= qFloor(doffset * invSumLength) * sumLength;
    10811132
    10821133    while (doffset >= dashes[idash]) {
    10831134        doffset -= dashes[idash];
    1084         idash = (idash + 1) % dashCount;
     1135        if (++idash >= dashCount)
     1136            idash = 0;
    10851137    }
    10861138
     
    10921144    QPainterPath dashPath;
    10931145
    1094     QSubpathFlatIterator it(&m_elements);
     1146    QSubpathFlatIterator it(&m_elements, m_dashThreshold);
    10951147    qfixed2d prev = it.next();
    10961148
     
    11201172
    11211173        bool done = pos >= estop;
     1174
     1175        if (clipping) {
     1176            // Check if the entire line can be clipped away.
     1177            if (!lineIntersectsRect(prev, e, clip_tl, clip_br)) {
     1178                // Cut away full dash sequences.
     1179                elen -= qFloor(elen * invSumLength) * sumLength;
     1180                // Update dash offset.
     1181                while (!done) {
     1182                    qreal dpos = pos + dashes[idash] - doffset - estart;
     1183
     1184                    Q_ASSERT(dpos >= 0);
     1185
     1186                    if (dpos > elen) { // dash extends this line
     1187                        doffset = dashes[idash] - (dpos - elen); // subtract the part already used
     1188                        pos = estop; // move pos to next path element
     1189                        done = true;
     1190                    } else { // Dash is on this line
     1191                        pos = dpos + estart;
     1192                        done = pos >= estop;
     1193                        if (++idash >= dashCount)
     1194                            idash = 0;
     1195                        doffset = 0; // full segment so no offset on next.
     1196                    }
     1197                }
     1198                hasMoveTo = false;
     1199                move_to_pos = e;
     1200            }
     1201        }
     1202
    11221203        // Dash away...
    11231204        while (!done) {
    11241205            QPointF p2;
    11251206
    1126             int idash_incr = 0;
    11271207            bool has_offset = doffset > 0;
     1208            bool evenDash = (idash & 1) == 0;
    11281209            qreal dpos = pos + dashes[idash] - doffset - estart;
    11291210
     
    11391220                pos = dpos + estart;
    11401221                done = pos >= estop;
    1141                 idash_incr = 1;
     1222                if (++idash >= dashCount)
     1223                    idash = 0;
    11421224                doffset = 0; // full segment so no offset on next.
    11431225            }
    11441226
    1145             if (idash % 2 == 0) {
     1227            if (evenDash) {
    11461228                line_to_pos.x = qt_real_to_fixed(p2.x());
    11471229                line_to_pos.y = qt_real_to_fixed(p2.y());
    11481230
    1149                 // If we have an offset, we're continuing a dash
    1150                 // from a previous element and should only
    1151                 // continue the current dash, without starting a
    1152                 // new subpath.
    1153                 if (!has_offset || !hasMoveTo) {
    1154                     emitMoveTo(move_to_pos.x, move_to_pos.y);
    1155                     hasMoveTo = true;
     1231                if (!clipping
     1232                    || lineRectIntersectsRect(move_to_pos, line_to_pos, clip_tl, clip_br))
     1233                {
     1234                    // If we have an offset, we're continuing a dash
     1235                    // from a previous element and should only
     1236                    // continue the current dash, without starting a
     1237                    // new subpath.
     1238                    if (!has_offset || !hasMoveTo) {
     1239                        emitMoveTo(move_to_pos.x, move_to_pos.y);
     1240                        hasMoveTo = true;
     1241                    }
     1242
     1243                    emitLineTo(line_to_pos.x, line_to_pos.y);
     1244                } else {
     1245                    hasMoveTo = false;
    11561246                }
    1157 
    1158                 if (!clipping
    1159                     // if move_to is inside...
    1160                     || (move_to_pos.x > clip_tl.x && move_to_pos.x < clip_br.x
    1161                      && move_to_pos.y > clip_tl.y && move_to_pos.y < clip_br.y)
    1162                     // Or if line_to is inside...
    1163                     || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x
    1164                      && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y))
    1165                 {
    1166                     emitLineTo(line_to_pos.x, line_to_pos.y);
    1167                 }
     1247                move_to_pos = line_to_pos;
    11681248            } else {
    11691249                move_to_pos.x = qt_real_to_fixed(p2.x());
    11701250                move_to_pos.y = qt_real_to_fixed(p2.y());
    11711251            }
    1172 
    1173             idash = (idash + idash_incr) % dashCount;
    11741252        }
    11751253
Note: See TracChangeset for help on using the changeset viewer.