[librsvg/rustify-rsvg-convert: 23/78] rsvg-convert: Add support for (E)PS and SVG output formats
- From: Sven Neumann <sneumann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/rustify-rsvg-convert: 23/78] rsvg-convert: Add support for (E)PS and SVG output formats
- Date: Wed, 3 Feb 2021 10:18:30 +0000 (UTC)
commit da172eef5ec40939e50e74714c1e44f0d39d3722
Author: Sven Neumann <sven svenfoo org>
Date: Mon Nov 2 15:26:54 2020 +0100
rsvg-convert: Add support for (E)PS and SVG output formats
We will want to revisit the package dependencies, only the rsvg-convert
binary needs the PS feature from cairo-rs.
Cargo.toml | 2 +-
src/bin/rsvg-convert/surface.rs | 90 +++++++++++++++++++++++++++++++----------
2 files changed, 69 insertions(+), 23 deletions(-)
---
diff --git a/Cargo.toml b/Cargo.toml
index 9f511b0d..45c965aa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@ crate-type = [ "staticlib", "rlib" ]
bitflags = "1.0"
# Keep these in sync with respect to the cairo-rs version:
# src/lib.rs - toplevel example in the docs
-cairo-rs = { version="0.8.0", features=["v1_16", "png", "pdf", "svg"] }
+cairo-rs = { version="0.8.0", features=["v1_16", "png", "pdf", "ps", "svg"] }
cairo-sys-rs = "0.9.0"
cast = "0.2.3"
clap = "~2.33.0"
diff --git a/src/bin/rsvg-convert/surface.rs b/src/bin/rsvg-convert/surface.rs
index 262bb15c..e834c349 100644
--- a/src/bin/rsvg-convert/surface.rs
+++ b/src/bin/rsvg-convert/surface.rs
@@ -3,12 +3,14 @@ use std::io;
use librsvg::{CairoRenderer, RenderingError};
-use crate::cli;
+use crate::cli::Format;
use crate::output::Stream;
pub enum Surface {
Png(cairo::ImageSurface, Stream),
Pdf(cairo::PdfSurface, (f64, f64)),
+ Ps(cairo::PsSurface, (f64, f64)),
+ Svg(cairo::SvgSurface, (f64, f64)),
}
impl Deref for Surface {
@@ -16,61 +18,105 @@ impl Deref for Surface {
fn deref(&self) -> &cairo::Surface {
match self {
- Self::Png(surface, _) => surface.deref(),
- Self::Pdf(surface, _) => surface.deref(),
+ Self::Png(surface, _) => &surface,
+ Self::Pdf(surface, _) => &surface,
+ Self::Ps(surface, _) => &surface,
+ Self::Svg(surface, _) => &surface,
}
}
}
impl Surface {
pub fn new(
- format: cli::Format,
+ format: Format,
width: f64,
height: f64,
stream: Stream,
) -> Result<Self, cairo::Status> {
match format {
- cli::Format::Png => {
- cairo::ImageSurface::create(cairo::Format::ARgb32, width as i32, height as i32)
- .map(|s| Self::Png(s, stream))
- }
- cli::Format::Pdf => cairo::PdfSurface::for_stream(width, height, stream)
- .map(|s| Self::Pdf(s, (width, height))),
- _ => Err(cairo::Status::InvalidFormat),
+ Format::Png => Self::new_for_png(width, height, stream),
+ Format::Pdf => Self::new_for_pdf(width, height, stream),
+ Format::Ps => Self::new_for_ps(width, height, stream, false),
+ Format::Eps => Self::new_for_ps(width, height, stream, true),
+ Format::Svg => Self::new_for_svg(width, height, stream),
}
}
+ fn new_for_png(width: f64, height: f64, stream: Stream) -> Result<Self, cairo::Status> {
+ let surface =
+ cairo::ImageSurface::create(cairo::Format::ARgb32, width as i32, height as i32)?;
+ Ok(Self::Png(surface, stream))
+ }
+
+ fn new_for_pdf(width: f64, height: f64, stream: Stream) -> Result<Self, cairo::Status> {
+ let surface = cairo::PdfSurface::for_stream(width, height, stream)?;
+ Ok(Self::Pdf(surface, (width, height)))
+ }
+
+ fn new_for_ps(
+ width: f64,
+ height: f64,
+ stream: Stream,
+ eps: bool,
+ ) -> Result<Self, cairo::Status> {
+ let surface = cairo::PsSurface::for_stream(width, height, stream)?;
+ surface.set_eps(eps);
+ Ok(Self::Ps(surface, (width, height)))
+ }
+
+ fn new_for_svg(width: f64, height: f64, stream: Stream) -> Result<Self, cairo::Status> {
+ let surface = cairo::SvgSurface::for_stream(width, height, stream)?;
+ Ok(Self::Svg(surface, (width, height)))
+ }
+
fn size(&self) -> (f64, f64) {
match self {
Self::Png(s, _) => (s.get_width() as f64, s.get_height() as f64),
Self::Pdf(_, size) => *size,
+ Self::Ps(_, size) => *size,
+ Self::Svg(_, size) => *size,
}
}
- pub fn render(&self, renderer: &CairoRenderer, id: Option<&str>) -> Result<(), RenderingError> {
- let cr = cairo::Context::new(self);
-
+ fn bounds(&self) -> cairo::Rectangle {
let (width, height) = self.size();
- let viewport = cairo::Rectangle {
+ cairo::Rectangle {
x: 0.0,
y: 0.0,
width,
height,
- };
+ }
+ }
- renderer.render_layer(&cr, id, &viewport)?;
- cr.show_page();
+ pub fn render(&self, renderer: &CairoRenderer, id: Option<&str>) -> Result<(), RenderingError> {
+ let cr = cairo::Context::new(self);
+ let viewport = self.bounds();
+ let show_page = |_| self.show_page(&cr);
+ renderer
+ .render_layer(&cr, id, &viewport)
+ .and_then(show_page)
+ }
+
+ pub fn show_page(&self, cr: &cairo::Context) -> Result<(), RenderingError> {
+ match self {
+ Self::Png(_, _) => (),
+ _ => cr.show_page(),
+ }
Ok(())
}
+ fn finish_output_stream(surface: &cairo::Surface) -> Result<(), cairo::IoError> {
+ match surface.finish_output_stream() {
+ Ok(_) => Ok(()),
+ Err(e) => Err(cairo::IoError::Io(io::Error::from(e))),
+ }
+ }
+
pub fn finish(&mut self) -> Result<(), cairo::IoError> {
match self {
Self::Png(surface, stream) => surface.write_to_png(stream),
- Self::Pdf(surface, _) => surface
- .finish_output_stream()
- .map(|_| ())
- .map_err(|e| cairo::IoError::Io(io::Error::from(e))),
+ _ => Self::finish_output_stream(self),
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]