| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use std::cell::Cell; |
| |
| use crate::{ |
| core::{Core, Object, ObjectRef, OnAdded}, |
| dyn_vec::DynVec, |
| shapes::{ |
| paint::{ShapePaint, Stroke}, |
| PathSpace, Shape, |
| }, |
| Artboard, |
| }; |
| |
| #[derive(Debug, Default)] |
| pub struct ShapePaintContainer { |
| default_path_space: Cell<PathSpace>, |
| shape_paints: DynVec<Object<ShapePaint>>, |
| } |
| |
| impl ShapePaintContainer { |
| pub fn push_paint(&self, shape_paint: Object<ShapePaint>) { |
| self.shape_paints.push(shape_paint); |
| } |
| |
| pub(crate) fn shape_paints(&self) -> impl Iterator<Item = Object<ShapePaint>> + '_ { |
| self.shape_paints.iter() |
| } |
| |
| pub fn path_space(&self) -> PathSpace { |
| self.shape_paints |
| .iter() |
| .map(|shape_paint| shape_paint.as_ref().path_space()) |
| .fold(self.default_path_space.get(), |a, e| a | e) |
| } |
| |
| pub fn add_default_path_space(&self, space: PathSpace) { |
| self.default_path_space.set(self.default_path_space.get() | space); |
| } |
| |
| pub fn invalidate_stroke_effects(&self) { |
| for paint in self.shape_paints.iter() { |
| if let Some(stroke) = paint.try_cast::<Stroke>() { |
| stroke.as_ref().invalidate_effects(); |
| } |
| } |
| } |
| |
| pub fn make_command_path(&self, _space: PathSpace) { |
| // let mut needs_render = |
| // ((space | self.default_path_space.get()) & PathSpace::CLIPPING) == PathSpace::CLIPPING; |
| // let mut needs_effects = false; |
| |
| // for paint in self.shape_paints.iter() { |
| // if !space.is_empty() && (space & paint.as_ref().path_space()) != space { |
| // continue; |
| // } |
| |
| // match paint.try_cast::<Stroke>() { |
| // Some(stroke) if stroke.as_ref().has_stroke_effect() => needs_effects = true, |
| // _ => needs_render = true, |
| // } |
| // } |
| |
| // if needs_render && needs_effects { |
| // Box::new(MetricsPath) |
| // } else if needs_effects { |
| // Box::new(MetricsPath) |
| // } else { |
| // Box::new(RenderPath) |
| // } |
| |
| todo!(); |
| } |
| } |
| |
| impl TryFrom<Object> for Object<ShapePaintContainer> { |
| type Error = (); |
| |
| fn try_from(value: Object) -> Result<Self, Self::Error> { |
| if let Some(artboard) = value.try_cast::<Artboard>() { |
| return Ok(artboard.cast()); |
| } |
| |
| if let Some(shape) = value.try_cast::<Shape>() { |
| return Ok(shape.cast()); |
| } |
| |
| Err(()) |
| } |
| } |
| |
| impl Core for ShapePaintContainer {} |
| |
| impl OnAdded for ObjectRef<'_, ShapePaintContainer> { |
| on_added!(); |
| } |