librsvg r1191 - in trunk: . doc



Author: robsta
Date: Thu Nov 27 15:33:04 2008
New Revision: 1191
URL: http://svn.gnome.org/viewvc/librsvg?rev=1191&view=rev

Log:
* doc/rsvg-sections.txt: New API rsvg_handle_get_position_sub(), gets
the offset of an SVG element.
* librsvg.def:
* rsvg-base.c (rsvg_handle_get_position_sub):
* rsvg-dimensions.c (main):
* rsvg.h: ditto.



Modified:
   trunk/ChangeLog
   trunk/doc/rsvg-sections.txt
   trunk/librsvg.def
   trunk/rsvg-base.c
   trunk/rsvg-dimensions.c
   trunk/rsvg.h

Modified: trunk/doc/rsvg-sections.txt
==============================================================================
--- trunk/doc/rsvg-sections.txt	(original)
+++ trunk/doc/rsvg-sections.txt	Thu Nov 27 15:33:04 2008
@@ -24,6 +24,8 @@
 rsvg_handle_get_title
 rsvg_handle_get_desc
 rsvg_handle_get_dimensions
+rsvg_handle_get_dimensions_sub
+rsvg_handle_get_position_sub
 </SECTION>
 
 <SECTION>

Modified: trunk/librsvg.def
==============================================================================
--- trunk/librsvg.def	(original)
+++ trunk/librsvg.def	Thu Nov 27 15:33:04 2008
@@ -16,6 +16,7 @@
 rsvg_handle_set_base_uri
 rsvg_handle_get_dimensions
 rsvg_handle_get_dimensions_sub
+rsvg_handle_get_position_sub
 rsvg_handle_get_title
 rsvg_handle_get_desc
 rsvg_handle_get_metadata

Modified: trunk/rsvg-base.c
==============================================================================
--- trunk/rsvg-base.c	(original)
+++ trunk/rsvg-base.c	Thu Nov 27 15:33:04 2008
@@ -1365,6 +1365,112 @@
     return TRUE;
 }
 
+/**
+ * rsvg_handle_get_position_sub
+ * @handle: A #RsvgHandle
+ * @position_data: 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;
+	RsvgNodeSvg			*root;
+	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);
+
+	/* 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 = (RsvgNode *) rsvg_defs_lookup (handle->priv->defs, id);
+	if (!node) {
+		return FALSE;
+	} else if (node == (RsvgNode *) handle->priv->treebase) {
+		/* Root node. */
+		position_data->x = 0;
+		position_data->y = 0;
+		return TRUE;
+	}
+
+	root = (RsvgNodeSvg *) handle->priv->treebase;
+	if (!root)
+		return FALSE;
+
+	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;
+
+	while (node != NULL) {
+	    draw->drawsub_stack = g_slist_prepend (draw->drawsub_stack, node);
+	    node = node->parent;
+	}
+
+	rsvg_state_push (draw);
+	cairo_save (cr);
+
+	rsvg_node_draw ((RsvgNode *) handle->priv->treebase, draw, 0);
+	bbox.x = ((RsvgCairoRender *) draw->render)->bbox.x;
+	bbox.y = ((RsvgCairoRender *) draw->render)->bbox.y;
+	bbox.w = ((RsvgCairoRender *) draw->render)->bbox.w;
+	bbox.h = ((RsvgCairoRender *) draw->render)->bbox.h;
+
+	cairo_restore (cr);
+	rsvg_state_pop (draw);
+	rsvg_drawing_ctx_free (draw);
+
+	/* Calculate position.
+	 * TODO: figure out what "bbox.w + bbox.x * 2" is or means
+	 * (copied from rsvg_handle_get_dimensions_sub(). - robsta */
+	position_data->x = (int) (_rsvg_css_hand_normalize_length_sub (&root->x, bbox.x, handle->priv->dpi_x,
+									    bbox.w + bbox.x * 2, 12) + 0.5);
+	position_data->y = (int) (_rsvg_css_hand_normalize_length_sub (&root->y, bbox.y, handle->priv->dpi_y, 
+									    bbox.h + bbox.y * 2, 12) + 0.5);
+
+	/* Also calculate dimension for the size callback, while re're at it. */
+	dimension_data.width = (int) (_rsvg_css_hand_normalize_length_sub (&root->w, bbox.w, handle->priv->dpi_x,
+									    bbox.w + bbox.x * 2, 12) + 0.5);
+	dimension_data.height = (int) (_rsvg_css_hand_normalize_length_sub (&root->h, bbox.h, handle->priv->dpi_y, 
+									    bbox.h + bbox.y * 2, 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);
+
+bail:
+	if (cr)
+		cairo_destroy (cr);
+	if (target)
+		cairo_surface_destroy (target);
+
+	return ret;
+}
+
 
 /** 
  * rsvg_set_default_dpi

Modified: trunk/rsvg-dimensions.c
==============================================================================
--- trunk/rsvg-dimensions.c	(original)
+++ trunk/rsvg-dimensions.c	Thu Nov 27 15:33:04 2008
@@ -28,6 +28,7 @@
 	char const		 *file;
 	RsvgHandle		 *handle;
 	RsvgDimensionData	  dimensions;
+	RsvgPositionData	  position;
 	GError			 *error;
 	int			  exit_code;
 	int                       i;
@@ -40,8 +41,11 @@
 
 	rsvg_init ();
 
+	context = NULL;
 	fragment = NULL;
 	filenames = NULL;
+	handle = NULL;
+	error = NULL;
 
 	context = g_option_context_new ("- SVG measuring tool.");
 	g_option_context_add_main_entries (context, options, NULL);
@@ -50,23 +54,23 @@
 	if (argc < 2) {
 		show_help (context);
 		exit_code = EXIT_SUCCESS;
-		goto bail1;
+		goto bail;
 	}
 
 	error = NULL;
 	g_option_context_parse (context, &argc, &argv, &error);
 	if (error) {
 		show_help (context);
-		g_warning (error->message);
+		g_warning ("%s", error->message);
 		exit_code = EXIT_FAILURE;
-		goto bail2;
+		goto bail;
 	}
 
 	/* Invalid / missing args? */
 	if (filenames == NULL) {
 		show_help (context);
 		exit_code = EXIT_FAILURE;
-		goto bail2;
+		goto bail;
 	}
 
 	g_option_context_free (context), context = NULL;
@@ -76,24 +80,27 @@
 		error = NULL;
 		handle = rsvg_handle_new_from_file (file, &error);
 		if (error) {
-			g_warning (error->message);
+			g_warning ("%s", error->message);
 			exit_code = EXIT_FAILURE;
-			goto bail2;
+			goto bail;
 		}
 
 		if (fragment && handle) {
-			gboolean have_fragment;
-			have_fragment = rsvg_handle_get_dimensions_sub (handle,
+			gboolean have_fragment = FALSE;
+			have_fragment |= rsvg_handle_get_dimensions_sub (handle,
 						&dimensions, fragment);
+			have_fragment |= rsvg_handle_get_position_sub (handle,
+						&position, fragment);
 			if (!have_fragment) {
 				g_warning ("%s: fragment `'%s' not found.",
 						file, fragment);
 				exit_code = EXIT_FAILURE;
-				goto bail3;
+				goto bail;
 			}
 
-			printf ("%s, fragment `%s': %dx%d, em=%f, ex=%f\n",
+			printf ("%s, fragment `%s': x=%d, y=%d, %dx%d, em=%f, ex=%f\n",
 					file, fragment,
+					position.x, position.y,
 					dimensions.width, dimensions.height,
 					dimensions.em, dimensions.ex);
 
@@ -105,7 +112,7 @@
 		} else {
 			g_warning ("Could not open file `%s'", file);
 			exit_code = EXIT_FAILURE;
-			goto bail2;
+			goto bail;
 		}
 
 		g_object_unref (G_OBJECT (handle)), handle = NULL;
@@ -113,15 +120,13 @@
 
 	exit_code = EXIT_SUCCESS;
 
-bail3:
+bail:
 	if (handle)
 		g_object_unref (G_OBJECT (handle)), handle = NULL;
-bail2:
 	if (context)
 		g_option_context_free (context), context = NULL;
 	if (error)
 		g_error_free (error), error = NULL;
-bail1:
 	rsvg_term ();
 	return exit_code;
 }

Modified: trunk/rsvg.h
==============================================================================
--- trunk/rsvg.h	(original)
+++ trunk/rsvg.h	Thu Nov 27 15:33:04 2008
@@ -58,6 +58,7 @@
 typedef struct RsvgHandlePrivate RsvgHandlePrivate;
 typedef struct _RsvgHandleClass RsvgHandleClass;
 typedef struct _RsvgDimensionData RsvgDimensionData;
+typedef struct _RsvgPositionData RsvgPositionData;
 
 struct _RsvgHandleClass {
     GObjectClass parent;
@@ -97,6 +98,14 @@
     gdouble ex;
 };
 
+/**
+ * Position of an SVG fragment.
+ **/
+struct _RsvgPositionData {
+    int x;
+    int y;
+};
+
 void rsvg_init (void);
 void rsvg_term (void);
 
@@ -119,6 +128,7 @@
 void rsvg_handle_get_dimensions (RsvgHandle * handle, RsvgDimensionData * dimension_data);
 
 gboolean rsvg_handle_get_dimensions_sub (RsvgHandle * handle, RsvgDimensionData * dimension_data, const char *id);
+gboolean rsvg_handle_get_position_sub (RsvgHandle * handle, RsvgPositionData * position_data, const char *id);
 
 /* Accessibility API */
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]