Revert "Revert the subclass branch temporarily"

Now that gtk-rs had a release, we can re-merge the subclass branch.

This reverts commit 21efded1.
parent 223cd7e2
This diff is collapsed.
......@@ -275,18 +275,10 @@
#include "rsvg.h"
/* Defined in rsvg_internals/src/handle.rs */
typedef struct RsvgHandleRust RsvgHandleRust;
/* Implemented in rsvg_internals/src/xml.rs */
typedef struct RsvgXmlState RsvgXmlState;
G_GNUC_INTERNAL
RsvgHandleRust *rsvg_handle_get_rust (RsvgHandle *handle);
/* Implemented in rsvg_internals/src/handle.rs */
extern RsvgHandleRust *rsvg_handle_rust_new (void);
extern void rsvg_handle_rust_free (RsvgHandleRust *raw_handle);
extern double rsvg_handle_rust_get_dpi_x (RsvgHandle *raw_handle);
extern double rsvg_handle_rust_get_dpi_y (RsvgHandle *raw_handle);
extern void rsvg_handle_rust_set_dpi_x (RsvgHandle *raw_handle, double dpi_x);
......@@ -352,236 +344,13 @@ extern void rsvg_handle_rust_get_intrinsic_dimensions (RsvgHandle *handle,
extern GType rsvg_rust_error_get_type (void);
extern GType rsvg_rust_handle_flags_get_type (void);
typedef struct {
RsvgHandleRust *rust_handle;
} RsvgHandlePrivate;
enum {
PROP_0,
PROP_FLAGS,
PROP_DPI_X,
PROP_DPI_Y,
PROP_BASE_URI,
PROP_WIDTH,
PROP_HEIGHT,
PROP_EM,
PROP_EX,
PROP_TITLE,
PROP_DESC,
PROP_METADATA,
NUM_PROPS
};
G_DEFINE_TYPE_WITH_CODE (RsvgHandle, rsvg_handle, G_TYPE_OBJECT,
G_ADD_PRIVATE (RsvgHandle))
static void
rsvg_handle_init (RsvgHandle *self)
{
RsvgHandlePrivate *priv = rsvg_handle_get_instance_private (self);
priv->rust_handle = rsvg_handle_rust_new();
}
static void
rsvg_handle_dispose (GObject *instance)
{
RsvgHandle *self = (RsvgHandle *) instance;
RsvgHandlePrivate *priv = rsvg_handle_get_instance_private (self);
g_clear_pointer (&priv->rust_handle, rsvg_handle_rust_free);
G_OBJECT_CLASS (rsvg_handle_parent_class)->dispose (instance);
}
static void
rsvg_handle_set_property (GObject * instance, guint prop_id, GValue const *value, GParamSpec * pspec)
{
RsvgHandle *self = RSVG_HANDLE (instance);
switch (prop_id) {
case PROP_FLAGS:
rsvg_handle_rust_set_flags (self, g_value_get_flags (value));
break;
case PROP_DPI_X:
rsvg_handle_rust_set_dpi_x (self, g_value_get_double (value));
break;
case PROP_DPI_Y:
rsvg_handle_rust_set_dpi_y (self, g_value_get_double (value));
break;
case PROP_BASE_URI: {
const char *str = g_value_get_string (value);
if (str) {
rsvg_handle_set_base_uri (self, str);
}
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (instance, prop_id, pspec);
}
}
static void
rsvg_handle_get_property (GObject * instance, guint prop_id, GValue * value, GParamSpec * pspec)
{
RsvgHandle *self = RSVG_HANDLE (instance);
RsvgDimensionData dim;
switch (prop_id) {
case PROP_FLAGS:
g_value_set_flags (value, rsvg_handle_rust_get_flags (self));
break;
case PROP_DPI_X:
g_value_set_double (value, rsvg_handle_rust_get_dpi_x (self));
break;
case PROP_DPI_Y:
g_value_set_double (value, rsvg_handle_rust_get_dpi_y (self));
break;
case PROP_BASE_URI:
g_value_set_string (value, rsvg_handle_get_base_uri (self));
break;
case PROP_WIDTH:
rsvg_handle_get_dimensions (self, &dim);
g_value_set_int (value, dim.width);
break;
case PROP_HEIGHT:
rsvg_handle_get_dimensions (self, &dim);
g_value_set_int (value, dim.height);
break;
case PROP_EM:
rsvg_handle_get_dimensions (self, &dim);
g_value_set_double (value, dim.em);
break;
case PROP_EX:
rsvg_handle_get_dimensions (self, &dim);
g_value_set_double (value, dim.ex);
break;
case PROP_TITLE:
/* deprecated */
break;
case PROP_DESC:
/* deprecated */
break;
case PROP_METADATA:
g_value_set_string (value, rsvg_handle_get_metadata (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (instance, prop_id, pspec);
}
}
/* Implemented in rsvg_internals/src/c_api.rs */
extern GType rsvg_handle_rust_get_type (void);
static void
rsvg_handle_class_init (RsvgHandleClass * klass)
GType
rsvg_handle_get_type (void)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->dispose = rsvg_handle_dispose;
gobject_class->set_property = rsvg_handle_set_property;
gobject_class->get_property = rsvg_handle_get_property;
/**
* RsvgHandle:flags:
*
* Flags from #RsvgHandleFlags.
*
* Since: 2.36
*/
g_object_class_install_property (gobject_class,
PROP_FLAGS,
g_param_spec_flags ("flags", NULL, NULL,
RSVG_TYPE_HANDLE_FLAGS,
RSVG_HANDLE_FLAGS_NONE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/**
* dpi-x:
*/
g_object_class_install_property (gobject_class,
PROP_DPI_X,
g_param_spec_double ("dpi-x", _("Horizontal resolution"),
_("Horizontal resolution"),
0., G_MAXDOUBLE, 0.,
(GParamFlags) (G_PARAM_READWRITE |
G_PARAM_CONSTRUCT)));
g_object_class_install_property (gobject_class,
PROP_DPI_Y,
g_param_spec_double ("dpi-y", _("Vertical resolution"),
_("Vertical resolution"),
0., G_MAXDOUBLE, 0.,
(GParamFlags) (G_PARAM_READWRITE |
G_PARAM_CONSTRUCT)));
g_object_class_install_property (gobject_class,
PROP_BASE_URI,
g_param_spec_string ("base-uri", _("Base URI"),
_("Base URI"), NULL,
(GParamFlags) (G_PARAM_READWRITE |
G_PARAM_CONSTRUCT)));
g_object_class_install_property (gobject_class,
PROP_WIDTH,
g_param_spec_int ("width", _("Image width"),
_("Image width"), 0, G_MAXINT, 0,
(GParamFlags) (G_PARAM_READABLE)));
g_object_class_install_property (gobject_class,
PROP_HEIGHT,
g_param_spec_int ("height", _("Image height"),
_("Image height"), 0, G_MAXINT, 0,
(GParamFlags) (G_PARAM_READABLE)));
g_object_class_install_property (gobject_class,
PROP_EM,
g_param_spec_double ("em", _("em"),
_("em"), 0, G_MAXDOUBLE, 0,
(GParamFlags) (G_PARAM_READABLE)));
g_object_class_install_property (gobject_class,
PROP_EX,
g_param_spec_double ("ex", _("ex"),
_("ex"), 0, G_MAXDOUBLE, 0,
(GParamFlags) (G_PARAM_READABLE)));
/**
* RsvgHandle:title:
*
* SVG's description
*
* Deprecated: 2.36
*/
g_object_class_install_property (gobject_class,
PROP_TITLE,
g_param_spec_string ("title", _("Title"),
_("SVG file title"), NULL,
(GParamFlags) (G_PARAM_READABLE)));
/**
* RsvgHandle:desc:
*
* SVG's description
*
* Deprecated: 2.36
*/
g_object_class_install_property (gobject_class,
PROP_DESC,
g_param_spec_string ("desc", _("Description"),
_("SVG file description"), NULL,
(GParamFlags) (G_PARAM_READABLE)));
/**
* RsvgHandle:metadata:
*
* SVG's description
*
* Deprecated: 2.36
*/
g_object_class_install_property (gobject_class,
PROP_METADATA,
g_param_spec_string ("metadata", _("Metadata"),
_("SVG file metadata"), NULL,
(GParamFlags) (G_PARAM_READABLE)));
return rsvg_handle_rust_get_type ();
}
/**
......@@ -958,13 +727,6 @@ rsvg_handle_get_desc (RsvgHandle *handle)
return NULL;
}
RsvgHandleRust *
rsvg_handle_get_rust (RsvgHandle *handle)
{
RsvgHandlePrivate *priv = rsvg_handle_get_instance_private (handle);
return priv->rust_handle;
}
/**
* rsvg_handle_render_cairo_sub:
* @handle: A #RsvgHandle
......
......@@ -9,14 +9,14 @@ build = "build.rs"
name = "librsvg"
[dependencies]
cairo-rs = "0.5.0"
glib = "0.6.0"
gio = { version="0.5.1", features=["v2_48"] } # per configure.ac
cairo-rs = "0.6.0"
glib = "0.7.0"
gio = { version="0.6.0", features=["v2_48"] } # per configure.ac
rsvg_internals = { path = "../rsvg_internals" }
url = "1.7.2"
[dev-dependencies]
cairo-rs = { version = "0.5.0", features = ["png"] }
cairo-rs = { version = "0.6.0", features = ["png"] }
[build-dependencies]
pkg-config = "0.3.14"
......@@ -274,9 +274,13 @@ impl LoadOptions {
file: &gio::File,
cancellable: P,
) -> Result<SvgHandle, LoadingError> {
let stream = file.read(None)?;
let cancellable = cancellable.into();
self.read_stream(&stream.upcast(), Some(&file), cancellable.into())
let cancellable_clone = cancellable.clone();
let stream = file.read(cancellable)?;
self.read_stream(&stream.upcast(), Some(&file), cancellable_clone)
}
/// Reads an SVG stream from a `gio::InputStream`.
......@@ -297,7 +301,7 @@ impl LoadOptions {
base_file: Option<&gio::File>,
cancellable: P,
) -> Result<SvgHandle, LoadingError> {
let mut handle = Handle::new_with_flags(self.load_flags());
let handle = Handle::new_with_flags(self.load_flags());
handle.construct_read_stream_sync(stream, base_file, cancellable.into())?;
Ok(SvgHandle(handle))
......
......@@ -20,20 +20,21 @@ build = "build.rs"
phf_codegen = "0.7.21"
[dependencies]
cairo-rs = "0.5.0"
cairo-sys-rs = "0.7.0"
bitflags = "1.0"
cairo-rs = "0.6.0"
cairo-sys-rs = "0.8.0"
cssparser = "0.25.1"
data-url = "0.1"
downcast-rs = "^1.0.0"
encoding = "0.2.33"
float-cmp = "0.4.0"
gdk-pixbuf = "0.5.0"
gdk-pixbuf-sys = "0.7.0"
gio = { version="0.5.1", features=["v2_48"] } # per configure.ac
gio-sys = "0.7.0"
glib = "0.6.0"
glib-sys = "0.7.0"
gobject-sys = "0.7.0"
gdk-pixbuf = "0.6.0"
gdk-pixbuf-sys = "0.8.0"
gio = { version="0.6.0", features=["v2_48"] } # per configure.ac
gio-sys = "0.8.0"
glib = { version="0.7.0", features=["subclassing"] }
glib-sys = "0.8.0"
gobject-sys = "0.8.0"
itertools = "0.8"
language-tags = "0.2.2"
lazy_static = "1.0.0"
......@@ -42,9 +43,9 @@ locale_config = "*" # recommended explicitly by locale_config's README.md
nalgebra = "0.17"
num-traits = "0.2"
owning_ref = "0.4.0"
pango = "0.5.0"
pango-sys = "0.7.0"
pangocairo = "0.6.0"
pango = "0.6.0"
pango-sys = "0.8.0"
pangocairo = "0.7.0"
phf = "0.7.21"
rayon = "1"
regex = "1"
......
use std::ops;
use std::sync::Once;
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::value::{FromValue, FromValueOptional, SetValue};
use glib::{ParamFlags, ParamSpec, StaticType, ToValue, Type, Value};
use glib_sys;
use gobject_sys::{self, GEnumValue, GFlagsValue};
use error::RSVG_ERROR_FAILED;
use handle::Handle;
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_rust_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 {
parent: gobject_sys::GObjectClass,
_abi_padding: [glib_sys::gpointer; 15],
}
// Keep this in sync with rsvg.h:RsvgHandle
#[repr(C)]
pub struct RsvgHandle {
parent: gobject_sys::GObject,
_abi_padding: [glib_sys::gpointer; 16],
}
unsafe impl ClassStruct for RsvgHandleClass {
type Type = Handle;
}
unsafe impl InstanceStruct for RsvgHandle {
type Type = Handle;
}
impl ops::Deref for RsvgHandleClass {
type Target = ObjectClass;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const _ as *const Self::Target) }
}
}
impl ops::DerefMut for RsvgHandleClass {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self as *mut _ as *mut Self::Target) }
}
}
static PROPERTIES: [subclass::Property; 11] = [
subclass::Property("flags", |name| {
ParamSpec::flags(
name,
"Flags",
"Loading flags",
HandleFlags::static_type(),
0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT_ONLY,
)
}),
subclass::Property("dpi-x", |name| {
ParamSpec::double(
name,
"Horizontal DPI",
"Horizontal resolution in dots per inch",
0.0,
f64::MAX,
0.0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
)
}),
subclass::Property("dpi-y", |name| {
ParamSpec::double(
name,
"Vertical DPI",
"Vertical resolution in dots per inch",
0.0,
f64::MAX,
0.0,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
)
}),
subclass::Property("base-uri", |name| {
ParamSpec::string(
name,
"Base URI",
"Base URI for resolving relative references",
None,
ParamFlags::READWRITE | ParamFlags::CONSTRUCT,
)
}),
subclass::Property("width", |name| {
ParamSpec::int(
name,
"Image width",
"Image width",
0,
i32::MAX,
0,
ParamFlags::READABLE,
)
}),
subclass::Property("height", |name| {
ParamSpec::int(
name,
"Image height",
"Image height",
0,
i32::MAX,
0,
ParamFlags::READABLE,
)
}),
subclass::Property("em", |name| {
ParamSpec::double(name, "em", "em", 0.0, f64::MAX, 0.0, ParamFlags::READABLE)
}),
subclass::Property("ex", |name| {
ParamSpec::double(name, "ex", "ex", 0.0, f64::MAX, 0.0, ParamFlags::READABLE)
}),
subclass::Property("title", |name| {
ParamSpec::string(name, "deprecated", "deprecated", None, ParamFlags::READABLE)
}),
subclass::Property("desc", |name| {
ParamSpec::string(name, "deprecated", "deprecated", None, ParamFlags::READABLE)
}),
subclass::Property("metadata", |name| {
ParamSpec::string(name, "deprecated", "deprecated", None, ParamFlags::READABLE)
}),
];
impl ObjectSubclass for Handle {
const NAME: &'static str = "RsvgHandle";
type ParentType = glib::Object;
// We don't use subclass:simple::InstanceStruct and ClassStruct
// because we need to maintain the respective _abi_padding of each
// of RsvgHandleClass and RsvgHandle.
type Instance = RsvgHandle;
type Class = RsvgHandleClass;
glib_object_subclass!();
fn class_init(klass: &mut RsvgHandleClass) {
klass.install_properties(&PROPERTIES);
}
fn new() -> Self {
Handle::new()
}
}
impl ObjectImpl for Handle {
glib_object_impl!();
fn set_property(&self, _obj: &glib::Object, id: usize, value: &glib::Value) {
let prop = &PROPERTIES[id];
match *prop {
subclass::Property("flags", ..) => {
let v: HandleFlags = value.get().expect("flags value has incorrect type");
self.set_load_flags(v);
}
subclass::Property("dpi-x", ..) => {
self.set_dpi_x(value.get().expect("dpi-x value has incorrect type"));
}
subclass::Property("dpi-y", ..) => {
self.set_dpi_y(value.get().expect("dpi-y value has incorrect type"));
}
subclass::Property("base-uri", ..) => {
let v: Option<String> = value.get();
// rsvg_handle_set_base_uri() expects non-NULL URI strings,
// but the "base-uri" property can be set to NULL due to a missing
// construct-time property.
if let Some(s) = v {
self.set_base_url(&s);
}
}
_ => unreachable!("invalid property id {}", id),
}
}
fn get_property(&self, _obj: &glib::Object, id: usize) -> Result<glib::Value, ()> {
let prop = &PROPERTIES[id];
match *prop {
subclass::Property("flags", ..) => Ok(self.load_flags.get().to_flags().to_value()),
subclass::Property("dpi-x", ..) => Ok(self.dpi.get().x().to_value()),
subclass::Property("dpi-y", ..) => Ok(self.dpi.get().y().to_value()),
subclass::Property("base-uri", ..) => Ok(self
.base_url
.borrow()
.as_ref()
.map(|url| url.as_str())
.to_value()),
subclass::Property("width", ..) => Ok(self.get_dimensions_no_error().width.to_value()),
subclass::Property("height", ..) => {
Ok(self.get_dimensions_no_error().height.to_value())
}
subclass::Property("em", ..) => Ok(self.get_dimensions_no_error().em.to_value()),
subclass::Property("ex", ..) => Ok(self.get_dimensions_no_error().ex.to_value()),
// the following three are deprecated
subclass::Property("title", ..) => Ok((None as Option<String>).to_value()),
subclass::Property("desc", ..) => Ok((None as Option<String>).to_value()),
subclass::Property("metadata", ..) => Ok((None as Option<String>).to_value()),
_ => unreachable!("invalid property id={} for RsvgHandle", id),
}
}
}
pub fn get_rust_handle<'a>(handle: *const RsvgHandle) -> &'a Handle {
let handle = unsafe { &*handle };
handle.get_impl()
}
#[no_mangle]
pub unsafe extern "C" fn rsvg_handle_rust_get_type() -> glib_sys::GType {
Handle::get_type().to_glib()
}
#[no_mangle]
pub unsafe extern "C" fn rsvg_rust_error_get_type() -> glib_sys::GType {
......
......@@ -105,6 +105,7 @@ pub enum RenderingError {
InvalidId(DefsLookupErrorKind),
InvalidHref,
OutOfMemory,
HandleIsNotLoaded,
}
impl From<cairo::Status> for RenderingError {
......@@ -243,6 +244,7 @@ impl error::Error for RenderingError {
RenderingError::InvalidId(_) => "invalid id",
RenderingError::InvalidHref => "invalid href",
RenderingError::OutOfMemory => "out of memory",
RenderingError::HandleIsNotLoaded => "SVG data is not loaded into handle",
}
}
}
......@@ -255,7 +257,8 @@ impl fmt::Display for RenderingError {
RenderingError::CircularReference
| RenderingError::InstancingLimit
| RenderingError::InvalidHref
| RenderingError::OutOfMemory => write!(f, "{}", self.description()),
| RenderingError::OutOfMemory
| RenderingError::HandleIsNotLoaded => write!(f, "{}", self.description()),
}
}
}
......
......@@ -65,12 +65,12 @@ impl Default for SpreadMethod {
}
}
impl From<SpreadMethod> for cairo::enums::Extend {
fn from(s: SpreadMethod) -> cairo::enums::Extend {
impl From<SpreadMethod> for cairo::Extend {
fn from(s: SpreadMethod) -> cairo::Extend {
match s {
SpreadMethod::Pad => cairo::enums::Extend::Pad,
SpreadMethod::Reflect => cairo::enums::Extend::Reflect,
SpreadMethod::Repeat => cairo::enums::Extend::Repeat,
SpreadMethod::Pad => cairo::Extend::Pad,
SpreadMethod::Reflect => cairo::Extend::Reflect,
SpreadMethod::Repeat => cairo::Extend::Repeat,
}
}
}
......@@ -483,7 +483,7 @@ fn set_common_on_pattern<P: cairo::PatternTrait + cairo::Gradient>(
affine.invert();
pattern.set_matrix(affine);
pattern.set_extend(cairo::enums::Extend::from(
pattern.set_extend(cairo::Extend::from(
gradient.common.spread.unwrap_or_default(),
));
......
This diff is collapsed.
......@@ -109,7 +109,7 @@ pub fn acquire_data(
let (contents, _etag) = file.load_contents(cancellable)?;
let (content_type, _uncertain) = gio::content_type_guess(uri, &contents);
let mime_type = gio::content_type_get_mime_type(&content_type);
<