diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-03-10 15:53:20 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-03-10 15:53:20 (GMT) |
commit | b80466364fe6c6ca030b884f2d8df94bdfa477b9 (patch) | |
tree | 3bceaf50ae806138525bd5977e693da6b58cf942 /src/gui | |
parent | 1e9552f826c05bf9884fb2893dedca265ead363b (diff) | |
parent | 9b016ce33e4d63725239945a2fcf19a8d6af14cf (diff) | |
download | Qt-b80466364fe6c6ca030b884f2d8df94bdfa477b9.zip Qt-b80466364fe6c6ca030b884f2d8df94bdfa477b9.tar.gz Qt-b80466364fe6c6ca030b884f2d8df94bdfa477b9.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
Re-enable tst_QGL::glWidgetRenderPixmap on X11/EGL
Added clipping to the dashed stroke processor in the GL2 engine.
Fixed assert failure when drawing dashes with raster engine.
Update tst_QGL::getSetCheck to check for new (correct) behaviour
Update QGLFormat from EGLConfig properly
Make calls to QGLFormat::set*BufferSize also update flags
Compile fix when Qt3Support is enabled for devices using EGL.
Cocoa: Fix misaligned text between format changes
Added configure check to diasable building QtDeclarative
Fixes Q3ListViewItem grandchildren not sorted if item has one child
Compile with Qt3Support in a ScratchBox environment.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 11 | ||||
-rw-r--r-- | src/gui/painting/qstroker.cpp | 116 | ||||
-rw-r--r-- | src/gui/text/qfontengine_mac.mm | 2 |
3 files changed, 100 insertions, 29 deletions
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index bfcf7db..03d0825 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1725,9 +1725,10 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) if (patternLength > 0) { int n = qFloor(dashOffset / patternLength); dashOffset -= n * patternLength; - while (dashOffset > pattern.at(dashIndex)) { + while (dashOffset >= pattern.at(dashIndex)) { dashOffset -= pattern.at(dashIndex); - dashIndex = (dashIndex + 1) % pattern.size(); + if (++dashIndex >= pattern.size()) + dashIndex = 0; inDash = !inDash; } } @@ -1738,7 +1739,6 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) const QLineF *lines = reinterpret_cast<const QLineF *>(path.points()); for (int i = 0; i < lineCount; ++i) { - dashOffset = s->lastPen.dashOffset(); if (lines[i].p1() == lines[i].p2()) { if (s->lastPen.capStyle() != Qt::FlatCap) { QPointF p = lines[i].p1(); @@ -3626,13 +3626,14 @@ void QRasterPaintEnginePrivate::rasterizeLine_dashed(QLineF line, } else { *dashOffset = 0; *inDash = !(*inDash); - *dashIndex = (*dashIndex + 1) % pattern.size(); + if (++*dashIndex >= pattern.size()) + *dashIndex = 0; length -= dash; l.setLength(dash); line.setP1(l.p2()); } - if (rasterize && dash != 0) + if (rasterize && dash > 0) rasterizer->rasterizeLine(l.p1(), l.p2(), width / dash, squareCap); } } diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 16e3c38..9740fce 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -1043,6 +1043,47 @@ QVector<qfixed> QDashStroker::patternForStyle(Qt::PenStyle style) return pattern; } +static inline bool lineRectIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) +{ + return ((p1.x > tl.x || p2.x > tl.x) && (p1.x < br.x || p2.x < br.x) + && (p1.y > tl.y || p2.y > tl.y) && (p1.y < br.y || p2.y < br.y)); +} + +// If the line intersects the rectangle, this function will return true. +static bool lineIntersectsRect(qfixed2d p1, qfixed2d p2, const qfixed2d &tl, const qfixed2d &br) +{ + if (!lineRectIntersectsRect(p1, p2, tl, br)) + return false; + if (p1.x == p2.x || p1.y == p2.y) + return true; + + if (p1.y > p2.y) + qSwap(p1, p2); // make p1 above p2 + qfixed2d u; + qfixed2d v; + qfixed2d w = {p2.x - p1.x, p2.y - p1.y}; + if (p1.x < p2.x) { + // backslash + u.x = tl.x - p1.x; u.y = br.y - p1.y; + v.x = br.x - p1.x; v.y = tl.y - p1.y; + } else { + // slash + u.x = tl.x - p1.x; u.y = tl.y - p1.y; + v.x = br.x - p1.x; v.y = br.y - p1.y; + } +#if defined(QFIXED_IS_26_6) || defined(QFIXED_IS_16_16) + qint64 val1 = qint64(u.x) * qint64(w.y) - qint64(u.y) * qint64(w.x); + qint64 val2 = qint64(v.x) * qint64(w.y) - qint64(v.y) * qint64(w.x); + return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); +#elif defined(QFIXED_IS_32_32) + // Cannot do proper test because it may overflow. + return true; +#else + qreal val1 = u.x * w.y - u.y * w.x; + qreal val2 = v.x * w.y - v.y * w.x; + return (val1 < 0 && val2 > 0) || (val1 > 0 && val2 < 0); +#endif +} void QDashStroker::processCurrentSubpath() { @@ -1067,9 +1108,11 @@ void QDashStroker::processCurrentSubpath() if (qFuzzyIsNull(sumLength)) return; + qreal invSumLength = qreal(1) / sumLength; + Q_ASSERT(dashCount > 0); - dashCount = (dashCount / 2) * 2; // Round down to even number + dashCount = dashCount & -2; // Round down to even number int idash = 0; // Index to current dash qreal pos = 0; // The position on the curve, 0 <= pos <= path.length @@ -1077,11 +1120,12 @@ void QDashStroker::processCurrentSubpath() qreal doffset = m_dashOffset * m_stroke_width; // make sure doffset is in range [0..sumLength) - doffset -= qFloor(doffset / sumLength) * sumLength; + doffset -= qFloor(doffset * invSumLength) * sumLength; while (doffset >= dashes[idash]) { doffset -= dashes[idash]; - idash = (idash + 1) % dashCount; + if (++idash >= dashCount) + idash = 0; } qreal estart = 0; // The elements starting position @@ -1119,12 +1163,41 @@ void QDashStroker::processCurrentSubpath() estop = estart + elen; bool done = pos >= estop; + + if (clipping) { + // Check if the entire line can be clipped away. + if (!lineIntersectsRect(prev, e, clip_tl, clip_br)) { + // Cut away full dash sequences. + elen -= qFloor(elen * invSumLength) * sumLength; + // Update dash offset. + while (!done) { + qreal dpos = pos + dashes[idash] - doffset - estart; + + Q_ASSERT(dpos >= 0); + + if (dpos > elen) { // dash extends this line + doffset = dashes[idash] - (dpos - elen); // subtract the part already used + pos = estop; // move pos to next path element + done = true; + } else { // Dash is on this line + pos = dpos + estart; + done = pos >= estop; + if (++idash >= dashCount) + idash = 0; + doffset = 0; // full segment so no offset on next. + } + } + hasMoveTo = false; + move_to_pos = e; + } + } + // Dash away... while (!done) { QPointF p2; - int idash_incr = 0; bool has_offset = doffset > 0; + bool evenDash = (idash & 1) == 0; qreal dpos = pos + dashes[idash] - doffset - estart; Q_ASSERT(dpos >= 0); @@ -1138,39 +1211,36 @@ void QDashStroker::processCurrentSubpath() p2 = cline.pointAt(dpos/elen); pos = dpos + estart; done = pos >= estop; - idash_incr = 1; + if (++idash >= dashCount) + idash = 0; doffset = 0; // full segment so no offset on next. } - if (idash % 2 == 0) { + if (evenDash) { line_to_pos.x = qt_real_to_fixed(p2.x()); line_to_pos.y = qt_real_to_fixed(p2.y()); - // If we have an offset, we're continuing a dash - // from a previous element and should only - // continue the current dash, without starting a - // new subpath. - if (!has_offset || !hasMoveTo) { - emitMoveTo(move_to_pos.x, move_to_pos.y); - hasMoveTo = true; - } - if (!clipping - // if move_to is inside... - || (move_to_pos.x > clip_tl.x && move_to_pos.x < clip_br.x - && move_to_pos.y > clip_tl.y && move_to_pos.y < clip_br.y) - // Or if line_to is inside... - || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x - && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y)) + || lineRectIntersectsRect(move_to_pos, line_to_pos, clip_tl, clip_br)) { + // If we have an offset, we're continuing a dash + // from a previous element and should only + // continue the current dash, without starting a + // new subpath. + if (!has_offset || !hasMoveTo) { + emitMoveTo(move_to_pos.x, move_to_pos.y); + hasMoveTo = true; + } + emitLineTo(line_to_pos.x, line_to_pos.y); + } else { + hasMoveTo = false; } + move_to_pos = line_to_pos; } else { move_to_pos.x = qt_real_to_fixed(p2.x()); move_to_pos.y = qt_real_to_fixed(p2.y()); } - - idash = (idash + idash_incr) % dashCount; } // Shuffle to the next cycle... diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 48bc635..8588214 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -308,7 +308,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; - outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width).ceil(); + outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width); } outGlyphs += glyphCount; outAttributes += glyphCount; |