[librsvg: 6/13] Minimal implementation of a public SvgHandle::set_stylesheet() API
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 6/13] Minimal implementation of a public SvgHandle::set_stylesheet() API
- Date: Sat, 1 Feb 2020 13:24:38 +0000 (UTC)
commit 7eeac4566845094de13bbae099e4846b013c4898
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Jan 23 18:36:10 2020 -0600
Minimal implementation of a public SvgHandle::set_stylesheet() API
librsvg_crate/src/lib.rs | 4 ++++
librsvg_crate/tests/api.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++
rsvg_internals/src/css.rs | 2 +-
rsvg_internals/src/handle.rs | 8 ++++++++
4 files changed, 61 insertions(+), 1 deletion(-)
---
diff --git a/librsvg_crate/src/lib.rs b/librsvg_crate/src/lib.rs
index d33cdef1..6583ca2c 100644
--- a/librsvg_crate/src/lib.rs
+++ b/librsvg_crate/src/lib.rs
@@ -365,6 +365,10 @@ impl SvgHandle {
pub fn has_element_with_id(&self, id: &str) -> Result<bool, RenderingError> {
self.0.has_sub(id)
}
+
+ pub fn set_stylesheet(&mut self, css: &str) -> Result<(), LoadingError> {
+ self.0.set_stylesheet(css)
+ }
}
/// Can render an `SvgHandle` to a Cairo context.
diff --git a/librsvg_crate/tests/api.rs b/librsvg_crate/tests/api.rs
index 1052ff9e..548a13a1 100644
--- a/librsvg_crate/tests/api.rs
+++ b/librsvg_crate/tests/api.rs
@@ -173,3 +173,51 @@ fn untransformed_element() {
compare_to_surface(&output_surf, &reference_surf, "untransformed_element");
}
+
+#[test]
+fn set_stylesheet() {
+ // This has a rectangle which we style from a user-supplied stylesheet.
+ let mut svg = load_svg(
+ br##"<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
+ <rect id="foo" x="10" y="20" width="30" height="40" fill="black"/>
+</svg>
+"##,
+ );
+
+ svg.set_stylesheet("rect { fill: #00ff00; }").expect("should be a valid stylesheet");
+
+ let renderer = CairoRenderer::new(&svg);
+
+ let output = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap();
+
+ let res = {
+ let cr = cairo::Context::new(&output);
+ let viewport = cairo::Rectangle {
+ x: 0.0,
+ y: 0.0,
+ width: 100.0,
+ height: 100.0,
+ };
+
+ renderer.render_document(&cr, &viewport)
+ };
+
+ let output_surf = res
+ .and_then(|_| Ok(SharedImageSurface::wrap(output, SurfaceType::SRgb).unwrap()))
+ .unwrap();
+
+ let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 100, 100).unwrap();
+
+ {
+ let cr = cairo::Context::new(&reference_surf);
+
+ cr.rectangle(10.0, 20.0, 30.0, 40.0);
+ cr.set_source_rgba(0.0, 1.0, 0.0, 1.0);
+ cr.fill();
+ }
+
+ let reference_surf = SharedImageSurface::wrap(reference_surf, SurfaceType::SRgb).unwrap();
+
+ compare_to_surface(&output_surf, &reference_surf, "set_stylesheet");
+}
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 8b4e5cb6..7226f3a7 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -651,7 +651,7 @@ impl Stylesheet {
///
/// The `base_url` is required for `@import` rules, so that librsvg
/// can determine if the requested path is allowed.
- fn parse(&mut self, buf: &str, base_url: Option<&Url>) -> Result<(), LoadingError> {
+ pub fn parse(&mut self, buf: &str, base_url: Option<&Url>) -> Result<(), LoadingError> {
let mut input = ParserInput::new(buf);
let mut parser = Parser::new(&mut input);
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index 6d9e6ac1..f887f0db 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -9,6 +9,7 @@ use locale_config::{LanguageRange, Locale};
use crate::allowed_url::{AllowedUrl, Href};
use crate::bbox::BoundingBox;
+use crate::css::{Origin, Stylesheet};
use crate::document::Document;
use crate::dpi::Dpi;
use crate::drawing_ctx::DrawingCtx;
@@ -581,6 +582,13 @@ impl Handle {
pub fn get_intrinsic_dimensions(&self) -> IntrinsicDimensions {
self.document.get_intrinsic_dimensions()
}
+
+ pub fn set_stylesheet(&mut self, css: &str) -> Result<(), LoadingError> {
+ let mut stylesheet = Stylesheet::new(Origin::User);
+ stylesheet.parse(css, None)?;
+ self.document.cascade(&[stylesheet]);
+ Ok(())
+ }
}
fn check_cairo_context(cr: &cairo::Context) -> Result<(), RenderingError> {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]