src/gui/painting/qpainter.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
--- 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 {