diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-11-16 21:32:29 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-11-16 21:32:29 +0100 |
| commit | 9a800daa82833c57eee04e92c701ca9a05a67d3b (patch) | |
| tree | a2c790f606037319393e9da3150bf58b44d4171d /src/frame.rs | |
| parent | 0cdf17216f47312f634d2dea8db237118ede72ce (diff) | |
Image fit modes
Diffstat (limited to 'src/frame.rs')
| -rw-r--r-- | src/frame.rs | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/src/frame.rs b/src/frame.rs index 68aa2e9c..94234ae9 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -16,8 +16,10 @@ pub struct Frame { pub size: Size, /// The baseline of the frame measured from the top. pub baseline: Length, + /// Whether this frame should be a clipping boundary. + pub clips: bool, /// The elements composing this layout. - pub children: Vec<(Point, FrameChild)>, + pub elements: Vec<(Point, Element)>, } impl Frame { @@ -25,37 +27,44 @@ impl Frame { #[track_caller] pub fn new(size: Size, baseline: Length) -> Self { assert!(size.is_finite()); - Self { size, baseline, children: vec![] } - } - - /// Add an element at a position in the foreground. - pub fn push(&mut self, pos: Point, element: Element) { - self.children.push((pos, FrameChild::Element(element))); + Self { + size, + baseline, + elements: vec![], + clips: false, + } } /// Add an element at a position in the background. pub fn prepend(&mut self, pos: Point, element: Element) { - self.children.insert(0, (pos, FrameChild::Element(element))); + self.elements.insert(0, (pos, element)); + } + + /// Add an element at a position in the foreground. + pub fn push(&mut self, pos: Point, element: Element) { + self.elements.push((pos, element)); } /// Add a frame element. pub fn push_frame(&mut self, pos: Point, subframe: Rc<Self>) { - self.children.push((pos, FrameChild::Group(subframe))) + self.elements.push((pos, Element::Frame(subframe))) } /// Add all elements of another frame, placing them relative to the given /// position. pub fn merge_frame(&mut self, pos: Point, subframe: Self) { - if pos == Point::zero() && self.children.is_empty() { - self.children = subframe.children; + if subframe.clips { + self.push_frame(pos, Rc::new(subframe)); + } else if pos == Point::zero() && self.elements.is_empty() { + self.elements = subframe.elements; } else { - for (subpos, child) in subframe.children { - self.children.push((pos + subpos, child)); + for (subpos, child) in subframe.elements { + self.elements.push((pos + subpos, child)); } } } - /// An iterator over all elements in the frame and its children. + /// An iterator over all non-frame elements in this and nested frames. pub fn elements(&self) -> Elements { Elements { stack: vec![(0, Point::zero(), self)] } } @@ -63,7 +72,7 @@ impl Frame { impl Debug for Frame { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - struct Children<'a>(&'a [(Point, FrameChild)]); + struct Children<'a>(&'a [(Point, Element)]); impl Debug for Children<'_> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { @@ -74,30 +83,12 @@ impl Debug for Frame { f.debug_struct("Frame") .field("size", &self.size) .field("baseline", &self.baseline) - .field("children", &Children(&self.children)) + .field("clips", &self.clips) + .field("children", &Children(&self.elements)) .finish() } } -/// A frame can contain two different kinds of children: a leaf element or a -/// nested frame. -#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] -pub enum FrameChild { - /// A leaf node in the frame tree. - Element(Element), - /// An interior group. - Group(Rc<Frame>), -} - -impl Debug for FrameChild { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Element(element) => element.fmt(f), - Self::Group(frame) => frame.fmt(f), - } - } -} - /// An iterator over all elements in a frame, alongside with their positions. pub struct Elements<'a> { stack: Vec<(usize, Point, &'a Frame)>, @@ -108,23 +99,21 @@ impl<'a> Iterator for Elements<'a> { fn next(&mut self) -> Option<Self::Item> { let (cursor, offset, frame) = self.stack.last_mut()?; - match frame.children.get(*cursor) { - Some((pos, FrameChild::Group(f))) => { + if let Some((pos, e)) = frame.elements.get(*cursor) { + if let Element::Frame(f) = e { let new_offset = *offset + *pos; self.stack.push((0, new_offset, f.as_ref())); self.next() - } - Some((pos, FrameChild::Element(e))) => { + } else { *cursor += 1; Some((*offset + *pos, e)) } - None => { - self.stack.pop(); - if let Some((cursor, _, _)) = self.stack.last_mut() { - *cursor += 1; - } - self.next() + } else { + self.stack.pop(); + if let Some((cursor, _, _)) = self.stack.last_mut() { + *cursor += 1; } + self.next() } } } @@ -141,6 +130,8 @@ pub enum Element { Image(ImageId, Size), /// A link to an external resource. Link(String, Size), + /// A subframe, which can be a clipping boundary. + Frame(Rc<Frame>), } /// A run of shaped text. |
