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 {
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 {
Self::Paragraph | Self::GenericBlock | Self::GenericInline => true,
_ => 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 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)?;
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
// the result is really a square or circle.
if is_quadratic(S) {

View File

@ -184,7 +184,7 @@ impl FlowLayouter {
let len = frames.len();
for (i, mut frame) in frames.into_iter().enumerate() {
// 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);
}

View File

@ -130,7 +130,8 @@ impl PageNode {
let pod = Regions::one(area, area, Spec::splat(true));
let role_map = StyleMap::with_role(role);
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) {
Arc::make_mut(frame).prepend_frame(pos, sub);

View File

@ -192,12 +192,14 @@ impl<'a> StackLayouter<'a> {
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 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.
let size = frame.size.to_gen(self.axis);
self.used.main += size.main;

View File

@ -66,13 +66,8 @@ impl HeadingNode {
impl Show for HeadingNode {
fn unguard(&self, sel: Selector) -> ShowNode {
let mut map = StyleMap::with_role(Role::Heading(self.level.get()));
map.push(StyleEntry::Unguard(sel));
Self {
body: self.body.clone().styled_with_map(map),
..*self
}
.pack()
let body = self.body.unguard(sel).role(Role::Heading(self.level.get()));
Self { body, ..*self }.pack()
}
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> {
fn unguard(&self, sel: Selector) -> ShowNode {
let mut map = StyleMap::with_role(Role::ListItemBody);
map.push(StyleEntry::Unguard(sel));
Self {
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
}),
..*self
@ -113,11 +110,14 @@ impl<const L: ListKind> Show for ListNode<L> {
for (item, map) in self.items.iter() {
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(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((*item.body).clone().styled_with_map(map.clone()).pack());
number += 1;
@ -163,9 +163,7 @@ impl<const L: ListKind> Show for ListNode<L> {
}
}
Ok(realized
.styled_with_map(StyleMap::with_role(Role::List(L == ORDERED)))
.spaced(above, below))
Ok(realized.role(Role::List(L == ORDERED)).spaced(above, below))
}
}

View File

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

View File

@ -551,14 +551,15 @@ fn prepare<'a>(
} else {
let size = Size::new(regions.first.x, regions.base.y);
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 shift = styles.get(TextNode::BASELINE);
if !shift.is_zero() {
Arc::make_mut(&mut frame).translate(Point::with_y(shift));
if !shift.is_zero() || frame.role().map_or(true, Role::is_weak) {
let frame = Arc::make_mut(&mut frame);
frame.translate(Point::with_y(shift));
frame.apply_role(Role::GenericInline);
}
items.push(Item::Frame(frame));

View File

@ -113,7 +113,7 @@ impl Show for RawNode {
styles: StyleChain,
mut realized: 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(TextNode::OVERHANG, 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));
}
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)))
}
/// 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.
pub fn unguard(&self, sel: Selector) -> Self {
self.clone().styled_with_entry(StyleEntry::Unguard(sel))