diff options
author | David Boddie <dboddie@trolltech.com> | 2009-12-04 16:00:13 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2009-12-04 16:00:13 (GMT) |
commit | 0ec20e4fdd70dc11df5932ea2c282efce21dee15 (patch) | |
tree | 7387b1db111bb0930e6e01c0b405112a0b317343 /src/gui/painting | |
parent | 8577da4a70be7400b1dc7d2265a31de46f8e8bb9 (diff) | |
parent | 33441e2a611f07207b0b942368aab9010cdf8ab1 (diff) | |
download | Qt-0ec20e4fdd70dc11df5932ea2c282efce21dee15.zip Qt-0ec20e4fdd70dc11df5932ea2c282efce21dee15.tar.gz Qt-0ec20e4fdd70dc11df5932ea2c282efce21dee15.tar.bz2 |
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.6
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qbackingstore.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 3 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 16 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 92 | ||||
-rw-r--r-- | src/gui/painting/qprintengine_pdf.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qvectorpath_p.h | 13 |
6 files changed, 88 insertions, 40 deletions
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8226797..1b8f413 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -949,6 +949,8 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; QWidgetBackingStore *wbs = x->backingStore; + if (!wbs) + return; static int accelEnv = -1; if (accelEnv == -1) { diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3f33319..4a72434 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3240,7 +3240,8 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte drawCached = false; // don't try to cache huge fonts - if (ti.fontEngine->fontDef.pixelSize * qSqrt(s->matrix.determinant()) >= 64) + const qreal pixelSize = ti.fontEngine->fontDef.pixelSize; + if (pixelSize * pixelSize * qAbs(s->matrix.determinant()) >= 64 * 64) drawCached = false; // ### Remove the TestFontEngine and Box engine crap, in these diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 7d1c109..9a0e319 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -56,6 +56,20 @@ QT_BEGIN_NAMESPACE * class QVectorPath * */ +QVectorPath::~QVectorPath() +{ + if (m_hints & ShouldUseCacheHint) { + CacheEntry *e = m_cache; + while (e) { + if (e->data) + e->cleanup(e->engine, e->data); + CacheEntry *n = e->next; + delete e; + e = n; + } + } +} + QRectF QVectorPath::controlPointRect() const { @@ -94,7 +108,7 @@ QRectF QVectorPath::controlPointRect() const QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data, - qvectorpath_cache_cleanup cleanup) { + qvectorpath_cache_cleanup cleanup) const{ Q_ASSERT(!lookupCacheData(engine)); if ((m_hints & IsCachedHint) == 0) { m_cache = 0; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 48629d1..443c9c5 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -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 diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp index 4cccc91..3d82edf 100644 --- a/src/gui/painting/qprintengine_pdf.cpp +++ b/src/gui/painting/qprintengine_pdf.cpp @@ -206,7 +206,7 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q QRect sourceRect = sr.toRect(); QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image; bool bitmap = true; - const int object = d->addImage(image, &bitmap, im.cacheKey()); + const int object = d->addImage(im, &bitmap, im.cacheKey()); if (object < 0) return; diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index ec27970..5eaddf4 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -68,7 +68,7 @@ QT_MODULE(Gui) class QPaintEngineEx; -typedef void (*qvectorpath_cache_cleanup)(void *data); +typedef void (*qvectorpath_cache_cleanup)(QPaintEngineEx *engine, void *data); struct QRealRect { qreal x1, y1, x2, y2; @@ -118,6 +118,8 @@ public: { } + ~QVectorPath(); + QRectF controlPointRect() const; inline Hint shape() const { return (Hint) (m_hints & ShapeMask); } @@ -128,6 +130,7 @@ public: inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } inline bool hasWindingFill() const { return m_hints & WindingFill; } + inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; } inline uint hints() const { return m_hints; } inline const QPainterPath::ElementType *elements() const { return m_elements; } @@ -146,9 +149,9 @@ public: CacheEntry *next; }; - CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup); + CacheEntry *addCacheData(QPaintEngineEx *engine, void *data, qvectorpath_cache_cleanup cleanup) const; inline CacheEntry *lookupCacheData(QPaintEngineEx *engine) const { - Q_ASSERT(m_hints & IsCachedHint); + Q_ASSERT(m_hints & ShouldUseCacheHint); CacheEntry *e = m_cache; while (e) { if (e->engine == engine) @@ -162,14 +165,14 @@ public: private: Q_DISABLE_COPY(QVectorPath) - CacheEntry *m_cache; - const QPainterPath::ElementType *m_elements; const qreal *m_points; const int m_count; mutable uint m_hints; mutable QRealRect m_cp_rect; + + mutable CacheEntry *m_cache; }; Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &path); |