[dia] [path] new DiaPathRenderer
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] [path] new DiaPathRenderer
- Date: Sun, 14 Oct 2012 13:27:35 +0000 (UTC)
commit 7f576000f12dfa1b749ec48b03cead88f90d43e3
Author: Hans Breuer <hans breuer org>
Date: Sun Oct 14 15:16:06 2012 +0200
[path] new DiaPathRenderer
- might bring "Convert to Path" to a whole new level
- will allow unit testing of DiaObject::draw()
lib/Makefile.am | 2 +
lib/create.h | 7 +-
lib/diapathrenderer.c | 692 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/diapathrenderer.h | 42 +++
lib/libdia.def | 3 +
lib/makefile.msc | 1 +
6 files changed, 745 insertions(+), 2 deletions(-)
---
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f0c8d0b..c2cc383 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -156,6 +156,8 @@ libdia_la_SOURCES = \
diainteractiverenderer.c \
diagdkrenderer.h \
diagdkrenderer.c \
+ diapathrenderer.h \
+ diapathrenderer.c \
diasvgrenderer.h \
diasvgrenderer.c \
dia_svg.h \
diff --git a/lib/create.h b/lib/create.h
index 7278e0f..ad8b01a 100644
--- a/lib/create.h
+++ b/lib/create.h
@@ -16,9 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-/*! \file create.h contains user_data structures for creating the non-trivial
- * standard objects (polylines & polygons).
+/*!
* \defgroup ObjectCreate Creation of standard objects
+ * \brief Helpers for creation of the non-trivial standard objects
+ *
* \ingroup StandardObjects
*
* Typical import plugins translate some vector representation of the import format
@@ -139,6 +140,8 @@ DiaObject *create_standard_image(real xpos, real ypos, real width, real height,
*/
DiaObject *create_standard_group(GList *items);
+DiaObject *create_standard_path_from_object (DiaObject *obj);
+
G_END_DECLS
#endif
diff --git a/lib/diapathrenderer.c b/lib/diapathrenderer.c
new file mode 100644
index 0000000..5488b31
--- /dev/null
+++ b/lib/diapathrenderer.c
@@ -0,0 +1,692 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * diapathrenderer.c -- render _everything_ to a path
+ * Copyright (C) 2012 Hans Breuer <hans breuer org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "config.h"
+
+#include "diapathrenderer.h"
+#include "text.h" /* just for text->color */
+#include "standard-path.h" /* for text_to_path() */
+#include "boundingbox.h"
+
+#include "attributes.h" /* attributes_get_foreground() */
+
+/*!
+ * \brief Renderer which turns everything into a path (or a list thereof)
+ *
+ * The path renderer does not produce any external output by itself. It
+ * stroes it's results only internally in one or more pathes. These are
+ * further processed by e.g. create_standard_path_from_object().
+ *
+ * \extends _DiaRenderer
+ */
+struct _DiaPathRenderer
+{
+ DiaRenderer parent_instance; /*!< inheritance in object oriented C */
+
+ GPtrArray *pathes;
+
+ Color stroke;
+ Color fill;
+};
+
+struct _DiaPathRendererClass
+{
+ DiaRendererClass parent_class; /*!< the base class */
+};
+
+
+G_DEFINE_TYPE (DiaPathRenderer, dia_path_renderer, DIA_TYPE_RENDERER)
+
+/*!
+ * \brief Constructor
+ * Initialize everything which needs something else than 0.
+ */
+static void
+dia_path_renderer_init (DiaPathRenderer *self)
+{
+ self->stroke = attributes_get_foreground ();
+ self->fill = attributes_get_background ();
+}
+/*!
+ * \brief Destructor
+ * If there are still pathes left, deallocate them
+ */
+static void
+dia_path_renderer_finalize (GObject *object)
+{
+ DiaPathRenderer *self = DIA_PATH_RENDERER (object);
+
+ if (self->pathes) {
+ guint i;
+
+ for (i = 0; i < self->pathes->len; ++i) {
+ GArray *path = g_ptr_array_index (self->pathes, self->pathes->len - 1);
+
+ g_array_free (path, TRUE);
+ }
+ g_ptr_array_free (self->pathes, TRUE);
+ self->pathes = NULL;
+ }
+ G_OBJECT_CLASS (dia_path_renderer_parent_class)->finalize (object);
+}
+
+/*!
+ * \brief Deliver the current path
+ * To be advanced if we want to support more than one path, e.g. for multiple
+ * color support.
+ * @param self explicit this pointer
+ * @param stroke line color or NULL
+ * @param fill fill color or NULL
+ * \private \memeberof _DiaPathRenderer
+ */
+static GArray *
+_get_current_path (DiaPathRenderer *self,
+ const Color *stroke,
+ const Color *fill)
+{
+ GArray *path;
+ /* creating a new path for every new color */
+ gboolean new_path = FALSE;
+
+ if (stroke && memcmp (stroke, &self->stroke, sizeof(*stroke)) != 0) {
+ memcpy (&self->stroke, stroke, sizeof(*stroke));
+ new_path = TRUE;
+ }
+ if (fill && memcmp (fill, &self->fill, sizeof(*fill)) != 0) {
+ memcpy (&self->fill, fill, sizeof(*fill));
+ new_path = TRUE;
+ }
+
+ if (!self->pathes || new_path) {
+ self->pathes = g_ptr_array_new ();
+ g_ptr_array_add (self->pathes, g_array_new (FALSE, FALSE, sizeof(BezPoint)));
+ }
+ path = g_ptr_array_index (self->pathes, self->pathes->len - 1);
+ return path;
+}
+/*!
+ * \brief Starting a new rendering run
+ * Could be used to clean the path leftovers from a previous run.
+ * Typical export tenderers flush here.
+ */
+static void
+begin_render (DiaRenderer *self, const Rectangle *update)
+{
+}
+/*!
+ * \brief End of current rendering run
+ * Should not be used to clean the accumulated pathes
+ */
+static void
+end_render(DiaRenderer *self)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+}
+static void
+set_linewidth(DiaRenderer *self, real linewidth)
+{ /* 0 == hairline **/
+}
+static void
+set_linecaps(DiaRenderer *self, LineCaps mode)
+{
+}
+static void
+set_linejoin(DiaRenderer *self, LineJoin mode)
+{
+}
+static void
+set_linestyle(DiaRenderer *self, LineStyle mode)
+{
+}
+static void
+set_dashlength(DiaRenderer *self, real length)
+{ /* dot = 20% of len */
+}
+static void
+set_fillstyle(DiaRenderer *self, FillStyle mode)
+{
+}
+
+/*! Find the last point matching or add a new move-to */
+static void
+_path_append (GArray *points, const Point *pt)
+{
+ const BezPoint *prev = (points->len > 0) ? &g_array_index (points, BezPoint, points->len - 1) : NULL;
+ const Point *last = prev ? (prev->type == BEZ_CURVE_TO ? &prev->p3 : &prev->p1) : NULL;
+
+ if (!last || last->x != pt->x || last->y != pt->y) {
+ BezPoint bp;
+ bp.type = BEZ_MOVE_TO;
+ bp.p1 = *pt;
+ g_array_append_val (points, bp);
+ }
+}
+static void
+_path_moveto (GArray *path, const Point *pt)
+{
+ BezPoint bp;
+ bp.type = BEZ_MOVE_TO;
+ bp.p1 = *pt;
+ g_array_append_val (path, bp);
+}
+static void
+_path_lineto (GArray *path, const Point *pt)
+{
+ BezPoint bp;
+ bp.type = BEZ_LINE_TO;
+ bp.p1 = *pt;
+ g_array_append_val (path, bp);
+}
+/*!
+ * \brief Create an arc segment approximation
+ * Code copied and adapted to our needs from _cairo_arc_segment()
+ */
+static void
+_path_arc_segment (GArray *path,
+ const Point *center,
+ real radius,
+ real angle_A,
+ real angle_B)
+{
+ BezPoint bp;
+ real r_sin_A, r_cos_A;
+ real r_sin_B, r_cos_B;
+ real h;
+
+ r_sin_A = radius * sin (angle_A);
+ r_cos_A = radius * cos (angle_A);
+ r_sin_B = radius * sin (angle_B);
+ r_cos_B = radius * cos (angle_B);
+
+ h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0);
+
+ bp.type = BEZ_CURVE_TO;
+ bp.p1.x = center->x + r_cos_A - h * r_sin_A;
+ bp.p1.y = center->y + r_sin_A + h * r_cos_A,
+ bp.p2.x = center->x + r_cos_B + h * r_sin_B,
+ bp.p2.y = center->y + r_sin_B - h * r_cos_B,
+ bp.p3.x = center->x + r_cos_B;
+ bp.p3.y = center->y + r_sin_B;
+
+ g_array_append_val (path, bp);
+}
+
+static void
+draw_line(DiaRenderer *self,
+ Point *start, Point *end,
+ Color *line_colour)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *points = _get_current_path (renderer, line_colour, NULL);
+
+ _path_append (points, start);
+ _path_lineto (points, end);
+}
+
+static void
+_polyline(DiaRenderer *self,
+ Point *points, int num_points,
+ const Color *stroke, const Color *fill)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ int i;
+ GArray *path = _get_current_path (renderer, stroke, fill);
+
+ g_return_if_fail (num_points > 1);
+
+ if (stroke)
+ _path_append (path, &points[0]);
+ else
+ _path_moveto (path, &points[0]);
+
+ for (i = 1; i < num_points; ++i)
+ _path_lineto (path, &points[i]);
+}
+static void
+draw_polyline(DiaRenderer *self,
+ Point *points, int num_points,
+ Color *line_colour)
+{
+ _polyline (self, points, num_points, line_colour, NULL);
+}
+static void
+draw_polygon(DiaRenderer *self,
+ Point *points, int num_points,
+ Color *line_colour)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, line_colour, NULL);
+
+ /* FIXME: can't be that simple ;) */
+ _polyline (self, points, num_points, line_colour, NULL);
+ _path_lineto (path, &points[0]);
+}
+static void
+fill_polygon(DiaRenderer *self,
+ Point *points, int num_points,
+ Color *color)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, NULL, color);
+
+ _polyline (self, points, num_points, NULL, color);
+ _path_lineto (path, &points[0]);
+}
+static void
+_rect (DiaRenderer *self,
+ Point *ul_corner, Point *lr_corner,
+ const Color *stroke, const Color *fill)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, stroke, fill);
+ int i;
+ real width = lr_corner->x - ul_corner->x;
+ real height = lr_corner->y - ul_corner->y;
+ Point pt = *ul_corner;
+
+ _path_moveto (path, &pt);
+
+ /* 0: top-right, clock-wise */
+ for (i = 0; i < 4; ++i) {
+ BezPoint bp;
+
+ bp.type = BEZ_LINE_TO;
+ bp.p1.x = pt.x + (i < 2 ? width : 0);
+ bp.p1.y = pt.y + (i > 0 && i < 3 ? height : 0);
+ g_array_append_val (path, bp);
+ }
+}
+static void
+draw_rect (DiaRenderer *self,
+ Point *ul_corner, Point *lr_corner,
+ Color *color)
+{
+ _rect (self, ul_corner, lr_corner, color, NULL);
+}
+static void
+fill_rect (DiaRenderer *self,
+ Point *ul_corner, Point *lr_corner,
+ Color *color)
+{
+ _rect (self, ul_corner, lr_corner, NULL, color);
+}
+/*!
+ * \brief Convert an arc to some bezier curve-to
+ * \bug For arcs going through angle 0 the result is wrong,
+ * kind of the opposite of the desired.
+ * \protected \memberof _DiaPathRenderer
+ */
+static void
+_arc (DiaRenderer *self,
+ Point *center,
+ real width, real height,
+ real angle1, real angle2,
+ const Color *stroke, const Color *fill)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, stroke, fill);
+ Point start, end;
+ real radius = sqrt(width * height) / 2.0;
+ real ar1 = (M_PI / 180.0) * angle1;
+ real ar2 = (M_PI / 180.0) * angle2;
+ int i, segs = 3;
+ real ars = - (ar2 - ar1) / segs;
+
+ /* move to start point */
+ start.x = center->x + (width / 2.0) * cos(ar1);
+ start.y = center->y - (height / 2.0) * sin(ar1);
+ end.x = center->x + (width / 2.0) * cos(ar2);
+ end.y = center->y - (height / 2.0) * sin(ar2);
+ /* Dia and Cairo don't agree on arc definitions, so it needs
+ * to be converted, i.e. mirrored at the x axis
+ */
+ ar1 = - ar1;
+ ar2 = - ar2;
+
+ if (stroke) {
+ _path_append (path, &start);
+ for (i = 0; i < segs; ++i, ar1 += ars)
+ _path_arc_segment (path, center, radius, ar1, ar1 + ars);
+ } else {
+ _path_moveto (path, &start);
+ _path_arc_segment (path, center, radius, ar1, ar2);
+ _path_lineto (path, center);
+ _path_lineto (path, &start);
+ }
+}
+static void
+draw_arc (DiaRenderer *self,
+ Point *center,
+ real width, real height,
+ real angle1, real angle2,
+ Color *color)
+{
+ _arc (self, center, width, height, angle1, angle2, color, NULL);
+}
+static void
+fill_arc (DiaRenderer *self,
+ Point *center,
+ real width, real height,
+ real angle1, real angle2,
+ Color *color)
+{
+ _arc (self, center, width, height, angle1, angle2, NULL, color);
+}
+static void
+_ellipse (DiaRenderer *self,
+ Point *center,
+ real width, real height,
+ const Color *stroke, const Color *fill)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, stroke, fill);
+ real w2 = width/2;
+ real h2 = height/2;
+ /* FIXME: just a rough estimation to get started */
+ real dx = w2 * 0.55;
+ real dy = h2 * 0.55;
+ Point pt;
+ int i;
+
+ pt = *center;
+ pt.y -= h2;
+ _path_moveto (path, &pt);
+ for (i = 0; i < 4; ++i) {
+ BezPoint bp;
+
+ /* i=0 is the right-most point, than going clock-wise */
+ pt.x = (i % 2 == 1 ? center->x : (i == 0 ? center->x + w2 : center->x -w2));
+ pt.y = (i % 2 == 0 ? center->y : (i == 1 ? center->y + h2 : center->y - h2));
+ bp.type = BEZ_CURVE_TO;
+ bp.p3 = pt;
+
+ switch (i) {
+ case 0 : /* going right for p1 */
+ bp.p1.x = center->x + dx;
+ bp.p1.y = center->y - h2;
+ bp.p2.x = pt.x;
+ bp.p2.y = pt.y - dy;
+ break;
+ case 1 : /* going down for p1 */
+ bp.p1.x = center->x + w2;
+ bp.p1.y = center->y + dy;
+ bp.p2.x = pt.x + dx;
+ bp.p2.y = pt.y;
+ break;
+ case 2 : /* going left for p1 */
+ bp.p1.x = center->x - dx;
+ bp.p1.y = center->y + h2;
+ bp.p2.x = pt.x;
+ bp.p2.y = pt.y + dy;
+ break;
+ case 3 : /* going up for p1 */
+ bp.p1.x = center->x - w2;
+ bp.p1.y = center->y - dy;
+ bp.p2.x = pt.x - dx;
+ bp.p2.y = pt.y;
+ break;
+ default :
+ g_assert_not_reached ();
+ }
+
+ g_array_append_val (path, bp);
+ }
+}
+static void
+draw_ellipse (DiaRenderer *self,
+ Point *center,
+ real width, real height,
+ Color *color)
+{
+ _ellipse (self, center, width, height, color, NULL);
+}
+static void
+fill_ellipse (DiaRenderer *self,
+ Point *center,
+ real width, real height,
+ Color *color)
+{
+ _ellipse (self, center, width, height, NULL, color);
+}
+static void
+_bezier (DiaRenderer *self,
+ BezPoint *points, int numpoints,
+ const Color *stroke, const Color *fill)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, stroke, fill);
+ int i;
+
+ for (i = 0; i < numpoints; ++i)
+ g_array_append_val (path, points[i]);
+ if (fill)
+ _path_lineto (path, &points[0].p1);
+}
+static void
+draw_bezier (DiaRenderer *self,
+ BezPoint *points,
+ int numpoints,
+ Color *color)
+{
+ _bezier(self, points, numpoints, color, NULL);
+}
+static void
+fill_bezier(DiaRenderer *self,
+ BezPoint *points, /* Last point must be same as first point */
+ int numpoints,
+ Color *color)
+{
+ _bezier(self, points, numpoints, NULL, color);
+}
+/*!
+ * \brief Convert the text object to a scaled path
+ * \memberof _DiaPathRenderer
+ */
+static void
+draw_text (DiaRenderer *self,
+ Text *text)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ GArray *path = _get_current_path (renderer, NULL, &text->color);
+ int n0 = path->len;
+
+ if (!text_is_empty (text)) {
+ Rectangle bz_bb, tx_bb;
+ PolyBBExtras extra = { 0, };
+ real dx, dy, sx, sy;
+ guint i;
+
+ text_to_path (text, path);
+
+ polybezier_bbox (&g_array_index (path, BezPoint, n0), path->len - n0, &extra, TRUE, &bz_bb);
+ text_calc_boundingbox (text, &tx_bb);
+ sx = (tx_bb.right - tx_bb.left) / (bz_bb.right - bz_bb.left);
+ sy = (tx_bb.bottom - tx_bb.top) / (bz_bb.bottom - bz_bb.top);
+ dx = tx_bb.left - bz_bb.left * sx;
+ dy = tx_bb.top - bz_bb.top * sy;
+
+ for (i = n0; i < path->len; ++i) {
+ BezPoint *bp = &g_array_index (path, BezPoint, i);
+
+ bp->p1.x = bp->p1.x * sx + dx;
+ bp->p1.y = bp->p1.y * sy + dy;
+ if (bp->type != BEZ_CURVE_TO)
+ continue;
+ bp->p2.x = bp->p2.x * sx + dx;
+ bp->p2.y = bp->p2.y * sy + dy;
+ bp->p3.x = bp->p3.x * sx + dx;
+ bp->p3.y = bp->p3.y * sy + dy;
+ }
+ }
+}
+
+/*!
+ * \brief Convert the string back to a _Text object and render that
+ * \memberof _DiaPathRenderer
+ */
+static void
+draw_string(DiaRenderer *self,
+ const char *text,
+ Point *pos, Alignment alignment,
+ Color *color)
+{
+ if (text && strlen(text)) {
+ Text *text_obj;
+ /* it could have been so easy without the context switch */
+ text_obj = new_text (text,
+ self->font, self->font_height,
+ pos, color, alignment);
+ draw_text (self, text_obj);
+ text_destroy (text_obj);
+ }
+}
+
+/*!
+ * \brief Render just a cheap emulation ;)
+ *
+ * It might be desirable to convert the given pixels to some vector representation.
+ * If simple and fast enough that code could even live in Dia's repository. For now
+ * just rendering the images bounding box has to be enough.
+ *
+ * \memberof _DiaPathRenderer
+ */
+static void
+draw_image(DiaRenderer *self,
+ Point *point,
+ real width, real height,
+ DiaImage *image)
+{
+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
+ /* warning colors ;) */
+ Color stroke = { 1.0, 0.0, 0.0, 0.75 };
+ Color fill = { 1.0, 1.0, 0.0, 0.5 };
+ GArray *path = _get_current_path (renderer, &stroke, &fill);
+ Point to = *point;
+
+ _path_moveto (path, &to);
+ to.x += width;
+ _path_lineto (path, &to);
+ to.y += height;
+ _path_lineto (path, &to);
+ to.x -= width;
+ _path_lineto (path, &to);
+ to.y -= height;
+ _path_lineto (path, &to);
+ to.x += width; to.y += height;
+ _path_lineto (path, &to);
+}
+
+/*!
+ * \brief _DiaPathRenderer class initialization
+ * Overwrite methods of the base classes here.
+ */
+static void
+dia_path_renderer_class_init (DiaPathRendererClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ DiaRendererClass *renderer_class = DIA_RENDERER_CLASS (klass);
+
+ object_class->finalize = dia_path_renderer_finalize;
+
+ /* renderer members */
+ renderer_class->begin_render = begin_render;
+ renderer_class->end_render = end_render;
+
+ renderer_class->set_linewidth = set_linewidth;
+ renderer_class->set_linecaps = set_linecaps;
+ renderer_class->set_linejoin = set_linejoin;
+ renderer_class->set_linestyle = set_linestyle;
+ renderer_class->set_dashlength = set_dashlength;
+ renderer_class->set_fillstyle = set_fillstyle;
+
+ renderer_class->draw_line = draw_line;
+ renderer_class->fill_polygon = fill_polygon;
+ renderer_class->draw_rect = draw_rect;
+ renderer_class->fill_rect = fill_rect;
+ renderer_class->draw_arc = draw_arc;
+ renderer_class->fill_arc = fill_arc;
+ renderer_class->draw_ellipse = draw_ellipse;
+ renderer_class->fill_ellipse = fill_ellipse;
+
+ renderer_class->draw_string = draw_string;
+ renderer_class->draw_image = draw_image;
+
+ /* medium level functions */
+ renderer_class->draw_rect = draw_rect;
+ renderer_class->draw_polyline = draw_polyline;
+ renderer_class->draw_polygon = draw_polygon;
+
+ renderer_class->draw_bezier = draw_bezier;
+ renderer_class->fill_bezier = fill_bezier;
+ renderer_class->draw_text = draw_text;
+
+}
+
+#include "object.h"
+#include "create.h"
+#include "group.h"
+
+/*!
+ * \brief Convert an object to a _StdPath by rendering it with _DiaPathRenderer
+ *
+ * The result is either a single _SdtPath or a _Group of _Stdpath depending ont
+ * the criteria implemented in _get_current_path() and of course the content of
+ * the given object.
+ */
+DiaObject *
+create_standard_path_from_object (DiaObject *obj)
+{
+ DiaObject *path;
+ DiaRenderer *renderer;
+ DiaPathRenderer *pr;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+
+ renderer = g_object_new (DIA_TYPE_PATH_RENDERER, 0);
+ pr = DIA_PATH_RENDERER (renderer);
+
+ obj->ops->draw (obj, renderer);
+
+ /* messing with internals */
+ if (!pr->pathes) { /* oops? */
+ path = NULL;
+ } else if (pr->pathes->len == 1) {
+ GArray *points = g_ptr_array_index (pr->pathes, 0);
+ path = create_standard_path (points->len, &g_array_index (points, BezPoint, 0));
+ } else {
+ /* create a group of pathes */
+ GList *list = NULL;
+ GArray *points;
+ gsize i;
+
+ for (i = 0; i < pr->pathes->len; ++i) {
+ GArray *points = g_ptr_array_index (pr->pathes, i);
+ DiaObject *obj;
+
+ obj = create_standard_path (points->len, &g_array_index (points, BezPoint, 0));
+ if (obj)
+ list = g_list_append (list, obj);
+ }
+ path = group_create (list);
+ }
+ g_object_unref (renderer);
+
+ return path;
+}
diff --git a/lib/diapathrenderer.h b/lib/diapathrenderer.h
new file mode 100644
index 0000000..16a9c89
--- /dev/null
+++ b/lib/diapathrenderer.h
@@ -0,0 +1,42 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * diapathrenderer.c -- render _everything_ to a path
+ * Copyright (C) 2012, Hans Breuer <Hans Breuer Org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef DIA_PATH_RENDERER_H
+#define DIA_PATH_RENDERER_H
+
+#include "diarenderer.h"
+
+typedef struct _DiaPathRenderer DiaPathRenderer;
+typedef struct _DiaPathRendererClass DiaPathRendererClass;
+
+/*! GObject boiler plate, create runtime information */
+#define DIA_TYPE_PATH_RENDERER (dia_path_renderer_get_type ())
+/*! GObject boiler plate, a safe type cast */
+#define DIA_PATH_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DIA_TYPE_PATH_RENDERER, DiaPathRenderer))
+/*! GObject boiler plate, in C++ this would be the vtable */
+#define DIA_PATH_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DIA_TYPE_PATH_RENDERER, DiaPathRendererClass))
+/*! GObject boiler plate, type check */
+#define DIA_IS_PATH_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DIA_TYPE_PATH_RENDERER))
+/*! GObject boiler plate, get from object to class (vtable) */
+#define DIA_PATH_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DIA_TYPE_PATH_RENDERER, DiaPathRendererClass))
+
+GType dia_path_renderer_get_type (void) G_GNUC_CONST;
+
+#endif
diff --git a/lib/libdia.def b/lib/libdia.def
index 730b89f..44be57c 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -127,6 +127,7 @@ EXPORTS
create_standard_group
create_standard_image
create_standard_path
+ create_standard_path_from_object
create_standard_path_from_text
create_standard_polygon
create_standard_polyline
@@ -296,6 +297,8 @@ EXPORTS
pixbuf_encode_base64
pixbuf_decode_base64
+ dia_path_renderer_get_type
+
dia_interactive_renderer_interface_get_type
dialog_make
diff --git a/lib/makefile.msc b/lib/makefile.msc
index 8548604..81cb5e1 100644
--- a/lib/makefile.msc
+++ b/lib/makefile.msc
@@ -73,6 +73,7 @@ OBJECTS = \
diagdkrenderer.obj \
diainteractiverenderer.obj \
diarenderer.obj \
+ diapathrenderer.obj \
diasvgrenderer.obj \
dynamic_obj.obj \
element.obj \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]