use std::hash::{Hash, Hasher};
use std::sync::Arc;
use ecow::EcoVec;
use typst_library::diag::SourceResult;
use typst_library::engine::Engine;
use typst_library::foundations::{Content, Output, Smart, StyleChain, Target};
use typst_library::introspection::Introspector;
use typst_library::layout::{Abs, Frame, Sides};
use typst_library::model::{Document, DocumentInfo, Numbering};
use typst_library::visualize::{Color, Paint};
use crate::PagedIntrospector;
#[derive(Debug, Clone)]
pub struct PagedDocument {
pages: EcoVec<Page>,
info: DocumentInfo,
introspector: Arc<PagedIntrospector>,
}
impl PagedDocument {
pub fn new(pages: EcoVec<Page>, info: DocumentInfo) -> Self {
let introspector = PagedIntrospector::new(&pages);
Self { pages, info, introspector: Arc::new(introspector) }
}
pub fn pages(&self) -> &[Page] {
&self.pages
}
pub fn info_mut(&mut self) -> &mut DocumentInfo {
&mut self.info
}
pub fn introspector(&self) -> &Arc<PagedIntrospector> {
&self.introspector
}
}
impl Hash for PagedDocument {
fn hash<H: Hasher>(&self, state: &mut H) {
self.pages.hash(state);
self.info.hash(state);
}
}
impl Document for PagedDocument {
fn info(&self) -> &DocumentInfo {
&self.info
}
}
impl Output for PagedDocument {
fn introspector(&self) -> &dyn Introspector {
self.introspector.as_ref()
}
fn target() -> Target {
Target::Paged
}
fn create(
engine: &mut Engine,
content: &Content,
styles: StyleChain,
) -> SourceResult<Self> {
crate::layout_document(engine, content, styles)
}
}
#[derive(Debug, Clone, Hash)]
pub struct Page {
pub frame: Frame,
pub bleed: Sides<Abs>,
pub fill: Smart<Option<Paint>>,
pub numbering: Option<Numbering>,
pub supplement: Content,
pub number: u64,
}
impl Page {
pub fn fill_or_transparent(&self) -> Option<Paint> {
self.fill.clone().unwrap_or(None)
}
pub fn fill_or_white(&self) -> Option<Paint> {
self.fill.clone().unwrap_or_else(|| Some(Color::WHITE.into()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_paged_document_is_send_and_sync() {
fn ensure_send_and_sync<T: Send + Sync>() {}
ensure_send_and_sync::<PagedDocument>();
}
}