// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef FLUTTER_IMPELLER_AIKS_PAINT_H_ #define FLUTTER_IMPELLER_AIKS_PAINT_H_ #include #include "impeller/aiks/color_filter.h" #include "impeller/aiks/color_source.h" #include "impeller/aiks/image_filter.h" #include "impeller/entity/contents/contents.h" #include "impeller/entity/contents/filters/color_filter_contents.h" #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/texture_contents.h" #include "impeller/entity/entity.h" #include "impeller/entity/geometry/geometry.h" #include "impeller/geometry/color.h" namespace impeller { struct Paint { using ImageFilterProc = std::function( FilterInput::Ref, const Matrix& effect_transform, Entity::RenderingMode rendering_mode)>; using MaskFilterProc = std::function( FilterInput::Ref, bool is_solid_color, const Matrix& effect_transform)>; using ColorSourceProc = std::function()>; /// @brief Whether or not a save layer with the provided paint can perform the /// opacity peephole optimization. static bool CanApplyOpacityPeephole(const Paint& paint) { return paint.blend_mode == BlendMode::kSourceOver && paint.invert_colors == false && !paint.mask_blur_descriptor.has_value() && paint.image_filter == nullptr && paint.color_filter == nullptr; } enum class Style { kFill, kStroke, }; struct MaskBlurDescriptor { FilterContents::BlurStyle style; Sigma sigma; /// Text mask blurs need to not apply the CTM to the blur kernel. /// See: https://github.com/flutter/flutter/issues/115112 bool respect_ctm = true; std::shared_ptr CreateMaskBlur( std::shared_ptr color_source_contents, const std::shared_ptr& color_filter) const; std::shared_ptr CreateMaskBlur( std::shared_ptr texture_contents) const; std::shared_ptr CreateMaskBlur( const FilterInput::Ref& input, bool is_solid_color, const Matrix& ctm) const; }; Color color = Color::Black(); ColorSource color_source; Scalar stroke_width = 0.0; Cap stroke_cap = Cap::kButt; Join stroke_join = Join::kMiter; Scalar stroke_miter = 4.0; Style style = Style::kFill; BlendMode blend_mode = BlendMode::kSourceOver; bool invert_colors = false; std::shared_ptr image_filter; std::shared_ptr color_filter; std::optional mask_blur_descriptor; std::shared_ptr GetColorFilter() const; /// @brief Wrap this paint's configured filters to the given contents. /// @param[in] input The contents to wrap with paint's filters. /// @return The filter-wrapped contents. If there are no filters that need /// to be wrapped for the current paint configuration, the /// original contents is returned. std::shared_ptr WithFilters(std::shared_ptr input) const; /// @brief Wrap this paint's configured filters to the given contents of /// subpass target. /// @param[in] input The contents of subpass target to wrap with paint's /// filters. /// /// @return The filter-wrapped contents. If there are no filters that need /// to be wrapped for the current paint configuration, the /// original contents is returned. std::shared_ptr WithFiltersForSubpassTarget( std::shared_ptr input, const Matrix& effect_transform = Matrix()) const; std::shared_ptr CreateContentsForGeometry( const std::shared_ptr& geometry) const; /// @brief Whether this paint has a color filter that can apply opacity bool HasColorFilter() const; std::shared_ptr WithMaskBlur(std::shared_ptr input, bool is_solid_color, const Matrix& ctm) const; std::shared_ptr WithImageFilter( const FilterInput::Variant& input, const Matrix& effect_transform, Entity::RenderingMode rendering_mode) const; private: std::shared_ptr WithColorFilter( std::shared_ptr input, ColorFilterContents::AbsorbOpacity absorb_opacity = ColorFilterContents::AbsorbOpacity::kNo) const; }; } // namespace impeller #endif // FLUTTER_IMPELLER_AIKS_PAINT_H_