summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2022-06-08 13:11:51 +0200
committerMartin Haug <mhaug@live.de>2022-06-08 13:11:51 +0200
commit995a7882d2f8455429c368b97e699eca59359c44 (patch)
tree427654a9b8858bed36381bac8bea673648d1a786 /src/library
parent6d8b65c4b24206a1482ea143791d7a1c410a4313 (diff)
Auto-detect grid row semantics
Diffstat (limited to 'src/library')
-rw-r--r--src/library/layout/grid.rs49
-rw-r--r--src/library/structure/heading.rs1
-rw-r--r--src/library/structure/list.rs4
-rw-r--r--src/library/structure/table.rs4
4 files changed, 31 insertions, 27 deletions
diff --git a/src/library/layout/grid.rs b/src/library/layout/grid.rs
index 2517d193..687091ff 100644
--- a/src/library/layout/grid.rs
+++ b/src/library/layout/grid.rs
@@ -9,8 +9,6 @@ pub struct GridNode {
pub gutter: Spec<Vec<TrackSizing>>,
/// The nodes to be arranged in a grid.
pub cells: Vec<LayoutNode>,
- /// The role of the grid in the semantic tree.
- pub semantic: GridSemantics,
}
#[node]
@@ -28,7 +26,6 @@ impl GridNode {
row_gutter.unwrap_or(base_gutter),
),
cells: args.all()?,
- semantic: GridSemantics::None,
}))
}
}
@@ -48,7 +45,6 @@ impl Layout for GridNode {
&self.cells,
regions,
styles,
- self.semantic,
);
// Measure the columns and layout the grid row-by-row.
@@ -71,7 +67,7 @@ pub enum TrackSizing {
/// Defines what kind of semantics a grid should represent.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum GridSemantics {
+enum GridSemantics {
/// The grid is transparent to the semantic tree.
None,
/// The grid is a list, its rows are list items. The bool indicates whether
@@ -82,6 +78,7 @@ pub enum GridSemantics {
}
impl GridSemantics {
+ /// The role of a row in a grid with these semantics.
fn row(self) -> Option<Role> {
match self {
Self::None => None,
@@ -89,6 +86,18 @@ impl GridSemantics {
Self::Table => Some(Role::TableRow),
}
}
+
+ /// Returns the semantic role of a grid row given the previous semantics and
+ /// the cell's role.
+ fn determine(other: Option<Self>, role: Option<Role>) -> Self {
+ match (other, role) {
+ (None, Some(Role::ListItem | Role::ListLabel)) => Self::List,
+ (Some(Self::List), Some(Role::ListItem | Role::ListLabel)) => Self::List,
+ (None, Some(Role::TableCell)) => Self::Table,
+ (Some(Self::Table), Some(Role::TableCell)) => Self::Table,
+ _ => Self::None,
+ }
+ }
}
castable! {
@@ -130,8 +139,6 @@ pub struct GridLayouter<'a> {
regions: Regions,
/// The inherited styles.
styles: StyleChain<'a>,
- /// The role of the grid in the semantic tree.
- semantic: GridSemantics,
/// Resolved column sizes.
rcols: Vec<Length>,
/// Rows in the current region.
@@ -167,7 +174,6 @@ impl<'a> GridLayouter<'a> {
cells: &'a [LayoutNode],
regions: &Regions,
styles: StyleChain<'a>,
- semantic: GridSemantics,
) -> Self {
let mut cols = vec![];
let mut rows = vec![];
@@ -222,7 +228,6 @@ impl<'a> GridLayouter<'a> {
rows,
regions,
styles,
- semantic,
rcols,
lrows,
full,
@@ -480,11 +485,9 @@ impl<'a> GridLayouter<'a> {
/// Layout a row with fixed height and return its frame.
fn layout_single_row(&mut self, height: Length, y: usize) -> TypResult<Frame> {
let mut output = Frame::new(Size::new(self.used.x, height));
- if let Some(role) = self.semantic.row() {
- output.apply_role(role);
- }
let mut pos = Point::zero();
+ let mut semantic = None;
for (x, &rcol) in self.rcols.iter().enumerate() {
if let Some(node) = self.cell(x, y) {
@@ -498,6 +501,7 @@ impl<'a> GridLayouter<'a> {
let pod = Regions::one(size, base, Spec::splat(true));
let frame = node.layout(self.ctx, &pod, self.styles)?.remove(0);
+ semantic = Some(GridSemantics::determine(semantic, frame.role()));
output.push_frame(pos, frame);
}
@@ -505,6 +509,10 @@ impl<'a> GridLayouter<'a> {
pos.x += rcol;
}
+ if let Some(role) = semantic.and_then(GridSemantics::row) {
+ output.apply_role(role);
+ }
+
Ok(output)
}
@@ -517,14 +525,7 @@ impl<'a> GridLayouter<'a> {
// Prepare frames.
let mut outputs: Vec<_> = heights
.iter()
- .map(|&h| {
- let mut f = Frame::new(Size::new(self.used.x, h));
- if let Some(role) = self.semantic.row() {
- f.apply_role(role);
- }
-
- f
- })
+ .map(|&h| Frame::new(Size::new(self.used.x, h)))
.collect();
// Prepare regions.
@@ -534,6 +535,7 @@ impl<'a> GridLayouter<'a> {
// Layout the row.
let mut pos = Point::zero();
+ let mut semantic = None;
for (x, &rcol) in self.rcols.iter().enumerate() {
if let Some(node) = self.cell(x, y) {
pod.first.x = rcol;
@@ -547,6 +549,7 @@ impl<'a> GridLayouter<'a> {
// Push the layouted frames into the individual output frames.
let frames = node.layout(self.ctx, &pod, self.styles)?;
for (output, frame) in outputs.iter_mut().zip(frames) {
+ semantic = Some(GridSemantics::determine(semantic, frame.role()));
output.push_frame(pos, frame);
}
}
@@ -554,6 +557,12 @@ impl<'a> GridLayouter<'a> {
pos.x += rcol;
}
+ for output in outputs.iter_mut() {
+ if let Some(role) = semantic.and_then(GridSemantics::row) {
+ output.apply_role(role);
+ }
+ }
+
Ok(outputs)
}
diff --git a/src/library/structure/heading.rs b/src/library/structure/heading.rs
index a376bf09..242912a3 100644
--- a/src/library/structure/heading.rs
+++ b/src/library/structure/heading.rs
@@ -1,7 +1,6 @@
use crate::library::layout::BlockSpacing;
use crate::library::prelude::*;
use crate::library::text::{FontFamily, TextNode, TextSize};
-use crate::model::StyleEntry;
/// A section heading.
#[derive(Debug, Hash)]
diff --git a/src/library/structure/list.rs b/src/library/structure/list.rs
index 1c0e251f..077536d4 100644
--- a/src/library/structure/list.rs
+++ b/src/library/structure/list.rs
@@ -2,11 +2,10 @@ use std::fmt::Write;
use unscanny::Scanner;
-use crate::library::layout::{BlockSpacing, GridNode, GridSemantics, TrackSizing};
+use crate::library::layout::{BlockSpacing, GridNode, TrackSizing};
use crate::library::prelude::*;
use crate::library::text::ParNode;
use crate::library::utility::Numbering;
-use crate::model::StyleEntry;
/// An unordered (bulleted) or ordered (numbered) list.
#[derive(Debug, Hash)]
@@ -141,7 +140,6 @@ impl<const L: ListKind> Show for ListNode<L> {
]),
gutter: Spec::with_y(vec![TrackSizing::Relative(gutter.into())]),
cells,
- semantic: GridSemantics::List,
}))
}
diff --git a/src/library/structure/table.rs b/src/library/structure/table.rs
index 118e48ca..0f74fc96 100644
--- a/src/library/structure/table.rs
+++ b/src/library/structure/table.rs
@@ -1,6 +1,5 @@
-use crate::library::layout::{BlockSpacing, GridNode, GridSemantics, TrackSizing};
+use crate::library::layout::{BlockSpacing, GridNode, TrackSizing};
use crate::library::prelude::*;
-use crate::model::StyleEntry;
/// A table of items.
#[derive(Debug, Hash)]
@@ -105,7 +104,6 @@ impl Show for TableNode {
tracks: self.tracks.clone(),
gutter: self.gutter.clone(),
cells,
- semantic: GridSemantics::Table,
})
.role(Role::Table))
}