app_server: fix gradients with no stops at the ends
When a gradient has no stop at offset 0 or 255, the drawing code will not automatically complete the gradiet with the first or last color, instead agg interpolation generated invalid random colors. To avoid this, insert extra stops at the start and end in the DrawingEngine when we prepare the gradient for drawing. We just copy the first and last stops to new stops at offsets 0 and 255, which makes sure the gradients covers the whole range and gives the expected result. Fixes #2945.
This commit is contained in:
parent
96bac1b30b
commit
c4e8d88f7c
@ -185,7 +185,7 @@ DrawingContext::ConvertToScreenForDrawing(BRegion* region) const
|
||||
void
|
||||
DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
{
|
||||
switch(gradient->GetType()) {
|
||||
switch (gradient->GetType()) {
|
||||
case BGradient::TYPE_LINEAR:
|
||||
{
|
||||
BGradientLinear* linear = (BGradientLinear*) gradient;
|
||||
@ -197,7 +197,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
ConvertToScreen(&end);
|
||||
linear->SetStart(start);
|
||||
linear->SetEnd(end);
|
||||
linear->SortColorStopsByOffset();
|
||||
break;
|
||||
}
|
||||
case BGradient::TYPE_RADIAL:
|
||||
@ -207,7 +206,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
fDrawState->Transform(¢er);
|
||||
ConvertToScreen(¢er);
|
||||
radial->SetCenter(center);
|
||||
radial->SortColorStopsByOffset();
|
||||
break;
|
||||
}
|
||||
case BGradient::TYPE_RADIAL_FOCUS:
|
||||
@ -221,7 +219,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
ConvertToScreen(&focal);
|
||||
radialFocus->SetCenter(center);
|
||||
radialFocus->SetFocal(focal);
|
||||
radialFocus->SortColorStopsByOffset();
|
||||
break;
|
||||
}
|
||||
case BGradient::TYPE_DIAMOND:
|
||||
@ -231,7 +228,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
fDrawState->Transform(¢er);
|
||||
ConvertToScreen(¢er);
|
||||
diamond->SetCenter(center);
|
||||
diamond->SortColorStopsByOffset();
|
||||
break;
|
||||
}
|
||||
case BGradient::TYPE_CONIC:
|
||||
@ -241,7 +237,6 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
fDrawState->Transform(¢er);
|
||||
ConvertToScreen(¢er);
|
||||
conic->SetCenter(center);
|
||||
conic->SortColorStopsByOffset();
|
||||
break;
|
||||
}
|
||||
case BGradient::TYPE_NONE:
|
||||
@ -249,6 +244,23 @@ DrawingContext::ConvertToScreenForDrawing(BGradient* gradient) const
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the gradient is fully padded so that out of bounds access
|
||||
// get the correct colors
|
||||
gradient->SortColorStopsByOffset();
|
||||
|
||||
BGradient::ColorStop* end = gradient->ColorStopAtFast(
|
||||
gradient->CountColorStops() - 1);
|
||||
|
||||
if (end->offset != 255)
|
||||
gradient->AddColor(end->color, 255);
|
||||
|
||||
BGradient::ColorStop* start = gradient->ColorStopAtFast(0);
|
||||
|
||||
if (start->offset != 0)
|
||||
gradient->AddColor(start->color, 0);
|
||||
|
||||
gradient->SortColorStopsByOffset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2881,7 +2881,7 @@ Painter::_RasterizePath(VertexSource& path, const BGradient& gradient) const
|
||||
|
||||
agg::trans_affine gradientTransform;
|
||||
|
||||
switch(gradient.GetType()) {
|
||||
switch (gradient.GetType()) {
|
||||
case BGradient::TYPE_LINEAR:
|
||||
{
|
||||
GTRACE(("Painter::_FillPath> type == TYPE_LINEAR\n"));
|
||||
|
Loading…
Reference in New Issue
Block a user