mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-15 04:24:28 +00:00
common sw_engine: gather scattered stroking composition.
There are two branches for completing stroke composition between the canvas and sw_engine. It is necessary to centralize the task on the canvas engine side so that we can maintain the logic without confusion.
This commit is contained in:
parent
3626ded041
commit
89db13037d
3 changed files with 30 additions and 38 deletions
|
@ -125,10 +125,6 @@ struct SwShapeTask : SwTask
|
|||
}
|
||||
}
|
||||
|
||||
//Decide Stroking Composition
|
||||
if (visibleStroke && visibleFill && opacity < 255) cmpStroking = true;
|
||||
else cmpStroking = false;
|
||||
|
||||
//Fill
|
||||
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
|
||||
if (visibleFill || clipper) {
|
||||
|
@ -143,7 +139,7 @@ struct SwShapeTask : SwTask
|
|||
if (auto fill = rshape->fill) {
|
||||
auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false;
|
||||
if (ctable) shapeResetFill(&shape);
|
||||
if (!shapeGenFillColors(&shape, fill, transform, surface, cmpStroking ? 255 : opacity, ctable)) goto err;
|
||||
if (!shapeGenFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||
} else {
|
||||
shapeDelFill(&shape);
|
||||
}
|
||||
|
@ -158,7 +154,7 @@ struct SwShapeTask : SwTask
|
|||
if (auto fill = rshape->strokeFill()) {
|
||||
auto ctable = (flags & RenderUpdateFlag::GradientStroke) ? true : false;
|
||||
if (ctable) shapeResetStrokeFill(&shape);
|
||||
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, cmpStroking ? 255 : opacity, ctable)) goto err;
|
||||
if (!shapeGenStrokeFillColors(&shape, fill, transform, surface, opacity, ctable)) goto err;
|
||||
} else {
|
||||
shapeDelStrokeFill(&shape);
|
||||
}
|
||||
|
@ -490,30 +486,15 @@ bool SwRenderer::renderShape(RenderData data)
|
|||
|
||||
if (task->opacity == 0) return true;
|
||||
|
||||
uint32_t opacity;
|
||||
Compositor* cmp = nullptr;
|
||||
|
||||
//Do Stroking Composition
|
||||
if (task->cmpStroking) {
|
||||
opacity = 255;
|
||||
cmp = target(task->bounds(), colorSpace());
|
||||
beginComposite(cmp, CompositeMethod::None, task->opacity);
|
||||
//No Stroking Composition
|
||||
} else {
|
||||
opacity = task->opacity;
|
||||
}
|
||||
|
||||
//Main raster stage
|
||||
if (task->rshape->stroke && task->rshape->stroke->strokeFirst) {
|
||||
_renderStroke(task, surface, opacity);
|
||||
_renderFill(task, surface, opacity);
|
||||
_renderStroke(task, surface, task->opacity);
|
||||
_renderFill(task, surface, task->opacity);
|
||||
} else {
|
||||
_renderFill(task, surface, opacity);
|
||||
_renderStroke(task, surface, opacity);
|
||||
_renderFill(task, surface, task->opacity);
|
||||
_renderStroke(task, surface, task->opacity);
|
||||
}
|
||||
|
||||
if (task->cmpStroking) endComposite(cmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ struct Scene::Impl
|
|||
RenderData rd = nullptr;
|
||||
Scene* scene = nullptr;
|
||||
uint8_t opacity; //for composition
|
||||
bool needComp; //composite or not
|
||||
|
||||
Impl(Scene* s) : scene(s)
|
||||
{
|
||||
|
@ -109,10 +110,12 @@ struct Scene::Impl
|
|||
|
||||
RenderData update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flag, bool clipper)
|
||||
{
|
||||
/* Overriding opacity value. If this scene is half-translucent,
|
||||
It must do intermeidate composition with that opacity value. */
|
||||
this->opacity = static_cast<uint8_t>(opacity);
|
||||
if (needComposition(opacity)) opacity = 255;
|
||||
if ((needComp = needComposition(opacity))) {
|
||||
/* Overriding opacity value. If this scene is half-translucent,
|
||||
It must do intermeidate composition with that opacity value. */
|
||||
this->opacity = static_cast<uint8_t>(opacity);
|
||||
opacity = 255;
|
||||
}
|
||||
|
||||
this->renderer = &renderer;
|
||||
|
||||
|
@ -136,7 +139,7 @@ struct Scene::Impl
|
|||
{
|
||||
Compositor* cmp = nullptr;
|
||||
|
||||
if (needComposition(opacity)) {
|
||||
if (needComp) {
|
||||
cmp = renderer.target(bounds(renderer), renderer.colorSpace());
|
||||
renderer.beginComposite(cmp, CompositeMethod::None, opacity);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ struct Shape::Impl
|
|||
RenderData rd = nullptr; //engine data
|
||||
uint32_t flag = RenderUpdateFlag::None;
|
||||
Shape* shape;
|
||||
bool needComp; //for composition
|
||||
uint8_t opacity; //for composition
|
||||
bool needComp; //composite or not
|
||||
|
||||
Impl(Shape* s) : shape(s)
|
||||
{
|
||||
|
@ -56,7 +57,7 @@ struct Shape::Impl
|
|||
|
||||
if (needComp) {
|
||||
cmp = renderer.target(bounds(renderer), renderer.colorSpace());
|
||||
renderer.beginComposite(cmp, CompositeMethod::None, 255);
|
||||
renderer.beginComposite(cmp, CompositeMethod::None, opacity);
|
||||
}
|
||||
ret = renderer.renderShape(rd);
|
||||
if (cmp) renderer.endComposite(cmp);
|
||||
|
@ -65,12 +66,14 @@ struct Shape::Impl
|
|||
|
||||
bool needComposition(uint32_t opacity)
|
||||
{
|
||||
//In this case, paint(shape) would try composition by backends. (See: SwShapeTask::run())
|
||||
//TODO: that composition should be moved here?
|
||||
if (opacity < 255) return false;
|
||||
if (opacity == 0) return false;
|
||||
|
||||
//Shape composition is only necessary when stroking is valid.
|
||||
//Shape composition is only necessary when stroking & fill are valid.
|
||||
if (!rs.stroke || rs.stroke->width < FLT_EPSILON || rs.stroke->color[3] == 0) return false;
|
||||
if (!rs.fill && rs.color[3] == 0) return false;
|
||||
|
||||
//translucent fill & stroke
|
||||
if (opacity < 255) return true;
|
||||
|
||||
//Composition test
|
||||
const Paint* target;
|
||||
|
@ -82,8 +85,13 @@ struct Shape::Impl
|
|||
}
|
||||
|
||||
RenderData update(RenderMethod& renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag, bool clipper)
|
||||
{
|
||||
needComp = needComposition(opacity);
|
||||
{
|
||||
if ((needComp = needComposition(opacity))) {
|
||||
/* Overriding opacity value. If this scene is half-translucent,
|
||||
It must do intermeidate composition with that opacity value. */
|
||||
this->opacity = static_cast<uint8_t>(opacity);
|
||||
opacity = 255;
|
||||
}
|
||||
|
||||
rd = renderer.prepare(rs, rd, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag), clipper);
|
||||
flag = RenderUpdateFlag::None;
|
||||
|
|
Loading…
Add table
Reference in a new issue