Hi folks,
The enclosed patch adds a new property to zig-zag lines, called
corner_radius. If set to something more than 0 (the default), then, all
corners are rounded.
Please note that this is *not* what I suggested in a previous post (waved
lines), it's another feature I needed (to draw SADT charts, mainly).
If this patch is deemed worthy of inclusion, I'll do the same for the
Polyline object.
The patch is against 0.80 but still applies cleanly to a less than 24-hour
old CVS snapshot.
Comments and suggestions of course welcome.
-- Cyrille
------------------------------------------------------------------
Oh, my god ! I'm trapped into a V90 modem ! PGP ID: A879BEF8
diff -urN dia-0.80/objects/standard/zigzagline.c
dia-mine/objects/standard/zigzagline.c
--- dia-0.80/objects/standard/zigzagline.c Mon Aug 23 21:33:51 1999
+++ dia-mine/objects/standard/zigzagline.c Sat Oct 30 01:59:08 1999
@@ -32,6 +32,7 @@
#include "pixmaps/zigzag.xpm"
#define DEFAULT_WIDTH 0.15
+#define DEFAULT_CORNER_RADIUS 0.0
#define HANDLE_MIDDLE HANDLE_CUSTOM1
@@ -46,6 +47,7 @@
LineStyle line_style;
real dashlength;
real line_width;
+ real corner_radius;
Arrow start_arrow, end_arrow;
};
@@ -56,6 +58,7 @@
LineStyle line_style;
real dashlength;
real line_width;
+ real corner_radius;
Arrow start_arrow, end_arrow;
} Zigzagline;
@@ -63,6 +66,7 @@
GtkWidget *vbox;
GtkSpinButton *line_width;
+ GtkSpinButton *corner_radius;
DiaColorSelector *color;
DiaLineStyleSelector *line_style;
@@ -75,6 +79,7 @@
typedef struct _ZigzaglineProperties {
Color line_color;
real line_width;
+ real corner_radius;
LineStyle line_style;
real dashlength;
Arrow start_arrow, end_arrow;
@@ -170,6 +175,8 @@
old_state = (ObjectState *)zigzagline_get_state(zigzagline);
+ zigzagline->corner_radius =
+gtk_spin_button_get_value_as_float(zigzagline_properties_dialog->corner_radius);
+
zigzagline->line_width =
gtk_spin_button_get_value_as_float(zigzagline_properties_dialog->line_width);
dia_color_selector_get_color(zigzagline_properties_dialog->color,
&zigzagline->line_color);
dia_line_style_selector_get_linestyle(zigzagline_properties_dialog->line_style,
&zigzagline->line_style, &zigzagline->dashlength);
@@ -194,6 +201,7 @@
GtkWidget *arrow;
GtkWidget *line_width;
GtkWidget *align;
+ GtkWidget *corner_radius;
GtkAdjustment *adj;
if (zigzagline_properties_dialog == NULL) {
@@ -216,6 +224,21 @@
gtk_widget_show (line_width);
gtk_widget_show(hbox);
gtk_box_pack_start (GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ label = gtk_label_new(_("Corner corner_radius:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ gtk_widget_show (label);
+ adj = (GtkAdjustment *) gtk_adjustment_new(0.1, 0.00, 10.0, 0.01, 0.0, 0.0);
+ corner_radius = gtk_spin_button_new(adj, 0.0, 2);
+ gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(corner_radius), TRUE);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(corner_radius), TRUE);
+ zigzagline_properties_dialog->corner_radius = GTK_SPIN_BUTTON(corner_radius);
+ gtk_box_pack_start(GTK_BOX (hbox), corner_radius, TRUE, TRUE, 0);
+ gtk_widget_show (corner_radius);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start (GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
+
hbox = gtk_hbox_new(FALSE, 5);
label = gtk_label_new(_("Color:"));
@@ -276,6 +299,8 @@
gtk_spin_button_set_value(zigzagline_properties_dialog->line_width,
zigzagline->line_width);
+ gtk_spin_button_set_value(zigzagline_properties_dialog->corner_radius,
+ zigzagline->corner_radius);
dia_color_selector_set_color(zigzagline_properties_dialog->color,
&zigzagline->line_color);
dia_line_style_selector_set_linestyle(zigzagline_properties_dialog->line_style,
@@ -432,8 +457,99 @@
renderer->ops->set_linejoin(renderer, LINEJOIN_MITER);
renderer->ops->set_linecaps(renderer, LINECAPS_BUTT);
- renderer->ops->draw_polyline(renderer, points, n, &zigzagline->line_color);
-
+ if (zigzagline->corner_radius == 0.0) {
+ renderer->ops->draw_polyline(renderer, points, n, &zigzagline->line_color);
+ } else {
+ int i;
+ Point *p;
+ real rr;
+ real zzr;
+ p = points;
+ zzr = zigzagline->corner_radius;
+
+ for (i=0; i<(n-2); i++,p++)
+ {
+ real len1,len2;
+ real rr,cosa,sina,cosb,sinb,cosg,sing,alpha,beta,gamma,ca,cb;
+ Point v1,v2,vca,vcb;
+ Point X,Y,m1,m2,M,C,A,B;
+
+ rr = zzr;
+
+ len1 = distance_point_point(p,p+1);
+ if ((len1/2) < rr) rr = len1/2;
+ len2 = distance_point_point(p+1,p+2);
+ if ((len2/2) < rr) rr = len2/2;
+
+ M.x = (*(p+1)).x; X.x = p->x; Y.x = (*(p+2)).x;
+ M.y = (*(p+1)).y; X.y = p->y; Y.y = (*(p+2)).y;
+ m1.x = (i==0)?(p->x):((p->x + M.x) / 2);
+ m1.y = (i==0)?(p->y):((p->y + M.y) / 2);
+ m2.x = (i==(n-3))?(Y.x):((M.x + Y.x) / 2);
+ m2.y = (i==(n-3))?(Y.y):((M.y + Y.y) / 2);
+
+ if (rr < .01) {
+ /* too small corner : we do it a bit faster */
+ renderer->ops->draw_line(renderer,&m1,&M,&zigzagline->line_color);
+ renderer->ops->draw_line(renderer,&M,&m2,&zigzagline->line_color);
+ } else {
+ /* full rendering. We know len1 and len2 are nonzero. */
+ v1.x = (M.x - X.x) / len1;
+ v1.y = (M.y - X.y) / len1;
+ v2.x = (Y.x - M.x) / len2;
+ v2.y = (Y.y - M.y) / len2;
+
+ A.x = M.x - (v1.x * rr);
+ A.y = M.y - (v1.y * rr);
+ renderer->ops->draw_line(renderer,&m1,&A,&zigzagline->line_color);
+ B.x = M.x + (v2.x * rr);
+ B.y = M.y + (v2.y * rr);
+ renderer->ops->draw_line(renderer,&B,&m2,&zigzagline->line_color);
+ C.x = A.x + (v2.x * rr); /* (or B.x - v1.x*rr) */
+ C.y = A.y + (v2.y * rr);
+
+ vca.x = A.x - C.x;
+ vca.y = -(A.y - C.y); /* @#$! coordinate system */
+ vcb.x = B.x - C.x;
+ vcb.y = -(B.y - C.y);
+
+ ca = distance_point_point(&C,&A);
+ cosa = vca.x / ca; sina = vca.y / ca;
+
+ cb = distance_point_point(&C,&B);
+ cosb = vcb.x / cb; sinb = vcb.y / cb;
+
+ /*cosg = ((M.x-X.x)*(Y.x-M.x) + (M.y-X.y)*(Y.y-M.y)) / (len1*len2);*/
+ sing = (-(M.x-X.x)*(Y.y-M.y) + (Y.x-M.x)*(M.y-X.y)) / (len1*len2);
+
+ alpha = acos(cosa) * 180.0 / M_PI;
+ if (sina < 0.0) alpha = -alpha;
+ beta = acos(cosb) * 180.0 / M_PI ;
+ if (sinb < 0.0) beta = -beta;
+
+ /* we'll keep gamma in radians, since we're only interested in its
+ sign */
+ /* after all, we don't even need to compute cos(gamma), and
+ we can use sin(gamma) to extract the sign of gamma itself. */
+
+ if (alpha < 0.0) alpha += 360.0;
+ if (beta < 0.0) beta += 360.0;
+ if (sing /* gamma*/ < 0) {
+ /* if this happens, we swap alpha and beta, in order to draw
+ the other portion of circle */
+ real tau;
+ tau = beta;
+ beta=alpha;
+ alpha = tau;
+ }
+
+
+renderer->ops->draw_arc(renderer,&C,rr*2,rr*2,alpha,beta,&zigzagline->line_color);
+
+ }
+ }
+ }
+
+
if (zigzagline->start_arrow.type != ARROW_NONE) {
arrow_draw(renderer, zigzagline->start_arrow.type,
&points[0], &points[1],
@@ -478,7 +594,8 @@
&zigzagline->dashlength);
zigzagline->start_arrow = attributes_get_default_start_arrow();
zigzagline->end_arrow = attributes_get_default_end_arrow();
-
+ zigzagline->corner_radius = DEFAULT_CORNER_RADIUS;
+
*handle1 = orth->handles[0];
*handle2 = orth->handles[orth->numpoints-2];
return (Object *)zigzagline;
@@ -510,6 +627,7 @@
newzigzagline->line_style = zigzagline->line_style;
newzigzagline->start_arrow = zigzagline->start_arrow;
newzigzagline->end_arrow = zigzagline->end_arrow;
+ newzigzagline->corner_radius = zigzagline->corner_radius;
return (Object *)newzigzagline;
}
@@ -527,6 +645,7 @@
state->line_width = zigzagline->line_width;
state->start_arrow = zigzagline->start_arrow;
state->end_arrow = zigzagline->end_arrow;
+ state->corner_radius = zigzagline->corner_radius;
return state;
}
@@ -540,6 +659,7 @@
zigzagline->line_width = state->line_width;
zigzagline->start_arrow = state->start_arrow;
zigzagline->end_arrow = state->end_arrow;
+ zigzagline->corner_radius = state->corner_radius;
g_free(state);
@@ -633,7 +753,11 @@
if (zigzagline->line_width != 0.1)
data_add_real(new_attribute(obj_node, "line_width"),
zigzagline->line_width);
-
+
+ if (zigzagline->corner_radius != DEFAULT_CORNER_RADIUS)
+ data_add_real(new_attribute(obj_node,"corner_radius"),
+ zigzagline->corner_radius);
+
if (zigzagline->line_style != LINESTYLE_SOLID)
data_add_enum(new_attribute(obj_node, "line_style"),
zigzagline->line_style);
@@ -684,6 +808,11 @@
attr = object_find_attribute(obj_node, "line_color");
if (attr != NULL)
data_color(attribute_first_data(attr), &zigzagline->line_color);
+
+ zigzagline->corner_radius = DEFAULT_CORNER_RADIUS;
+ attr = object_find_attribute(obj_node,"corner_radius");
+ if (attr != NULL)
+ zigzagline->corner_radius = data_real(attribute_first_data(attr));
zigzagline->line_width = 0.1;
attr = object_find_attribute(obj_node, "line_width");