summaryrefslogtreecommitdiff
path: root/src/frame.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/frame.rs')
-rw-r--r--src/frame.rs141
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 {