| // 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. |
| |
| #include "impeller/aiks/color_source.h" |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "impeller/aiks/paint.h" |
| #include "impeller/core/sampler_descriptor.h" |
| #include "impeller/entity/contents/conical_gradient_contents.h" |
| #include "impeller/entity/contents/linear_gradient_contents.h" |
| #include "impeller/entity/contents/radial_gradient_contents.h" |
| #include "impeller/entity/contents/runtime_effect_contents.h" |
| #include "impeller/entity/contents/solid_color_contents.h" |
| #include "impeller/entity/contents/sweep_gradient_contents.h" |
| #include "impeller/entity/contents/tiled_texture_contents.h" |
| #include "impeller/geometry/color.h" |
| #include "impeller/geometry/matrix.h" |
| #include "impeller/geometry/scalar.h" |
| #include "impeller/runtime_stage/runtime_stage.h" |
| |
| #if IMPELLER_ENABLE_3D |
| #include "impeller/entity/contents/scene_contents.h" // nogncheck |
| #include "impeller/scene/node.h" // nogncheck |
| #endif // IMPELLER_ENABLE_3D |
| |
| namespace impeller { |
| |
| ColorSource::ColorSource() noexcept |
| : proc_([](const Paint& paint) -> std::shared_ptr<ColorSourceContents> { |
| auto contents = std::make_shared<SolidColorContents>(); |
| contents->SetColor(paint.color); |
| return contents; |
| }){}; |
| |
| ColorSource::~ColorSource() = default; |
| |
| ColorSource ColorSource::MakeColor() { |
| return {}; |
| } |
| |
| ColorSource ColorSource::MakeLinearGradient(Point start_point, |
| Point end_point, |
| std::vector<Color> colors, |
| std::vector<Scalar> stops, |
| Entity::TileMode tile_mode, |
| Matrix effect_transform) { |
| ColorSource result; |
| result.type_ = Type::kLinearGradient; |
| result.proc_ = [start_point, end_point, colors = std::move(colors), |
| stops = std::move(stops), tile_mode, |
| effect_transform](const Paint& paint) { |
| auto contents = std::make_shared<LinearGradientContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetColors(colors); |
| contents->SetStops(stops); |
| contents->SetEndPoints(start_point, end_point); |
| contents->SetTileMode(tile_mode); |
| contents->SetDither(paint.dither); |
| contents->SetEffectTransform(effect_transform); |
| |
| std::vector<Point> bounds{start_point, end_point}; |
| auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); |
| if (intrinsic_size.has_value()) { |
| contents->SetColorSourceSize(intrinsic_size->size); |
| } |
| return contents; |
| }; |
| return result; |
| } |
| |
| ColorSource ColorSource::MakeConicalGradient(Point center, |
| Scalar radius, |
| std::vector<Color> colors, |
| std::vector<Scalar> stops, |
| Point focus_center, |
| Scalar focus_radius, |
| Entity::TileMode tile_mode, |
| Matrix effect_transform) { |
| ColorSource result; |
| result.type_ = Type::kConicalGradient; |
| result.proc_ = [center, radius, colors = std::move(colors), |
| stops = std::move(stops), focus_center, focus_radius, |
| tile_mode, effect_transform](const Paint& paint) { |
| std::shared_ptr<ConicalGradientContents> contents = |
| std::make_shared<ConicalGradientContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetColors(colors); |
| contents->SetStops(stops); |
| contents->SetCenterAndRadius(center, radius); |
| contents->SetTileMode(tile_mode); |
| contents->SetDither(paint.dither); |
| contents->SetEffectTransform(effect_transform); |
| contents->SetFocus(focus_center, focus_radius); |
| |
| auto radius_pt = Point(radius, radius); |
| std::vector<Point> bounds{center + radius_pt, center - radius_pt}; |
| auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); |
| if (intrinsic_size.has_value()) { |
| contents->SetColorSourceSize(intrinsic_size->size); |
| } |
| return contents; |
| }; |
| return result; |
| } |
| |
| ColorSource ColorSource::MakeRadialGradient(Point center, |
| Scalar radius, |
| std::vector<Color> colors, |
| std::vector<Scalar> stops, |
| Entity::TileMode tile_mode, |
| Matrix effect_transform) { |
| ColorSource result; |
| result.type_ = Type::kRadialGradient; |
| result.proc_ = [center, radius, colors = std::move(colors), |
| stops = std::move(stops), tile_mode, |
| effect_transform](const Paint& paint) { |
| auto contents = std::make_shared<RadialGradientContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetColors(colors); |
| contents->SetStops(stops); |
| contents->SetCenterAndRadius(center, radius); |
| contents->SetTileMode(tile_mode); |
| contents->SetDither(paint.dither); |
| contents->SetEffectTransform(effect_transform); |
| |
| auto radius_pt = Point(radius, radius); |
| std::vector<Point> bounds{center + radius_pt, center - radius_pt}; |
| auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); |
| if (intrinsic_size.has_value()) { |
| contents->SetColorSourceSize(intrinsic_size->size); |
| } |
| return contents; |
| }; |
| return result; |
| } |
| |
| ColorSource ColorSource::MakeSweepGradient(Point center, |
| Degrees start_angle, |
| Degrees end_angle, |
| std::vector<Color> colors, |
| std::vector<Scalar> stops, |
| Entity::TileMode tile_mode, |
| Matrix effect_transform) { |
| ColorSource result; |
| result.type_ = Type::kSweepGradient; |
| result.proc_ = [center, start_angle, end_angle, colors = std::move(colors), |
| stops = std::move(stops), tile_mode, |
| effect_transform](const Paint& paint) { |
| auto contents = std::make_shared<SweepGradientContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetCenterAndAngles(center, start_angle, end_angle); |
| contents->SetColors(colors); |
| contents->SetStops(stops); |
| contents->SetTileMode(tile_mode); |
| contents->SetDither(paint.dither); |
| contents->SetEffectTransform(effect_transform); |
| |
| return contents; |
| }; |
| return result; |
| } |
| |
| ColorSource ColorSource::MakeImage(std::shared_ptr<Texture> texture, |
| Entity::TileMode x_tile_mode, |
| Entity::TileMode y_tile_mode, |
| SamplerDescriptor sampler_descriptor, |
| Matrix effect_transform) { |
| ColorSource result; |
| result.type_ = Type::kImage; |
| result.proc_ = [texture = std::move(texture), x_tile_mode, y_tile_mode, |
| sampler_descriptor = std::move(sampler_descriptor), |
| effect_transform](const Paint& paint) { |
| auto contents = std::make_shared<TiledTextureContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetTexture(texture); |
| contents->SetTileModes(x_tile_mode, y_tile_mode); |
| contents->SetSamplerDescriptor(sampler_descriptor); |
| contents->SetEffectTransform(effect_transform); |
| if (paint.color_filter) { |
| TiledTextureContents::ColorFilterProc filter_proc = |
| [color_filter = paint.color_filter](FilterInput::Ref input) { |
| return color_filter->WrapWithGPUColorFilter(std::move(input), |
| false); |
| }; |
| contents->SetColorFilter(filter_proc); |
| } |
| contents->SetColorSourceSize(Size::Ceil(texture->GetSize())); |
| return contents; |
| }; |
| return result; |
| } |
| |
| ColorSource ColorSource::MakeRuntimeEffect( |
| std::shared_ptr<RuntimeStage> runtime_stage, |
| std::shared_ptr<std::vector<uint8_t>> uniform_data, |
| std::vector<RuntimeEffectContents::TextureInput> texture_inputs) { |
| ColorSource result; |
| result.type_ = Type::kRuntimeEffect; |
| result.proc_ = [runtime_stage = std::move(runtime_stage), |
| uniform_data = std::move(uniform_data), |
| texture_inputs = |
| std::move(texture_inputs)](const Paint& paint) { |
| auto contents = std::make_shared<RuntimeEffectContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetRuntimeStage(runtime_stage); |
| contents->SetUniformData(uniform_data); |
| contents->SetTextureInputs(texture_inputs); |
| return contents; |
| }; |
| return result; |
| } |
| |
| #if IMPELLER_ENABLE_3D |
| ColorSource ColorSource::MakeScene(std::shared_ptr<scene::Node> scene_node, |
| Matrix camera_transform) { |
| ColorSource result; |
| result.type_ = Type::kScene; |
| result.proc_ = [scene_node = std::move(scene_node), |
| camera_transform](const Paint& paint) { |
| auto contents = std::make_shared<SceneContents>(); |
| contents->SetOpacityFactor(paint.color.alpha); |
| contents->SetNode(scene_node); |
| contents->SetCameraTransform(camera_transform); |
| return contents; |
| }; |
| return result; |
| } |
| #endif // IMPELLER_ENABLE_3D |
| |
| ColorSource::Type ColorSource::GetType() const { |
| return type_; |
| } |
| |
| std::shared_ptr<ColorSourceContents> ColorSource::GetContents( |
| const Paint& paint) const { |
| return proc_(paint); |
| } |
| |
| } // namespace impeller |