librsvg source for verification 2026-05-22

This commit is contained in:
2026-05-22 16:45:08 +08:00
commit 75af7ac721
2138 changed files with 161177 additions and 0 deletions

17
librsvg-rebind/LICENSE Normal file
View File

@@ -0,0 +1,17 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

8
librsvg-rebind/README.md Normal file
View File

@@ -0,0 +1,8 @@
# librsvg-rebind
See [librsvg-rebind/README.md] for the use cases of these crates.
## Regenerate bindings
To regenerate the bindings you can call `./regen.sh` after running
`git submodule update --init --recursive`.

View File

@@ -0,0 +1,39 @@
[package]
name = "librsvg-rebind"
authors = ["Sophie Herold <sophie@hemio.de>"]
readme = "README.md"
homepage = "https://gitlab.gnome.org/GNOME/librsvg"
description = "Rust bindings for librsvg"
license = "MIT"
repository = "https://gitlab.gnome.org/GNOME/librsvg"
documentation = "https://gnome.pages.gitlab.gnome.org/librsvg/doc/librsvg_rebind/"
categories = ["api-bindings"]
version = "0.3.0"
keywords = ["svg"]
edition = "2024"
exclude = ["Gir.toml"]
[dependencies]
libc.workspace = true
bitflags.workspace = true
cairo-rs.workspace = true
glib.workspace = true
gio.workspace = true
[dev-dependencies]
cairo-rs = { workspace = true, features = ['png'] }
[dependencies.ffi]
package = "librsvg-rebind-sys"
version = "0.3.0"
path = "./sys"
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]
all-features = true
[features]
v2_58 = ["ffi/v2_58"]
v2_59 = ["v2_58", "ffi/v2_59"]

View File

@@ -0,0 +1,64 @@
# Configuration for https://github.com/gtk-rs/gir
[external_libraries]
Gio = { min_version = "2.66" }
[options]
girs_directories = ["../gir-files", "../"]
library = "Rsvg"
version = "2.0"
min_cfg_version = "2.52.0"
target_path = "."
work_mode = "normal"
generate_safety_asserts = true
deprecate_by_min_version = true
single_version_file = true
external_libraries = ["GLib", "Gio", "GObject", "GdkPixbuf", "cairo"]
generate = ["Rsvg.Error", "Rsvg.Unit", "Rsvg.HandleFlags"]
manual = [
"GLib.Bytes",
"GLib.DateTime",
"GLib.Error",
"GLib.HashTable",
"GLib.Quark",
"GLib.String",
"Gio.AsyncReadyCallback",
"Gio.AsyncResult",
"Gio.Cancellable",
"Gio.File",
"Gio.InputStream",
"cairo.Context",
"cairo.FontOptions",
"cairo.RectangleInt",
"cairo.Region",
"cairo.Surface",
"Rsvg.Length",
"Rsvg.Rectangle",
]
[[object]]
name = "Rsvg.Handle"
status = "generate"
manual_traits = ["ToplevelExtManual"]
[[object.function]]
name = "render_document"
[[object.function.parameter]]
name = "cr"
const = true
[[object.function]]
name = "render_element"
[[object.function.parameter]]
name = "cr"
const = true
[[object.function]]
name = "render_layer"
[[object.function.parameter]]
name = "cr"
const = true
[[object.function]]
name = "get_intrinsic_dimensions"
manual = true
doc_trait_name = "ToplevelExtManual"

View File

@@ -0,0 +1 @@
../LICENSE

View File

@@ -0,0 +1,8 @@
# librsvg-rebind
The *librsvg-rebind* crates allow to use *librsvg*'s C-API from rust. Since
*librsvg* is written in Rust, a
[native Rust API](https://crates.io/crates/librsvg) does exist. However,
statically linking the library into a binary might not be desired in all cases.
In these cases, *librsvg* can be linked dynamically and can reduce the Rust
binary size by about 5 MB.

View File

@@ -0,0 +1,199 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from ../builddir/rsvg
// from gir-files
// DO NOT EDIT
use crate::ffi;
use glib::{prelude::*, translate::*};
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
#[non_exhaustive]
#[doc(alias = "RsvgError")]
pub enum Error {
#[doc(alias = "RSVG_ERROR_FAILED")]
Failed,
#[doc(hidden)]
__Unknown(i32),
}
#[doc(hidden)]
impl IntoGlib for Error {
type GlibType = ffi::RsvgError;
#[inline]
fn into_glib(self) -> ffi::RsvgError {
match self {
Self::Failed => ffi::RSVG_ERROR_FAILED,
Self::__Unknown(value) => value,
}
}
}
#[doc(hidden)]
impl FromGlib<ffi::RsvgError> for Error {
#[inline]
unsafe fn from_glib(value: ffi::RsvgError) -> Self {
skip_assert_initialized!();
match value {
ffi::RSVG_ERROR_FAILED => Self::Failed,
value => Self::__Unknown(value),
}
}
}
impl glib::error::ErrorDomain for Error {
#[inline]
fn domain() -> glib::Quark {
skip_assert_initialized!();
unsafe { from_glib(ffi::rsvg_error_quark()) }
}
#[inline]
fn code(self) -> i32 {
self.into_glib()
}
#[inline]
#[allow(clippy::match_single_binding)]
fn from(code: i32) -> Option<Self> {
skip_assert_initialized!();
match unsafe { from_glib(code) } {
Self::__Unknown(_) => Some(Self::Failed),
value => Some(value),
}
}
}
impl StaticType for Error {
#[inline]
#[doc(alias = "rsvg_error_get_type")]
fn static_type() -> glib::Type {
unsafe { from_glib(ffi::rsvg_error_get_type()) }
}
}
impl glib::HasParamSpec for Error {
type ParamSpec = glib::ParamSpecEnum;
type SetValue = Self;
type BuilderFn = fn(&str, Self) -> glib::ParamSpecEnumBuilder<Self>;
fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder_with_default
}
}
impl glib::value::ValueType for Error {
type Type = Self;
}
unsafe impl<'a> glib::value::FromValue<'a> for Error {
type Checker = glib::value::GenericValueTypeChecker<Self>;
#[inline]
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
unsafe { from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0)) }
}
}
impl ToValue for Error {
#[inline]
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Self>();
unsafe {
glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib());
}
value
}
#[inline]
fn value_type(&self) -> glib::Type {
Self::static_type()
}
}
impl From<Error> for glib::Value {
#[inline]
fn from(v: Error) -> Self {
skip_assert_initialized!();
ToValue::to_value(&v)
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
#[non_exhaustive]
#[doc(alias = "RsvgUnit")]
pub enum Unit {
#[doc(alias = "RSVG_UNIT_PERCENT")]
Percent,
#[doc(alias = "RSVG_UNIT_PX")]
Px,
#[doc(alias = "RSVG_UNIT_EM")]
Em,
#[doc(alias = "RSVG_UNIT_EX")]
Ex,
#[doc(alias = "RSVG_UNIT_IN")]
In,
#[doc(alias = "RSVG_UNIT_CM")]
Cm,
#[doc(alias = "RSVG_UNIT_MM")]
Mm,
#[doc(alias = "RSVG_UNIT_PT")]
Pt,
#[doc(alias = "RSVG_UNIT_PC")]
Pc,
#[cfg(feature = "v2_58")]
#[cfg_attr(docsrs, doc(cfg(feature = "v2_58")))]
#[doc(alias = "RSVG_UNIT_CH")]
Ch,
#[doc(hidden)]
__Unknown(i32),
}
#[doc(hidden)]
impl IntoGlib for Unit {
type GlibType = ffi::RsvgUnit;
#[inline]
fn into_glib(self) -> ffi::RsvgUnit {
match self {
Self::Percent => ffi::RSVG_UNIT_PERCENT,
Self::Px => ffi::RSVG_UNIT_PX,
Self::Em => ffi::RSVG_UNIT_EM,
Self::Ex => ffi::RSVG_UNIT_EX,
Self::In => ffi::RSVG_UNIT_IN,
Self::Cm => ffi::RSVG_UNIT_CM,
Self::Mm => ffi::RSVG_UNIT_MM,
Self::Pt => ffi::RSVG_UNIT_PT,
Self::Pc => ffi::RSVG_UNIT_PC,
#[cfg(feature = "v2_58")]
Self::Ch => ffi::RSVG_UNIT_CH,
Self::__Unknown(value) => value,
}
}
}
#[doc(hidden)]
impl FromGlib<ffi::RsvgUnit> for Unit {
#[inline]
unsafe fn from_glib(value: ffi::RsvgUnit) -> Self {
skip_assert_initialized!();
match value {
ffi::RSVG_UNIT_PERCENT => Self::Percent,
ffi::RSVG_UNIT_PX => Self::Px,
ffi::RSVG_UNIT_EM => Self::Em,
ffi::RSVG_UNIT_EX => Self::Ex,
ffi::RSVG_UNIT_IN => Self::In,
ffi::RSVG_UNIT_CM => Self::Cm,
ffi::RSVG_UNIT_MM => Self::Mm,
ffi::RSVG_UNIT_PT => Self::Pt,
ffi::RSVG_UNIT_PC => Self::Pc,
#[cfg(feature = "v2_58")]
ffi::RSVG_UNIT_CH => Self::Ch,
value => Self::__Unknown(value),
}
}
}

View File

@@ -0,0 +1,95 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from ../builddir/rsvg
// from gir-files
// DO NOT EDIT
use crate::ffi;
use glib::{bitflags::bitflags, prelude::*, translate::*};
bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[doc(alias = "RsvgHandleFlags")]
pub struct HandleFlags: u32 {
#[doc(alias = "RSVG_HANDLE_FLAGS_NONE")]
const FLAGS_NONE = ffi::RSVG_HANDLE_FLAGS_NONE as _;
#[doc(alias = "RSVG_HANDLE_FLAG_UNLIMITED")]
const FLAG_UNLIMITED = ffi::RSVG_HANDLE_FLAG_UNLIMITED as _;
#[doc(alias = "RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA")]
const FLAG_KEEP_IMAGE_DATA = ffi::RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA as _;
}
}
#[doc(hidden)]
impl IntoGlib for HandleFlags {
type GlibType = ffi::RsvgHandleFlags;
#[inline]
fn into_glib(self) -> ffi::RsvgHandleFlags {
self.bits()
}
}
#[doc(hidden)]
impl FromGlib<ffi::RsvgHandleFlags> for HandleFlags {
#[inline]
unsafe fn from_glib(value: ffi::RsvgHandleFlags) -> Self {
skip_assert_initialized!();
Self::from_bits_truncate(value)
}
}
impl StaticType for HandleFlags {
#[inline]
#[doc(alias = "rsvg_handle_flags_get_type")]
fn static_type() -> glib::Type {
unsafe { from_glib(ffi::rsvg_handle_flags_get_type()) }
}
}
impl glib::HasParamSpec for HandleFlags {
type ParamSpec = glib::ParamSpecFlags;
type SetValue = Self;
type BuilderFn = fn(&str) -> glib::ParamSpecFlagsBuilder<Self>;
fn param_spec_builder() -> Self::BuilderFn {
Self::ParamSpec::builder
}
}
impl glib::value::ValueType for HandleFlags {
type Type = Self;
}
unsafe impl<'a> glib::value::FromValue<'a> for HandleFlags {
type Checker = glib::value::GenericValueTypeChecker<Self>;
#[inline]
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
unsafe { from_glib(glib::gobject_ffi::g_value_get_flags(value.to_glib_none().0)) }
}
}
impl ToValue for HandleFlags {
#[inline]
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Self>();
unsafe {
glib::gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, self.into_glib());
}
value
}
#[inline]
fn value_type(&self) -> glib::Type {
Self::static_type()
}
}
impl From<HandleFlags> for glib::Value {
#[inline]
fn from(v: HandleFlags) -> Self {
skip_assert_initialized!();
ToValue::to_value(&v)
}
}

View File

@@ -0,0 +1,518 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from ../builddir/rsvg
// from gir-files
// DO NOT EDIT
#![allow(deprecated)]
use crate::{HandleFlags, Rectangle, ffi};
use glib::{
prelude::*,
signal::{SignalHandlerId, connect_raw},
translate::*,
};
use std::boxed::Box as Box_;
glib::wrapper! {
#[doc(alias = "RsvgHandle")]
pub struct Handle(Object<ffi::RsvgHandle, ffi::RsvgHandleClass>);
match fn {
type_ => || ffi::rsvg_handle_get_type(),
}
}
impl Handle {
pub const NONE: Option<&'static Handle> = None;
#[doc(alias = "rsvg_handle_new")]
pub fn new() -> Handle {
assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::rsvg_handle_new()) }
}
#[doc(alias = "rsvg_handle_new_from_data")]
#[doc(alias = "new_from_data")]
pub fn from_data(data: &[u8]) -> Result<Handle, glib::Error> {
assert_initialized_main_thread!();
let data_len = data.len() as _;
unsafe {
let mut error = std::ptr::null_mut();
let ret = ffi::rsvg_handle_new_from_data(data.to_glib_none().0, data_len, &mut error);
if error.is_null() {
Ok(from_glib_full(ret))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_new_from_file")]
#[doc(alias = "new_from_file")]
pub fn from_file(filename: &str) -> Result<Handle, glib::Error> {
assert_initialized_main_thread!();
unsafe {
let mut error = std::ptr::null_mut();
let ret = ffi::rsvg_handle_new_from_file(filename.to_glib_none().0, &mut error);
if error.is_null() {
Ok(from_glib_full(ret))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_new_from_gfile_sync")]
#[doc(alias = "new_from_gfile_sync")]
pub fn from_gfile_sync(
file: &impl IsA<gio::File>,
flags: HandleFlags,
cancellable: Option<&impl IsA<gio::Cancellable>>,
) -> Result<Handle, glib::Error> {
assert_initialized_main_thread!();
unsafe {
let mut error = std::ptr::null_mut();
let ret = ffi::rsvg_handle_new_from_gfile_sync(
file.as_ref().to_glib_none().0,
flags.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
&mut error,
);
if error.is_null() {
Ok(from_glib_full(ret))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_new_from_stream_sync")]
#[doc(alias = "new_from_stream_sync")]
pub fn from_stream_sync(
input_stream: &impl IsA<gio::InputStream>,
base_file: Option<&impl IsA<gio::File>>,
flags: HandleFlags,
cancellable: Option<&impl IsA<gio::Cancellable>>,
) -> Result<Handle, glib::Error> {
assert_initialized_main_thread!();
unsafe {
let mut error = std::ptr::null_mut();
let ret = ffi::rsvg_handle_new_from_stream_sync(
input_stream.as_ref().to_glib_none().0,
base_file.map(|p| p.as_ref()).to_glib_none().0,
flags.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
&mut error,
);
if error.is_null() {
Ok(from_glib_full(ret))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_new_with_flags")]
#[doc(alias = "new_with_flags")]
pub fn with_flags(flags: HandleFlags) -> Handle {
assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::rsvg_handle_new_with_flags(flags.into_glib())) }
}
}
impl Default for Handle {
fn default() -> Self {
Self::new()
}
}
pub trait HandleExt: IsA<Handle> + 'static {
#[doc(alias = "rsvg_handle_get_base_uri")]
#[doc(alias = "get_base_uri")]
#[doc(alias = "base-uri")]
fn base_uri(&self) -> Option<glib::GString> {
unsafe {
from_glib_none(ffi::rsvg_handle_get_base_uri(
self.as_ref().to_glib_none().0,
))
}
}
#[doc(alias = "rsvg_handle_get_geometry_for_element")]
#[doc(alias = "get_geometry_for_element")]
fn geometry_for_element(
&self,
id: Option<&str>,
) -> Result<(Rectangle, Rectangle), glib::Error> {
unsafe {
let mut out_ink_rect = Rectangle::uninitialized();
let mut out_logical_rect = Rectangle::uninitialized();
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_get_geometry_for_element(
self.as_ref().to_glib_none().0,
id.to_glib_none().0,
out_ink_rect.to_glib_none_mut().0,
out_logical_rect.to_glib_none_mut().0,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok((out_ink_rect, out_logical_rect))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_get_geometry_for_layer")]
#[doc(alias = "get_geometry_for_layer")]
fn geometry_for_layer(
&self,
id: Option<&str>,
viewport: &Rectangle,
) -> Result<(Rectangle, Rectangle), glib::Error> {
unsafe {
let mut out_ink_rect = Rectangle::uninitialized();
let mut out_logical_rect = Rectangle::uninitialized();
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_get_geometry_for_layer(
self.as_ref().to_glib_none().0,
id.to_glib_none().0,
viewport.to_glib_none().0,
out_ink_rect.to_glib_none_mut().0,
out_logical_rect.to_glib_none_mut().0,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok((out_ink_rect, out_logical_rect))
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_get_intrinsic_size_in_pixels")]
#[doc(alias = "get_intrinsic_size_in_pixels")]
fn intrinsic_size_in_pixels(&self) -> Option<(f64, f64)> {
unsafe {
let mut out_width = std::mem::MaybeUninit::uninit();
let mut out_height = std::mem::MaybeUninit::uninit();
let ret = from_glib(ffi::rsvg_handle_get_intrinsic_size_in_pixels(
self.as_ref().to_glib_none().0,
out_width.as_mut_ptr(),
out_height.as_mut_ptr(),
));
if ret {
Some((out_width.assume_init(), out_height.assume_init()))
} else {
None
}
}
}
//#[cfg_attr(feature = "v2_58", deprecated = "Since 2.58")]
//#[allow(deprecated)]
//#[doc(alias = "rsvg_handle_get_pixbuf")]
//#[doc(alias = "get_pixbuf")]
//fn pixbuf(&self) -> /*Ignored*/Option<gdk_pixbuf::Pixbuf> {
// unsafe { TODO: call ffi:rsvg_handle_get_pixbuf() }
//}
//#[cfg(feature = "v2_59")]
//#[cfg_attr(docsrs, doc(cfg(feature = "v2_59")))]
//#[doc(alias = "rsvg_handle_get_pixbuf_and_error")]
//#[doc(alias = "get_pixbuf_and_error")]
//fn pixbuf_and_error(&self) -> Result</*Ignored*/Option<gdk_pixbuf::Pixbuf>, glib::Error> {
// unsafe { TODO: call ffi:rsvg_handle_get_pixbuf_and_error() }
//}
//#[doc(alias = "rsvg_handle_get_pixbuf_sub")]
//#[doc(alias = "get_pixbuf_sub")]
//fn pixbuf_sub(&self, id: Option<&str>) -> /*Ignored*/Option<gdk_pixbuf::Pixbuf> {
// unsafe { TODO: call ffi:rsvg_handle_get_pixbuf_sub() }
//}
#[doc(alias = "rsvg_handle_has_sub")]
fn has_sub(&self, id: &str) -> bool {
unsafe {
from_glib(ffi::rsvg_handle_has_sub(
self.as_ref().to_glib_none().0,
id.to_glib_none().0,
))
}
}
#[doc(alias = "rsvg_handle_internal_set_testing")]
fn internal_set_testing(&self, testing: bool) {
unsafe {
ffi::rsvg_handle_internal_set_testing(
self.as_ref().to_glib_none().0,
testing.into_glib(),
);
}
}
#[doc(alias = "rsvg_handle_read_stream_sync")]
fn read_stream_sync(
&self,
stream: &impl IsA<gio::InputStream>,
cancellable: Option<&impl IsA<gio::Cancellable>>,
) -> Result<(), glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_read_stream_sync(
self.as_ref().to_glib_none().0,
stream.as_ref().to_glib_none().0,
cancellable.map(|p| p.as_ref()).to_glib_none().0,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_render_document")]
fn render_document(
&self,
cr: &cairo::Context,
viewport: &Rectangle,
) -> Result<(), glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_render_document(
self.as_ref().to_glib_none().0,
mut_override(cr.to_glib_none().0),
viewport.to_glib_none().0,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_render_element")]
fn render_element(
&self,
cr: &cairo::Context,
id: Option<&str>,
element_viewport: &Rectangle,
) -> Result<(), glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_render_element(
self.as_ref().to_glib_none().0,
mut_override(cr.to_glib_none().0),
id.to_glib_none().0,
element_viewport.to_glib_none().0,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_render_layer")]
fn render_layer(
&self,
cr: &cairo::Context,
id: Option<&str>,
viewport: &Rectangle,
) -> Result<(), glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_render_layer(
self.as_ref().to_glib_none().0,
mut_override(cr.to_glib_none().0),
id.to_glib_none().0,
viewport.to_glib_none().0,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "rsvg_handle_set_base_gfile")]
fn set_base_gfile(&self, base_file: &impl IsA<gio::File>) {
unsafe {
ffi::rsvg_handle_set_base_gfile(
self.as_ref().to_glib_none().0,
base_file.as_ref().to_glib_none().0,
);
}
}
#[doc(alias = "rsvg_handle_set_base_uri")]
#[doc(alias = "base-uri")]
fn set_base_uri(&self, base_uri: &str) {
unsafe {
ffi::rsvg_handle_set_base_uri(
self.as_ref().to_glib_none().0,
base_uri.to_glib_none().0,
);
}
}
#[cfg(feature = "v2_59")]
#[cfg_attr(docsrs, doc(cfg(feature = "v2_59")))]
#[doc(alias = "rsvg_handle_set_cancellable_for_rendering")]
fn set_cancellable_for_rendering(&self, cancellable: Option<&impl IsA<gio::Cancellable>>) {
unsafe {
ffi::rsvg_handle_set_cancellable_for_rendering(
self.as_ref().to_glib_none().0,
cancellable.map(|p| p.as_ref()).to_glib_none().0,
);
}
}
#[doc(alias = "rsvg_handle_set_dpi")]
fn set_dpi(&self, dpi: f64) {
unsafe {
ffi::rsvg_handle_set_dpi(self.as_ref().to_glib_none().0, dpi);
}
}
#[doc(alias = "rsvg_handle_set_dpi_x_y")]
fn set_dpi_x_y(&self, dpi_x: f64, dpi_y: f64) {
unsafe {
ffi::rsvg_handle_set_dpi_x_y(self.as_ref().to_glib_none().0, dpi_x, dpi_y);
}
}
#[doc(alias = "rsvg_handle_set_stylesheet")]
fn set_stylesheet(&self, css: &[u8]) -> Result<(), glib::Error> {
let css_len = css.len() as _;
unsafe {
let mut error = std::ptr::null_mut();
let is_ok = ffi::rsvg_handle_set_stylesheet(
self.as_ref().to_glib_none().0,
css.to_glib_none().0,
css_len,
&mut error,
);
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
if error.is_null() {
Ok(())
} else {
Err(from_glib_full(error))
}
}
}
#[doc(alias = "dpi-x")]
fn dpi_x(&self) -> f64 {
ObjectExt::property(self.as_ref(), "dpi-x")
}
#[doc(alias = "dpi-x")]
fn set_dpi_x(&self, dpi_x: f64) {
ObjectExt::set_property(self.as_ref(), "dpi-x", dpi_x)
}
#[doc(alias = "dpi-y")]
fn dpi_y(&self) -> f64 {
ObjectExt::property(self.as_ref(), "dpi-y")
}
#[doc(alias = "dpi-y")]
fn set_dpi_y(&self, dpi_y: f64) {
ObjectExt::set_property(self.as_ref(), "dpi-y", dpi_y)
}
fn flags(&self) -> HandleFlags {
ObjectExt::property(self.as_ref(), "flags")
}
#[doc(alias = "base-uri")]
fn connect_base_uri_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_base_uri_trampoline<P: IsA<Handle>, F: Fn(&P) + 'static>(
this: *mut ffi::RsvgHandle,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
unsafe {
let f: &F = &*(f as *const F);
f(Handle::from_glib_borrow(this).unsafe_cast_ref())
}
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
c"notify::base-uri".as_ptr() as *const _,
Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
notify_base_uri_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[doc(alias = "dpi-x")]
fn connect_dpi_x_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_dpi_x_trampoline<P: IsA<Handle>, F: Fn(&P) + 'static>(
this: *mut ffi::RsvgHandle,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
unsafe {
let f: &F = &*(f as *const F);
f(Handle::from_glib_borrow(this).unsafe_cast_ref())
}
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
c"notify::dpi-x".as_ptr() as *const _,
Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
notify_dpi_x_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
#[doc(alias = "dpi-y")]
fn connect_dpi_y_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
unsafe extern "C" fn notify_dpi_y_trampoline<P: IsA<Handle>, F: Fn(&P) + 'static>(
this: *mut ffi::RsvgHandle,
_param_spec: glib::ffi::gpointer,
f: glib::ffi::gpointer,
) {
unsafe {
let f: &F = &*(f as *const F);
f(Handle::from_glib_borrow(this).unsafe_cast_ref())
}
}
unsafe {
let f: Box_<F> = Box_::new(f);
connect_raw(
self.as_ptr() as *mut _,
c"notify::dpi-y".as_ptr() as *const _,
Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
notify_dpi_y_trampoline::<Self, F> as *const (),
)),
Box_::into_raw(f),
)
}
}
}
impl<O: IsA<Handle>> HandleExt for O {}

View File

@@ -0,0 +1,18 @@
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from ../builddir/rsvg
// from gir-files
// DO NOT EDIT
mod handle;
pub use self::handle::Handle;
mod enums;
pub use self::enums::Error;
pub use self::enums::Unit;
mod flags;
pub use self::flags::HandleFlags;
pub(crate) mod traits {
pub use super::handle::HandleExt;
}

View File

@@ -0,0 +1,3 @@
Generated by gir (https://github.com/gtk-rs/gir @ 88f37d4165a8)
from ../builddir/rsvg (@ 5bf47e852751)
from gir-files (@ 6cef10cd64df)

View File

@@ -0,0 +1,33 @@
use glib::{prelude::*, translate::*};
use crate::{Handle, Length, Rectangle};
pub trait HandleExtManual: IsA<Handle> + 'static {
#[doc(alias = "rsvg_handle_get_intrinsic_dimensions")]
#[doc(alias = "get_intrinsic_dimensions")]
fn intrinsic_dimensions(&self) -> (Length, Length, Option<Rectangle>) {
unsafe {
let mut out_has_width = std::mem::MaybeUninit::uninit();
let mut out_width = Length::uninitialized();
let mut out_has_height = std::mem::MaybeUninit::uninit();
let mut out_height = Length::uninitialized();
let mut out_has_viewbox = std::mem::MaybeUninit::uninit();
let mut out_viewbox = Rectangle::uninitialized();
ffi::rsvg_handle_get_intrinsic_dimensions(
self.as_ref().to_glib_none().0,
out_has_width.as_mut_ptr(),
out_width.to_glib_none_mut().0,
out_has_height.as_mut_ptr(),
out_height.to_glib_none_mut().0,
out_has_viewbox.as_mut_ptr(),
out_viewbox.to_glib_none_mut().0,
);
(
out_width,
out_height,
(out_has_viewbox.assume_init() != 0).then_some(out_viewbox),
)
}
}
}
impl<O: IsA<Handle>> HandleExtManual for O {}

View File

@@ -0,0 +1,20 @@
use glib::translate::FromGlib;
use crate::Unit;
glib::wrapper! {
#[doc(alias = "RsvgLength")]
#[derive(Debug)]
pub struct Length(BoxedInline<ffi::RsvgLength>);
}
impl Length {
#[inline]
pub fn length(&self) -> f64 {
self.inner.length
}
pub fn unit(&self) -> Unit {
unsafe { Unit::from_glib(self.inner.unit) }
}
}

View File

@@ -0,0 +1,64 @@
#![allow(clippy::needless_doctest_main)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(html_logo_url = "https://gnome.pages.gitlab.gnome.org/librsvg/Rsvg-2.0/librsvg-r.svg")]
//! # Rust librsvg bindings
//!
//! This package contains safe Rust bindings for the librsvg C library.
//!
//! Since librsvg is written in Rust, the native [`rsvg`] crate is available
//! to use the same features. One of the main purposes of *librsvg-rebind*
//! is to reduce the binary sice.
//!
//! To use this package, the *librsvg-2* library has to be available on the system.
//! If you use the native [`rsvg`] crate, this is not required.
//!
//! [`rsvg`]: https://crates.io/crates/librsvg
//!
//! # Example
//!
//! ```
//! use librsvg_rebind::prelude::*;
//!
//! let handle = librsvg_rebind::Handle::from_file("../../rsvg/example.svg")
//! .unwrap()
//! .unwrap();
//!
//! let (width, height) = handle.intrinsic_size_in_pixels().unwrap();
//!
//! let surface =
//! cairo::ImageSurface::create(cairo::Format::ARgb32, width as i32, height as i32).unwrap();
//! let context = cairo::Context::new(&surface).unwrap();
//!
//! let viewport = librsvg_rebind::Rectangle::new(0., 0., height, width);
//!
//! handle.render_document(&context, &viewport).unwrap();
//!
//! let mut output_file = std::fs::File::create("/dev/null").unwrap();
//! surface.write_to_png(&mut output_file).unwrap();
//! ```
/// No-op.
macro_rules! skip_assert_initialized {
() => {};
}
// Re-export the -sys bindings
pub use ffi;
pub use gio;
pub use glib;
/// No-op.
macro_rules! assert_initialized_main_thread {
() => {};
}
mod auto;
mod handle;
mod length;
mod rectangle;
mod unit;
pub use auto::*;
pub use length::*;
pub use rectangle::*;
pub mod prelude;

View File

@@ -0,0 +1,3 @@
pub use crate::auto::traits::*;
pub use crate::handle::HandleExtManual;

View File

@@ -0,0 +1,42 @@
use ::glib::translate::*;
glib::wrapper! {
#[doc(alias = "GtkRectangle")]
#[derive(Debug)]
pub struct Rectangle(BoxedInline<ffi::RsvgRectangle>);
}
impl Rectangle {
#[inline]
pub fn new(x: f64, y: f64, width: f64, height: f64) -> Self {
assert_initialized_main_thread!();
unsafe {
Self::unsafe_from(ffi::RsvgRectangle {
x,
y,
width,
height,
})
}
}
#[inline]
pub fn x(&self) -> f64 {
self.inner.x
}
#[inline]
pub fn y(&self) -> f64 {
self.inner.y
}
#[inline]
pub fn width(&self) -> f64 {
self.inner.width
}
#[inline]
pub fn height(&self) -> f64 {
self.inner.height
}
}

View File

@@ -0,0 +1,22 @@
use crate::Unit;
impl std::fmt::Display for Unit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Self::Percent => "%",
Self::Px => "px",
Self::Em => "em",
Self::Ex => "ex",
Self::In => "in",
Self::Cm => "cm",
Self::Mm => "mm",
Self::Pt => "pt",
Self::Pc => "pc",
#[cfg(feature = "v2_59")]
Self::Ch => "ch",
Self::__Unknown(_) => "unknown",
};
f.write_str(s)
}
}

View File

@@ -0,0 +1,58 @@
[package]
name = "librsvg-rebind-sys"
authors = ["Sophie Herold <sophie@hemio.de>"]
version = "0.3.0"
description = "FFI bindings for librsvg"
homepage = "https://gitlab.gnome.org/GNOME/librsvg"
license = "MIT"
repository = "https://gitlab.gnome.org/GNOME/librsvg"
documentation = "https://gnome.pages.gitlab.gnome.org/librsvg/doc/librsvg_rebind_sys/"
categories = ["api-bindings"]
edition = "2024"
build = "build.rs"
keywords = ["svg"]
exclude = ["Gir.toml", "tests/"]
[package.metadata.docs.rs]
rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"]
all-features = true
[package.metadata.system-deps.librsvg_2_0]
name = "librsvg-2.0"
version = "2.50"
[package.metadata.system-deps.librsvg_2_0.v2_58]
version = "2.58"
[package.metadata.system-deps.librsvg_2_0.v2_59]
version = "2.59"
[dependencies]
libc.workspace = true
[dependencies.gdk-pixbuf-sys]
workspace = true
[dependencies.cairo-sys-rs]
workspace = true
[dependencies.glib-sys]
workspace = true
[dependencies.gio-sys]
workspace = true
[dependencies.gobject-sys]
workspace = true
[build-dependencies]
system-deps = "7"
[dev-dependencies]
shell-words.workspace = true
tempfile.workspace = true
[features]
v2_58 = []
v2_59 = ["v2_58"]

View File

@@ -0,0 +1,21 @@
# Configuration for https://github.com/gtk-rs/gir
[options]
library = "Rsvg"
version = "2.0"
target_path = "."
min_cfg_version = "2.52.0"
work_mode = "sys"
girs_directories = ["../../gir-files", "../../"]
external_libraries = ["GLib", "Gio", "GObject", "GdkPixbuf", "Cairo"]
ignore = [
"Rsvg.VERSION",
"Rsvg.MAJOR_VERSION",
"Rsvg.MICRO_VERSION",
"Rsvg.MINOR_VERSION",
"Rsvg.HAVE_CSS",
"Rsvg.HAVE_PIXBUF",
"Rsvg.HAVE_SVGZ",
]

View File

@@ -0,0 +1 @@
../../LICENSE

View File

@@ -0,0 +1,16 @@
// Generated by gir (https://github.com/gtk-rs/gir @ 88f37d4165a8)
// from ../builddir/rsvg (@ 5bf47e852751)
// from gir-files (@ 6cef10cd64df)
// DO NOT EDIT
fn main() {
if std::env::var("DOCS_RS").is_ok() {
// prevent linking libraries to avoid documentation failure
return;
}
if let Err(s) = system_deps::Config::new().probe() {
println!("cargo:warning={s}");
std::process::exit(1);
}
}

View File

@@ -0,0 +1,370 @@
// Generated by gir (https://github.com/gtk-rs/gir @ 88f37d4165a8)
// from ../builddir/rsvg (@ 5bf47e852751)
// from gir-files (@ 6cef10cd64df)
// DO NOT EDIT
#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)]
#![allow(
clippy::approx_constant,
clippy::type_complexity,
clippy::unreadable_literal,
clippy::upper_case_acronyms
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
use cairo_sys as cairo;
use gdk_pixbuf_sys as gdk_pixbuf;
use gio_sys as gio;
use glib_sys as glib;
use gobject_sys as gobject;
#[allow(unused_imports)]
use libc::{FILE, intptr_t, off_t, size_t, ssize_t, time_t, uintptr_t};
#[cfg(unix)]
#[allow(unused_imports)]
use libc::{dev_t, gid_t, pid_t, socklen_t, uid_t};
#[allow(unused_imports)]
use std::ffi::{
c_char, c_double, c_float, c_int, c_long, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void,
};
#[allow(unused_imports)]
use glib::{GType, gboolean, gconstpointer, gpointer};
// Enums
pub type RsvgError = c_int;
pub const RSVG_ERROR_FAILED: RsvgError = 0;
pub type RsvgUnit = c_int;
pub const RSVG_UNIT_PERCENT: RsvgUnit = 0;
pub const RSVG_UNIT_PX: RsvgUnit = 1;
pub const RSVG_UNIT_EM: RsvgUnit = 2;
pub const RSVG_UNIT_EX: RsvgUnit = 3;
pub const RSVG_UNIT_IN: RsvgUnit = 4;
pub const RSVG_UNIT_CM: RsvgUnit = 5;
pub const RSVG_UNIT_MM: RsvgUnit = 6;
pub const RSVG_UNIT_PT: RsvgUnit = 7;
pub const RSVG_UNIT_PC: RsvgUnit = 8;
#[cfg(feature = "v2_58")]
#[cfg_attr(docsrs, doc(cfg(feature = "v2_58")))]
pub const RSVG_UNIT_CH: RsvgUnit = 9;
// Constants
// Flags
pub type RsvgHandleFlags = c_uint;
pub const RSVG_HANDLE_FLAGS_NONE: RsvgHandleFlags = 0;
pub const RSVG_HANDLE_FLAG_UNLIMITED: RsvgHandleFlags = 1;
pub const RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: RsvgHandleFlags = 2;
// Callbacks
pub type RsvgSizeFunc = Option<unsafe extern "C" fn(*mut c_int, *mut c_int, gpointer)>;
// Records
#[derive(Copy, Clone)]
#[repr(C)]
pub struct RsvgDimensionData {
pub width: c_int,
pub height: c_int,
pub em: c_double,
pub ex: c_double,
}
impl ::std::fmt::Debug for RsvgDimensionData {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("RsvgDimensionData @ {self:p}"))
.field("width", &self.width)
.field("height", &self.height)
.field("em", &self.em)
.field("ex", &self.ex)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct RsvgHandleClass {
pub parent: gobject::GObjectClass,
pub _abi_padding: [gpointer; 15],
}
impl ::std::fmt::Debug for RsvgHandleClass {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("RsvgHandleClass @ {self:p}"))
.field("parent", &self.parent)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct RsvgLength {
pub length: c_double,
pub unit: RsvgUnit,
}
impl ::std::fmt::Debug for RsvgLength {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("RsvgLength @ {self:p}"))
.field("length", &self.length)
.field("unit", &self.unit)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct RsvgPositionData {
pub x: c_int,
pub y: c_int,
}
impl ::std::fmt::Debug for RsvgPositionData {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("RsvgPositionData @ {self:p}"))
.field("x", &self.x)
.field("y", &self.y)
.finish()
}
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct RsvgRectangle {
pub x: c_double,
pub y: c_double,
pub width: c_double,
pub height: c_double,
}
impl ::std::fmt::Debug for RsvgRectangle {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("RsvgRectangle @ {self:p}"))
.field("x", &self.x)
.field("y", &self.y)
.field("width", &self.width)
.field("height", &self.height)
.finish()
}
}
// Classes
#[derive(Copy, Clone)]
#[repr(C)]
pub struct RsvgHandle {
pub parent: gobject::GObject,
pub _abi_padding: [gpointer; 16],
}
impl ::std::fmt::Debug for RsvgHandle {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("RsvgHandle @ {self:p}"))
.field("parent", &self.parent)
.finish()
}
}
unsafe extern "C" {
//=========================================================================
// RsvgError
//=========================================================================
pub fn rsvg_error_get_type() -> GType;
pub fn rsvg_error_quark() -> glib::GQuark;
//=========================================================================
// RsvgHandleFlags
//=========================================================================
pub fn rsvg_handle_flags_get_type() -> GType;
//=========================================================================
// RsvgHandle
//=========================================================================
pub fn rsvg_handle_get_type() -> GType;
pub fn rsvg_handle_new() -> *mut RsvgHandle;
pub fn rsvg_handle_new_from_data(
data: *const u8,
data_len: size_t,
error: *mut *mut glib::GError,
) -> *mut RsvgHandle;
pub fn rsvg_handle_new_from_file(
filename: *const c_char,
error: *mut *mut glib::GError,
) -> *mut RsvgHandle;
pub fn rsvg_handle_new_from_gfile_sync(
file: *mut gio::GFile,
flags: RsvgHandleFlags,
cancellable: *mut gio::GCancellable,
error: *mut *mut glib::GError,
) -> *mut RsvgHandle;
pub fn rsvg_handle_new_from_stream_sync(
input_stream: *mut gio::GInputStream,
base_file: *mut gio::GFile,
flags: RsvgHandleFlags,
cancellable: *mut gio::GCancellable,
error: *mut *mut glib::GError,
) -> *mut RsvgHandle;
pub fn rsvg_handle_new_with_flags(flags: RsvgHandleFlags) -> *mut RsvgHandle;
pub fn rsvg_handle_close(handle: *mut RsvgHandle, error: *mut *mut glib::GError) -> gboolean;
pub fn rsvg_handle_free(handle: *mut RsvgHandle);
pub fn rsvg_handle_get_base_uri(handle: *mut RsvgHandle) -> *const c_char;
pub fn rsvg_handle_get_desc(handle: *mut RsvgHandle) -> *const c_char;
pub fn rsvg_handle_get_dimensions(
handle: *mut RsvgHandle,
dimension_data: *mut RsvgDimensionData,
);
pub fn rsvg_handle_get_dimensions_sub(
handle: *mut RsvgHandle,
dimension_data: *mut RsvgDimensionData,
id: *const c_char,
) -> gboolean;
pub fn rsvg_handle_get_geometry_for_element(
handle: *mut RsvgHandle,
id: *const c_char,
out_ink_rect: *mut RsvgRectangle,
out_logical_rect: *mut RsvgRectangle,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_get_geometry_for_layer(
handle: *mut RsvgHandle,
id: *const c_char,
viewport: *const RsvgRectangle,
out_ink_rect: *mut RsvgRectangle,
out_logical_rect: *mut RsvgRectangle,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_get_intrinsic_dimensions(
handle: *mut RsvgHandle,
out_has_width: *mut gboolean,
out_width: *mut RsvgLength,
out_has_height: *mut gboolean,
out_height: *mut RsvgLength,
out_has_viewbox: *mut gboolean,
out_viewbox: *mut RsvgRectangle,
);
pub fn rsvg_handle_get_intrinsic_size_in_pixels(
handle: *mut RsvgHandle,
out_width: *mut c_double,
out_height: *mut c_double,
) -> gboolean;
pub fn rsvg_handle_get_metadata(handle: *mut RsvgHandle) -> *const c_char;
pub fn rsvg_handle_get_pixbuf(handle: *mut RsvgHandle) -> *mut gdk_pixbuf::GdkPixbuf;
#[cfg(feature = "v2_59")]
#[cfg_attr(docsrs, doc(cfg(feature = "v2_59")))]
pub fn rsvg_handle_get_pixbuf_and_error(
handle: *mut RsvgHandle,
error: *mut *mut glib::GError,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_handle_get_pixbuf_sub(
handle: *mut RsvgHandle,
id: *const c_char,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_handle_get_position_sub(
handle: *mut RsvgHandle,
position_data: *mut RsvgPositionData,
id: *const c_char,
) -> gboolean;
pub fn rsvg_handle_get_title(handle: *mut RsvgHandle) -> *const c_char;
pub fn rsvg_handle_has_sub(handle: *mut RsvgHandle, id: *const c_char) -> gboolean;
pub fn rsvg_handle_internal_set_testing(handle: *mut RsvgHandle, testing: gboolean);
pub fn rsvg_handle_read_stream_sync(
handle: *mut RsvgHandle,
stream: *mut gio::GInputStream,
cancellable: *mut gio::GCancellable,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_render_cairo(handle: *mut RsvgHandle, cr: *mut cairo::cairo_t) -> gboolean;
pub fn rsvg_handle_render_cairo_sub(
handle: *mut RsvgHandle,
cr: *mut cairo::cairo_t,
id: *const c_char,
) -> gboolean;
pub fn rsvg_handle_render_document(
handle: *mut RsvgHandle,
cr: *mut cairo::cairo_t,
viewport: *const RsvgRectangle,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_render_element(
handle: *mut RsvgHandle,
cr: *mut cairo::cairo_t,
id: *const c_char,
element_viewport: *const RsvgRectangle,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_render_layer(
handle: *mut RsvgHandle,
cr: *mut cairo::cairo_t,
id: *const c_char,
viewport: *const RsvgRectangle,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_set_base_gfile(handle: *mut RsvgHandle, base_file: *mut gio::GFile);
pub fn rsvg_handle_set_base_uri(handle: *mut RsvgHandle, base_uri: *const c_char);
#[cfg(feature = "v2_59")]
#[cfg_attr(docsrs, doc(cfg(feature = "v2_59")))]
pub fn rsvg_handle_set_cancellable_for_rendering(
handle: *mut RsvgHandle,
cancellable: *mut gio::GCancellable,
);
pub fn rsvg_handle_set_dpi(handle: *mut RsvgHandle, dpi: c_double);
pub fn rsvg_handle_set_dpi_x_y(handle: *mut RsvgHandle, dpi_x: c_double, dpi_y: c_double);
pub fn rsvg_handle_set_size_callback(
handle: *mut RsvgHandle,
size_func: RsvgSizeFunc,
user_data: gpointer,
user_data_destroy: glib::GDestroyNotify,
);
pub fn rsvg_handle_set_stylesheet(
handle: *mut RsvgHandle,
css: *const u8,
css_len: size_t,
error: *mut *mut glib::GError,
) -> gboolean;
pub fn rsvg_handle_write(
handle: *mut RsvgHandle,
buf: *const u8,
count: size_t,
error: *mut *mut glib::GError,
) -> gboolean;
//=========================================================================
// Other functions
//=========================================================================
pub fn rsvg_cleanup();
pub fn rsvg_init();
pub fn rsvg_pixbuf_from_file(
filename: *const c_char,
error: *mut *mut glib::GError,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_pixbuf_from_file_at_max_size(
filename: *const c_char,
max_width: c_int,
max_height: c_int,
error: *mut *mut glib::GError,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_pixbuf_from_file_at_size(
filename: *const c_char,
width: c_int,
height: c_int,
error: *mut *mut glib::GError,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_pixbuf_from_file_at_zoom(
filename: *const c_char,
x_zoom: c_double,
y_zoom: c_double,
error: *mut *mut glib::GError,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_pixbuf_from_file_at_zoom_with_max(
filename: *const c_char,
x_zoom: c_double,
y_zoom: c_double,
max_width: c_int,
max_height: c_int,
error: *mut *mut glib::GError,
) -> *mut gdk_pixbuf::GdkPixbuf;
pub fn rsvg_set_default_dpi(dpi: c_double);
pub fn rsvg_set_default_dpi_x_y(dpi_x: c_double, dpi_y: c_double);
pub fn rsvg_term();
}

View File

@@ -0,0 +1,285 @@
// Generated by gir (https://github.com/gtk-rs/gir @ 88f37d4165a8)
// from ../builddir/rsvg (@ 5bf47e852751)
// from gir-files (@ 6cef10cd64df)
// DO NOT EDIT
#![cfg(unix)]
use librsvg_rebind_sys::*;
use std::env;
use std::error::Error;
use std::ffi::OsString;
use std::mem::{align_of, size_of};
use std::path::Path;
use std::process::{Command, Stdio};
use std::str;
use tempfile::Builder;
static PACKAGES: &[&str] = &["librsvg-2.0"];
#[derive(Clone, Debug)]
struct Compiler {
pub args: Vec<String>,
}
impl Compiler {
pub fn new() -> Result<Self, Box<dyn Error>> {
let mut args = get_var("CC", "cc")?;
args.push("-Wno-deprecated-declarations".to_owned());
// For _Generic
args.push("-std=c11".to_owned());
// For %z support in printf when using MinGW.
args.push("-D__USE_MINGW_ANSI_STDIO".to_owned());
args.extend(get_var("CFLAGS", "")?);
args.extend(get_var("CPPFLAGS", "")?);
args.extend(pkg_config_cflags(PACKAGES)?);
Ok(Self { args })
}
pub fn compile(&self, src: &Path, out: &Path) -> Result<(), Box<dyn Error>> {
let mut cmd = self.to_command();
cmd.arg(src);
cmd.arg("-o");
cmd.arg(out);
let status = cmd.spawn()?.wait()?;
if !status.success() {
return Err(format!("compilation command {cmd:?} failed, {status}").into());
}
Ok(())
}
fn to_command(&self) -> Command {
let mut cmd = Command::new(&self.args[0]);
cmd.args(&self.args[1..]);
cmd
}
}
fn get_var(name: &str, default: &str) -> Result<Vec<String>, Box<dyn Error>> {
match env::var(name) {
Ok(value) => Ok(shell_words::split(&value)?),
Err(env::VarError::NotPresent) => Ok(shell_words::split(default)?),
Err(err) => Err(format!("{name} {err}").into()),
}
}
fn pkg_config_cflags(packages: &[&str]) -> Result<Vec<String>, Box<dyn Error>> {
if packages.is_empty() {
return Ok(Vec::new());
}
let pkg_config = env::var_os("PKG_CONFIG").unwrap_or_else(|| OsString::from("pkg-config"));
let mut cmd = Command::new(pkg_config);
cmd.arg("--cflags");
cmd.args(packages);
cmd.stderr(Stdio::inherit());
let out = cmd.output()?;
if !out.status.success() {
let (status, stdout) = (out.status, String::from_utf8_lossy(&out.stdout));
return Err(format!("command {cmd:?} failed, {status:?}\nstdout: {stdout}").into());
}
let stdout = str::from_utf8(&out.stdout)?;
Ok(shell_words::split(stdout.trim())?)
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
struct Layout {
size: usize,
alignment: usize,
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
struct Results {
/// Number of successfully completed tests.
passed: usize,
/// Total number of failed tests (including those that failed to compile).
failed: usize,
}
impl Results {
fn record_passed(&mut self) {
self.passed += 1;
}
fn record_failed(&mut self) {
self.failed += 1;
}
fn summary(&self) -> String {
format!("{} passed; {} failed", self.passed, self.failed)
}
fn expect_total_success(&self) {
if self.failed == 0 {
println!("OK: {}", self.summary());
} else {
panic!("FAILED: {}", self.summary());
};
}
}
#[test]
fn cross_validate_constants_with_c() {
let mut c_constants: Vec<(String, String)> = Vec::new();
for l in get_c_output("constant").unwrap().lines() {
let (name, value) = l.split_once(';').expect("Missing ';' separator");
c_constants.push((name.to_owned(), value.to_owned()));
}
let mut results = Results::default();
for ((rust_name, rust_value), (c_name, c_value)) in
RUST_CONSTANTS.iter().zip(c_constants.iter())
{
if rust_name != c_name {
results.record_failed();
eprintln!("Name mismatch:\nRust: {rust_name:?}\nC: {c_name:?}");
continue;
}
if rust_value != c_value {
results.record_failed();
eprintln!(
"Constant value mismatch for {rust_name}\nRust: {rust_value:?}\nC: {c_value:?}",
);
continue;
}
results.record_passed();
}
results.expect_total_success();
}
#[test]
fn cross_validate_layout_with_c() {
let mut c_layouts = Vec::new();
for l in get_c_output("layout").unwrap().lines() {
let (name, value) = l.split_once(';').expect("Missing first ';' separator");
let (size, alignment) = value.split_once(';').expect("Missing second ';' separator");
let size = size.parse().expect("Failed to parse size");
let alignment = alignment.parse().expect("Failed to parse alignment");
c_layouts.push((name.to_owned(), Layout { size, alignment }));
}
let mut results = Results::default();
for ((rust_name, rust_layout), (c_name, c_layout)) in RUST_LAYOUTS.iter().zip(c_layouts.iter())
{
if rust_name != c_name {
results.record_failed();
eprintln!("Name mismatch:\nRust: {rust_name:?}\nC: {c_name:?}");
continue;
}
if rust_layout != c_layout {
results.record_failed();
eprintln!("Layout mismatch for {rust_name}\nRust: {rust_layout:?}\nC: {c_layout:?}",);
continue;
}
results.record_passed();
}
results.expect_total_success();
}
fn get_c_output(name: &str) -> Result<String, Box<dyn Error>> {
let tmpdir = Builder::new().prefix("abi").tempdir()?;
let exe = tmpdir.path().join(name);
let c_file = Path::new("tests").join(name).with_extension("c");
let cc = Compiler::new().expect("configured compiler");
cc.compile(&c_file, &exe)?;
let mut cmd = Command::new(exe);
cmd.stderr(Stdio::inherit());
let out = cmd.output()?;
if !out.status.success() {
let (status, stdout) = (out.status, String::from_utf8_lossy(&out.stdout));
return Err(format!("command {cmd:?} failed, {status:?}\nstdout: {stdout}").into());
}
Ok(String::from_utf8(out.stdout)?)
}
const RUST_LAYOUTS: &[(&str, Layout)] = &[
(
"RsvgDimensionData",
Layout {
size: size_of::<RsvgDimensionData>(),
alignment: align_of::<RsvgDimensionData>(),
},
),
(
"RsvgError",
Layout {
size: size_of::<RsvgError>(),
alignment: align_of::<RsvgError>(),
},
),
(
"RsvgHandle",
Layout {
size: size_of::<RsvgHandle>(),
alignment: align_of::<RsvgHandle>(),
},
),
(
"RsvgHandleClass",
Layout {
size: size_of::<RsvgHandleClass>(),
alignment: align_of::<RsvgHandleClass>(),
},
),
(
"RsvgHandleFlags",
Layout {
size: size_of::<RsvgHandleFlags>(),
alignment: align_of::<RsvgHandleFlags>(),
},
),
(
"RsvgLength",
Layout {
size: size_of::<RsvgLength>(),
alignment: align_of::<RsvgLength>(),
},
),
(
"RsvgPositionData",
Layout {
size: size_of::<RsvgPositionData>(),
alignment: align_of::<RsvgPositionData>(),
},
),
(
"RsvgRectangle",
Layout {
size: size_of::<RsvgRectangle>(),
alignment: align_of::<RsvgRectangle>(),
},
),
(
"RsvgUnit",
Layout {
size: size_of::<RsvgUnit>(),
alignment: align_of::<RsvgUnit>(),
},
),
];
const RUST_CONSTANTS: &[(&str, &str)] = &[
("(gint) RSVG_ERROR_FAILED", "0"),
("(guint) RSVG_HANDLE_FLAGS_NONE", "0"),
("(guint) RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA", "2"),
("(guint) RSVG_HANDLE_FLAG_UNLIMITED", "1"),
("(gint) RSVG_UNIT_CH", "9"),
("(gint) RSVG_UNIT_CM", "5"),
("(gint) RSVG_UNIT_EM", "2"),
("(gint) RSVG_UNIT_EX", "3"),
("(gint) RSVG_UNIT_IN", "4"),
("(gint) RSVG_UNIT_MM", "6"),
("(gint) RSVG_UNIT_PC", "8"),
("(gint) RSVG_UNIT_PERCENT", "0"),
("(gint) RSVG_UNIT_PT", "7"),
("(gint) RSVG_UNIT_PX", "1"),
];

View File

@@ -0,0 +1,47 @@
// Generated by gir (https://github.com/gtk-rs/gir @ 88f37d4165a8)
// from ../builddir/rsvg (@ 5bf47e852751)
// from gir-files (@ 6cef10cd64df)
// DO NOT EDIT
#include "manual.h"
#include <stdio.h>
#define PRINT_CONSTANT(CONSTANT_NAME) \
printf("%s;", #CONSTANT_NAME); \
printf(_Generic((CONSTANT_NAME), \
char *: "%s", \
const char *: "%s", \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
short int: "%hd", \
unsigned short int: "%hu", \
int: "%d", \
unsigned int: "%u", \
long: "%ld", \
unsigned long: "%lu", \
long long: "%lld", \
unsigned long long: "%llu", \
float: "%.6f", \
double: "%.6f", \
long double: "%ld"), \
CONSTANT_NAME); \
printf("\n");
int main() {
PRINT_CONSTANT((gint) RSVG_ERROR_FAILED);
PRINT_CONSTANT((guint) RSVG_HANDLE_FLAGS_NONE);
PRINT_CONSTANT((guint) RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA);
PRINT_CONSTANT((guint) RSVG_HANDLE_FLAG_UNLIMITED);
PRINT_CONSTANT((gint) RSVG_UNIT_CH);
PRINT_CONSTANT((gint) RSVG_UNIT_CM);
PRINT_CONSTANT((gint) RSVG_UNIT_EM);
PRINT_CONSTANT((gint) RSVG_UNIT_EX);
PRINT_CONSTANT((gint) RSVG_UNIT_IN);
PRINT_CONSTANT((gint) RSVG_UNIT_MM);
PRINT_CONSTANT((gint) RSVG_UNIT_PC);
PRINT_CONSTANT((gint) RSVG_UNIT_PERCENT);
PRINT_CONSTANT((gint) RSVG_UNIT_PT);
PRINT_CONSTANT((gint) RSVG_UNIT_PX);
return 0;
}

View File

@@ -0,0 +1,21 @@
// Generated by gir (https://github.com/gtk-rs/gir @ 88f37d4165a8)
// from ../builddir/rsvg (@ 5bf47e852751)
// from gir-files (@ 6cef10cd64df)
// DO NOT EDIT
#include "manual.h"
#include <stdalign.h>
#include <stdio.h>
int main() {
printf("%s;%zu;%zu\n", "RsvgDimensionData", sizeof(RsvgDimensionData), alignof(RsvgDimensionData));
printf("%s;%zu;%zu\n", "RsvgError", sizeof(RsvgError), alignof(RsvgError));
printf("%s;%zu;%zu\n", "RsvgHandle", sizeof(RsvgHandle), alignof(RsvgHandle));
printf("%s;%zu;%zu\n", "RsvgHandleClass", sizeof(RsvgHandleClass), alignof(RsvgHandleClass));
printf("%s;%zu;%zu\n", "RsvgHandleFlags", sizeof(RsvgHandleFlags), alignof(RsvgHandleFlags));
printf("%s;%zu;%zu\n", "RsvgLength", sizeof(RsvgLength), alignof(RsvgLength));
printf("%s;%zu;%zu\n", "RsvgPositionData", sizeof(RsvgPositionData), alignof(RsvgPositionData));
printf("%s;%zu;%zu\n", "RsvgRectangle", sizeof(RsvgRectangle), alignof(RsvgRectangle));
printf("%s;%zu;%zu\n", "RsvgUnit", sizeof(RsvgUnit), alignof(RsvgUnit));
return 0;
}

View File

@@ -0,0 +1,3 @@
// Feel free to edit this file, it won't be regenerated by gir generator unless removed.
#include <librsvg/rsvg.h>

18
librsvg-rebind/regen.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh -e
BUILDDIR="../builddir"
set -x
cd "$(dirname "$0")"
if [ -d "../builddir" ]; then
meson setup --reconfigure "$BUILDDIR" ../
else
meson setup "$BUILDDIR" ../
fi
meson compile -C ../builddir
./gir/generator.py --no-fmt --gir-files-directories "$BUILDDIR/rsvg" gir-files/ $@
cargo fmt --all