From 06d7fb7c694eeb0f83aeec38ed416a20bfec976a Mon Sep 17 00:00:00 2001 From: Laurenz Stampfl Date: Tue, 17 Dec 2024 11:26:18 +0100 Subject: [PATCH] more refactors --- Cargo.lock | 152 +++------------------------------ crates/typst-pdf/src/krilla.rs | 7 +- crates/typst-pdf/src/lib.rs | 3 +- crates/typst-pdf/src/page.rs | 59 +++++++++++++ crates/typst-pdf/src/util.rs | 65 +------------- 5 files changed, 80 insertions(+), 206 deletions(-) create mode 100644 crates/typst-pdf/src/page.rs diff --git a/Cargo.lock b/Cargo.lock index 247b96c31..6e48636e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,20 +806,6 @@ dependencies = [ "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]] name = "fontdb" version = "0.22.0" @@ -1333,23 +1319,23 @@ dependencies = [ "comemo", "flate2", "float-cmp 0.10.0", - "fontdb 0.22.0", + "fontdb", "gif", "image-webp", "imagesize", "miniz_oxide", "once_cell", - "pdf-writer 0.12.0 (git+https://github.com/LaurenzV/pdf-writer?rev=f95a19c)", + "pdf-writer", "rayon", - "resvg 0.44.0", + "resvg", "rustybuzz", "siphasher 1.0.1", "skrifa", - "subsetter 0.2.0 (git+https://github.com/typst/subsetter?rev=172416a)", + "subsetter", "tiny-skia", "tiny-skia-path", - "usvg 0.44.0", - "xmp-writer 0.3.0 (git+https://github.com/LaurenzV/xmp-writer?rev=1c2b8ae9)", + "usvg", + "xmp-writer", "yoke", "zune-jpeg", "zune-png", @@ -1781,18 +1767,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "pdf-writer" version = "0.12.0" @@ -2112,23 +2086,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "resvg" version = "0.44.0" @@ -2142,7 +2099,7 @@ dependencies = [ "rgb", "svgtypes", "tiny-skia", - "usvg 0.44.0", + "usvg", "zune-jpeg", ] @@ -2511,37 +2468,11 @@ dependencies = [ "syn", ] -[[package]] -name = "subsetter" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f98178f34057d4d4de93d68104007c6dea4dfac930204a69ab4622daefa648" - [[package]] name = "subsetter" version = "0.2.0" 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]] name = "svgtypes" version = "0.15.2" @@ -2988,7 +2919,7 @@ dependencies = [ "ecow", "env_proxy", "flate2", - "fontdb 0.22.0", + "fontdb", "native-tls", "once_cell", "openssl", @@ -3045,7 +2976,7 @@ dependencies = [ "csv", "ecow", "flate2", - "fontdb 0.22.0", + "fontdb", "hayagriva", "icu_properties", "icu_provider", @@ -3084,7 +3015,7 @@ dependencies = [ "unicode-math-class", "unicode-segmentation", "unscanny", - "usvg 0.44.0", + "usvg", "wasmi", "xmlwriter", ] @@ -3116,32 +3047,6 @@ dependencies = [ "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]] name = "typst-realize" version = "0.12.0" @@ -3166,7 +3071,7 @@ dependencies = [ "comemo", "image", "pixglyph", - "resvg 0.44.0", + "resvg", "tiny-skia", "ttf-parser", "typst-library", @@ -3388,33 +3293,6 @@ dependencies = [ "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]] name = "usvg" version = "0.44.0" @@ -3424,7 +3302,7 @@ dependencies = [ "base64", "data-url", "flate2", - "fontdb 0.22.0", + "fontdb", "imagesize", "kurbo", "log", @@ -3809,12 +3687,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" -[[package]] -name = "xmp-writer" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8254499146a4fd0c86e3e99cf4a9f468f595808fb49ff8f3e495f2b117bf4ebc" - [[package]] name = "xmp-writer" version = "0.3.0" diff --git a/crates/typst-pdf/src/krilla.rs b/crates/typst-pdf/src/krilla.rs index 13216f413..ea7cdfe70 100644 --- a/crates/typst-pdf/src/krilla.rs +++ b/crates/typst-pdf/src/krilla.rs @@ -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 bytemuck::TransparentWrapper; use ecow::EcoString; @@ -30,6 +30,7 @@ use typst_library::visualize::{ }; use typst_syntax::Span; use crate::outline::build_outline; +use crate::page::PageLabelExt; #[derive(Debug, Clone)] pub(crate) struct State { @@ -384,7 +385,7 @@ pub fn pdf( Ok(r) => Ok(r), Err(e) => match e { 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})"); } KrillaError::UserError(u) => { @@ -698,7 +699,7 @@ pub fn handle_text( true, ) { 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}"); } Some(f) => f, diff --git a/crates/typst-pdf/src/lib.rs b/crates/typst-pdf/src/lib.rs index 6facbd150..92067d1fd 100644 --- a/crates/typst-pdf/src/lib.rs +++ b/crates/typst-pdf/src/lib.rs @@ -1,8 +1,9 @@ -//! Exporting of Typst documents into PDFs. +//! Exporting Typst documents to PDF. mod image; mod krilla; mod paint; +mod page; mod util; mod outline; diff --git a/crates/typst-pdf/src/page.rs b/crates/typst-pdf/src/page.rs new file mode 100644 index 000000000..02f0b06b6 --- /dev/null +++ b/crates/typst-pdf/src/page.rs @@ -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; + /// 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 { + { + 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)) + } +} \ No newline at end of file diff --git a/crates/typst-pdf/src/util.rs b/crates/typst-pdf/src/util.rs index 88111c61f..cfcf13e96 100644 --- a/crates/typst-pdf/src/util.rs +++ b/crates/typst-pdf/src/util.rs @@ -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::model::Numbering; use typst_library::text::Font; use typst_library::visualize::{FillRule, LineCap, LineJoin}; @@ -85,9 +82,7 @@ impl FillRuleExt for FillRule { } } -/// Additional methods for [`Abs`]. pub(crate) trait AbsExt { - /// Convert an to a number of points. fn to_f32(self) -> f32; } @@ -97,62 +92,8 @@ impl AbsExt for Abs { } } -pub(crate) trait PageLabelExt { - fn generate(numbering: &Numbering, number: usize) -> Option; - 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 { - { - 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 { +/// Display the font family and variant. +pub(crate) fn display_font(font: &Font) -> String { let font_family = &font.info().family; let font_variant = font.info().variant; format!("{} ({:?})", font_family, font_variant)