summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
authorDavid Boddie <dboddie@trolltech.com>2010-08-13 12:10:00 (GMT)
committerDavid Boddie <dboddie@trolltech.com>2010-08-13 12:10:00 (GMT)
commit9878c1765332d9a68a8371b90888fe09e272c7a8 (patch)
treea67a7a28f6737b17498a76bcc40d5ffd65e81572 /src/gui/painting
parent7d805a6717692b540c02b8caace25a0b47c7f0d6 (diff)
parentb52da4ab2179079a6aff95891786d2f6598048b5 (diff)
downloadQt-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.h140
-rw-r--r--src/gui/painting/qgraphicssystem_runtime.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp84
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;