[librsvg: 25/38] Bind RsvgHandleFlags with bitflags, to Rust



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]