forma/composition/
layer.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use surpass::painter::Props;
6use surpass::{GeomId, GeomPresTransform, Order, Path};
7
8use crate::small_bit_set::SmallBitSet;
9
10use super::interner::Interned;
11use super::state::LayerSharedState;
12
13#[derive(Debug)]
14pub struct Layer {
15    pub(crate) inner: surpass::Layer,
16    pub(crate) shared_state: LayerSharedState,
17    pub(crate) geom_id: GeomId,
18    pub(crate) props: Interned<Props>,
19    pub(crate) is_unchanged: SmallBitSet,
20    pub(crate) lines_count: usize,
21}
22
23impl Layer {
24    pub fn insert(&mut self, path: &Path) -> &mut Self {
25        {
26            let mut state = self.shared_state.inner();
27            let builder = state.lines_builder.as_mut().expect("lines_builder should not be None");
28
29            let old_len = builder.len();
30            builder.push_path(self.geom_id, path);
31            let len = builder.len() - old_len;
32
33            state.geom_id_to_order.insert(self.geom_id, self.inner.order);
34
35            self.lines_count += len;
36        }
37
38        self.is_unchanged.clear();
39        self
40    }
41
42    pub fn clear(&mut self) -> &mut Self {
43        {
44            let mut state = self.shared_state.inner();
45
46            state.geom_id_to_order.remove(&self.geom_id);
47
48            self.geom_id = state.new_geom_id();
49        }
50
51        self.lines_count = 0;
52
53        self.is_unchanged.clear();
54        self
55    }
56
57    pub(crate) fn set_order(&mut self, order: Option<Order>) {
58        if order.is_some() && self.inner.order != order {
59            self.inner.order = order;
60            self.is_unchanged.clear();
61        }
62
63        let geom_id = self.geom_id();
64        self.shared_state.inner().geom_id_to_order.insert(geom_id, order);
65    }
66
67    pub fn geom_id(&self) -> GeomId {
68        self.geom_id
69    }
70
71    pub(crate) fn is_unchanged(&self, cache_id: u8) -> bool {
72        self.is_unchanged.contains(&cache_id)
73    }
74
75    pub(crate) fn set_is_unchanged(&mut self, cache_id: u8, is_unchanged: bool) -> bool {
76        if is_unchanged {
77            self.is_unchanged.insert(cache_id)
78        } else {
79            self.is_unchanged.remove(cache_id)
80        }
81    }
82
83    #[inline]
84    pub fn is_enabled(&self) -> bool {
85        self.inner.is_enabled
86    }
87
88    #[inline]
89    pub fn set_is_enabled(&mut self, is_enabled: bool) -> &mut Self {
90        self.inner.is_enabled = is_enabled;
91        self
92    }
93
94    #[inline]
95    pub fn disable(&mut self) -> &mut Self {
96        self.set_is_enabled(false)
97    }
98
99    #[inline]
100    pub fn enable(&mut self) -> &mut Self {
101        self.set_is_enabled(true)
102    }
103
104    #[inline]
105    pub fn transform(&self) -> GeomPresTransform {
106        self.inner.affine_transform.unwrap_or_default()
107    }
108
109    #[inline]
110    pub fn set_transform(&mut self, transform: GeomPresTransform) -> &mut Self {
111        // We want to perform a cheap check for the common case without hampering this function too
112        // much.
113        #[allow(clippy::float_cmp)]
114        let affine_transform = if transform.is_identity() { None } else { Some(transform) };
115
116        if self.inner.affine_transform != affine_transform {
117            self.is_unchanged.clear();
118            self.inner.affine_transform = affine_transform;
119        }
120
121        self
122    }
123
124    #[inline]
125    pub fn props(&self) -> &Props {
126        &self.props
127    }
128
129    #[inline]
130    pub fn set_props(&mut self, props: Props) -> &mut Self {
131        if *self.props != props {
132            self.is_unchanged.clear();
133            self.props = self.shared_state.inner().props_interner.get(props);
134        }
135
136        self
137    }
138}
139
140impl Drop for Layer {
141    fn drop(&mut self) {
142        self.shared_state.inner().geom_id_to_order.remove(&self.geom_id);
143    }
144}