Direct2D QPA: Stroke using direct2d primitives
Use native direct2d stroking instead of falling back to QPaintEngineEx::stroke which in turn calls the pure virtual QPaintEngineEx::fill which is reimplemented in QWindowsDirect2DPaintEngine. In some cases like arc stroking this is significantly faster (up to 3x in my measurements) and results in better visual quality. Change-Id: I1c86ff772ba591432ff6550c7c59704ace4f0e0f Reviewed-by: Risto Avila <risto.avila@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
parent
35766fbe47
commit
58caefa13e
@ -934,6 +934,33 @@ void QWindowsDirect2DPaintEngine::setState(QPainterState *s)
|
||||
transformChanged();
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::draw(const QVectorPath &path)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
|
||||
ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
if (!geometry) {
|
||||
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
const QBrush &brush = state()->brush;
|
||||
if (qbrush_style(brush) != Qt::NoBrush) {
|
||||
if (emulationRequired(BrushEmulation))
|
||||
rasterFill(path, brush);
|
||||
else
|
||||
fill(geometry.Get(), brush);
|
||||
}
|
||||
|
||||
const QPen &pen = state()->pen;
|
||||
if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush) {
|
||||
if (emulationRequired(PenEmulation))
|
||||
QPaintEngineEx::stroke(path, pen);
|
||||
else
|
||||
stroke(geometry.Get(), pen);
|
||||
}
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
@ -943,7 +970,6 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
|
||||
return;
|
||||
|
||||
ensureBrush(brush);
|
||||
|
||||
if (emulationRequired(BrushEmulation)) {
|
||||
rasterFill(path, brush);
|
||||
return;
|
||||
@ -961,6 +987,56 @@ void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &br
|
||||
d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get());
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::fill(ID2D1Geometry *geometry, const QBrush &brush)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
D2D_TAG(D2DDebugFillTag);
|
||||
|
||||
ensureBrush(brush);
|
||||
if (!d->brush.brush)
|
||||
return;
|
||||
|
||||
d->dc()->FillGeometry(geometry, d->brush.brush.Get());
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
D2D_TAG(D2DDebugFillTag);
|
||||
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
ensurePen(pen);
|
||||
if (emulationRequired(PenEmulation)) {
|
||||
QPaintEngineEx::stroke(path, pen);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!d->pen.brush)
|
||||
return;
|
||||
|
||||
ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
if (!geometry) {
|
||||
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
d->dc()->DrawGeometry(geometry.Get(), d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::stroke(ID2D1Geometry *geometry, const QPen &pen)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
D2D_TAG(D2DDebugFillTag);
|
||||
|
||||
ensurePen(pen);
|
||||
if (!d->pen.brush)
|
||||
return;
|
||||
|
||||
d->dc()->DrawGeometry(geometry, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
|
||||
}
|
||||
|
||||
void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
|
||||
{
|
||||
Q_D(QWindowsDirect2DPaintEngine);
|
||||
|
@ -68,7 +68,14 @@ public:
|
||||
|
||||
void setState(QPainterState *s) Q_DECL_OVERRIDE;
|
||||
|
||||
void draw(const QVectorPath &path) Q_DECL_OVERRIDE;
|
||||
|
||||
void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
|
||||
void fill(ID2D1Geometry *geometry, const QBrush &brush);
|
||||
|
||||
void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE;
|
||||
void stroke(ID2D1Geometry *geometry, const QPen &pen);
|
||||
|
||||
void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
|
||||
|
||||
void clipEnabledChanged() Q_DECL_OVERRIDE;
|
||||
|
Loading…
Reference in New Issue
Block a user