diff options
author | Federico Mena Quintero <federico@gnome.org> | 2018-09-26 18:12:26 -0500 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2018-09-26 18:43:31 -0500 |
commit | 3af8281e6fdcf7f8b1c387074a710e9b67612aaa (patch) | |
tree | a477ae5f9c8772d99724e6e3ecfbde87ad1394c3 | |
parent | 114a7d9b67669338b5911ca85a732f6e4ec8616c (diff) | |
download | librsvg-3af8281e6fdcf7f8b1c387074a710e9b67612aaa.tar.gz |
Move CSS importing to Rust
This moves all the libcroco-related calls to Rust. Yay!
-rw-r--r-- | librsvg/rsvg-styles.c | 33 | ||||
-rw-r--r-- | rsvg_internals/src/croco.rs | 1 | ||||
-rw-r--r-- | rsvg_internals/src/css.rs | 30 | ||||
-rw-r--r-- | rsvg_internals/src/handle.rs | 42 |
4 files changed, 63 insertions, 43 deletions
diff --git a/librsvg/rsvg-styles.c b/librsvg/rsvg-styles.c index c009ce95..7b8bce1d 100644 --- a/librsvg/rsvg-styles.c +++ b/librsvg/rsvg-styles.c @@ -35,39 +35,6 @@ #include <libcroco/libcroco.h> -#if 0 -static void -ccss_import_style (CRDocHandler * a_this, - GList * a_media_list, - CRString * a_uri, CRString * a_uri_default_ns, CRParsingLocation * a_location) -{ - CSSUserData *user_data = (CSSUserData *) a_this->app_data; - char *stylesheet_data; - gsize stylesheet_data_len; - char *mime_type = NULL; - - if (a_uri == NULL) - return; - - stylesheet_data = _rsvg_handle_acquire_data (user_data->handle, - cr_string_peek_raw_str (a_uri), - &mime_type, - &stylesheet_data_len, - NULL); - if (stylesheet_data == NULL || - mime_type == NULL || - strcmp (mime_type, "text/css") != 0) { - g_free (stylesheet_data); - g_free (mime_type); - return; - } - - rsvg_parse_cssbuffer (user_data->handle, stylesheet_data, stylesheet_data_len); - 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 3d551398..892aca9b 100644 --- a/rsvg_internals/src/croco.rs +++ b/rsvg_internals/src/croco.rs @@ -94,7 +94,6 @@ extern "C" { pub fn cr_simple_sel_to_string(a_this: CRSimpleSel) -> *mut libc::c_char; pub fn cr_string_peek_raw_str(a_this: CRString) -> *const libc::c_char; - pub fn cr_string_peek_raw_str_len(a_this: CRString) -> libc::c_int; pub fn cr_term_to_string(a_this: CRTerm) -> *mut libc::c_char; diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs index 991c3788..d4ef1df1 100644 --- a/rsvg_internals/src/css.rs +++ b/rsvg_internals/src/css.rs @@ -127,13 +127,29 @@ fn init_cr_doc_handler(handler: &mut CRDocHandler) { } unsafe extern "C" fn css_import_style( - _a_this: *mut CRDocHandler, + a_this: *mut CRDocHandler, _a_media_list: *mut GList, - _a_uri: CRString, + a_uri: CRString, _a_uri_default_ns: CRString, _a_location: CRParsingLocation, ) { - unimplemented!(); + let handler_data = get_doc_handler_data(a_this); + + if a_uri.is_null() { + return; + } + + let raw_uri = cr_string_peek_raw_str(a_uri); + let uri = utf8_cstr(raw_uri); + + if let Ok(binary_data) = handle::acquire_data(handler_data.handle, uri) { + if binary_data.content_type.as_ref().map(String::as_ref) == Some("text/css") { + parse_into_handle( + handler_data.handle, + str::from_utf8_unchecked(&binary_data.data), + ); + } + } } unsafe fn get_doc_handler_data<'a>(doc_handler: *mut CRDocHandler) -> &'a mut DocHandlerData { @@ -180,12 +196,8 @@ unsafe extern "C" fn css_property( 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 raw_prop_name = cr_string_peek_raw_str(a_name); + let prop_name = utf8_cstr(raw_prop_name); let prop_value = <String as FromGlibPtrFull<_>>::from_glib_full(cr_term_to_string(a_expression)); diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs index f77a4d9f..f75492e5 100644 --- a/rsvg_internals/src/handle.rs +++ b/rsvg_internals/src/handle.rs @@ -1,4 +1,8 @@ +use std::ptr; + +use glib; use glib::translate::*; +use glib_sys; use libc; use css::{CssStyles, RsvgCssStyles}; @@ -21,6 +25,14 @@ extern "C" { ) -> *const RsvgHandle; fn rsvg_handle_get_css_styles(handle: *const RsvgHandle) -> *mut RsvgCssStyles; + + fn _rsvg_handle_acquire_data( + handle: *mut RsvgHandle, + url: *const libc::c_char, + out_content_type: *mut *mut libc::c_char, + out_len: *mut usize, + error: *mut *mut glib_sys::GError, + ) -> *mut u8; } pub fn get_defs<'a>(handle: *const RsvgHandle) -> &'a Defs { @@ -52,3 +64,33 @@ pub fn get_css_styles<'a>(handle: *const RsvgHandle) -> &'a 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) } } + +pub struct BinaryData { + pub data: Vec<u8>, + pub content_type: Option<String>, +} + +pub fn acquire_data(handle: *mut RsvgHandle, url: &str) -> Result<BinaryData, glib::Error> { + unsafe { + let mut content_type: *mut libc::c_char = ptr::null_mut(); + let mut len = 0; + let mut error = ptr::null_mut(); + + let buf = _rsvg_handle_acquire_data( + handle, + url.to_glib_none().0, + &mut content_type as *mut *mut _, + &mut len, + &mut error, + ); + + if buf.is_null() { + Err(from_glib_full(error)) + } else { + Ok(BinaryData { + data: FromGlibContainer::from_glib_full_num(buf as *mut u8, len), + content_type: from_glib_full(content_type), + }) + } + } +} |