api: renamed the composite with mask.

Since we've separated ClipPath and Masking,
Masking now has a distinct and independent purpose.

API Modification:
 - enum class CompositeMethod -> enum class MaskMethod
 - Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) -> Result Paint::mask(std::unique_ptr<Paint> target, MaskMethod method)
 - CompositeMethod Paint::mask(const Paint** target) const -> MaskMethod Paint::mask(const Paint** target) const

issue: https://github.com/thorvg/thorvg/issues/1372
This commit is contained in:
Hermet Park 2024-10-15 18:30:36 +09:00 committed by Hermet Park
parent adebbcd4e2
commit 0a16152d75
36 changed files with 351 additions and 360 deletions

View file

@ -66,7 +66,7 @@ struct UserExample : tvgexam::Example
mask->appendCircle(180, 180, 75, 75);
mask->fill(255, 255, 255); //AlphaMask RGB channels are unused.
picture2->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
picture2->mask(std::move(mask), tvg::MaskMethod::Alpha);
canvas->push(std::move(picture2));
return true;

View file

@ -194,7 +194,7 @@ void contents()
Tvg_Paint* comp = tvg_shape_new();
tvg_shape_append_circle(comp, 600.0f, 600.0f, 100.0f, 100.0f);
tvg_shape_set_fill_color(comp, 0, 0, 0, 200);
tvg_paint_set_composite_method(pict, comp, TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK);
tvg_paint_set_mask_method(pict, comp, TVG_MASK_METHOD_INVERSE_ALPHA);
//Push the scene into the canvas
tvg_canvas_push(canvas, pict);

View file

@ -49,7 +49,7 @@ struct UserExample : tvgexam::Example
fill->colorStops(colorStops,2);
shape->fill(std::move(fill));
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
shape->mask(std::move(mask), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape));
//-------------------------------------------
@ -81,7 +81,7 @@ struct UserExample : tvgexam::Example
fill1->colorStops(colorStops1,2);
shape1->fill(std::move(fill1));
shape1->composite(std::move(mask1), tvg::CompositeMethod::AlphaMask);
shape1->mask(std::move(mask1), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape1));
//-------------------------------------------
@ -103,7 +103,7 @@ struct UserExample : tvgexam::Example
fill2->colorStops(colorStops2,2);
shape2->fill(std::move(fill2));
shape2->composite(std::move(mask2), tvg::CompositeMethod::InvAlphaMask);
shape2->mask(std::move(mask2), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape2));
//-------------------------------------------
@ -135,7 +135,7 @@ struct UserExample : tvgexam::Example
fill3->colorStops(colorStops3,2);
shape3->fill(std::move(fill3));
shape3->composite(std::move(mask3), tvg::CompositeMethod::InvAlphaMask);
shape3->mask(std::move(mask3), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape3));
return true;

View file

@ -47,8 +47,8 @@ struct UserExample : tvgexam::Example
nMask->appendCircle(220, 220, 125, 125);
nMask->fill(255, 200, 255);
mask->composite(std::move(nMask), tvg::CompositeMethod::InvLumaMask);
shape->composite(std::move(mask), tvg::CompositeMethod::InvLumaMask);
mask->mask(std::move(nMask), tvg::MaskMethod::InvLuma);
shape->mask(std::move(mask), tvg::MaskMethod::InvLuma);
canvas->push(std::move(shape));
//SVG
@ -63,7 +63,7 @@ struct UserExample : tvgexam::Example
mask2->appendCircle(150, 500, 75, 75);
mask2->appendRect(150, 500, 200, 200, 30, 30);
mask2->fill(255, 255, 255);
svg->composite(std::move(mask2), tvg::CompositeMethod::InvLumaMask);
svg->mask(std::move(mask2), tvg::MaskMethod::InvLuma);
canvas->push(std::move(svg));
//Star
@ -87,7 +87,7 @@ struct UserExample : tvgexam::Example
auto mask3 = tvg::Shape::gen();
mask3->appendCircle(600, 200, 125, 125);
mask3->fill(0, 255, 255);
star->composite(std::move(mask3), tvg::CompositeMethod::InvLumaMask);
star->mask(std::move(mask3), tvg::MaskMethod::InvLuma);
canvas->push(std::move(star));
//Image
@ -111,7 +111,7 @@ struct UserExample : tvgexam::Example
mask4_circle->fill(128, 0, 128);
mask4->push(std::move(mask4_rect));
mask4->push(std::move(mask4_circle));
image->composite(std::move(mask4), tvg::CompositeMethod::InvLumaMask);
image->mask(std::move(mask4), tvg::MaskMethod::InvLuma);
canvas->push(std::move(image));
free(data);

View file

@ -47,8 +47,8 @@ struct UserExample : tvgexam::Example
nMask->appendCircle(220, 220, 125, 125);
nMask->fill(255, 255, 255); //InvAlphaMask RGB channels are unused.
mask->composite(std::move(nMask), tvg::CompositeMethod::InvAlphaMask);
shape->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask);
mask->mask(std::move(nMask), tvg::MaskMethod::InvAlpha);
shape->mask(std::move(mask), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape));
//SVG
@ -63,7 +63,7 @@ struct UserExample : tvgexam::Example
mask2->appendCircle(150, 500, 75, 75);
mask2->appendRect(150, 500, 200, 200, 30, 30);
mask2->fill(255, 255, 255); //InvAlphaMask RGB channels are unused.
svg->composite(std::move(mask2), tvg::CompositeMethod::InvAlphaMask);
svg->mask(std::move(mask2), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(svg));
//Star
@ -87,7 +87,7 @@ struct UserExample : tvgexam::Example
auto mask3 = tvg::Shape::gen();
mask3->appendCircle(600, 200, 125, 125);
mask3->fill(255, 255, 255); //InvAlphaMask RGB channels are unused.
star->composite(std::move(mask3), tvg::CompositeMethod::InvAlphaMask);
star->mask(std::move(mask3), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(star));
//Image
@ -117,7 +117,7 @@ struct UserExample : tvgexam::Example
mask4->close();
mask4->fill(255, 255, 255); //InvAlphaMask RGB channels are unused.
mask4->opacity(70);
image->composite(std::move(mask4), tvg::CompositeMethod::InvAlphaMask);
image->mask(std::move(mask4), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image));
return true;

View file

@ -47,8 +47,8 @@ struct UserExample : tvgexam::Example
nMask->appendCircle(220, 220, 125, 125);
nMask->fill(255, 200, 255);
mask->composite(std::move(nMask), tvg::CompositeMethod::LumaMask);
shape->composite(std::move(mask), tvg::CompositeMethod::LumaMask);
mask->mask(std::move(nMask), tvg::MaskMethod::Luma);
shape->mask(std::move(mask), tvg::MaskMethod::Luma);
canvas->push(std::move(shape));
//SVG
@ -63,7 +63,7 @@ struct UserExample : tvgexam::Example
mask2->appendCircle(150, 500, 75, 75);
mask2->appendRect(150, 500, 200, 200, 30, 30);
mask2->fill(255, 255, 255);
svg->composite(std::move(mask2), tvg::CompositeMethod::LumaMask);
svg->mask(std::move(mask2), tvg::MaskMethod::Luma);
canvas->push(std::move(svg));
//Star
@ -87,7 +87,7 @@ struct UserExample : tvgexam::Example
auto mask3 = tvg::Shape::gen();
mask3->appendCircle(600, 200, 125, 125);
mask3->fill(0, 255, 255);
star->composite(std::move(mask3), tvg::CompositeMethod::LumaMask);
star->mask(std::move(mask3), tvg::MaskMethod::Luma);
canvas->push(std::move(star));
//Image
@ -111,7 +111,7 @@ struct UserExample : tvgexam::Example
mask4_circle->fill(128, 0, 128);
mask4->push(std::move(mask4_rect));
mask4->push(std::move(mask4_circle));
image->composite(std::move(mask4), tvg::CompositeMethod::LumaMask);
image->mask(std::move(mask4), tvg::MaskMethod::Luma);
canvas->push(std::move(image));
free(data);

View file

@ -47,8 +47,8 @@ struct UserExample : tvgexam::Example
nMask->appendCircle(220, 220, 125, 125);
nMask->fill(255, 255, 255); //AlphaMask RGB channels are unused.
mask->composite(std::move(nMask), tvg::CompositeMethod::AlphaMask);
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
mask->mask(std::move(nMask), tvg::MaskMethod::Alpha);
shape->mask(std::move(mask), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape));
//SVG
@ -63,7 +63,7 @@ struct UserExample : tvgexam::Example
mask2->appendCircle(150, 500, 75, 75);
mask2->appendRect(150, 500, 200, 200, 30, 30);
mask2->fill(255, 255, 255); //AlphaMask RGB channels are unused.
svg->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
svg->mask(std::move(mask2), tvg::MaskMethod::Alpha);
canvas->push(std::move(svg));
//Star
@ -89,7 +89,7 @@ struct UserExample : tvgexam::Example
mask3->appendCircle(600, 200, 125, 125);
mask3->fill(255, 255, 255); //AlphaMask RGB channels are unused.
mask3->opacity(200);
star->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
star->mask(std::move(mask3), tvg::MaskMethod::Alpha);
canvas->push(std::move(star));
//Image
@ -118,7 +118,7 @@ struct UserExample : tvgexam::Example
mask4->close();
mask4->fill(255, 255, 255); //AlphaMask RGB channels are unused.
mask4->opacity(70);
image->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
image->mask(std::move(mask4), tvg::MaskMethod::Alpha);
canvas->push(std::move(image));
free(data);

View file

@ -58,8 +58,8 @@ struct UserExample : tvgexam::Example
auto add = tvg::Shape::gen();
add->appendCircle(175, 100, 50, 50);
add->fill(255, 255, 255);
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
mask->mask(std::move(add), tvg::MaskMethod::Add);
shape->mask(std::move(mask), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape));
//Shape + Shape Mask Subtract
@ -74,8 +74,8 @@ struct UserExample : tvgexam::Example
auto sub = tvg::Shape::gen();
sub->appendCircle(400, 100, 50, 50);
sub->fill(255, 255, 255);
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
shape2->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
mask2->mask(std::move(sub), tvg::MaskMethod::Subtract);
shape2->mask(std::move(mask2), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape2));
//Shape + Shape Mask Intersect
@ -90,8 +90,8 @@ struct UserExample : tvgexam::Example
auto inter = tvg::Shape::gen();
inter->appendCircle(650, 100, 50, 50);
inter->fill(255, 255, 255);
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
shape3->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
mask3->mask(std::move(inter), tvg::MaskMethod::Intersect);
shape3->mask(std::move(mask3), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape3));
//Shape + Shape Mask Difference
@ -106,8 +106,8 @@ struct UserExample : tvgexam::Example
auto diff = tvg::Shape::gen();
diff->appendCircle(900, 100, 50, 50);
diff->fill(255, 255, 255);
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
shape4->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
mask4->mask(std::move(diff), tvg::MaskMethod::Difference);
shape4->mask(std::move(mask4), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape4));
//Shape + Shape Mask Lighten
@ -122,8 +122,8 @@ struct UserExample : tvgexam::Example
auto light = tvg::Shape::gen();
light->appendCircle(1150, 100, 50, 50);
light->fill(255, 255, 255);
mask5->composite(std::move(light), tvg::CompositeMethod::LightenMask);
shape5->composite(std::move(mask5), tvg::CompositeMethod::AlphaMask);
mask5->mask(std::move(light), tvg::MaskMethod::Lighten);
shape5->mask(std::move(mask5), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape5));
//Shape + Shape Mask Darken
@ -138,8 +138,8 @@ struct UserExample : tvgexam::Example
auto dark = tvg::Shape::gen();
dark->appendCircle(1400, 100, 50, 50);
dark->fill(255, 255, 255);
mask6->composite(std::move(dark), tvg::CompositeMethod::DarkenMask);
shape6->composite(std::move(mask6), tvg::CompositeMethod::AlphaMask);
mask6->mask(std::move(dark), tvg::MaskMethod::Darken);
shape6->mask(std::move(mask6), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape6));
}
{
@ -155,8 +155,8 @@ struct UserExample : tvgexam::Example
auto add = tvg::Shape::gen();
add->appendCircle(175, 300, 50, 50);
add->fill(255, 255, 255);
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
shape->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask);
mask->mask(std::move(add), tvg::MaskMethod::Add);
shape->mask(std::move(mask), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape));
//Shape + Shape Mask Subtract
@ -171,8 +171,8 @@ struct UserExample : tvgexam::Example
auto sub = tvg::Shape::gen();
sub->appendCircle(400, 300, 50, 50);
sub->fill(255, 255, 255);
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
shape2->composite(std::move(mask2), tvg::CompositeMethod::InvAlphaMask);
mask2->mask(std::move(sub), tvg::MaskMethod::Subtract);
shape2->mask(std::move(mask2), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape2));
//Shape + Shape Mask Intersect
@ -187,8 +187,8 @@ struct UserExample : tvgexam::Example
auto inter = tvg::Shape::gen();
inter->appendCircle(650, 300, 50, 50);
inter->fill(255, 255, 255);
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
shape3->composite(std::move(mask3), tvg::CompositeMethod::InvAlphaMask);
mask3->mask(std::move(inter), tvg::MaskMethod::Intersect);
shape3->mask(std::move(mask3), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape3));
//Shape + Shape Mask Difference
@ -203,8 +203,8 @@ struct UserExample : tvgexam::Example
auto diff = tvg::Shape::gen();
diff->appendCircle(900, 300, 50, 50);
diff->fill(255, 255, 255);
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
shape4->composite(std::move(mask4), tvg::CompositeMethod::InvAlphaMask);
mask4->mask(std::move(diff), tvg::MaskMethod::Difference);
shape4->mask(std::move(mask4), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape4));
//Shape + Shape Mask Lighten
@ -219,8 +219,8 @@ struct UserExample : tvgexam::Example
auto light = tvg::Shape::gen();
light->appendCircle(1150, 300, 50, 50);
light->fill(255, 255, 255);
mask5->composite(std::move(light), tvg::CompositeMethod::LightenMask);
shape5->composite(std::move(mask5), tvg::CompositeMethod::InvAlphaMask);
mask5->mask(std::move(light), tvg::MaskMethod::Lighten);
shape5->mask(std::move(mask5), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape5));
//Shape + Shape Mask Darken
@ -235,8 +235,8 @@ struct UserExample : tvgexam::Example
auto dark = tvg::Shape::gen();
dark->appendCircle(1400, 300, 50, 50);
dark->fill(255, 255, 255);
mask6->composite(std::move(dark), tvg::CompositeMethod::DarkenMask);
shape6->composite(std::move(mask6), tvg::CompositeMethod::InvAlphaMask);
mask6->mask(std::move(dark), tvg::MaskMethod::Darken);
shape6->mask(std::move(mask6), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(shape6));
}
{
@ -252,8 +252,8 @@ struct UserExample : tvgexam::Example
auto add = tvg::Shape::gen();
add->appendRect(125, 450, 100, 100);
add->fill(255, 255, 255);
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
mask->mask(std::move(add), tvg::MaskMethod::Add);
shape->mask(std::move(mask), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape));
//Rect + Rect Mask Subtract
@ -268,8 +268,8 @@ struct UserExample : tvgexam::Example
auto sub = tvg::Shape::gen();
sub->appendRect(375, 450, 100, 100);
sub->fill(255, 255, 255);
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
shape2->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
mask2->mask(std::move(sub), tvg::MaskMethod::Subtract);
shape2->mask(std::move(mask2), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape2));
//Rect + Rect Mask Intersect
@ -284,8 +284,8 @@ struct UserExample : tvgexam::Example
auto inter = tvg::Shape::gen();
inter->appendRect(625, 450, 100, 100);
inter->fill(255, 255, 255);
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
shape3->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
mask3->mask(std::move(inter), tvg::MaskMethod::Intersect);
shape3->mask(std::move(mask3), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape3));
//Rect + Rect Mask Difference
@ -300,8 +300,8 @@ struct UserExample : tvgexam::Example
auto diff = tvg::Shape::gen();
diff->appendRect(875, 450, 100, 100);
diff->fill(255, 255, 255);
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
shape4->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
mask4->mask(std::move(diff), tvg::MaskMethod::Difference);
shape4->mask(std::move(mask4), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape4));
//Rect + Rect Mask Lighten
@ -316,8 +316,8 @@ struct UserExample : tvgexam::Example
auto light = tvg::Shape::gen();
light->appendRect(1175, 450, 100, 100);
light->fill(255, 255, 255);
mask5->composite(std::move(light), tvg::CompositeMethod::LightenMask);
shape5->composite(std::move(mask5), tvg::CompositeMethod::AlphaMask);
mask5->mask(std::move(light), tvg::MaskMethod::Lighten);
shape5->mask(std::move(mask5), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape5));
//Rect + Rect Mask Darken
@ -332,8 +332,8 @@ struct UserExample : tvgexam::Example
auto dark = tvg::Shape::gen();
dark->appendRect(1400, 450, 100, 100);
dark->fill(255, 255, 255);
mask6->composite(std::move(dark), tvg::CompositeMethod::DarkenMask);
shape6->composite(std::move(mask6), tvg::CompositeMethod::AlphaMask);
mask6->mask(std::move(dark), tvg::MaskMethod::Darken);
shape6->mask(std::move(mask6), tvg::MaskMethod::Alpha);
canvas->push(std::move(shape6));
}
{
@ -351,8 +351,8 @@ struct UserExample : tvgexam::Example
auto add = tvg::Shape::gen();
add->appendCircle(150, 750, 50, 50);
add->fill(255, 255, 255);
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
image->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
mask->mask(std::move(add), tvg::MaskMethod::Add);
image->mask(std::move(mask), tvg::MaskMethod::Alpha);
canvas->push(std::move(image));
//Transformed Image + Shape Mask Subtract
@ -369,8 +369,8 @@ struct UserExample : tvgexam::Example
auto sub = tvg::Shape::gen();
sub->appendCircle(400, 750, 50, 50);
sub->fill(255, 255, 255);
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
image2->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask);
mask2->mask(std::move(sub), tvg::MaskMethod::Subtract);
image2->mask(std::move(mask2), tvg::MaskMethod::Alpha);
canvas->push(std::move(image2));
//Transformed Image + Shape Mask Intersect
@ -387,8 +387,8 @@ struct UserExample : tvgexam::Example
auto inter = tvg::Shape::gen();
inter->appendCircle(650, 750, 50, 50);
inter->fill(255, 255, 255, 127);
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
image3->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
mask3->mask(std::move(inter), tvg::MaskMethod::Intersect);
image3->mask(std::move(mask3), tvg::MaskMethod::Alpha);
canvas->push(std::move(image3));
//Transformed Image + Shape Mask Difference
@ -405,8 +405,8 @@ struct UserExample : tvgexam::Example
auto diff = tvg::Shape::gen();
diff->appendCircle(900, 750, 50, 50);
diff->fill(255, 255, 255);
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
image4->composite(std::move(mask4), tvg::CompositeMethod::AlphaMask);
mask4->mask(std::move(diff), tvg::MaskMethod::Difference);
image4->mask(std::move(mask4), tvg::MaskMethod::Alpha);
canvas->push(std::move(image4));
//Transformed Image + Shape Mask Lighten
@ -423,8 +423,8 @@ struct UserExample : tvgexam::Example
auto light = tvg::Shape::gen();
light->appendCircle(1150, 750, 50, 50);
light->fill(255, 255, 255);
mask5->composite(std::move(light), tvg::CompositeMethod::LightenMask);
image5->composite(std::move(mask5), tvg::CompositeMethod::AlphaMask);
mask5->mask(std::move(light), tvg::MaskMethod::Lighten);
image5->mask(std::move(mask5), tvg::MaskMethod::Alpha);
canvas->push(std::move(image5));
//Transformed Image + Shape Mask Darken
@ -441,8 +441,8 @@ struct UserExample : tvgexam::Example
auto dark = tvg::Shape::gen();
dark->appendCircle(1400, 750, 50, 50);
dark->fill(255, 255, 255);
mask6->composite(std::move(dark), tvg::CompositeMethod::DarkenMask);
image6->composite(std::move(mask6), tvg::CompositeMethod::AlphaMask);
mask6->mask(std::move(dark), tvg::MaskMethod::Darken);
image6->mask(std::move(mask6), tvg::MaskMethod::Alpha);
canvas->push(std::move(image6));
}
{
@ -460,8 +460,8 @@ struct UserExample : tvgexam::Example
auto add = tvg::Shape::gen();
add->appendCircle(150, 950, 50, 50);
add->fill(255, 255, 255);
mask->composite(std::move(add), tvg::CompositeMethod::AddMask);
image->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask);
mask->mask(std::move(add), tvg::MaskMethod::Add);
image->mask(std::move(mask), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image));
//Transformed Image + Shape Mask Subtract
@ -478,8 +478,8 @@ struct UserExample : tvgexam::Example
auto sub = tvg::Shape::gen();
sub->appendCircle(400, 950, 50, 50);
sub->fill(255, 255, 255);
mask2->composite(std::move(sub), tvg::CompositeMethod::SubtractMask);
image2->composite(std::move(mask2), tvg::CompositeMethod::InvAlphaMask);
mask2->mask(std::move(sub), tvg::MaskMethod::Subtract);
image2->mask(std::move(mask2), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image2));
//Transformed Image + Shape Mask Intersect
@ -496,8 +496,8 @@ struct UserExample : tvgexam::Example
auto inter = tvg::Shape::gen();
inter->appendCircle(650, 950, 50, 50);
inter->fill(255, 255, 255, 127);
mask3->composite(std::move(inter), tvg::CompositeMethod::IntersectMask);
image3->composite(std::move(mask3), tvg::CompositeMethod::InvAlphaMask);
mask3->mask(std::move(inter), tvg::MaskMethod::Intersect);
image3->mask(std::move(mask3), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image3));
//Transformed Image + Shape Mask Difference
@ -514,8 +514,8 @@ struct UserExample : tvgexam::Example
auto diff = tvg::Shape::gen();
diff->appendCircle(900, 950, 50, 50);
diff->fill(255, 255, 255);
mask4->composite(std::move(diff), tvg::CompositeMethod::DifferenceMask);
image4->composite(std::move(mask4), tvg::CompositeMethod::InvAlphaMask);
mask4->mask(std::move(diff), tvg::MaskMethod::Difference);
image4->mask(std::move(mask4), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image4));
//Transformed Image + Shape Mask Lighten
@ -532,8 +532,8 @@ struct UserExample : tvgexam::Example
auto light = tvg::Shape::gen();
light->appendCircle(1150, 950, 50, 50);
light->fill(255, 255, 255);
mask5->composite(std::move(light), tvg::CompositeMethod::LightenMask);
image5->composite(std::move(mask5), tvg::CompositeMethod::InvAlphaMask);
mask5->mask(std::move(light), tvg::MaskMethod::Lighten);
image5->mask(std::move(mask5), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image5));
//Transformed Image + Shape Mask Darken
@ -550,8 +550,8 @@ struct UserExample : tvgexam::Example
auto dark = tvg::Shape::gen();
dark->appendCircle(1400, 950, 50, 50);
dark->fill(255, 255, 255);
mask6->composite(std::move(dark), tvg::CompositeMethod::DarkenMask);
image6->composite(std::move(mask6), tvg::CompositeMethod::InvAlphaMask);
mask6->mask(std::move(dark), tvg::MaskMethod::Darken);
image6->mask(std::move(mask6), tvg::MaskMethod::InvAlpha);
canvas->push(std::move(image6));
}
free(data);

View file

@ -44,7 +44,7 @@ struct UserExample : tvgexam::Example
auto picture = tvg::Picture::gen();
picture->load(EXAMPLE_DIR"/svg/tiger.svg");
picture->size(w, h);
picture->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
picture->mask(std::move(mask), tvg::MaskMethod::Alpha);
pPicture = picture.get();
canvas->push(std::move(picture));

View file

@ -45,7 +45,7 @@ struct UserExample : tvgexam::Example
auto picture = tvg::Picture::gen();
if (!tvgexam::verify(picture->load(EXAMPLE_DIR"/svg/tiger.svg"))) return false;
picture->size(w, h);
picture->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
picture->mask(std::move(mask), tvg::MaskMethod::Alpha);
pPicture = picture.get();
canvas->push(std::move(picture));

View file

@ -159,25 +159,25 @@ enum class FillRule : uint8_t
/**
* @brief Enumeration indicating the method used in the composition of two objects - the target and the source.
* @brief Enumeration indicating the method used in the mask of two objects - the target and the source.
*
* Notation: S(Source), T(Target), SA(Source Alpha), TA(Target Alpha)
*
* @see Paint::composite()
* @see Paint::mask()
*/
enum class CompositeMethod : uint8_t
enum class MaskMethod : uint8_t
{
None = 0, ///< No composition is applied.
AlphaMask, ///< Alpha Masking using the compositing target's pixels as an alpha value.
InvAlphaMask, ///< Alpha Masking using the complement to the compositing target's pixels as an alpha value.
LumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the compositing target's pixels. @since 0.9
InvLumaMask, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the complement to the compositing target's pixels. @since 0.11
AddMask, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API)
SubtractMask, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API)
IntersectMask, ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) (Experimental API)
DifferenceMask, ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API)
LightenMask, ///< Where multiple masks intersect, the highest transparency value is used. (Experimental API)
DarkenMask ///< Where multiple masks intersect, the lowest transparency value is used. (Experimental API)
None = 0, ///< No Masking is applied.
Alpha, ///< Alpha Masking using the masking target's pixels as an alpha value.
InvAlpha, ///< Alpha Masking using the complement to the masking target's pixels as an alpha value.
Luma, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the masking target's pixels. @since 0.9
InvLuma, ///< Alpha Masking using the grayscale (0.2125R + 0.7154G + 0.0721*B) of the complement to the masking target's pixels. @since 0.11
Add, ///< Combines the target and source objects pixels using target alpha. (T * TA) + (S * (255 - TA)) (Experimental API)
Subtract, ///< Subtracts the source color from the target color while considering their respective target alpha. (T * TA) - (S * (255 - TA)) (Experimental API)
Intersect, ///< Computes the result by taking the minimum value between the target alpha and the source alpha and multiplies it with the target color. (T * min(TA, SA)) (Experimental API)
Difference, ///< Calculates the absolute difference between the target color and the source color multiplied by the complement of the target alpha. abs(T - S * (255 - TA)) (Experimental API)
Lighten, ///< Where multiple masks intersect, the highest transparency value is used. (Experimental API)
Darken ///< Where multiple masks intersect, the lowest transparency value is used. (Experimental API)
};
@ -370,12 +370,12 @@ public:
Result opacity(uint8_t o) noexcept;
/**
* @brief Sets the composition target object and the composition method.
* @brief Sets the masking target object and the masking method.
*
* @param[in] target The paint of the target object.
* @param[in] method The method used to composite the source object with the target.
* @param[in] method The method used to mask the source object with the target.
*/
Result composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept;
Result mask(std::unique_ptr<Paint> target, MaskMethod method) noexcept;
/**
* @brief Clip the drawing region of the paint object.
@ -437,15 +437,15 @@ public:
uint8_t opacity() const noexcept;
/**
* @brief Gets the composition target object and the composition method.
* @brief Gets the masking target object and the masking method.
*
* @param[out] target The paint of the target object.
*
* @return The method used to composite the source object with the target.
* @return The method used to mask the source object with the target.
*
* @since 0.5
*/
CompositeMethod composite(const Paint** target) const noexcept;
MaskMethod mask(const Paint** target) const noexcept;
/**
* @brief Returns the ID value of this class.

View file

@ -132,17 +132,17 @@ typedef enum {
/**
* \brief Enumeration indicating the method used in the composition of two objects - the target and the source.
* \brief Enumeration indicating the method used in the masking of two objects - the target and the source.
*
* \ingroup ThorVGCapi_Paint
*/
typedef enum {
TVG_COMPOSITE_METHOD_NONE = 0, ///< No composition is applied.
TVG_COMPOSITE_METHOD_ALPHA_MASK, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible.
TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible.
TVG_COMPOSITE_METHOD_LUMA_MASK, ///< The source pixels are converted to grayscale (luma value) and alpha blended with the target. As a result, only the part of the source which intersects with the target is visible. \since 0.9
TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK ///< The source pixels are converted to grayscale (luma value) and complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. \since 0.14
} Tvg_Composite_Method;
TVG_MASK_METHOD_NONE = 0, ///< No masking is applied.
TVG_MASK_METHOD_ALPHA, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which intersects with the target is visible.
TVG_MASK_METHOD_INVERSE_ALPHA, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible.
TVG_MASK_METHOD_LUMA, ///< The source pixels are converted to grayscale (luma value) and alpha blended with the target. As a result, only the part of the source which intersects with the target is visible. \since 0.9
TVG_MASK_METHOD_INVERSE_LUMA ///< The source pixels are converted to grayscale (luma value) and complement to the target's pixels are alpha blended. As a result, only the part of the source which is not covered by the target is visible. \since 0.14
} Tvg_Mask_Method;
/**
* @brief Enumeration indicates the method used for blending paint. Please refer to the respective formulas for each method.
@ -938,29 +938,29 @@ TVG_API Tvg_Result tvg_paint_get_bounds(const Tvg_Paint* paint, float* x, float*
/*!
* \brief Sets the composition target object and the composition method.
* \brief Sets the masking target object and the masking method.
*
* \param[in] paint The source object of the composition.
* \param[in] target The target object of the composition.
* \param[in] method The method used to composite the source object with the target.
* \param[in] paint The source object of the masking.
* \param[in] target The target object of the masking.
* \param[in] method The method used to mask the source object with the target.
*
* \return Tvg_Result enumeration.
* \retval TVG_RESULT_INVALID_ARGUMENT An invalid @p paint or @p target object or the @p method equal to TVG_COMPOSITE_METHOD_NONE.
* \retval TVG_RESULT_INVALID_ARGUMENT An invalid @p paint or @p target object or the @p method equal to TVG_MASK_METHOD_NONE.
*/
TVG_API Tvg_Result tvg_paint_set_composite_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Composite_Method method);
TVG_API Tvg_Result tvg_paint_set_mask_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Mask_Method method);
/**
* \brief Gets the composition target object and the composition method.
* \brief Gets the masking target object and the masking method.
*
* \param[in] paint The source object of the composition.
* \param[out] target The target object of the composition.
* \param[out] method The method used to composite the source object with the target.
* \param[in] paint The source object of the masking.
* \param[out] target The target object of the masking.
* \param[out] method The method used to mask the source object with the target.
*
* \return Tvg_Result enumeration.
* \retval TVG_RESULT_INVALID_ARGUMENT A @c nullptr is passed as the argument.
*/
TVG_API Tvg_Result tvg_paint_get_composite_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Composite_Method* method);
TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Mask_Method* method);
/*!

View file

@ -216,17 +216,17 @@ TVG_API Tvg_Result tvg_paint_get_bounds(const Tvg_Paint* paint, float* x, float*
}
TVG_API Tvg_Result tvg_paint_set_composite_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Composite_Method method)
TVG_API Tvg_Result tvg_paint_set_mask_method(Tvg_Paint* paint, Tvg_Paint* target, Tvg_Mask_Method method)
{
if (!paint) return TVG_RESULT_INVALID_ARGUMENT;
return (Tvg_Result) reinterpret_cast<Paint*>(paint)->composite(unique_ptr<Paint>((Paint*)(target)), (CompositeMethod)method);
return (Tvg_Result) reinterpret_cast<Paint*>(paint)->mask(unique_ptr<Paint>((Paint*)(target)), (MaskMethod)method);
}
TVG_API Tvg_Result tvg_paint_get_composite_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Composite_Method* method)
TVG_API Tvg_Result tvg_paint_get_mask_method(const Tvg_Paint* paint, const Tvg_Paint** target, Tvg_Mask_Method* method)
{
if (!paint || !target || !method) return TVG_RESULT_INVALID_ARGUMENT;
*reinterpret_cast<CompositeMethod*>(method) = reinterpret_cast<const Paint*>(paint)->composite(reinterpret_cast<const Paint**>(target));
*reinterpret_cast<MaskMethod*>(method) = reinterpret_cast<const Paint*>(paint)->mask(reinterpret_cast<const Paint**>(target));
return TVG_RESULT_SUCCESS;
}

View file

@ -1143,10 +1143,10 @@ void LottieBuilder::updateMaskings(LottieLayer* layer, float frameNo)
pMask->pathset(frameNo, P(pShape)->rs.path.cmds, P(pShape)->rs.path.pts, nullptr, nullptr, &offset, exps);
}
auto compMethod = (pMethod == CompositeMethod::SubtractMask || pMethod == CompositeMethod::InvAlphaMask) ? CompositeMethod::InvAlphaMask : CompositeMethod::AlphaMask;
auto compMethod = (pMethod == MaskMethod::Subtract || pMethod == MaskMethod::InvAlpha) ? MaskMethod::InvAlpha : MaskMethod::Alpha;
//Cheaper. Replace the masking with a clipper
if (layer->masks.count == 1 && compMethod == CompositeMethod::AlphaMask && opacity == 255) {
if (layer->masks.count == 1 && compMethod == MaskMethod::Alpha && opacity == 255) {
layer->scene->clip(tvg::cast(pShape));
return;
}
@ -1158,16 +1158,16 @@ void LottieBuilder::updateMaskings(LottieLayer* layer, float frameNo)
layer->scene = scene;
}
layer->scene->composite(tvg::cast(pShape), compMethod);
layer->scene->mask(tvg::cast(pShape), compMethod);
//Apply the subsquent masks
for (auto m = layer->masks.begin() + 1; m < layer->masks.end(); ++m) {
auto mask = static_cast<LottieMask*>(*m);
auto method = mask->method;
if (method == CompositeMethod::None) continue;
if (method == MaskMethod::None) continue;
//Append the mask shape
if (pMethod == method && (method == CompositeMethod::SubtractMask || method == CompositeMethod::DifferenceMask)) {
if (pMethod == method && (method == MaskMethod::Subtract || method == MaskMethod::Difference)) {
mask->pathset(frameNo, P(pShape)->rs.path.cmds, P(pShape)->rs.path.pts, nullptr, nullptr, nullptr, exps);
//Chain composition
} else {
@ -1176,7 +1176,7 @@ void LottieBuilder::updateMaskings(LottieLayer* layer, float frameNo)
shape->fill(255, 255, 255, mask->opacity(frameNo));
shape->transform(layer->cache.matrix);
mask->pathset(frameNo, P(shape)->rs.path.cmds, P(shape)->rs.path.pts, nullptr, nullptr, nullptr, exps);
pShape->composite(tvg::cast(shape), method);
pShape->mask(tvg::cast(shape), method);
pShape = shape;
pMethod = method;
}
@ -1192,8 +1192,8 @@ bool LottieBuilder::updateMatte(LottieComposition* comp, float frameNo, Scene* s
updateLayer(comp, scene, target, frameNo);
if (target->scene) {
layer->scene->composite(cast(target->scene), layer->matteType);
} else if (layer->matteType == CompositeMethod::AlphaMask || layer->matteType == CompositeMethod::LumaMask) {
layer->scene->mask(cast(target->scene), layer->matteType);
} else if (layer->matteType == MaskMethod::Alpha || layer->matteType == MaskMethod::Luma) {
//matte target is not exist. alpha blending definitely bring an invisible result
delete(layer->scene);
layer->scene = nullptr;
@ -1357,7 +1357,7 @@ static bool _buildComposition(LottieComposition* comp, LottieLayer* parent)
//attach the precomp layer.
if (child->rid) _buildReference(comp, child);
if (child->matteType != CompositeMethod::None) {
if (child->matteType != MaskMethod::None) {
//no index of the matte layer is provided: the layer above is used as the matte source
if (child->mid == -1) {
if (c > parent->children.begin()) {

View file

@ -245,7 +245,7 @@ bool LottieLoader::resize(Paint* paint, float w, float h)
//apply the scale to the base clipper
const Paint* clipper;
paint->composite(&clipper);
paint->mask(&clipper);
if (clipper) const_cast<Paint*>(clipper)->transform(m);
return true;

View file

@ -109,7 +109,7 @@ struct LottieMask
LottiePathSet pathset;
LottieFloat expand = 0.0f;
LottieOpacity opacity = 255;
CompositeMethod method;
MaskMethod method;
bool inverse = false;
};
@ -788,7 +788,7 @@ struct LottieLayer : LottieGroup
uint8_t opacity;
} cache;
CompositeMethod matteType = CompositeMethod::None;
MaskMethod matteType = MaskMethod::None;
BlendMethod blendMethod = BlendMethod::Normal;
Type type = Null;
bool autoOrient = false;

View file

@ -66,22 +66,22 @@ LottieEffect* LottieParser::getEffect(int type)
}
CompositeMethod LottieParser::getMaskMethod(bool inversed)
MaskMethod LottieParser::getMaskMethod(bool inversed)
{
auto mode = getString();
if (!mode) return CompositeMethod::None;
if (!mode) return MaskMethod::None;
switch (mode[0]) {
case 'a': {
if (inversed) return CompositeMethod::InvAlphaMask;
else return CompositeMethod::AddMask;
if (inversed) return MaskMethod::InvAlpha;
else return MaskMethod::Add;
}
case 's': return CompositeMethod::SubtractMask;
case 'i': return CompositeMethod::IntersectMask;
case 'f': return CompositeMethod::DifferenceMask;
case 'l': return CompositeMethod::LightenMask;
case 'd': return CompositeMethod::DarkenMask;
default: return CompositeMethod::None;
case 's': return MaskMethod::Subtract;
case 'i': return MaskMethod::Intersect;
case 'f': return MaskMethod::Difference;
case 'l': return MaskMethod::Lighten;
case 'd': return MaskMethod::Darken;
default: return MaskMethod::None;
}
}
@ -123,14 +123,14 @@ FillRule LottieParser::getFillRule()
}
CompositeMethod LottieParser::getMatteType()
MaskMethod LottieParser::getMatteType()
{
switch (getInt()) {
case 1: return CompositeMethod::AlphaMask;
case 2: return CompositeMethod::InvAlphaMask;
case 3: return CompositeMethod::LumaMask;
case 4: return CompositeMethod::InvLumaMask;
default: return CompositeMethod::None;
case 1: return MaskMethod::Alpha;
case 2: return MaskMethod::InvAlpha;
case 3: return MaskMethod::Luma;
case 4: return MaskMethod::InvLuma;
default: return MaskMethod::None;
}
}
@ -1229,7 +1229,7 @@ LottieMask* LottieParser::parseMask()
else if (KEY_AS("mode"))
{
mask->method = getMaskMethod(mask->inverse);
if (mask->method == CompositeMethod::None) valid = false;
if (mask->method == MaskMethod::None) valid = false;
}
else if (valid && KEY_AS("pt")) getPathSet(mask->pathset);
else if (valid && KEY_AS("o")) parseProperty<LottieProperty::Type::Opacity>(mask->opacity);

View file

@ -44,11 +44,11 @@ public:
private:
RGB24 getColor(const char *str);
CompositeMethod getMatteType();
MaskMethod getMatteType();
FillRule getFillRule();
StrokeCap getStrokeCap();
StrokeJoin getStrokeJoin();
CompositeMethod getMaskMethod(bool inversed);
MaskMethod getMaskMethod(bool inversed);
LottieInterpolator* getInterpolator(const char* key, Point& in, Point& out);
LottieEffect* getEffect(int type);

View file

@ -287,9 +287,9 @@ static void _applyComposition(SvgLoaderData& loaderData, Paint* paint, const Svg
}
if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) {
paint->composite(std::move(comp), CompositeMethod::LumaMask);
paint->mask(std::move(comp), MaskMethod::Luma);
} else {
paint->composite(std::move(comp), CompositeMethod::AlphaMask);
paint->mask(std::move(comp), MaskMethod::Alpha);
}
}
@ -918,12 +918,12 @@ Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, Aspe
auto viewBoxClip = Shape::gen();
viewBoxClip->appendRect(0, 0, w, h);
auto compositeLayer = Scene::gen();
compositeLayer->clip(std::move(viewBoxClip));
compositeLayer->push(std::move(docNode));
auto clippingLayer = Scene::gen();
clippingLayer->clip(std::move(viewBoxClip));
clippingLayer->push(std::move(docNode));
auto root = Scene::gen();
root->push(std::move(compositeLayer));
root->push(std::move(clippingLayer));
loaderData.doc->node.doc.vx = vBox.x;
loaderData.doc->node.doc.vy = vBox.y;

View file

@ -751,7 +751,7 @@ void GlRenderer::prepareCmpTask(GlRenderTask* task, const RenderRegion& vp, uint
void GlRenderer::endRenderPass(RenderCompositor* cmp)
{
auto gl_cmp = static_cast<GlCompositor*>(cmp);
if (cmp->method != CompositeMethod::None) {
if (cmp->method != MaskMethod::None) {
auto self_pass = std::move(mRenderPassStack.back());
mRenderPassStack.pop_back();
@ -763,43 +763,41 @@ void GlRenderer::endRenderPass(RenderCompositor* cmp)
GlProgram* program = nullptr;
switch(cmp->method) {
case CompositeMethod::AlphaMask:
case MaskMethod::Alpha:
program = mPrograms[RT_MaskAlpha].get();
break;
case CompositeMethod::InvAlphaMask:
case MaskMethod::InvAlpha:
program = mPrograms[RT_MaskAlphaInv].get();
break;
case CompositeMethod::LumaMask:
case MaskMethod::Luma:
program = mPrograms[RT_MaskLuma].get();
break;
case CompositeMethod::InvLumaMask:
case MaskMethod::InvLuma:
program = mPrograms[RT_MaskLumaInv].get();
break;
case CompositeMethod::AddMask:
case MaskMethod::Add:
program = mPrograms[RT_MaskAdd].get();
break;
case CompositeMethod::SubtractMask:
case MaskMethod::Subtract:
program = mPrograms[RT_MaskSub].get();
break;
case CompositeMethod::IntersectMask:
case MaskMethod::Intersect:
program = mPrograms[RT_MaskIntersect].get();
break;
case CompositeMethod::DifferenceMask:
case MaskMethod::Difference:
program = mPrograms[RT_MaskDifference].get();
break;
case CompositeMethod::LightenMask:
case MaskMethod::Lighten:
program = mPrograms[RT_MaskLighten].get();
break;
case CompositeMethod::DarkenMask:
case MaskMethod::Darken:
program = mPrograms[RT_MaskDarken].get();
break;
default:
break;
}
if (program == nullptr) {
return;
}
if (!program) return;
auto prev_task = mask_pass.endRenderPass<GlComposeTask>(nullptr, currentPass()->getFboId());
prev_task->setDrawDepth(currentPass()->nextDrawDepth());
@ -812,15 +810,8 @@ void GlRenderer::endRenderPass(RenderCompositor* cmp)
prepareCmpTask(compose_task, gl_cmp->bbox, self_pass.getFboWidth(), self_pass.getFboHeight());
{
uint32_t loc = program->getUniformLocation("uSrcTexture");
compose_task->addBindResource(GlBindingResource{0, self_pass.getTextureId(), loc});
}
{
uint32_t loc = program->getUniformLocation("uMaskTexture");
compose_task->addBindResource(GlBindingResource{1, mask_pass.getTextureId(), loc});
}
compose_task->addBindResource(GlBindingResource{0, self_pass.getTextureId(), (uint)program->getUniformLocation("uSrcTexture")});
compose_task->addBindResource(GlBindingResource{1, mask_pass.getTextureId(), (uint)program->getUniformLocation("uMaskTexture")});
compose_task->setDrawDepth(currentPass()->nextDrawDepth());
compose_task->setParentSize(static_cast<uint32_t>(currentPass()->getViewport().w), static_cast<uint32_t>(currentPass()->getViewport().h));
@ -1007,7 +998,7 @@ RenderCompositor* GlRenderer::target(const RenderRegion& region, TVG_UNUSED Colo
}
bool GlRenderer::beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity)
bool GlRenderer::beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity)
{
if (!cmp) return false;

View file

@ -83,7 +83,7 @@ public:
bool clear() override;
RenderCompositor* target(const RenderRegion& region, ColorSpace cs) override;
bool beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity) override;
bool beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity) override;
bool endComposite(RenderCompositor* cmp) override;
bool prepare(RenderEffect* effect) override;

View file

@ -248,7 +248,7 @@ struct SwSurface : RenderSurface
SwCompositor* compositor = nullptr; //compositor (optional)
BlendMethod blendMethod = BlendMethod::Normal;
SwAlpha alpha(CompositeMethod method)
SwAlpha alpha(MaskMethod method)
{
auto idx = (int)(method) - 1; //-1 for None
return alphas[idx > 3 ? 0 : idx]; //CompositeMethod has only four Matting methods.

View file

@ -154,14 +154,14 @@ static inline bool _blending(const SwSurface* surface)
This would help to enhance the performance by avoiding the unnecessary matting from the composition */
static inline bool _compositing(const SwSurface* surface)
{
if (!surface->compositor || surface->compositor->method == CompositeMethod::None) return false;
if (!surface->compositor || surface->compositor->method == MaskMethod::None) return false;
return true;
}
static inline bool _matting(const SwSurface* surface)
{
if ((int)surface->compositor->method < (int)CompositeMethod::AddMask) return true;
if ((int)surface->compositor->method < (int)MaskMethod::Add) return true;
else return false;
}
@ -206,22 +206,22 @@ static inline uint8_t _opMaskDarken(uint8_t s, uint8_t d, uint8_t a)
}
static inline bool _direct(CompositeMethod method)
static inline bool _direct(MaskMethod method)
{
if (method == CompositeMethod::SubtractMask || method == CompositeMethod::IntersectMask || method == CompositeMethod::DarkenMask) return true;
if (method == MaskMethod::Subtract || method == MaskMethod::Intersect || method == MaskMethod::Darken) return true;
return false;
}
static inline SwMask _getMaskOp(CompositeMethod method)
static inline SwMask _getMaskOp(MaskMethod method)
{
switch (method) {
case CompositeMethod::AddMask: return _opMaskAdd;
case CompositeMethod::SubtractMask: return _opMaskSubtract;
case CompositeMethod::DifferenceMask: return _opMaskDifference;
case CompositeMethod::IntersectMask: return _opMaskIntersect;
case CompositeMethod::LightenMask: return _opMaskLighten;
case CompositeMethod::DarkenMask: return _opMaskDarken;
case MaskMethod::Add: return _opMaskAdd;
case MaskMethod::Subtract: return _opMaskSubtract;
case MaskMethod::Difference: return _opMaskDifference;
case MaskMethod::Intersect: return _opMaskIntersect;
case MaskMethod::Lighten: return _opMaskLighten;
case MaskMethod::Darken: return _opMaskDarken;
default: return nullptr;
}
}
@ -1626,7 +1626,7 @@ void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
bool rasterCompositor(SwSurface* surface)
{
//See CompositeMethod, Alpha:3, InvAlpha:4, Luma:5, InvLuma:6
//See MaskMethod, Alpha:3, InvAlpha:4, Luma:5, InvLuma:6
surface->alphas[0] = _alpha;
surface->alphas[1] = _ialpha;

View file

@ -496,7 +496,7 @@ RenderRegion SwRenderer::region(RenderData data)
}
bool SwRenderer::beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity)
bool SwRenderer::beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity)
{
if (!cmp) return false;
auto p = static_cast<SwCompositor*>(cmp);
@ -505,7 +505,7 @@ bool SwRenderer::beginComposite(RenderCompositor* cmp, CompositeMethod method, u
p->opacity = opacity;
//Current Context?
if (p->method != CompositeMethod::None) {
if (p->method != MaskMethod::None) {
surface = p->recoverSfc;
surface->compositor = p;
}
@ -629,7 +629,7 @@ bool SwRenderer::endComposite(RenderCompositor* cmp)
surface->compositor = p->recoverCmp;
//Default is alpha blending
if (p->method == CompositeMethod::None) {
if (p->method == MaskMethod::None) {
Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
return rasterImage(surface, &p->image, m, p->bbox, p->opacity);
}

View file

@ -56,7 +56,7 @@ public:
bool mempool(bool shared);
RenderCompositor* target(const RenderRegion& region, ColorSpace cs) override;
bool beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity) override;
bool beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity) override;
bool endComposite(RenderCompositor* cmp) override;
void clearCompositors();

View file

@ -153,7 +153,7 @@ Iterator* Paint::Impl::iterator()
Paint* Paint::Impl::duplicate(Paint* ret)
{
if (ret) ret->composite(nullptr, CompositeMethod::None);
if (ret) ret->mask(nullptr, MaskMethod::None);
PAINT_METHOD(ret, duplicate(ret));
@ -163,7 +163,7 @@ Paint* Paint::Impl::duplicate(Paint* ret)
ret->pImpl->opacity = opacity;
if (compData) ret->pImpl->composite(ret, compData->target->duplicate(), compData->method);
if (maskData) ret->pImpl->mask(ret, maskData->target->duplicate(), maskData->method);
if (clipper) ret->pImpl->clip(clipper->duplicate());
return ret;
@ -210,19 +210,19 @@ bool Paint::Impl::render(RenderMethod* renderer)
RenderCompositor* cmp = nullptr;
if (compData && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) {
if (maskData && !(maskData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) {
RenderRegion region;
PAINT_METHOD(region, bounds(renderer));
if (MASK_REGION_MERGING(compData->method)) region.add(P(compData->target)->bounds(renderer));
if (MASK_REGION_MERGING(maskData->method)) region.add(P(maskData->target)->bounds(renderer));
if (region.w == 0 || region.h == 0) return true;
cmp = renderer->target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method));
if (renderer->beginComposite(cmp, CompositeMethod::None, 255)) {
compData->target->pImpl->render(renderer);
cmp = renderer->target(region, MASK_TO_COLORSPACE(renderer, maskData->method));
if (renderer->beginComposite(cmp, MaskMethod::None, 255)) {
maskData->target->pImpl->render(renderer);
}
}
if (cmp) renderer->beginComposite(cmp, compData->method, compData->target->pImpl->opacity);
if (cmp) renderer->beginComposite(cmp, maskData->method, maskData->target->pImpl->opacity);
bool ret;
PAINT_METHOD(ret, render(renderer));
@ -248,20 +248,20 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix& pm, Array<R
RenderRegion viewport;
Result compFastTrack = Result::InsufficientCondition;
if (compData) {
auto target = compData->target;
auto method = compData->method;
if (maskData) {
auto target = maskData->target;
auto method = maskData->method;
P(target)->ctxFlag &= ~ContextFlag::FastTrack; //reset
/* If the transformation has no rotational factors and the Alpha(InvAlpha) Masking involves a simple rectangle,
we can optimize by using the viewport instead of the regular AlphaMasking sequence for improved performance. */
we can optimize by using the viewport instead of the regular Alphaing sequence for improved performance. */
if (target->type() == Type::Shape) {
auto shape = static_cast<Shape*>(target);
uint8_t a;
shape->fillColor(nullptr, nullptr, nullptr, &a);
//no gradient fill & no compositions of the composition target.
if (!shape->fill() && !(PP(shape)->compData)) {
if ((method == CompositeMethod::AlphaMask && a == 255 && PP(shape)->opacity == 255) || (method == CompositeMethod::InvAlphaMask && (a == 0 || PP(shape)->opacity == 0))) {
//no gradient fill & no maskings of the masking target.
if (!shape->fill() && !(PP(shape)->maskData)) {
if ((method == MaskMethod::Alpha && a == 255 && PP(shape)->opacity == 255) || (method == MaskMethod::InvAlpha && (a == 0 || PP(shape)->opacity == 0))) {
viewport = renderer->viewport();
if ((compFastTrack = _compFastTrack(renderer, target, pm, viewport)) == Result::Success) {
P(target)->ctxFlag |= ContextFlag::FastTrack;
@ -361,10 +361,10 @@ void Paint::Impl::reset()
clipper = nullptr;
}
if (compData) {
if (P(compData->target)->unref() == 0) delete(compData->target);
free(compData);
compData = nullptr;
if (maskData) {
if (P(maskData->target)->unref() == 0) delete(maskData->target);
free(maskData);
maskData = nullptr;
}
tvg::identity(&tr.m);
@ -455,24 +455,24 @@ Result Paint::clip(std::unique_ptr<Paint> clipper) noexcept
}
Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) noexcept
Result Paint::mask(std::unique_ptr<Paint> target, MaskMethod method) noexcept
{
auto p = target.release();
if (pImpl->composite(this, p, method)) return Result::Success;
if (pImpl->mask(this, p, method)) return Result::Success;
delete(p);
return Result::InvalidArguments;
}
CompositeMethod Paint::composite(const Paint** target) const noexcept
MaskMethod Paint::mask(const Paint** target) const noexcept
{
if (pImpl->compData) {
if (target) *target = pImpl->compData->target;
return pImpl->compData->method;
if (pImpl->maskData) {
if (target) *target = pImpl->maskData->target;
return pImpl->maskData->method;
} else {
if (target) *target = nullptr;
return CompositeMethod::None;
return MaskMethod::None;
}
}

View file

@ -38,17 +38,17 @@ namespace tvg
virtual void begin() = 0;
};
struct Composite
struct Mask
{
Paint* target;
Paint* source;
CompositeMethod method;
MaskMethod method;
};
struct Paint::Impl
{
Paint* paint = nullptr;
Composite* compData = nullptr;
Mask* maskData = nullptr;
Paint* clipper = nullptr;
RenderMethod* renderer = nullptr;
struct {
@ -85,9 +85,9 @@ namespace tvg
~Impl()
{
if (compData) {
if (P(compData->target)->unref() == 0) delete(compData->target);
free(compData);
if (maskData) {
if (P(maskData->target)->unref() == 0) delete(maskData->target);
free(maskData);
}
if (clipper && P(clipper)->unref() == 0) delete(clipper);
if (renderer && (renderer->unref() == 0)) delete(renderer);
@ -136,30 +136,30 @@ namespace tvg
P(clipper)->ref();
}
bool composite(Paint* source, Paint* target, CompositeMethod method)
bool mask(Paint* source, Paint* target, MaskMethod method)
{
//Invalid case
if ((!target && method != CompositeMethod::None) || (target && method == CompositeMethod::None)) return false;
if ((!target && method != MaskMethod::None) || (target && method == MaskMethod::None)) return false;
if (compData) {
P(compData->target)->unref();
if ((compData->target != target) && P(compData->target)->refCnt == 0) {
delete(compData->target);
if (maskData) {
P(maskData->target)->unref();
if ((maskData->target != target) && P(maskData->target)->refCnt == 0) {
delete(maskData->target);
}
//Reset scenario
if (!target && method == CompositeMethod::None) {
free(compData);
compData = nullptr;
if (!target && method == MaskMethod::None) {
free(maskData);
maskData = nullptr;
return true;
}
} else {
if (!target && method == CompositeMethod::None) return true;
compData = static_cast<Composite*>(calloc(1, sizeof(Composite)));
if (!target && method == MaskMethod::None) return true;
maskData = static_cast<Mask*>(malloc(sizeof(Mask)));
}
P(target)->ref();
compData->target = target;
compData->source = source;
compData->method = method;
maskData->target = target;
maskData->source = source;
maskData->method = method;
return true;
}

View file

@ -63,7 +63,7 @@ bool Picture::Impl::needComposition(uint8_t opacity)
//Composition test
const Paint* target;
picture->composite(&target);
picture->mask(&target);
if (!target || target->pImpl->opacity == 255 || target->pImpl->opacity == 0) return false;
return true;
}
@ -79,7 +79,7 @@ bool Picture::Impl::render(RenderMethod* renderer)
RenderCompositor* cmp = nullptr;
if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer->beginComposite(cmp, CompositeMethod::None, 255);
renderer->beginComposite(cmp, MaskMethod::None, 255);
}
ret = paint->pImpl->render(renderer);
if (cmp) renderer->endComposite(cmp);

View file

@ -69,7 +69,7 @@ struct RenderSurface
struct RenderCompositor
{
CompositeMethod method;
MaskMethod method;
uint8_t opacity;
};
@ -314,31 +314,31 @@ public:
virtual bool sync() = 0;
virtual RenderCompositor* target(const RenderRegion& region, ColorSpace cs) = 0;
virtual bool beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity) = 0;
virtual bool beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity) = 0;
virtual bool endComposite(RenderCompositor* cmp) = 0;
virtual bool prepare(RenderEffect* effect) = 0;
virtual bool effect(RenderCompositor* cmp, const RenderEffect* effect) = 0;
};
static inline bool MASK_REGION_MERGING(CompositeMethod method)
static inline bool MASK_REGION_MERGING(MaskMethod method)
{
switch(method) {
case CompositeMethod::AlphaMask:
case CompositeMethod::InvAlphaMask:
case CompositeMethod::LumaMask:
case CompositeMethod::InvLumaMask:
case CompositeMethod::SubtractMask:
case CompositeMethod::IntersectMask:
case MaskMethod::Alpha:
case MaskMethod::InvAlpha:
case MaskMethod::Luma:
case MaskMethod::InvLuma:
case MaskMethod::Subtract:
case MaskMethod::Intersect:
return false;
//these might expand the rendering region
case CompositeMethod::AddMask:
case CompositeMethod::DifferenceMask:
case CompositeMethod::LightenMask:
case CompositeMethod::DarkenMask:
case MaskMethod::Add:
case MaskMethod::Difference:
case MaskMethod::Lighten:
case MaskMethod::Darken:
return true;
default:
TVGERR("RENDERER", "Unsupported Composite Method! = %d", (int)method);
TVGERR("RENDERER", "Unsupported Masking Method! = %d", (int)method);
return false;
}
}
@ -360,24 +360,24 @@ static inline uint8_t CHANNEL_SIZE(ColorSpace cs)
}
}
static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod* renderer, CompositeMethod method)
static inline ColorSpace MASK_TO_COLORSPACE(RenderMethod* renderer, MaskMethod method)
{
switch(method) {
case CompositeMethod::AlphaMask:
case CompositeMethod::InvAlphaMask:
case CompositeMethod::AddMask:
case CompositeMethod::DifferenceMask:
case CompositeMethod::SubtractMask:
case CompositeMethod::IntersectMask:
case CompositeMethod::LightenMask:
case CompositeMethod::DarkenMask:
case MaskMethod::Alpha:
case MaskMethod::InvAlpha:
case MaskMethod::Add:
case MaskMethod::Difference:
case MaskMethod::Subtract:
case MaskMethod::Intersect:
case MaskMethod::Lighten:
case MaskMethod::Darken:
return ColorSpace::Grayscale8;
//TODO: Optimize Luma/InvLuma colorspace to Grayscale8
case CompositeMethod::LumaMask:
case CompositeMethod::InvLumaMask:
case MaskMethod::Luma:
case MaskMethod::InvLuma:
return renderer->colorSpace();
default:
TVGERR("RENDERER", "Unsupported Composite Size! = %d", (int)method);
TVGERR("RENDERER", "Unsupported Masking Size! = %d", (int)method);
return ColorSpace::Unknown;
}
}

View file

@ -90,7 +90,7 @@ struct Scene::Impl
if (effects) return true;
//Masking / Blending may require composition (even if opacity == 255)
if (scene->composite(nullptr) != CompositeMethod::None) return true;
if (scene->mask(nullptr) != MaskMethod::None) return true;
if (PP(scene)->blendMethod != BlendMethod::Normal) return true;
//Half translucent requires intermediate composition.
@ -130,7 +130,7 @@ struct Scene::Impl
if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
renderer->beginComposite(cmp, MaskMethod::None, opacity);
}
for (auto paint : paints) {

View file

@ -59,7 +59,7 @@ struct Shape::Impl
if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
renderer->beginComposite(cmp, CompositeMethod::None, opacity);
renderer->beginComposite(cmp, MaskMethod::None, opacity);
}
auto ret = renderer->renderShape(rd);
@ -80,7 +80,7 @@ struct Shape::Impl
//Composition test
const Paint* target;
auto method = shape->composite(&target);
auto method = shape->mask(&target);
if (!target) return false;
if ((target->pImpl->opacity == 255 || target->pImpl->opacity == 0) && target->type() == Type::Shape) {
@ -89,7 +89,7 @@ struct Shape::Impl
uint8_t r, g, b, a;
shape->fillColor(&r, &g, &b, &a);
if (a == 0 || a == 255) {
if (method == CompositeMethod::LumaMask || method == CompositeMethod::InvLumaMask) {
if (method == MaskMethod::Luma || method == MaskMethod::InvLuma) {
if ((r == 255 && g == 255 && b == 255) || (r == 0 && g == 0 && b == 0)) return false;
} else return false;
}

View file

@ -355,7 +355,7 @@ RenderCompositor* WgRenderer::target(TVG_UNUSED const RenderRegion& region, TVG_
}
bool WgRenderer::beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity)
bool WgRenderer::beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity)
{
// save current composition settings
WgCompose* compose = (WgCompose *)cmp;
@ -380,7 +380,7 @@ bool WgRenderer::endComposite(RenderCompositor* cmp)
// end current render pass
mCompositor.endRenderPass();
// finish scene blending
if (comp->method == CompositeMethod::None) {
if (comp->method == MaskMethod::None) {
// get source and destination render storages
WgRenderStorage* src = mRenderStorageStack.last();
mRenderStorageStack.pop();

View file

@ -49,7 +49,7 @@ public:
bool target(WGPUSurface surface, uint32_t w, uint32_t h);
RenderCompositor* target(const RenderRegion& region, ColorSpace cs) override;
bool beginComposite(RenderCompositor* cmp, CompositeMethod method, uint8_t opacity) override;
bool beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_t opacity) override;
bool endComposite(RenderCompositor* cmp) override;
bool prepare(RenderEffect* effect) override;

View file

@ -261,20 +261,20 @@ TEST_CASE("Paint AlphaMask Composite Method", "[capiPaint]")
Tvg_Paint* target = tvg_shape_new();
REQUIRE(target);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_composite_method(paint, target, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_ALPHA_MASK) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_NONE) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target, TVG_MASK_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_ALPHA) == TVG_RESULT_INVALID_ARGUMENT);
Tvg_Paint* target2 = tvg_shape_new();
REQUIRE(target2);
REQUIRE(tvg_paint_set_composite_method(paint, target2, TVG_COMPOSITE_METHOD_ALPHA_MASK) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target2, TVG_MASK_METHOD_ALPHA) == TVG_RESULT_SUCCESS);
const Tvg_Paint* target3 = nullptr;
Tvg_Composite_Method method = TVG_COMPOSITE_METHOD_NONE;
REQUIRE(tvg_paint_get_composite_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_composite_method(paint, &target3, NULL) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_composite_method(paint, &target3, &method) == TVG_RESULT_SUCCESS);
REQUIRE(method == TVG_COMPOSITE_METHOD_ALPHA_MASK);
Tvg_Mask_Method method = TVG_MASK_METHOD_NONE;
REQUIRE(tvg_paint_get_mask_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_mask_method(paint, &target3, NULL) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_mask_method(paint, &target3, &method) == TVG_RESULT_SUCCESS);
REQUIRE(method == TVG_MASK_METHOD_ALPHA);
REQUIRE(target2 == target3);
REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
@ -288,20 +288,20 @@ TEST_CASE("Paint InvAlphaMask Composite Method", "[capiPaint]")
Tvg_Paint* target = tvg_shape_new();
REQUIRE(target);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_composite_method(paint, target, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_NONE) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target, TVG_MASK_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_INVERSE_ALPHA) == TVG_RESULT_INVALID_ARGUMENT);
Tvg_Paint* target2 = tvg_shape_new();
REQUIRE(target2);
REQUIRE(tvg_paint_set_composite_method(paint, target2, TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target2, TVG_MASK_METHOD_INVERSE_ALPHA) == TVG_RESULT_SUCCESS);
const Tvg_Paint* target3 = nullptr;
Tvg_Composite_Method method = TVG_COMPOSITE_METHOD_NONE;
REQUIRE(tvg_paint_get_composite_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_composite_method(paint, &target3, NULL) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_composite_method(paint, &target3, &method) == TVG_RESULT_SUCCESS);
REQUIRE(method == TVG_COMPOSITE_METHOD_INVERSE_ALPHA_MASK);
Tvg_Mask_Method method = TVG_MASK_METHOD_NONE;
REQUIRE(tvg_paint_get_mask_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_mask_method(paint, &target3, NULL) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_mask_method(paint, &target3, &method) == TVG_RESULT_SUCCESS);
REQUIRE(method == TVG_MASK_METHOD_INVERSE_ALPHA);
REQUIRE(target2 == target3);
REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);
@ -315,25 +315,25 @@ TEST_CASE("Paint LumaMask Composite Method", "[capiPaint]")
Tvg_Paint* target = tvg_shape_new();
REQUIRE(target);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_composite_method(paint, target, TVG_COMPOSITE_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_LUMA_MASK) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_composite_method(paint, NULL, TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_NONE) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target, TVG_MASK_METHOD_NONE) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_LUMA) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_set_mask_method(paint, NULL, TVG_MASK_METHOD_INVERSE_LUMA) == TVG_RESULT_INVALID_ARGUMENT);
Tvg_Paint* target2 = tvg_shape_new();
REQUIRE(target2);
REQUIRE(tvg_paint_set_composite_method(paint, target2, TVG_COMPOSITE_METHOD_LUMA_MASK) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target2, TVG_MASK_METHOD_LUMA) == TVG_RESULT_SUCCESS);
Tvg_Paint* target3 = tvg_shape_new();
REQUIRE(target3);
REQUIRE(tvg_paint_set_composite_method(paint, target3, TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK) == TVG_RESULT_SUCCESS);
REQUIRE(tvg_paint_set_mask_method(paint, target3, TVG_MASK_METHOD_INVERSE_LUMA) == TVG_RESULT_SUCCESS);
const Tvg_Paint* target4 = nullptr;
Tvg_Composite_Method method = TVG_COMPOSITE_METHOD_NONE;
REQUIRE(tvg_paint_get_composite_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_composite_method(paint, &target4, NULL) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_composite_method(paint, &target4, &method) == TVG_RESULT_SUCCESS);
REQUIRE(method == TVG_COMPOSITE_METHOD_INVERSE_LUMA_MASK);
Tvg_Mask_Method method = TVG_MASK_METHOD_NONE;
REQUIRE(tvg_paint_get_mask_method(paint, NULL, &method) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_mask_method(paint, &target4, NULL) == TVG_RESULT_INVALID_ARGUMENT);
REQUIRE(tvg_paint_get_mask_method(paint, &target4, &method) == TVG_RESULT_SUCCESS);
REQUIRE(method == TVG_MASK_METHOD_INVERSE_LUMA);
REQUIRE(target3 == target4);
REQUIRE(tvg_paint_del(paint) == TVG_RESULT_SUCCESS);

View file

@ -207,10 +207,10 @@ TEST_CASE("Composition", "[tvgPaint]")
REQUIRE(shape);
//Negative
REQUIRE(shape->composite(nullptr) == CompositeMethod::None);
REQUIRE(shape->mask(nullptr) == MaskMethod::None);
auto comp = Shape::gen();
REQUIRE(shape->composite(std::move(comp), CompositeMethod::None) == Result::InvalidArguments);
REQUIRE(shape->mask(std::move(comp), MaskMethod::None) == Result::InvalidArguments);
//Clipping
comp = Shape::gen();
@ -220,34 +220,34 @@ TEST_CASE("Composition", "[tvgPaint]")
//AlphaMask
comp = Shape::gen();
pComp = comp.get();
REQUIRE(shape->composite(std::move(comp), CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(shape->mask(std::move(comp), MaskMethod::Alpha) == Result::Success);
const Paint* pComp2 = nullptr;
REQUIRE(shape->composite(&pComp2) == CompositeMethod::AlphaMask);
REQUIRE(shape->mask(&pComp2) == MaskMethod::Alpha);
REQUIRE(pComp == pComp2);
//InvAlphaMask
comp = Shape::gen();
pComp = comp.get();
REQUIRE(shape->composite(std::move(comp), CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(shape->mask(std::move(comp), MaskMethod::InvAlpha) == Result::Success);
REQUIRE(shape->composite(&pComp2) == CompositeMethod::InvAlphaMask);
REQUIRE(shape->mask(&pComp2) == MaskMethod::InvAlpha);
REQUIRE(pComp == pComp2);
//LumaMask
comp = Shape::gen();
pComp = comp.get();
REQUIRE(shape->composite(std::move(comp), CompositeMethod::LumaMask) == Result::Success);
REQUIRE(shape->mask(std::move(comp), MaskMethod::Luma) == Result::Success);
REQUIRE(shape->composite(&pComp2) == CompositeMethod::LumaMask);
REQUIRE(shape->mask(&pComp2) == MaskMethod::Luma);
REQUIRE(pComp == pComp2);
//InvLumaMask
comp = Shape::gen();
pComp = comp.get();
REQUIRE(shape->composite(std::move(comp), CompositeMethod::InvLumaMask) == Result::Success);
REQUIRE(shape->mask(std::move(comp), MaskMethod::InvLuma) == Result::Success);
REQUIRE(shape->composite(&pComp2) == CompositeMethod::InvLumaMask);
REQUIRE(shape->mask(&pComp2) == MaskMethod::InvLuma);
REQUIRE(pComp == pComp2);
}

View file

@ -151,16 +151,16 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
REQUIRE(rleMask7);
// Rect
REQUIRE(basicPicture->composite(std::move(rectMask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(basicPicture->mask(std::move(rectMask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture)) == Result::Success);
REQUIRE(basicPicture2->composite(std::move(rectMask2), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(basicPicture2->mask(std::move(rectMask2), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture2)) == Result::Success);
REQUIRE(basicPicture3->clip(std::move(rectMask3)) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture3)) == Result::Success);
REQUIRE(basicPicture4->composite(std::move(rectMask4), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(basicPicture4->mask(std::move(rectMask4), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture4)) == Result::Success);
REQUIRE(basicPicture5->opacity(100) == Result::Success);
@ -217,16 +217,16 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
REQUIRE(rleMask7);
// Rect
REQUIRE(basicPicture->composite(std::move(rectMask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(basicPicture->mask(std::move(rectMask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture)) == Result::Success);
REQUIRE(basicPicture2->composite(std::move(rectMask2), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(basicPicture2->mask(std::move(rectMask2), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture2)) == Result::Success);
REQUIRE(basicPicture3->clip(std::move(rectMask3)) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture3)) == Result::Success);
REQUIRE(basicPicture4->composite(std::move(rectMask4), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(basicPicture4->mask(std::move(rectMask4), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture4)) == Result::Success);
REQUIRE(basicPicture5->opacity(100) == Result::Success);
@ -281,16 +281,16 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
REQUIRE(rleMask7);
// Rect
REQUIRE(basicPicture->composite(std::move(rectMask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(basicPicture->mask(std::move(rectMask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture)) == Result::Success);
REQUIRE(basicPicture2->composite(std::move(rectMask2), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(basicPicture2->mask(std::move(rectMask2), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture2)) == Result::Success);
REQUIRE(basicPicture3->clip(std::move(rectMask3)) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture3)) == Result::Success);
REQUIRE(basicPicture4->composite(std::move(rectMask4), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(basicPicture4->mask(std::move(rectMask4), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture4)) == Result::Success);
REQUIRE(basicPicture5->opacity(100) == Result::Success);
@ -345,16 +345,16 @@ TEST_CASE("Image Draw", "[tvgSwEngine]")
REQUIRE(rleMask7);
// Rect
REQUIRE(basicPicture->composite(std::move(rectMask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(basicPicture->mask(std::move(rectMask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture)) == Result::Success);
REQUIRE(basicPicture2->composite(std::move(rectMask2), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(basicPicture2->mask(std::move(rectMask2), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture2)) == Result::Success);
REQUIRE(basicPicture3->clip(std::move(rectMask3)) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture3)) == Result::Success);
REQUIRE(basicPicture4->composite(std::move(rectMask4), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(basicPicture4->mask(std::move(rectMask4), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(basicPicture4)) == Result::Success);
REQUIRE(basicPicture5->opacity(100) == Result::Success);
@ -414,16 +414,16 @@ TEST_CASE("Rect Draw", "[tvgSwEngine]")
auto basicShape5 = tvg::cast<Shape>(basicShape->duplicate());
REQUIRE(basicShape5);
REQUIRE(basicShape->composite(std::move(basicMask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(basicShape->mask(std::move(basicMask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape)) == Result::Success);
REQUIRE(basicShape2->composite(std::move(basicMask2), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(basicShape2->mask(std::move(basicMask2), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape2)) == Result::Success);
REQUIRE(basicShape3->clip(std::move(basicMask3)) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape3)) == Result::Success);
REQUIRE(basicShape4->composite(std::move(basicMask4), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(basicShape4->mask(std::move(basicMask4), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape4)) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape5)) == Result::Success);
@ -472,16 +472,16 @@ TEST_CASE("RLE Draw", "[tvgSwEngine]")
auto basicShape5 = tvg::cast<Shape>(basicShape->duplicate());
REQUIRE(basicShape5);
REQUIRE(basicShape->composite(std::move(basicMask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(basicShape->mask(std::move(basicMask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape)) == Result::Success);
REQUIRE(basicShape2->composite(std::move(basicMask2), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(basicShape2->mask(std::move(basicMask2), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape2)) == Result::Success);
REQUIRE(basicShape3->clip(std::move(basicMask3)) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape3)) == Result::Success);
REQUIRE(basicShape4->composite(std::move(basicMask4), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(basicShape4->mask(std::move(basicMask4), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape4)) == Result::Success);
REQUIRE(canvas->push(std::move(basicShape5)) == Result::Success);
@ -642,7 +642,7 @@ TEST_CASE("Filling AlphaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -701,7 +701,7 @@ TEST_CASE("Filling InvAlphaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -760,7 +760,7 @@ TEST_CASE("Filling LumaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -976,7 +976,7 @@ TEST_CASE("RLE Filling AlphaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -1035,7 +1035,7 @@ TEST_CASE("RLE Filling InvAlphaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::InvAlphaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::InvAlpha) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -1094,7 +1094,7 @@ TEST_CASE("RLE Filling LumaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::LumaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::Luma) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -1153,7 +1153,7 @@ TEST_CASE("RLE Filling InvLumaMask", "[tvgSwEngine]")
REQUIRE(scene);
REQUIRE(scene->push(std::move(shape3)) == Result::Success);
REQUIRE(scene->push(std::move(shape4)) == Result::Success);
REQUIRE(scene->composite(std::move(mask), tvg::CompositeMethod::InvLumaMask) == Result::Success);
REQUIRE(scene->mask(std::move(mask), tvg::MaskMethod::InvLuma) == Result::Success);
REQUIRE(canvas->push(std::move(scene)) == Result::Success);
//Draw
@ -1414,7 +1414,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]")
REQUIRE(shape3);
REQUIRE(shape3->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape3->fill(std::move(linearFill2)) == Result::Success);
REQUIRE(shape3->composite(std::move(mask), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(shape3->mask(std::move(mask), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(shape3->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape3)) == Result::Success);
@ -1432,7 +1432,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]")
REQUIRE(shape4);
REQUIRE(shape4->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape4->fill(std::move(radialFill2)) == Result::Success);
REQUIRE(shape4->composite(std::move(mask2), tvg::CompositeMethod::AlphaMask) == Result::Success);
REQUIRE(shape4->mask(std::move(mask2), tvg::MaskMethod::Alpha) == Result::Success);
REQUIRE(shape4->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape4)) == Result::Success);
@ -1450,7 +1450,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]")
REQUIRE(shape5);
REQUIRE(shape5->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape5->fill(std::move(linearFill3)) == Result::Success);
REQUIRE(shape5->composite(std::move(mask3), tvg::CompositeMethod::AddMask) == Result::Success);
REQUIRE(shape5->mask(std::move(mask3), tvg::MaskMethod::Add) == Result::Success);
REQUIRE(shape5->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape5)) == Result::Success);
@ -1468,7 +1468,7 @@ TEST_CASE("Blending with Gradient Filling", "[tvgSwEngine]")
REQUIRE(shape6);
REQUIRE(shape6->appendRect(0, 0, 100, 100) == Result::Success);
REQUIRE(shape6->fill(std::move(radialFill3)) == Result::Success);
REQUIRE(shape6->composite(std::move(mask4), tvg::CompositeMethod::SubtractMask) == Result::Success);
REQUIRE(shape6->mask(std::move(mask4), tvg::MaskMethod::Subtract) == Result::Success);
REQUIRE(shape6->blend(BlendMethod::Difference) == Result::Success);
REQUIRE(canvas->push(std::move(shape6)) == Result::Success);