70 #include <private/qwidget_p.h> |
70 #include <private/qwidget_p.h> |
71 #include <private/qpaintengine_raster_p.h> |
71 #include <private/qpaintengine_raster_p.h> |
72 #include <private/qmath_p.h> |
72 #include <private/qmath_p.h> |
73 #include <qstatictext.h> |
73 #include <qstatictext.h> |
74 #include <private/qstatictext_p.h> |
74 #include <private/qstatictext_p.h> |
|
75 #include <private/qstylehelper_p.h> |
75 |
76 |
76 QT_BEGIN_NAMESPACE |
77 QT_BEGIN_NAMESPACE |
77 |
78 |
78 #define QGradient_StretchToDevice 0x10000000 |
79 #define QGradient_StretchToDevice 0x10000000 |
79 #define QPaintEngine_OpaqueBackground 0x40000000 |
80 #define QPaintEngine_OpaqueBackground 0x40000000 |
1871 // required for QPixmap::grabWidget() |
1871 // required for QPixmap::grabWidget() |
1872 if (d->original_device->devType() == QInternal::Widget) { |
1872 if (d->original_device->devType() == QInternal::Widget) { |
1873 QWidget *widget = static_cast<QWidget *>(d->original_device); |
1873 QWidget *widget = static_cast<QWidget *>(d->original_device); |
1874 initFrom(widget); |
1874 initFrom(widget); |
1875 } else { |
1875 } else { |
1876 d->state->layoutDirection = QApplication::layoutDirection(); |
1876 d->state->layoutDirection = Qt::LayoutDirectionAuto; |
1877 // make sure we have a font compatible with the paintdevice |
1877 // make sure we have a font compatible with the paintdevice |
1878 d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device()); |
1878 d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device()); |
1879 } |
1879 } |
1880 |
1880 |
1881 QRect systemRect = d->engine->systemRect(); |
1881 QRect systemRect = d->engine->systemRect(); |
5853 if (d->extended == 0 || !d->state->matrix.isAffine()) { |
5851 if (d->extended == 0 || !d->state->matrix.isAffine()) { |
5854 staticText_d->paintText(topLeftPosition, this); |
5852 staticText_d->paintText(topLeftPosition, this); |
5855 return; |
5853 return; |
5856 } |
5854 } |
5857 |
5855 |
|
5856 if (d->extended->type() == QPaintEngine::OpenGL2 && !staticText_d->untransformedCoordinates) { |
|
5857 staticText_d->untransformedCoordinates = true; |
|
5858 staticText_d->needsRelayout = true; |
|
5859 } else if (d->extended->type() != QPaintEngine::OpenGL2 && staticText_d->untransformedCoordinates) { |
|
5860 staticText_d->untransformedCoordinates = false; |
|
5861 staticText_d->needsRelayout = true; |
|
5862 } |
|
5863 |
5858 // Don't recalculate entire layout because of translation, rather add the dx and dy |
5864 // Don't recalculate entire layout because of translation, rather add the dx and dy |
5859 // into the position to move each text item the correct distance. |
5865 // into the position to move each text item the correct distance. |
5860 QPointF transformedPosition = topLeftPosition * d->state->matrix; |
5866 QPointF transformedPosition = topLeftPosition; |
5861 QTransform matrix = d->state->matrix; |
5867 if (!staticText_d->untransformedCoordinates) |
|
5868 transformedPosition = transformedPosition * d->state->matrix; |
|
5869 QTransform oldMatrix; |
5862 |
5870 |
5863 // The translation has been applied to transformedPosition. Remove translation |
5871 // The translation has been applied to transformedPosition. Remove translation |
5864 // component from matrix. |
5872 // component from matrix. |
5865 if (d->state->matrix.isTranslating()) { |
5873 if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) { |
5866 qreal m11 = d->state->matrix.m11(); |
5874 qreal m11 = d->state->matrix.m11(); |
5867 qreal m12 = d->state->matrix.m12(); |
5875 qreal m12 = d->state->matrix.m12(); |
5868 qreal m13 = d->state->matrix.m13(); |
5876 qreal m13 = d->state->matrix.m13(); |
5869 qreal m21 = d->state->matrix.m21(); |
5877 qreal m21 = d->state->matrix.m21(); |
5870 qreal m22 = d->state->matrix.m22(); |
5878 qreal m22 = d->state->matrix.m22(); |
5871 qreal m23 = d->state->matrix.m23(); |
5879 qreal m23 = d->state->matrix.m23(); |
5872 qreal m33 = d->state->matrix.m33(); |
5880 qreal m33 = d->state->matrix.m33(); |
5873 |
5881 |
|
5882 oldMatrix = d->state->matrix; |
5874 d->state->matrix.setMatrix(m11, m12, m13, |
5883 d->state->matrix.setMatrix(m11, m12, m13, |
5875 m21, m22, m23, |
5884 m21, m22, m23, |
5876 0.0, 0.0, m33); |
5885 0.0, 0.0, m33); |
5877 } |
5886 } |
5878 |
5887 |
5879 // If the transform is not identical to the text transform, |
5888 // If the transform is not identical to the text transform, |
5880 // we have to relayout the text (for other transformations than plain translation) |
5889 // we have to relayout the text (for other transformations than plain translation) |
5881 bool staticTextNeedsReinit = staticText_d->needsRelayout; |
5890 bool staticTextNeedsReinit = staticText_d->needsRelayout; |
5882 if (staticText_d->matrix != d->state->matrix) { |
5891 if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) { |
5883 staticText_d->matrix = d->state->matrix; |
5892 staticText_d->matrix = d->state->matrix; |
5884 staticTextNeedsReinit = true; |
5893 staticTextNeedsReinit = true; |
5885 } |
5894 } |
5886 |
5895 |
5887 // Recreate the layout of the static text because the matrix or font has changed |
5896 // Recreate the layout of the static text because the matrix or font has changed |
5934 |
5943 |
5935 Q_D(QPainter); |
5944 Q_D(QPainter); |
5936 |
5945 |
5937 if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen) |
5946 if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen) |
5938 return; |
5947 return; |
|
5948 |
|
5949 if (tf & Qt::TextBypassShaping) { |
|
5950 // Skip harfbuzz complex shaping, shape using glyph advances only |
|
5951 int len = str.length(); |
|
5952 int numGlyphs = len; |
|
5953 QVarLengthGlyphLayoutArray glyphs(len); |
|
5954 QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common); |
|
5955 if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) { |
|
5956 glyphs.resize(numGlyphs); |
|
5957 if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) |
|
5958 Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); |
|
5959 } |
|
5960 |
|
5961 QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine); |
|
5962 drawTextItem(p, gf); |
|
5963 return; |
|
5964 } |
5939 |
5965 |
5940 QStackTextEngine engine(str, d->state->font); |
5966 QStackTextEngine engine(str, d->state->font); |
5941 engine.option.setTextDirection(d->state->layoutDirection); |
5967 engine.option.setTextDirection(d->state->layoutDirection); |
5942 if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) { |
5968 if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) { |
5943 engine.ignoreBidi = true; |
5969 engine.ignoreBidi = true; |
6215 |
6241 |
6216 static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) |
6242 static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) |
6217 { |
6243 { |
6218 const qreal radiusBase = qMax(qreal(1), maxRadius); |
6244 const qreal radiusBase = qMax(qreal(1), maxRadius); |
6219 |
6245 |
6220 QString key = QLatin1String("WaveUnderline-"); |
6246 QString key = QLatin1Literal("WaveUnderline-") |
6221 key += pen.color().name(); |
6247 % pen.color().name() |
6222 key += QLatin1Char('-'); |
6248 % HexString<qreal>(radiusBase); |
6223 key += QString::number(radiusBase); |
|
6224 |
6249 |
6225 QPixmap pixmap; |
6250 QPixmap pixmap; |
6226 if (QPixmapCache::find(key, pixmap)) |
6251 if (QPixmapCache::find(key, pixmap)) |
6227 return pixmap; |
6252 return pixmap; |
6228 |
6253 |
8026 |
8051 |
8027 /*! |
8052 /*! |
8028 Sets the layout direction used by the painter when drawing text, |
8053 Sets the layout direction used by the painter when drawing text, |
8029 to the specified \a direction. |
8054 to the specified \a direction. |
8030 |
8055 |
8031 \sa layoutDirection(), drawText(), {QPainter#Settings}{Settings} |
8056 The default is Qt::LayoutDirectionAuto, which will implicitly determine the |
|
8057 direction from the text drawn. |
|
8058 |
|
8059 \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings} |
8032 */ |
8060 */ |
8033 void QPainter::setLayoutDirection(Qt::LayoutDirection direction) |
8061 void QPainter::setLayoutDirection(Qt::LayoutDirection direction) |
8034 { |
8062 { |
8035 Q_D(QPainter); |
8063 Q_D(QPainter); |
8036 if (d->state) |
8064 if (d->state) |
8038 } |
8066 } |
8039 |
8067 |
8040 /*! |
8068 /*! |
8041 Returns the layout direction used by the painter when drawing text. |
8069 Returns the layout direction used by the painter when drawing text. |
8042 |
8070 |
8043 \sa setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} |
8071 \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} |
8044 */ |
8072 */ |
8045 Qt::LayoutDirection QPainter::layoutDirection() const |
8073 Qt::LayoutDirection QPainter::layoutDirection() const |
8046 { |
8074 { |
8047 Q_D(const QPainter); |
8075 Q_D(const QPainter); |
8048 return d->state ? d->state->layoutDirection : Qt::LeftToRight; |
8076 return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto; |
8049 } |
8077 } |
8050 |
8078 |
8051 QPainterState::QPainterState(const QPainterState *s) |
8079 QPainterState::QPainterState(const QPainterState *s) |
8052 : brushOrigin(s->brushOrigin), font(s->font), deviceFont(s->deviceFont), |
8080 : brushOrigin(s->brushOrigin), font(s->font), deviceFont(s->deviceFont), |
8053 pen(s->pen), brush(s->brush), bgBrush(s->bgBrush), |
8081 pen(s->pen), brush(s->brush), bgBrush(s->bgBrush), |
8939 Q_D(QPainter); |
8967 Q_D(QPainter); |
8940 |
8968 |
8941 if (!d->engine) |
8969 if (!d->engine) |
8942 return; |
8970 return; |
8943 |
8971 |
|
8972 #ifndef QT_NO_DEBUG |
|
8973 for (int i = 0; i < fragmentCount; ++i) { |
|
8974 QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop, |
|
8975 fragments[i].width, fragments[i].height); |
|
8976 if (!(QRectF(pixmap.rect()).contains(sourceRect))) |
|
8977 qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle"); |
|
8978 } |
|
8979 #endif |
|
8980 |
8944 if (d->engine->isExtended()) { |
8981 if (d->engine->isExtended()) { |
8945 d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); |
8982 d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); |
8946 } else { |
8983 } else { |
8947 qreal oldOpacity = opacity(); |
8984 qreal oldOpacity = opacity(); |
8948 QTransform oldTransform = transform(); |
8985 QTransform oldTransform = transform(); |