diff --git a/include/tgfx/layers/LayerType.h b/include/tgfx/layers/LayerType.h index d454aaf..47626ca 100644 --- a/include/tgfx/layers/LayerType.h +++ b/include/tgfx/layers/LayerType.h @@ -43,5 +43,9 @@ enum class LayerType { * A layer displaying a simple text. */ Text, + /** + * A layer that fills its bounds with style. + */ + Solid }; } // namespace tgfx diff --git a/include/tgfx/layers/ShapeStyle.h b/include/tgfx/layers/ShapeStyle.h index 38a71c0..b33e1d3 100644 --- a/include/tgfx/layers/ShapeStyle.h +++ b/include/tgfx/layers/ShapeStyle.h @@ -37,5 +37,6 @@ class ShapeStyle { virtual std::shared_ptr getShader() const = 0; friend class ShapeLayer; + friend class SolidLayer; }; } // namespace tgfx diff --git a/include/tgfx/layers/SolidLayer.h b/include/tgfx/layers/SolidLayer.h new file mode 100644 index 0000000..86568f7 --- /dev/null +++ b/include/tgfx/layers/SolidLayer.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "SolidColor.h" +#include "tgfx/layers/Layer.h" +#include "tgfx/layers/ShapeStyle.h" + +namespace tgfx { +/** + * A layer that fills its bounds with a solid color, gradient, or image pattern. + */ +class SolidLayer : public Layer { + public: + /** + * Creates a new solid layer with the given width, height, and fill style. + */ + static std::shared_ptr Make(int width, int height, std::shared_ptr style); + + LayerType type() const override { + return LayerType::Solid; + } + /** + * Returns the style used to fill the layer, which can be a solid color, gradient, or image + * pattern. + */ + std::shared_ptr fillStyle() const { + return _fillStyle; + } + + /** + * Sets the style used to fill the layer. If the fill style is set to nullptr, the shape will not + * be filled. + */ + void setFillStyle(std::shared_ptr style); + + protected: + SolidLayer(int width, int height, std::shared_ptr style); + + std::unique_ptr onUpdateContent() override; + + private: + std::shared_ptr _fillStyle = nullptr; + + Path _path = {}; +}; + +} // namespace tgfx diff --git a/src/core/SolidLayer.cpp b/src/core/SolidLayer.cpp new file mode 100644 index 0000000..3620110 --- /dev/null +++ b/src/core/SolidLayer.cpp @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "tgfx/layers/SolidLayer.h" +#include "layers/contents/ShapeContent.h" + +namespace tgfx { +std::shared_ptr SolidLayer::Make(int width, int height, + std::shared_ptr style) { + if (width == 0 || height == 0) { + return nullptr; + } + auto layer = std::shared_ptr(new SolidLayer(width, height, std::move(style))); + layer->weakThis = layer; + return layer; +} + +SolidLayer::SolidLayer(int width, int height, std::shared_ptr style) { + _path.addRect(0, 0, static_cast(width), static_cast(height)); + setFillStyle(std::move(style)); +} + +void SolidLayer::setFillStyle(std::shared_ptr style) { + if (_fillStyle == style) { + return; + } + _fillStyle = std::move(style); + invalidateContent(); +} + +std::unique_ptr SolidLayer::onUpdateContent() { + std::vector> contents = {}; + auto shader = _fillStyle ? _fillStyle->getShader() : nullptr; + auto content = std::make_unique(_path, shader); + contents.push_back(std::move(content)); + return LayerContent::Compose(std::move(contents)); +} + +} // namespace tgfx \ No newline at end of file diff --git a/test/baseline/version.json b/test/baseline/version.json index 165e3c1..e846806 100644 --- a/test/baseline/version.json +++ b/test/baseline/version.json @@ -65,7 +65,8 @@ "getBounds": "8a26de7", "greyColorMatrix": "a1605b2", "identityMatrix": "a1605b2", - "imageLayer": "99a5cd9" + "imageLayer": "99a5cd9", + "draw_solid": "b4a1231" }, "MaskTest": { "rasterize_emoji": "c0f39f8", diff --git a/test/src/LayerTest.cpp b/test/src/LayerTest.cpp index ea2a032..b94de65 100644 --- a/test/src/LayerTest.cpp +++ b/test/src/LayerTest.cpp @@ -24,6 +24,7 @@ #include "tgfx/layers/ImageLayer.h" #include "tgfx/layers/Layer.h" #include "tgfx/layers/ShapeLayer.h" +#include "tgfx/layers/SolidLayer.h" #include "tgfx/layers/TextLayer.h" #include "tgfx/layers/filters/BlendFilter.h" #include "tgfx/layers/filters/BlurFilter.h" @@ -462,6 +463,26 @@ TGFX_TEST(LayerTest, shapeLayer) { device->unlock(); } +TGFX_TEST(LayerTest, solidLayer) { + auto device = DevicePool::Make(); + ASSERT_TRUE(device != nullptr); + auto context = device->lockContext(); + auto surface = Surface::Make(context, 200, 100); + auto displayList = std::make_unique(); + auto layer = Layer::Make(); + displayList->root()->addChild(layer); + auto solidLayer = SolidLayer::Make(150, 80, SolidColor::Make(Color::Blue())); + layer->addChild(solidLayer); + auto solidLayerRect = solidLayer->getBounds(); + auto bounds = Rect::MakeXYWH(0, 0, 150, 80); + ASSERT_TRUE(solidLayerRect == bounds); + + displayList->render(surface.get()); + context->submit(); + EXPECT_TRUE(Baseline::Compare(surface, "LayerTest/draw_solid")); + device->unlock(); +} + TGFX_TEST(LayerTest, FilterTest) { auto filter = DropShadowFilter::Make(-80, -80, 0, 0, Color::Black()); auto filter2 = DropShadowFilter::Make(-40, -40, 0, 0, Color::Green());