[librsvg: 8/13] New C API, rsvg_handle_set_stylesheet()



commit 931144874e559a4d976318ef630e91664ce410e9
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Jan 24 20:07:51 2020 -0600

    New C API, rsvg_handle_set_stylesheet()

 librsvg/c_api.rs      | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 librsvg/rsvg-handle.c | 39 +++++++++++++++++++++++++++++++++++++++
 librsvg/rsvg.h        |  6 ++++++
 3 files changed, 92 insertions(+)
---
diff --git a/librsvg/c_api.rs b/librsvg/c_api.rs
index 6a6e78ef..8f0f5ba7 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -4,6 +4,7 @@ use std::ops;
 use std::path::PathBuf;
 use std::ptr;
 use std::slice;
+use std::str;
 use std::sync::Once;
 use std::{f64, i32};
 
@@ -690,6 +691,20 @@ impl CHandle {
             .map_err(warn_on_invalid_id)
     }
 
+    fn set_stylesheet(&self, css: &str) -> Result<(), LoadingError> {
+        match *self.load_state.borrow_mut() {
+            LoadState::ClosedOk { ref mut handle } => handle.set_stylesheet(css),
+
+            _ => {
+                rsvg_g_critical(
+                    "handle must already be loaded in order to call \
+                     rsvg_handle_set_stylesheet()",
+                );
+                Err(LoadingError::Unknown)
+            },
+        }
+    }
+
     fn render_cairo_sub(
         &self,
         cr: &cairo::Context,
@@ -1296,6 +1311,38 @@ unsafe fn set_out_param<T: Copy>(
     }
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_rust_handle_set_stylesheet(
+    handle: *const RsvgHandle,
+    css: *const libc::c_char,
+    css_len: usize,
+    error: *mut *mut glib_sys::GError,
+) -> glib_sys::gboolean {
+    let rhandle = get_rust_handle(handle);
+
+    let css = match (css, css_len) {
+        (p, 0) if p.is_null() => "",
+        (_, _) => {
+            let s = slice::from_raw_parts(css as *const u8, css_len);
+            match str::from_utf8(s) {
+                Ok(s) => s,
+                Err(e) => {
+                    set_gerror(error, 0, &format!("CSS is not valid UTF-8: {}", e));
+                    return false.to_glib();
+                }
+            }
+        }
+    };
+
+    match rhandle.set_stylesheet(css) {
+        Ok(()) => true.to_glib(),
+        Err(e) => {
+            set_gerror(error, 0, &format!("{}", e));
+            false.to_glib()
+        }
+    }
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn rsvg_rust_handle_get_intrinsic_dimensions(
     handle: *mut RsvgHandle,
diff --git a/librsvg/rsvg-handle.c b/librsvg/rsvg-handle.c
index 0b06203e..d1ed8dad 100644
--- a/librsvg/rsvg-handle.c
+++ b/librsvg/rsvg-handle.c
@@ -372,6 +372,11 @@ extern RsvgHandle *rsvg_rust_handle_new_from_stream_sync (GInputStream *input_st
 extern RsvgHandle *rsvg_rust_handle_new_from_data (const guint8 *data,
                                                    gsize data_len,
                                                    GError **error);
+extern gboolean rsvg_rust_handle_set_stylesheet (RsvgHandle  *handle,
+                                                 const char  *css,
+                                                 gsize        css_len,
+                                                 GError     **error);
+
 extern void rsvg_rust_handle_get_intrinsic_dimensions (RsvgHandle *handle,
                                                        gboolean   *out_has_width,
                                                        RsvgLength *out_width,
@@ -768,6 +773,40 @@ rsvg_handle_get_base_uri (RsvgHandle *handle)
     return rsvg_rust_handle_get_base_url (handle);
 }
 
+/**
+ * rsvg_handle_set_stylesheet:
+ * @handle: A #RsvgHandle.
+ * @css: (array length=css_len): String with CSS data; must be valid UTF-8.
+ * @css_len: Length of the @css string in bytes.
+ * @error: (optional): return location for errors.
+ *
+ * Sets a CSS stylesheet to use for an SVG document.
+ *
+ * The @css_len argument is mandatory; this function will not compute the length
+ * of the @css string.  This is because a provided stylesheet, which the calling
+ * program could read from a file, can have nul characters in it.
+ *
+ * During the CSS cascade, the specified stylesheet will be used with a "User"
+ * <ulink
+ * url="https://drafts.csswg.org/css-cascade-3/#cascading-origins";>origin</ulink>.
+ *
+ * Note that `@import` rules will not be resolved, except for `data:` URLs.
+ *
+ * Since: 2.48
+ */
+gboolean
+rsvg_handle_set_stylesheet (RsvgHandle  *handle,
+                            const char  *css,
+                            gsize        css_len,
+                            GError     **error)
+{
+    g_return_val_if_fail (RSVG_IS_HANDLE (handle), FALSE);
+    g_return_val_if_fail ((css != NULL && css_len >= 0) || (css == NULL && css_len == 0), FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+    return rsvg_rust_handle_set_stylesheet (handle, css, css_len, error);
+}
+
 /**
  * rsvg_handle_get_metadata:
  * @handle: An #RsvgHandle
diff --git a/librsvg/rsvg.h b/librsvg/rsvg.h
index c0280bf5..63b9354d 100644
--- a/librsvg/rsvg.h
+++ b/librsvg/rsvg.h
@@ -343,6 +343,12 @@ RsvgHandle *rsvg_handle_new_from_data (const guint8 *data, gsize data_len, GErro
 RSVG_API
 RsvgHandle *rsvg_handle_new_from_file (const gchar *filename, GError **error);
 
+RSVG_API
+gboolean rsvg_handle_set_stylesheet (RsvgHandle  *handle,
+                                     const char  *css,
+                                     gsize        css_len,
+                                     GError     **error);
+
 #ifndef __GTK_DOC_IGNORE__
 RSVG_API
 void rsvg_handle_internal_set_testing (RsvgHandle *handle, gboolean testing);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]