[librsvg: 25/38] Bind RsvgHandleFlags with bitflags, to Rust
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 25/38] Bind RsvgHandleFlags with bitflags, to Rust
- Date: Fri, 25 Jan 2019 19:39:28 +0000 (UTC)
commit 689cceaea992880d4fc437e53256f94b87b653f8
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Jan 23 13:41:15 2019 -0600
Bind RsvgHandleFlags with bitflags, to Rust
I think we need this so we can have a glib::Value of type
HandleFlags::static_type(), so get_property()/get_property() will get
the correct types.
Cargo.lock | 1 +
rsvg_internals/Cargo.toml | 1 +
rsvg_internals/src/c_api.rs | 72 +++++++++++++++++++++++++++++++++++++++++---
rsvg_internals/src/handle.rs | 38 ++++++++++++-----------
rsvg_internals/src/lib.rs | 3 ++
5 files changed, 94 insertions(+), 21 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index 4db321fe..eab89b29 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -946,6 +946,7 @@ dependencies = [
name = "rsvg_internals"
version = "0.0.1"
dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-rs 0.5.0 (git+https://github.com/gtk-rs/cairo)",
"cairo-sys-rs 0.7.0 (git+https://github.com/gtk-rs/cairo)",
"criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 4dfe206a..5d0435d9 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -20,6 +20,7 @@ build = "build.rs"
phf_codegen = "0.7.21"
[dependencies]
+bitflags = "1.0"
cairo-rs = { git="https://github.com/gtk-rs/cairo", branch="master" }
cairo-sys-rs = { git="https://github.com/gtk-rs/cairo", branch="master" }
cssparser = "0.25.1"
diff --git a/rsvg_internals/src/c_api.rs b/rsvg_internals/src/c_api.rs
index 10dec2fd..b4979c81 100644
--- a/rsvg_internals/src/c_api.rs
+++ b/rsvg_internals/src/c_api.rs
@@ -1,12 +1,15 @@
use std::ops;
use std::{f64, i32};
+use libc;
+
use glib::object::ObjectClass;
use glib::subclass;
use glib::subclass::object::ObjectClassSubclassExt;
use glib::subclass::prelude::*;
use glib::translate::*;
-use glib::{ParamFlags, ParamSpec, ToValue};
+use glib::value::{FromValue, FromValueOptional, SetValue};
+use glib::{ParamFlags, ParamSpec, StaticType, ToValue, Type, Value};
use glib_sys;
use gobject_sys;
@@ -17,6 +20,65 @@ extern "C" {
fn rsvg_handle_flags_get_type() -> glib_sys::GType;
}
+mod handle_flags {
+ // The following is entirely stolen from the auto-generated code
+ // for GBindingFlags, from gtk-rs/glib/src/gobject/auto/flags.rs
+
+ use super::*;
+
+ // Keep these in sync with rsvg.h:RsvgHandleFlags
+ #[cfg_attr(rustfmt, rustfmt_skip)]
+ bitflags! {
+ pub struct HandleFlags: u32 {
+ const NONE = 0;
+ const UNLIMITED = 1 << 0;
+ const KEEP_IMAGE_DATA = 1 << 1;
+ }
+ }
+
+ pub type RsvgHandleFlags = libc::c_uint;
+
+ impl ToGlib for HandleFlags {
+ type GlibType = RsvgHandleFlags;
+
+ fn to_glib(&self) -> RsvgHandleFlags {
+ self.bits()
+ }
+ }
+
+ impl FromGlib<RsvgHandleFlags> for HandleFlags {
+ fn from_glib(value: RsvgHandleFlags) -> HandleFlags {
+ HandleFlags::from_bits_truncate(value)
+ }
+ }
+
+ impl StaticType for HandleFlags {
+ fn static_type() -> Type {
+ unsafe { from_glib(rsvg_handle_flags_get_type()) }
+ }
+ }
+
+ impl<'a> FromValueOptional<'a> for HandleFlags {
+ unsafe fn from_value_optional(value: &Value) -> Option<Self> {
+ Some(FromValue::from_value(value))
+ }
+ }
+
+ impl<'a> FromValue<'a> for HandleFlags {
+ unsafe fn from_value(value: &Value) -> Self {
+ from_glib(gobject_sys::g_value_get_flags(value.to_glib_none().0))
+ }
+ }
+
+ impl SetValue for HandleFlags {
+ unsafe fn set_value(value: &mut Value, this: &Self) {
+ gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, this.to_glib())
+ }
+ }
+}
+
+pub use self::handle_flags::*;
+
// Keep this in sync with rsvg.h:RsvgHandleClass
#[repr(C)]
pub struct RsvgHandleClass {
@@ -61,7 +123,7 @@ static PROPERTIES: [subclass::Property; 11] = [
name,
"Flags",
"Loading flags",
- from_glib(unsafe { rsvg_handle_flags_get_type() }),
+ HandleFlags::static_type(),
0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
)
@@ -167,7 +229,9 @@ impl ObjectImpl for Handle {
match *prop {
subclass::Property("flags", ..) => {
- self.set_load_flags(value.get().expect("flags value has incorrect type"));
+ let v: HandleFlags = value.get().expect("flags value has incorrect type");
+
+ self.set_load_flags(v);
}
subclass::Property("dpi-x", ..) => {
@@ -196,7 +260,7 @@ impl ObjectImpl for Handle {
subclass::Property("base-uri", ..) => Ok(self
.base_url
- .borrow()
+ .borrow()
.as_ref()
.map(|url| url.as_str())
.to_value()),
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index f15e5e97..d7d14897 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -21,6 +21,7 @@ use libc;
use url::Url;
use allowed_url::{AllowedUrl, Href};
+use c_api::{HandleFlags, RsvgHandle, RsvgHandleFlags};
use dpi::Dpi;
use drawing_ctx::{DrawingCtx, RsvgRectangle};
use error::{set_gerror, DefsLookupErrorKind, LoadingError, RenderingError};
@@ -57,7 +58,7 @@ pub struct RsvgPositionData {
/// Flags used during loading
///
-/// We communicate these to/from the C code with a guint <-> u32,
+/// We communicate these to/from the C code with a HandleFlags
/// and this struct provides to_flags() and from_flags() methods.
#[derive(Default, Copy, Clone)]
pub struct LoadFlags {
@@ -617,7 +618,7 @@ impl Handle {
}
// from the public API
- pub fn set_load_flags(&self, flags: u32) {
+ pub fn set_load_flags(&self, flags: HandleFlags) {
self.load_flags.set(LoadFlags::from_flags(flags));
}
@@ -632,27 +633,23 @@ impl Handle {
}
}
-// Keep these in sync with rsvg.h:RsvgHandleFlags
-const RSVG_HANDLE_FLAG_UNLIMITED: u32 = 1 << 0;
-const RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: u32 = 1 << 1;
-
impl LoadFlags {
- pub fn from_flags(flags: u32) -> Self {
+ pub fn from_flags(flags: HandleFlags) -> Self {
LoadFlags {
- unlimited_size: (flags & RSVG_HANDLE_FLAG_UNLIMITED) != 0,
- keep_image_data: (flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0,
+ unlimited_size: flags.contains(HandleFlags::UNLIMITED),
+ keep_image_data: flags.contains(HandleFlags::KEEP_IMAGE_DATA),
}
}
- pub fn to_flags(&self) -> u32 {
- let mut flags = 0;
+ pub fn to_flags(&self) -> HandleFlags {
+ let mut flags = HandleFlags::empty();
if self.unlimited_size {
- flags |= RSVG_HANDLE_FLAG_UNLIMITED;
+ flags.insert(HandleFlags::UNLIMITED);
}
if self.keep_image_data {
- flags |= RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA;
+ flags.insert(HandleFlags::KEEP_IMAGE_DATA);
}
flags
@@ -761,17 +758,24 @@ pub unsafe extern "C" fn rsvg_handle_rust_get_dpi_y(raw_handle: *const RsvgHandl
}
#[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_get_flags(raw_handle: *const RsvgHandle) -> u32 {
+pub unsafe extern "C" fn rsvg_handle_rust_get_flags(
+ raw_handle: *const RsvgHandle,
+) -> RsvgHandleFlags {
let rhandle = get_rust_handle(raw_handle);
- rhandle.load_flags.get().to_flags()
+ rhandle.load_flags.get().to_flags().to_glib()
}
#[no_mangle]
-pub unsafe extern "C" fn rsvg_handle_rust_set_flags(raw_handle: *const RsvgHandle, flags: u32) {
+pub unsafe extern "C" fn rsvg_handle_rust_set_flags(
+ raw_handle: *const RsvgHandle,
+ flags: RsvgHandleFlags,
+) {
let rhandle = get_rust_handle(raw_handle);
- rhandle.load_flags.set(LoadFlags::from_flags(flags));
+ rhandle
+ .load_flags
+ .set(LoadFlags::from_flags(from_glib(flags)));
}
#[no_mangle]
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 3f90e58b..7212d06a 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -34,6 +34,9 @@ extern crate xml as xml_rs;
#[macro_use]
extern crate lazy_static;
+#[macro_use]
+extern crate bitflags;
+
#[macro_use]
extern crate glib;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]