forma_render/composition/
layer.rs

1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{math::GeomPresTransform, styling::Props, utils::SmallBitSet, GeomId, Order, Path};
16
17use super::{Interned, LayerSharedState};
18
19/// Small, compact version of a [`Layer`] that implements [`Send`] and is used by the
20/// [`SegmentBuffer`].
21///
22/// This type should be as small as possible since it gets copied on use and thus
23/// should only contain information needed by the [`SegmentBuffer`].
24///
25/// [`SegmentBuffer`]: crate::segment::SegmentBuffer
26#[derive(Clone, Debug)]
27pub struct InnerLayer {
28    pub is_enabled: bool,
29    pub affine_transform: Option<GeomPresTransform>,
30    pub order: Option<Order>,
31}
32
33impl Default for InnerLayer {
34    fn default() -> Self {
35        Self {
36            is_enabled: true,
37            affine_transform: None,
38            order: None,
39        }
40    }
41}
42
43/// A layer is a *reusable* collection of geometry (i.e. [`Path`]s) with common properties and
44/// order in the paint stack.
45///
46/// They are created by calling [`Composition::create_layer`] or
47/// [`Composition::get_mut_or_insert_default`].
48///
49/// [`Composition::create_layer`]: crate::Composition::create_layer
50/// [`Composition::get_mut_or_insert_default`]: crate::Composition::get_mut_or_insert_default
51///
52/// # Examples
53///
54/// ```
55/// # use forma_render::prelude::*;
56/// let mut composition = Composition::new();
57///
58/// let _layer = composition.get_mut_or_insert_default(Order::new(0).unwrap());
59/// ```
60#[derive(Debug)]
61pub struct Layer {
62    pub(crate) inner: InnerLayer,
63    pub(crate) shared_state: LayerSharedState,
64    pub(crate) geom_id: GeomId,
65    pub(crate) props: Interned<Props>,
66    pub(crate) is_unchanged: SmallBitSet,
67    pub(crate) lines_count: usize,
68}
69
70impl Layer {
71    /// Inserts `path` into the geometry of the layer.
72    ///
73    /// The inserted paths basically contribute to a single internal path containing the geometry
74    /// of all the paths.
75    ///
76    /// # Examples
77    ///
78    /// ```
79    /// # use forma_render::prelude::*;
80    /// let mut composition = Composition::new();
81    ///
82    /// let line0 = PathBuilder::new().line_to(Point::new(10.0, 10.0)).build();
83    /// let line1 = PathBuilder::new().line_to(Point::new(10.0, 0.0)).build();
84    ///
85    /// composition
86    ///     .get_mut_or_insert_default(Order::new(0).unwrap())
87    ///     .insert(&line0)
88    ///     .insert(&line1);
89    /// ```
90    pub fn insert(&mut self, path: &Path) -> &mut Self {
91        {
92            let mut state = self.shared_state.inner();
93            let builder = state
94                .segment_buffer
95                .as_mut()
96                .expect("lines_builder should not be None");
97
98            let old_len = builder.len();
99            builder.push_path(self.geom_id, path);
100            let len = builder.len() - old_len;
101
102            state
103                .geom_id_to_order
104                .insert(self.geom_id, self.inner.order);
105
106            self.lines_count += len;
107        }
108
109        self.is_unchanged.clear();
110        self
111    }
112
113    /// Clears the geometry stored in the layer and resets its [geometry ID](Self::geom_id).
114    ///
115    /// # Examples
116    ///
117    /// ```
118    /// # use forma_render::prelude::*;
119    /// let mut composition = Composition::new();
120    ///
121    /// let mut layer = composition.create_layer();
122    ///
123    /// let initial_id = layer.geom_id();
124    ///
125    /// layer.clear();
126    ///
127    /// assert_ne!(layer.geom_id(), initial_id);
128    /// ```
129    pub fn clear(&mut self) -> &mut Self {
130        {
131            let mut state = self.shared_state.inner();
132
133            state.geom_id_to_order.remove(&self.geom_id);
134
135            self.geom_id = state.new_geom_id();
136            state
137                .geom_id_to_order
138                .insert(self.geom_id, self.inner.order);
139        }
140
141        self.lines_count = 0;
142
143        self.is_unchanged.clear();
144        self
145    }
146
147    pub(crate) fn set_order(&mut self, order: Option<Order>) {
148        if order.is_some() && self.inner.order != order {
149            self.inner.order = order;
150            self.is_unchanged.clear();
151        }
152
153        self.shared_state
154            .inner()
155            .geom_id_to_order
156            .insert(self.geom_id, order);
157    }
158
159    /// Returns the layer's geometry ID.
160    ///
161    /// Used to retrieve the layer's [`Order`] if stored in a [`Composition`](crate::Composition).
162    ///
163    /// # Examples
164    ///
165    /// ```
166    /// # use forma_render::prelude::*;
167    /// let mut composition = Composition::new();
168    ///
169    /// let order = Order::new(0).unwrap();
170    /// let layer = composition.get_mut_or_insert_default(order);
171    /// let id = layer.geom_id();
172    ///
173    /// assert_eq!(composition.get_order_if_stored(id), Some(order));
174    /// ```
175    pub fn geom_id(&self) -> GeomId {
176        self.geom_id
177    }
178
179    pub(crate) fn is_unchanged(&self, cache_id: u8) -> bool {
180        self.is_unchanged.contains(&cache_id)
181    }
182
183    pub(crate) fn set_is_unchanged(&mut self, cache_id: u8, is_unchanged: bool) -> bool {
184        if is_unchanged {
185            self.is_unchanged.insert(cache_id)
186        } else {
187            self.is_unchanged.remove(cache_id)
188        }
189    }
190
191    /// Returns `true` if the layer is enabled.
192    ///
193    /// # Examples
194    ///
195    /// ```
196    /// # use forma_render::prelude::*;
197    /// let mut composition = Composition::new();
198    ///
199    /// let layer = composition.create_layer();
200    ///
201    /// assert!(layer.is_enabled());
202    /// ```
203    #[inline]
204    pub fn is_enabled(&self) -> bool {
205        self.inner.is_enabled
206    }
207
208    /// Sets the layer's enabled state.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// # use forma_render::prelude::*;
214    /// let mut composition = Composition::new();
215    ///
216    /// let mut layer = composition.create_layer();
217    ///
218    /// layer.set_is_enabled(false);
219    ///
220    /// assert!(!layer.is_enabled());
221    /// ```
222    #[inline]
223    pub fn set_is_enabled(&mut self, is_enabled: bool) -> &mut Self {
224        self.inner.is_enabled = is_enabled;
225        self
226    }
227
228    /// Disables the layer.
229    ///
230    /// # Examples
231    ///
232    /// ```
233    /// # use forma_render::prelude::*;
234    /// let mut composition = Composition::new();
235    ///
236    /// let mut layer = composition.create_layer();
237    ///
238    /// layer.disable();
239    ///
240    /// assert!(!layer.is_enabled());
241    /// ```
242    #[inline]
243    pub fn disable(&mut self) -> &mut Self {
244        self.set_is_enabled(false)
245    }
246
247    /// Enables the layer.
248    ///
249    /// # Examples
250    ///
251    /// ```
252    /// # use forma_render::prelude::*;
253    /// let mut composition = Composition::new();
254    ///
255    /// let mut layer = composition.create_layer();
256    ///
257    /// layer.disable();
258    /// layer.enable();
259    ///
260    /// assert!(layer.is_enabled());
261    /// ```
262    #[inline]
263    pub fn enable(&mut self) -> &mut Self {
264        self.set_is_enabled(true)
265    }
266
267    /// Returns the layer's transform.
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// # use forma_render::prelude::*;
273    /// let mut composition = Composition::new();
274    ///
275    /// let layer = composition.create_layer();
276    ///
277    /// assert!(layer.transform().is_identity());
278    /// ```
279    #[inline]
280    pub fn transform(&self) -> GeomPresTransform {
281        self.inner.affine_transform.unwrap_or_default()
282    }
283
284    /// Sets the layer's transform.
285    ///
286    /// # Examples
287    ///
288    /// ```
289    /// # use forma_render::prelude::*;
290    /// let mut composition = Composition::new();
291    ///
292    /// let mut layer = composition.create_layer();
293    ///
294    /// layer.set_transform(AffineTransform::from([1.0, 0.0, 0.0, 1.0, 1.0, 0.0]).try_into().unwrap());
295    /// ```
296    #[inline]
297    pub fn set_transform(&mut self, transform: GeomPresTransform) -> &mut Self {
298        // We want to perform a cheap check for the common case without hampering this function too
299        // much.
300        #[allow(clippy::float_cmp)]
301        let affine_transform = (!transform.is_identity()).then_some(transform);
302
303        if self.inner.affine_transform != affine_transform {
304            self.is_unchanged.clear();
305            self.inner.affine_transform = affine_transform;
306        }
307
308        self
309    }
310
311    /// Returns the layer's properties.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// # use forma_render::prelude::*;
317    /// let mut composition = Composition::new();
318    ///
319    /// let layer = composition.create_layer();
320    ///
321    /// assert_eq!(layer.props().fill_rule, FillRule::NonZero);
322    /// ```
323    #[inline]
324    pub fn props(&self) -> &Props {
325        &self.props
326    }
327
328    /// Sets the layer's properties.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// # use forma_render::prelude::*;
334    /// let mut composition = Composition::new();
335    ///
336    /// let mut layer = composition.create_layer();
337    ///
338    /// layer.set_props(Props {
339    ///     fill_rule: FillRule::EvenOdd,
340    ///     ..Default::default()
341    /// });
342    /// ```
343    #[inline]
344    pub fn set_props(&mut self, props: Props) -> &mut Self {
345        if *self.props != props {
346            self.is_unchanged.clear();
347            self.props = self.shared_state.inner().props_interner.get(props);
348        }
349
350        self
351    }
352}
353
354impl Drop for Layer {
355    fn drop(&mut self) {
356        self.shared_state
357            .inner()
358            .geom_id_to_order
359            .remove(&self.geom_id);
360    }
361}