more refactors

This commit is contained in:
Laurenz Stampfl 2024-12-17 11:26:18 +01:00
parent 548e7c6794
commit 06d7fb7c69
5 changed files with 80 additions and 206 deletions

152
Cargo.lock generated
View File

@ -806,20 +806,6 @@ dependencies = [
"roxmltree", "roxmltree",
] ]
[[package]]
name = "fontdb"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37be9fc20d966be438cd57a45767f73349477fb0f85ce86e000557f787298afb"
dependencies = [
"fontconfig-parser",
"log",
"memmap2",
"slotmap",
"tinyvec",
"ttf-parser",
]
[[package]] [[package]]
name = "fontdb" name = "fontdb"
version = "0.22.0" version = "0.22.0"
@ -1333,23 +1319,23 @@ dependencies = [
"comemo", "comemo",
"flate2", "flate2",
"float-cmp 0.10.0", "float-cmp 0.10.0",
"fontdb 0.22.0", "fontdb",
"gif", "gif",
"image-webp", "image-webp",
"imagesize", "imagesize",
"miniz_oxide", "miniz_oxide",
"once_cell", "once_cell",
"pdf-writer 0.12.0 (git+https://github.com/LaurenzV/pdf-writer?rev=f95a19c)", "pdf-writer",
"rayon", "rayon",
"resvg 0.44.0", "resvg",
"rustybuzz", "rustybuzz",
"siphasher 1.0.1", "siphasher 1.0.1",
"skrifa", "skrifa",
"subsetter 0.2.0 (git+https://github.com/typst/subsetter?rev=172416a)", "subsetter",
"tiny-skia", "tiny-skia",
"tiny-skia-path", "tiny-skia-path",
"usvg 0.44.0", "usvg",
"xmp-writer 0.3.0 (git+https://github.com/LaurenzV/xmp-writer?rev=1c2b8ae9)", "xmp-writer",
"yoke", "yoke",
"zune-jpeg", "zune-jpeg",
"zune-png", "zune-png",
@ -1781,18 +1767,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]]
name = "pdf-writer"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be17f48d7fbbd22c6efedb58af5d409aa578e407f40b29a0bcb4e66ed84c5c98"
dependencies = [
"bitflags 2.6.0",
"itoa",
"memchr",
"ryu",
]
[[package]] [[package]]
name = "pdf-writer" name = "pdf-writer"
version = "0.12.0" version = "0.12.0"
@ -2112,23 +2086,6 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "resvg"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7314563c59c7ce31c18e23ad3dd092c37b928a0fa4e1c0a1a6504351ab411d1"
dependencies = [
"gif",
"image-webp",
"log",
"pico-args",
"rgb",
"svgtypes",
"tiny-skia",
"usvg 0.43.0",
"zune-jpeg",
]
[[package]] [[package]]
name = "resvg" name = "resvg"
version = "0.44.0" version = "0.44.0"
@ -2142,7 +2099,7 @@ dependencies = [
"rgb", "rgb",
"svgtypes", "svgtypes",
"tiny-skia", "tiny-skia",
"usvg 0.44.0", "usvg",
"zune-jpeg", "zune-jpeg",
] ]
@ -2511,37 +2468,11 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "subsetter"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f98178f34057d4d4de93d68104007c6dea4dfac930204a69ab4622daefa648"
[[package]] [[package]]
name = "subsetter" name = "subsetter"
version = "0.2.0" version = "0.2.0"
source = "git+https://github.com/typst/subsetter?rev=172416a#172416a806246e6e9010d400d5690ca7a026e53d" source = "git+https://github.com/typst/subsetter?rev=172416a#172416a806246e6e9010d400d5690ca7a026e53d"
[[package]]
name = "svg2pdf"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5014c9dadcf318fb7ef8c16438e95abcc9de1ae24d60d5bccc64c55100c50364"
dependencies = [
"fontdb 0.21.0",
"image",
"log",
"miniz_oxide",
"once_cell",
"pdf-writer 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"resvg 0.43.0",
"siphasher 1.0.1",
"subsetter 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-skia",
"ttf-parser",
"usvg 0.43.0",
]
[[package]] [[package]]
name = "svgtypes" name = "svgtypes"
version = "0.15.2" version = "0.15.2"
@ -2988,7 +2919,7 @@ dependencies = [
"ecow", "ecow",
"env_proxy", "env_proxy",
"flate2", "flate2",
"fontdb 0.22.0", "fontdb",
"native-tls", "native-tls",
"once_cell", "once_cell",
"openssl", "openssl",
@ -3045,7 +2976,7 @@ dependencies = [
"csv", "csv",
"ecow", "ecow",
"flate2", "flate2",
"fontdb 0.22.0", "fontdb",
"hayagriva", "hayagriva",
"icu_properties", "icu_properties",
"icu_provider", "icu_provider",
@ -3084,7 +3015,7 @@ dependencies = [
"unicode-math-class", "unicode-math-class",
"unicode-segmentation", "unicode-segmentation",
"unscanny", "unscanny",
"usvg 0.44.0", "usvg",
"wasmi", "wasmi",
"xmlwriter", "xmlwriter",
] ]
@ -3116,32 +3047,6 @@ dependencies = [
"typst-utils", "typst-utils",
] ]
[[package]]
name = "typst-pdf-old"
version = "0.12.0"
dependencies = [
"arrayvec",
"base64",
"bytemuck",
"comemo",
"ecow",
"image",
"indexmap 2.6.0",
"miniz_oxide",
"pdf-writer 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde",
"subsetter 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"svg2pdf",
"ttf-parser",
"typst-assets",
"typst-library",
"typst-macros",
"typst-syntax",
"typst-timing",
"typst-utils",
"xmp-writer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "typst-realize" name = "typst-realize"
version = "0.12.0" version = "0.12.0"
@ -3166,7 +3071,7 @@ dependencies = [
"comemo", "comemo",
"image", "image",
"pixglyph", "pixglyph",
"resvg 0.44.0", "resvg",
"tiny-skia", "tiny-skia",
"ttf-parser", "ttf-parser",
"typst-library", "typst-library",
@ -3388,33 +3293,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "usvg"
version = "0.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6803057b5cbb426e9fb8ce2216f3a9b4ca1dd2c705ba3cbebc13006e437735fd"
dependencies = [
"base64",
"data-url",
"flate2",
"fontdb 0.21.0",
"imagesize",
"kurbo",
"log",
"pico-args",
"roxmltree",
"rustybuzz",
"simplecss",
"siphasher 1.0.1",
"strict-num",
"svgtypes",
"tiny-skia-path",
"unicode-bidi",
"unicode-script",
"unicode-vo",
"xmlwriter",
]
[[package]] [[package]]
name = "usvg" name = "usvg"
version = "0.44.0" version = "0.44.0"
@ -3424,7 +3302,7 @@ dependencies = [
"base64", "base64",
"data-url", "data-url",
"flate2", "flate2",
"fontdb 0.22.0", "fontdb",
"imagesize", "imagesize",
"kurbo", "kurbo",
"log", "log",
@ -3809,12 +3687,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
[[package]]
name = "xmp-writer"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8254499146a4fd0c86e3e99cf4a9f468f595808fb49ff8f3e495f2b117bf4ebc"
[[package]] [[package]]
name = "xmp-writer" name = "xmp-writer"
version = "0.3.0" version = "0.3.0"

View File

@ -1,4 +1,4 @@
use crate::util::{font_to_str, AbsExt, PageLabelExt, PointExt, SizeExt, TransformExt}; use crate::util::{display_font, AbsExt, PointExt, SizeExt, TransformExt};
use crate::{paint, PdfOptions}; use crate::{paint, PdfOptions};
use bytemuck::TransparentWrapper; use bytemuck::TransparentWrapper;
use ecow::EcoString; use ecow::EcoString;
@ -30,6 +30,7 @@ use typst_library::visualize::{
}; };
use typst_syntax::Span; use typst_syntax::Span;
use crate::outline::build_outline; use crate::outline::build_outline;
use crate::page::PageLabelExt;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct State { pub(crate) struct State {
@ -384,7 +385,7 @@ pub fn pdf(
Ok(r) => Ok(r), Ok(r) => Ok(r),
Err(e) => match e { Err(e) => match e {
KrillaError::FontError(f, s) => { KrillaError::FontError(f, s) => {
let font_str = font_to_str(gc.fonts_backward.get(&f).unwrap()); let font_str = display_font(gc.fonts_backward.get(&f).unwrap());
bail!(Span::detached(), "failed to process font {font_str} ({s})"); bail!(Span::detached(), "failed to process font {font_str} ({s})");
} }
KrillaError::UserError(u) => { KrillaError::UserError(u) => {
@ -698,7 +699,7 @@ pub fn handle_text(
true, true,
) { ) {
None => { None => {
let font_str = font_to_str(&typst_font); let font_str = display_font(&typst_font);
bail!(Span::detached(), "failed to process font {font_str}"); bail!(Span::detached(), "failed to process font {font_str}");
} }
Some(f) => f, Some(f) => f,

View File

@ -1,8 +1,9 @@
//! Exporting of Typst documents into PDFs. //! Exporting Typst documents to PDF.
mod image; mod image;
mod krilla; mod krilla;
mod paint; mod paint;
mod page;
mod util; mod util;
mod outline; mod outline;

View File

@ -0,0 +1,59 @@
use std::num::NonZeroUsize;
use krilla::page::{NumberingStyle, PageLabel};
use typst_library::model::Numbering;
pub trait PageLabelExt {
/// Create a new `PageLabel` from a `Numbering` applied to a page
/// number.
fn generate(numbering: &Numbering, number: usize) -> Option<PageLabel>;
/// Creates an arabic page label with the specified page number.
/// For example, this will display page label `11` when given the page
/// number 11.
fn arabic(number: usize) -> PageLabel;
}
impl PageLabelExt for PageLabel {
fn generate(numbering: &Numbering, number: usize) -> Option<PageLabel> {
{
let Numbering::Pattern(pat) = numbering else {
return None;
};
let (prefix, kind) = pat.pieces.first()?;
// If there is a suffix, we cannot use the common style optimisation,
// since PDF does not provide a suffix field.
let style = if pat.suffix.is_empty() {
use krilla::page::NumberingStyle as Style;
use typst_library::model::NumberingKind as Kind;
match kind {
Kind::Arabic => Some(Style::Arabic),
Kind::LowerRoman => Some(Style::LowerRoman),
Kind::UpperRoman => Some(Style::UpperRoman),
Kind::LowerLatin if number <= 26 => Some(Style::LowerAlpha),
Kind::LowerLatin if number <= 26 => Some(Style::UpperAlpha),
_ => None,
}
} else {
None
};
// Prefix and offset depend on the style: If it is supported by the PDF
// spec, we use the given prefix and an offset. Otherwise, everything
// goes into prefix.
let prefix = if style.is_none() {
Some(pat.apply(&[number]))
} else {
(!prefix.is_empty()).then(|| prefix.clone())
};
let offset = style.and(NonZeroUsize::new(number));
Some(PageLabel::new(style, prefix.map(|s| s.to_string()), offset))
}
}
fn arabic(number: usize) -> PageLabel {
PageLabel::new(Some(NumberingStyle::Arabic), None, NonZeroUsize::new(number))
}
}

View File

@ -1,9 +1,6 @@
//! Convert basic primitive types from typst to krilla. //! Basic utilities for converting typst types to krilla.
use krilla::page::{NumberingStyle, PageLabel};
use std::num::NonZeroUsize;
use typst_library::layout::{Abs, Point, Size, Transform}; use typst_library::layout::{Abs, Point, Size, Transform};
use typst_library::model::Numbering;
use typst_library::text::Font; use typst_library::text::Font;
use typst_library::visualize::{FillRule, LineCap, LineJoin}; use typst_library::visualize::{FillRule, LineCap, LineJoin};
@ -85,9 +82,7 @@ impl FillRuleExt for FillRule {
} }
} }
/// Additional methods for [`Abs`].
pub(crate) trait AbsExt { pub(crate) trait AbsExt {
/// Convert an to a number of points.
fn to_f32(self) -> f32; fn to_f32(self) -> f32;
} }
@ -97,62 +92,8 @@ impl AbsExt for Abs {
} }
} }
pub(crate) trait PageLabelExt { /// Display the font family and variant.
fn generate(numbering: &Numbering, number: usize) -> Option<PageLabel>; pub(crate) fn display_font(font: &Font) -> String {
fn arabic(number: usize) -> PageLabel;
}
impl PageLabelExt for PageLabel {
/// Create a new `PageLabel` from a `Numbering` applied to a page
/// number.
fn generate(numbering: &Numbering, number: usize) -> Option<PageLabel> {
{
let Numbering::Pattern(pat) = numbering else {
return None;
};
let (prefix, kind) = pat.pieces.first()?;
// If there is a suffix, we cannot use the common style optimisation,
// since PDF does not provide a suffix field.
let style = if pat.suffix.is_empty() {
use krilla::page::NumberingStyle as Style;
use typst_library::model::NumberingKind as Kind;
match kind {
Kind::Arabic => Some(Style::Arabic),
Kind::LowerRoman => Some(Style::LowerRoman),
Kind::UpperRoman => Some(Style::UpperRoman),
Kind::LowerLatin if number <= 26 => Some(Style::LowerAlpha),
Kind::LowerLatin if number <= 26 => Some(Style::UpperAlpha),
_ => None,
}
} else {
None
};
// Prefix and offset depend on the style: If it is supported by the PDF
// spec, we use the given prefix and an offset. Otherwise, everything
// goes into prefix.
let prefix = if style.is_none() {
Some(pat.apply(&[number]))
} else {
(!prefix.is_empty()).then(|| prefix.clone())
};
let offset = style.and(NonZeroUsize::new(number));
Some(PageLabel::new(style, prefix.map(|s| s.to_string()), offset))
}
}
/// Creates an arabic page label with the specified page number.
/// For example, this will display page label `11` when given the page
/// number 11.
fn arabic(number: usize) -> PageLabel {
PageLabel::new(Some(NumberingStyle::Arabic), None, NonZeroUsize::new(number))
}
}
pub(crate) fn font_to_str(font: &Font) -> String {
let font_family = &font.info().family; let font_family = &font.info().family;
let font_variant = font.info().variant; let font_variant = font.info().variant;
format!("{} ({:?})", font_family, font_variant) format!("{} ({:?})", font_family, font_variant)