summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--library/src/layout/mod.rs26
-rw-r--r--library/src/text/mod.rs8
-rw-r--r--src/model/content.rs10
-rw-r--r--src/model/styles.rs13
-rw-r--r--src/util/mod.rs6
5 files changed, 45 insertions, 18 deletions
diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs
index e116f159..1032ba54 100644
--- a/library/src/layout/mod.rs
+++ b/library/src/layout/mod.rs
@@ -33,7 +33,7 @@ use typst::frame::Frame;
use typst::geom::*;
use typst::model::{
capability, Barrier, Content, Node, SequenceNode, Show, StyleChain, StyleEntry,
- StyleMap, StyleVec, StyleVecBuilder, StyledNode, Target,
+ StyleVec, StyleVecBuilder, StyledNode, Target,
};
use typst::World;
@@ -253,8 +253,10 @@ struct Builder<'a> {
struct Scratch<'a> {
/// An arena where intermediate style chains are stored.
styles: Arena<StyleChain<'a>>,
+ /// An arena for individual intermediate style entries.
+ entries: Arena<StyleEntry>,
/// An arena where intermediate content resulting from show rules is stored.
- templates: Arena<Content>,
+ content: Arena<Content>,
}
/// Determines whether a style could interrupt some composable structure.
@@ -305,7 +307,7 @@ impl<'a> Builder<'a> {
) -> SourceResult<()> {
if let Some(text) = content.downcast::<TextNode>() {
if let Some(realized) = styles.apply(self.world, Target::Text(&text.0))? {
- let stored = self.scratch.templates.alloc(realized);
+ let stored = self.scratch.content.alloc(realized);
return self.accept(stored, styles);
}
} else if let Some(styled) = content.downcast::<StyledNode>() {
@@ -357,16 +359,18 @@ impl<'a> Builder<'a> {
content: &'a Content,
styles: StyleChain<'a>,
) -> SourceResult<bool> {
- let Some(mut realized) = styles.apply(self.world, Target::Node(content))? else {
+ let barrier = StyleEntry::Barrier(Barrier::new(content.id()));
+ let styles = self
+ .scratch
+ .entries
+ .alloc(barrier)
+ .chain(self.scratch.styles.alloc(styles));
+
+ let Some(realized) = styles.apply(self.world, Target::Node(content))? else {
return Ok(false);
};
- let mut map = StyleMap::new();
- let barrier = Barrier::new(content.id());
- map.push(StyleEntry::Barrier(barrier));
- map.push(StyleEntry::Barrier(barrier));
- realized = realized.styled_with_map(map);
- let stored = self.scratch.templates.alloc(realized);
+ let stored = self.scratch.content.alloc(realized);
self.accept(stored, styles)?;
Ok(true)
@@ -680,7 +684,7 @@ impl<'a> ListBuilder<'a> {
DESC | _ => ListNode::<DESC> { tight, attached, items }.pack(),
};
- let stored = parent.scratch.templates.alloc(content);
+ let stored = parent.scratch.content.alloc(content);
parent.accept(stored, shared)?;
for (content, styles) in self.staged {
diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs
index a8164727..c2a67547 100644
--- a/library/src/text/mod.rs
+++ b/library/src/text/mod.rs
@@ -25,7 +25,7 @@ use self::quotes::*;
use crate::prelude::*;
/// A single run of text with the same style.
-#[derive(Debug, Clone, Hash)]
+#[derive(Clone, Hash)]
pub struct TextNode(pub EcoString);
impl TextNode {
@@ -169,6 +169,12 @@ impl TextNode {
}
}
+impl Debug for TextNode {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "Text({:?})", self.0)
+ }
+}
+
/// A lowercased font family like "arial".
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct FontFamily(EcoString);
diff --git a/src/model/content.rs b/src/model/content.rs
index bc25cd79..3851d38d 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -115,10 +115,14 @@ impl Content {
pub fn styled_with_entry(mut self, entry: StyleEntry) -> Self {
if let Some(styled) = self.try_downcast_mut::<StyledNode>() {
styled.map.apply(entry);
- return self;
+ self
+ } else if let Some(styled) = self.downcast::<StyledNode>() {
+ let mut map = styled.map.clone();
+ map.apply(entry);
+ StyledNode { sub: styled.sub.clone(), map }.pack()
+ } else {
+ StyledNode { sub: self, map: entry.into() }.pack()
}
-
- StyledNode { sub: self, map: entry.into() }.pack()
}
/// Style this content with a full style map.
diff --git a/src/model/styles.rs b/src/model/styles.rs
index 8e731942..62e3188f 100644
--- a/src/model/styles.rs
+++ b/src/model/styles.rs
@@ -85,6 +85,15 @@ impl StyleMap {
/// Like [`chain`](Self::chain) or [`apply_map`](Self::apply_map), but with
/// only a entry.
pub fn apply(&mut self, entry: StyleEntry) {
+ if let StyleEntry::Guard(a) = &entry {
+ if let [StyleEntry::Unguard(b), ..] = self.0.as_slice() {
+ if a == b {
+ self.0.remove(0);
+ return;
+ }
+ }
+ }
+
self.0.insert(0, entry);
}
@@ -124,7 +133,7 @@ impl From<StyleEntry> for StyleMap {
impl Debug for StyleMap {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- for entry in self.0.iter().rev() {
+ for entry in self.0.iter() {
writeln!(f, "{:?}", entry)?;
}
Ok(())
@@ -351,7 +360,7 @@ impl<'a> StyleChain<'a> {
impl Debug for StyleChain<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- for entry in self.entries() {
+ for entry in self.entries().collect::<Vec<_>>().into_iter().rev() {
writeln!(f, "{:?}", entry)?;
}
Ok(())
diff --git a/src/util/mod.rs b/src/util/mod.rs
index c6809d23..0b681223 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -161,9 +161,13 @@ impl ReadableTypeId {
impl Debug for ReadableTypeId {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
#[cfg(debug_assertions)]
- f.pad(self.name)?;
+ if let Some(part) = self.name.split("::").last() {
+ f.pad(part)?;
+ }
+
#[cfg(not(debug_assertions))]
f.pad("ReadableTypeId")?;
+
Ok(())
}
}