diff --git a/crates/typst-pdf/src/krilla.rs b/crates/typst-pdf/src/krilla.rs index 80898281c..53e0cdae6 100644 --- a/crates/typst-pdf/src/krilla.rs +++ b/crates/typst-pdf/src/krilla.rs @@ -1,3 +1,6 @@ +use crate::metadata::build_metadata; +use crate::outline::build_outline; +use crate::page::PageLabelExt; use crate::util::{display_font, AbsExt, PointExt, SizeExt, TransformExt}; use crate::{paint, PdfOptions}; use bytemuck::TransparentWrapper; @@ -29,8 +32,6 @@ use typst_library::visualize::{ FillRule, Geometry, Image, ImageKind, Paint, Path, PathItem, Shape, }; use typst_syntax::Span; -use crate::outline::build_outline; -use crate::page::PageLabelExt; #[derive(Debug, Clone)] pub(crate) struct State { @@ -170,7 +171,7 @@ pub struct GlobalContext<'a> { /// Mapping between locations in the document and named destinations. loc_to_named: HashMap, /// The languages used throughout the document. - languages: BTreeMap, + pub(crate) languages: BTreeMap, } impl<'a> GlobalContext<'a> { @@ -334,56 +335,8 @@ pub fn pdf( } } - let metadata = { - let creator = format!("Typst {}", env!("CARGO_PKG_VERSION")); - - let mut metadata = krilla::metadata::Metadata::new() - .creator(creator) - .keywords( - typst_document - .info - .keywords - .iter() - .map(EcoString::to_string) - .collect(), - ) - .authors( - typst_document.info.author.iter().map(EcoString::to_string).collect(), - ); - - let lang = gc.languages.iter().max_by_key(|(_, &count)| count).map(|(&l, _)| l); - - if let Some(lang) = lang { - metadata = metadata.language(lang.as_str().to_string()); - } - - if let Some(title) = &typst_document.info.title { - metadata = metadata.title(title.to_string()); - } - - if let Some(subject) = &typst_document.info.description { - metadata = metadata.subject(subject.to_string()); - } - - if let Some(ident) = options.ident.custom() { - metadata = metadata.subject(ident.to_string()); - } - - let tz = typst_document.info.date.is_auto(); - if let Some(date) = typst_document - .info - .date - .unwrap_or(options.timestamp) - .and_then(|d| krilla_date(d, tz)) - { - metadata = metadata.modification_date(date).creation_date(date); - } - - metadata - }; - document.set_outline(build_outline(&gc)); - document.set_metadata(metadata); + document.set_metadata(build_metadata(&gc)); match document.finish() { Ok(r) => Ok(r), @@ -500,38 +453,6 @@ pub fn pdf( } } -fn krilla_date(datetime: Datetime, tz: bool) -> Option { - let year = datetime.year().filter(|&y| y >= 0)? as u16; - - let mut krilla_date = krilla::metadata::DateTime::new(year); - - if let Some(month) = datetime.month() { - krilla_date = krilla_date.month(month); - } - - if let Some(day) = datetime.day() { - krilla_date = krilla_date.day(day); - } - - if let Some(h) = datetime.hour() { - krilla_date = krilla_date.hour(h); - } - - if let Some(m) = datetime.minute() { - krilla_date = krilla_date.minute(m); - } - - if let Some(s) = datetime.second() { - krilla_date = krilla_date.second(s); - } - - if tz { - krilla_date = krilla_date.utc_offset_hour(0).utc_offset_minute(0); - } - - Some(krilla_date) -} - pub fn process_frame( fc: &mut FrameContext, frame: &Frame, diff --git a/crates/typst-pdf/src/lib.rs b/crates/typst-pdf/src/lib.rs index 92067d1fd..da1cbce34 100644 --- a/crates/typst-pdf/src/lib.rs +++ b/crates/typst-pdf/src/lib.rs @@ -2,10 +2,11 @@ mod image; mod krilla; -mod paint; -mod page; -mod util; +mod metadata; mod outline; +mod page; +mod paint; +mod util; use typst_library::diag::SourceResult; use typst_library::foundations::{Datetime, Smart}; diff --git a/crates/typst-pdf/src/metadata.rs b/crates/typst-pdf/src/metadata.rs new file mode 100644 index 000000000..c0793d1f5 --- /dev/null +++ b/crates/typst-pdf/src/metadata.rs @@ -0,0 +1,78 @@ +use ecow::EcoString; +use krilla::metadata::Metadata; +use typst_library::foundations::Datetime; + +use crate::krilla::GlobalContext; + +pub(crate) fn build_metadata(gc: &GlobalContext) -> Metadata { + let creator = format!("Typst {}", env!("CARGO_PKG_VERSION")); + + let mut metadata = Metadata::new() + .creator(creator) + .keywords(gc.document.info.keywords.iter().map(EcoString::to_string).collect()) + .authors(gc.document.info.author.iter().map(EcoString::to_string).collect()); + + let lang = gc.languages.iter().max_by_key(|(_, &count)| count).map(|(&l, _)| l); + + if let Some(lang) = lang { + metadata = metadata.language(lang.as_str().to_string()); + } + + if let Some(title) = &gc.document.info.title { + metadata = metadata.title(title.to_string()); + } + + if let Some(subject) = &gc.document.info.description { + metadata = metadata.subject(subject.to_string()); + } + + if let Some(ident) = gc.options.ident.custom() { + metadata = metadata.subject(ident.to_string()); + } + + let tz = gc.document.info.date.is_auto(); + if let Some(date) = gc + .document + .info + .date + .unwrap_or(gc.options.timestamp) + .and_then(|d| convert_date(d, tz)) + { + metadata = metadata.modification_date(date).creation_date(date); + } + + metadata +} + +// TODO: Sync with recent PR +fn convert_date(datetime: Datetime, tz: bool) -> Option { + let year = datetime.year().filter(|&y| y >= 0)? as u16; + + let mut krilla_date = krilla::metadata::DateTime::new(year); + + if let Some(month) = datetime.month() { + krilla_date = krilla_date.month(month); + } + + if let Some(day) = datetime.day() { + krilla_date = krilla_date.day(day); + } + + if let Some(h) = datetime.hour() { + krilla_date = krilla_date.hour(h); + } + + if let Some(m) = datetime.minute() { + krilla_date = krilla_date.minute(m); + } + + if let Some(s) = datetime.second() { + krilla_date = krilla_date.second(s); + } + + if tz { + krilla_date = krilla_date.utc_offset_hour(0).utc_offset_minute(0); + } + + Some(krilla_date) +} diff --git a/crates/typst-pdf/src/page.rs b/crates/typst-pdf/src/page.rs index 02f0b06b6..25e4a4976 100644 --- a/crates/typst-pdf/src/page.rs +++ b/crates/typst-pdf/src/page.rs @@ -56,4 +56,4 @@ impl PageLabelExt for PageLabel { 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 54e3febab..01a69cf7d 100644 --- a/crates/typst-pdf/src/util.rs +++ b/crates/typst-pdf/src/util.rs @@ -1,8 +1,8 @@ //! Basic utilities for converting typst types to krilla. +use krilla::color::rgb as kr; use krilla::geom as kg; use krilla::path as kp; -use krilla::color::rgb as kr; use typst_library::layout::{Abs, Point, Size, Transform}; use typst_library::text::Font; @@ -105,8 +105,7 @@ impl ColorExt for Color { fn to_krilla_rgb(&self) -> (kr::Color, u8) { let components = self.to_space(ColorSpace::Srgb).to_vec4_u8(); ( - kr::Color::new(components[0], components[1], components[2]) - .into(), + kr::Color::new(components[0], components[1], components[2]).into(), components[3], ) }