Direct2D QPA: Fix paint engine state handling

Fix the paint handling to support QPaintEngineEx style state updates. This
fixes most of the outstanding issues, as QPainter save and restore were
essentially broken before

Change-Id: I477d8acfd71bba32dfac4c491bc5bbaad1804ec5
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Risto Avila <risto.avila@digia.com>
Reviewed-by: Andrew Knight <andrew.knight@digia.com>
This commit is contained in:
Louai Al-Khanji 2014-04-23 15:30:58 +03:00 committed by The Qt Project
parent 5611b66c90
commit 1467b63b06
2 changed files with 57 additions and 13 deletions

View File

@ -495,7 +495,7 @@ public:
{
Q_Q(const QWindowsDirect2DPaintEngine);
if (qbrush_fast_equals(brush.qbrush, newBrush))
if (qbrush_fast_equals(brush.qbrush, newBrush) && (brush.brush || brush.emulate))
return;
brush.brush = to_d2d_brush(newBrush, &brush.emulate);
@ -540,12 +540,10 @@ public:
currentBrushOrigin = origin;
}
void updatePen()
void updatePen(const QPen &newPen)
{
Q_Q(const QWindowsDirect2DPaintEngine);
const QPen &newPen = q->state()->pen;
if (qpen_fast_equals(newPen, pen.qpen))
if (qpen_fast_equals(newPen, pen.qpen) && (pen.brush || pen.emulate))
return;
pen.reset();
@ -909,6 +907,23 @@ QPaintEngine::Type QWindowsDirect2DPaintEngine::type() const
return QPaintEngine::Direct2D;
}
void QWindowsDirect2DPaintEngine::setState(QPainterState *s)
{
Q_D(QWindowsDirect2DPaintEngine);
QPaintEngineEx::setState(s);
d->clearClips();
clipEnabledChanged();
penChanged();
brushChanged();
brushOriginChanged();
opacityChanged();
compositionModeChanged();
renderHintsChanged();
transformChanged();
}
void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
{
Q_D(QWindowsDirect2DPaintEngine);
@ -917,7 +932,7 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
if (path.isEmpty())
return;
d->updateBrush(brush);
ensureBrush(brush);
if (d->brush.emulate) {
// We mostly (only?) get here when gradients are required.
@ -981,7 +996,7 @@ void QWindowsDirect2DPaintEngine::clipEnabledChanged()
void QWindowsDirect2DPaintEngine::penChanged()
{
Q_D(QWindowsDirect2DPaintEngine);
d->updatePen();
d->updatePen(state()->pen);
}
void QWindowsDirect2DPaintEngine::brushChanged()
@ -1051,6 +1066,8 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle());
QWindowsDirect2DBitmap *bitmap = pp->bitmap();
ensurePen();
if (bitmap->bitmap() != d->bitmap->bitmap()) {
// Good, src bitmap != dst bitmap
if (sr.isValid())
@ -1149,12 +1166,11 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText
Q_D(QWindowsDirect2DPaintEngine);
D2D_TAG(D2DDebugDrawStaticTextItemTag);
if (qpen_style(d->pen.qpen) == Qt::NoPen && qbrush_style(d->brush.qbrush) == Qt::NoBrush)
return;
if (staticTextItem->numGlyphs == 0)
return;
ensurePen();
// If we can't support the current configuration with Direct2D, fall back to slow path
// Most common cases are perspective transform and gradient brush as pen
if ((state()->transform().isAffine() == false) || d->pen.emulate) {
@ -1199,13 +1215,12 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
Q_D(QWindowsDirect2DPaintEngine);
D2D_TAG(D2DDebugDrawTextItemTag);
if (qpen_style(d->pen.qpen) == Qt::NoPen && qbrush_style(d->brush.qbrush) == Qt::NoBrush)
return;
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
if (ti.glyphs.numGlyphs == 0)
return;
ensurePen();
// If we can't support the current configuration with Direct2D, fall back to slow path
// Most common cases are perspective transform and gradient brush as pen
if ((state()->transform().isAffine() == false) || d->pen.emulate) {
@ -1307,4 +1322,26 @@ void QWindowsDirect2DPaintEngine::drawGlyphRun(const D2D1_POINT_2F &pos,
DWRITE_MEASURING_MODE_GDI_CLASSIC);
}
void QWindowsDirect2DPaintEngine::ensureBrush()
{
ensureBrush(state()->brush);
}
void QWindowsDirect2DPaintEngine::ensureBrush(const QBrush &brush)
{
Q_D(QWindowsDirect2DPaintEngine);
d->updateBrush(brush);
}
void QWindowsDirect2DPaintEngine::ensurePen()
{
ensurePen(state()->pen);
}
void QWindowsDirect2DPaintEngine::ensurePen(const QPen &pen)
{
Q_D(QWindowsDirect2DPaintEngine);
d->updatePen(pen);
}
QT_END_NAMESPACE

View File

@ -65,6 +65,8 @@ public:
Type type() const Q_DECL_OVERRIDE;
void setState(QPainterState *s) Q_DECL_OVERRIDE;
void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
@ -87,6 +89,11 @@ private:
void drawGlyphRun(const D2D1_POINT_2F &pos, IDWriteFontFace *fontFace, const QFont &font,
int numGlyphs, const UINT16 *glyphIndices, const FLOAT *glyphAdvances,
const DWRITE_GLYPH_OFFSET *glyphOffsets, bool rtl);
void ensureBrush();
void ensureBrush(const QBrush &brush);
void ensurePen();
void ensurePen(const QPen &pen);
};
QT_END_NAMESPACE