More consistent role application

This commit is contained in:
Martin Haug 2022-06-08 12:30:10 +02:00
parent 4640585fbd
commit 6d8b65c4b2
11 changed files with 43 additions and 39 deletions

View File

@ -448,7 +448,9 @@ pub enum Role {
} }
impl Role { impl Role {
fn is_weak(&self) -> bool { /// Whether the role describes a generic element and is not very
/// descriptive.
pub fn is_weak(self) -> bool {
match self { match self {
Self::Paragraph | Self::GenericBlock | Self::GenericInline => true, Self::Paragraph | Self::GenericBlock | Self::GenericInline => true,
_ => false, _ => false,

View File

@ -91,11 +91,14 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
let child = child.clone().padded(inset.map(|side| side.map(RawLength::from))); let child = child.clone().padded(inset.map(|side| side.map(RawLength::from)));
let mut pod = Regions::one(regions.first, regions.base, regions.expand); let mut pod = Regions::one(regions.first, regions.base, regions.expand);
let role_map = StyleMap::with_role(Role::GenericBlock);
let styles = role_map.chain(&styles);
frames = child.layout(ctx, &pod, styles)?; frames = child.layout(ctx, &pod, styles)?;
for frame in frames.iter_mut() {
if frame.role().map_or(true, Role::is_weak) {
Arc::make_mut(frame).apply_role(Role::GenericBlock);
}
}
// Relayout with full expansion into square region to make sure // Relayout with full expansion into square region to make sure
// the result is really a square or circle. // the result is really a square or circle.
if is_quadratic(S) { if is_quadratic(S) {

View File

@ -184,7 +184,7 @@ impl FlowLayouter {
let len = frames.len(); let len = frames.len();
for (i, mut frame) in frames.into_iter().enumerate() { for (i, mut frame) in frames.into_iter().enumerate() {
// Set the generic block role. // Set the generic block role.
if frame.role().is_none() { if frame.role().map_or(true, Role::is_weak) {
Arc::make_mut(&mut frame).apply_role(Role::GenericBlock); Arc::make_mut(&mut frame).apply_role(Role::GenericBlock);
} }

View File

@ -130,7 +130,8 @@ impl PageNode {
let pod = Regions::one(area, area, Spec::splat(true)); let pod = Regions::one(area, area, Spec::splat(true));
let role_map = StyleMap::with_role(role); let role_map = StyleMap::with_role(role);
let styles = role_map.chain(&styles); let styles = role_map.chain(&styles);
let sub = content.layout(ctx, &pod, styles)?.remove(0); let mut sub = content.layout(ctx, &pod, styles)?.remove(0);
Arc::make_mut(&mut sub).apply_role(role);
if std::ptr::eq(marginal, background) { if std::ptr::eq(marginal, background) {
Arc::make_mut(frame).prepend_frame(pos, sub); Arc::make_mut(frame).prepend_frame(pos, sub);

View File

@ -192,12 +192,14 @@ impl<'a> StackLayouter<'a> {
self.dir.start().into() self.dir.start().into()
}); });
let role_map = StyleMap::with_role(Role::GenericBlock);
let styles = role_map.chain(&styles);
let frames = node.layout(ctx, &self.regions, styles)?; let frames = node.layout(ctx, &self.regions, styles)?;
let len = frames.len(); let len = frames.len();
for (i, frame) in frames.into_iter().enumerate() { for (i, mut frame) in frames.into_iter().enumerate() {
// Set the generic block role.
if frame.role().map_or(true, Role::is_weak) {
Arc::make_mut(&mut frame).apply_role(Role::GenericBlock);
}
// Grow our size, shrink the region and save the frame for later. // Grow our size, shrink the region and save the frame for later.
let size = frame.size.to_gen(self.axis); let size = frame.size.to_gen(self.axis);
self.used.main += size.main; self.used.main += size.main;

View File

@ -66,13 +66,8 @@ impl HeadingNode {
impl Show for HeadingNode { impl Show for HeadingNode {
fn unguard(&self, sel: Selector) -> ShowNode { fn unguard(&self, sel: Selector) -> ShowNode {
let mut map = StyleMap::with_role(Role::Heading(self.level.get())); let body = self.body.unguard(sel).role(Role::Heading(self.level.get()));
map.push(StyleEntry::Unguard(sel)); Self { body, ..*self }.pack()
Self {
body: self.body.clone().styled_with_map(map),
..*self
}
.pack()
} }
fn encode(&self, _: StyleChain) -> Dict { fn encode(&self, _: StyleChain) -> Dict {

View File

@ -77,12 +77,9 @@ impl<const L: ListKind> ListNode<L> {
impl<const L: ListKind> Show for ListNode<L> { impl<const L: ListKind> Show for ListNode<L> {
fn unguard(&self, sel: Selector) -> ShowNode { fn unguard(&self, sel: Selector) -> ShowNode {
let mut map = StyleMap::with_role(Role::ListItemBody);
map.push(StyleEntry::Unguard(sel));
Self { Self {
items: self.items.map(|item| ListItem { items: self.items.map(|item| ListItem {
body: Box::new(item.body.clone().styled_with_map(map.clone())), body: Box::new(item.body.unguard(sel).role(Role::ListItemBody)),
..*item ..*item
}), }),
..*self ..*self
@ -113,11 +110,14 @@ impl<const L: ListKind> Show for ListNode<L> {
for (item, map) in self.items.iter() { for (item, map) in self.items.iter() {
number = item.number.unwrap_or(number); number = item.number.unwrap_or(number);
let mut label_map = map.clone();
label_map.push(StyleEntry::Role(Role::ListLabel));
cells.push(LayoutNode::default()); cells.push(LayoutNode::default());
cells.push(label.resolve(ctx, L, number)?.styled_with_map(label_map).pack()); cells.push(
label
.resolve(ctx, L, number)?
.styled_with_map(map.clone())
.role(Role::ListLabel)
.pack(),
);
cells.push(LayoutNode::default()); cells.push(LayoutNode::default());
cells.push((*item.body).clone().styled_with_map(map.clone()).pack()); cells.push((*item.body).clone().styled_with_map(map.clone()).pack());
number += 1; number += 1;
@ -163,9 +163,7 @@ impl<const L: ListKind> Show for ListNode<L> {
} }
} }
Ok(realized Ok(realized.role(Role::List(L == ORDERED)).spaced(above, below))
.styled_with_map(StyleMap::with_role(Role::List(L == ORDERED)))
.spaced(above, below))
} }
} }

View File

@ -50,16 +50,13 @@ impl TableNode {
impl Show for TableNode { impl Show for TableNode {
fn unguard(&self, sel: Selector) -> ShowNode { fn unguard(&self, sel: Selector) -> ShowNode {
let mut map = StyleMap::with_role(Role::TableCell);
map.push(StyleEntry::Unguard(sel));
Self { Self {
tracks: self.tracks.clone(), tracks: self.tracks.clone(),
gutter: self.gutter.clone(), gutter: self.gutter.clone(),
cells: self cells: self
.cells .cells
.iter() .iter()
.map(|cell| cell.clone().styled_with_map(map.clone())) .map(|cell| cell.unguard(sel).role(Role::TableCell))
.collect(), .collect(),
} }
.pack() .pack()
@ -110,7 +107,7 @@ impl Show for TableNode {
cells, cells,
semantic: GridSemantics::Table, semantic: GridSemantics::Table,
}) })
.styled_with_map(StyleMap::with_role(Role::Table))) .role(Role::Table))
} }
fn finalize( fn finalize(

View File

@ -551,14 +551,15 @@ fn prepare<'a>(
} else { } else {
let size = Size::new(regions.first.x, regions.base.y); let size = Size::new(regions.first.x, regions.base.y);
let pod = Regions::one(size, regions.base, Spec::splat(false)); let pod = Regions::one(size, regions.base, Spec::splat(false));
let role_map = StyleMap::with_role(Role::GenericInline);
let styles = role_map.chain(&styles);
let mut frame = node.layout(ctx, &pod, styles)?.remove(0); let mut frame = node.layout(ctx, &pod, styles)?.remove(0);
let shift = styles.get(TextNode::BASELINE); let shift = styles.get(TextNode::BASELINE);
if !shift.is_zero() { if !shift.is_zero() || frame.role().map_or(true, Role::is_weak) {
Arc::make_mut(&mut frame).translate(Point::with_y(shift)); let frame = Arc::make_mut(&mut frame);
frame.translate(Point::with_y(shift));
frame.apply_role(Role::GenericInline);
} }
items.push(Item::Frame(frame)); items.push(Item::Frame(frame));

View File

@ -113,7 +113,7 @@ impl Show for RawNode {
styles: StyleChain, styles: StyleChain,
mut realized: Content, mut realized: Content,
) -> TypResult<Content> { ) -> TypResult<Content> {
let mut map = StyleMap::with_role(Role::Code); let mut map = StyleMap::new();
map.set_family(styles.get(Self::FAMILY).clone(), styles); map.set_family(styles.get(Self::FAMILY).clone(), styles);
map.set(TextNode::OVERHANG, false); map.set(TextNode::OVERHANG, false);
map.set(TextNode::HYPHENATE, Smart::Custom(Hyphenate(false))); map.set(TextNode::HYPHENATE, Smart::Custom(Hyphenate(false)));
@ -123,7 +123,7 @@ impl Show for RawNode {
realized = realized.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW)); realized = realized.spaced(styles.get(Self::ABOVE), styles.get(Self::BELOW));
} }
Ok(realized.styled_with_map(map)) Ok(realized.styled_with_map(map).role(Role::Code))
} }
} }

View File

@ -204,6 +204,11 @@ impl Content {
Self::Styled(Arc::new((self, styles))) Self::Styled(Arc::new((self, styles)))
} }
/// Assign a role to this content by adding a style map.
pub fn role(self, role: Role) -> Self {
self.styled_with_map(StyleMap::with_role(role))
}
/// Reenable the show rule identified by the selector. /// Reenable the show rule identified by the selector.
pub fn unguard(&self, sel: Selector) -> Self { pub fn unguard(&self, sel: Selector) -> Self {
self.clone().styled_with_entry(StyleEntry::Unguard(sel)) self.clone().styled_with_entry(StyleEntry::Unguard(sel))