diff options
author | Gunnar Sletta <gunnar@trolltech.com> | 2009-12-09 06:24:35 (GMT) |
---|---|---|
committer | Gunnar Sletta <gunnar@trolltech.com> | 2009-12-09 06:24:35 (GMT) |
commit | 32b45ba08745fdcedf6b3537a9f62cd23a5eb1ba (patch) | |
tree | 6a33a5221b2f37dfa9782739b0b456cd7496a10b /src/gui/painting | |
parent | 120a12f5dc13dea327cdbbbc94b58f29d1f3306b (diff) | |
parent | f59908d4a6edcd333a156d4c94ddbd9b30f7e810 (diff) | |
download | Qt-32b45ba08745fdcedf6b3537a9f62cd23a5eb1ba.zip Qt-32b45ba08745fdcedf6b3537a9f62cd23a5eb1ba.tar.gz Qt-32b45ba08745fdcedf6b3537a9f62cd23a5eb1ba.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.6
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qpaintdevice.qdoc | 2 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 96 |
2 files changed, 63 insertions, 35 deletions
diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc index ac1c3de..e923e90 100644 --- a/src/gui/painting/qpaintdevice.qdoc +++ b/src/gui/painting/qpaintdevice.qdoc @@ -82,7 +82,7 @@ horizontal and vertical resolution of the device in dots per inch. The physicalDpiX() and physicalDpiY() functions also return the resolution of the device in dots per inch, but note that if - the logical and vertical resolution differ, the corresponding + the logical and physical resolution differ, the corresponding QPaintEngine must handle the mapping. Finally, the colorCount() function returns the number of different colors available for the paint device. diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 48629d1..66bf4f7 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -284,7 +284,7 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) // Update matrix. if (q->d_ptr->state->WxF) { - q->d_ptr->state->redirectionMatrix *= q->d_ptr->state->worldMatrix; + q->d_ptr->state->redirectionMatrix = q->d_ptr->state->matrix; q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y()); q->d_ptr->state->worldMatrix = QTransform(); q->d_ptr->state->WxF = false; @@ -5886,7 +5886,12 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption Draws the text item \a ti at position \a p. */ -/*! \internal +/*! + \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti) + + \internal + \since 4.1 + Draws the text item \a ti at position \a p. This method ignores the painters background mode and @@ -5899,34 +5904,57 @@ void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption ignored aswell. You'll need to pass in the correct flags to get underlining and strikeout. */ -static QPainterPath generateWavyPath(qreal minWidth, qreal maxRadius, QPaintDevice *device) + +static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) { - extern int qt_defaultDpi(); + const qreal radiusBase = qMax(qreal(1), maxRadius); + + QString key = QLatin1String("WaveUnderline-"); + key += pen.color().name(); + key += QLatin1Char('-'); + key += QString::number(radiusBase); + + QPixmap pixmap; + if (QPixmapCache::find(key, pixmap)) + return pixmap; + + const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio + const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod); + const int radius = qFloor(radiusBase); + QPainterPath path; - bool up = true; - const qreal radius = qMax(qreal(.5), qMin(qreal(1.25 * device->logicalDpiY() / qt_defaultDpi()), maxRadius)); - qreal xs, ys; - int i = 0; - path.moveTo(0, radius); - do { - xs = i*(2*radius); - ys = 0; + qreal xs = 0; + qreal ys = radius; - qreal remaining = minWidth - xs; - qreal angle = 180; + while (xs < width) { + xs += halfPeriod; + ys = -ys; + path.quadTo(xs - halfPeriod / 2, ys, xs, 0); + } - // cut-off at the last arc segment - if (remaining < 2 * radius) - angle = 180 * remaining / (2 * radius); + pixmap = QPixmap(width, radius * 2); + pixmap.fill(Qt::transparent); + { + QPen wavePen = pen; + wavePen.setCapStyle(Qt::SquareCap); + + // This is to protect against making the line too fat, as happens on Mac OS X + // due to it having a rather thick width for the regular underline. + const qreal maxPenWidth = .8 * radius; + if (wavePen.widthF() > maxPenWidth) + wavePen.setWidth(maxPenWidth); - path.arcTo(xs, ys, 2*radius, 2*radius, 180, up ? angle : -angle); + QPainter imgPainter(&pixmap); + imgPainter.setPen(wavePen); + imgPainter.setRenderHint(QPainter::Antialiasing); + imgPainter.translate(0, radius); + imgPainter.drawPath(path); + } - up = !up; - ++i; - } while (xs + 2*radius < minWidth); + QPixmapCache::insert(key, pixmap); - return path; + return pixmap; } static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) @@ -5947,9 +5975,11 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setCapStyle(Qt::FlatCap); QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y()); + + const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(fe->underlinePosition().toReal()); + const qreal underlinePos = pos.y() + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); @@ -5957,16 +5987,18 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const if (underlineStyle == QTextCharFormat::WaveUnderline) { painter->save(); - painter->setRenderHint(QPainter::Antialiasing); - painter->translate(pos.x(), underlinePos); + painter->translate(0, pos.y() + 1); QColor uc = ti.charFormat.underlineColor(); if (uc.isValid()) - painter->setPen(uc); + pen.setColor(uc); - painter->drawPath(generateWavyPath(ti.width.toReal(), - fe->underlinePosition().toReal(), - painter->device())); + // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms + const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen); + const int descent = (int) ti.descent.toReal(); + + painter->setBrushOrigin(painter->brushOrigin().x(), 0); + painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); @@ -6001,10 +6033,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } -/*! - \internal - \since 4.1 -*/ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW @@ -7602,7 +7630,7 @@ start_lengthVariant: // in the paint engines when drawing on floating point offsets const qreal scale = painter->transform().m22(); if (scale != 0) - yoff = qRound(yoff * scale) / scale; + yoff = -qRound(-yoff * scale) / scale; } } } |