diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 6223bc87..7edd1055 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -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; } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index 3f594539..504cee4d 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -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& 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(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(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); } diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index a8a1d211..d2ec201e 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -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& 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(opacity); + opacity = 255; + } rd = renderer.prepare(rs, rd, transform, opacity, clips, static_cast(pFlag | flag), clipper); flag = RenderUpdateFlag::None;