common: ignoring color/alpha/opacity of a clip object

According to the svg specs clip's fill and opacity
should be ignored. Till now setting the alpha/opacity
value to zero resulted in the shape's rendering abort.

@Issue: https://github.com/Samsung/thorvg/issues/1192
This commit is contained in:
Mira Grudzinska 2022-12-27 16:21:42 +01:00 committed by Mira Grudzinska
parent b58c20b881
commit 0de3872be3
4 changed files with 34 additions and 3 deletions

View file

@ -363,6 +363,20 @@ public:
*/
CompositeMethod composite(const Paint** target) const noexcept;
/**
* @brief Gets the composition source object and the composition method.
*
* @param[out] source The paint of the composition source object.
* @param[out] method The method used to composite the source object with the target.
*
* @return Result::Success when the paint object used as a composition target, Result::InsufficientCondition otherwise.
*
* @warning Please do not use it, this API is not official one. It could be modified in the next version.
*
* @BETA_API
*/
Result composite(const Paint** source, CompositeMethod* method) const noexcept;
/**
* @brief Return the unique id value of the paint instance.
*

View file

@ -77,7 +77,9 @@ struct SwShapeTask : SwTask
void run(unsigned tid) override
{
if (opacity == 0) return; //Invisible
auto compMethod = CompositeMethod::None;
auto usedAsClip = (sdata->composite(nullptr, &compMethod) == Result::Success) && (compMethod == CompositeMethod::ClipPath);
if (opacity == 0 && !usedAsClip) return; //Invisible
uint8_t strokeAlpha = 0;
auto visibleStroke = false;
@ -99,7 +101,7 @@ struct SwShapeTask : SwTask
sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
visibleFill = (alpha > 0 || sdata->fill());
if (visibleFill || visibleStroke) {
if (visibleFill || visibleStroke || usedAsClip) {
shapeReset(&shape);
if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err;
}
@ -111,7 +113,7 @@ struct SwShapeTask : SwTask
//Fill
if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
if (visibleFill) {
if (visibleFill || usedAsClip) {
/* 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.

View file

@ -385,6 +385,19 @@ CompositeMethod Paint::composite(const Paint** target) const noexcept
}
Result Paint::composite(const Paint** source, CompositeMethod* method) const noexcept
{
if (source) *source = pImpl->compSource;
auto met = (pImpl->compSource && pImpl->compSource->pImpl->compData ?
pImpl->compSource->pImpl->compData->method : CompositeMethod::None);
if (method) *method = met;
if (pImpl->compSource != nullptr && met != CompositeMethod::None)
return Result::Success;
return Result::InsufficientCondition;
}
Result Paint::opacity(uint8_t o) noexcept
{
if (pImpl->opacity == o) return Result::Success;

View file

@ -63,6 +63,7 @@ namespace tvg
StrategyMethod* smethod = nullptr;
RenderTransform* rTransform = nullptr;
Composite* compData = nullptr;
Paint* compSource = nullptr;
uint32_t renderFlag = RenderUpdateFlag::None;
uint32_t ctxFlag = ContextFlag::Invalid;
uint32_t id;
@ -137,6 +138,7 @@ namespace tvg
if (!target && method == CompositeMethod::None) return true;
compData = static_cast<Composite*>(calloc(1, sizeof(Composite)));
}
target->pImpl->compSource = source;
compData->target = target;
compData->source = source;
compData->method = method;