Painter: change to a solid pattern for gradients

Gradients don't use patterns, but then some common drawing code makes
decisions based on them. Let's set the pattern to B_SOLID_HIGH so that
we get the expected result, in particular one that does not depend on
the last pattern used by a previous operation.

Fixes #18370.

Change-Id: I9d71c6d334d77be8fe4783a072b8df519486d74e
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6416
Reviewed-by: John Scipione <jscipione@gmail.com>
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
Reviewed-by: Stephan Aßmus <superstippi@gmx.de>
This commit is contained in:
Máximo Castañeda 2023-05-05 19:08:09 +02:00 committed by Stephan Aßmus
parent 412bcb11fd
commit 44233abf11
2 changed files with 52 additions and 36 deletions

View File

@ -175,6 +175,30 @@ detect_simd()
}
// Gradients and strings don't use patterns, but we want the special handling
// we have for solid patterns in certain modes to get the expected results for
// border antialiasing.
class SolidPatternGuard {
public:
SolidPatternGuard(Painter* painter)
:
fPainter(painter),
fPattern(fPainter->Pattern())
{
fPainter->SetPattern(B_SOLID_HIGH);
}
~SolidPatternGuard()
{
fPainter->SetPattern(fPattern);
}
private:
Painter* fPainter;
pattern fPattern;
};
// #pragma mark -
@ -636,7 +660,7 @@ Painter::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3) const
// FillTriangle
BRect
Painter::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
const BGradient& gradient) const
const BGradient& gradient)
{
CHECK_CLIPPING
@ -692,7 +716,7 @@ Painter::DrawPolygon(BPoint* p, int32 numPts, bool filled, bool closed) const
// FillPolygon
BRect
Painter::FillPolygon(BPoint* p, int32 numPts, const BGradient& gradient,
bool closed) const
bool closed)
{
CHECK_CLIPPING
@ -744,7 +768,7 @@ Painter::DrawBezier(BPoint* p, bool filled) const
// FillBezier
BRect
Painter::FillBezier(BPoint* p, const BGradient& gradient) const
Painter::FillBezier(BPoint* p, const BGradient& gradient)
{
CHECK_CLIPPING
@ -785,7 +809,7 @@ Painter::DrawShape(const int32& opCount, const uint32* opList,
BRect
Painter::FillShape(const int32& opCount, const uint32* opList,
const int32& ptCount, const BPoint* points, const BGradient& gradient,
const BPoint& viewToScreenOffset, float viewScale) const
const BPoint& viewToScreenOffset, float viewScale)
{
CHECK_CLIPPING
@ -920,7 +944,7 @@ Painter::FillRect(const BRect& r) const
// FillRect
BRect
Painter::FillRect(const BRect& r, const BGradient& gradient) const
Painter::FillRect(const BRect& r, const BGradient& gradient)
{
CHECK_CLIPPING
@ -1133,7 +1157,7 @@ Painter::FillRoundRect(const BRect& r, float xRadius, float yRadius) const
// FillRoundRect
BRect
Painter::FillRoundRect(const BRect& r, float xRadius, float yRadius,
const BGradient& gradient) const
const BGradient& gradient)
{
CHECK_CLIPPING
@ -1203,7 +1227,7 @@ Painter::DrawEllipse(BRect r, bool fill) const
// FillEllipse
BRect
Painter::FillEllipse(BRect r, const BGradient& gradient) const
Painter::FillEllipse(BRect r, const BGradient& gradient)
{
CHECK_CLIPPING
@ -1286,7 +1310,7 @@ Painter::FillArc(BPoint center, float xRadius, float yRadius, float angle,
// FillArc
BRect
Painter::FillArc(BPoint center, float xRadius, float yRadius, float angle,
float span, const BGradient& gradient) const
float span, const BGradient& gradient)
{
CHECK_CLIPPING
@ -1337,17 +1361,12 @@ Painter::DrawString(const char* utf8String, uint32 length, BPoint baseLine,
BRect bounds;
// text is not rendered with patterns, but we need to
// make sure that the previous pattern is restored
pattern oldPattern = *fPatternHandler.GetR5Pattern();
SetPattern(B_SOLID_HIGH);
SolidPatternGuard _(this);
bounds = fTextRenderer.RenderString(utf8String, length,
baseLine, fClippingRegion->Frame(), false, NULL, delta,
cacheReference);
SetPattern(oldPattern);
return _Clipped(bounds);
}
@ -1363,17 +1382,12 @@ Painter::DrawString(const char* utf8String, uint32 length,
BRect bounds;
// text is not rendered with patterns, but we need to
// make sure that the previous pattern is restored
pattern oldPattern = *fPatternHandler.GetR5Pattern();
SetPattern(B_SOLID_HIGH);
SolidPatternGuard _(this);
bounds = fTextRenderer.RenderString(utf8String, length,
offsets, fClippingRegion->Frame(), false, NULL,
cacheReference);
SetPattern(oldPattern);
return _Clipped(bounds);
}
@ -1460,7 +1474,7 @@ Painter::FillRegion(const BRegion* region) const
// FillRegion
BRect
Painter::FillRegion(const BRegion* region, const BGradient& gradient) const
Painter::FillRegion(const BRegion* region, const BGradient& gradient)
{
CHECK_CLIPPING
@ -1860,7 +1874,7 @@ Painter::_RasterizePath(VertexSource& path) const
// _FillPath
template<class VertexSource>
BRect
Painter::_FillPath(VertexSource& path, const BGradient& gradient) const
Painter::_FillPath(VertexSource& path, const BGradient& gradient)
{
if (fIdentityTransform)
return _RasterizePath(path, gradient);
@ -1873,7 +1887,7 @@ Painter::_FillPath(VertexSource& path, const BGradient& gradient) const
// _FillPath
template<class VertexSource>
BRect
Painter::_RasterizePath(VertexSource& path, const BGradient& gradient) const
Painter::_RasterizePath(VertexSource& path, const BGradient& gradient)
{
GTRACE("Painter::_RasterizePath\n");
@ -2089,7 +2103,7 @@ template<class VertexSource, typename GradientFunction>
void
Painter::_RasterizePath(VertexSource& path, const BGradient& gradient,
GradientFunction function, agg::trans_affine& gradientTransform,
int gradientStop) const
int gradientStop)
{
GTRACE("Painter::_RasterizePath\n");
@ -2101,6 +2115,8 @@ Painter::_RasterizePath(VertexSource& path, const BGradient& gradient,
typedef agg::renderer_scanline_aa<renderer_base, span_allocator_type,
span_gradient_type> renderer_gradient_type;
SolidPatternGuard _(this);
interpolator_type spanInterpolator(gradientTransform);
span_allocator_type spanAllocator;
color_array_type colorArray;

View File

@ -121,20 +121,20 @@ public:
BPoint pt3) const;
BRect FillTriangle(BPoint pt1, BPoint pt2,
BPoint pt3,
const BGradient& gradient) const;
const BGradient& gradient);
// polygons
BRect DrawPolygon(BPoint* ptArray, int32 numPts,
bool filled, bool closed) const;
BRect FillPolygon(BPoint* ptArray, int32 numPts,
const BGradient& gradient,
bool closed) const;
bool closed);
// bezier curves
BRect DrawBezier(BPoint* controlPoints,
bool filled) const;
BRect FillBezier(BPoint* controlPoints,
const BGradient& gradient) const;
const BGradient& gradient);
// shapes
BRect DrawShape(const int32& opCount,
@ -147,7 +147,7 @@ public:
const BPoint* ptList,
const BGradient& gradient,
const BPoint& viewToScreenOffset,
float viewScale) const;
float viewScale);
// rects
BRect StrokeRect(const BRect& r) const;
@ -158,7 +158,7 @@ public:
BRect FillRect(const BRect& r) const;
BRect FillRect(const BRect& r,
const BGradient& gradient) const;
const BGradient& gradient);
// fills a solid rect with color c, no blending
void FillRect(const BRect& r,
@ -183,7 +183,7 @@ public:
float yRadius) const;
BRect FillRoundRect(const BRect& r, float xRadius,
float yRadius,
const BGradient& gradient) const;
const BGradient& gradient);
// ellipses
void AlignEllipseRect(BRect* rect,
@ -191,7 +191,7 @@ public:
BRect DrawEllipse(BRect r, bool filled) const;
BRect FillEllipse(BRect r,
const BGradient& gradient) const;
const BGradient& gradient);
// arcs
BRect StrokeArc(BPoint center, float xRadius,
@ -203,7 +203,7 @@ public:
float span) const;
BRect FillArc(BPoint center, float xRadius,
float yRadius, float angle, float span,
const BGradient& gradient) const;
const BGradient& gradient);
// strings
BRect DrawString(const char* utf8String,
@ -239,7 +239,7 @@ public:
// some convenience stuff
BRect FillRegion(const BRegion* region) const;
BRect FillRegion(const BRegion* region,
const BGradient& gradient) const;
const BGradient& gradient);
BRect InvertRect(const BRect& r) const;
@ -298,10 +298,10 @@ private:
template<class VertexSource>
BRect _FillPath(VertexSource& path,
const BGradient& gradient) const;
const BGradient& gradient);
template<class VertexSource>
BRect _RasterizePath(VertexSource& path,
const BGradient& gradient) const;
const BGradient& gradient);
void _CalcLinearGradientTransform(BPoint startPoint,
BPoint endPoint, agg::trans_affine& mtx,
@ -323,7 +323,7 @@ private:
const BGradient& gradient,
GradientFunction function,
agg::trans_affine& gradientTransform,
int gradientStop = 100) const;
int gradientStop = 100);
private:
class BitmapPainter;