• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


Commit MetaInfo

修訂8ef8e78d630e1f708cded07cc327e227597d82cf (tree)
時間2007-10-07 05:06:42
作者Hans Breuer <hans@breu...>
CommiterHans Breuer

Log Message

major restructuring - getting calculate and draw by function pointer. A

2007-10-06 Hans Breuer <hans@breuer.org>

* lib/arrows.c : major restructuring - getting calculate and draw by
function pointer. A lot of arrows are converted to the new style thus
arrow_bbox() can give the correct bounding box.
* objects/standard/arc.c : bug #340705 and bug #477569
objects/standard/bezier.c : bug #300055
objects/standard/line.c objects/standard/polyline.c
objects/standard/zigzagline.c : not using *BBExtra to adjust the
bounding box for arrows but instead a combination of arrow_bbox()
and calculate_arrow_point()
* lib/bounding_box.c : just a comment for now
* samples/arrows.dia : more coverage

svn path=/trunk/; revision=3800

Change Summary

差異

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
11 2007-10-06 Hans Breuer <hans@breuer.org>
22
3+ * lib/arrows.c : major restructuring - getting calculate and draw by
4+ function pointer. A lot of arrows are converted to the new style thus
5+ arrow_bbox() can give the correct bounding box.
6+ * objects/standard/arc.c : bug #340705 and bug #477569
7+ objects/standard/bezier.c : bug #300055
8+ objects/standard/line.c objects/standard/polyline.c
9+ objects/standard/zigzagline.c : not using *BBExtra to adjust the
10+ bounding box for arrows but instead a combination of arrow_bbox()
11+ and calculate_arrow_point()
12+ * lib/bounding_box.c : just a comment for now
13+ * samples/arrows.dia : more coverage
14+
15+2007-10-06 Hans Breuer <hans@breuer.org>
16+
17+ * makefile.msc bindings/makefile.msc : integrated bindings in the build
18+
319 * configure.in acinclude.m4 Makefile.am bindings/Makefile.am :
420 build bindings given --with-swig (and SWIG is found)
521 * bindings/dia-diagramdata.h bindings/dia-extra.cpp
@@ -58,7 +74,7 @@
5874 settings from prefs on startup. Fixes bug #479244. Also a bit of
5975 cleanup.
6076
61-2007-09-21 Hans Breuer <hans@breuer.org>
77+2007-09-22 Hans Breuer <hans@breuer.org>
6278
6379 * lib/arrow.[hc] : refactoring to more information hiding:
6480 type menudesc renamed to ArrowDesc and moved arrow_types to arrow.c.
--- a/lib/arrows.c
+++ b/lib/arrows.c
@@ -40,48 +40,6 @@
4040 #include "widgets.h"
4141 #include "intl.h"
4242
43-struct ArrowDesc {
44- const char *name;
45- ArrowType enum_value;
46-};
47-
48-struct ArrowDesc arrow_types[] =
49- {{N_("None"),ARROW_NONE},
50- {N_("Lines"),ARROW_LINES},
51- {N_("Hollow Triangle"),ARROW_HOLLOW_TRIANGLE},
52- {N_("Filled Triangle"),ARROW_FILLED_TRIANGLE},
53- {N_("Unfilled Triangle"),ARROW_UNFILLED_TRIANGLE},
54- {N_("Hollow Diamond"),ARROW_HOLLOW_DIAMOND},
55- {N_("Filled Diamond"),ARROW_FILLED_DIAMOND},
56- {N_("Half Diamond"), ARROW_HALF_DIAMOND},
57- {N_("Half Head"),ARROW_HALF_HEAD},
58- {N_("Slashed Cross"),ARROW_SLASHED_CROSS},
59- {N_("Filled Ellipse"),ARROW_FILLED_ELLIPSE},
60- {N_("Hollow Ellipse"),ARROW_HOLLOW_ELLIPSE},
61- {N_("Filled Dot"),ARROW_FILLED_DOT},
62- {N_("Dimension Origin"),ARROW_DIMENSION_ORIGIN},
63- {N_("Blanked Dot"),ARROW_BLANKED_DOT},
64- {N_("Double Hollow Triangle"),ARROW_DOUBLE_HOLLOW_TRIANGLE},
65- {N_("Double Filled Triangle"),ARROW_DOUBLE_FILLED_TRIANGLE},
66- {N_("Filled Dot and Triangle"), ARROW_FILLED_DOT_N_TRIANGLE},
67- {N_("Filled Box"),ARROW_FILLED_BOX},
68- {N_("Blanked Box"),ARROW_BLANKED_BOX},
69- {N_("Slashed"),ARROW_SLASH_ARROW},
70- {N_("Integral Symbol"),ARROW_INTEGRAL_SYMBOL},
71- {N_("Crow Foot"),ARROW_CROW_FOOT},
72- {N_("Cross"),ARROW_CROSS},
73- {N_("1-or-many"),ARROW_ONE_OR_MANY},
74- {N_("0-or-many"),ARROW_NONE_OR_MANY},
75- {N_("1-or-0"),ARROW_ONE_OR_NONE},
76- {N_("1 exactly"),ARROW_ONE_EXACTLY},
77- {N_("Filled Concave"),ARROW_FILLED_CONCAVE},
78- {N_("Blanked Concave"),ARROW_BLANKED_CONCAVE},
79- {N_("Round"), ARROW_ROUNDED},
80- {N_("Open Round"), ARROW_OPEN_ROUNDED},
81- {N_("Backslash"),ARROW_BACKSLASH},
82- {N_("Infinite Line"),ARROW_THREE_DOTS},
83- {NULL,0}};
84-
8543 /**** prototypes ****/
8644 static void
8745 draw_empty_ellipse(DiaRenderer *renderer, Point *to, Point *from,
@@ -89,14 +47,14 @@ draw_empty_ellipse(DiaRenderer *renderer, Point *to, Point *from,
8947 Color *fg_color);
9048 static void
9149 calculate_double_arrow(Point *second_to, Point *second_from,
92- Point *to, Point *from, real length);
50+ const Point *to, const Point *from, real length);
9351
9452 static void
9553 draw_crow_foot(DiaRenderer *renderer, Point *to, Point *from,
9654 real length, real width, real linewidth,
9755 Color *fg_color,Color *bg_color);
98-static void
99-calculate_diamond(Point *poly/*[4]*/, Point *to, Point *from,
56+static int
57+calculate_diamond(Point *poly/*[4]*/, const Point *to, const Point *from,
10058 real length, real width);
10159
10260 /** The function calculate_arrow_point adjusts the placement of the line and
@@ -321,7 +279,7 @@ calculate_arrow_point(const Arrow *arrow, const Point *to, const Point *from,
321279 * @param length How long the arrowhead should be.
322280 * @param width How wide the arrowhead should be.
323281 */
324-static void
282+static int
325283 calculate_arrow(Point *poly, const Point *to, const Point *from,
326284 real length, real width)
327285 {
@@ -353,6 +311,8 @@ calculate_arrow(Point *poly, const Point *to, const Point *from,
353311 poly[2] = *to;
354312 point_sub(&poly[2], &delta);
355313 point_add(&poly[2], &orth_delta);
314+
315+ return 3;
356316 }
357317
358318 /** Calculate the actual point of a crows-foot arrow.
@@ -364,8 +324,8 @@ calculate_arrow(Point *poly, const Point *to, const Point *from,
364324 * @param length How long the arrowhead should be.
365325 * @param width How wide the arrowhead should be.
366326 */
367-static void
368-calculate_crow(Point *poly, Point *to, Point *from,
327+static int
328+calculate_crow(Point *poly, const Point *to, const Point *from,
369329 real length, real width)
370330 {
371331 Point delta;
@@ -395,6 +355,8 @@ calculate_crow(Point *poly, Point *to, Point *from,
395355 point_sub(&poly[1], &orth_delta);
396356 poly[2] = *to;
397357 point_add(&poly[2], &orth_delta);
358+
359+ return 3;
398360 }
399361
400362 /** Draw ER arrow for 0..N according to Modern database management,
@@ -588,7 +550,7 @@ draw_crow_foot(DiaRenderer *renderer, Point *to, Point *from,
588550 static void
589551 draw_lines(DiaRenderer *renderer, Point *to, Point *from,
590552 real length, real width, real linewidth,
591- Color *color)
553+ Color *fg_color, Color *bg_color)
592554 {
593555 Point poly[3];
594556
@@ -599,7 +561,14 @@ draw_lines(DiaRenderer *renderer, Point *to, Point *from,
599561 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
600562 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
601563
602- DIA_RENDERER_GET_CLASS(renderer)->draw_polyline(renderer, poly, 3, color);
564+ DIA_RENDERER_GET_CLASS(renderer)->draw_polyline(renderer, poly, 3, fg_color);
565+}
566+
567+static int
568+calculate_ellipse (Point *poly, const Point *to, const Point *from,
569+ real length, real width)
570+{
571+ return calculate_diamond (poly, to, from, length, width);
603572 }
604573
605574 /** Draw an arrowhead that is a filled ellipse.
@@ -734,6 +703,41 @@ draw_empty_ellipse(DiaRenderer *renderer, Point *to, Point *from,
734703 DIA_RENDERER_GET_CLASS(renderer)->draw_bezier(renderer,bp,sizeof(bp)/sizeof(bp[0]),fg_color);
735704 }
736705
706+static int
707+calculate_box (Point *poly, const Point *to, const Point *from,
708+ real length, real width)
709+{
710+ Point vl, vt;
711+ Point bs, be;
712+
713+ point_copy(&vl,from); point_sub(&vl,to);
714+ if (point_len(&vl) > 0)
715+ point_normalize(&vl);
716+ else {
717+ vl.x = 1.0; vl.y = 0.0;
718+ }
719+ if (!finite(vl.x)) {
720+ vl.x = 1.0; vl.y = 0.0;
721+ }
722+ point_get_perp(&vt,&vl);
723+
724+ point_copy_add_scaled(&bs,to,&vl,length/4);
725+ point_copy_add_scaled(&be,&bs,&vt,-width/2.0);
726+ point_add_scaled(&bs,&vt,width/2.0);
727+
728+ point_copy(&poly[0],to);
729+ point_copy(&poly[1],&poly[0]);
730+ point_add_scaled(&poly[0],&vt,width/4.0);
731+ point_add_scaled(&poly[1],&vt,-width/4.0);
732+ point_copy_add_scaled(&poly[2],&poly[1],&vl,length/2.0);
733+ point_copy_add_scaled(&poly[3],&poly[0],&vl,length/2.0);
734+
735+ poly[4] = bs;
736+ poly[5] = be;
737+
738+ return 6;
739+}
740+
737741 /** Draw an arrow head that is an (optionall) filled box.
738742 * @param renderer A renderer instance to draw into
739743 * @param to The point that the arrow points to.
@@ -750,9 +754,7 @@ draw_fill_box(DiaRenderer *renderer, Point *to, Point *from,
750754 real length, real width, real linewidth,
751755 Color *fg_color,Color *bg_color)
752756 {
753- Point vl,vt;
754- Point bs,be;
755- Point poly[4];
757+ Point poly[6];
756758 real lw_factor,clength,cwidth;
757759
758760 DIA_RENDERER_GET_CLASS(renderer)->set_linewidth(renderer, linewidth);
@@ -770,27 +772,7 @@ draw_fill_box(DiaRenderer *renderer, Point *to, Point *from,
770772 clength = length + lw_factor;
771773 cwidth = width + lw_factor;
772774
773- point_copy(&vl,from); point_sub(&vl,to);
774- if (point_len(&vl) > 0)
775- point_normalize(&vl);
776- else {
777- vl.x = 1.0; vl.y = 0.0;
778- }
779- if (!finite(vl.x)) {
780- vl.x = 1.0; vl.y = 0.0;
781- }
782- point_get_perp(&vt,&vl);
783-
784- point_copy_add_scaled(&bs,to,&vl,length/4);
785- point_copy_add_scaled(&be,&bs,&vt,-width/2.0);
786- point_add_scaled(&bs,&vt,width/2.0);
787-
788- point_copy(&poly[0],to);
789- point_copy(&poly[1],&poly[0]);
790- point_add_scaled(&poly[0],&vt,cwidth/4.0);
791- point_add_scaled(&poly[1],&vt,-cwidth/4.0);
792- point_copy_add_scaled(&poly[2],&poly[1],&vl,clength/2.0);
793- point_copy_add_scaled(&poly[3],&poly[0],&vl,clength/2.0);
775+ calculate_box (poly, to, from, clength, cwidth);
794776
795777 if (fg_color == bg_color) {
796778 DIA_RENDERER_GET_CLASS(renderer)->fill_polygon(renderer, poly, 4, fg_color);
@@ -798,9 +780,14 @@ draw_fill_box(DiaRenderer *renderer, Point *to, Point *from,
798780 DIA_RENDERER_GET_CLASS(renderer)->fill_polygon(renderer, poly, 4, bg_color);
799781 DIA_RENDERER_GET_CLASS(renderer)->draw_polygon(renderer, poly, 4, fg_color);
800782 }
801- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer,&bs,&be,fg_color);
783+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer,&poly[4],&poly[5],fg_color);
784+}
785+static int
786+calculate_dot (Point *poly, const Point *to, const Point *from,
787+ real length, real width)
788+{
789+ return calculate_diamond (poly, to, from, length, width);
802790 }
803-
804791 /** Draw a "filled dot" arrow.
805792 * @param renderer A renderer instance to draw into
806793 * @param to The point that the arrow points to.
@@ -815,7 +802,7 @@ draw_fill_box(DiaRenderer *renderer, Point *to, Point *from,
815802 static void
816803 draw_fill_dot(DiaRenderer *renderer, Point *to, Point *from,
817804 real length, real width, real linewidth,
818- Color *fg_color,Color *bg_color)
805+ Color *fg_color, Color *bg_color)
819806 {
820807 BezPoint bp[5];
821808 Point vl,vt;
@@ -944,6 +931,38 @@ draw_integral(DiaRenderer *renderer, Point *to, Point *from,
944931 DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &bs, &be, fg_color);
945932 DIA_RENDERER_GET_CLASS(renderer)->draw_bezier(renderer,bp,sizeof(bp)/sizeof(bp[0]),fg_color);
946933 }
934+static int
935+calculate_slashed (Point *poly, const Point *to, const Point *from,
936+ real length, real width)
937+{
938+ Point vl,vt;
939+
940+ point_copy(&vl,from);
941+ point_sub(&vl,to);
942+ if (point_len(&vl) > 0)
943+ point_normalize(&vl);
944+ else {
945+ vl.x = 1.0; vl.y = 0.0;
946+ }
947+ if (!finite(vl.x)) {
948+ vl.x = 1.0; vl.y = 0.0;
949+ }
950+ point_get_perp(&vt,&vl);
951+
952+ point_copy_add_scaled(&poly[2],to,&vl,length/2);
953+ point_copy_add_scaled(&poly[3],&poly[2],&vt,-width/2.0);
954+ point_add_scaled(&poly[2],&vt,width/2.0);
955+
956+ point_copy_add_scaled(&poly[0],to,&vl,length/2);
957+ point_copy_add_scaled(&poly[1],&poly[0],&vl,length/2);
958+
959+ point_copy_add_scaled(&poly[4],to,&vl,.1*length);
960+ point_add_scaled(&poly[4],&vt,.4*width);
961+ point_copy_add_scaled(&poly[5],to,&vl,.9*length);
962+ point_add_scaled(&poly[5],&vt,-.4*width);
963+
964+ return 6;
965+}
947966
948967 /** Draw the arrowhead that is a line with a slash through it.
949968 * @param renderer A renderer instance to draw into
@@ -960,42 +979,20 @@ draw_integral(DiaRenderer *renderer, Point *to, Point *from,
960979 static void
961980 draw_slashed(DiaRenderer *renderer, Point *to, Point *from,
962981 real length, real width, real linewidth,
963- Color *fg_color)
982+ Color *fg_color, Color *bg_color)
964983 {
965- Point vl,vt;
966- Point bs,be, bs2,be2, bs3,be3;
984+ Point poly[6];
985+
986+ calculate_slashed (poly, to, from, length, width);
967987
968988 DIA_RENDERER_GET_CLASS(renderer)->set_linewidth(renderer, linewidth);
969989 DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID);
970990 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
971991 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
972992
973- point_copy(&vl,from); point_sub(&vl,to);
974- if (point_len(&vl) > 0)
975- point_normalize(&vl);
976- else {
977- vl.x = 1.0; vl.y = 0.0;
978- }
979- if (!finite(vl.x)) {
980- vl.x = 1.0; vl.y = 0.0;
981- }
982- point_get_perp(&vt,&vl);
983-
984- point_copy_add_scaled(&bs,to,&vl,length/2);
985- point_copy_add_scaled(&be,&bs,&vt,-width/2.0);
986- point_add_scaled(&bs,&vt,width/2.0);
987-
988- point_copy_add_scaled(&bs2,to,&vl,length/2);
989- point_copy_add_scaled(&be2,&bs2,&vl,length/2);
990-
991- point_copy_add_scaled(&bs3,to,&vl,.1*length);
992- point_add_scaled(&bs3,&vt,.4*width);
993- point_copy_add_scaled(&be3,to,&vl,.9*length);
994- point_add_scaled(&be3,&vt,-.4*width);
995-
996- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &bs2, &be2, fg_color);
997- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &bs, &be, fg_color);
998- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &bs3, &be3, fg_color);
993+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[0], &poly[1], fg_color);
994+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[2], &poly[3], fg_color);
995+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[4], &poly[5], fg_color);
999996 }
1000997
1001998 /** Calculate positions for the half-head arrow (only left-hand(?) line drawn)
@@ -1007,20 +1004,19 @@ draw_slashed(DiaRenderer *renderer, Point *to, Point *from,
10071004 * @param linewidth The width of the lines used to draw the arrow
10081005 * @bug Describe better what is put into poly.
10091006 */
1010-static void
1011-calculate_halfhead(Point *poly, Point *to, Point *from,
1012- real length, real width, real linewidth)
1007+static int
1008+calculate_halfhead(Point *poly, const Point *to, const Point *from,
1009+ real length, real width)
10131010 {
10141011 Point delta;
10151012 Point orth_delta;
10161013 real len;
1017- real angle, add_len;
1014+ real angle;
10181015
10191016 if (width > 0.0000001) {
10201017 angle = atan(length/(width/2));
1021- add_len = linewidth/cos(angle);
10221018 } else {
1023- add_len = 0;
1019+ angle = 0;
10241020 }
10251021
10261022 delta = *to;
@@ -1046,9 +1042,10 @@ calculate_halfhead(Point *poly, Point *to, Point *from,
10461042 poly[1] = *to;
10471043 poly[2] = *to;
10481044 point_normalize(&delta);
1049- point_scale(&delta, add_len);
1045+ point_scale(&delta, 0);
10501046 point_sub(&poly[2], &delta);
10511047 /* point_add(&poly[2], &orth_delta);*/
1048+ return 3;
10521049 }
10531050
10541051 /** Draw a halfhead arrow.
@@ -1063,18 +1060,18 @@ calculate_halfhead(Point *poly, Point *to, Point *from,
10631060 static void
10641061 draw_halfhead(DiaRenderer *renderer, Point *to, Point *from,
10651062 real length, real width, real linewidth,
1066- Color *color)
1063+ Color *fg_color, Color *bg_color)
10671064 {
10681065 Point poly[3];
10691066
1070- calculate_halfhead(poly, to, from, length, width, linewidth);
1067+ calculate_halfhead(poly, to, from, length, width);
10711068
10721069 DIA_RENDERER_GET_CLASS(renderer)->set_linewidth(renderer, linewidth);
10731070 DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID);
10741071 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
10751072 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
10761073
1077- DIA_RENDERER_GET_CLASS(renderer)->draw_polyline(renderer, poly, 3, color);
1074+ DIA_RENDERER_GET_CLASS(renderer)->draw_polyline(renderer, poly, 3, fg_color);
10781075 }
10791076
10801077 /** Draw a basic triangular arrow.
@@ -1089,7 +1086,7 @@ draw_halfhead(DiaRenderer *renderer, Point *to, Point *from,
10891086 static void
10901087 draw_triangle(DiaRenderer *renderer, Point *to, Point *from,
10911088 real length, real width, real linewidth,
1092- Color *color)
1089+ Color *fg_color, Color *bg_color)
10931090 {
10941091 Point poly[3];
10951092
@@ -1099,7 +1096,7 @@ draw_triangle(DiaRenderer *renderer, Point *to, Point *from,
10991096 DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID);
11001097 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
11011098
1102- DIA_RENDERER_GET_CLASS(renderer)->draw_polygon(renderer, poly, 3, color);
1099+ DIA_RENDERER_GET_CLASS(renderer)->draw_polygon(renderer, poly, 3, fg_color);
11031100 }
11041101
11051102 /** Draw a simple triangular arrow, with filled head.
@@ -1113,7 +1110,8 @@ draw_triangle(DiaRenderer *renderer, Point *to, Point *from,
11131110 */
11141111 static void
11151112 fill_triangle(DiaRenderer *renderer, Point *to, Point *from,
1116- real length, real width, Color *color)
1113+ real length, real width, real linewidth,
1114+ Color *fg_color, Color *bg_color)
11171115 {
11181116 Point poly[3];
11191117
@@ -1122,7 +1120,7 @@ fill_triangle(DiaRenderer *renderer, Point *to, Point *from,
11221120 DIA_RENDERER_GET_CLASS(renderer)->set_fillstyle(renderer, FILLSTYLE_SOLID);
11231121 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
11241122
1125- DIA_RENDERER_GET_CLASS(renderer)->fill_polygon(renderer, poly, 3, color);
1123+ DIA_RENDERER_GET_CLASS(renderer)->fill_polygon(renderer, poly, 3, bg_color);
11261124 }
11271125
11281126 /** Calculate the points needed to draw a diamon arrowhead.
@@ -1135,10 +1133,9 @@ fill_triangle(DiaRenderer *renderer, Point *to, Point *from,
11351133 * @param from The point the arrow points away from (e.g. bezier control line)
11361134 * @param length The length of the arrowhead
11371135 * @param width The width of the arrowhead
1138- * @bug Take linewidth into account.
11391136 */
1140-static void
1141-calculate_diamond(Point *poly, Point *to, Point *from,
1137+static int
1138+calculate_diamond(Point *poly, const Point *to, const Point *from,
11421139 real length, real width)
11431140 {
11441141 Point delta;
@@ -1172,6 +1169,8 @@ calculate_diamond(Point *poly, Point *to, Point *from,
11721169 poly[3] = *to;
11731170 point_sub(&poly[3], &delta);
11741171 point_add(&poly[3], &orth_delta);
1172+
1173+ return 4;
11751174 }
11761175
11771176 /** Draw a diamond-shaped arrow head.
@@ -1212,7 +1211,7 @@ draw_diamond(DiaRenderer *renderer, Point *to, Point *from,
12121211 static void
12131212 draw_half_diamond(DiaRenderer *renderer, Point *to, Point *from,
12141213 real length, real width, real linewidth,
1215- Color *color)
1214+ Color *fg_color, Color *bg_color)
12161215 {
12171216 Point poly[4];
12181217
@@ -1223,7 +1222,7 @@ draw_half_diamond(DiaRenderer *renderer, Point *to, Point *from,
12231222 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
12241223 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
12251224
1226- DIA_RENDERER_GET_CLASS(renderer)->draw_polyline(renderer, poly+1, 3, color);
1225+ DIA_RENDERER_GET_CLASS(renderer)->draw_polyline(renderer, poly+1, 3, fg_color);
12271226 }
12281227
12291228 /** Draw a filled diamond arrow head.
@@ -1258,8 +1257,8 @@ fill_diamond(DiaRenderer *renderer, Point *to, Point *from,
12581257 * @param width The width of the arrowhead.
12591258 * @bug Describe what is where in the poly array.
12601259 */
1261-static void
1262-calculate_slashed_cross(Point *poly, Point *to, Point *from,
1260+static int
1261+calculate_slashed_cross(Point *poly, const Point *to, const Point *from,
12631262 real length, real width)
12641263 {
12651264 Point delta;
@@ -1296,6 +1295,8 @@ calculate_slashed_cross(Point *poly, Point *to, Point *from,
12961295
12971296 point_add(&poly[4], &orth_delta);
12981297 point_sub(&poly[5], &orth_delta);
1298+
1299+ return 6;
12991300 }
13001301
13011302 /** Draw a slashed cross arrowhead.
@@ -1309,7 +1310,8 @@ calculate_slashed_cross(Point *poly, Point *to, Point *from,
13091310 */
13101311 static void
13111312 draw_slashed_cross(DiaRenderer *renderer, Point *to, Point *from,
1312- real length, real width, real linewidth, Color *color)
1313+ real length, real width, real linewidth,
1314+ Color *fg_color, Color *bg_color)
13131315 {
13141316 Point poly[6];
13151317
@@ -1320,27 +1322,14 @@ draw_slashed_cross(DiaRenderer *renderer, Point *to, Point *from,
13201322 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
13211323 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
13221324
1323- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[0],&poly[1], color);
1324- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[2],&poly[3], color);
1325- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[4],&poly[5], color);
1325+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[0],&poly[1], fg_color);
1326+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[2],&poly[3], fg_color);
1327+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[4],&poly[5], fg_color);
13261328 }
1327-
1328-/** Draw a backslash arrowhead.
1329- * @param renderer A renderer instance to draw into
1330- * @param to The point that the arrow points to.
1331- * @param from Where the arrow points from (e.g. end of stem)
1332- * @param length The length of the arrow
1333- * @param width The width of the arrow
1334- * @param linewidth The thickness of the lines used to draw the arrow.
1335- * @param color The color used for drawing the arrowhead.
1336- * @todo refactor into calculate and draw.
1337- */
1338-static void
1339-draw_backslash(DiaRenderer *renderer, Point *to, Point *from,
1340- real length, real width, real linewidth, Color *color)
1329+static int
1330+calculate_backslash (Point *poly, const Point *to, const Point *from,
1331+ real length, real width)
13411332 {
1342- Point point1;
1343- Point point2;
13441333 Point delta;
13451334 Point orth_delta;
13461335 real len;
@@ -1362,22 +1351,42 @@ draw_backslash(DiaRenderer *renderer, Point *to, Point *from,
13621351 point_scale(&delta, length/2.0);
13631352 point_scale(&orth_delta, width/2.0);
13641353
1365- point1 = *to;
1366- point_sub(&point1, &delta);
1367- point_sub(&point1, &delta);
1368- point_sub(&point1, &delta);
1369- point_add(&point1, &orth_delta);
1354+ poly[0] = *to;
1355+ point_sub(&poly[0], &delta);
1356+ point_sub(&poly[0], &delta);
1357+ point_sub(&poly[0], &delta);
1358+ point_add(&poly[0], &orth_delta);
13701359
1371- point2 = *to;
1372- point_sub(&point2, &delta);
1373- point_sub(&point2, &orth_delta);
1360+ poly[1] = *to;
1361+ point_sub(&poly[1], &delta);
1362+ point_sub(&poly[1], &orth_delta);
1363+
1364+ return 2;
1365+}
1366+/** Draw a backslash arrowhead.
1367+ * @param renderer A renderer instance to draw into
1368+ * @param to The point that the arrow points to.
1369+ * @param from Where the arrow points from (e.g. end of stem)
1370+ * @param length The length of the arrow
1371+ * @param width The width of the arrow
1372+ * @param linewidth The thickness of the lines used to draw the arrow.
1373+ * @param color The color used for drawing the arrowhead.
1374+ */
1375+static void
1376+draw_backslash(DiaRenderer *renderer, Point *to, Point *from,
1377+ real length, real width, real linewidth,
1378+ Color *fg_color, Color *bg_color)
1379+{
1380+ Point poly[2];
13741381
1382+ calculate_backslash (poly, to, from, length, width);
1383+
13751384 DIA_RENDERER_GET_CLASS(renderer)->set_linewidth(renderer, linewidth);
13761385 DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID);
13771386 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
13781387 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
13791388
1380- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &point1,&point2, color);
1389+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[0], &poly[1], fg_color);
13811390 }
13821391
13831392 /** Draw a cross-like arrowhead.
@@ -1391,7 +1400,8 @@ draw_backslash(DiaRenderer *renderer, Point *to, Point *from,
13911400 */
13921401 static void
13931402 draw_cross(DiaRenderer *renderer, Point *to, Point *from,
1394- real length, real width, real linewidth, Color *color)
1403+ real length, real width, real linewidth,
1404+ Color *fg_color, Color *bg_color)
13951405 {
13961406 Point poly[6];
13971407
@@ -1402,7 +1412,7 @@ draw_cross(DiaRenderer *renderer, Point *to, Point *from,
14021412 DIA_RENDERER_GET_CLASS(renderer)->set_linejoin(renderer, LINEJOIN_MITER);
14031413 DIA_RENDERER_GET_CLASS(renderer)->set_linecaps(renderer, LINECAPS_BUTT);
14041414
1405- DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[0],&poly[2], color);
1415+ DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[0],&poly[2], fg_color);
14061416 /*DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[4],&poly[5], color); */
14071417 }
14081418
@@ -1417,7 +1427,7 @@ draw_cross(DiaRenderer *renderer, Point *to, Point *from,
14171427 */
14181428 static void
14191429 calculate_double_arrow(Point *second_to, Point *second_from,
1420- Point *to, Point *from, real length)
1430+ const Point *to, const Point *from, real length)
14211431 {
14221432 Point delta;
14231433 real len;
@@ -1454,13 +1464,14 @@ calculate_double_arrow(Point *second_to, Point *second_from,
14541464 */
14551465 static void
14561466 draw_double_triangle(DiaRenderer *renderer, Point *to, Point *from,
1457- real length, real width, real linewidth, Color *color)
1467+ real length, real width, real linewidth,
1468+ Color *fg_color, Color *bg_color)
14581469 {
14591470 Point second_from, second_to;
14601471
1461- draw_triangle(renderer, to, from, length, width, linewidth, color);
1472+ draw_triangle(renderer, to, from, length, width, linewidth, fg_color, bg_color);
14621473 calculate_double_arrow(&second_to, &second_from, to, from, length+linewidth);
1463- draw_triangle(renderer, &second_to, &second_from, length, width, linewidth, color);
1474+ draw_triangle(renderer, &second_to, &second_from, length, width, linewidth, fg_color, bg_color);
14641475 }
14651476
14661477 /** Draw a filled double-triangle arrowhead.
@@ -1474,13 +1485,14 @@ draw_double_triangle(DiaRenderer *renderer, Point *to, Point *from,
14741485 */
14751486 static void
14761487 fill_double_triangle(DiaRenderer *renderer, Point *to, Point *from,
1477- real length, real width, Color *color)
1488+ real length, real width, real linewidth,
1489+ Color *fg_color, Color *bg_color)
14781490 {
14791491 Point second_from, second_to;
14801492
1481- fill_triangle(renderer, to, from, length, width, color);
1493+ fill_triangle(renderer, to, from, length, width, linewidth, NULL, bg_color);
14821494 calculate_double_arrow(&second_to, &second_from, to, from, length);
1483- fill_triangle(renderer, &second_to, &second_from, length, width, color);
1495+ fill_triangle(renderer, &second_to, &second_from, length, width, linewidth, NULL, bg_color);
14841496 }
14851497
14861498 /** Calculate the points needed to draw a concave arrowhead.
@@ -1494,8 +1506,8 @@ fill_double_triangle(DiaRenderer *renderer, Point *to, Point *from,
14941506 * @param length The length of the arrow.
14951507 * @param width The width of the arrow.
14961508 */
1497-static void
1498-calculate_concave(Point *poly, Point *to, Point *from,
1509+static int
1510+calculate_concave(Point *poly, const Point *to, const Point *from,
14991511 real length, real width)
15001512 {
15011513 Point delta;
@@ -1536,6 +1548,8 @@ calculate_concave(Point *poly, Point *to, Point *from,
15361548 point_sub(&poly[3], &delta);
15371549 point_sub(&poly[3], &delta);
15381550 point_sub(&poly[3], &delta);
1551+
1552+ return 4;
15391553 }
15401554
15411555 /** Draw a concave triangle arrowhead.
@@ -1753,6 +1767,155 @@ draw_three_dots(DiaRenderer *renderer, Point *to, Point *from,
17531767 }
17541768 }
17551769
1770+static void
1771+draw_hollow_triangle (DiaRenderer *renderer, Point *to, Point *from,
1772+ real length, real width, real linewidth,
1773+ Color *fg_color, Color *bg_color)
1774+{
1775+ fill_triangle(renderer, to, from, length, width, linewidth, NULL, bg_color);
1776+ draw_triangle(renderer, to, from, length, width, linewidth, fg_color, NULL);
1777+}
1778+static void
1779+draw_filled_triangle (DiaRenderer *renderer, Point *to, Point *from,
1780+ real length, real width, real linewidth,
1781+ Color *fg_color, Color *bg_color)
1782+{
1783+ fill_triangle(renderer, to, from, length, width, linewidth, NULL, fg_color);
1784+ draw_triangle(renderer, to, from, length, width, linewidth, fg_color, NULL);
1785+}
1786+static void
1787+draw_unfilled_triangle (DiaRenderer *renderer, Point *to, Point *from,
1788+ real length, real width, real linewidth,
1789+ Color *fg_color, Color *bg_color)
1790+{
1791+ draw_triangle(renderer, to, from, length, width, linewidth, fg_color, bg_color);
1792+}
1793+static void
1794+draw_hollow_diamond (DiaRenderer *renderer, Point *to, Point *from,
1795+ real length, real width, real linewidth,
1796+ Color *fg_color, Color *bg_color)
1797+{
1798+ fill_diamond(renderer, to, from, length, width, bg_color);
1799+ draw_diamond(renderer, to, from, length, width, linewidth, fg_color);
1800+}
1801+static void
1802+draw_filled_diamond (DiaRenderer *renderer, Point *to, Point *from,
1803+ real length, real width, real linewidth,
1804+ Color *fg_color, Color *bg_color)
1805+{
1806+ fill_diamond(renderer, to, from, length, width, fg_color);
1807+ draw_diamond(renderer, to, from, length, width, linewidth, fg_color);
1808+}
1809+static void
1810+draw_filled_ellipse (DiaRenderer *renderer, Point *to, Point *from,
1811+ real length, real width, real linewidth,
1812+ Color *fg_color, Color *bg_color)
1813+{
1814+ draw_fill_ellipse(renderer,to,from,length,width,linewidth,fg_color,fg_color);
1815+}
1816+static void
1817+draw_filled_dot (DiaRenderer *renderer, Point *to, Point *from,
1818+ real length, real width, real linewidth,
1819+ Color *fg_color, Color *bg_color)
1820+{
1821+ draw_fill_dot(renderer,to,from,length,width,linewidth,fg_color,fg_color);
1822+}
1823+static void
1824+draw_filled_box (DiaRenderer *renderer, Point *to, Point *from,
1825+ real length, real width, real linewidth,
1826+ Color *fg_color, Color *bg_color)
1827+{
1828+ draw_fill_box(renderer,to,from,length,width,linewidth,fg_color,fg_color);
1829+}
1830+static void
1831+draw_filled_concave (DiaRenderer *renderer, Point *to, Point *from,
1832+ real length, real width, real linewidth,
1833+ Color *fg_color, Color *bg_color)
1834+{
1835+ draw_concave_triangle(renderer, to, from, length, width, linewidth, fg_color, fg_color);
1836+}
1837+static int
1838+calculate_double_triangle (Point *poly, const Point *to, const Point *from,
1839+ real length, real width)
1840+{
1841+ Point second_from, second_to;
1842+
1843+ calculate_arrow (poly, to, from, length, width);
1844+ calculate_double_arrow(&second_to, &second_from, to, from, length);
1845+ calculate_arrow (poly+3, &second_to, &second_from, length, width);
1846+ return 6;
1847+}
1848+static void
1849+draw_double_hollow_triangle (DiaRenderer *renderer, Point *to, Point *from,
1850+ real length, real width, real linewidth,
1851+ Color *fg_color, Color *bg_color)
1852+{
1853+ fill_double_triangle(renderer, to, from, length+(linewidth/2), width, linewidth, fg_color, bg_color);
1854+ draw_double_triangle(renderer, to, from, length, width, linewidth, fg_color, bg_color);
1855+}
1856+static void
1857+draw_double_filled_triangle (DiaRenderer *renderer, Point *to, Point *from,
1858+ real length, real width, real linewidth,
1859+ Color *fg_color, Color *bg_color)
1860+{
1861+ fill_double_triangle(renderer, to, from, length, width, linewidth, fg_color, fg_color);
1862+}
1863+struct ArrowDesc {
1864+ const char *name;
1865+ ArrowType enum_value;
1866+ /* calculates the points for the arrow, their number is returned */
1867+ int (*calculate) (Point *poly, /* variable size poly */
1868+ const Point *to, /* pointing to */
1869+ const Point *from, /* coming from */
1870+ real length, /* the arrows length */
1871+ real width); /* the arrows width */
1872+ /* draw the arrow, internally calculated with the respective calculate */
1873+ void (*draw) (DiaRenderer *renderer,
1874+ Point *to,
1875+ Point *from,
1876+ real length,
1877+ real width,
1878+ real linewidth, /* the lines width also used in many arrows */
1879+ Color *fg_color, /* the main drawin color */
1880+ Color *bg_color); /* not always used */
1881+} arrow_types[] =
1882+ {{N_("None"),ARROW_NONE},
1883+ {N_("Lines"),ARROW_LINES, calculate_arrow, draw_lines},
1884+ {N_("Hollow Triangle"), ARROW_HOLLOW_TRIANGLE, calculate_arrow, draw_hollow_triangle},
1885+ {N_("Filled Triangle"), ARROW_FILLED_TRIANGLE, calculate_arrow, draw_filled_triangle},
1886+ {N_("Unfilled Triangle"), ARROW_UNFILLED_TRIANGLE, calculate_arrow, draw_unfilled_triangle},
1887+ {N_("Hollow Diamond"),ARROW_HOLLOW_DIAMOND, calculate_diamond, draw_hollow_diamond},
1888+ {N_("Filled Diamond"),ARROW_FILLED_DIAMOND, calculate_diamond, draw_filled_diamond},
1889+ {N_("Half Diamond"), ARROW_HALF_DIAMOND, calculate_diamond, draw_half_diamond},
1890+ {N_("Half Head"), ARROW_HALF_HEAD, calculate_halfhead, draw_halfhead},
1891+ {N_("Slashed Cross"), ARROW_SLASHED_CROSS, calculate_slashed_cross, draw_slashed_cross},
1892+ {N_("Filled Ellipse"), ARROW_FILLED_ELLIPSE, calculate_ellipse, draw_filled_ellipse},
1893+ {N_("Hollow Ellipse"), ARROW_HOLLOW_ELLIPSE, calculate_ellipse, draw_fill_ellipse},
1894+ {N_("Filled Dot"), ARROW_FILLED_DOT, calculate_dot, draw_filled_dot},
1895+ {N_("Dimension Origin"),ARROW_DIMENSION_ORIGIN},
1896+ {N_("Blanked Dot"),ARROW_BLANKED_DOT, calculate_dot, draw_fill_dot},
1897+ {N_("Double Hollow Triangle"),ARROW_DOUBLE_HOLLOW_TRIANGLE, calculate_double_triangle, draw_double_hollow_triangle},
1898+ {N_("Double Filled Triangle"),ARROW_DOUBLE_FILLED_TRIANGLE, calculate_double_triangle, draw_double_filled_triangle},
1899+ {N_("Filled Dot and Triangle"), ARROW_FILLED_DOT_N_TRIANGLE},
1900+ {N_("Filled Box"), ARROW_FILLED_BOX, calculate_box, draw_filled_box},
1901+ {N_("Blanked Box"),ARROW_BLANKED_BOX, calculate_box, draw_fill_box},
1902+ {N_("Slashed"), ARROW_SLASH_ARROW, calculate_slashed, draw_slashed},
1903+ {N_("Integral Symbol"),ARROW_INTEGRAL_SYMBOL},
1904+ {N_("Crow Foot"), ARROW_CROW_FOOT, calculate_crow, draw_crow_foot},
1905+ {N_("Cross"),ARROW_CROSS, calculate_arrow, draw_cross},
1906+ {N_("1-or-many"),ARROW_ONE_OR_MANY},
1907+ {N_("0-or-many"),ARROW_NONE_OR_MANY},
1908+ {N_("1-or-0"),ARROW_ONE_OR_NONE},
1909+ {N_("1 exactly"),ARROW_ONE_EXACTLY},
1910+ {N_("Filled Concave"),ARROW_FILLED_CONCAVE, calculate_concave, draw_filled_concave},
1911+ {N_("Blanked Concave"),ARROW_BLANKED_CONCAVE, calculate_concave, draw_concave_triangle},
1912+ {N_("Round"), ARROW_ROUNDED},
1913+ {N_("Open Round"), ARROW_OPEN_ROUNDED},
1914+ {N_("Backslash"), ARROW_BACKSLASH, calculate_backslash, draw_backslash},
1915+ {N_("Infinite Line"),ARROW_THREE_DOTS},
1916+ {NULL,0}
1917+};
1918+
17561919 /** following the signature pattern of lib/boundingbox.h
17571920 * the arrow bounding box is added to the given rect
17581921 * @param arrow the arrow
@@ -1765,23 +1928,26 @@ void
17651928 arrow_bbox (const Arrow *arrow, real line_width, const Point *to, const Point *from,
17661929 Rectangle *rect)
17671930 {
1768-#define N_POINTS 3 /* 3 for calculate_arrow() */
1769- Point poly[N_POINTS];
1931+ Point poly[6]; /* Attention: nust be the maximum used! */
17701932 PolyBBExtras pextra;
1933+ int n_points = 0;
1934+ int idx = arrow_index_from_type(arrow->type);
17711935
17721936 if (ARROW_NONE == arrow->type)
17731937 return; /* bbox not growing */
17741938
17751939 /* some extra steps necessary for e.g circle shapes? */
1776- calculate_arrow(poly, to, from, arrow->length, arrow->width);
1777-
1940+ if (arrow_types[idx].calculate)
1941+ n_points = arrow_types[idx].calculate (poly, to, from, arrow->length, arrow->width);
1942+ else /* fallback, should vanish */
1943+ n_points = calculate_arrow(poly, to, from, arrow->length, arrow->width);
1944+ g_assert (n_points > 0 && n_points <= sizeof(poly)/sizeof(Point));
1945+
17781946 pextra.start_trans = pextra.end_trans =
17791947 pextra.start_long = pextra.end_long =
17801948 pextra.middle_trans = line_width/2.0;
17811949
1782- polyline_bbox (poly, N_POINTS, &pextra, TRUE, rect);
1783-
1784-#undef N_POINTS
1950+ polyline_bbox (poly, n_points, &pextra, TRUE, rect);
17851951 }
17861952
17871953 /** Draw any arrowhead.
@@ -1804,72 +1970,12 @@ arrow_draw(DiaRenderer *renderer, ArrowType type,
18041970 switch(type) {
18051971 case ARROW_NONE:
18061972 break;
1807- case ARROW_LINES:
1808- draw_lines(renderer, to, from, length, width, linewidth, fg_color);
1809- break;
1810- case ARROW_HALF_HEAD:
1811- draw_halfhead(renderer, to, from, length, width, linewidth, fg_color);
1812- break;
1813- case ARROW_HOLLOW_TRIANGLE:
1814- fill_triangle(renderer, to, from, length, width, bg_color);
1815- draw_triangle(renderer, to, from, length, width, linewidth, fg_color);
1816- break;
1817- case ARROW_UNFILLED_TRIANGLE:
1818- draw_triangle(renderer, to, from, length, width, linewidth, fg_color);
1819- break;
1820- case ARROW_FILLED_TRIANGLE:
1821- fill_triangle(renderer, to, from, length, width, fg_color);
1822- break;
1823- case ARROW_HOLLOW_DIAMOND:
1824- fill_diamond(renderer, to, from, length, width, bg_color);
1825- draw_diamond(renderer, to, from, length, width, linewidth, fg_color);
1826- break;
1827- case ARROW_FILLED_DIAMOND:
1828- fill_diamond(renderer, to, from, length, width, fg_color);
1829- break;
1830- case ARROW_HALF_DIAMOND:
1831- /* fill_diamond(renderer, to, from, length, width, bg_color);*/
1832- draw_half_diamond(renderer, to, from, length, width, linewidth, fg_color);
1833- break;
1834- case ARROW_SLASHED_CROSS:
1835- draw_slashed_cross(renderer, to, from, length, width, linewidth, fg_color);
1836- break;
1837- case ARROW_FILLED_ELLIPSE:
1838- draw_fill_ellipse(renderer,to,from,length,width,linewidth,
1839- fg_color,NULL);
1840- break;
1841- case ARROW_HOLLOW_ELLIPSE:
1842- draw_fill_ellipse(renderer,to,from,length,width,linewidth,
1843- fg_color,bg_color);
1844- break;
1845- case ARROW_DOUBLE_HOLLOW_TRIANGLE:
1846- fill_double_triangle(renderer, to, from, length+(linewidth/2), width, bg_color);
1847- draw_double_triangle(renderer, to, from, length, width, linewidth, fg_color);
1848- break;
1849- case ARROW_DOUBLE_FILLED_TRIANGLE:
1850- fill_double_triangle(renderer, to, from, length, width, fg_color);
1851- break;
1852- case ARROW_FILLED_DOT:
1853- draw_fill_dot(renderer,to,from,length,width,linewidth,fg_color,fg_color);
1854- break;
1855- case ARROW_BLANKED_DOT:
1856- draw_fill_dot(renderer,to,from,length,width,linewidth,fg_color,bg_color);
1857- break;
1858- case ARROW_FILLED_BOX:
1859- draw_fill_box(renderer,to,from,length,width,linewidth,fg_color,fg_color);
1860- break;
1861- case ARROW_BLANKED_BOX:
1862- draw_fill_box(renderer,to,from,length,width,linewidth,fg_color,bg_color);
1863- break;
18641973 case ARROW_DIMENSION_ORIGIN:
18651974 draw_fill_dot(renderer,to,from,length,width,linewidth,fg_color,NULL);
18661975 break;
18671976 case ARROW_INTEGRAL_SYMBOL:
18681977 draw_integral(renderer,to,from,length,width,linewidth,fg_color);
18691978 break;
1870- case ARROW_SLASH_ARROW:
1871- draw_slashed(renderer,to,from,length,width,linewidth,fg_color);
1872- break;
18731979 case ARROW_ONE_OR_MANY:
18741980 draw_one_or_many(renderer,to,from,length,width,linewidth,fg_color,bg_color);
18751981 break;
@@ -1882,18 +1988,6 @@ arrow_draw(DiaRenderer *renderer, ArrowType type,
18821988 case ARROW_ONE_OR_NONE:
18831989 draw_one_or_none(renderer,to,from,length,width,linewidth,fg_color,bg_color);
18841990 break;
1885- case ARROW_CROW_FOOT:
1886- draw_crow_foot(renderer,to,from,length,width,linewidth,fg_color,bg_color);
1887- break;
1888- case ARROW_CROSS:
1889- draw_cross(renderer, to, from, length, width, linewidth, fg_color);
1890- break;
1891- case ARROW_FILLED_CONCAVE:
1892- draw_concave_triangle(renderer, to, from, length, width, linewidth, fg_color, fg_color);
1893- break;
1894- case ARROW_BLANKED_CONCAVE:
1895- draw_concave_triangle(renderer, to, from, length, width, linewidth, fg_color, bg_color);
1896- break;
18971991 case ARROW_ROUNDED:
18981992 draw_rounded(renderer, to, from, length, width, linewidth, fg_color, bg_color);
18991993 break;
@@ -1905,14 +1999,18 @@ arrow_draw(DiaRenderer *renderer, ArrowType type,
19051999 draw_filled_dot_n_triangle(renderer, to, from, length, width, linewidth,
19062000 fg_color, bg_color);
19072001 break;
1908- case ARROW_BACKSLASH:
1909- draw_backslash(renderer,to,from,length,width,linewidth,fg_color);
1910- break;
19112002 case ARROW_THREE_DOTS:
19122003 draw_three_dots(renderer,to,from,length,width,linewidth,fg_color);
19132004 break;
19142005 case MAX_ARROW_TYPE:
19152006 break;
2007+ default :
2008+ {
2009+ int idx = arrow_index_from_type(type);
2010+ g_return_if_fail (arrow_types[idx].draw != NULL);
2011+ arrow_types[idx].draw (renderer,to,from,length,width,linewidth,fg_color,bg_color);
2012+ break;
2013+ }
19162014 }
19172015 if ((type != ARROW_NONE) && (render_bounding_boxes) && (renderer->is_interactive)) {
19182016 Arrow arrow = {type, length, width};
--- a/lib/boundingbox.c
+++ b/lib/boundingbox.c
@@ -201,7 +201,7 @@ line_bbox(const Point *p1, const Point *p2,
201201 rect->left = rect->right = p1->x;
202202 rect->top = rect->bottom = p1->y;
203203
204- rectangle_add_point(rect,p2); /* as a safety */
204+ rectangle_add_point(rect,p2); /* as a safety, so we don't need to care if it above or below p1 */
205205
206206 point_copy_add_scaled(&vl,p1,p2,-1);
207207 point_normalize(&vl);
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -554,6 +554,7 @@ EXPORTS
554554 point_add_scaled
555555 point_convex
556556 point_copy
557+ point_cross
557558 point_dot
558559 point_len
559560 point_normalize
--- a/objects/standard/arc.c
+++ b/objects/standard/arc.c
@@ -737,6 +737,21 @@ arc_copy(Arc *arc)
737737 return &newarc->connection.object;
738738 }
739739
740+/* copied from lib/diarenderer.c, the one there should be removed */
741+static gboolean
742+is_right_hand (const Point *a, const Point *b, const Point *c)
743+{
744+ Point dot1, dot2;
745+
746+ dot1 = *a;
747+ point_sub(&dot1, c);
748+ point_normalize(&dot1);
749+ dot2 = *b;
750+ point_sub(&dot2, c);
751+ point_normalize(&dot2);
752+ return point_cross(&dot1, &dot2) > 0;
753+}
754+
740755 static void
741756 arc_update_data(Arc *arc)
742757 {
@@ -747,6 +762,7 @@ arc_update_data(Arc *arc)
747762 real x1,y1,x2,y2,xc,yc;
748763 real lensq, alpha, radius;
749764 real angle1, angle2;
765+ gboolean righthand;
750766
751767 endpoints = &arc->connection.endpoints[0];
752768 x1 = endpoints[0].x;
@@ -791,7 +807,12 @@ arc_update_data(Arc *arc)
791807 extra->start_long =
792808 extra->end_long = (arc->line_width / 2.0);
793809
810+ /* updates midpoint */
811+ arc_update_handles(arc);
812+ /* startpoint, midpoint, endpoint */
813+ righthand = is_right_hand (&endpoints[0], &arc->middle_handle.pos, &endpoints[1]);
794814 connection_update_boundingbox(conn);
815+
795816 /* fix boundingbox for arc's special shape XXX find a more elegant way: */
796817 if (in_angle(0, arc->angle1, arc->angle2)) {
797818 /* rigth side, y does not matter if included */
@@ -805,7 +826,7 @@ arc_update_data(Arc *arc)
805826 }
806827 if (in_angle(180, arc->angle1, arc->angle2)) {
807828 /* left side, y does not matter if included */
808- Point pt = { arc->center.x - arc->radius - (arc->line_width / 2.0) };
829+ Point pt = { arc->center.x - arc->radius - (arc->line_width / 2.0), y1 };
809830 rectangle_add_point (&obj->bounding_box, &pt);
810831 }
811832 if (in_angle(270, arc->angle1, arc->angle2)) {
@@ -824,22 +845,18 @@ arc_update_data(Arc *arc)
824845 Point from = to;
825846 point_sub (&from, &arc->center);
826847 tmp = from.x;
827- if (angle2 > angle1)
848+ if (righthand)
828849 from.x = -from.y, from.y = tmp;
829850 else
830851 from.x = from.y, from.y = -tmp;
831852 point_add (&from, &to);
832-#if 0
853+
833854 calculate_arrow_point(&arc->start_arrow, &to, &from,
834855 &move_arrow, &move_line, arc->line_width);
835- /* make them absolute positions, i.e. moved */
836- point_add(&move_arrow, &to);
837- point_add(&move_line, &from);
838- arrow_bbox(&arc->start_arrow, arc->line_width, &move_arrow, &move_line, &bbox);
839-#else
856+ /* move them */
857+ point_sub(&to, &move_arrow);
858+ point_sub(&from, &move_line);
840859 arrow_bbox(&arc->start_arrow, arc->line_width, &to, &from, &bbox);
841-#endif
842- /* to test the bounding box it was quite useful to */
843860 rectangle_union(&obj->bounding_box, &bbox);
844861 }
845862 if (arc->end_arrow.type != ARROW_NONE) {
@@ -850,23 +867,21 @@ arc_update_data(Arc *arc)
850867 Point from = to;
851868 point_sub (&from, &arc->center);
852869 tmp = from.x;
853- if (angle2 > angle1)
870+ if (righthand)
854871 from.x = from.y, from.y = -tmp;
855872 else
856873 from.x = -from.y, from.y = tmp;
857874 point_add (&from, &to);
858875 calculate_arrow_point(&arc->end_arrow, &to, &from,
859876 &move_arrow, &move_line, arc->line_width);
860- /* make them absolute positions, i.e. moved */
861- point_add(&move_arrow, &to);
862- point_add(&move_line, &from);
863- arrow_bbox(&arc->end_arrow, arc->line_width, &move_arrow, &move_line, &bbox);
877+ /* move them */
878+ point_sub(&to, &move_arrow);
879+ point_sub(&from, &move_line);
880+ arrow_bbox(&arc->end_arrow, arc->line_width, &to, &from, &bbox);
864881 rectangle_union(&obj->bounding_box, &bbox);
865882 }
866883
867884 obj->position = conn->endpoints[0];
868-
869- arc_update_handles(arc);
870885 }
871886
872887 static void
--- a/objects/standard/bezier.c
+++ b/objects/standard/bezier.c
@@ -508,31 +508,49 @@ bezierline_update_data(Bezierline *bezierline)
508508
509509 bezierconn_update_data(bez);
510510
511- extra->start_trans = (bezierline->line_width / 2.0);
512- extra->end_trans = (bezierline->line_width / 2.0);
513- extra->middle_trans = (bezierline->line_width / 2.0);
514-
515- if (bezierline->start_arrow.type != ARROW_NONE)
516- extra->start_trans = MAX(extra->start_trans,bezierline->start_arrow.width);
517- if (bezierline->end_arrow.type != ARROW_NONE)
518- extra->end_trans = MAX(extra->end_trans,bezierline->end_arrow.width);
519-
520- extra->start_long = (bezierline->line_width / 2.0);
521- extra->end_long = (bezierline->line_width / 2.0);
511+ extra->start_trans = extra->start_long =
512+ extra->middle_trans =
513+ extra->end_trans = extra->end_long = (bezierline->line_width / 2.0);
522514
523515 obj->position = bez->points[0].p1;
524516
525517 if (connpoint_is_autogap(bez->object.handles[0]->connected_to) ||
526518 connpoint_is_autogap(bez->object.handles[3*(bez->numpoints-1)]->connected_to) ||
527- bezierline->absolute_start_gap || bezierline->absolute_end_gap) {
519+ bezierline->absolute_start_gap || bezierline->absolute_end_gap ||
520+ bezierline->start_arrow.type != ARROW_NONE || bezierline->end_arrow.type != ARROW_NONE) {
528521 Point gap_points[4];
522+ Rectangle bbox_union = {bez->points[0].p1.x, bez->points[0].p1.y, bez->points[0].p1.x, bez->points[0].p1.y};
529523 compute_gap_points(bezierline, gap_points);
530524 exchange_bez_gap_points(bez,gap_points);
525+ /* further modifying the points data, accounts for corrcet arrow and bezier bounding box */
526+ if (bezierline->start_arrow.type != ARROW_NONE) {
527+ Rectangle bbox;
528+ Point move_arrow, move_line;
529+ Point to = bez->points[0].p1, from = bez->points[1].p1;
530+
531+ calculate_arrow_point(&bezierline->start_arrow, &to, &from, &move_arrow, &move_line, bezierline->line_width);
532+ point_sub(&to, &move_arrow);
533+ point_sub(&bez->points[0].p1, &move_line);
534+ arrow_bbox (&bezierline->start_arrow, bezierline->line_width, &to, &from, &bbox);
535+ rectangle_union (&bbox_union, &bbox);
536+ }
537+ if (bezierline->end_arrow.type != ARROW_NONE) {
538+ Rectangle bbox;
539+ Point move_arrow, move_line;
540+ int num_points = bez->numpoints;
541+ Point to = bez->points[num_points-1].p3, from = bez->points[num_points-1].p2;
542+
543+ calculate_arrow_point(&bezierline->end_arrow, &to, &from, &move_arrow, &move_line, bezierline->line_width);
544+ point_sub(&to, &move_arrow);
545+ point_sub(&bez->points[num_points-1].p3, &move_line);
546+ arrow_bbox (&bezierline->end_arrow, bezierline->line_width, &to, &from, &bbox);
547+ rectangle_union (&bbox_union, &bbox);
548+ }
531549 bezierconn_update_boundingbox(bez);
532- exchange_bez_gap_points(bez,gap_points);
533-
550+ rectangle_union (&obj->bounding_box, &bbox_union);
551+ exchange_bez_gap_points(bez,gap_points);
534552 } else {
535- bezierconn_update_boundingbox(bez);
553+ bezierconn_update_boundingbox(bez);
536554 }
537555
538556 }
--- a/objects/standard/line.c
+++ b/objects/standard/line.c
@@ -513,14 +513,10 @@ line_update_data(Line *line)
513513 LineBBExtras *extra = &conn->extra_spacing;
514514 Point start, end;
515515
516- extra->start_trans = (line->line_width / 2.0);
517- extra->end_trans = (line->line_width / 2.0);
518- extra->start_long = (line->line_width / 2.0);
516+ extra->start_trans =
517+ extra->end_trans =
518+ extra->start_long =
519519 extra->end_long = (line->line_width / 2.0);
520- if (line->start_arrow.type != ARROW_NONE)
521- extra->start_trans = MAX(extra->start_trans,line->start_arrow.width);
522- if (line->end_arrow.type != ARROW_NONE)
523- extra->end_trans = MAX(extra->end_trans,line->end_arrow.width);
524520
525521 if (connpoint_is_autogap(line->connection.endpoint_handles[0].connected_to) ||
526522 connpoint_is_autogap(line->connection.endpoint_handles[1].connected_to)) {
@@ -539,11 +535,39 @@ line_update_data(Line *line)
539535 start = conn->endpoints[0];
540536 end = conn->endpoints[1];
541537 }
538+ if (line->start_arrow.type != ARROW_NONE) {
539+ Rectangle bbox;
540+ Point move_arrow, move_line;
541+ Point to = start;
542+ Point from = end;
543+ calculate_arrow_point(&line->start_arrow, &to, &from,
544+ &move_arrow, &move_line, line->line_width);
545+ /* move them */
546+ point_sub(&to, &move_arrow);
547+ point_sub(&from, &move_line);
548+
549+ arrow_bbox (&line->start_arrow, line->line_width, &to, &from, &bbox);
550+ rectangle_union (&obj->bounding_box, &bbox);
551+ }
552+ if (line->end_arrow.type != ARROW_NONE) {
553+ Rectangle bbox;
554+ Point move_arrow, move_line;
555+ Point to = end;
556+ Point from = start;
557+ calculate_arrow_point(&line->start_arrow, &to, &from,
558+ &move_arrow, &move_line, line->line_width);
559+ /* move them */
560+ point_sub(&to, &move_arrow);
561+ point_sub(&from, &move_line);
562+
563+ arrow_bbox (&line->end_arrow, line->line_width, &to, &from, &bbox);
564+ rectangle_union (&obj->bounding_box, &bbox);
565+ }
542566
543567 obj->position = conn->endpoints[0];
544568
545569 connpointline_update(line->cpl);
546- connpointline_putonaline(line->cpl,&start, &end);
570+ connpointline_putonaline(line->cpl, &start, &end);
547571
548572 connection_update_handles(conn);
549573 }
--- a/objects/standard/polyline.c
+++ b/objects/standard/polyline.c
@@ -411,23 +411,53 @@ polyline_update_data(Polyline *polyline)
411411 PolyConn *poly = &polyline->poly;
412412 DiaObject *obj = &poly->object;
413413 PolyBBExtras *extra = &poly->extra_spacing;
414+ Point gap_endpoints[2];
414415
415416 polyconn_update_data(&polyline->poly);
416417
417418 extra->start_trans = (polyline->line_width / 2.0);
418419 extra->end_trans = (polyline->line_width / 2.0);
419420 extra->middle_trans = (polyline->line_width / 2.0);
420-
421- if (polyline->start_arrow.type != ARROW_NONE)
422- extra->start_trans = MAX(extra->start_trans,polyline->start_arrow.width);
423- if (polyline->end_arrow.type != ARROW_NONE)
424- extra->end_trans = MAX(extra->end_trans,polyline->end_arrow.width);
425-
426421 extra->start_long = (polyline->line_width / 2.0);
427422 extra->end_long = (polyline->line_width / 2.0);
428423
424+ polyline_calculate_gap_endpoints(polyline, gap_endpoints);
425+ polyline_exchange_gap_points(polyline, gap_endpoints);
426+
429427 polyconn_update_boundingbox(poly);
430428
429+ if (polyline->start_arrow.type != ARROW_NONE) {
430+ Rectangle bbox;
431+ Point move_arrow, move_line;
432+ Point to = gap_endpoints[0];
433+ Point from = poly->points[1];
434+ calculate_arrow_point(&polyline->start_arrow, &to, &from,
435+ &move_arrow, &move_line, polyline->line_width);
436+ /* move them */
437+ point_sub(&to, &move_arrow);
438+ point_sub(&from, &move_line);
439+
440+ arrow_bbox (&polyline->start_arrow, polyline->line_width, &to, &from, &bbox);
441+ rectangle_union (&obj->bounding_box, &bbox);
442+ }
443+ if (polyline->end_arrow.type != ARROW_NONE) {
444+ Rectangle bbox;
445+ int n = polyline->poly.numpoints;
446+ Point move_arrow, move_line;
447+ Point to = gap_endpoints[1];
448+ Point from = poly->points[n-2];
449+ calculate_arrow_point(&polyline->start_arrow, &to, &from,
450+ &move_arrow, &move_line, polyline->line_width);
451+ /* move them */
452+ point_sub(&to, &move_arrow);
453+ point_sub(&from, &move_line);
454+
455+ arrow_bbox (&polyline->end_arrow, polyline->line_width, &to, &from, &bbox);
456+ rectangle_union (&obj->bounding_box, &bbox);
457+ }
458+
459+ polyline_exchange_gap_points(polyline, gap_endpoints);
460+
431461 obj->position = poly->points[0];
432462 }
433463
--- a/objects/standard/zigzagline.c
+++ b/objects/standard/zigzagline.c
@@ -308,22 +308,48 @@ static void
308308 zigzagline_update_data(Zigzagline *zigzagline)
309309 {
310310 OrthConn *orth = &zigzagline->orth;
311+ DiaObject *obj = &orth->object;
311312 PolyBBExtras *extra = &orth->extra_spacing;
312313
313314 orthconn_update_data(&zigzagline->orth);
314315
315316 extra->start_long =
316317 extra->end_long =
317- extra->middle_trans = zigzagline->line_width/2.0;
318- extra->start_trans = (zigzagline->line_width / 2.0);
319- extra->end_trans = (zigzagline->line_width / 2.0);
320-
321- if (zigzagline->start_arrow.type != ARROW_NONE)
322- extra->start_trans = MAX(extra->start_trans,zigzagline->start_arrow.width);
323- if (zigzagline->end_arrow.type != ARROW_NONE)
324- extra->end_trans = MAX(extra->end_trans,zigzagline->end_arrow.width);
325-
318+ extra->middle_trans =
319+ extra->start_trans =
320+ extra->end_trans = (zigzagline->line_width / 2.0);
321+
326322 orthconn_update_boundingbox(orth);
323+
324+ if (zigzagline->start_arrow.type != ARROW_NONE) {
325+ Rectangle bbox;
326+ Point move_arrow, move_line;
327+ Point to = orth->points[0];
328+ Point from = orth->points[1];
329+ calculate_arrow_point(&zigzagline->start_arrow, &to, &from,
330+ &move_arrow, &move_line, zigzagline->line_width);
331+ /* move them */
332+ point_sub(&to, &move_arrow);
333+ point_sub(&from, &move_line);
334+
335+ arrow_bbox (&zigzagline->start_arrow, zigzagline->line_width, &to, &from, &bbox);
336+ rectangle_union (&obj->bounding_box, &bbox);
337+ }
338+ if (zigzagline->end_arrow.type != ARROW_NONE) {
339+ Rectangle bbox;
340+ Point move_arrow, move_line;
341+ int n = orth->numpoints;
342+ Point to = orth->points[n-1];
343+ Point from = orth->points[n-2];
344+ calculate_arrow_point(&zigzagline->start_arrow, &to, &from,
345+ &move_arrow, &move_line, zigzagline->line_width);
346+ /* move them */
347+ point_sub(&to, &move_arrow);
348+ point_sub(&from, &move_line);
349+
350+ arrow_bbox (&zigzagline->end_arrow, zigzagline->line_width, &to, &from, &bbox);
351+ rectangle_union (&obj->bounding_box, &bbox);
352+ }
327353 }
328354
329355 static ObjectChange *
Binary files a/samples/arrows.dia and b/samples/arrows.dia differ