diff options
author | David Boddie <dboddie@trolltech.com> | 2010-08-13 12:10:00 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2010-08-13 12:10:00 (GMT) |
commit | 9878c1765332d9a68a8371b90888fe09e272c7a8 (patch) | |
tree | a67a7a28f6737b17498a76bcc40d5ffd65e81572 /src/gui/painting | |
parent | 7d805a6717692b540c02b8caace25a0b47c7f0d6 (diff) | |
parent | b52da4ab2179079a6aff95891786d2f6598048b5 (diff) | |
download | Qt-9878c1765332d9a68a8371b90888fe09e272c7a8.zip Qt-9878c1765332d9a68a8371b90888fe09e272c7a8.tar.gz Qt-9878c1765332d9a68a8371b90888fe09e272c7a8.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7
Conflicts:
doc/src/examples/simpletreemodel.qdoc
doc/src/examples/spinboxdelegate.qdoc
doc/src/index.qdoc
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qdrawhelper_p.h | 140 | ||||
-rw-r--r-- | src/gui/painting/qgraphicssystem_runtime.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 84 |
3 files changed, 141 insertions, 87 deletions
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 1a87127..d04c70d 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -314,18 +314,61 @@ struct QSpanData void adjustSpanMethods(); }; +#if defined(Q_CC_RVCT) +# pragma push +# pragma arm +#endif +Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { + uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; + t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; + t &= 0xff00ff; -Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) { - a += 1; - uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0; - t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f; - return t; + x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; + x = (x + ((x >> 8) & 0xff00ff) + 0x800080); + x &= 0xff00ff00; + x |= t; + return x; } +#if defined(Q_CC_RVCT) +# pragma pop +#endif -Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) { - uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0; - t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f; - return t; +#if QT_POINTER_SIZE == 8 // 64-bit versions + +Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t += (((quint64(y)) | ((quint64(y)) << 24)) & 0x00ff00ff00ff00ff) * b; + t >>= 8; + t &= 0x00ff00ff00ff00ff; + return (uint(t)) | (uint(t >> 24)); +} + +Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) { + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; + t &= 0x00ff00ff00ff00ff; + return (uint(t)) | (uint(t >> 24)); +} + +Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { + uint a = x >> 24; + quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a; + t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8; + t &= 0x000000ff00ff00ff; + return (uint(t)) | (uint(t >> 24)) | (a << 24); +} + +#else // 32-bit versions + +Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { + uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; + t >>= 8; + t &= 0xff00ff; + + x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; + x &= 0xff00ff00; + x |= t; + return x; } #if defined(Q_CC_RVCT) @@ -359,6 +402,21 @@ Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { x |= t | (a << 24); return x; } +#endif + + +Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16(uint x, uint a) { + a += 1; + uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0; + t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f; + return t; +} + +Q_STATIC_INLINE_FUNCTION uint BYTE_MUL_RGB16_32(uint x, uint a) { + uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0; + t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f; + return t; +} #define INV_PREMUL(p) \ (qAlpha(p) == 0 ? 0 : \ @@ -1847,70 +1905,6 @@ inline int qBlue565(quint16 rgb) { return (b << 3) | (b >> 2); } -#if 1 -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { - uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; - t >>= 8; - t &= 0xff00ff; - - x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; - x &= 0xff00ff00; - x |= t; - return x; -} - -#if defined(Q_CC_RVCT) -# pragma push -# pragma arm -#endif -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { - uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b; - t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8; - t &= 0xff00ff; - - x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b; - x = (x + ((x >> 8) & 0xff00ff) + 0x800080); - x &= 0xff00ff00; - x |= t; - return x; -} -#if defined(Q_CC_RVCT) -# pragma pop -#endif -#else -// possible implementation for 64 bit -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) { - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b; - t >>= 8; - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)); -} - -Q_STATIC_INLINE_FUNCTION uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b) { - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t += (((ulong(y)) | ((ulong(y)) << 24)) & 0x00ff00ff00ff00ff) * b; - t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080); - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)); -} - -Q_STATIC_INLINE_FUNCTION uint BYTE_MUL(uint x, uint a) { - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080); - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)); -} - -Q_STATIC_INLINE_FUNCTION uint PREMUL(uint x) { - uint a = x >> 24; - ulong t = (((ulong(x)) | ((ulong(x)) << 24)) & 0x00ff00ff00ff00ff) * a; - t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080); - t &= 0x00ff00ff00ff00ff; - return (uint(t)) | (uint(t >> 24)) | 0xff000000; -} -#endif - const uint qt_bayer_matrix[16][16] = { { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc, 0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff}, diff --git a/src/gui/painting/qgraphicssystem_runtime.cpp b/src/gui/painting/qgraphicssystem_runtime.cpp index e1e0ad0..2828e9d 100644 --- a/src/gui/painting/qgraphicssystem_runtime.cpp +++ b/src/gui/painting/qgraphicssystem_runtime.cpp @@ -366,7 +366,7 @@ void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name) #ifdef QT_DEBUG qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )"; #endif - delete m_graphicsSystem; + QGraphicsSystem *oldSystem = m_graphicsSystem; m_graphicsSystem = QGraphicsSystemFactory::create(name); m_graphicsSystemName = name; @@ -393,6 +393,8 @@ void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name) proxy->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget)); qt_widget_private(widget)->invalidateBuffer(widget->rect()); } + + delete oldSystem; } void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9dadbd5..b694d9c 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -90,6 +90,15 @@ void qt_format_text(const QFont &font, const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect, int tabstops, int* tabarray, int tabarraylen, QPainter *painter); +static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, + QTextCharFormat::UnderlineStyle underlineStyle, + const QTextItem::RenderFlags flags, qreal width, + const QTextCharFormat &charFormat); +// Helper function to calculate left most position, width and flags for decoration drawing +static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat); static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush) { @@ -5923,6 +5932,10 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText currentColor = item->color; } d->extended->drawStaticTextItem(item); + + drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions, + item->numGlyphs, item->fontEngine, staticText_d->font, + QTextCharFormat()); } if (currentColor != oldPen.color()) setPen(oldPen); @@ -6290,15 +6303,15 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) return pixmap; } -static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItemInt &ti) +static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, + QTextCharFormat::UnderlineStyle underlineStyle, + const QTextItem::RenderFlags flags, qreal width, + const QTextCharFormat &charFormat) { - QTextCharFormat::UnderlineStyle underlineStyle = ti.underlineStyle; if (underlineStyle == QTextCharFormat::NoUnderline - && !(ti.flags & (QTextItem::StrikeOut | QTextItem::Overline))) + && !(flags & (QTextItem::StrikeOut | QTextItem::Overline))) return; - QFontEngine *fe = ti.fontEngine; - const QPen oldPen = painter->pen(); const QBrush oldBrush = painter->brush(); painter->setBrush(Qt::NoBrush); @@ -6307,7 +6320,7 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setWidthF(fe->lineThickness().toReal()); pen.setCapStyle(Qt::FlatCap); - QLineF line(pos.x(), pos.y(), pos.x() + ti.width.toReal(), pos.y()); + QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y()); const qreal underlineOffset = fe->underlinePosition().toReal(); // deliberately ceil the offset to avoid the underline coming too close to @@ -6322,21 +6335,21 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->save(); painter->translate(0, pos.y() + 1); - QColor uc = ti.charFormat.underlineColor(); + QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); // 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(); + const int descent = (int) fe->descent().toReal(); painter->setBrushOrigin(painter->brushOrigin().x(), 0); - painter->fillRect(pos.x(), 0, qCeil(ti.width.toReal()), qMin(wave.height(), descent), wave); + painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); painter->restore(); } else if (underlineStyle != QTextCharFormat::NoUnderline) { QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos); - QColor uc = ti.charFormat.underlineColor(); + QColor uc = charFormat.underlineColor(); if (uc.isValid()) pen.setColor(uc); @@ -6348,14 +6361,14 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const pen.setStyle(Qt::SolidLine); pen.setColor(oldPen.color()); - if (ti.flags & QTextItem::StrikeOut) { + if (flags & QTextItem::StrikeOut) { QLineF strikeOutLine = line; strikeOutLine.translate(0., - fe->ascent().toReal() / 3.); painter->setPen(pen); painter->drawLine(strikeOutLine); } - if (ti.flags & QTextItem::Overline) { + if (flags & QTextItem::Overline) { QLineF overLine = line; overLine.translate(0., - fe->ascent().toReal()); painter->setPen(pen); @@ -6366,6 +6379,50 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } +static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat) +{ + if (!(font.underline() || font.strikeOut() || font.overline())) + return; + + QFixed leftMost; + QFixed rightMost; + QFixed baseLine; + for (int i=0; i<glyphCount; ++i) { + glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]); + if (i == 0 || leftMost > positions[i].x) + leftMost = positions[i].x; + + // We don't support glyphs that do not share a common baseline. If this turns out to + // be a relevant use case, then we need to find clusters of glyphs that share a baseline + // and do a drawTextItemDecorations call per cluster. + if (i == 0 || baseLine < positions[i].y) + baseLine = positions[i].y; + + // We use the advance rather than the actual bounds to match the algorithm in drawText() + if (i == 0 || rightMost < positions[i].x + gm.xoff) + rightMost = positions[i].x + gm.xoff; + } + + QFixed width = rightMost - leftMost; + QTextItem::RenderFlags flags = 0; + + if (font.underline()) + flags |= QTextItem::Underline; + if (font.overline()) + flags |= QTextItem::Overline; + if (font.strikeOut()) + flags |= QTextItem::StrikeOut; + + drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()), + fontEngine, + font.underline() ? QTextCharFormat::SingleUnderline + : QTextCharFormat::NoUnderline, flags, + width.toReal(), charFormat); +} + void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) { #ifdef QT_DEBUG_DRAW @@ -6496,7 +6553,8 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) else d->engine->drawTextItem(p, ti); } - drawTextItemDecoration(this, p, ti); + drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(), + ti.charFormat); if (d->state->renderHints != oldRenderHints) { d->state->renderHints = oldRenderHints; |