[librsvg: 2/10] Pass unit to set_document_unit
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 2/10] Pass unit to set_document_unit
- Date: Tue, 7 Dec 2021 19:37:30 +0000 (UTC)
commit c5a197cef7ac56239b616fdb0d53a72410fcff78
Author: Daniel Petri Rocha <daniel petri tum de>
Date: Sat Nov 6 20:03:55 2021 +0100
Pass unit to set_document_unit
src/bin/rsvg-convert.rs | 70 +++++++++++++++++++++++++++++++++----------------
src/length.rs | 22 +++++++++++++---
2 files changed, 66 insertions(+), 26 deletions(-)
---
diff --git a/src/bin/rsvg-convert.rs b/src/bin/rsvg-convert.rs
index 0e67e7b3..46bae5a2 100644
--- a/src/bin/rsvg-convert.rs
+++ b/src/bin/rsvg-convert.rs
@@ -16,7 +16,6 @@ mod windows_imports {
pub use std::io;
pub use std::os::windows::io::AsRawHandle;
}
-
#[cfg(windows)]
use self::windows_imports::*;
@@ -195,13 +194,13 @@ impl Deref for Surface {
}
impl Surface {
- pub fn new(format: Format, size: Size, stream: OutputStream) -> Result<Self, Error> {
+ pub fn new(format: Format, size: Size, stream: OutputStream, unit: LengthUnit) -> Result<Self, Error> {
match format {
Format::Png => Self::new_for_png(size, stream),
Format::Pdf => Self::new_for_pdf(size, stream),
Format::Ps => Self::new_for_ps(size, stream, false),
Format::Eps => Self::new_for_ps(size, stream, true),
- Format::Svg => Self::new_for_svg(size, stream),
+ Format::Svg => Self::new_for_svg(size, stream, unit),
}
}
@@ -240,14 +239,25 @@ impl Surface {
}
#[cfg(system_deps_have_cairo_svg)]
- fn new_for_svg(size: Size, stream: OutputStream) -> Result<Self, Error> {
+ fn new_for_svg(size: Size, stream: OutputStream, unit: LengthUnit) -> Result<Self, Error> {
let mut surface = cairo::SvgSurface::for_stream(size.w, size.h, stream.into_write())?;
- surface.set_document_unit(cairo::SvgUnit::User);
+
+ let svg_unit = match unit {
+ LengthUnit::Cm => cairo::SvgUnit::Cm,
+ LengthUnit::In => cairo::SvgUnit::In,
+ LengthUnit::Mm => cairo::SvgUnit::Mm,
+ LengthUnit::Pc => cairo::SvgUnit::Pc,
+ LengthUnit::Pt => cairo::SvgUnit::Pt,
+ _ => cairo::SvgUnit::User,
+ };
+
+ println!("Setting document unit to #{:?}", svg_unit);
+ surface.set_document_unit(svg_unit);
Ok(Self::Svg(surface, size))
}
#[cfg(not(system_deps_have_cairo_svg))]
- fn new_for_svg(_size: Size, _stream: OutputStream) -> Result<Self, Error> {
+ fn new_for_svg(_size: Size, _stream: OutputStream, u: LengthUnit) -> Result<Self, Error> {
Err(Error("unsupported format".to_string()))
}
@@ -450,6 +460,7 @@ impl Converter {
};
let mut surface: Option<Surface> = None;
+ let mut unit = LengthUnit::Px;
for (page_idx, input) in self.input.iter().enumerate() {
let (stream, basefile) = match input {
@@ -485,6 +496,7 @@ impl Converter {
let natural_size = Size::new(geometry.width, geometry.height);
let params = NormalizeParams::from_dpi(Dpi::new(self.dpi.0, self.dpi.1));
+
// Convert natural size and requested size to pixels or points, depending on the target format,
let (natural_size, requested_width, requested_height, page_size) = match self.format {
Format::Png => {
@@ -522,6 +534,8 @@ impl Converter {
// TODO: SVG surface can be created with any unit type; let's use pixels for now
// Determine original unit type
+ // --left and --top units ignored for now
+
let w_unit = self.width.map(|l| l.unit);
let h_unit = self.height.map(|l| l.unit);
let page_size_w_unit = self.page_size.map(|(w, _)| w.unit);
@@ -533,16 +547,12 @@ impl Converter {
println!("Page height unit is {:?}", page_size_h_unit);
let mut specified_units = vec![w_unit, h_unit, page_size_w_unit, page_size_h_unit];
-
- println!("Specified units before {:?}", specified_units);
specified_units.retain(|u| u.is_some());
- println!("Specified units after {:?}", specified_units);
- println!("Length of specified units {:?}", specified_units.len());
println!("Units are {:?}", &specified_units);
println!("All equal: {:?}", all_equal_units(&specified_units));
- let svg_unit = if !specified_units.is_empty() && all_equal_units(&specified_units) {
+ unit = if !specified_units.is_empty() && all_equal_units(&specified_units) {
match specified_units.pop().unwrap() {
Some(u) => u,
_ => LengthUnit::Px,
@@ -552,15 +562,28 @@ impl Converter {
LengthUnit::Px
};
- println!("SVG unit is {:?}", svg_unit);
- (
- natural_size,
- self.width.map(|l| l.to_user(¶ms)),
- self.height.map(|l| l.to_user(¶ms)),
- self.page_size.map(|(w, h)| Size {
- w: w.to_user(¶ms),
- h: h.to_user(¶ms),
- }),
+ println!("SVG unit is {:?}", unit);
+
+ // Supported SVG units are px, in, cm, mm, pt, pc
+
+ fn set_unit<T: librsvg::rsvg_convert_only::Normalize>(l: ULength<T>, p:
&NormalizeParams, u: LengthUnit) -> f64 {
+ match u {
+ LengthUnit::Pt => l.to_points(p),
+ LengthUnit::In => l.to_inches(p),
+ LengthUnit::Cm => l.to_cm(p),
+ LengthUnit::Mm => l.to_mm(p),
+ LengthUnit::Pc => l.to_picas(p),
+ _ => l.to_user(p),
+ }
+ }
+
+ (Size {
+ w: set_unit(ULength::<Horizontal>::new(natural_size.w, LengthUnit::Px), ¶ms,
unit),
+ h: set_unit(ULength::<Vertical>::new(natural_size.h, LengthUnit::Px), ¶ms,
unit),
+ },
+ self.width.map(|l| set_unit(l, ¶ms, unit)),
+ self.height.map(|l| set_unit(l, ¶ms, unit)),
+ self.page_size.map(|(w, h)| Size { w: set_unit(w, ¶ms, unit), h: set_unit(h,
¶ms, unit), }),
)
}
};
@@ -610,7 +633,8 @@ impl Converter {
}
s
}
- surface @ None => surface.insert(self.create_surface(page_size)?),
+ surface @ None => surface.insert(self.create_surface(page_size, unit)?),
+
};
let left = self.left.map(|l| l.to_user(¶ms)).unwrap_or(0.0);
@@ -650,7 +674,7 @@ impl Converter {
.ok_or_else(|| error!("The SVG {} has no dimensions", input))
}
- fn create_surface(&self, size: Size) -> Result<Surface, Error> {
+ fn create_surface(&self, size: Size, unit: LengthUnit) -> Result<Surface, Error> {
let output_stream = match self.output {
Output::Stdout => Stdout::stream(),
Output::Path(ref p) => {
@@ -662,7 +686,7 @@ impl Converter {
}
};
- Surface::new(self.format, size, output_stream)
+ Surface::new(self.format, size, output_stream, unit)
}
}
diff --git a/src/length.rs b/src/length.rs
index e10c32e9..b6a6d658 100644
--- a/src/length.rs
+++ b/src/length.rs
@@ -410,15 +410,15 @@ impl<N: Normalize, V: Validate> CssLength<N, V> {
}
LengthUnit::Percent => {
- panic!("Cannot convert a percentage length into points");
+ panic!("Cannot convert a percentage length into an absolute length");
}
LengthUnit::Em => {
- panic!("Cannot convert an Em length into points");
+ panic!("Cannot convert an Em length into an absolute length");
}
LengthUnit::Ex => {
- panic!("Cannot convert an Ex length into points");
+ panic!("Cannot convert an Ex length into an absolute length");
}
LengthUnit::In => self.length * POINTS_PER_INCH,
@@ -432,6 +432,22 @@ impl<N: Normalize, V: Validate> CssLength<N, V> {
LengthUnit::Pc => self.length / PICA_PER_INCH * POINTS_PER_INCH,
}
}
+
+ pub fn to_inches(&self, params: &NormalizeParams) -> f64 {
+ self.to_points(params) / POINTS_PER_INCH
+ }
+
+ pub fn to_cm(&self, params: &NormalizeParams) -> f64 {
+ self.to_inches(params) * CM_PER_INCH
+ }
+
+ pub fn to_mm(&self, params: &NormalizeParams) -> f64 {
+ self.to_inches(params) * MM_PER_INCH
+ }
+
+ pub fn to_picas(&self, params: &NormalizeParams) -> f64 {
+ self.to_inches(params) * PICA_PER_INCH
+ }
}
fn font_size_from_values(values: &ComputedValues, dpi: Dpi) -> f64 {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]