diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 0fe07b756c73a..b0009af71890b 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -35,6 +35,9 @@ void SolidColorContents::SetCover(bool cover) { std::optional SolidColorContents::GetCoverage( const Entity& entity) const { + if (color_.IsTransparent()) { + return std::nullopt; + } return path_.GetTransformedBoundingBox(entity.GetTransformation()); }; @@ -60,10 +63,6 @@ VertexBuffer SolidColorContents::CreateSolidFillVertices(const Path& path, bool SolidColorContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (color_.IsTransparent()) { - return true; - } - using VS = SolidFillPipeline::VertexShader; Command cmd; diff --git a/impeller/entity/contents/solid_stroke_contents.cc b/impeller/entity/contents/solid_stroke_contents.cc index 20a76652bf276..201f7ad6cd722 100644 --- a/impeller/entity/contents/solid_stroke_contents.cc +++ b/impeller/entity/contents/solid_stroke_contents.cc @@ -35,6 +35,10 @@ void SolidStrokeContents::SetPath(Path path) { std::optional SolidStrokeContents::GetCoverage( const Entity& entity) const { + if (color_.IsTransparent()) { + return std::nullopt; + } + auto path_bounds = path_.GetBoundingBox(); if (!path_bounds.has_value()) { return std::nullopt; @@ -173,7 +177,7 @@ static VertexBuffer CreateSolidStrokeVertices( bool SolidStrokeContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (color_.IsTransparent() || stroke_size_ <= 0.0) { + if (stroke_size_ <= 0.0) { return true; } diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc index 560ab9a89584d..cc9b883870fe6 100644 --- a/impeller/entity/contents/texture_contents.cc +++ b/impeller/entity/contents/texture_contents.cc @@ -4,6 +4,8 @@ #include "texture_contents.h" +#include + #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" #include "impeller/entity/texture_fill.frag.h" @@ -35,6 +37,9 @@ void TextureContents::SetOpacity(Scalar opacity) { } std::optional TextureContents::GetCoverage(const Entity& entity) const { + if (opacity_ == 0) { + return std::nullopt; + } return path_.GetTransformedBoundingBox(entity.GetTransformation()); }; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 2559ff8b77908..5552c39c39679 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -925,6 +925,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { contents->SetStrokeCap(SolidStrokeContents::Cap::kButt); contents->SetStrokeJoin(SolidStrokeContents::Join::kBevel); contents->SetStrokeSize(4); + contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); auto actual = entity.GetCoverage(); auto expected = Rect::MakeLTRB(-2, -2, 12, 12); @@ -940,6 +941,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { contents->SetStrokeCap(SolidStrokeContents::Cap::kSquare); contents->SetStrokeJoin(SolidStrokeContents::Join::kBevel); contents->SetStrokeSize(4); + contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); auto actual = entity.GetCoverage(); auto expected = @@ -957,6 +959,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { contents->SetStrokeJoin(SolidStrokeContents::Join::kMiter); contents->SetStrokeSize(4); contents->SetStrokeMiter(2); + contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); auto actual = entity.GetCoverage(); auto expected = Rect::MakeLTRB(-4, -4, 14, 14); @@ -1011,5 +1014,47 @@ TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithoutIndex) { ASSERT_TRUE(OpenPlaygroundHere(e)); } +TEST_P(EntityTest, SolidFillCoverageIsCorrect) { + // No transform + { + auto fill = std::make_shared(); + fill->SetColor(Color::CornflowerBlue()); + auto expected = Rect::MakeLTRB(100, 110, 200, 220); + fill->SetPath(PathBuilder{}.AddRect(expected).TakePath()); + + auto coverage = fill->GetCoverage({}); + ASSERT_TRUE(coverage.has_value()); + ASSERT_RECT_NEAR(coverage.value(), expected); + } + + // Entity transform + { + auto fill = std::make_shared(); + fill->SetColor(Color::CornflowerBlue()); + fill->SetPath( + PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()); + + Entity entity; + entity.SetTransformation(Matrix::MakeTranslation(Vector2(4, 5))); + entity.SetContents(std::move(fill)); + + auto coverage = entity.GetCoverage(); + auto expected = Rect::MakeLTRB(104, 115, 204, 225); + ASSERT_TRUE(coverage.has_value()); + ASSERT_RECT_NEAR(coverage.value(), expected); + } + + // No coverage for fully transparent colors + { + auto fill = std::make_shared(); + fill->SetColor(Color::WhiteTransparent()); + fill->SetPath( + PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()); + + auto coverage = fill->GetCoverage({}); + ASSERT_FALSE(coverage.has_value()); + } +} + } // namespace testing } // namespace impeller