Simplify code by factoring out brush transformation for gradients
Emulation of non-logical coordinate mode gradients was implemented by essentially 3 x 2 repetitions of the same manipulation of the QBrush transform. Avoid the code duplication by extracting a common method. Add lancelot test scripts that excersizes these code paths. Change-Id: I7baa921923231ef9e83e443dba996b82b32ad1e7 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
8eccd1b0ad
commit
5dc0e4b285
@ -72,6 +72,14 @@ QPainterState *QEmulationPaintEngine::createState(QPainterState *orig) const
|
||||
return real_engine->createState(orig);
|
||||
}
|
||||
|
||||
static inline void combineXForm(QBrush *brush, const QRectF &r)
|
||||
{
|
||||
QTransform t = brush->transform();
|
||||
t.translate(r.x(), r.y());
|
||||
t.scale(r.width(), r.height());
|
||||
brush->setTransform(t);
|
||||
}
|
||||
|
||||
void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
|
||||
{
|
||||
QPainterState *s = state();
|
||||
@ -84,26 +92,14 @@ void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
|
||||
|
||||
Qt::BrushStyle style = qbrush_style(brush);
|
||||
if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
|
||||
const QGradient *g = brush.gradient();
|
||||
|
||||
if (g->coordinateMode() > QGradient::LogicalMode) {
|
||||
if (g->coordinateMode() == QGradient::StretchToDeviceMode) {
|
||||
QBrush copy = brush;
|
||||
QTransform mat = copy.transform();
|
||||
mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
|
||||
copy.setTransform(mat);
|
||||
real_engine->fill(path, copy);
|
||||
return;
|
||||
} else if (g->coordinateMode() == QGradient::ObjectBoundingMode) {
|
||||
QBrush copy = brush;
|
||||
QTransform mat = copy.transform();
|
||||
QRectF r = path.controlPointRect();
|
||||
mat.translate(r.x(), r.y());
|
||||
mat.scale(r.width(), r.height());
|
||||
copy.setTransform(mat);
|
||||
real_engine->fill(path, copy);
|
||||
return;
|
||||
}
|
||||
QGradient::CoordinateMode coMode = brush.gradient()->coordinateMode();
|
||||
if (coMode > QGradient::LogicalMode) {
|
||||
QBrush copy = brush;
|
||||
const QPaintDevice *d = real_engine->painter()->device();
|
||||
QRectF r = (coMode == QGradient::ObjectBoundingMode) ? path.controlPointRect() : QRectF(0, 0, d->width(), d->height());
|
||||
combineXForm(©, r);
|
||||
real_engine->fill(path, copy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,27 +120,15 @@ void QEmulationPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
|
||||
QBrush brush = pen.brush();
|
||||
QPen copy = pen;
|
||||
Qt::BrushStyle style = qbrush_style(brush);
|
||||
if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
|
||||
const QGradient *g = brush.gradient();
|
||||
|
||||
if (g->coordinateMode() > QGradient::LogicalMode) {
|
||||
if (g->coordinateMode() == QGradient::StretchToDeviceMode) {
|
||||
QTransform mat = brush.transform();
|
||||
mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
|
||||
brush.setTransform(mat);
|
||||
copy.setBrush(brush);
|
||||
real_engine->stroke(path, copy);
|
||||
return;
|
||||
} else if (g->coordinateMode() == QGradient::ObjectBoundingMode) {
|
||||
QTransform mat = brush.transform();
|
||||
QRectF r = path.controlPointRect();
|
||||
mat.translate(r.x(), r.y());
|
||||
mat.scale(r.width(), r.height());
|
||||
brush.setTransform(mat);
|
||||
copy.setBrush(brush);
|
||||
real_engine->stroke(path, copy);
|
||||
return;
|
||||
}
|
||||
if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern ) {
|
||||
QGradient::CoordinateMode coMode = brush.gradient()->coordinateMode();
|
||||
if (coMode > QGradient::LogicalMode) {
|
||||
const QPaintDevice *d = real_engine->painter()->device();
|
||||
QRectF r = (coMode == QGradient::ObjectBoundingMode) ? path.controlPointRect() : QRectF(0, 0, d->width(), d->height());
|
||||
combineXForm(&brush, r);
|
||||
copy.setBrush(brush);
|
||||
real_engine->stroke(path, copy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,18 +163,16 @@ void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &text
|
||||
QGradient g = *s->pen.brush().gradient();
|
||||
|
||||
if (g.coordinateMode() > QGradient::LogicalMode) {
|
||||
QTransform mat = s->pen.brush().transform();
|
||||
if (g.coordinateMode() == QGradient::StretchToDeviceMode) {
|
||||
mat.scale(real_engine->painter()->device()->width(), real_engine->painter()->device()->height());
|
||||
} else if (g.coordinateMode() == QGradient::ObjectBoundingMode) {
|
||||
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
|
||||
QRectF r(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
|
||||
mat.translate(r.x(), r.y());
|
||||
mat.scale(r.width(), r.height());
|
||||
}
|
||||
QBrush copy = s->pen.brush();
|
||||
const QPaintDevice *d = real_engine->painter()->device();
|
||||
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
|
||||
QRectF r = (g.coordinateMode() == QGradient::ObjectBoundingMode) ?
|
||||
QRectF(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal()) :
|
||||
QRectF(0, 0, d->width(), d->height());
|
||||
combineXForm(©, r);
|
||||
g.setCoordinateMode(QGradient::LogicalMode);
|
||||
QBrush brush(g);
|
||||
brush.setTransform(mat);
|
||||
brush.setTransform(copy.transform());
|
||||
s->pen.setBrush(brush);
|
||||
penChanged();
|
||||
real_engine->drawTextItem(p, textItem);
|
||||
|
67
tests/auto/other/lancelot/scripts/gradientxform_device.qps
Normal file
67
tests/auto/other/lancelot/scripts/gradientxform_device.qps
Normal file
@ -0,0 +1,67 @@
|
||||
# Version: 1
|
||||
# CheckVsReference: 5%
|
||||
|
||||
gradient_clearStops
|
||||
gradient_appendStop 0 black
|
||||
gradient_appendStop 0.4 yellow
|
||||
gradient_appendStop 1 gray
|
||||
|
||||
gradient_setSpread PadSpread
|
||||
|
||||
gradient_setCoordinateMode StretchToDeviceMode
|
||||
|
||||
# first run is dummy, make it offscreen
|
||||
save
|
||||
translate -500 -500
|
||||
|
||||
begin_block row
|
||||
save
|
||||
|
||||
setPen nopen
|
||||
drawRect 50 0 100 100
|
||||
|
||||
setPen brush 30
|
||||
setBrush lightblue
|
||||
drawRect 175 15 70 70
|
||||
|
||||
setFont "times" 110 99
|
||||
drawText 270 100 "X"
|
||||
|
||||
restore
|
||||
end_block row
|
||||
|
||||
restore
|
||||
|
||||
drawText 160 20 "PLAIN"
|
||||
drawText 560 20 "BRUSH XFORM"
|
||||
translate 0 20
|
||||
|
||||
begin_block block
|
||||
save
|
||||
|
||||
drawText 75 20 "Brush Fill"
|
||||
drawText 176 20 "Pen Stroke"
|
||||
drawText 277 20 "Text Stroke"
|
||||
translate 0 30
|
||||
drawText 0 50 "Linear"
|
||||
drawText 0 160 "Radial"
|
||||
drawText 0 270 "Conical"
|
||||
|
||||
gradient_setLinear 0.0 0.0 0.4 0.0
|
||||
repeat_block row
|
||||
|
||||
translate 0 110
|
||||
gradient_setRadial 0.04 0.08 0.3 0.3 0.05
|
||||
repeat_block row
|
||||
|
||||
translate 0 110
|
||||
gradient_setConical 0.25 0.1 45
|
||||
repeat_block row
|
||||
restore
|
||||
end_block block
|
||||
|
||||
translate 400 0
|
||||
brushRotate 30.0
|
||||
brushScale 1.5 .5
|
||||
brushTranslate 0 -80
|
||||
repeat_block block
|
67
tests/auto/other/lancelot/scripts/gradientxform_logical.qps
Normal file
67
tests/auto/other/lancelot/scripts/gradientxform_logical.qps
Normal file
@ -0,0 +1,67 @@
|
||||
# Version: 1
|
||||
# CheckVsReference: 5%
|
||||
|
||||
gradient_clearStops
|
||||
gradient_appendStop 0 black
|
||||
gradient_appendStop 0.4 yellow
|
||||
gradient_appendStop 1 gray
|
||||
|
||||
gradient_setSpread PadSpread
|
||||
|
||||
gradient_setCoordinateMode LogicalMode
|
||||
|
||||
# first run is dummy, make it offscreen
|
||||
save
|
||||
translate -500 -500
|
||||
|
||||
begin_block row
|
||||
save
|
||||
|
||||
setPen nopen
|
||||
drawRect 50 0 100 100
|
||||
|
||||
setPen brush 30
|
||||
setBrush lightblue
|
||||
drawRect 175 15 70 70
|
||||
|
||||
setFont "times" 110 99
|
||||
drawText 270 100 "X"
|
||||
|
||||
restore
|
||||
end_block row
|
||||
|
||||
restore
|
||||
|
||||
drawText 160 20 "PLAIN"
|
||||
drawText 560 20 "BRUSH XFORM"
|
||||
translate 0 20
|
||||
|
||||
begin_block block
|
||||
save
|
||||
|
||||
drawText 75 20 "Brush Fill"
|
||||
drawText 176 20 "Pen Stroke"
|
||||
drawText 277 20 "Text Stroke"
|
||||
translate 0 30
|
||||
drawText 0 50 "Linear"
|
||||
drawText 0 160 "Radial"
|
||||
drawText 0 270 "Conical"
|
||||
|
||||
gradient_setLinear 0 0 400 0
|
||||
repeat_block row
|
||||
|
||||
translate 0 110
|
||||
gradient_setRadial 200 50 140 70 20
|
||||
repeat_block row
|
||||
|
||||
translate 0 110
|
||||
gradient_setConical 220 60 45
|
||||
repeat_block row
|
||||
restore
|
||||
end_block block
|
||||
|
||||
translate 400 0
|
||||
brushRotate 30.0
|
||||
brushScale 1.5 .5
|
||||
brushTranslate 0 -80
|
||||
repeat_block block
|
68
tests/auto/other/lancelot/scripts/gradientxform_object.qps
Normal file
68
tests/auto/other/lancelot/scripts/gradientxform_object.qps
Normal file
@ -0,0 +1,68 @@
|
||||
# Version: 1
|
||||
# CheckVsReference: 5%
|
||||
|
||||
gradient_clearStops
|
||||
gradient_appendStop 0 black
|
||||
gradient_appendStop 0.4 yellow
|
||||
gradient_appendStop 1 gray
|
||||
|
||||
gradient_setSpread PadSpread
|
||||
|
||||
gradient_setCoordinateMode ObjectBoundingMode
|
||||
|
||||
# first run is dummy, make it offscreen
|
||||
save
|
||||
translate -500 -500
|
||||
|
||||
begin_block row
|
||||
save
|
||||
|
||||
setPen nopen
|
||||
drawRect 50 0 100 100
|
||||
|
||||
setPen brush 30
|
||||
setBrush lightblue
|
||||
translate 110 0
|
||||
drawRect 65 15 70 70
|
||||
|
||||
translate 110 0
|
||||
setFont "times" 110 99
|
||||
drawText 50 100 "X"
|
||||
|
||||
restore
|
||||
end_block row
|
||||
|
||||
restore
|
||||
|
||||
drawText 160 20 "PLAIN"
|
||||
drawText 560 20 "BRUSH XFORM"
|
||||
translate 0 20
|
||||
|
||||
begin_block block
|
||||
save
|
||||
|
||||
drawText 75 20 "Brush Fill"
|
||||
drawText 176 20 "Pen Stroke"
|
||||
drawText 277 20 "Text Stroke"
|
||||
translate 0 30
|
||||
drawText 0 50 "Linear"
|
||||
drawText 0 160 "Radial"
|
||||
drawText 0 270 "Conical"
|
||||
|
||||
gradient_setLinear 0.1 0.0 0.5 0.0
|
||||
repeat_block row
|
||||
|
||||
translate 0 110
|
||||
gradient_setRadial 0.3 0.2 0.5 0.4 0.5
|
||||
repeat_block row
|
||||
|
||||
translate 0 110
|
||||
gradient_setConical 0.5 0.7 45
|
||||
repeat_block row
|
||||
restore
|
||||
end_block block
|
||||
|
||||
translate 400 0
|
||||
brushRotate 30.0
|
||||
brushScale 1.5 .5
|
||||
repeat_block block
|
Loading…
Reference in New Issue
Block a user