From a3d444c119f3c8b603ef0dd59cb4c78b479f05f3 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 5 Oct 2025 18:11:10 -0700 Subject: [PATCH] work on pagesetup --- rust/Cargo.lock | 1 + rust/pspp/Cargo.toml | 1 + rust/pspp/src/output/page.rs | 60 +++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 20418374eb..88ec82c1f7 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1823,6 +1823,7 @@ dependencies = [ "ordered-float", "pango", "pangocairo", + "paper-sizes", "pspp-derive", "quick-xml", "rand", diff --git a/rust/pspp/Cargo.toml b/rust/pspp/Cargo.toml index 232a8282b8..5479134fb5 100644 --- a/rust/pspp/Cargo.toml +++ b/rust/pspp/Cargo.toml @@ -57,6 +57,7 @@ displaydoc = "0.2.5" codepage-437 = "0.1.0" serde_path_to_error = "0.1.20" html_parser = "0.7.0" +paper-sizes = { path = "../paper-sizes" } [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.48.0", features = ["Win32_Globalization"] } diff --git a/rust/pspp/src/output/page.rs b/rust/pspp/src/output/page.rs index ab89d6c375..19ddcf801f 100644 --- a/rust/pspp/src/output/page.rs +++ b/rust/pspp/src/output/page.rs @@ -14,10 +14,11 @@ // You should have received a copy of the GNU General Public License along with // this program. If not, see . -use std::{path::Path, str::FromStr}; +use std::{path::Path, str::FromStr, sync::LazyLock}; use enum_map::{EnumMap, enum_map}; -use serde::{Deserialize, Serialize}; +use paper_sizes::{Catalog, PaperSize}; +use serde::{Deserialize, Deserializer, Serialize, de::Error}; use super::pivot::{Axis2, HorzAlign}; @@ -72,6 +73,7 @@ pub struct PageSetup { pub initial_page_number: i32, /// Paper size in inches. + #[serde(with = "paper_size_serde")] pub paper: EnumMap, /// Margin width in inches. @@ -90,11 +92,62 @@ pub struct PageSetup { pub headings: [Heading; 2], } +static CATALOG: LazyLock = LazyLock::new(|| Catalog::new()); + +mod paper_size_serde { + use std::str::FromStr; + + use enum_map::EnumMap; + use paper_sizes::{PaperSize, Unit::Inch}; + use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error}; + + use crate::{ + output::{ + page::{CATALOG, paper_size_to_enum_map}, + pivot::Axis2, + }, + util::ToSmallString, + }; + + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let size = String::deserialize(deserializer)?; + let paper_size = PaperSize::from_str(&size).or_else(|_| { + CATALOG + .get_by_name(&size) + .map(|spec| spec.size) + .ok_or_else(|| D::Error::custom("unknown or invalid paper size {size}")) + })?; + Ok(paper_size_to_enum_map(paper_size)) + } + + pub fn serialize(paper_size: &EnumMap, serializer: S) -> Result + where + S: Serializer, + { + PaperSize::new(paper_size[Axis2::X], paper_size[Axis2::Y], Inch) + .to_string() + .serialize(serializer) + } +} + +fn paper_size_to_enum_map(paper_size: PaperSize) -> EnumMap { + let (w, h) = paper_size + .as_unit(paper_sizes::Unit::Inch) + .into_width_height(); + enum_map! { + Axis2::X => w, + Axis2::Y => h + } +} + impl Default for PageSetup { fn default() -> Self { Self { initial_page_number: 1, - paper: enum_map! { Axis2::X => 8.5, Axis2::Y => 11.0 }, + paper: paper_size_to_enum_map(CATALOG.default_paper().size), margins: enum_map! { Axis2::X => [0.5, 0.5], Axis2::Y => [0.5, 0.5] }, orientation: Default::default(), object_spacing: 12.0 / 72.0, @@ -109,4 +162,3 @@ impl PageSetup { EnumMap::from_fn(|axis| self.paper[axis] - self.margins[axis][0] - self.margins[axis][1]) } } - -- 2.30.2