[lasem] <svg:marker> Automatic orientation computation.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [lasem] <svg:marker> Automatic orientation computation.
- Date: Tue, 18 Aug 2009 08:40:19 +0000 (UTC)
commit 63957f66cbac787efe9b41ff75658e22e288e9f4
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Tue Aug 18 10:39:08 2009 +0200
<svg:marker> Automatic orientation computation.
Thanks to librsvg code.
src/lsmsvgmarkerelement.c | 11 +++-
src/lsmsvgview.c | 136 +++++++++++++++++++++++++++++---------------
2 files changed, 98 insertions(+), 49 deletions(-)
---
diff --git a/src/lsmsvgmarkerelement.c b/src/lsmsvgmarkerelement.c
index 5c13b02..829fc18 100644
--- a/src/lsmsvgmarkerelement.c
+++ b/src/lsmsvgmarkerelement.c
@@ -88,8 +88,14 @@ _marker_element_render (LsmSvgElement *self, LsmSvgView *view)
lsm_debug ("[LsmSvgMarkerElement::render] stroke_width scale = %g",
marker->stroke_width);
- lsm_svg_matrix_init_translate (&matrix, -ref_x, -ref_y);
- lsm_svg_matrix_rotate (&matrix, marker->vertex_angle);
+ if (marker->orientation.value.type == LSM_SVG_ANGLE_TYPE_FIXED) {
+ lsm_svg_matrix_init_rotate (&matrix, marker->orientation.value.angle);
+ lsm_debug ("[LsmSvgMarkerElement::render] fixed angle = %g", marker->orientation.value.angle);
+ } else {
+ lsm_svg_matrix_init_rotate (&matrix, marker->vertex_angle);
+ lsm_debug ("[LsmSvgMarkerElement::render] auto angle = %g", marker->vertex_angle);
+ }
+ lsm_svg_matrix_translate (&matrix, -ref_x, -ref_y);
lsm_svg_view_push_matrix (view, &matrix);
lsm_svg_view_push_viewport (view, &viewport, &marker->viewbox.value,
@@ -151,6 +157,7 @@ lsm_svg_marker_element_init (LsmSvgMarkerElement *self)
self->width.length = width_default;
self->height.length = width_default;
self->preserve_aspect_ratio.value = preserve_aspect_ratio_default;
+ self->orientation.value = orientation_default;
}
static void
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index b3635d0..e3e3926 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -800,27 +800,6 @@ _set_color (LsmSvgView *view, LsmSvgViewPaintOperation operation,
}
static void
-render_marker (LsmSvgView *view, LsmSvgMarkerElement *marker,
- double x, double y,
- double stroke_width, double vertex_angle)
-{
- cairo_t *cairo;
-
- if (marker == NULL)
- return;
-
- cairo = view->dom_view.cairo;
-
- cairo_save (cairo);
-
- cairo_translate (cairo, x, y);
-
- lsm_svg_marker_element_render (marker, view,
- stroke_width, vertex_angle);
- cairo_restore (cairo);
-}
-
-static void
paint (LsmSvgView *view)
{
LsmSvgElement *element;
@@ -927,6 +906,12 @@ paint (LsmSvgView *view)
cairo_path_data_t *data;
cairo_path_data_t *next_data;
double stroke_width;
+ double prev_x, prev_y;
+ double x, y;
+ double next_x, next_y;
+ cairo_path_data_type_t type;
+ cairo_path_data_type_t next_type;
+ double angle;
int i;
marker = lsm_svg_document_get_element_by_url (LSM_SVG_DOCUMENT (view->dom_view.document),
@@ -952,42 +937,99 @@ paint (LsmSvgView *view)
if (path->num_data > 0) {
next_data = &path->data[0];
+ next_type = next_data->header.type;
+
+ if (next_type == CAIRO_PATH_CURVE_TO) {
+ next_x = next_data[3].point.x;
+ next_y = next_data[3].point.y;
+ } else {
+ next_x = next_data[1].point.x;
+ next_y = next_data[1].point.y;
+ }
- for (i = 0; i < path->num_data; i += path->data[i].header.length) {
+ for (i = 0; i < path->num_data; i += path->data[i].header.length) {
+ data = next_data;
- data = next_data;
+ prev_x = x;
+ prev_y = y;
+ x = next_x;
+ y = next_y;
+ type = next_type;
- if (i + path->data[i].header.length < path->num_data)
- next_data = &path->data[i + path->data[i].header.length];
- else
- next_data = NULL;
-
- if (data->header.type == CAIRO_PATH_CLOSE_PATH) {
- marker = NULL;
- } else if (next_data == NULL ||
- next_data->header.type == CAIRO_PATH_MOVE_TO) {
- marker = marker_end;
- } else if (data->header.type == CAIRO_PATH_MOVE_TO) {
- marker = marker_start;
+ if (i + path->data[i].header.length < path->num_data) {
+ next_data = &path->data[i + path->data[i].header.length];
+ next_type = next_data->header.type;
+
+ if (next_type == CAIRO_PATH_CURVE_TO) {
+ next_x = next_data[3].point.x;
+ next_y = next_data[3].point.y;
} else {
- marker = marker_mid;
+ next_x = next_data[1].point.x;
+ next_y = next_data[1].point.y;
}
+ } else {
+ next_data = NULL;
+ next_type = CAIRO_PATH_MOVE_TO;
+ next_x = 0.0;
+ next_y = 0.0;
+ }
- if (marker != NULL) {
- double x, y;
+ if (data->header.type == CAIRO_PATH_CLOSE_PATH) {
+ marker = NULL;
+ } else if (next_data == NULL ||
+ next_data->header.type == CAIRO_PATH_MOVE_TO) {
+ marker = marker_end;
+ if (type == CAIRO_PATH_CURVE_TO)
+ angle = atan2 (y - data[2].point.y,
+ x - data[2].point.x);
+ else
+ angle = atan2 (y - prev_y, x - prev_x);
+ } else if (data->header.type == CAIRO_PATH_MOVE_TO) {
+ marker = marker_start;
+ if (next_type == CAIRO_PATH_CURVE_TO)
+ angle = atan2 (data[1].point.y - y,
+ data[1].point.x - x);
+ else
+ angle = atan2 (next_y - y, next_x - x);
+ } else {
+ double xdifin, ydifin, xdifout, ydifout, intot, outtot;
- if (data->header.type == CAIRO_PATH_CURVE_TO) {
- x = data[3].point.x;
- y = data[3].point.y;
- } else {
- x = data[1].point.x;
- y = data[1].point.y;
- }
+ marker = marker_mid;
- render_marker (view, LSM_SVG_MARKER_ELEMENT (marker),
- x, y, stroke_width, 0.0);
+ if (type == CAIRO_PATH_CURVE_TO) {
+ xdifin = x - data[2].point.x;
+ ydifin = y - data[2].point.y;
+ } else {
+ xdifin = x - prev_x;
+ ydifin = y - prev_y;
}
+ if (next_type == CAIRO_PATH_CURVE_TO) {
+ xdifout = data[3].point.x - x;
+ ydifout = data[3].point.y - y;
+ } else {
+ xdifout = next_x - x;
+ ydifout = next_y - y;
+ }
+
+ intot = sqrt (xdifin * xdifin + ydifin * ydifin);
+ outtot = sqrt (xdifout * xdifout + ydifout * ydifout);
+
+ xdifin /= intot;
+ ydifin /= intot;
+ xdifout /= outtot;
+ ydifout /= outtot;
+
+ angle = atan2 ((ydifin + ydifout) / 2, (xdifin + xdifout) / 2);
+ }
+
+ if (marker != NULL) {
+ cairo_save (cairo);
+ cairo_translate (cairo, x, y);
+ lsm_svg_marker_element_render (LSM_SVG_MARKER_ELEMENT (marker), view,
+ stroke_width, angle);
+ cairo_restore (cairo);
}
+ }
cairo_path_destroy (path);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]