[librsvg/librsvg-2.44] css.rs: Move most of the libcroco callbacks to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.44] css.rs: Move most of the libcroco callbacks to Rust
- Date: Thu, 27 Sep 2018 16:33:12 +0000 (UTC)
commit 8b5a56ef710303e1af2c4166511dc28260d333d2
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Sep 25 10:05:04 2018 -0500
css.rs: Move most of the libcroco callbacks to Rust
Makefile.am | 1 -
librsvg/rsvg-load.c | 5 +-
librsvg/rsvg-private.h | 6 ++
librsvg/rsvg-styles.c | 156 +------------------------------------------
librsvg/rsvg-styles.h | 40 -----------
rsvg_internals/src/croco.rs | 2 +-
rsvg_internals/src/css.rs | 136 ++++++++++++++++++++++++++++++++-----
rsvg_internals/src/handle.rs | 4 ++
rsvg_internals/src/lib.rs | 7 +-
9 files changed, 142 insertions(+), 215 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 285a90d5..2e5d2e88 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,7 +38,6 @@ librsvg_@RSVG_API_MAJOR_VERSION@_la_SOURCES = \
librsvg/rsvg-size-callback.c \
librsvg/rsvg-size-callback.h \
librsvg/rsvg-styles.c \
- librsvg/rsvg-styles.h \
librsvg/rsvg.h \
$(NULL)
diff --git a/librsvg/rsvg-load.c b/librsvg/rsvg-load.c
index 9287ad0e..44e1f670 100644
--- a/librsvg/rsvg-load.c
+++ b/librsvg/rsvg-load.c
@@ -28,7 +28,6 @@
#include "rsvg-attributes.h"
#include "rsvg-load.h"
-#include "rsvg-styles.h"
typedef enum {
LOAD_STATE_START,
@@ -184,7 +183,7 @@ style_handler_free (RsvgSaxHandler * self)
RsvgSaxHandlerStyle *z = (RsvgSaxHandlerStyle *) self;
if (z->is_text_css)
- rsvg_parse_cssbuffer (z->load->handle, z->style->str, z->style->len);
+ rsvg_css_parse_into_handle (z->load->handle, z->style->str, z->style->len);
g_string_free (z->style, TRUE);
g_free (z);
@@ -933,7 +932,7 @@ sax_processing_instruction_cb (void *user_data, const xmlChar * target, const xm
if (style_data &&
mime_type &&
strcmp (mime_type, "text/css") == 0) {
- rsvg_parse_cssbuffer (load->handle, style_data, style_data_len);
+ rsvg_css_parse_into_handle (load->handle, style_data, style_data_len);
}
g_free (mime_type);
diff --git a/librsvg/rsvg-private.h b/librsvg/rsvg-private.h
index 5c2c61e1..e5c94c4d 100644
--- a/librsvg/rsvg-private.h
+++ b/librsvg/rsvg-private.h
@@ -206,6 +206,12 @@ void rsvg_css_styles_define (RsvgCssStyles *styles,
const char *style_value,
gboolean important);
+/* Implemented in rsvg_internals/src/css.rs */
+G_GNUC_INTERNAL
+void rsvg_css_parse_into_handle (RsvgHandle *handle,
+ const char *buf,
+ gsize len);
+
/* Implemented in rsvg_internals/src/structure.rs */
G_GNUC_INTERNAL
gboolean rsvg_node_svg_get_size (RsvgNode *node, double dpi_x, double dpi_y, int *out_width, int
*out_height);
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c
index e296fb50..c009ce95 100644
--- a/librsvg/rsvg-styles.c
+++ b/librsvg/rsvg-styles.c
@@ -32,163 +32,10 @@
#include "rsvg-attributes.h"
#include "rsvg-private.h"
#include "rsvg-css.h"
-#include "rsvg-styles.h"
#include <libcroco/libcroco.h>
-
-typedef struct _CSSUserData {
- RsvgHandle *handle;
- CRSelector *selector;
-} CSSUserData;
-
-static void
-css_user_data_init (CSSUserData *user_data, RsvgHandle *handle)
-{
- user_data->handle = handle;
- user_data->selector = NULL;
-}
-
-static void
-ccss_start_selector (CRDocHandler * a_handler, CRSelector * a_selector_list)
-{
- CSSUserData *user_data;
-
- g_return_if_fail (a_handler);
-
- user_data = (CSSUserData *) a_handler->app_data;
- cr_selector_ref (a_selector_list);
- user_data->selector = a_selector_list;
-}
-
-static void
-ccss_end_selector (CRDocHandler * a_handler, CRSelector * a_selector_list)
-{
- CSSUserData *user_data;
-
- g_return_if_fail (a_handler);
-
- user_data = (CSSUserData *) a_handler->app_data;
-
- cr_selector_unref (user_data->selector);
- user_data->selector = NULL;
-}
-
-static void
-ccss_property (CRDocHandler * a_handler, CRString * a_name, CRTerm * a_expr, gboolean important)
-{
- CSSUserData *user_data;
- gchar *name = NULL;
- size_t len = 0;
-
- g_return_if_fail (a_handler);
-
- user_data = (CSSUserData *) a_handler->app_data;
-
- if (a_name && a_expr && user_data->selector) {
- CRSelector *cur;
- for (cur = user_data->selector; cur; cur = cur->next) {
- if (cur->simple_sel) {
- gchar *selector = (gchar *) cr_simple_sel_to_string (cur->simple_sel);
- if (selector) {
- gchar *prop_name, *prop_value;
- name = (gchar *) cr_string_peek_raw_str (a_name);
- len = cr_string_peek_raw_str_len (a_name);
- prop_name = g_strndup (name, len);
- prop_value = (gchar *)cr_term_to_string (a_expr);
- rsvg_css_styles_define (user_data->handle->priv->css_styles,
- selector,
- prop_name,
- prop_value,
- important);
- g_free (selector);
- g_free (prop_name);
- g_free (prop_value);
- }
- }
- }
- }
-}
-
-static void
-ccss_error (CRDocHandler * a_handler)
-{
- /* yup, like i care about CSS parsing errors ;-)
- ignore, chug along */
- g_message (_("CSS parsing error\n"));
-}
-
-static void
-ccss_unrecoverable_error (CRDocHandler * a_handler)
-{
- /* yup, like i care about CSS parsing errors ;-)
- ignore, chug along */
- g_message (_("CSS unrecoverable error\n"));
-}
-
-static void
- ccss_import_style (CRDocHandler * a_this,
- GList * a_media_list,
- CRString * a_uri, CRString * a_uri_default_ns, CRParsingLocation * a_location);
-
-static void
-init_sac_handler (CRDocHandler * a_handler)
-{
- a_handler->start_document = NULL;
- a_handler->end_document = NULL;
- a_handler->import_style = ccss_import_style;
- a_handler->namespace_declaration = NULL;
- a_handler->comment = NULL;
- a_handler->start_selector = ccss_start_selector;
- a_handler->end_selector = ccss_end_selector;
- a_handler->property = ccss_property;
- a_handler->start_font_face = NULL;
- a_handler->end_font_face = NULL;
- a_handler->start_media = NULL;
- a_handler->end_media = NULL;
- a_handler->start_page = NULL;
- a_handler->end_page = NULL;
- a_handler->ignorable_at_rule = NULL;
- a_handler->error = ccss_error;
- a_handler->unrecoverable_error = ccss_unrecoverable_error;
-}
-
-void
-rsvg_parse_cssbuffer (RsvgHandle *handle, const char *buff, size_t buflen)
-{
- CRParser *parser = NULL;
- CRDocHandler *css_handler = NULL;
- CSSUserData user_data;
-
- if (buff == NULL || buflen == 0)
- return;
-
- css_handler = cr_doc_handler_new ();
- init_sac_handler (css_handler);
-
- css_user_data_init (&user_data, handle);
- css_handler->app_data = &user_data;
-
- /* TODO: fix libcroco to take in const strings */
- parser = cr_parser_new_from_buf ((guchar *) buff, (gulong) buflen, CR_UTF_8, FALSE);
- if (parser == NULL) {
- cr_doc_handler_unref (css_handler);
- return;
- }
-
- cr_parser_set_sac_handler (parser, css_handler);
- cr_doc_handler_unref (css_handler);
-
- cr_parser_set_use_core_grammar (parser, FALSE);
- cr_parser_parse (parser);
-
- /* FIXME: we aren't reporting errors in the CSS; we have no way to know if
- * we should print the "buff" for diagnostics.
- */
-
- cr_parser_destroy (parser);
-}
-
+#if 0
static void
ccss_import_style (CRDocHandler * a_this,
GList * a_media_list,
@@ -219,6 +66,7 @@ ccss_import_style (CRDocHandler * a_this,
g_free (stylesheet_data);
g_free (mime_type);
}
+#endif
/* This is defined like this so that we can export the Rust function... just for
* the benefit of rsvg-convert.c
diff --git a/rsvg_internals/src/croco.rs b/rsvg_internals/src/croco.rs
index 4ee67e72..3d551398 100644
--- a/rsvg_internals/src/croco.rs
+++ b/rsvg_internals/src/croco.rs
@@ -13,7 +13,7 @@ pub type CRTerm = gpointer;
pub type CRStatus = u32;
pub type CREncoding = u32;
-pub const CREncoding_CR_UTF_8: CREncoding = 5;
+pub const CR_UTF_8: CREncoding = 5;
#[repr(C)]
pub struct CRParsingLocation {
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 689cfcbd..991c3788 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -1,14 +1,17 @@
use std::collections::hash_map::Entry;
use std::collections::HashMap;
-use std::str::FromStr;
+use std::ptr;
+use std::slice;
+use std::str::{self, FromStr};
use libc;
use glib::translate::*;
-use glib_sys::{self, gboolean, GList};
+use glib_sys::{self, gboolean, gpointer, GList};
use attributes::Attribute;
use croco::*;
+use handle::{self, RsvgHandle};
use state::State;
use util::utf8_cstr;
@@ -78,6 +81,42 @@ impl CssStyles {
}
}
+struct DocHandlerData {
+ handle: *mut RsvgHandle,
+ selector: *mut CRSelector,
+}
+
+fn parse_into_handle(handle: *mut RsvgHandle, buf: &str) {
+ unsafe {
+ let handler_data = DocHandlerData {
+ handle,
+ selector: ptr::null_mut(),
+ };
+
+ let doc_handler = cr_doc_handler_new();
+ init_cr_doc_handler(&mut *doc_handler);
+
+ (*doc_handler).app_data = &handler_data as *const _ as gpointer;
+
+ let buf_ptr = buf.as_ptr() as *mut _;
+ let buf_len = buf.len() as u64;
+
+ let parser = cr_parser_new_from_buf(buf_ptr, buf_len, CR_UTF_8, false.to_glib());
+ if parser.is_null() {
+ cr_doc_handler_unref(doc_handler);
+ return;
+ }
+
+ cr_parser_set_sac_handler(parser, doc_handler);
+ cr_doc_handler_unref(doc_handler);
+
+ cr_parser_set_use_core_grammar(parser, false.to_glib());
+ cr_parser_parse(parser);
+
+ cr_parser_destroy(parser);
+ }
+}
+
fn init_cr_doc_handler(handler: &mut CRDocHandler) {
handler.import_style = Some(css_import_style);
handler.start_selector = Some(css_start_selector);
@@ -88,24 +127,37 @@ fn init_cr_doc_handler(handler: &mut CRDocHandler) {
}
unsafe extern "C" fn css_import_style(
- a_this: *mut CRDocHandler,
- a_media_list: *mut GList,
- a_uri: CRString,
- a_uri_default_ns: CRString,
- a_location: CRParsingLocation,
+ _a_this: *mut CRDocHandler,
+ _a_media_list: *mut GList,
+ _a_uri: CRString,
+ _a_uri_default_ns: CRString,
+ _a_location: CRParsingLocation,
) {
unimplemented!();
}
+unsafe fn get_doc_handler_data<'a>(doc_handler: *mut CRDocHandler) -> &'a mut DocHandlerData {
+ &mut *((*doc_handler).app_data as *mut DocHandlerData)
+}
+
unsafe extern "C" fn css_start_selector(
a_this: *mut CRDocHandler,
a_selector_list: *mut CRSelector,
) {
- unimplemented!();
+ let handler_data = get_doc_handler_data(a_this);
+
+ cr_selector_ref(a_selector_list);
+ handler_data.selector = a_selector_list;
}
-unsafe extern "C" fn css_end_selector(a_this: *mut CRDocHandler, a_selector_list: *mut CRSelector) {
- unimplemented!();
+unsafe extern "C" fn css_end_selector(
+ a_this: *mut CRDocHandler,
+ _a_selector_list: *mut CRSelector,
+) {
+ let handler_data = get_doc_handler_data(a_this);
+
+ cr_selector_unref(handler_data.selector);
+ handler_data.selector = ptr::null_mut();
}
unsafe extern "C" fn css_property(
@@ -114,15 +166,51 @@ unsafe extern "C" fn css_property(
a_expression: CRTerm,
a_is_important: gboolean,
) {
- unimplemented!();
+ let handler_data = get_doc_handler_data(a_this);
+
+ if a_name.is_null() || a_expression.is_null() || handler_data.selector.is_null() {
+ return;
+ }
+
+ let mut cur_sel = handler_data.selector;
+ while !cur_sel.is_null() {
+ let simple_sel = (*cur_sel).simple_sel;
+
+ if !simple_sel.is_null() {
+ let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;
+
+ if !raw_selector_name.is_null() {
+ let prop_name_ptr = cr_string_peek_raw_str(a_name);
+ let prop_name_len = cr_string_peek_raw_str_len(a_name) as usize;
+
+ let prop_name_bytes =
+ slice::from_raw_parts(prop_name_ptr as *const u8, prop_name_len);
+ let prop_name = str::from_utf8_unchecked(prop_name_bytes);
+
+ let prop_value =
+ <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression));
+
+ let selector_name =
+ <String as FromGlibPtrFull<_>>::from_glib_full(raw_selector_name);
+
+ let important = from_glib(a_is_important);
+
+ let styles = handle::get_css_styles_mut(handler_data.handle);
+
+ styles.define(&selector_name, prop_name, &prop_value, important);
+ }
+ }
+
+ cur_sel = (*cur_sel).next;
+ }
}
-unsafe extern "C" fn css_error(a_this: *mut CRDocHandler) {
- unimplemented!();
+unsafe extern "C" fn css_error(_a_this: *mut CRDocHandler) {
+ println!("CSS parsing error");
}
-unsafe extern "C" fn css_unrecoverable_error(a_this: *mut CRDocHandler) {
- unimplemented!();
+unsafe extern "C" fn css_unrecoverable_error(_a_this: *mut CRDocHandler) {
+ println!("CSS unrecoverable error");
}
#[no_mangle]
@@ -157,3 +245,21 @@ pub extern "C" fn rsvg_css_styles_define(
styles.define(selector, prop_name, prop_value, from_glib(important));
}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_css_parse_into_handle(
+ handle: *mut RsvgHandle,
+ buf: *const libc::c_char,
+ len: usize,
+) {
+ assert!(!handle.is_null());
+
+ if buf.is_null() || len == 0 {
+ return;
+ }
+
+ let bytes = slice::from_raw_parts(buf as *const u8, len);
+ let utf8 = str::from_utf8_unchecked(bytes);
+
+ parse_into_handle(handle, utf8);
+}
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index c17b6bad..f77a4d9f 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -48,3 +48,7 @@ pub fn load_extern(handle: *const RsvgHandle, uri: &str) -> *const RsvgHandle {
pub fn get_css_styles<'a>(handle: *const RsvgHandle) -> &'a CssStyles {
unsafe { &*(rsvg_handle_get_css_styles(handle) as *const CssStyles) }
}
+
+pub fn get_css_styles_mut<'a>(handle: *const RsvgHandle) -> &'a mut CssStyles {
+ unsafe { &mut *(rsvg_handle_get_css_styles(handle) as *mut CssStyles) }
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index cc5691e5..c0147338 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -27,7 +27,12 @@ extern crate downcast_rs;
pub use color::{rsvg_css_parse_color, ColorKind, ColorSpec};
-pub use css::{rsvg_css_styles_define, rsvg_css_styles_free, rsvg_css_styles_new};
+pub use css::{
+ rsvg_css_parse_into_handle,
+ rsvg_css_styles_define,
+ rsvg_css_styles_free,
+ rsvg_css_styles_new,
+};
pub use defs::{rsvg_defs_free, rsvg_defs_lookup, rsvg_defs_new};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]