diff options
Diffstat (limited to 'src/frame.rs')
| -rw-r--r-- | src/frame.rs | 141 |
1 files changed, 96 insertions, 45 deletions
diff --git a/src/frame.rs b/src/frame.rs index 934c3f22..628d8c5b 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -17,38 +17,65 @@ use crate::util::{EcoString, MaybeShared}; #[derive(Default, Clone, Eq, PartialEq)] pub struct Frame { /// The size of the frame. - pub size: Size, + size: Size, /// The baseline of the frame measured from the top. If this is `None`, the /// frame's implicit baseline is at the bottom. - pub baseline: Option<Length>, - /// The elements composing this layout. - pub elements: Vec<(Point, Element)>, + baseline: Option<Length>, /// The semantic role of the frame. role: Option<Role>, + /// The elements composing this layout. + elements: Vec<(Point, Element)>, } +/// Accessors and setters. impl Frame { /// Create a new, empty frame. + /// + /// Panics the size is not finite. #[track_caller] pub fn new(size: Size) -> Self { assert!(size.is_finite()); Self { size, baseline: None, - elements: vec![], role: None, + elements: vec![], } } + /// The size of the frame. + pub fn size(&self) -> Size { + self.size + } + + /// The size of the frame, mutably. + pub fn size_mut(&mut self) -> &mut Size { + &mut self.size + } + + /// Set the size of the frame. + pub fn set_size(&mut self, size: Size) { + self.size = size; + } + + /// The width of the frame. + pub fn width(&self) -> Length { + self.size.x + } + + /// The height of the frame. + pub fn height(&self) -> Length { + self.size.y + } + /// The baseline of the frame. pub fn baseline(&self) -> Length { self.baseline.unwrap_or(self.size.y) } - /// The layer the next item will be added on. This corresponds to the number - /// of elements in the frame. - pub fn layer(&self) -> usize { - self.elements.len() + /// Set the frame's baseline from the top. + pub fn set_baseline(&mut self, baseline: Length) { + self.baseline = Some(baseline); } /// The role of the frame. @@ -56,9 +83,36 @@ impl Frame { self.role } - /// Whether the frame has comparatively few elements. - pub fn is_light(&self) -> bool { - self.elements.len() <= 5 + /// An iterator over the elements inside this frame alongside their + /// positions relative to the top-left of the frame. + pub fn elements(&self) -> std::slice::Iter<'_, (Point, Element)> { + self.elements.iter() + } + + /// Recover the text inside of the frame and its children. + pub fn text(&self) -> EcoString { + let mut text = EcoString::new(); + for (_, element) in &self.elements { + match element { + Element::Text(content) => { + for glyph in &content.glyphs { + text.push(glyph.c); + } + } + Element::Group(group) => text.push_str(&group.frame.text()), + _ => {} + } + } + text + } +} + +/// Inserting elements and subframes. +impl Frame { + /// The layer the next item will be added on. This corresponds to the number + /// of elements in the frame. + pub fn layer(&self) -> usize { + self.elements.len() } /// Add an element at a position in the foreground. @@ -66,6 +120,14 @@ impl Frame { self.elements.push((pos, element)); } + /// Insert an element at the given layer in the frame. + /// + /// This panics if the layer is greater than the number of layers present. + #[track_caller] + pub fn insert(&mut self, layer: usize, pos: Point, element: Element) { + self.elements.insert(layer, (pos, element)); + } + /// Add a frame. /// /// Automatically decides whether to inline the frame or to include it as a @@ -105,11 +167,17 @@ impl Frame { } } - /// Insert an element at the given layer in the frame. - /// - /// This panics if the layer is greater than the number of layers present. - pub fn insert(&mut self, layer: usize, pos: Point, element: Element) { - self.elements.insert(layer, (pos, element)); + /// Whether the frame has comparatively few elements. + fn is_light(&self) -> bool { + self.elements.len() <= 5 + } +} + +/// Modify the frame. +impl Frame { + /// Remove all elements from the frame. + pub fn clear(&mut self) { + self.elements.clear(); } /// Resize the frame to a new size, distributing new space according to the @@ -137,11 +205,6 @@ impl Frame { } } - /// Arbitrarily transform the contents of the frame. - pub fn transform(&mut self, transform: Transform) { - self.group(|g| g.transform = transform); - } - /// Apply the given role to the frame if it doesn't already have one. pub fn apply_role(&mut self, role: Role) { if self.role.map_or(true, Role::is_weak) { @@ -149,13 +212,23 @@ impl Frame { } } + /// Link the whole frame to a resource. + pub fn link(&mut self, dest: Destination) { + self.push(Point::zero(), Element::Link(dest, self.size)); + } + + /// Arbitrarily transform the contents of the frame. + pub fn transform(&mut self, transform: Transform) { + self.group(|g| g.transform = transform); + } + /// Clip the contents of a frame to its size. pub fn clip(&mut self) { self.group(|g| g.clips = true); } /// Wrap the frame's contents in a group and modify that group with `f`. - pub fn group<F>(&mut self, f: F) + fn group<F>(&mut self, f: F) where F: FnOnce(&mut Group), { @@ -165,28 +238,6 @@ impl Frame { wrapper.push(Point::zero(), Element::Group(group)); *self = wrapper; } - - /// Link the whole frame to a resource. - pub fn link(&mut self, dest: Destination) { - self.push(Point::zero(), Element::Link(dest, self.size)); - } - - /// Recover the text inside of the frame and its children. - pub fn text(&self) -> EcoString { - let mut text = EcoString::new(); - for (_, element) in &self.elements { - match element { - Element::Text(content) => { - for glyph in &content.glyphs { - text.push(glyph.c); - } - } - Element::Group(group) => text.push_str(&group.frame.text()), - _ => {} - } - } - text - } } impl Debug for Frame { |
