[librsvg] Move the surface-to-pixbuf code to a separate file
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Move the surface-to-pixbuf code to a separate file
- Date: Sat, 12 Jan 2019 01:12:05 +0000 (UTC)
commit adcd3744cd7e2861e9551299efb828e7c06161c9
Author: Federico Mena Quintero <federico gnome org>
Date: Thu Jan 10 19:00:50 2019 -0600
Move the surface-to-pixbuf code to a separate file
Makefile.am | 1 +
rsvg_internals/src/error.rs | 1 +
rsvg_internals/src/handle.rs | 38 ++++-------------------------
rsvg_internals/src/lib.rs | 1 +
rsvg_internals/src/pixbuf_utils.rs | 49 ++++++++++++++++++++++++++++++++++++++
5 files changed, 56 insertions(+), 34 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ce2fe885..d83aaaeb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -97,6 +97,7 @@ RUST_SRC = \
rsvg_internals/src/path_builder.rs \
rsvg_internals/src/path_parser.rs \
rsvg_internals/src/pattern.rs \
+ rsvg_internals/src/pixbuf_utils.rs \
rsvg_internals/src/property_bag.rs \
rsvg_internals/src/property_macros.rs \
rsvg_internals/src/rect.rs \
diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
index 58537172..38064761 100644
--- a/rsvg_internals/src/error.rs
+++ b/rsvg_internals/src/error.rs
@@ -105,6 +105,7 @@ pub enum RenderingError {
InstancingLimit,
InvalidId(DefsLookupErrorKind),
SvgHasNoSize,
+ OutOfMemory,
}
impl From<cairo::Status> for RenderingError {
diff --git a/rsvg_internals/src/handle.rs b/rsvg_internals/src/handle.rs
index e0adf6ee..a8eb0459 100644
--- a/rsvg_internals/src/handle.rs
+++ b/rsvg_internals/src/handle.rs
@@ -8,7 +8,7 @@ use std::slice;
use cairo::{self, ImageSurface, Status};
use cairo_sys;
-use gdk_pixbuf::{Colorspace, Pixbuf, PixbufLoader, PixbufLoaderExt};
+use gdk_pixbuf::{Pixbuf, PixbufLoader, PixbufLoaderExt};
use gdk_pixbuf_sys;
use gio::{self, FileExt};
use gio_sys;
@@ -27,13 +27,9 @@ use error::{set_gerror, DefsLookupErrorKind, LoadingError, RenderingError};
use io;
use load::LoadContext;
use node::{Node, RsvgNode};
-use rect::IRect;
+use pixbuf_utils::pixbuf_from_surface;
use structure::NodeSvg;
-use surface_utils::{
- iterators::Pixels,
- shared_surface::SharedImageSurface,
- shared_surface::SurfaceType,
-};
+use surface_utils::{shared_surface::SharedImageSurface, shared_surface::SurfaceType};
use svg::Svg;
use util::rsvg_g_warning;
@@ -555,33 +551,7 @@ impl Handle {
let surface = SharedImageSurface::new(surface, SurfaceType::SRgb)?;
- let bounds = IRect {
- x0: 0,
- y0: 0,
- x1: dimensions.width,
- y1: dimensions.height,
- };
-
- let pixbuf = Pixbuf::new(
- Colorspace::Rgb,
- true,
- 8,
- dimensions.width,
- dimensions.height,
- );
-
- for (x, y, pixel) in Pixels::new(&surface, bounds) {
- let (r, g, b, a) = if pixel.a == 0 {
- (0, 0, 0, 0)
- } else {
- let pixel = pixel.unpremultiply();
- (pixel.r, pixel.g, pixel.b, pixel.a)
- };
-
- pixbuf.put_pixel(x as i32, y as i32, r, g, b, a);
- }
-
- Ok(pixbuf)
+ pixbuf_from_surface(&surface)
}
fn construct_new_from_gfile_sync(
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index c1c2ff44..ed906bb4 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -116,6 +116,7 @@ mod parsers;
mod path_builder;
mod path_parser;
mod pattern;
+mod pixbuf_utils;
mod property_bag;
mod rect;
mod shapes;
diff --git a/rsvg_internals/src/pixbuf_utils.rs b/rsvg_internals/src/pixbuf_utils.rs
new file mode 100644
index 00000000..a809518a
--- /dev/null
+++ b/rsvg_internals/src/pixbuf_utils.rs
@@ -0,0 +1,49 @@
+use glib::translate::*;
+
+use error::RenderingError;
+use gdk_pixbuf::{Colorspace, Pixbuf};
+use gdk_pixbuf_sys as ffi;
+use rect::IRect;
+use surface_utils::{iterators::Pixels, shared_surface::SharedImageSurface};
+
+// Pixbuf::new() doesn't return out-of-memory errors properly
+// See https://github.com/gtk-rs/gdk-pixbuf/issues/96
+fn pixbuf_new(width: i32, height: i32) -> Result<Pixbuf, RenderingError> {
+ unsafe {
+ let raw_pixbuf =
+ ffi::gdk_pixbuf_new(Colorspace::Rgb.to_glib(), true.to_glib(), 8, width, height);
+
+ if raw_pixbuf.is_null() {
+ return Err(RenderingError::OutOfMemory);
+ }
+
+ Ok(from_glib_full(raw_pixbuf))
+ }
+}
+
+pub fn pixbuf_from_surface(surface: &SharedImageSurface) -> Result<Pixbuf, RenderingError> {
+ let width = surface.width();
+ let height = surface.height();
+
+ let pixbuf = pixbuf_new(width as i32, height as i32)?;
+
+ let bounds = IRect {
+ x0: 0,
+ y0: 0,
+ x1: width,
+ y1: height,
+ };
+
+ for (x, y, pixel) in Pixels::new(&surface, bounds) {
+ let (r, g, b, a) = if pixel.a == 0 {
+ (0, 0, 0, 0)
+ } else {
+ let pixel = pixel.unpremultiply();
+ (pixel.r, pixel.g, pixel.b, pixel.a)
+ };
+
+ pixbuf.put_pixel(x as i32, y as i32, r, g, b, a);
+ }
+
+ Ok(pixbuf)
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]