--- a/src/gui/painting/qpainter.cpp Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/painting/qpainter.cpp Wed Aug 18 10:37:55 2010 +0300
@@ -72,6 +72,7 @@
#include <private/qmath_p.h>
#include <qstatictext.h>
#include <private/qstatictext_p.h>
+#include <private/qstylehelper_p.h>
QT_BEGIN_NAMESPACE
@@ -1563,7 +1564,6 @@
d->engine->setDirty(QPaintEngine::DirtyBrush);
d->engine->setDirty(QPaintEngine::DirtyFont);
}
- d->state->layoutDirection = widget->layoutDirection();
}
@@ -1873,7 +1873,7 @@
QWidget *widget = static_cast<QWidget *>(d->original_device);
initFrom(widget);
} else {
- d->state->layoutDirection = QApplication::layoutDirection();
+ d->state->layoutDirection = Qt::LayoutDirectionAuto;
// make sure we have a font compatible with the paintdevice
d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device());
}
@@ -2391,6 +2391,8 @@
qWarning("QPainter::setCompositionMode: Painter not active");
return;
}
+ if (d->state->composition_mode == mode)
+ return;
if (d->extended) {
d->state->composition_mode = mode;
d->extended->compositionModeChanged();
@@ -4238,8 +4240,6 @@
return;
QRectF rect(r.normalized());
- if (rect.isEmpty())
- return;
if (d->extended) {
d->extended->drawEllipse(rect);
@@ -4281,8 +4281,6 @@
return;
QRect rect(r.normalized());
- if (rect.isEmpty())
- return;
if (d->extended) {
d->extended->drawEllipse(rect);
@@ -5855,14 +5853,24 @@
return;
}
+ if (d->extended->type() == QPaintEngine::OpenGL2 && !staticText_d->untransformedCoordinates) {
+ staticText_d->untransformedCoordinates = true;
+ staticText_d->needsRelayout = true;
+ } else if (d->extended->type() != QPaintEngine::OpenGL2 && staticText_d->untransformedCoordinates) {
+ staticText_d->untransformedCoordinates = false;
+ staticText_d->needsRelayout = true;
+ }
+
// Don't recalculate entire layout because of translation, rather add the dx and dy
// into the position to move each text item the correct distance.
- QPointF transformedPosition = topLeftPosition * d->state->matrix;
- QTransform matrix = d->state->matrix;
+ QPointF transformedPosition = topLeftPosition;
+ if (!staticText_d->untransformedCoordinates)
+ transformedPosition = transformedPosition * d->state->matrix;
+ QTransform oldMatrix;
// The translation has been applied to transformedPosition. Remove translation
// component from matrix.
- if (d->state->matrix.isTranslating()) {
+ if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) {
qreal m11 = d->state->matrix.m11();
qreal m12 = d->state->matrix.m12();
qreal m13 = d->state->matrix.m13();
@@ -5871,6 +5879,7 @@
qreal m23 = d->state->matrix.m23();
qreal m33 = d->state->matrix.m33();
+ oldMatrix = d->state->matrix;
d->state->matrix.setMatrix(m11, m12, m13,
m21, m22, m23,
0.0, 0.0, m33);
@@ -5879,7 +5888,7 @@
// If the transform is not identical to the text transform,
// we have to relayout the text (for other transformations than plain translation)
bool staticTextNeedsReinit = staticText_d->needsRelayout;
- if (staticText_d->matrix != d->state->matrix) {
+ if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) {
staticText_d->matrix = d->state->matrix;
staticTextNeedsReinit = true;
}
@@ -5918,8 +5927,8 @@
if (currentColor != oldPen.color())
setPen(oldPen);
- if (matrix.isTranslating())
- d->state->matrix = matrix;
+ if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating())
+ d->state->matrix = oldMatrix;
}
/*!
@@ -5937,6 +5946,23 @@
if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen)
return;
+ if (tf & Qt::TextBypassShaping) {
+ // Skip harfbuzz complex shaping, shape using glyph advances only
+ int len = str.length();
+ int numGlyphs = len;
+ QVarLengthGlyphLayoutArray glyphs(len);
+ QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common);
+ if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) {
+ glyphs.resize(numGlyphs);
+ if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
+ Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
+ }
+
+ QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine);
+ drawTextItem(p, gf);
+ return;
+ }
+
QStackTextEngine engine(str, d->state->font);
engine.option.setTextDirection(d->state->layoutDirection);
if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) {
@@ -6217,10 +6243,9 @@
{
const qreal radiusBase = qMax(qreal(1), maxRadius);
- QString key = QLatin1String("WaveUnderline-");
- key += pen.color().name();
- key += QLatin1Char('-');
- key += QString::number(radiusBase);
+ QString key = QLatin1Literal("WaveUnderline-")
+ % pen.color().name()
+ % HexString<qreal>(radiusBase);
QPixmap pixmap;
if (QPixmapCache::find(key, pixmap))
@@ -8028,7 +8053,10 @@
Sets the layout direction used by the painter when drawing text,
to the specified \a direction.
- \sa layoutDirection(), drawText(), {QPainter#Settings}{Settings}
+ The default is Qt::LayoutDirectionAuto, which will implicitly determine the
+ direction from the text drawn.
+
+ \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings}
*/
void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
{
@@ -8040,12 +8068,12 @@
/*!
Returns the layout direction used by the painter when drawing text.
- \sa setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}
+ \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}
*/
Qt::LayoutDirection QPainter::layoutDirection() const
{
Q_D(const QPainter);
- return d->state ? d->state->layoutDirection : Qt::LeftToRight;
+ return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto;
}
QPainterState::QPainterState(const QPainterState *s)
@@ -8941,6 +8969,15 @@
if (!d->engine)
return;
+#ifndef QT_NO_DEBUG
+ for (int i = 0; i < fragmentCount; ++i) {
+ QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
+ fragments[i].width, fragments[i].height);
+ if (!(QRectF(pixmap.rect()).contains(sourceRect)))
+ qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle");
+ }
+#endif
+
if (d->engine->isExtended()) {
d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
} else {