Skip to content

Replace typst-based pdf creation with custom one#52

Merged
frblo merged 41 commits into
mainfrom
pdf-engine
Apr 1, 2026
Merged

Replace typst-based pdf creation with custom one#52
frblo merged 41 commits into
mainfrom
pdf-engine

Conversation

@frblo

@frblo frblo commented Mar 3, 2026

Copy link
Copy Markdown
Owner

Fixes #30. Replaces the typst-based pdf exporter with a krilla-based one, with an entirely custom built layout engine specifically built to create screenplays. This also removes the typst exporting option, as it was only ever really an intermediate step to create pdfs and I don't see any real argument to keeping it, now that the pdf generation no longer relies on it.

The new pdf generation works incredibly (blazing perhaps?) fast, and removing the typst dependency has also significantly reduced the number of dependencies we use, and thereby significantly reduced the build time for Rustwell.

@frblo frblo marked this pull request as ready for review March 14, 2026 17:29
@frblo frblo requested a review from Frequinzy March 14, 2026 17:30

@Frequinzy Frequinzy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this works but it's pretty messy.

One thing that could help would be storing state in a struct and instead doing function calls as methods on this struct.

I think we can merge this and leave cleaning as an issue if we want, but there is definitely a lot that can be done to make this clearer to understand.

If we decide to merge I can circle back to cleaning thins up a bit in a week or so.

let bold_italic_data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(FONTS[3]);
let mut document = Document::new();

let fonts = FontFamily {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should set the FontFamily when creating the PdfExporter. In the future this can allow us to make it easy for a user to provide their own font.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is something we can look into in the future, but right now I think we should stay to this batteries included approach.

Comment thread crates/rustwell/src/export/pdf.rs Outdated

/// The different ways to break a line into multiple lines.
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
enum BreakType {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should move to its own file. Makes it easier if someone wants to re-use the logic for layouting.

Comment thread crates/rustwell/src/rich_string.rs Outdated
Comment thread crates/rustwell/src/rich_string.rs Outdated
Comment on lines +131 to +135
/// Appends a [`RichString`] to self. Will not merge the last [`Element`] of self, and the
/// first of the other even if they have the same style attributes.
pub fn append(&mut self, mut other: Self) {
self.elements.append(&mut other.elements);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should merge last Element of self, and the first of other if they have the same style. This is an invariant of the RichString and it's nice to maintain it. Although, not crucial.

}
}

impl Display for RichString {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it would be more accurate for Display to add back the delimiters to produce a String that can be parsed to the same RichString. Such that,

let a: RichString;
assert_eq!(a, RichString::from(&a.toString()))


/// An intermediate iterator which allows for seamless iteration over the [Chars] inside a
/// [`RichString`].
pub struct RichIterator<'a> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably also return the Attributes affecting the given char.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attributes are not public, so I won't do this.

frblo and others added 2 commits April 1, 2026 16:18
Co-authored-by: Emil Hultcrantz <90456354+Frequinzy@users.noreply.github.com>
@frblo frblo requested a review from Frequinzy April 1, 2026 19:38
@frblo frblo merged commit debe95c into main Apr 1, 2026
1 check passed
@frblo frblo deleted the pdf-engine branch April 1, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Layout engine

2 participants