dia r3883 - in trunk: lib objects/custom
- From: lclausen svn gnome org
- To: svn-commits-list gnome org
- Subject: dia r3883 - in trunk: lib objects/custom
- Date: Tue, 12 Feb 2008 17:15:01 +0000 (GMT)
Author: lclausen
Date: Tue Feb 12 17:15:00 2008
New Revision: 3883
URL: http://svn.gnome.org/viewvc/dia?rev=3883&view=rev
Log:
Patch from Marcel Toele for subshapes.
Added:
trunk/lib/units.c
trunk/lib/units.h
Modified:
trunk/lib/Makefile.am
trunk/lib/diatypes.h
trunk/lib/geometry.c
trunk/lib/geometry.h
trunk/lib/widgets.c
trunk/lib/widgets.h
trunk/objects/custom/custom_object.c
trunk/objects/custom/shape_info.c
trunk/objects/custom/shape_info.h
Modified: trunk/lib/Makefile.am
==============================================================================
--- trunk/lib/Makefile.am (original)
+++ trunk/lib/Makefile.am Tue Feb 12 17:15:00 2008
@@ -101,6 +101,8 @@
objchange.h \
widgets.c \
widgets.h \
+ units.c \
+ units.h \
dia_image.c \
dia_image.h \
intl.c \
Modified: trunk/lib/diatypes.h
==============================================================================
--- trunk/lib/diatypes.h (original)
+++ trunk/lib/diatypes.h Tue Feb 12 17:15:00 2008
@@ -21,6 +21,8 @@
#ifndef TYPES_H
#define TYPES_H
+#include "units.h"
+
/* In diagramdata.h: */
typedef struct _DiagramData DiagramData;
typedef struct _Layer Layer;
@@ -97,7 +99,6 @@
typedef struct _DiaFontClass DiaFontClass;
/* In geometry.h: */
-typedef struct _DiaUnitDef DiaUnitDef;
typedef struct _Point Point;
typedef struct _Rectangle Rectangle;
typedef struct _IntRectangle IntRectangle;
Modified: trunk/lib/geometry.c
==============================================================================
--- trunk/lib/geometry.c (original)
+++ trunk/lib/geometry.c Tue Feb 12 17:15:00 2008
@@ -28,25 +28,9 @@
#define G_INLINE_FUNC extern
#define G_CAN_INLINE 1
#include "geometry.h"
-#include "object.h"
-
-/* from gnome-libs/libgnome/gnome-paper.c */
-const DiaUnitDef units[] =
-{
- /* XXX does anyone *really* measure paper size in feet? meters? */
-
- /* human name, abreviation, points per unit */
- { "Centimeter", "cm", 28.346457, 2 },
- { "Decimeter", "dm", 283.46457, 3 },
- { "Feet", "ft", 864, 4 },
- { "Inch", "in", 72, 3 },
- { "Meter", "m", 2834.6457, 4 },
- { "Millimeter", "mm", 2.8346457, 2 },
- { "Point", "pt", 1, 2 },
- { "Pica", "pi", 12, 2 },
- { 0 }
-};
+#include "object.h"
+#include "units.h"
void
rectangle_union(Rectangle *r1, const Rectangle *r2)
Modified: trunk/lib/geometry.h
==============================================================================
--- trunk/lib/geometry.h (original)
+++ trunk/lib/geometry.h Tue Feb 12 17:15:00 2008
@@ -66,16 +66,6 @@
G_BEGIN_DECLS
-/** Definitions of miscellaneous units. Note that all sizes used
- * internally are in cm, units should only be used for display purposes.
- */
-struct _DiaUnitDef {
- char* name;
- char* unit;
- float factor;
- int digits; /** Number of digits after the decimal separator */
-};
-extern const DiaUnitDef units[];
/*
Coordinate system used:
Added: trunk/lib/units.c
==============================================================================
--- (empty file)
+++ trunk/lib/units.c Tue Feb 12 17:15:00 2008
@@ -0,0 +1,19 @@
+
+#include "units.h"
+
+/* from gnome-libs/libgnome/gnome-paper.c */
+const DiaUnitDef units[] =
+{
+ /* XXX does anyone *really* measure paper size in feet? meters? */
+
+ /* human name, abreviation, points per unit */
+ { "Centimeter", "cm", 28.346457, 2 },
+ { "Decimeter", "dm", 283.46457, 3 },
+ { "Feet", "ft", 864, 4 },
+ { "Inch", "in", 72, 3 },
+ { "Meter", "m", 2834.6457, 4 },
+ { "Millimeter", "mm", 2.8346457, 2 },
+ { "Point", "pt", 1, 2 },
+ { "Pica", "pi", 12, 2 },
+ { 0 }
+};
Added: trunk/lib/units.h
==============================================================================
--- (empty file)
+++ trunk/lib/units.h Tue Feb 12 17:15:00 2008
@@ -0,0 +1,44 @@
+/* Dia -- an diagram creation/manipulation program
+ * Copyright (C) 1998 Alexander Larsson
+ *
+ * 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 UNITS_H
+#define UNITS_H
+
+#include <config.h>
+
+typedef enum {
+ DIA_UNIT_CENTIMETER,
+ DIA_UNIT_DECIMETER,
+ DIA_UNIT_FEET,
+ DIA_UNIT_INCH,
+ DIA_UNIT_METER,
+ DIA_UNIT_MILLIMETER,
+ DIA_UNIT_POINT,
+ DIA_UNIT_PICA,
+} DiaUnit;
+
+typedef struct _DiaUnitDef DiaUnitDef;
+struct _DiaUnitDef {
+ char* name;
+ char* unit;
+ float factor;
+ int digits; /** Number of digits after the decimal separator */
+};
+
+extern const DiaUnitDef units[];
+
+#endif /* UNITS_H */
Modified: trunk/lib/widgets.c
==============================================================================
--- trunk/lib/widgets.c (original)
+++ trunk/lib/widgets.c Tue Feb 12 17:15:00 2008
@@ -21,6 +21,7 @@
#include "intl.h"
#undef GTK_DISABLE_DEPRECATED /* GtkOptionMenu, ... */
#include "widgets.h"
+#include "units.h"
#include "message.h"
#include "dia_dirs.h"
#include "arrows.h"
Modified: trunk/lib/widgets.h
==============================================================================
--- trunk/lib/widgets.h (original)
+++ trunk/lib/widgets.h Tue Feb 12 17:15:00 2008
@@ -33,7 +33,6 @@
#include <gtk/gtkmenuitem.h>
#include "diatypes.h"
-
#include "font.h"
#include "color.h"
#include "arrows.h"
@@ -169,17 +168,6 @@
typedef struct _DiaUnitSpinner DiaUnitSpinner;
typedef struct _DiaUnitSpinnerClass DiaUnitSpinnerClass;
-typedef enum {
- DIA_UNIT_CENTIMETER,
- DIA_UNIT_DECIMETER,
- DIA_UNIT_FEET,
- DIA_UNIT_INCH,
- DIA_UNIT_METER,
- DIA_UNIT_MILLIMETER,
- DIA_UNIT_POINT,
- DIA_UNIT_PICA,
-} DiaUnit;
-
struct _DiaUnitSpinner {
GtkSpinButton parent;
Modified: trunk/objects/custom/custom_object.c
==============================================================================
--- trunk/objects/custom/custom_object.c (original)
+++ trunk/objects/custom/custom_object.c Tue Feb 12 17:15:00 2008
@@ -4,6 +4,9 @@
* Custom Objects -- objects defined in XML rather than C.
* Copyright (C) 1999 James Henstridge.
*
+ * Non-uniform scaling/subshape support by Marcel Toele.
+ * Modifications (C) 2007 Kern Automatiseringsdiensten BV.
+ *
* 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
@@ -50,10 +53,6 @@
#include "pixmaps/custom.xpm"
-#define DEFAULT_WIDTH 2.0
-#define DEFAULT_HEIGHT 2.0
-#define DEFAULT_BORDER 0.25
-
/* used when resizing to decide which side of the shape to expand/shrink */
typedef enum {
ANCHOR_MIDDLE,
@@ -71,6 +70,17 @@
real xscale, yscale;
real xoffs, yoffs;
+ /* The subscale variables
+ * The old_subscale is used for interactive
+ * (shift-pressed) scaling
+ */
+ real subscale;
+ real old_subscale;
+ /* this is sort of a hack, passing a temporary value
+ using this field, but otherwise
+ subshapes are going to need major code refactoring: */
+ GraphicElementSubShape* current_subshape;
+
ConnectionPoint *connections;
real border_width;
Color border_color;
@@ -111,6 +121,14 @@
ModifierKeys modifiers);
static ObjectChange* custom_move(Custom *custom, Point *to);
static void custom_draw(Custom *custom, DiaRenderer *renderer);
+static void custom_draw_displaylist(GList *display_list, Custom *custom,
+ DiaRenderer *renderer, GArray *arr, GArray *barr, real* cur_line,
+ real* cur_dash, LineCaps* cur_caps, LineJoin* cur_join,
+ LineStyle* cur_style);
+static void custom_draw_element(GraphicElement* el, Custom *custom,
+ DiaRenderer *renderer, GArray *arr, GArray *barr, real* cur_line,
+ real* cur_dash, LineCaps* cur_caps, LineJoin* cur_join,
+ LineStyle* cur_style, Color* fg, Color* bg);
static void custom_update_data(Custom *custom, AnchorShape h, AnchorShape v);
static void custom_reposition_text(Custom *custom, GraphicElementText *text);
static DiaObject *custom_create(Point *startpoint,
@@ -178,6 +196,9 @@
N_("Flip horizontal"), NULL, NULL },
{ "flip_vertical", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE|PROP_FLAG_OPTIONAL,
N_("Flip vertical"), NULL, NULL },
+
+ { "subscale", PROP_TYPE_REAL, PROP_FLAG_OPTIONAL,
+ N_("Scale of the subshapes"), NULL, NULL },
PROP_DESC_END
};
@@ -203,6 +224,9 @@
N_("Flip horizontal"), NULL, NULL },
{ "flip_vertical", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE|PROP_FLAG_OPTIONAL,
N_("Flip vertical"), NULL, NULL },
+
+ { "subscale", PROP_TYPE_REAL, PROP_FLAG_OPTIONAL,
+ N_("Scale of the subshapes"), NULL, NULL },
PROP_DESC_END
};
@@ -216,6 +240,7 @@
offsetof(Custom, line_style), offsetof(Custom, dashlength) },
{ "flip_horizontal", PROP_TYPE_BOOL, offsetof(Custom, flip_h) },
{ "flip_vertical", PROP_TYPE_BOOL, offsetof(Custom, flip_v) },
+ { "subscale", PROP_TYPE_REAL, offsetof(Custom, subscale) },
{ NULL, 0, 0 }
};
@@ -229,6 +254,7 @@
offsetof(Custom, line_style), offsetof(Custom, dashlength) },
{ "flip_horizontal", PROP_TYPE_BOOL, offsetof(Custom, flip_h) },
{ "flip_vertical", PROP_TYPE_BOOL, offsetof(Custom, flip_v) },
+ { "subscale", PROP_TYPE_REAL, offsetof(Custom, subscale) },
{"text",PROP_TYPE_TEXT,offsetof(Custom,text)},
{"text_font",PROP_TYPE_FONT,offsetof(Custom,attrs.font)},
{PROP_STDNAME_TEXT_HEIGHT, PROP_STDTYPE_TEXT_HEIGHT,offsetof(Custom,attrs.height)},
@@ -385,12 +411,105 @@
}
}
+static void
+transform_subshape_coord(Custom *custom, GraphicElementSubShape* subshape,
+ const Point *p1, Point *out)
+{
+ if (subshape->default_scale == 0.0) {
+ ShapeInfo *info = custom->info;
+ real svg_width = info->shape_bounds.right - info->shape_bounds.left;
+ real svg_height = info->shape_bounds.bottom - info->shape_bounds.top;
+
+ subshape->default_scale = info->default_width / svg_width /
+ units[prefs_get_length_unit()].factor;
+ }
+
+ real scale = custom->subscale * subshape->default_scale;
+
+ coord cx = 0.0;
+ coord cy = 0.0;
+
+ real width = 0.0;
+ real height = 0.0;
+
+ real xoffs = custom->xoffs;
+ real yoffs = custom->yoffs;
+
+ /* step 1: calculate boundaries */
+ Rectangle orig_bounds = custom->info->shape_bounds;
+ Rectangle new_bounds;
+
+ /* step 2: undo unkown/funky number magic when flip_h or flip_v is set */
+ if(custom->flip_h) custom->xscale = -custom->xscale;
+ if(custom->flip_v) custom->yscale = -custom->yscale;
+
+ new_bounds.top = orig_bounds.top * custom->yscale;
+ new_bounds.bottom = orig_bounds.bottom * custom->yscale;
+ new_bounds.left = orig_bounds.left * custom->xscale;
+ new_bounds.right = orig_bounds.right * custom->xscale;
+
+ width = new_bounds.right - new_bounds.left;
+ height = new_bounds.bottom - new_bounds.top;
+
+ /* step #3: calculate the new center */
+ if (subshape->h_anchor_method == OFFSET_METHOD_PROPORTIONAL) {
+ /* handle proportional offset in x direction */
+ cx = subshape->center.x * custom->xscale;
+ } else {
+ /* handle fixed offset in x direction */
+ if (subshape->h_anchor_method < 0) {
+ cx = new_bounds.right - ((orig_bounds.right-subshape->center.x) * scale);
+ } else {
+ cx = new_bounds.left + (subshape->center.x * scale);
+ }
+ }
+
+ if (subshape->v_anchor_method == OFFSET_METHOD_PROPORTIONAL) {
+ /* handle proportional offset in y direction */
+ cy = subshape->center.y * custom->yscale;
+ } else {
+ /* handle fixed offset in y direction */
+ if (subshape->v_anchor_method < 0) {
+ cy = new_bounds.bottom - ((orig_bounds.bottom-subshape->center.y) * scale);
+ } else {
+ cy = new_bounds.top + (subshape->center.y * scale);
+ }
+ }
+
+ /* step #4: calculate the new coordinate relative to the calculated center */
+ out->x = cx - ((subshape->center.x - p1->x) * scale);
+ out->y = cy - ((subshape->center.y - p1->y) * scale);
+
+ /* step #5: handle flip_h/flip_v */
+ if (custom->flip_h) {
+ out->x = -out->x + width;
+ cx = -cx + width;
+
+ xoffs -= (new_bounds.right - new_bounds.left);
+ custom->xscale = -custom->xscale; /* undo the damage we've done above */
+ }
+ if (custom->flip_v) {
+ out->y = -out->y + height;
+ cy = -cy + height;
+
+ yoffs -= (new_bounds.bottom - new_bounds.top);
+ custom->yscale = -custom->yscale; /* undo the damage we've done above */
+ }
+
+ /* step #6: finally, translate the coordinate to the correct offset */
+ out->x += xoffs;
+ out->y += yoffs;
+}
static void
transform_coord(Custom *custom, const Point *p1, Point *out)
{
- out->x = p1->x * custom->xscale + custom->xoffs;
- out->y = p1->y * custom->yscale + custom->yoffs;
+ if (custom->current_subshape != NULL) {
+ transform_subshape_coord(custom, custom->current_subshape, p1, out);
+ } else {
+ out->x = p1->x * custom->xscale + custom->xoffs;
+ out->y = p1->y * custom->yscale + custom->yoffs;
+ }
}
static void
@@ -558,6 +677,58 @@
element_update_handles(&custom->element);
}
+static void
+custom_adjust_scale(Custom *custom, Handle *handle,
+ Point *to, ConnectionPoint *cp,
+ HandleMoveReason reason, ModifierKeys modifiers)
+{
+#define IS_MODIFIER_PRESSED(m) ((modifiers&(m)) != 0)
+
+ static int uniform_scale = FALSE;
+ static Point orig_pos;
+
+ float delta_max = 0.0f;
+
+ switch (reason) {
+ case HANDLE_MOVE_USER:
+ if (!uniform_scale) {
+ orig_pos.x = to->x;
+ orig_pos.y = to->y;
+ }
+
+ if (!uniform_scale && IS_MODIFIER_PRESSED(MODIFIER_SHIFT)) {
+ custom->old_subscale = MAX(custom->subscale, 0.0);
+ }
+
+ uniform_scale = IS_MODIFIER_PRESSED(MODIFIER_SHIFT);
+
+ delta_max = (to->x - orig_pos.x);
+
+#ifdef USE_DELTA_MAX
+ /* This may yield some awkard effects for new-comers.
+ * Maybe we should make it a configurable option.
+ */
+ if (ABS(to->y - orig_pos.y) > ABS(delta_max))
+ delta_max = (to->y - orig_pos.y);
+#endif
+
+ if (uniform_scale)
+ custom->subscale =
+ custom->old_subscale + (SUBSCALE_ACCELERATION * delta_max);
+
+ if( custom->subscale < SUBSCALE_MININUM_SCALE )
+ custom->subscale = SUBSCALE_MININUM_SCALE;
+
+#undef IS_MODIFIER_PRESSED
+ break;
+ case HANDLE_MOVE_USER_FINAL:
+ uniform_scale = FALSE;
+ break;
+ default:
+ break;
+ }
+}
+
static ObjectChange*
custom_move_handle(Custom *custom, Handle *handle,
Point *to, ConnectionPoint *cp,
@@ -569,6 +740,12 @@
assert(handle!=NULL);
assert(to!=NULL);
+ switch (reason) {
+ case HANDLE_MOVE_USER:
+ case HANDLE_MOVE_USER_FINAL:
+ custom_adjust_scale(custom, handle, to, cp, reason, modifiers);
+ }
+
element_move_handle(&custom->element, handle->id, to, cp, reason, modifiers);
switch (handle->id) {
@@ -634,11 +811,6 @@
{
DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
static GArray *arr = NULL, *barr = NULL;
- Point p1, p2;
- real coord;
- int i;
- GList *tmp;
- Element *elem;
real cur_line = 1.0, cur_dash = 1.0;
LineCaps cur_caps = LINECAPS_BUTT;
LineJoin cur_join = LINEJOIN_MITER;
@@ -652,8 +824,6 @@
if (!barr)
barr = g_array_new(FALSE, FALSE, sizeof(BezPoint));
- elem = &custom->element;
-
renderer_ops->set_fillstyle(renderer, FILLSTYLE_SOLID);
renderer_ops->set_linewidth(renderer, custom->border_width);
cur_line = custom->border_width;
@@ -662,173 +832,301 @@
renderer_ops->set_linecaps(renderer, cur_caps);
renderer_ops->set_linejoin(renderer, cur_join);
- for (tmp = custom->info->display_list; tmp; tmp = tmp->next) {
+ /*
+ * Because we do not know if any of these values are reused in the loop, we pass
+ * them all by reference.
+ * If anyone does know this, please correct/simplify.
+ */
+ custom_draw_displaylist(custom->info->display_list, custom, renderer, arr, barr,
+ &cur_line, &cur_dash, &cur_caps, &cur_join, &cur_style);
+
+ if (custom->info->has_text) {
+ /*Rectangle tb;
+
+ if (renderer->is_interactive) {
+ transform_rect(custom, &custom->info->text_bounds, &tb);
+ p1.x = tb.left; p1.y = tb.top;
+ p2.x = tb.right; p2.y = tb.bottom;
+ renderer_ops->draw_rect(renderer, &p1, &p2, &custom->border_color);
+ }*/
+ text_draw(custom->text, renderer);
+ }
+}
+
+static void
+custom_draw_displaylist(GList *display_list, Custom *custom, DiaRenderer *renderer,
+ GArray *arr, GArray *barr, real* cur_line, real* cur_dash,
+ LineCaps* cur_caps, LineJoin* cur_join, LineStyle* cur_style)
+{
+ GList *tmp;
+ for (tmp = display_list; tmp; tmp = tmp->next) {
GraphicElement *el = tmp->data;
Color fg, bg;
- if (el->any.s.line_width != cur_line) {
- cur_line = el->any.s.line_width;
- renderer_ops->set_linewidth(renderer,
- custom->border_width*cur_line);
- }
- if ((el->any.s.linecap == DIA_SVG_LINECAPS_DEFAULT && cur_caps != LINECAPS_BUTT) ||
- el->any.s.linecap != cur_caps) {
- cur_caps = (el->any.s.linecap!=DIA_SVG_LINECAPS_DEFAULT) ?
- el->any.s.linecap : LINECAPS_BUTT;
- renderer_ops->set_linecaps(renderer, cur_caps);
- }
- if ((el->any.s.linejoin==DIA_SVG_LINEJOIN_DEFAULT && cur_join!=LINEJOIN_MITER) ||
- el->any.s.linejoin != cur_join) {
- cur_join = (el->any.s.linejoin!=DIA_SVG_LINEJOIN_DEFAULT) ?
- el->any.s.linejoin : LINEJOIN_MITER;
- renderer_ops->set_linejoin(renderer, cur_join);
- }
- if ((el->any.s.linestyle == DIA_SVG_LINESTYLE_DEFAULT &&
- cur_style != custom->line_style) ||
- el->any.s.linestyle != cur_style) {
- cur_style = (el->any.s.linestyle!=DIA_SVG_LINESTYLE_DEFAULT) ?
- el->any.s.linestyle : custom->line_style;
- renderer_ops->set_linestyle(renderer, cur_style);
- }
- if (el->any.s.dashlength != cur_dash) {
- cur_dash = el->any.s.dashlength;
- renderer_ops->set_dashlength(renderer,
- custom->dashlength*cur_dash);
- }
+ /*
+ * Because we do not know if any of these values are reused in the loop,
+ * we pass them all by reference.
+ * If anyone does know this, please correct/simplify.
+ */
+ custom_draw_element( el, custom, renderer, arr, barr, cur_line, cur_dash,
+ cur_caps, cur_join, cur_style, &fg, &bg );
+ }
+}
+
+static void
+custom_draw_element(GraphicElement* el, Custom *custom, DiaRenderer *renderer,
+ GArray *arr, GArray *barr, real* cur_line, real* cur_dash,
+ LineCaps* cur_caps, LineJoin* cur_join, LineStyle* cur_style,
+ Color* fg, Color* bg)
+{
+ DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
+ Point p1, p2;
+ real coord;
+ int i;
+
+ if (el->any.s.line_width != (*cur_line)) {
+ (*cur_line) = el->any.s.line_width;
+ renderer_ops->set_linewidth(renderer,
+ custom->border_width*(*cur_line));
+ }
+ if ((el->any.s.linecap == DIA_SVG_LINECAPS_DEFAULT && (*cur_caps) != LINECAPS_BUTT) ||
+ el->any.s.linecap != (*cur_caps)) {
+ (*cur_caps) = (el->any.s.linecap!=DIA_SVG_LINECAPS_DEFAULT) ?
+ el->any.s.linecap : LINECAPS_BUTT;
+ renderer_ops->set_linecaps(renderer, (*cur_caps));
+ }
+ if ((el->any.s.linejoin==DIA_SVG_LINEJOIN_DEFAULT && (*cur_join)!=LINEJOIN_MITER) ||
+ el->any.s.linejoin != (*cur_join)) {
+ (*cur_join) = (el->any.s.linejoin!=DIA_SVG_LINEJOIN_DEFAULT) ?
+ el->any.s.linejoin : LINEJOIN_MITER;
+ renderer_ops->set_linejoin(renderer, (*cur_join));
+ }
+ if ((el->any.s.linestyle == DIA_SVG_LINESTYLE_DEFAULT &&
+ (*cur_style) != custom->line_style) || el->any.s.linestyle != (*cur_style)) {
+ (*cur_style) = (el->any.s.linestyle!=DIA_SVG_LINESTYLE_DEFAULT) ?
+ el->any.s.linestyle : custom->line_style;
+ renderer_ops->set_linestyle(renderer, (*cur_style));
+ }
+ if (el->any.s.dashlength != (*cur_dash)) {
+ (*cur_dash) = el->any.s.dashlength;
+ renderer_ops->set_dashlength(renderer,
+ custom->dashlength*(*cur_dash));
+ }
- cur_line = el->any.s.line_width;
- get_colour(custom, &fg, el->any.s.stroke);
- get_colour(custom, &bg, el->any.s.fill);
- switch (el->type) {
- case GE_LINE:
- transform_coord(custom, &el->line.p1, &p1);
- transform_coord(custom, &el->line.p2, &p2);
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_line(renderer, &p1, &p2, &fg);
- break;
- case GE_POLYLINE:
- g_array_set_size(arr, el->polyline.npoints);
- for (i = 0; i < el->polyline.npoints; i++)
- transform_coord(custom, &el->polyline.points[i],
+ (*cur_line) = el->any.s.line_width;
+ get_colour(custom, fg, el->any.s.stroke);
+ get_colour(custom, bg, el->any.s.fill);
+ switch (el->type) {
+ case GE_LINE:
+ transform_coord(custom, &el->line.p1, &p1);
+ transform_coord(custom, &el->line.p2, &p2);
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_line(renderer, &p1, &p2, fg);
+ break;
+ case GE_POLYLINE:
+ g_array_set_size(arr, el->polyline.npoints);
+ for (i = 0; i < el->polyline.npoints; i++)
+ transform_coord(custom, &el->polyline.points[i],
&g_array_index(arr, Point, i));
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_polyline(renderer,
- (Point *)arr->data, el->polyline.npoints,
- &fg);
- break;
- case GE_POLYGON:
- g_array_set_size(arr, el->polygon.npoints);
- for (i = 0; i < el->polygon.npoints; i++)
- transform_coord(custom, &el->polygon.points[i],
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_polyline(renderer,
+ (Point *)arr->data, el->polyline.npoints,
+ fg);
+ break;
+ case GE_POLYGON:
+ g_array_set_size(arr, el->polygon.npoints);
+ for (i = 0; i < el->polygon.npoints; i++)
+ transform_coord(custom, &el->polygon.points[i],
&g_array_index(arr, Point, i));
- if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
- renderer_ops->fill_polygon(renderer,
+ if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
+ renderer_ops->fill_polygon(renderer,
(Point *)arr->data, el->polygon.npoints,
- &bg);
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_polygon(renderer,
+ bg);
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_polygon(renderer,
(Point *)arr->data, el->polygon.npoints,
- &fg);
- break;
- case GE_RECT:
- transform_coord(custom, &el->rect.corner1, &p1);
- transform_coord(custom, &el->rect.corner2, &p2);
- if (p1.x > p2.x) {
- coord = p1.x;
- p1.x = p2.x;
- p2.x = coord;
- }
- if (p1.y > p2.y) {
- coord = p1.y;
- p1.y = p2.y;
- p2.y = coord;
- }
- if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
- renderer_ops->fill_rect(renderer, &p1, &p2, &bg);
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_rect(renderer, &p1, &p2, &fg);
- break;
- case GE_TEXT:
- custom_reposition_text(custom, &el->text);
- text_draw(el->text.object, renderer);
- text_set_position(el->text.object, &el->text.anchor);
- break;
- case GE_ELLIPSE:
- transform_coord(custom, &el->ellipse.center, &p1);
- if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
- renderer_ops->fill_ellipse(renderer, &p1,
+ fg);
+ break;
+ case GE_RECT:
+ transform_coord(custom, &el->rect.corner1, &p1);
+ transform_coord(custom, &el->rect.corner2, &p2);
+ if (p1.x > p2.x) {
+ coord = p1.x;
+ p1.x = p2.x;
+ p2.x = coord;
+ }
+ if (p1.y > p2.y) {
+ coord = p1.y;
+ p1.y = p2.y;
+ p2.y = coord;
+ }
+ if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
+ renderer_ops->fill_rect(renderer, &p1, &p2, bg);
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_rect(renderer, &p1, &p2, fg);
+ break;
+ case GE_TEXT:
+ custom_reposition_text(custom, &el->text);
+ text_draw(el->text.object, renderer);
+ text_set_position(el->text.object, &el->text.anchor);
+ break;
+ case GE_ELLIPSE:
+ transform_coord(custom, &el->ellipse.center, &p1);
+ if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
+ renderer_ops->fill_ellipse(renderer, &p1,
el->ellipse.width * fabs(custom->xscale),
el->ellipse.height * fabs(custom->yscale),
- &bg);
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_ellipse(renderer, &p1,
+ bg);
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_ellipse(renderer, &p1,
el->ellipse.width * fabs(custom->xscale),
el->ellipse.height * fabs(custom->yscale),
- &fg);
- break;
- case GE_IMAGE:
- transform_coord(custom, &el->image.topleft, &p1);
- renderer_ops->draw_image(renderer, &p1,
+ fg);
+ break;
+ case GE_IMAGE:
+ transform_coord(custom, &el->image.topleft, &p1);
+ renderer_ops->draw_image(renderer, &p1,
el->image.width * fabs(custom->xscale),
el->image.height * fabs(custom->yscale),
el->image.image);
- break;
- case GE_PATH:
- g_array_set_size(barr, el->path.npoints);
- for (i = 0; i < el->path.npoints; i++)
- switch (g_array_index(barr,BezPoint,i).type=el->path.points[i].type) {
- case BEZ_CURVE_TO:
- transform_coord(custom, &el->path.points[i].p3,
- &g_array_index(barr, BezPoint, i).p3);
- transform_coord(custom, &el->path.points[i].p2,
- &g_array_index(barr, BezPoint, i).p2);
- case BEZ_MOVE_TO:
- case BEZ_LINE_TO:
- transform_coord(custom, &el->path.points[i].p1,
- &g_array_index(barr, BezPoint, i).p1);
- }
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_bezier(renderer, (BezPoint *)barr->data,
- el->path.npoints, &fg);
- break;
- case GE_SHAPE:
- g_array_set_size(barr, el->path.npoints);
- for (i = 0; i < el->path.npoints; i++)
- switch (g_array_index(barr,BezPoint,i).type=el->path.points[i].type) {
- case BEZ_CURVE_TO:
- transform_coord(custom, &el->path.points[i].p3,
+ break;
+ case GE_PATH:
+ g_array_set_size(barr, el->path.npoints);
+ for (i = 0; i < el->path.npoints; i++)
+ switch (g_array_index(barr,BezPoint,i).type=el->path.points[i].type) {
+ case BEZ_CURVE_TO:
+ transform_coord(custom, &el->path.points[i].p3,
+ &g_array_index(barr, BezPoint, i).p3);
+ transform_coord(custom, &el->path.points[i].p2,
+ &g_array_index(barr, BezPoint, i).p2);
+ case BEZ_MOVE_TO:
+ case BEZ_LINE_TO:
+ transform_coord(custom, &el->path.points[i].p1,
+ &g_array_index(barr, BezPoint, i).p1);
+ }
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_bezier(renderer, (BezPoint *)barr->data,
+ el->path.npoints, fg);
+ break;
+ case GE_SHAPE:
+ g_array_set_size(barr, el->path.npoints);
+ for (i = 0; i < el->path.npoints; i++)
+ switch (g_array_index(barr,BezPoint,i).type=el->path.points[i].type) {
+ case BEZ_CURVE_TO:
+ transform_coord(custom, &el->path.points[i].p3,
&g_array_index(barr, BezPoint, i).p3);
- transform_coord(custom, &el->path.points[i].p2,
+ transform_coord(custom, &el->path.points[i].p2,
&g_array_index(barr, BezPoint, i).p2);
- case BEZ_MOVE_TO:
- case BEZ_LINE_TO:
- transform_coord(custom, &el->path.points[i].p1,
- &g_array_index(barr, BezPoint, i).p1);
- }
- if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
- renderer_ops->fill_bezier(renderer, (BezPoint *)barr->data,
- el->path.npoints, &bg);
- if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
- renderer_ops->draw_bezier(renderer, (BezPoint *)barr->data,
- el->path.npoints, &fg);
- break;
+ case BEZ_MOVE_TO:
+ case BEZ_LINE_TO:
+ transform_coord(custom, &el->path.points[i].p1,
+ &g_array_index(barr, BezPoint, i).p1);
}
+ if (custom->show_background && el->any.s.fill != DIA_SVG_COLOUR_NONE)
+ renderer_ops->fill_bezier(renderer, (BezPoint *)barr->data,
+ el->path.npoints, bg);
+ if (el->any.s.stroke != DIA_SVG_COLOUR_NONE)
+ renderer_ops->draw_bezier(renderer, (BezPoint *)barr->data,
+ el->path.npoints, fg);
+ break;
+ case GE_SUBSHAPE:
+ {
+ GraphicElementSubShape* subshape = (GraphicElementSubShape*)el;
+
+ custom->current_subshape = subshape;
+ custom_draw_displaylist(subshape->display_list, custom, renderer, arr, barr, cur_line, cur_dash, cur_caps, cur_join, cur_style);
+ custom->current_subshape = NULL;
+ }
+ break;
}
+}
- if (custom->info->has_text) {
- /*Rectangle tb;
+static void
+assert_boundaries(Custom *custom)
+{
+ Element *elem = &custom->element;
+ ShapeInfo *info = custom->info;
+
+ int i = 0;
+ GList *tmp;
+
+ real min_width = 0.0;
+ real min_height = 0.0;
+ real r = 0.0;
+
+ /* undo unkown/funky number magic when flip_h or flip_v is set */
+ if (custom->flip_h) custom->xscale = -custom->xscale;
+ if (custom->flip_v) custom->yscale = -custom->yscale;
+
+ /* calculate the minimum width and height required for all subshapes */
+ for (tmp = info->subshapes; tmp != NULL; tmp = tmp->next, i++) {
+ GraphicElementSubShape *subshape = tmp->data;
- if (renderer->is_interactive) {
- transform_rect(custom, &custom->info->text_bounds, &tb);
- p1.x = tb.left; p1.y = tb.top;
- p2.x = tb.right; p2.y = tb.bottom;
- renderer_ops->draw_rect(renderer, &p1, &p2, &custom->border_color);
- }*/
- text_draw(custom->text, renderer);
+ real parent_shape_orig_width = info->shape_bounds.right - info->shape_bounds.left;
+ real parent_shape_orig_height = info->shape_bounds.bottom - info->shape_bounds.top;
+
+ real scale = custom->subscale * subshape->default_scale;
+ real width = (2*subshape->half_width) * scale;
+ real height = (2*subshape->half_height) * scale;
+
+ if (subshape->h_anchor_method == OFFSET_METHOD_PROPORTIONAL) {
+ /* handle proportional anchor in x direction */
+ real prop_min_width = subshape->center.x / parent_shape_orig_width;
+ real scaled_half_width = subshape->half_width * scale;
+
+ if (prop_min_width > 0.5)
+ prop_min_width = 1.0 - prop_min_width;
+
+ r = prop_min_width * parent_shape_orig_width*custom->xscale;
+
+ if (scaled_half_width > r)
+ width = (scaled_half_width / prop_min_width)-0.01;
+
+ } else {
+ /* handle fixed anchor in x direction */
+ if (subshape->h_anchor_method > 0)
+ width = (subshape->center.x + subshape->half_width) * scale;
+ else
+ width = (parent_shape_orig_width - subshape->center.x + subshape->half_width) * scale;
+ }
+
+ if (subshape->v_anchor_method == OFFSET_METHOD_PROPORTIONAL) {
+ /* handle proportional anchor in y direction */
+ real prop_min_height = subshape->center.y / parent_shape_orig_height;
+ real scaled_half_height = subshape->half_height * scale;
+
+ if (prop_min_height > 0.5)
+ prop_min_height = 1.0 - prop_min_height;
+
+ r = prop_min_height * parent_shape_orig_height*custom->yscale;
+
+ if (scaled_half_height > r)
+ height = (scaled_half_height / prop_min_height)-0.01;
+
+ } else {
+ /* handle fixed anchor in y direction */
+ if (subshape->v_anchor_method > 0)
+ height = (subshape->center.y + subshape->half_height) * scale;
+ else if(subshape->v_anchor_method < 0)
+ height = (parent_shape_orig_height - subshape->center.y + subshape->half_height) * scale;
+ }
+
+ if (width > min_width)
+ min_width = width;
+ if (height > min_height)
+ min_height = height;
}
+
+ if (elem->width < min_width)
+ elem->width = min_width;
+ if (elem->height < min_height)
+ elem->height = min_height;
+
+ /* redo unkown/funky number magic when flip_h or flip_v is set */
+ if (custom->flip_h) custom->xscale = -custom->xscale;
+ if (custom->flip_v) custom->yscale = -custom->yscale;
}
-
static void
custom_update_data(Custom *custom, AnchorShape horiz, AnchorShape vert)
{
@@ -849,7 +1147,9 @@
bottom_right.x += elem->width;
center.y += elem->height/2;
bottom_right.y += elem->height;
-
+
+ assert_boundaries(custom);
+
/* update the translation coefficients first ... */
custom->xscale = elem->width / (info->shape_bounds.right -
info->shape_bounds.left);
@@ -1233,10 +1533,17 @@
obj->ops = &custom_ops;
elem->corner = *startpoint;
- elem->width = DEFAULT_WIDTH;
- elem->height = DEFAULT_HEIGHT;
+
+ elem->width = shape_info_get_default_width(info) /
+ units[prefs_get_length_unit()].factor;
+ elem->height = shape_info_get_default_height(info) /
+ units[prefs_get_length_unit()].factor;
custom->info = info;
+
+ custom->old_subscale = 1.0;
+ custom->subscale = 1.0;
+ custom->current_subshape = NULL;
custom->border_width = attributes_get_default_linewidth();
custom->border_color = attributes_get_foreground();
@@ -1329,6 +1636,10 @@
newcustom->flip_h = custom->flip_h;
newcustom->flip_v = custom->flip_v;
+ newcustom->current_subshape = custom->current_subshape;
+ newcustom->old_subscale = custom->old_subscale;
+ newcustom->subscale = custom->subscale;
+
if (custom->info->has_text) {
newcustom->text = text_copy(custom->text);
text_get_attributes(newcustom->text,&newcustom->attrs);
@@ -1368,6 +1679,7 @@
object_load_props(obj,obj_node);
custom_update_data(custom, ANCHOR_MIDDLE, ANCHOR_MIDDLE);
+ custom->old_subscale = custom->subscale;
}
return obj;
}
Modified: trunk/objects/custom/shape_info.c
==============================================================================
--- trunk/objects/custom/shape_info.c (original)
+++ trunk/objects/custom/shape_info.c Tue Feb 12 17:15:00 2008
@@ -4,6 +4,9 @@
* Custom Objects -- objects defined in XML rather than C.
* Copyright (C) 1999 James Henstridge.
*
+ * Non-uniform scaling/subshape support by Marcel Toele.
+ * Modifications (C) 2007 Kern Automatiseringsdiensten BV.
+ *
* 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
@@ -34,10 +37,13 @@
#include "message.h"
#include "intl.h"
+#include "units.h"
+
#define FONT_HEIGHT_DEFAULT 1
#define TEXT_ALIGNMENT_DEFAULT ALIGN_CENTER
static ShapeInfo *load_shape_info(const gchar *filename, ShapeInfo *preload);
+static void update_bounds(ShapeInfo *info);
static GHashTable *name_to_info = NULL;
@@ -122,6 +128,23 @@
}
}
+real
+shape_info_get_default_width(ShapeInfo *info)
+{
+ if (info->default_width == 0.0)
+ info->default_width = DEFAULT_WIDTH * units[prefs_get_length_unit()].factor;
+
+ return( info->default_width );
+}
+
+real
+shape_info_get_default_height(ShapeInfo *info)
+{
+ if (info->default_height == 0.0)
+ info->default_height = DEFAULT_HEIGHT * units[prefs_get_length_unit()].factor;
+
+ return( info->default_height );
+}
static void
parse_path(ShapeInfo *info, const char *path_str, DiaSvgStyle *s, const char* filename)
@@ -166,6 +189,23 @@
g_array_free (points, TRUE);
}
+static gboolean
+is_subshape(xmlElement* elt)
+{
+ gboolean res = FALSE;
+
+ if (xmlHasProp(elt, "subshape")) {
+ gchar* value = xmlGetProp(elt, "subshape");
+
+ if (!strcmp(value, "true"))
+ res = TRUE;
+
+ xmlFree(value);
+ }
+
+ return res;
+}
+
static void
parse_svg_node(ShapeInfo *info, xmlNodePtr node, xmlNsPtr svg_ns,
DiaSvgStyle *style, const gchar *filename)
@@ -412,8 +452,72 @@
xmlFree(str);
}
} else if (!xmlStrcmp(node->name, (const xmlChar *)"g")) {
+ if (!is_subshape((xmlElement*)node)) {
/* add elements from the group element */
- parse_svg_node(info, node, svg_ns, &s, filename);
+ parse_svg_node(info, node, svg_ns, &s, filename);
+ } else {
+ /* add elements from the group element, but make it a subshape */
+ GraphicElementSubShape *subshape = g_new0(GraphicElementSubShape, 1);
+ ShapeInfo* tmpinfo = g_new0(ShapeInfo, 1);
+ DiaSvgStyle tmp_s = {
+ 1.0, DIA_SVG_COLOUR_FOREGROUND,
+ DIA_SVG_COLOUR_NONE,
+ DIA_SVG_LINECAPS_DEFAULT,
+ DIA_SVG_LINEJOIN_DEFAULT,
+ DIA_SVG_LINESTYLE_DEFAULT, 1.0
+ };
+ xmlAttrPtr v_anchor_attr = xmlGetProp(node,"v_anchor");
+ xmlAttrPtr h_anchor_attr = xmlGetProp(node,"h_anchor");
+
+ parse_svg_node(tmpinfo, node, svg_ns, &tmp_s, filename);
+
+ tmpinfo->shape_bounds.top = DBL_MAX;
+ tmpinfo->shape_bounds.left = DBL_MAX;
+ tmpinfo->shape_bounds.bottom = -DBL_MAX;
+ tmpinfo->shape_bounds.right = -DBL_MAX;
+
+ update_bounds( tmpinfo );
+ update_bounds( info );
+
+ subshape->half_width = (tmpinfo->shape_bounds.right-tmpinfo->shape_bounds.left) / 2.0;
+ subshape->half_height = (tmpinfo->shape_bounds.bottom-tmpinfo->shape_bounds.top) / 2.0;
+ subshape->center.x = tmpinfo->shape_bounds.left + subshape->half_width;
+ subshape->center.y = tmpinfo->shape_bounds.top + subshape->half_height;
+
+ subshape->type = GE_SUBSHAPE;
+ subshape->display_list = tmpinfo->display_list;
+ subshape->v_anchor_method = OFFSET_METHOD_FIXED;
+ subshape->h_anchor_method = OFFSET_METHOD_FIXED;
+ subshape->default_scale = 0.0;
+
+ if (!v_anchor_attr || !strcmp(v_anchor_attr,"fixed.top"))
+ subshape->v_anchor_method = OFFSET_METHOD_FIXED;
+ else if (v_anchor_attr && !strcmp(v_anchor_attr,"fixed.bottom"))
+ subshape->v_anchor_method = -OFFSET_METHOD_FIXED;
+ else if (v_anchor_attr && !strcmp(v_anchor_attr,"proportional"))
+ subshape->v_anchor_method = OFFSET_METHOD_PROPORTIONAL;
+ else
+ fprintf( stderr, "illegal v_anchor `%s', defaulting to fixed.top\n",
+ v_anchor_attr );
+
+ if (!h_anchor_attr || !strcmp(h_anchor_attr,"fixed.left"))
+ subshape->h_anchor_method = OFFSET_METHOD_FIXED;
+ else if (h_anchor_attr && !strcmp(h_anchor_attr,"fixed.right"))
+ subshape->h_anchor_method = -OFFSET_METHOD_FIXED;
+ else if (h_anchor_attr && !strcmp(h_anchor_attr,"proportional"))
+ subshape->h_anchor_method = OFFSET_METHOD_PROPORTIONAL;
+ else
+ fprintf( stderr, "illegal h_anchor `%s', defaulting to fixed.left\n",
+ h_anchor_attr );
+
+ info->subshapes = g_list_append(info->subshapes, subshape);
+
+ /* gfree( tmpinfo );*/
+ xmlFree(v_anchor_attr);
+ xmlFree(h_anchor_attr);
+
+ el = (GraphicElementSubShape *)subshape;
+ }
}
if (el) {
el->any.s = s;
@@ -497,6 +601,17 @@
break;
}
}
+
+ {
+ real width = info->shape_bounds.right-info->shape_bounds.left;
+ real height = info->shape_bounds.bottom-info->shape_bounds.top;
+
+ if (info->default_width > 0.0 && info->default_height == 0.0) {
+ info->default_height = (info->default_width / width) * height;
+ } else if (info->default_height > 0.0 && info->default_width == 0.0) {
+ info->default_width = (info->default_height / height) * width;
+ }
+ }
}
static ShapeInfo *
@@ -546,6 +661,8 @@
info->shape_bounds.bottom = -DBL_MAX;
info->shape_bounds.right = -DBL_MAX;
info->aspect_type = SHAPE_ASPECT_FREE;
+ info->default_width = 0.0;
+ info->default_height = 0.0;
info->main_cp = -1;
i = 0;
@@ -556,7 +673,7 @@
tmp = (gchar *) xmlNodeGetContent(node);
if (preload) {
if (strcmp (tmp, info->name) != 0)
- g_warning ("Shape(preoad) '%s' can't change name '%s'", info->name, tmp);
+ g_warning ("Shape(preload) '%s' can't change name '%s'", info->name, tmp);
/* the key name is already used as key in name_to_info */
} else {
g_free(info->name);
@@ -680,6 +797,35 @@
}
xmlFree(tmp);
}
+ } else if (node->ns == shape_ns && (!xmlStrcmp(node->name, (const xmlChar *)"default-width") || !xmlStrcmp(node->name, (const xmlChar *)"default-height"))) {
+
+ int j = 0;
+ DiaUnitDef ud;
+
+ gdouble val = 0.0;
+
+ int unit_ssize = 0;
+ int ssize = 0;
+ tmp = (gchar *) xmlNodeGetContent(node);
+ ssize = strlen(tmp);
+
+ val = g_ascii_strtod(tmp, NULL);
+
+ for (j = 0, ud = units[i]; ud.name; ud = units[++j]) {
+ unit_ssize = strlen(ud.unit);
+ if (ssize > unit_ssize && !strcmp(tmp+(ssize-unit_ssize), ud.unit)) {
+ val *= ud.factor;
+ break;
+ }
+ }
+
+ if (!xmlStrcmp(node->name, (const xmlChar *)"default-width")) {
+ info->default_width = val;
+ } else {
+ info->default_height = val;
+ }
+
+ xmlFree(tmp);
} else if (node->ns == svg_ns && !xmlStrcmp(node->name, (const xmlChar *)"svg")) {
DiaSvgStyle s = {
1.0, DIA_SVG_COLOUR_FOREGROUND, DIA_SVG_COLOUR_NONE,
Modified: trunk/objects/custom/shape_info.h
==============================================================================
--- trunk/objects/custom/shape_info.h (original)
+++ trunk/objects/custom/shape_info.h Tue Feb 12 17:15:00 2008
@@ -4,6 +4,9 @@
* Custom Objects -- objects defined in XML rather than C.
* Copyright (C) 1999 James Henstridge.
*
+ * Non-uniform scaling/subshape support by Marcel Toele.
+ * Modifications (C) 2007 Kern Automatiseringsdiensten BV.
+ *
* 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
@@ -39,7 +42,8 @@
GE_PATH,
GE_SHAPE,
GE_TEXT,
- GE_IMAGE
+ GE_IMAGE,
+ GE_SUBSHAPE
} GraphicElementType;
typedef union _GraphicElement GraphicElement;
@@ -51,6 +55,7 @@
typedef struct _GraphicElementPath GraphicElementPath;
typedef struct _GraphicElementText GraphicElementText;
typedef struct _GraphicElementImage GraphicElementImage;
+typedef struct _GraphicElementSubShape GraphicElementSubShape;
#define SHAPE_INFO_COMMON \
GraphicElementType type; \
@@ -103,6 +108,26 @@
DiaImage image;
};
+#define OFFSET_METHOD_PROPORTIONAL 0
+#define OFFSET_METHOD_FIXED 1
+#define SUBSCALE_ACCELERATION 1
+#define SUBSCALE_MININUM_SCALE 0.0001
+struct _GraphicElementSubShape {
+ SHAPE_INFO_COMMON;
+ GList *display_list;
+
+ gint h_anchor_method;
+ gint v_anchor_method;
+
+ real default_scale;
+
+ /* subshape bounding box, center, ... */
+
+ Point center;
+ real half_width;
+ real half_height;
+};
+
#undef SHAPE_INFO_COMMON
union _GraphicElement {
@@ -117,6 +142,7 @@
GraphicElementPath shape;
GraphicElementText text;
GraphicElementImage image;
+ GraphicElementSubShape subshape;
};
typedef struct _ExtAttribute {
@@ -131,6 +157,10 @@
SHAPE_ASPECT_RANGE
} ShapeAspectType;
+#define DEFAULT_WIDTH 2.0
+#define DEFAULT_HEIGHT 2.0
+#define DEFAULT_BORDER 0.25
+
typedef struct _ShapeInfo ShapeInfo;
struct _ShapeInfo {
gchar *name;
@@ -154,7 +184,12 @@
ShapeAspectType aspect_type;
real aspect_min, aspect_max;
+ real default_width; /* default_width normalized in points */
+ real default_height; /* default_height normalized in points */
+
GList *display_list;
+
+ GList *subshapes;
DiaObjectType *object_type; /* back link so we can find the correct type */
@@ -171,6 +206,9 @@
ShapeInfo *shape_info_get(ObjectNode obj_node);
ShapeInfo *shape_info_getbyname(const gchar *name);
+real shape_info_get_default_width(ShapeInfo *info);
+real shape_info_get_default_height(ShapeInfo *info);
+
void shape_info_realise(ShapeInfo* info);
void shape_info_print(ShapeInfo *info);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]