[librsvg] rsvg-handle.c: Move more RsvgHandle methods here
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] rsvg-handle.c: Move more RsvgHandle methods here
- Date: Wed, 6 Dec 2017 01:51:48 +0000 (UTC)
commit 323cb2798dcf9e9cd42cfaf66e502e113dd81fdb
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Dec 5 19:45:44 2017 -0600
rsvg-handle.c: Move more RsvgHandle methods here
rsvg-base.c | 562 --------------------------------------------------------
rsvg-handle.c | 565 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 565 insertions(+), 562 deletions(-)
---
diff --git a/rsvg-base.c b/rsvg-base.c
index e3edd3f..2841615 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -1111,137 +1111,6 @@ rsvg_SAX_handler_struct_init (void)
}
}
-/* http://www.ietf.org/rfc/rfc2396.txt */
-
-static gboolean
-rsvg_path_is_uri (char const *path)
-{
- char const *p;
-
- if (path == NULL)
- return FALSE;
-
- if (strlen (path) < 4)
- return FALSE;
-
- if ((path[0] < 'a' || path[0] > 'z') &&
- (path[0] < 'A' || path[0] > 'Z')) {
- return FALSE;
- }
-
- for (p = &path[1];
- (*p >= 'a' && *p <= 'z') ||
- (*p >= 'A' && *p <= 'Z') ||
- (*p >= '0' && *p <= '9') ||
- *p == '+' ||
- *p == '-' ||
- *p == '.';
- p++);
-
- if (strlen (p) < 3)
- return FALSE;
-
- return (p[0] == ':' && p[1] == '/' && p[2] == '/');
-}
-
-static gchar *
-rsvg_get_base_uri_from_filename (const gchar * filename)
-{
- gchar *current_dir;
- gchar *absolute_filename;
- gchar *base_uri;
-
- if (g_path_is_absolute (filename))
- return g_filename_to_uri (filename, NULL, NULL);
-
- current_dir = g_get_current_dir ();
- absolute_filename = g_build_filename (current_dir, filename, NULL);
- base_uri = g_filename_to_uri (absolute_filename, NULL, NULL);
- g_free (absolute_filename);
- g_free (current_dir);
-
- return base_uri;
-}
-
-/**
- * rsvg_handle_set_base_uri:
- * @handle: A #RsvgHandle
- * @base_uri: The base uri
- *
- * Set the base URI for this SVG. This can only be called before rsvg_handle_write()
- * has been called.
- *
- * Since: 2.9
- */
-void
-rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
-{
- gchar *uri;
- GFile *file;
-
- g_return_if_fail (handle != NULL);
-
- if (base_uri == NULL)
- return;
-
- if (rsvg_path_is_uri (base_uri))
- uri = g_strdup (base_uri);
- else
- uri = rsvg_get_base_uri_from_filename (base_uri);
-
- file = g_file_new_for_uri (uri ? uri : "data:");
- rsvg_handle_set_base_gfile (handle, file);
- g_object_unref (file);
- g_free (uri);
-}
-
-/**
- * rsvg_handle_set_base_gfile:
- * @handle: a #RsvgHandle
- * @base_file: a #GFile
- *
- * Set the base URI for @handle from @file.
- * Note: This function may only be called before rsvg_handle_write()
- * or rsvg_handle_read_stream_sync() has been called.
- *
- * Since: 2.32
- */
-void
-rsvg_handle_set_base_gfile (RsvgHandle *handle,
- GFile *base_file)
-{
- RsvgHandlePrivate *priv;
-
- g_return_if_fail (RSVG_IS_HANDLE (handle));
- g_return_if_fail (G_IS_FILE (base_file));
-
- priv = handle->priv;
-
- g_object_ref (base_file);
- if (priv->base_gfile)
- g_object_unref (priv->base_gfile);
- priv->base_gfile = base_file;
-
- g_free (priv->base_uri);
- priv->base_uri = g_file_get_uri (base_file);
-}
-
-/**
- * rsvg_handle_get_base_uri:
- * @handle: A #RsvgHandle
- *
- * Gets the base uri for this #RsvgHandle.
- *
- * Returns: the base uri, possibly null
- * Since: 2.8
- */
-const char *
-rsvg_handle_get_base_uri (RsvgHandle * handle)
-{
- g_return_val_if_fail (handle, NULL);
- return handle->priv->base_uri;
-}
-
/**
* rsvg_error_quark:
*
@@ -1356,321 +1225,6 @@ rsvg_drawing_ctx_free (RsvgDrawingCtx * handle)
}
/**
- * rsvg_handle_get_metadata:
- * @handle: An #RsvgHandle
- *
- * Returns the SVG's metadata in UTF-8 or %NULL. You must make a copy
- * of this metadata if you wish to use it after @handle has been freed.
- *
- * Returns: (nullable): The SVG's title
- *
- * Since: 2.9
- *
- * Deprecated: 2.36
- */
-const char *
-rsvg_handle_get_metadata (RsvgHandle * handle)
-{
- g_return_val_if_fail (handle, NULL);
-
- if (handle->priv->metadata)
- return handle->priv->metadata->str;
- else
- return NULL;
-}
-
-/**
- * rsvg_handle_get_title:
- * @handle: An #RsvgHandle
- *
- * Returns the SVG's title in UTF-8 or %NULL. You must make a copy
- * of this title if you wish to use it after @handle has been freed.
- *
- * Returns: (nullable): The SVG's title
- *
- * Since: 2.4
- *
- * Deprecated: 2.36
- */
-const char *
-rsvg_handle_get_title (RsvgHandle * handle)
-{
- g_return_val_if_fail (handle, NULL);
-
- if (handle->priv->title)
- return handle->priv->title->str;
- else
- return NULL;
-}
-
-/**
- * rsvg_handle_get_desc:
- * @handle: An #RsvgHandle
- *
- * Returns the SVG's description in UTF-8 or %NULL. You must make a copy
- * of this description if you wish to use it after @handle has been freed.
- *
- * Returns: (nullable): The SVG's description
- *
- * Since: 2.4
- *
- * Deprecated: 2.36
- */
-const char *
-rsvg_handle_get_desc (RsvgHandle * handle)
-{
- g_return_val_if_fail (handle, NULL);
-
- if (handle->priv->desc)
- return handle->priv->desc->str;
- else
- return NULL;
-}
-
-/**
- * rsvg_handle_get_dimensions:
- * @handle: A #RsvgHandle
- * @dimension_data: (out): A place to store the SVG's size
- *
- * Get the SVG's size. Do not call from within the size_func callback, because an infinite loop will occur.
- *
- * Since: 2.14
- */
-void
-rsvg_handle_get_dimensions (RsvgHandle * handle, RsvgDimensionData * dimension_data)
-{
- /* This function is probably called from the cairo_render functions.
- * To prevent an infinite loop we are saving the state.
- */
- if (!handle->priv->in_loop) {
- handle->priv->in_loop = TRUE;
- rsvg_handle_get_dimensions_sub (handle, dimension_data, NULL);
- handle->priv->in_loop = FALSE;
- } else {
- /* Called within the size function, so return a standard size */
- dimension_data->em = dimension_data->width = 1;
- dimension_data->ex = dimension_data->height = 1;
- }
-}
-
-/**
- * rsvg_handle_get_dimensions_sub:
- * @handle: A #RsvgHandle
- * @dimension_data: (out): A place to store the SVG's size
- * @id: (nullable): An element's id within the SVG, or %NULL to get
- * the dimension of the whole SVG. For example, if you have a layer
- * called "layer1" for that you want to get the dimension, pass
- * "#layer1" as the id.
- *
- * Get the size of a subelement of the SVG file. Do not call from within the size_func callback, because an
infinite loop will occur.
- *
- * Since: 2.22
- */
-gboolean
-rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimension_data, const char *id)
-{
- cairo_t *cr;
- cairo_surface_t *target;
- RsvgDrawingCtx *draw;
- RsvgNode *sself = NULL;
- RsvgBbox bbox;
- RsvgLength root_width, root_height;
- RsvgViewBox root_vbox;
-
- gboolean handle_subelement = TRUE;
-
- g_return_val_if_fail (handle, FALSE);
- g_return_val_if_fail (dimension_data, FALSE);
-
- memset (dimension_data, 0, sizeof (RsvgDimensionData));
-
- if (id && *id) {
- sself = rsvg_defs_lookup (handle->priv->defs, id);
-
- if (rsvg_node_is_same (sself, handle->priv->treebase))
- id = NULL;
- } else {
- sself = handle->priv->treebase;
- }
-
- if (!sself && id)
- return FALSE;
-
- if (!handle->priv->treebase)
- return FALSE;
-
- g_assert (rsvg_node_get_type (handle->priv->treebase) == RSVG_NODE_TYPE_SVG);
-
- bbox.rect.x = bbox.rect.y = 0;
- bbox.rect.width = bbox.rect.height = 1;
-
- rsvg_node_svg_get_size (handle->priv->treebase, &root_width, &root_height);
- root_vbox = rsvg_node_svg_get_view_box (handle->priv->treebase);
-
- if (!id) {
- if ((root_width.unit == LENGTH_UNIT_PERCENT || root_height.unit == LENGTH_UNIT_PERCENT) &&
!root_vbox.active)
- handle_subelement = TRUE;
- else
- handle_subelement = FALSE;
- }
-
- if (handle_subelement == TRUE) {
- target = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
- 1, 1);
- cr = cairo_create (target);
-
- draw = rsvg_cairo_new_drawing_ctx (cr, handle);
-
- if (!draw) {
- cairo_destroy (cr);
- cairo_surface_destroy (target);
-
- return FALSE;
- }
-
- g_assert (sself != NULL);
- rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, sself);
-
- rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
- bbox = RSVG_CAIRO_RENDER (draw->render)->bbox;
-
- rsvg_drawing_ctx_free (draw);
- cairo_destroy (cr);
- cairo_surface_destroy (target);
-
- dimension_data->width = bbox.rect.width;
- dimension_data->height = bbox.rect.height;
- } else {
- bbox.rect.width = root_vbox.rect.width;
- bbox.rect.height = root_vbox.rect.height;
-
- dimension_data->width = (int) (rsvg_length_hand_normalize (&root_width, handle->priv->dpi_x,
- bbox.rect.width, 12) + 0.5);
- dimension_data->height = (int) (rsvg_length_hand_normalize (&root_height, handle->priv->dpi_y,
- bbox.rect.height, 12) + 0.5);
- }
-
- dimension_data->em = dimension_data->width;
- dimension_data->ex = dimension_data->height;
-
- if (handle->priv->size_func)
- (*handle->priv->size_func) (&dimension_data->width, &dimension_data->height,
- handle->priv->user_data);
-
- return TRUE;
-}
-
-/**
- * rsvg_handle_get_position_sub:
- * @handle: A #RsvgHandle
- * @position_data: (out): A place to store the SVG fragment's position.
- * @id: An element's id within the SVG.
- * For example, if you have a layer called "layer1" for that you want to get
- * the position, pass "##layer1" as the id.
- *
- * Get the position of a subelement of the SVG file. Do not call from within
- * the size_func callback, because an infinite loop will occur.
- *
- * Since: 2.22
- */
-gboolean
-rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_data, const char *id)
-{
- RsvgDrawingCtx *draw;
- RsvgNode *node;
- RsvgBbox bbox;
- RsvgDimensionData dimension_data;
- cairo_surface_t *target = NULL;
- cairo_t *cr = NULL;
- gboolean ret = FALSE;
-
- g_return_val_if_fail (handle, FALSE);
- g_return_val_if_fail (position_data, FALSE);
-
- if (!handle->priv->treebase)
- return FALSE;
-
- /* Short-cut when no id is given. */
- if (NULL == id || '\0' == *id) {
- position_data->x = 0;
- position_data->y = 0;
- return TRUE;
- }
-
- memset (position_data, 0, sizeof (*position_data));
- memset (&dimension_data, 0, sizeof (dimension_data));
-
- node = rsvg_defs_lookup (handle->priv->defs, id);
- if (!node) {
- return FALSE;
- } else if (rsvg_node_is_same (node, handle->priv->treebase)) {
- /* Root node. */
- position_data->x = 0;
- position_data->y = 0;
- return TRUE;
- }
-
- target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
- cr = cairo_create (target);
- draw = rsvg_cairo_new_drawing_ctx (cr, handle);
- if (!draw)
- goto bail;
-
- g_assert (node != NULL);
- rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, node);
-
- rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
- bbox = RSVG_CAIRO_RENDER (draw->render)->bbox;
-
- rsvg_drawing_ctx_free (draw);
-
- position_data->x = bbox.rect.x;
- position_data->y = bbox.rect.y;
- dimension_data.width = bbox.rect.width;
- dimension_data.height = bbox.rect.height;
-
- dimension_data.em = dimension_data.width;
- dimension_data.ex = dimension_data.height;
-
- if (handle->priv->size_func)
- (*handle->priv->size_func) (&dimension_data.width, &dimension_data.height,
- handle->priv->user_data);
-
- ret = TRUE;
-
-bail:
- if (cr)
- cairo_destroy (cr);
- if (target)
- cairo_surface_destroy (target);
-
- return ret;
-}
-
-/**
- * rsvg_handle_has_sub:
- * @handle: a #RsvgHandle
- * @id: an element's id within the SVG
- *
- * Checks whether the element @id exists in the SVG document.
- *
- * Returns: %TRUE if @id exists in the SVG document
- *
- * Since: 2.22
- */
-gboolean
-rsvg_handle_has_sub (RsvgHandle * handle,
- const char *id)
-{
- g_return_val_if_fail (handle, FALSE);
-
- if (G_UNLIKELY (!id || !id[0]))
- return FALSE;
-
- return rsvg_defs_lookup (handle->priv->defs, id) != NULL;
-}
-
-/**
* rsvg_set_default_dpi:
* @dpi: Dots Per Inch (aka Pixels Per Inch)
*
@@ -1711,106 +1265,6 @@ rsvg_set_default_dpi_x_y (double dpi_x, double dpi_y)
rsvg_internal_dpi_y = dpi_y;
}
-/**
- * rsvg_handle_set_dpi:
- * @handle: An #RsvgHandle
- * @dpi: Dots Per Inch (aka Pixels Per Inch)
- *
- * Sets the DPI for the outgoing pixbuf. Common values are
- * 75, 90, and 300 DPI. Passing a number <= 0 to @dpi will
- * reset the DPI to whatever the default value happens to be.
- *
- * Since: 2.8
- */
-void
-rsvg_handle_set_dpi (RsvgHandle * handle, double dpi)
-{
- rsvg_handle_set_dpi_x_y (handle, dpi, dpi);
-}
-
-/**
- * rsvg_handle_set_dpi_x_y:
- * @handle: An #RsvgHandle
- * @dpi_x: Dots Per Inch (aka Pixels Per Inch)
- * @dpi_y: Dots Per Inch (aka Pixels Per Inch)
- *
- * Sets the DPI for the outgoing pixbuf. Common values are
- * 75, 90, and 300 DPI. Passing a number <= 0 to #dpi_x or @dpi_y will
- * reset the DPI to whatever the default value happens to be.
- *
- * Since: 2.8
- */
-void
-rsvg_handle_set_dpi_x_y (RsvgHandle * handle, double dpi_x, double dpi_y)
-{
- g_return_if_fail (handle != NULL);
-
- if (dpi_x <= 0.)
- handle->priv->dpi_x = rsvg_internal_dpi_x;
- else
- handle->priv->dpi_x = dpi_x;
-
- if (dpi_y <= 0.)
- handle->priv->dpi_y = rsvg_internal_dpi_y;
- else
- handle->priv->dpi_y = dpi_y;
-}
-
-/**
- * rsvg_handle_set_size_callback:
- * @handle: An #RsvgHandle
- * @size_func: (nullable): A sizing function, or %NULL
- * @user_data: User data to pass to @size_func, or %NULL
- * @user_data_destroy: Destroy function for @user_data, or %NULL
- *
- * Sets the sizing function for the @handle. This function is called right
- * after the size of the image has been loaded. The size of the image is passed
- * in to the function, which may then modify these values to set the real size
- * of the generated pixbuf. If the image has no associated size, then the size
- * arguments are set to -1.
- *
- * Deprecated: Set up a cairo matrix and use rsvg_handle_render_cairo() instead.
- * You can call rsvg_handle_get_dimensions() to figure out the size of your SVG,
- * and then scale it to the desired size via Cairo. For example, the following
- * code renders an SVG at a specified size, scaled proportionally from whatever
- * original size it may have had:
- *
- * |[<!-- language="C" -->
- * void
- * render_scaled_proportionally (RsvgHandle *handle, cairo_t cr, int width, int height)
- * {
- * RsvgDimensionData dimensions;
- * double x_factor, y_factor;
- * double scale_factor;
- *
- * rsvg_handle_get_dimensions (handle, &dimensions);
- *
- * x_factor = (double) width / dimensions.width;
- * y_factor = (double) height / dimensions.height;
- *
- * scale_factor = MIN (x_factor, y_factor);
- *
- * cairo_scale (cr, scale_factor, scale_factor);
- *
- * rsvg_handle_render_cairo (handle, cr);
- * }
- * ]|
- **/
-void
-rsvg_handle_set_size_callback (RsvgHandle * handle,
- RsvgSizeFunc size_func,
- gpointer user_data, GDestroyNotify user_data_destroy)
-{
- g_return_if_fail (handle != NULL);
-
- if (handle->priv->user_data_destroy)
- (*handle->priv->user_data_destroy) (handle->priv->user_data);
-
- handle->priv->size_func = size_func;
- handle->priv->user_data = user_data;
- handle->priv->user_data_destroy = user_data_destroy;
-}
-
#define GZ_MAGIC_0 ((guchar) 0x1f)
#define GZ_MAGIC_1 ((guchar) 0x8b)
@@ -2081,22 +1535,6 @@ rsvg_handle_read_stream_sync (RsvgHandle *handle,
}
/**
- * _rsvg_handle_internal_set_testing:
- * @handle: a #RsvgHandle
- * @testing: Whether to enable testing mode
- *
- * Do not call this function. This is intended for librsvg's internal
- * test suite only.
- **/
-void
-rsvg_handle_internal_set_testing (RsvgHandle *handle, gboolean testing)
-{
- g_return_if_fail (RSVG_IS_HANDLE (handle));
-
- handle->priv->is_testing = testing ? TRUE : FALSE;
-}
-
-/**
* rsvg_init:
*
* Initializes librsvg
diff --git a/rsvg-handle.c b/rsvg-handle.c
index 00a80e6..f0ac86a 100644
--- a/rsvg-handle.c
+++ b/rsvg-handle.c
@@ -112,9 +112,12 @@
*/
#include "config.h"
+#include <string.h>
#include "rsvg-private.h"
#include "rsvg-defs.h"
+#include "rsvg-cairo-render.h"
+#include "rsvg-structure.h"
enum {
PROP_0,
@@ -570,3 +573,565 @@ rsvg_handle_new_from_stream_sync (GInputStream *input_stream,
return handle;
}
+
+/* http://www.ietf.org/rfc/rfc2396.txt */
+
+static gboolean
+path_is_uri (char const *path)
+{
+ char const *p;
+
+ if (path == NULL)
+ return FALSE;
+
+ if (strlen (path) < 4)
+ return FALSE;
+
+ if ((path[0] < 'a' || path[0] > 'z') &&
+ (path[0] < 'A' || path[0] > 'Z')) {
+ return FALSE;
+ }
+
+ for (p = &path[1];
+ (*p >= 'a' && *p <= 'z') ||
+ (*p >= 'A' && *p <= 'Z') ||
+ (*p >= '0' && *p <= '9') ||
+ *p == '+' ||
+ *p == '-' ||
+ *p == '.';
+ p++);
+
+ if (strlen (p) < 3)
+ return FALSE;
+
+ return (p[0] == ':' && p[1] == '/' && p[2] == '/');
+}
+
+static gchar *
+get_base_uri_from_filename (const gchar * filename)
+{
+ gchar *current_dir;
+ gchar *absolute_filename;
+ gchar *base_uri;
+
+ if (g_path_is_absolute (filename))
+ return g_filename_to_uri (filename, NULL, NULL);
+
+ current_dir = g_get_current_dir ();
+ absolute_filename = g_build_filename (current_dir, filename, NULL);
+ base_uri = g_filename_to_uri (absolute_filename, NULL, NULL);
+ g_free (absolute_filename);
+ g_free (current_dir);
+
+ return base_uri;
+}
+
+/**
+ * rsvg_handle_set_base_uri:
+ * @handle: A #RsvgHandle
+ * @base_uri: The base uri
+ *
+ * Set the base URI for this SVG. This can only be called before rsvg_handle_write()
+ * has been called.
+ *
+ * Since: 2.9
+ */
+void
+rsvg_handle_set_base_uri (RsvgHandle * handle, const char *base_uri)
+{
+ gchar *uri;
+ GFile *file;
+
+ g_return_if_fail (handle != NULL);
+
+ if (base_uri == NULL)
+ return;
+
+ if (path_is_uri (base_uri))
+ uri = g_strdup (base_uri);
+ else
+ uri = get_base_uri_from_filename (base_uri);
+
+ file = g_file_new_for_uri (uri ? uri : "data:");
+ rsvg_handle_set_base_gfile (handle, file);
+ g_object_unref (file);
+ g_free (uri);
+}
+
+/**
+ * rsvg_handle_set_base_gfile:
+ * @handle: a #RsvgHandle
+ * @base_file: a #GFile
+ *
+ * Set the base URI for @handle from @file.
+ * Note: This function may only be called before rsvg_handle_write()
+ * or rsvg_handle_read_stream_sync() has been called.
+ *
+ * Since: 2.32
+ */
+void
+rsvg_handle_set_base_gfile (RsvgHandle *handle,
+ GFile *base_file)
+{
+ RsvgHandlePrivate *priv;
+
+ g_return_if_fail (RSVG_IS_HANDLE (handle));
+ g_return_if_fail (G_IS_FILE (base_file));
+
+ priv = handle->priv;
+
+ g_object_ref (base_file);
+ if (priv->base_gfile)
+ g_object_unref (priv->base_gfile);
+ priv->base_gfile = base_file;
+
+ g_free (priv->base_uri);
+ priv->base_uri = g_file_get_uri (base_file);
+}
+
+/**
+ * rsvg_handle_get_base_uri:
+ * @handle: A #RsvgHandle
+ *
+ * Gets the base uri for this #RsvgHandle.
+ *
+ * Returns: the base uri, possibly null
+ * Since: 2.8
+ */
+const char *
+rsvg_handle_get_base_uri (RsvgHandle * handle)
+{
+ g_return_val_if_fail (handle, NULL);
+ return handle->priv->base_uri;
+}
+
+/**
+ * rsvg_handle_get_metadata:
+ * @handle: An #RsvgHandle
+ *
+ * Returns the SVG's metadata in UTF-8 or %NULL. You must make a copy
+ * of this metadata if you wish to use it after @handle has been freed.
+ *
+ * Returns: (nullable): The SVG's title
+ *
+ * Since: 2.9
+ *
+ * Deprecated: 2.36
+ */
+const char *
+rsvg_handle_get_metadata (RsvgHandle * handle)
+{
+ g_return_val_if_fail (handle, NULL);
+
+ if (handle->priv->metadata)
+ return handle->priv->metadata->str;
+ else
+ return NULL;
+}
+
+/**
+ * rsvg_handle_get_title:
+ * @handle: An #RsvgHandle
+ *
+ * Returns the SVG's title in UTF-8 or %NULL. You must make a copy
+ * of this title if you wish to use it after @handle has been freed.
+ *
+ * Returns: (nullable): The SVG's title
+ *
+ * Since: 2.4
+ *
+ * Deprecated: 2.36
+ */
+const char *
+rsvg_handle_get_title (RsvgHandle * handle)
+{
+ g_return_val_if_fail (handle, NULL);
+
+ if (handle->priv->title)
+ return handle->priv->title->str;
+ else
+ return NULL;
+}
+
+/**
+ * rsvg_handle_get_desc:
+ * @handle: An #RsvgHandle
+ *
+ * Returns the SVG's description in UTF-8 or %NULL. You must make a copy
+ * of this description if you wish to use it after @handle has been freed.
+ *
+ * Returns: (nullable): The SVG's description
+ *
+ * Since: 2.4
+ *
+ * Deprecated: 2.36
+ */
+const char *
+rsvg_handle_get_desc (RsvgHandle * handle)
+{
+ g_return_val_if_fail (handle, NULL);
+
+ if (handle->priv->desc)
+ return handle->priv->desc->str;
+ else
+ return NULL;
+}
+
+/**
+ * rsvg_handle_get_dimensions:
+ * @handle: A #RsvgHandle
+ * @dimension_data: (out): A place to store the SVG's size
+ *
+ * Get the SVG's size. Do not call from within the size_func callback, because an infinite loop will occur.
+ *
+ * Since: 2.14
+ */
+void
+rsvg_handle_get_dimensions (RsvgHandle * handle, RsvgDimensionData * dimension_data)
+{
+ /* This function is probably called from the cairo_render functions.
+ * To prevent an infinite loop we are saving the state.
+ */
+ if (!handle->priv->in_loop) {
+ handle->priv->in_loop = TRUE;
+ rsvg_handle_get_dimensions_sub (handle, dimension_data, NULL);
+ handle->priv->in_loop = FALSE;
+ } else {
+ /* Called within the size function, so return a standard size */
+ dimension_data->em = dimension_data->width = 1;
+ dimension_data->ex = dimension_data->height = 1;
+ }
+}
+
+/**
+ * rsvg_handle_get_dimensions_sub:
+ * @handle: A #RsvgHandle
+ * @dimension_data: (out): A place to store the SVG's size
+ * @id: (nullable): An element's id within the SVG, or %NULL to get
+ * the dimension of the whole SVG. For example, if you have a layer
+ * called "layer1" for that you want to get the dimension, pass
+ * "#layer1" as the id.
+ *
+ * Get the size of a subelement of the SVG file. Do not call from within the size_func callback, because an
infinite loop will occur.
+ *
+ * Since: 2.22
+ */
+gboolean
+rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimension_data, const char *id)
+{
+ cairo_t *cr;
+ cairo_surface_t *target;
+ RsvgDrawingCtx *draw;
+ RsvgNode *sself = NULL;
+ RsvgBbox bbox;
+ RsvgLength root_width, root_height;
+ RsvgViewBox root_vbox;
+
+ gboolean handle_subelement = TRUE;
+
+ g_return_val_if_fail (handle, FALSE);
+ g_return_val_if_fail (dimension_data, FALSE);
+
+ memset (dimension_data, 0, sizeof (RsvgDimensionData));
+
+ if (id && *id) {
+ sself = rsvg_defs_lookup (handle->priv->defs, id);
+
+ if (rsvg_node_is_same (sself, handle->priv->treebase))
+ id = NULL;
+ } else {
+ sself = handle->priv->treebase;
+ }
+
+ if (!sself && id)
+ return FALSE;
+
+ if (!handle->priv->treebase)
+ return FALSE;
+
+ g_assert (rsvg_node_get_type (handle->priv->treebase) == RSVG_NODE_TYPE_SVG);
+
+ bbox.rect.x = bbox.rect.y = 0;
+ bbox.rect.width = bbox.rect.height = 1;
+
+ rsvg_node_svg_get_size (handle->priv->treebase, &root_width, &root_height);
+ root_vbox = rsvg_node_svg_get_view_box (handle->priv->treebase);
+
+ if (!id) {
+ if ((root_width.unit == LENGTH_UNIT_PERCENT || root_height.unit == LENGTH_UNIT_PERCENT) &&
!root_vbox.active)
+ handle_subelement = TRUE;
+ else
+ handle_subelement = FALSE;
+ }
+
+ if (handle_subelement == TRUE) {
+ target = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+ 1, 1);
+ cr = cairo_create (target);
+
+ draw = rsvg_cairo_new_drawing_ctx (cr, handle);
+
+ if (!draw) {
+ cairo_destroy (cr);
+ cairo_surface_destroy (target);
+
+ return FALSE;
+ }
+
+ g_assert (sself != NULL);
+ rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, sself);
+
+ rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
+ bbox = RSVG_CAIRO_RENDER (draw->render)->bbox;
+
+ rsvg_drawing_ctx_free (draw);
+ cairo_destroy (cr);
+ cairo_surface_destroy (target);
+
+ dimension_data->width = bbox.rect.width;
+ dimension_data->height = bbox.rect.height;
+ } else {
+ bbox.rect.width = root_vbox.rect.width;
+ bbox.rect.height = root_vbox.rect.height;
+
+ dimension_data->width = (int) (rsvg_length_hand_normalize (&root_width, handle->priv->dpi_x,
+ bbox.rect.width, 12) + 0.5);
+ dimension_data->height = (int) (rsvg_length_hand_normalize (&root_height, handle->priv->dpi_y,
+ bbox.rect.height, 12) + 0.5);
+ }
+
+ dimension_data->em = dimension_data->width;
+ dimension_data->ex = dimension_data->height;
+
+ if (handle->priv->size_func)
+ (*handle->priv->size_func) (&dimension_data->width, &dimension_data->height,
+ handle->priv->user_data);
+
+ return TRUE;
+}
+
+/**
+ * rsvg_handle_get_position_sub:
+ * @handle: A #RsvgHandle
+ * @position_data: (out): A place to store the SVG fragment's position.
+ * @id: An element's id within the SVG.
+ * For example, if you have a layer called "layer1" for that you want to get
+ * the position, pass "##layer1" as the id.
+ *
+ * Get the position of a subelement of the SVG file. Do not call from within
+ * the size_func callback, because an infinite loop will occur.
+ *
+ * Since: 2.22
+ */
+gboolean
+rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_data, const char *id)
+{
+ RsvgDrawingCtx *draw;
+ RsvgNode *node;
+ RsvgBbox bbox;
+ RsvgDimensionData dimension_data;
+ cairo_surface_t *target = NULL;
+ cairo_t *cr = NULL;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (handle, FALSE);
+ g_return_val_if_fail (position_data, FALSE);
+
+ if (!handle->priv->treebase)
+ return FALSE;
+
+ /* Short-cut when no id is given. */
+ if (NULL == id || '\0' == *id) {
+ position_data->x = 0;
+ position_data->y = 0;
+ return TRUE;
+ }
+
+ memset (position_data, 0, sizeof (*position_data));
+ memset (&dimension_data, 0, sizeof (dimension_data));
+
+ node = rsvg_defs_lookup (handle->priv->defs, id);
+ if (!node) {
+ return FALSE;
+ } else if (rsvg_node_is_same (node, handle->priv->treebase)) {
+ /* Root node. */
+ position_data->x = 0;
+ position_data->y = 0;
+ return TRUE;
+ }
+
+ target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
+ cr = cairo_create (target);
+ draw = rsvg_cairo_new_drawing_ctx (cr, handle);
+ if (!draw)
+ goto bail;
+
+ g_assert (node != NULL);
+ rsvg_drawing_ctx_add_node_and_ancestors_to_stack (draw, node);
+
+ rsvg_drawing_ctx_draw_node_from_stack (draw, handle->priv->treebase, 0);
+ bbox = RSVG_CAIRO_RENDER (draw->render)->bbox;
+
+ rsvg_drawing_ctx_free (draw);
+
+ position_data->x = bbox.rect.x;
+ position_data->y = bbox.rect.y;
+ dimension_data.width = bbox.rect.width;
+ dimension_data.height = bbox.rect.height;
+
+ dimension_data.em = dimension_data.width;
+ dimension_data.ex = dimension_data.height;
+
+ if (handle->priv->size_func)
+ (*handle->priv->size_func) (&dimension_data.width, &dimension_data.height,
+ handle->priv->user_data);
+
+ ret = TRUE;
+
+bail:
+ if (cr)
+ cairo_destroy (cr);
+ if (target)
+ cairo_surface_destroy (target);
+
+ return ret;
+}
+
+/**
+ * rsvg_handle_has_sub:
+ * @handle: a #RsvgHandle
+ * @id: an element's id within the SVG
+ *
+ * Checks whether the element @id exists in the SVG document.
+ *
+ * Returns: %TRUE if @id exists in the SVG document
+ *
+ * Since: 2.22
+ */
+gboolean
+rsvg_handle_has_sub (RsvgHandle * handle,
+ const char *id)
+{
+ g_return_val_if_fail (handle, FALSE);
+
+ if (G_UNLIKELY (!id || !id[0]))
+ return FALSE;
+
+ return rsvg_defs_lookup (handle->priv->defs, id) != NULL;
+}
+
+/**
+ * rsvg_handle_set_dpi:
+ * @handle: An #RsvgHandle
+ * @dpi: Dots Per Inch (aka Pixels Per Inch)
+ *
+ * Sets the DPI for the outgoing pixbuf. Common values are
+ * 75, 90, and 300 DPI. Passing a number <= 0 to @dpi will
+ * reset the DPI to whatever the default value happens to be.
+ *
+ * Since: 2.8
+ */
+void
+rsvg_handle_set_dpi (RsvgHandle * handle, double dpi)
+{
+ rsvg_handle_set_dpi_x_y (handle, dpi, dpi);
+}
+
+/**
+ * rsvg_handle_set_dpi_x_y:
+ * @handle: An #RsvgHandle
+ * @dpi_x: Dots Per Inch (aka Pixels Per Inch)
+ * @dpi_y: Dots Per Inch (aka Pixels Per Inch)
+ *
+ * Sets the DPI for the outgoing pixbuf. Common values are
+ * 75, 90, and 300 DPI. Passing a number <= 0 to #dpi_x or @dpi_y will
+ * reset the DPI to whatever the default value happens to be.
+ *
+ * Since: 2.8
+ */
+void
+rsvg_handle_set_dpi_x_y (RsvgHandle * handle, double dpi_x, double dpi_y)
+{
+ g_return_if_fail (handle != NULL);
+
+ if (dpi_x <= 0.)
+ handle->priv->dpi_x = rsvg_internal_dpi_x;
+ else
+ handle->priv->dpi_x = dpi_x;
+
+ if (dpi_y <= 0.)
+ handle->priv->dpi_y = rsvg_internal_dpi_y;
+ else
+ handle->priv->dpi_y = dpi_y;
+}
+
+/**
+ * rsvg_handle_set_size_callback:
+ * @handle: An #RsvgHandle
+ * @size_func: (nullable): A sizing function, or %NULL
+ * @user_data: User data to pass to @size_func, or %NULL
+ * @user_data_destroy: Destroy function for @user_data, or %NULL
+ *
+ * Sets the sizing function for the @handle. This function is called right
+ * after the size of the image has been loaded. The size of the image is passed
+ * in to the function, which may then modify these values to set the real size
+ * of the generated pixbuf. If the image has no associated size, then the size
+ * arguments are set to -1.
+ *
+ * Deprecated: Set up a cairo matrix and use rsvg_handle_render_cairo() instead.
+ * You can call rsvg_handle_get_dimensions() to figure out the size of your SVG,
+ * and then scale it to the desired size via Cairo. For example, the following
+ * code renders an SVG at a specified size, scaled proportionally from whatever
+ * original size it may have had:
+ *
+ * |[<!-- language="C" -->
+ * void
+ * render_scaled_proportionally (RsvgHandle *handle, cairo_t cr, int width, int height)
+ * {
+ * RsvgDimensionData dimensions;
+ * double x_factor, y_factor;
+ * double scale_factor;
+ *
+ * rsvg_handle_get_dimensions (handle, &dimensions);
+ *
+ * x_factor = (double) width / dimensions.width;
+ * y_factor = (double) height / dimensions.height;
+ *
+ * scale_factor = MIN (x_factor, y_factor);
+ *
+ * cairo_scale (cr, scale_factor, scale_factor);
+ *
+ * rsvg_handle_render_cairo (handle, cr);
+ * }
+ * ]|
+ **/
+void
+rsvg_handle_set_size_callback (RsvgHandle * handle,
+ RsvgSizeFunc size_func,
+ gpointer user_data, GDestroyNotify user_data_destroy)
+{
+ g_return_if_fail (handle != NULL);
+
+ if (handle->priv->user_data_destroy)
+ (*handle->priv->user_data_destroy) (handle->priv->user_data);
+
+ handle->priv->size_func = size_func;
+ handle->priv->user_data = user_data;
+ handle->priv->user_data_destroy = user_data_destroy;
+}
+
+/**
+ * _rsvg_handle_internal_set_testing:
+ * @handle: a #RsvgHandle
+ * @testing: Whether to enable testing mode
+ *
+ * Do not call this function. This is intended for librsvg's internal
+ * test suite only.
+ **/
+void
+rsvg_handle_internal_set_testing (RsvgHandle *handle, gboolean testing)
+{
+ g_return_if_fail (RSVG_IS_HANDLE (handle));
+
+ handle->priv->is_testing = testing ? TRUE : FALSE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]