[librsvg: 11/15] New API function rsvg_handle_get_intrinsic_size_in_pixels()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 11/15] New API function rsvg_handle_get_intrinsic_size_in_pixels()
- Date: Tue, 27 Oct 2020 23:36:50 +0000 (UTC)
commit 33a7c326e63d64dba1eec65ae594ed65d8b5b0cb
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Oct 27 16:51:43 2020 -0600
New API function rsvg_handle_get_intrinsic_size_in_pixels()
doc/rsvg-sections.txt | 1 +
librsvg/c_api.rs | 38 ++++++++++++++++++++++++++
librsvg/lib.rs | 1 +
librsvg/rsvg.h | 60 ++++++++++++++++++++++++++++++++++++++++++
tests/api.c | 49 ++++++++++++++++++++++++++++++++++
tests/fixtures/api/no-size.svg | 1 +
tests/fixtures/api/size.svg | 1 +
7 files changed, 151 insertions(+)
---
diff --git a/doc/rsvg-sections.txt b/doc/rsvg-sections.txt
index ee7b9ed4..c0d8828a 100644
--- a/doc/rsvg-sections.txt
+++ b/doc/rsvg-sections.txt
@@ -70,6 +70,7 @@ RSVG_TYPE_HANDLE_FLAGS
<FILE>rsvg-cairo</FILE>
<TITLE>Using RSVG with cairo</TITLE>
rsvg_handle_get_intrinsic_dimensions
+rsvg_handle_get_intrinsic_size_in_pixels
rsvg_handle_render_document
rsvg_handle_get_geometry_for_layer
rsvg_handle_render_layer
diff --git a/librsvg/c_api.rs b/librsvg/c_api.rs
index 9cbc8dd6..af922a6b 100644
--- a/librsvg/c_api.rs
+++ b/librsvg/c_api.rs
@@ -1060,6 +1060,13 @@ impl CHandle {
Ok(handle.get_intrinsic_dimensions())
}
+ fn get_intrinsic_size_in_pixels(&self) -> Result<Option<(f64, f64)>, RenderingError> {
+ let handle = self.get_handle_ref()?;
+ let inner = self.inner.borrow();
+
+ Ok(handle.get_intrinsic_size_in_pixels(inner.dpi.into()))
+ }
+
fn set_testing(&self, is_testing: bool) {
let mut inner = self.inner.borrow_mut();
inner.is_testing = is_testing;
@@ -1874,6 +1881,37 @@ pub unsafe extern "C" fn rsvg_handle_get_intrinsic_dimensions(
set_out_param(out_has_viewbox, out_viewbox, &r);
}
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_handle_get_intrinsic_size_in_pixels(
+ handle: *const RsvgHandle,
+ out_width: *mut f64,
+ out_height: *mut f64,
+) -> glib_sys::gboolean {
+ rsvg_return_val_if_fail! {
+ rsvg_handle_get_intrinsic_size_in_pixels => false.to_glib();
+
+ is_rsvg_handle(handle),
+ }
+
+ let rhandle = get_rust_handle(handle);
+
+ let dim = rhandle
+ .get_intrinsic_size_in_pixels()
+ .unwrap_or_else(|_| panic!("API called out of order"));
+
+ let (w, h) = dim.unwrap_or((0.0, 0.0));
+
+ if !out_width.is_null() {
+ *out_width = w;
+ }
+
+ if !out_height.is_null() {
+ *out_height = h;
+ }
+
+ dim.is_some().to_glib()
+}
+
#[no_mangle]
pub unsafe extern "C" fn rsvg_handle_render_document(
handle: *const RsvgHandle,
diff --git a/librsvg/lib.rs b/librsvg/lib.rs
index d6beaf21..8f647f8a 100644
--- a/librsvg/lib.rs
+++ b/librsvg/lib.rs
@@ -12,6 +12,7 @@ pub use crate::c_api::{
rsvg_handle_get_geometry_for_element,
rsvg_handle_get_geometry_for_layer,
rsvg_handle_get_intrinsic_dimensions,
+ rsvg_handle_get_intrinsic_size_in_pixels,
rsvg_handle_get_pixbuf_sub,
rsvg_handle_get_position_sub,
rsvg_handle_has_sub,
diff --git a/librsvg/rsvg.h b/librsvg/rsvg.h
index 7bead03c..11b02931 100644
--- a/librsvg/rsvg.h
+++ b/librsvg/rsvg.h
@@ -889,6 +889,66 @@ void rsvg_handle_get_intrinsic_dimensions (RsvgHandle *handle,
gboolean *out_has_viewbox,
RsvgRectangle *out_viewbox);
+/**
+ * rsvg_handle_get_intrinsic_size_in_pixels:
+ * @handle: An #RsvgHandle
+ * @out_width: (out)(optional): Will be set to the computed width
+ * @out_height: (out)(optional): Will be set to the computed height
+ *
+ * Converts an SVG document's intrinsic dimensions to pixels, and returns the result.
+ *
+ * This function is able to extract the size in pixels from an SVG document if the
+ * document has both <literal>width</literal> and <literal>height</literal> attributes
+ * with physical units (px, in, cm, mm, pt, pc) or font-based units (em, ex). For
+ * physical units, the dimensions are normalized to pixels using the dots-per-inch (DPI)
+ * value set previously with rsvg_handle_set_dpi(). For font-based units, this function
+ * uses the computed value of the `font-size` property for the toplevel
+ * <literal><svg></literal> element. In those cases, this function returns %TRUE.
+ *
+ * This function is not able to extract the size in pixels directly from the intrinsic
+ * dimensions of the SVG document if the <literal>width</literal> or
+ * <literal>height</literal> are in percentage units (or if they do not exist, in which
+ * case the SVG spec mandates that they default to 100%), as these require a
+ * <firstterm>viewport</firstterm> to be resolved to a final size. In this case, the
+ * function returns %FALSE.
+ *
+ * For example, the following document fragment has intrinsic dimensions that will resolve
+ * to 20x30 pixels.
+ *
+ * |[
+ * <svg xmlns="http://www.w3.org/2000/svg" width="20" height="30"/>
+ * ]|
+ *
+ * Similarly, if the DPI is set to 96, this document will resolve to 192x288 pixels (i.e. 96*2 x 96*3).
+ *
+ * |[
+ * <svg xmlns="http://www.w3.org/2000/svg" width="2in" height="3in"/>
+ * ]|
+ *
+ * The dimensions of the following documents cannot be resolved to pixels directly, and
+ * this function would return %FALSE for them:
+ *
+ * |[
+ * <!-- Needs a viewport against which to compute the percentages. -->
+ * <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"/>
+ *
+ * <!-- Does not have intrinsic width/height, just a 1:2 aspect ratio which
+ * needs to be fitted within a viewport. -->
+ * <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 200"/>
+ * ]|
+ *
+ *
+ * Returns: %TRUE if the dimensions could be converted directly to pixels; in this case
+ * @out_width and @out_height will be set accordingly. If the dimensions cannot be converted
+ * to pixels, returns %FALSE and puts 0.0 in both @out_width and @out_height.
+ *
+ * Since: 2.52
+ */
+RSVG_API
+gboolean rsvg_handle_get_intrinsic_size_in_pixels (RsvgHandle *handle,
+ gdouble *out_width,
+ gdouble *out_height);
+
/* GIO APIs */
/**
diff --git a/tests/api.c b/tests/api.c
index c344d32b..d4f53b88 100644
--- a/tests/api.c
+++ b/tests/api.c
@@ -968,6 +968,53 @@ get_intrinsic_dimensions (void)
g_object_unref (handle);
}
+static void
+get_intrinsic_size_in_pixels_yes (void)
+{
+ char *filename = get_test_filename ("size.svg");
+ GError *error = NULL;
+ gdouble width, height;
+
+ RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+ g_free (filename);
+
+ g_assert_nonnull (handle);
+ g_assert_no_error (error);
+
+ rsvg_handle_set_dpi (handle, 96.0);
+
+ /* Test optional parameters */
+ g_assert (rsvg_handle_get_intrinsic_size_in_pixels (handle, NULL, NULL));
+
+ /* Test the actual result */
+ g_assert (rsvg_handle_get_intrinsic_size_in_pixels (handle, &width, &height));
+ g_assert_cmpfloat (width, ==, 192.0);
+ g_assert_cmpfloat (height, ==, 288.0);
+
+ g_object_unref (handle);
+}
+
+static void
+get_intrinsic_size_in_pixels_no (void)
+{
+ char *filename = get_test_filename ("no-size.svg");
+ GError *error = NULL;
+ gdouble width, height;
+
+ RsvgHandle *handle = rsvg_handle_new_from_file (filename, &error);
+ g_free (filename);
+
+ g_assert_nonnull (handle);
+ g_assert_no_error (error);
+
+ rsvg_handle_set_dpi (handle, 96.0);
+ g_assert (!rsvg_handle_get_intrinsic_size_in_pixels (handle, &width, &height));
+ g_assert_cmpfloat (width, ==, 0.0);
+ g_assert_cmpfloat (height, ==, 0.0);
+
+ g_object_unref (handle);
+}
+
static void
render_document (void)
{
@@ -1630,6 +1677,8 @@ add_api_tests (void)
g_test_add_func ("/api/can_draw_to_non_image_surface", can_draw_to_non_image_surface);
g_test_add_func ("/api/render_cairo_sub", render_cairo_sub);
g_test_add_func ("/api/get_intrinsic_dimensions", get_intrinsic_dimensions);
+ g_test_add_func ("/api/get_intrinsic_size_in_pixels/yes", get_intrinsic_size_in_pixels_yes);
+ g_test_add_func ("/api/get_intrinsic_size_in_pixels/no", get_intrinsic_size_in_pixels_no);
g_test_add_func ("/api/render_document", render_document);
g_test_add_func ("/api/get_geometry_for_layer", get_geometry_for_layer);
g_test_add_func ("/api/render_layer", render_layer);
diff --git a/tests/fixtures/api/no-size.svg b/tests/fixtures/api/no-size.svg
new file mode 100644
index 00000000..1a45cb32
--- /dev/null
+++ b/tests/fixtures/api/no-size.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"/>
diff --git a/tests/fixtures/api/size.svg b/tests/fixtures/api/size.svg
new file mode 100644
index 00000000..25c1e0bf
--- /dev/null
+++ b/tests/fixtures/api/size.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="2in" height="3in"/>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]