mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 11:36:25 +00:00
sw_engine: preventing a double application of the opacity (#540)
For filled and stroked shapes with a gradient, the opacity was applied during the composition and during the ctable update. To prevent this, in case the composition occured, ctable is updated with the opacity = 255.
This commit is contained in:
parent
8826394b56
commit
96f22e282d
1 changed files with 18 additions and 25 deletions
|
@ -69,18 +69,14 @@ struct SwShapeTask : SwTask
|
||||||
{
|
{
|
||||||
if (opacity == 0) return; //Invisible
|
if (opacity == 0) return; //Invisible
|
||||||
|
|
||||||
/* Valid filling & stroking each increases the value by 1.
|
|
||||||
This value is referenced for compositing shape & stroking. */
|
|
||||||
bool stroking = false;
|
|
||||||
bool filling = false;
|
|
||||||
|
|
||||||
//Valid Stroking?
|
//Valid Stroking?
|
||||||
uint8_t strokeAlpha = 0;
|
uint8_t strokeAlpha = 0;
|
||||||
auto strokeWidth = sdata->strokeWidth();
|
auto strokeWidth = sdata->strokeWidth();
|
||||||
if (HALF_STROKE(strokeWidth) > 0) {
|
if (HALF_STROKE(strokeWidth) > 0) {
|
||||||
sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
|
sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
|
||||||
}
|
}
|
||||||
bool validStroke = (strokeAlpha > 0) || sdata->strokeFill();
|
bool visibleStroke = (static_cast<uint32_t>(strokeAlpha * opacity / 255) > 0) || sdata->strokeFill();
|
||||||
|
bool visibleFill = false;
|
||||||
auto clipRegion = bbox;
|
auto clipRegion = bbox;
|
||||||
|
|
||||||
//invisible shape turned to visible by alpha.
|
//invisible shape turned to visible by alpha.
|
||||||
|
@ -92,30 +88,28 @@ struct SwShapeTask : SwTask
|
||||||
uint8_t alpha = 0;
|
uint8_t alpha = 0;
|
||||||
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
|
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
|
||||||
alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
|
alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
|
||||||
bool renderShape = (alpha > 0 || sdata->fill());
|
visibleFill = (alpha > 0 || sdata->fill());
|
||||||
if (renderShape || validStroke) {
|
if (visibleFill || visibleStroke) {
|
||||||
shapeReset(&shape);
|
shapeReset(&shape);
|
||||||
if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err;
|
if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err;
|
||||||
if (renderShape) {
|
|
||||||
/* We assume that if stroke width is bigger than 2,
|
|
||||||
shape outline below stroke could be full covered by stroke drawing.
|
|
||||||
Thus it turns off antialising in that condition.
|
|
||||||
Also, it shouldn't be dash style. */
|
|
||||||
auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2 && sdata->strokeDash(nullptr) == 0) ? false : true;
|
|
||||||
if (!shapeGenRle(&shape, sdata, antiAlias, clips.count > 0 ? true : false)) goto err;
|
|
||||||
filling = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fill
|
//Fill
|
||||||
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
||||||
auto fill = sdata->fill();
|
if (visibleFill) {
|
||||||
if (fill) {
|
/* We assume that if stroke width is bigger than 2,
|
||||||
|
shape outline below stroke could be full covered by stroke drawing.
|
||||||
|
Thus it turns off antialising in that condition.
|
||||||
|
Also, it shouldn't be dash style. */
|
||||||
|
auto antiAlias = (strokeAlpha == 255 && strokeWidth > 2 && sdata->strokeDash(nullptr) == 0) ? false : true;
|
||||||
|
if (!shapeGenRle(&shape, sdata, antiAlias, clips.count > 0 ? true : false)) goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto fill = sdata->fill()) {
|
||||||
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
|
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
|
||||||
if (ctable) shapeResetFill(&shape);
|
if (ctable) shapeResetFill(&shape);
|
||||||
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
if (!shapeGenFillColors(&shape, fill, transform, surface, visibleStroke ? 255 : opacity, ctable)) goto err;
|
||||||
filling = true;
|
|
||||||
} else {
|
} else {
|
||||||
shapeDelFill(&shape);
|
shapeDelFill(&shape);
|
||||||
}
|
}
|
||||||
|
@ -123,15 +117,14 @@ struct SwShapeTask : SwTask
|
||||||
|
|
||||||
//Stroke
|
//Stroke
|
||||||
if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
|
if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) {
|
||||||
if (validStroke) {
|
if (visibleStroke) {
|
||||||
shapeResetStroke(&shape, sdata, transform);
|
shapeResetStroke(&shape, sdata, transform);
|
||||||
if (!shapeGenStrokeRle(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err;
|
if (!shapeGenStrokeRle(&shape, sdata, transform, clipRegion, bbox, mpool, tid)) goto err;
|
||||||
stroking = true;
|
|
||||||
|
|
||||||
if (auto fill = sdata->strokeFill()) {
|
if (auto fill = sdata->strokeFill()) {
|
||||||
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
||||||
if (ctable) shapeResetStrokeFill(&shape);
|
if (ctable) shapeResetStrokeFill(&shape);
|
||||||
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, visibleFill ? 255 : opacity, ctable)) goto err;
|
||||||
} else {
|
} else {
|
||||||
shapeDelStrokeFill(&shape);
|
shapeDelStrokeFill(&shape);
|
||||||
}
|
}
|
||||||
|
@ -160,7 +153,7 @@ struct SwShapeTask : SwTask
|
||||||
shapeReset(&shape);
|
shapeReset(&shape);
|
||||||
end:
|
end:
|
||||||
shapeDelOutline(&shape, mpool, tid);
|
shapeDelOutline(&shape, mpool, tid);
|
||||||
if (stroking && filling && opacity < 255) cmpStroking = true;
|
if (visibleStroke && visibleFill && opacity < 255) cmpStroking = true;
|
||||||
else cmpStroking = false;
|
else cmpStroking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue