1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #define finite(d) _finite(d)
33 #define finite(d) isfinite(d)
37 #include "diarenderer.h"
40 struct menudesc arrow_types
[] =
41 {{N_("None"),ARROW_NONE
},
42 {N_("Lines"),ARROW_LINES
},
43 {N_("Hollow Triangle"),ARROW_HOLLOW_TRIANGLE
},
44 {N_("Filled Triangle"),ARROW_FILLED_TRIANGLE
},
45 {N_("Unfilled Triangle"),ARROW_UNFILLED_TRIANGLE
},
46 {N_("Hollow Diamond"),ARROW_HOLLOW_DIAMOND
},
47 {N_("Filled Diamond"),ARROW_FILLED_DIAMOND
},
48 {N_("Half Diamond"), ARROW_HALF_DIAMOND
},
49 {N_("Half Head"),ARROW_HALF_HEAD
},
50 {N_("Slashed Cross"),ARROW_SLASHED_CROSS
},
51 {N_("Filled Ellipse"),ARROW_FILLED_ELLIPSE
},
52 {N_("Hollow Ellipse"),ARROW_HOLLOW_ELLIPSE
},
53 {N_("Filled Dot"),ARROW_FILLED_DOT
},
54 {N_("Dimension Origin"),ARROW_DIMENSION_ORIGIN
},
55 {N_("Blanked Dot"),ARROW_BLANKED_DOT
},
56 {N_("Double Hollow Triangle"),ARROW_DOUBLE_HOLLOW_TRIANGLE
},
57 {N_("Double Filled Triangle"),ARROW_DOUBLE_FILLED_TRIANGLE
},
58 {N_("Filled Dot and Triangle"), ARROW_FILLED_DOT_N_TRIANGLE
},
59 {N_("Filled Box"),ARROW_FILLED_BOX
},
60 {N_("Blanked Box"),ARROW_BLANKED_BOX
},
61 {N_("Slashed"),ARROW_SLASH_ARROW
},
62 {N_("Integral Symbol"),ARROW_INTEGRAL_SYMBOL
},
63 {N_("Crow Foot"),ARROW_CROW_FOOT
},
64 {N_("Cross"),ARROW_CROSS
},
65 {N_("1-or-many"),ARROW_ONE_OR_MANY
},
66 {N_("0-or-many"),ARROW_NONE_OR_MANY
},
67 {N_("1-or-0"),ARROW_ONE_OR_NONE
},
68 {N_("1 exactly"),ARROW_ONE_EXACTLY
},
69 {N_("Filled Concave"),ARROW_FILLED_CONCAVE
},
70 {N_("Blanked Concave"),ARROW_BLANKED_CONCAVE
},
71 {N_("Round"), ARROW_ROUNDED
},
72 {N_("Open Round"), ARROW_OPEN_ROUNDED
},
73 {N_("Backslash"),ARROW_BACKSLASH
},
74 {N_("Infinite Line"),ARROW_THREE_DOTS
},
77 /**** prototypes ****/
79 draw_empty_ellipse(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
80 real length
, real width
, real linewidth
,
83 calculate_double_arrow(Point
*second_to
, Point
*second_from
,
84 Point
*to
, Point
*from
, real length
);
87 draw_crow_foot(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
88 real length
, real width
, real linewidth
,
89 Color
*fg_color
,Color
*bg_color
);
91 calculate_diamond(Point
*poly
/*[4]*/, Point
*to
, Point
*from
,
92 real length
, real width
);
94 /** The function calculate_arrow_point adjusts the placement of the line and
95 * the arrow, so that the arrow doesn't overshoot the connectionpoint and the
96 * line doesn't stick out the other end of the arrow.
97 * @param arrow An arrow to calculate adjustments for. The arrow type
98 * determins what adjustments are done..
99 * @param to Where the arrow points to (e.g. connection point)
100 * @param from Where the arrow points from (e.g. bezier control line end)
101 * @param move_arrow A place to return the new end point of the arrow head
102 * (i.e. where 'to' should be to render the arrow head well)
103 * @param move_line A place to return the new end point of the line (i.e.
104 * where 'to' should be to render the connecting line without
105 * leaving bits of its linewidth outside the arrow).
106 * @param linewidth The linewidth used for drawing both arrow and line.
109 calculate_arrow_point(const Arrow
*arrow
, const Point
*to
, const Point
*from
,
110 Point
*move_arrow
, Point
*move_line
,
117 /* Otherwise line is drawn through arrow
118 * head for some hollow arrow heads
120 if (linewidth
== 0.0)
123 /* First, we move the arrow head backwards.
124 * This in most cases just accounts for the linewidth of the arrow.
125 * In pointy arrows, this means we must look at the angle of the
128 switch (arrow
->type
) {
130 case ARROW_HOLLOW_TRIANGLE
:
131 case ARROW_UNFILLED_TRIANGLE
:
132 case ARROW_FILLED_CONCAVE
:
133 case ARROW_BLANKED_CONCAVE
:
134 case ARROW_DOUBLE_HOLLOW_TRIANGLE
:
135 if (arrow
->width
< 0.0000001) return;
136 angle
= atan(arrow
->length
/(arrow
->width
/2));
137 if (angle
< 75*2*G_PI
/360.0) {
138 add_len
= .5*linewidth
/cos(angle
);
144 point_sub(move_arrow
, from
);
145 point_normalize(move_arrow
);
146 point_scale(move_arrow
, add_len
);
148 case ARROW_HALF_HEAD
:
149 if (arrow
->width
< 0.0000001) return;
150 angle
= atan(arrow
->length
/(arrow
->width
/2));
151 if (angle
< 60*2*G_PI
/360.0) {
152 add_len
= linewidth
/cos(angle
);
158 point_sub(move_arrow
, from
);
159 point_normalize(move_arrow
);
160 point_scale(move_arrow
, add_len
);
162 case ARROW_FILLED_TRIANGLE
:
163 case ARROW_HOLLOW_ELLIPSE
:
165 case ARROW_DIMENSION_ORIGIN
:
166 case ARROW_BLANKED_DOT
:
167 case ARROW_BLANKED_BOX
:
168 add_len
= .5*linewidth
;
171 point_sub(move_arrow
, from
);
172 point_normalize(move_arrow
);
173 point_scale(move_arrow
, add_len
);
175 case ARROW_ONE_EXACTLY
:
176 case ARROW_ONE_OR_NONE
:
177 case ARROW_ONE_OR_MANY
:
178 case ARROW_NONE_OR_MANY
:
185 /* Now move the line to be behind the arrowhead. */
186 switch (arrow
->type
) {
188 case ARROW_HALF_HEAD
:
189 *move_line
= *move_arrow
;
190 point_scale(move_line
, 2.0);
192 case ARROW_HOLLOW_TRIANGLE
:
193 case ARROW_UNFILLED_TRIANGLE
:
194 case ARROW_FILLED_TRIANGLE
:
195 case ARROW_FILLED_ELLIPSE
:
196 case ARROW_HOLLOW_ELLIPSE
:
198 *move_line
= *move_arrow
;
199 point_normalize(move_line
);
200 point_scale(move_line
, arrow
->length
);
201 point_add(move_line
, move_arrow
);
203 case ARROW_HALF_DIAMOND
:
204 case ARROW_OPEN_ROUNDED
:
205 /* These don't move the arrow, so *move_arrow can't be used. */
207 point_sub(move_line
, from
);
208 point_normalize(move_line
);
209 point_scale(move_line
, arrow
->length
);
210 point_add(move_line
, move_arrow
);
212 case ARROW_HOLLOW_DIAMOND
:
213 case ARROW_FILLED_DIAMOND
:
214 /* Make move_line be a unit vector in direction of line */
216 point_sub(move_line
, from
);
217 point_normalize(move_line
);
219 /* Set the length to arrow_length - \/2*linewidth */
221 point_scale(move_line
, arrow
->length
);
222 point_scale(&tmp
, G_SQRT2
*linewidth
);
223 point_sub(move_line
, &tmp
);
225 case ARROW_DIMENSION_ORIGIN
:
226 case ARROW_BLANKED_DOT
:
227 case ARROW_BLANKED_BOX
:
228 *move_line
= *move_arrow
;
229 point_normalize(move_line
);
230 point_scale(move_line
, .5*arrow
->length
);
232 case ARROW_FILLED_DOT
:
233 case ARROW_FILLED_BOX
:
235 point_sub(move_line
, from
);
236 point_normalize(move_line
);
237 point_scale(move_line
, .5*arrow
->length
);
239 case ARROW_FILLED_CONCAVE
:
240 case ARROW_BLANKED_CONCAVE
:
241 *move_line
= *move_arrow
;
242 point_normalize(move_line
);
243 point_scale(move_line
, .75*arrow
->length
);
244 point_add(move_line
, move_arrow
);
246 case ARROW_DOUBLE_HOLLOW_TRIANGLE
:
247 *move_line
= *move_arrow
;
248 point_normalize(move_line
);
250 point_scale(move_line
, 2.0*arrow
->length
);
251 point_add(move_line
, move_arrow
);
252 point_scale(&tmp
, linewidth
);
253 point_add(move_line
, &tmp
);
255 case ARROW_DOUBLE_FILLED_TRIANGLE
:
257 point_sub(move_line
, from
);
258 point_normalize(move_line
);
259 point_scale(move_line
, 2*arrow
->length
);
261 case ARROW_FILLED_DOT_N_TRIANGLE
:
263 point_sub(move_line
, from
);
264 point_normalize(move_line
);
265 point_scale(move_line
, arrow
->length
+ arrow
->width
);
267 case ARROW_THREE_DOTS
:
269 point_sub(move_line
, from
);
270 add_len
= point_len(move_line
);
271 point_normalize(move_line
);
272 if (add_len
> 4*arrow
->length
)
273 point_scale(move_line
, 2*arrow
->length
);
275 point_scale(move_line
, arrow
->length
);
277 case ARROW_SLASH_ARROW
:
278 case ARROW_INTEGRAL_SYMBOL
:
280 point_sub(move_line
, from
);
281 add_len
= point_len(move_line
);
282 point_normalize(move_line
);
283 point_scale(move_line
, arrow
->length
/ 2);
285 case ARROW_ONE_EXACTLY
:
286 case ARROW_ONE_OR_NONE
:
287 case ARROW_ONE_OR_MANY
:
288 case ARROW_NONE_OR_MANY
:
298 /** Calculate the corners of a normal arrow.
299 * @param poly A three-element array in which to return the three points
300 * involved in making a simple arrow: poly[0] is the right-
301 * hand point, poly[1] is the tip, and poly[2] is the left-hand
303 * @param to Where the arrow is pointing to
304 * @param from Where the arrow is pointing from (e.g. the end of the stem)
305 * @param length How long the arrowhead should be.
306 * @param width How wide the arrowhead should be.
309 calculate_arrow(Point
*poly
, Point
*to
, Point
*from
,
310 real length
, real width
)
317 point_sub(&delta
, from
);
318 len
= point_len(&delta
);
327 orth_delta
.x
= delta
.y
;
328 orth_delta
.y
= -delta
.x
;
330 point_scale(&delta
, length
);
331 point_scale(&orth_delta
, width
/2.0);
334 point_sub(&poly
[0], &delta
);
335 point_sub(&poly
[0], &orth_delta
);
338 point_sub(&poly
[2], &delta
);
339 point_add(&poly
[2], &orth_delta
);
342 /** Calculate the actual point of a crows-foot arrow.
343 * @param poly A three-element array in which to return the three points
344 * involved in making a simple arrow: poly[0] is the tip, poly[1]
345 * is the right-hand point, and poly[2] is the left-hand point.
346 * @param to Where the arrow is pointing to
347 * @param from Where the arrow is pointing from (e.g. the end of the stem)
348 * @param length How long the arrowhead should be.
349 * @param width How wide the arrowhead should be.
352 calculate_crow(Point
*poly
, Point
*to
, Point
*from
,
353 real length
, real width
)
360 point_sub(&delta
, from
);
361 len
= point_len(&delta
);
370 orth_delta
.x
= delta
.y
;
371 orth_delta
.y
= -delta
.x
;
373 point_scale(&delta
, length
);
374 point_scale(&orth_delta
, width
/2.0);
377 point_sub(&poly
[0], &delta
);
379 point_sub(&poly
[1], &orth_delta
);
381 point_add(&poly
[2], &orth_delta
);
384 /** Draw ER arrow for 0..N according to Modern database management,
385 * McFadden/Hoffer/Prescott, Addison-Wessley, 1999
386 * @param renderer A renderer instance to draw into
387 * @param to The point that the arrow points to.
388 * @param from Where the arrow points from (e.g. end of stem)
389 * @param length The length of the arrow
390 * @param width The width of the arrow
391 * @param linewidth The thickness of the lines used to draw the arrow.
392 * @param fg_color The color used for drawing the arrow lines.
393 * @param bg_color Ignored.
394 * @todo The ER-drawing methods are ripe for some refactoring.
397 draw_none_or_many(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
398 real length
, real width
, real linewidth
,
399 Color
*fg_color
,Color
*bg_color
)
401 Point second_from
, second_to
;
403 draw_crow_foot(renderer
, to
, from
, length
, width
,
404 linewidth
, fg_color
, bg_color
);
406 calculate_double_arrow(&second_to
, &second_from
, to
, from
, length
);
407 /* use the middle of the arrow */
409 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
410 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
411 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
412 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
414 draw_empty_ellipse(renderer
, &second_to
, &second_from
, length
/2,
415 width
, linewidth
, fg_color
);
418 /** ER arrow for exactly-one relations according to Modern database management,
419 * McFadden/Hoffer/Prescott, Addison-Wessley, 1999
420 * @param renderer A renderer instance to draw into
421 * @param to The point that the arrow points to.
422 * @param from Where the arrow points from (e.g. end of stem)
423 * @param length The length of the arrow
424 * @param width The width of the arrow
425 * @param linewidth The thickness of the lines used to draw the arrow.
426 * @param fg_color The color used for drawing the arrow lines.
427 * @param bg_color Ignored.
430 draw_one_exactly(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
431 real length
, real width
, real linewidth
,
432 Color
*fg_color
,Color
*bg_color
)
438 point_copy(&vl
,from
); point_sub(&vl
,to
);
439 if (point_len(&vl
) > 0)
440 point_normalize(&vl
);
442 vl
.x
= 1.0; vl
.y
= 0.0;
445 vl
.x
= 1.0; vl
.y
= 0.0;
447 point_get_perp(&vt
,&vl
);
448 point_copy_add_scaled(&bs
,to
,&vl
,length
/2);
449 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
450 point_add_scaled(&bs
,&vt
,width
/2.0);
452 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&bs
,&be
,fg_color
);
454 point_copy_add_scaled(&bs
,to
,&vl
,length
);
456 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
457 point_add_scaled(&bs
,&vt
,width
/2.0);
459 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&bs
,&be
,fg_color
);
462 /* ER arrow for 1..N according to Modern database management,
463 * McFadden/Hoffer/Prescott, Addison-Wessley, 1999
464 * @param renderer A renderer instance to draw into
465 * @param to The point that the arrow points to.
466 * @param from Where the arrow points from (e.g. end of stem)
467 * @param length The length of the arrow
468 * @param width The width of the arrow
469 * @param linewidth The thickness of the lines used to draw the arrow.
470 * @param fg_color The color used for drawing the arrow lines.
471 * @param bg_color Ignored.
474 draw_one_or_many(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
475 real length
, real width
, real linewidth
,
476 Color
*fg_color
,Color
*bg_color
)
481 draw_crow_foot(renderer
, to
, from
, length
, width
,
482 linewidth
, fg_color
, bg_color
);
484 calculate_arrow(poly
, to
, from
, length
, width
);
486 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
487 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
488 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
489 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
491 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &poly
[0],&poly
[2], fg_color
);
494 /* ER arrow for 0,1 according to Modern database management,
495 * McFadden/Hoffer/Prescott, Addison-Wessley, 1999
496 * @param renderer A renderer instance to draw into
497 * @param to The point that the arrow points to.
498 * @param from Where the arrow points from (e.g. end of stem)
499 * @param length The length of the arrow
500 * @param width The width of the arrow
501 * @param linewidth The thickness of the lines used to draw the arrow.
502 * @param fg_color The color used for drawing the arrow lines.
503 * @param bg_color Ignored.
506 draw_one_or_none(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
507 real length
, real width
, real linewidth
,
508 Color
*fg_color
,Color
*bg_color
)
512 Point second_from
, second_to
;
515 point_copy(&vl
,from
); point_sub(&vl
,to
);
516 if (point_len(&vl
) > 0)
517 point_normalize(&vl
);
519 vl
.x
= 1.0; vl
.y
= 0.0;
522 vl
.x
= 1.0; vl
.y
= 0.0;
524 point_get_perp(&vt
,&vl
);
525 point_copy_add_scaled(&bs
,to
,&vl
,length
/2);
526 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
527 point_add_scaled(&bs
,&vt
,width
/2.0);
529 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&bs
,&be
,fg_color
);
531 calculate_double_arrow(&second_to
, &second_from
, to
, from
, length
);
532 draw_empty_ellipse(renderer
, &second_to
, &second_from
, length
/2, width
, linewidth
, fg_color
);
535 /** Draw a crow's foot arrowhead.
536 * @param renderer A renderer instance to draw into
537 * @param to The point that the arrow points to.
538 * @param from Where the arrow points from (e.g. end of stem)
539 * @param length The length of the arrow
540 * @param width The width of the arrow
541 * @param linewidth The thickness of the lines used to draw the arrow.
542 * @param fg_color The color used for drawing the arrow lines.
543 * @param bg_color Ignored.
546 draw_crow_foot(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
547 real length
, real width
, real linewidth
,
548 Color
*fg_color
,Color
*bg_color
)
553 calculate_crow(poly
, to
, from
, length
, width
);
555 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
556 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
557 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
559 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&poly
[0],&poly
[1],fg_color
);
560 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&poly
[0],&poly
[2],fg_color
);
563 /** Draw a simple open line arrow.
564 * @param renderer A renderer instance to draw into
565 * @param to The point that the arrow points to.
566 * @param from Where the arrow points from (e.g. end of stem)
567 * @param length The length of the arrow
568 * @param width The width of the arrow
569 * @param linewidth The thickness of the lines used to draw the arrow.
570 * @param fg_color The color used for drawing the arrow lines.
573 draw_lines(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
574 real length
, real width
, real linewidth
,
579 calculate_arrow(poly
, to
, from
, length
, width
);
581 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
582 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
583 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
584 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
586 DIA_RENDERER_GET_CLASS(renderer
)->draw_polyline(renderer
, poly
, 3, color
);
589 /** Draw an arrowhead that is a filled ellipse.
590 * @param renderer A renderer instance to draw into
591 * @param to The point that the arrow points to.
592 * @param from Where the arrow points from (e.g. end of stem)
593 * @param length The length of the arrow
594 * @param width The width of the arrow
595 * @param linewidth The thickness of the lines used to draw the arrow.
596 * @param fg_color The color used for drawing the arrow lines.
597 * @param bg_color Used to fill the ellipse, usually white and non-settable.
598 * If null, the ellipse is filled with fg_color and slightly
599 * smaller (by linewidth/2).
602 draw_fill_ellipse(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
603 real length
, real width
, real linewidth
,
604 Color
*fg_color
,Color
*bg_color
)
609 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
610 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
611 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
612 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
615 /* no bg_color means filled ellipse ; we then compensate for the line width
620 point_copy(&vl
,from
); point_sub(&vl
,to
);
621 if (point_len(&vl
) > 0)
622 point_normalize(&vl
);
624 vl
.x
= 1.0; vl
.y
= 0.0;
627 vl
.x
= 1.0; vl
.y
= 0.0;
629 point_get_perp(&vt
,&vl
);
632 /* This pile of crap is quite well handled by gcc. */
633 bp
[0].type
= BEZ_MOVE_TO
;
634 point_copy(&bp
[0].p1
,to
);
635 bp
[1].type
= bp
[2].type
= bp
[3].type
= bp
[4].type
= BEZ_CURVE_TO
;
636 point_copy(&bp
[4].p3
,&bp
[0].p1
);
638 point_copy_add_scaled(&bp
[2].p3
,&bp
[0].p1
,&vl
,length
);
639 point_copy_add_scaled(&bp
[2].p2
,&bp
[2].p3
,&vt
,-width
/ 4.0);
640 point_copy_add_scaled(&bp
[3].p1
,&bp
[2].p3
,&vt
,width
/ 4.0);
641 point_copy_add_scaled(&bp
[1].p1
,&bp
[0].p1
,&vt
,-width
/ 4.0);
642 point_copy_add_scaled(&bp
[4].p2
,&bp
[0].p1
,&vt
,width
/ 4.0);
643 point_copy_add_scaled(&bp
[1].p3
,&bp
[0].p1
,&vl
,length
/ 2.0); /* temp */
644 point_copy_add_scaled(&bp
[3].p3
,&bp
[1].p3
,&vt
,width
/ 2.0);
645 point_add_scaled(&bp
[1].p3
,&vt
,-width
/ 2.0);
646 point_copy_add_scaled(&bp
[1].p2
,&bp
[1].p3
,&vl
,-length
/ 4.0);
647 point_copy_add_scaled(&bp
[4].p1
,&bp
[3].p3
,&vl
,-length
/ 4.0);
648 point_copy_add_scaled(&bp
[2].p1
,&bp
[1].p3
,&vl
,length
/ 4.0);
649 point_copy_add_scaled(&bp
[3].p2
,&bp
[3].p3
,&vl
,length
/ 4.0);
651 DIA_RENDERER_GET_CLASS(renderer
)->fill_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),bg_color
);
652 DIA_RENDERER_GET_CLASS(renderer
)->draw_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),fg_color
);
654 DIA_RENDERER_GET_CLASS(renderer
)->fill_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),fg_color
);
658 /** Draw an arrowhead that is an ellipse with empty interior.
659 * @param renderer A renderer instance to draw into
660 * @param to The point that the arrow points to.
661 * @param from Where the arrow points from (e.g. end of stem)
662 * @param length The length of the arrow
663 * @param width The width of the arrow
664 * @param linewidth The thickness of the lines used to draw the arrow.
665 * @param fg_color The color used for drawing the arrow lines.
668 draw_empty_ellipse(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
669 real length
, real width
, real linewidth
,
676 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
677 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
678 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
679 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
681 point_copy(&vl
,from
);
683 if (point_len(&vl
) > 0)
684 point_normalize(&vl
);
686 vl
.x
= 1.0; vl
.y
= 0.0;
689 vl
.x
= 1.0; vl
.y
= 0.0;
692 point_get_perp(&vt
,&vl
);
694 point_copy(&disp
, &vl
);
698 /* This pile of crap is quite well handled by gcc. */
699 bp
[0].type
= BEZ_MOVE_TO
;
700 point_copy(&bp
[0].p1
,to
);
701 point_add(&bp
[0].p1
,&disp
);
702 bp
[1].type
= bp
[2].type
= bp
[3].type
= bp
[4].type
= BEZ_CURVE_TO
;
703 point_copy(&bp
[4].p3
,&bp
[0].p1
);
705 point_copy_add_scaled(&bp
[2].p3
,&bp
[0].p1
,&vl
,length
);
706 point_copy_add_scaled(&bp
[2].p2
,&bp
[2].p3
,&vt
,-width
/ 4.0);
707 point_copy_add_scaled(&bp
[3].p1
,&bp
[2].p3
,&vt
,width
/ 4.0);
708 point_copy_add_scaled(&bp
[1].p1
,&bp
[0].p1
,&vt
,-width
/ 4.0);
709 point_copy_add_scaled(&bp
[4].p2
,&bp
[0].p1
,&vt
,width
/ 4.0);
710 point_copy_add_scaled(&bp
[1].p3
,&bp
[0].p1
,&vl
,length
/ 2.0); /* temp */
711 point_copy_add_scaled(&bp
[3].p3
,&bp
[1].p3
,&vt
,width
/ 2.0);
712 point_add_scaled(&bp
[1].p3
,&vt
,-width
/ 2.0);
713 point_copy_add_scaled(&bp
[1].p2
,&bp
[1].p3
,&vl
,-length
/ 4.0);
714 point_copy_add_scaled(&bp
[4].p1
,&bp
[3].p3
,&vl
,-length
/ 4.0);
715 point_copy_add_scaled(&bp
[2].p1
,&bp
[1].p3
,&vl
,length
/ 4.0);
716 point_copy_add_scaled(&bp
[3].p2
,&bp
[3].p3
,&vl
,length
/ 4.0);
718 DIA_RENDERER_GET_CLASS(renderer
)->draw_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),fg_color
);
721 /** Draw an arrow head that is an (optionall) filled box.
722 * @param renderer A renderer instance to draw into
723 * @param to The point that the arrow points to.
724 * @param from Where the arrow points from (e.g. end of stem)
725 * @param length The length of the arrow
726 * @param width The width of the arrow
727 * @param linewidth The thickness of the lines used to draw the arrow.
728 * @param fg_color The color used for drawing the arrow lines.
729 * @param bg_color The color used for the interior of the box. If
730 * fg_color == bg_color, the box is rendered slightly smaller.
733 draw_fill_box(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
734 real length
, real width
, real linewidth
,
735 Color
*fg_color
,Color
*bg_color
)
740 real lw_factor
,clength
,cwidth
;
742 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
743 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
744 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
745 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
747 if (fg_color
== bg_color
) {
749 lw_factor
= linewidth
;
751 /* Hollow dot or dimension origin */
754 clength
= length
+ lw_factor
;
755 cwidth
= width
+ lw_factor
;
757 point_copy(&vl
,from
); point_sub(&vl
,to
);
758 if (point_len(&vl
) > 0)
759 point_normalize(&vl
);
761 vl
.x
= 1.0; vl
.y
= 0.0;
764 vl
.x
= 1.0; vl
.y
= 0.0;
766 point_get_perp(&vt
,&vl
);
768 point_copy_add_scaled(&bs
,to
,&vl
,length
/4);
769 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
770 point_add_scaled(&bs
,&vt
,width
/2.0);
772 point_copy(&poly
[0],to
);
773 point_copy(&poly
[1],&poly
[0]);
774 point_add_scaled(&poly
[0],&vt
,cwidth
/4.0);
775 point_add_scaled(&poly
[1],&vt
,-cwidth
/4.0);
776 point_copy_add_scaled(&poly
[2],&poly
[1],&vl
,clength
/2.0);
777 point_copy_add_scaled(&poly
[3],&poly
[0],&vl
,clength
/2.0);
779 if (fg_color
== bg_color
) {
780 DIA_RENDERER_GET_CLASS(renderer
)->fill_polygon(renderer
, poly
, 4, fg_color
);
782 DIA_RENDERER_GET_CLASS(renderer
)->fill_polygon(renderer
, poly
, 4, bg_color
);
783 DIA_RENDERER_GET_CLASS(renderer
)->draw_polygon(renderer
, poly
, 4, fg_color
);
785 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&bs
,&be
,fg_color
);
788 /** Draw a "filled dot" arrow.
789 * @param renderer A renderer instance to draw into
790 * @param to The point that the arrow points to.
791 * @param from Where the arrow points from (e.g. end of stem)
792 * @param length The length of the arrow
793 * @param width The width of the arrow
794 * @param linewidth The thickness of the lines used to draw the arrow.
795 * @param fg_color The color used for drawing the arrow lines.
796 * @param bg_color The collor used for the interior of the dot.
797 * @bug Need to describe the diff between this and ellipse arrow.
800 draw_fill_dot(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
801 real length
, real width
, real linewidth
,
802 Color
*fg_color
,Color
*bg_color
)
807 real lw_factor
,clength
,cwidth
;
809 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
810 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
811 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
812 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
814 if (fg_color
== bg_color
) {
816 lw_factor
= linewidth
;
818 /* Hollow dot or dimension origin */
821 clength
= length
+ lw_factor
;
822 cwidth
= width
+ lw_factor
;
824 point_copy(&vl
,from
); point_sub(&vl
,to
);
825 if (point_len(&vl
) > 0)
826 point_normalize(&vl
);
828 vl
.x
= 1.0; vl
.y
= 0.0;
831 vl
.x
= 1.0; vl
.y
= 0.0;
833 point_get_perp(&vt
,&vl
);
835 point_copy_add_scaled(&bs
,to
,&vl
,length
/4);
836 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
837 point_add_scaled(&bs
,&vt
,width
/2.0);
839 /* This pile of crap is quite well handled by gcc. */
840 bp
[0].type
= BEZ_MOVE_TO
;
841 point_copy(&bp
[0].p1
,to
);
842 bp
[1].type
= bp
[2].type
= bp
[3].type
= bp
[4].type
= BEZ_CURVE_TO
;
843 point_copy(&bp
[4].p3
,&bp
[0].p1
);
845 point_copy_add_scaled(&bp
[2].p3
,&bp
[0].p1
,&vl
,clength
/2);
846 point_copy_add_scaled(&bp
[2].p2
,&bp
[2].p3
,&vt
,-cwidth
/ 8.0);
847 point_copy_add_scaled(&bp
[3].p1
,&bp
[2].p3
,&vt
,cwidth
/ 8.0);
848 point_copy_add_scaled(&bp
[1].p1
,&bp
[0].p1
,&vt
,-cwidth
/ 8.0);
849 point_copy_add_scaled(&bp
[4].p2
,&bp
[0].p1
,&vt
,cwidth
/ 8.0);
850 point_copy_add_scaled(&bp
[1].p3
,&bp
[0].p1
,&vl
,clength
/ 4.0); /* temp */
851 point_copy_add_scaled(&bp
[3].p3
,&bp
[1].p3
,&vt
,cwidth
/ 4.0);
852 point_add_scaled(&bp
[1].p3
,&vt
,-cwidth
/ 4.0);
853 point_copy_add_scaled(&bp
[1].p2
,&bp
[1].p3
,&vl
,-clength
/ 8.0);
854 point_copy_add_scaled(&bp
[4].p1
,&bp
[3].p3
,&vl
,-clength
/ 8.0);
855 point_copy_add_scaled(&bp
[2].p1
,&bp
[1].p3
,&vl
,clength
/ 8.0);
856 point_copy_add_scaled(&bp
[3].p2
,&bp
[3].p3
,&vl
,clength
/ 8.0);
859 /* Means dimension origin */
862 point_copy_add_scaled(&doe
,to
,&vl
,length
);
863 point_copy_add_scaled(&dos
,to
,&vl
,length
/2);
865 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&dos
,&doe
,fg_color
);
867 DIA_RENDERER_GET_CLASS(renderer
)->fill_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),bg_color
);
869 if (fg_color
!= bg_color
) {
870 DIA_RENDERER_GET_CLASS(renderer
)->draw_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),fg_color
);
872 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
,&bs
,&be
,fg_color
);
875 /** Draw the integral-sign arrow head.
876 * @param renderer A renderer instance to draw into
877 * @param to The point that the arrow points to.
878 * @param from Where the arrow points from (e.g. end of stem)
879 * @param length The length of the arrow
880 * @param width The width of the arrow
881 * @param linewidth The thickness of the lines used to draw the arrow.
882 * @param fg_color The color used for drawing the arrow lines.
883 * @param bg_color The color used to kludge around the longer stem of this
885 * @bug The bg_color kludge should not be necessary, arrow pos is adjustable.
888 draw_integral(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
889 real length
, real width
, real linewidth
,
894 Point bs
,be
, bs2
,be2
;
895 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
896 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
897 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
898 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
900 point_copy(&vl
,from
); point_sub(&vl
,to
);
901 if (point_len(&vl
) > 0)
902 point_normalize(&vl
);
904 vl
.x
= 1.0; vl
.y
= 0.0;
907 vl
.x
= 1.0; vl
.y
= 0.0;
909 point_get_perp(&vt
,&vl
);
911 point_copy_add_scaled(&bs
,to
,&vl
,length
/2);
912 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
913 point_add_scaled(&bs
,&vt
,width
/2.0);
915 point_copy_add_scaled(&bs2
,to
,&vl
,length
/2);
916 point_copy_add_scaled(&be2
,&bs2
,&vl
,length
/2);
918 bp
[0].type
= BEZ_MOVE_TO
;
919 bp
[1].type
= BEZ_CURVE_TO
;
920 point_copy_add_scaled(&bp
[0].p1
,to
,&vl
,.1*length
);
921 point_add_scaled(&bp
[0].p1
,&vt
,.4*width
);
922 point_copy_add_scaled(&bp
[1].p3
,to
,&vl
,.9*length
);
923 point_add_scaled(&bp
[1].p3
,&vt
,-.4*width
);
924 point_copy_add_scaled(&bp
[1].p1
,&bp
[0].p1
,&vl
,.35*length
);
925 point_copy_add_scaled(&bp
[1].p2
,&bp
[1].p3
,&vl
,-.35*length
);
927 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &bs2
, &be2
, fg_color
);
928 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &bs
, &be
, fg_color
);
929 DIA_RENDERER_GET_CLASS(renderer
)->draw_bezier(renderer
,bp
,sizeof(bp
)/sizeof(bp
[0]),fg_color
);
932 /** Draw the arrowhead that is a line with a slash through it.
933 * @param renderer A renderer instance to draw into
934 * @param to The point that the arrow points to.
935 * @param from Where the arrow points from (e.g. end of stem)
936 * @param length The length of the arrow
937 * @param width The width of the arrow
938 * @param linewidth The thickness of the lines used to draw the arrow.
939 * @param fg_color The color used for drawing the arrow lines.
940 * @param bg_color Used for a kludge of "erasing" the line tip instead of
941 * figuring out the correct way to do this.
942 * @bug Figure out the right way to do this, avoid kludge.
945 draw_slashed(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
946 real length
, real width
, real linewidth
,
950 Point bs
,be
, bs2
,be2
, bs3
,be3
;
952 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
953 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
954 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
955 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
957 point_copy(&vl
,from
); point_sub(&vl
,to
);
958 if (point_len(&vl
) > 0)
959 point_normalize(&vl
);
961 vl
.x
= 1.0; vl
.y
= 0.0;
964 vl
.x
= 1.0; vl
.y
= 0.0;
966 point_get_perp(&vt
,&vl
);
968 point_copy_add_scaled(&bs
,to
,&vl
,length
/2);
969 point_copy_add_scaled(&be
,&bs
,&vt
,-width
/2.0);
970 point_add_scaled(&bs
,&vt
,width
/2.0);
972 point_copy_add_scaled(&bs2
,to
,&vl
,length
/2);
973 point_copy_add_scaled(&be2
,&bs2
,&vl
,length
/2);
975 point_copy_add_scaled(&bs3
,to
,&vl
,.1*length
);
976 point_add_scaled(&bs3
,&vt
,.4*width
);
977 point_copy_add_scaled(&be3
,to
,&vl
,.9*length
);
978 point_add_scaled(&be3
,&vt
,-.4*width
);
980 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &bs2
, &be2
, fg_color
);
981 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &bs
, &be
, fg_color
);
982 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &bs3
, &be3
, fg_color
);
985 /** Calculate positions for the half-head arrow (only left-hand(?) line drawn)
986 * @param poly The three-element array to store the result in.
987 * @param to Where the arrow points to
988 * @param from Where the arrow points from (e.g. end of stem)
989 * @param length The length of the arrowhead
990 * @param width The width of the arrowhead
991 * @param linewidth The width of the lines used to draw the arrow
992 * @bug Describe better what is put into poly.
995 calculate_halfhead(Point
*poly
, Point
*to
, Point
*from
,
996 real length
, real width
, real linewidth
)
1001 real angle
, add_len
;
1003 if (width
> 0.0000001) {
1004 angle
= atan(length
/(width
/2));
1005 add_len
= linewidth
/cos(angle
);
1011 point_sub(&delta
, from
);
1012 len
= point_len(&delta
);
1013 if (len
<= 0.0001) {
1021 orth_delta
.x
= delta
.y
;
1022 orth_delta
.y
= -delta
.x
;
1024 point_scale(&delta
, length
);
1025 point_scale(&orth_delta
, width
/2.0);
1028 point_sub(&poly
[0], &delta
);
1029 point_sub(&poly
[0], &orth_delta
);
1032 point_normalize(&delta
);
1033 point_scale(&delta
, add_len
);
1034 point_sub(&poly
[2], &delta
);
1035 /* point_add(&poly[2], &orth_delta);*/
1038 /** Draw a halfhead arrow.
1039 * @param renderer A renderer instance to draw into
1040 * @param to The point that the arrow points to.
1041 * @param from Where the arrow points from (e.g. end of stem)
1042 * @param length The length of the arrow
1043 * @param width The width of the arrow
1044 * @param linewidth The thickness of the lines used to draw the arrow.
1045 * @param color The color used for drawing the arrow lines.
1048 draw_halfhead(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1049 real length
, real width
, real linewidth
,
1054 calculate_halfhead(poly
, to
, from
, length
, width
, linewidth
);
1056 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1057 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1058 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1059 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1061 DIA_RENDERER_GET_CLASS(renderer
)->draw_polyline(renderer
, poly
, 3, color
);
1064 /** Draw a basic triangular arrow.
1065 * @param renderer A renderer instance to draw into
1066 * @param to The point that the arrow points to.
1067 * @param from Where the arrow points from (e.g. end of stem)
1068 * @param length The length of the arrow
1069 * @param width The width of the arrow
1070 * @param linewidth The thickness of the lines used to draw the arrow.
1071 * @param color The color used for drawing the arrow lines.
1074 draw_triangle(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1075 real length
, real width
, real linewidth
,
1080 calculate_arrow(poly
, to
, from
, length
, width
);
1082 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1083 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1084 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1086 DIA_RENDERER_GET_CLASS(renderer
)->draw_polygon(renderer
, poly
, 3, color
);
1089 /** Draw a simple triangular arrow, with filled head.
1090 * @param renderer A renderer instance to draw into
1091 * @param to The point that the arrow points to.
1092 * @param from Where the arrow points from (e.g. end of stem)
1093 * @param length The length of the arrow
1094 * @param width The width of the arrow
1095 * @param linewidth The thickness of the lines used to draw the arrow.
1096 * @param color The color used for drawing the arrowhead.
1099 fill_triangle(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1100 real length
, real width
, Color
*color
)
1104 calculate_arrow(poly
, to
, from
, length
, width
);
1106 DIA_RENDERER_GET_CLASS(renderer
)->set_fillstyle(renderer
, FILLSTYLE_SOLID
);
1107 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1109 DIA_RENDERER_GET_CLASS(renderer
)->fill_polygon(renderer
, poly
, 3, color
);
1112 /** Calculate the points needed to draw a diamon arrowhead.
1113 * @param poly A 4-element arrow to hold the return values:
1114 * poly[0] holds the tip of the diamond.
1115 * poly[1] holds the right-side tip of the diamond.
1116 * poly[2] holds the back end of the diamond.
1117 * poly[3] holds the left-side tip of the diamond.
1118 * @param to The point the arrow points to.
1119 * @param from The point the arrow points away from (e.g. bezier control line)
1120 * @param length The length of the arrowhead
1121 * @param width The width of the arrowhead
1122 * @bug Take linewidth into account.
1125 calculate_diamond(Point
*poly
, Point
*to
, Point
*from
,
1126 real length
, real width
)
1133 point_sub(&delta
, from
);
1134 len
= sqrt(point_dot(&delta
, &delta
));
1135 if (len
<= 0.0001) {
1143 orth_delta
.x
= delta
.y
;
1144 orth_delta
.y
= -delta
.x
;
1146 point_scale(&delta
, length
/2.0);
1147 point_scale(&orth_delta
, width
/2.0);
1151 point_sub(&poly
[1], &delta
);
1152 point_sub(&poly
[1], &orth_delta
);
1154 point_sub(&poly
[2], &delta
);
1155 point_sub(&poly
[2], &delta
);
1157 point_sub(&poly
[3], &delta
);
1158 point_add(&poly
[3], &orth_delta
);
1161 /** Draw a diamond-shaped arrow head.
1162 * @param renderer A renderer instance to draw into
1163 * @param to The point that the arrow points to.
1164 * @param from Where the arrow points from (e.g. end of stem)
1165 * @param length The length of the arrow
1166 * @param width The width of the arrow
1167 * @param linewidth The thickness of the lines used to draw the arrow.
1168 * @param color The color used for drawing the arrowhead.
1171 draw_diamond(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1172 real length
, real width
, real linewidth
,
1177 calculate_diamond(poly
, to
, from
, length
, width
);
1179 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1180 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1181 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1182 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1184 DIA_RENDERER_GET_CLASS(renderer
)->draw_polygon(renderer
, poly
, 4, color
);
1187 /** Draw a right-hand part of a diamond arrowhead.
1188 * @param renderer A renderer instance to draw into
1189 * @param to The point that the arrow points to.
1190 * @param from Where the arrow points from (e.g. end of stem)
1191 * @param length The length of the arrow
1192 * @param width The width of the arrow
1193 * @param linewidth The thickness of the lines used to draw the arrow.
1194 * @param color The color used for drawing the arrowhead.
1197 draw_half_diamond(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1198 real length
, real width
, real linewidth
,
1203 calculate_diamond(poly
, to
, from
, length
, width
);
1205 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1206 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1207 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1208 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1210 DIA_RENDERER_GET_CLASS(renderer
)->draw_polyline(renderer
, poly
+1, 3, color
);
1213 /** Draw a filled diamond arrow head.
1214 * @param renderer A renderer instance to draw into
1215 * @param to The point that the arrow points to.
1216 * @param from Where the arrow points from (e.g. end of stem)
1217 * @param length The length of the arrow
1218 * @param width The width of the arrow
1219 * @param color The color used for drawing the arrowhead.
1222 fill_diamond(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1223 real length
, real width
,
1228 calculate_diamond(poly
, to
, from
, length
, width
);
1230 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1231 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1232 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1234 DIA_RENDERER_GET_CLASS(renderer
)->fill_polygon(renderer
, poly
, 4, color
);
1237 /** Calculate the points needed to draw a slashed-cross arrowhead.
1238 * @param poly A 6-element array to hold the points calculated:
1239 * @param to Where the arrow points to.
1240 * @param from Where the arrow points from (e.g. other end of stem).
1241 * @param length The length of the arrowhead.
1242 * @param width The width of the arrowhead.
1243 * @bug Describe what is where in the poly array.
1246 calculate_slashed_cross(Point
*poly
, Point
*to
, Point
*from
,
1247 real length
, real width
)
1255 point_sub(&delta
, from
);
1256 len
= sqrt(point_dot(&delta
, &delta
));
1257 if (len
<= 0.0001) {
1265 orth_delta
.x
= delta
.y
;
1266 orth_delta
.y
= -delta
.x
;
1268 point_scale(&delta
, length
/2.0);
1269 point_scale(&orth_delta
, width
/2.0);
1271 for(i
=0; i
<6;i
++)poly
[i
] = *to
;
1273 point_add(&poly
[1], &delta
);
1275 point_add(&poly
[2], &delta
);
1276 point_add(&poly
[2], &orth_delta
);
1278 point_sub(&poly
[3], &delta
);
1279 point_sub(&poly
[3], &orth_delta
);
1281 point_add(&poly
[4], &orth_delta
);
1282 point_sub(&poly
[5], &orth_delta
);
1285 /** Draw a slashed cross arrowhead.
1286 * @param renderer A renderer instance to draw into
1287 * @param to The point that the arrow points to.
1288 * @param from Where the arrow points from (e.g. end of stem)
1289 * @param length The length of the arrow
1290 * @param width The width of the arrow
1291 * @param linewidth The thickness of the lines used to draw the arrow.
1292 * @param color The color used for drawing the arrowhead.
1295 draw_slashed_cross(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1296 real length
, real width
, real linewidth
, Color
*color
)
1300 calculate_slashed_cross(poly
, to
, from
, length
, width
);
1302 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1303 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1304 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1305 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1307 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &poly
[0],&poly
[1], color
);
1308 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &poly
[2],&poly
[3], color
);
1309 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &poly
[4],&poly
[5], color
);
1312 /** Draw a backslash arrowhead.
1313 * @param renderer A renderer instance to draw into
1314 * @param to The point that the arrow points to.
1315 * @param from Where the arrow points from (e.g. end of stem)
1316 * @param length The length of the arrow
1317 * @param width The width of the arrow
1318 * @param linewidth The thickness of the lines used to draw the arrow.
1319 * @param color The color used for drawing the arrowhead.
1320 * @todo refactor into calculate and draw.
1323 draw_backslash(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1324 real length
, real width
, real linewidth
, Color
*color
)
1333 point_sub(&delta
, from
);
1334 len
= sqrt(point_dot(&delta
, &delta
));
1335 if (len
<= 0.0001) {
1343 orth_delta
.x
= delta
.y
;
1344 orth_delta
.y
= -delta
.x
;
1346 point_scale(&delta
, length
/2.0);
1347 point_scale(&orth_delta
, width
/2.0);
1350 point_sub(&point1
, &delta
);
1351 point_sub(&point1
, &delta
);
1352 point_sub(&point1
, &delta
);
1353 point_add(&point1
, &orth_delta
);
1356 point_sub(&point2
, &delta
);
1357 point_sub(&point2
, &orth_delta
);
1359 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1360 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1361 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1362 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1364 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &point1
,&point2
, color
);
1367 /** Draw a cross-like arrowhead.
1368 * @param renderer A renderer instance to draw into
1369 * @param to The point that the arrow points to.
1370 * @param from Where the arrow points from (e.g. end of stem)
1371 * @param length The length of the arrow
1372 * @param width The width of the arrow
1373 * @param linewidth The thickness of the lines used to draw the arrow.
1374 * @param color The color used for drawing the arrowhead.
1377 draw_cross(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1378 real length
, real width
, real linewidth
, Color
*color
)
1382 calculate_arrow(poly
, to
, from
, length
, width
);
1384 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1385 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1386 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1387 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1389 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &poly
[0],&poly
[2], color
);
1390 /*DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &poly[4],&poly[5], color); */
1393 /** Calculate where to put the second arrowhead of a double arrow
1394 * @param second_to Return value for the point where the second arrowhead
1396 * @param second_from Return value for the point where the second arrowhead
1397 * should point from.
1398 * @param to Where the first arrowhead should point to.
1399 * @param from Where the whole arrow points from (e.g. end of stem)
1400 * @param length The length of each arrowhead.
1403 calculate_double_arrow(Point
*second_to
, Point
*second_from
,
1404 Point
*to
, Point
*from
, real length
)
1410 point_sub(&delta
, from
);
1411 len
= sqrt(point_dot(&delta
, &delta
));
1412 if (len
<= 0.0001) {
1420 point_scale(&delta
, length
/2);
1423 point_sub(second_to
, &delta
);
1424 point_sub(second_to
, &delta
);
1425 *second_from
= *from
;
1426 point_add(second_from
, &delta
);
1427 point_add(second_from
, &delta
);
1430 /** Draw a double-triangle arrowhead.
1431 * @param renderer A renderer instance to draw into
1432 * @param to The point that the arrow points to.
1433 * @param from Where the arrow points from (e.g. end of stem)
1434 * @param length The length of the arrow
1435 * @param width The width of the arrow
1436 * @param linewidth The thickness of the lines used to draw the arrow.
1437 * @param color The color used for drawing the arrowhead.
1440 draw_double_triangle(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1441 real length
, real width
, real linewidth
, Color
*color
)
1443 Point second_from
, second_to
;
1445 draw_triangle(renderer
, to
, from
, length
, width
, linewidth
, color
);
1446 calculate_double_arrow(&second_to
, &second_from
, to
, from
, length
+linewidth
);
1447 draw_triangle(renderer
, &second_to
, &second_from
, length
, width
, linewidth
, color
);
1450 /** Draw a filled double-triangle arrowhead.
1451 * @param renderer A renderer instance to draw into
1452 * @param to The point that the arrow points to.
1453 * @param from Where the arrow points from (e.g. end of stem)
1454 * @param length The length of the arrow
1455 * @param width The width of the arrow
1456 * @param linewidth The thickness of the lines used to draw the arrow.
1457 * @param color The color used for drawing the arrowhead.
1460 fill_double_triangle(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1461 real length
, real width
, Color
*color
)
1463 Point second_from
, second_to
;
1465 fill_triangle(renderer
, to
, from
, length
, width
, color
);
1466 calculate_double_arrow(&second_to
, &second_from
, to
, from
, length
);
1467 fill_triangle(renderer
, &second_to
, &second_from
, length
, width
, color
);
1470 /** Calculate the points needed to draw a concave arrowhead.
1471 * @param poly A 4-element array of return points:
1472 * poly[0] is the tip of the arrow.
1473 * poly[1] is the right-hand point of the arrow.
1474 * poly[2] is the rear indent point of the arrow.
1475 * poly[3] is the left-hand point of the arrow.
1476 * @param to Where the arrow points to.
1477 * @param from Where the arrow points from (e.g. bezier control point)
1478 * @param length The length of the arrow.
1479 * @param width The width of the arrow.
1482 calculate_concave(Point
*poly
, Point
*to
, Point
*from
,
1483 real length
, real width
)
1490 point_sub(&delta
, from
);
1491 len
= sqrt(point_dot(&delta
, &delta
));
1492 if (len
<= 0.0001) {
1500 orth_delta
.x
= delta
.y
;
1501 orth_delta
.y
= -delta
.x
;
1503 point_scale(&delta
, length
/4.0);
1504 point_scale(&orth_delta
, width
/2.0);
1508 point_sub(&poly
[1], &delta
);
1509 point_sub(&poly
[1], &delta
);
1510 point_sub(&poly
[1], &delta
);
1511 point_sub(&poly
[1], &delta
);
1512 point_sub(&poly
[1], &orth_delta
);
1514 point_sub(&poly
[2], &delta
);
1515 point_sub(&poly
[2], &delta
);
1516 point_sub(&poly
[2], &delta
);
1518 point_add(&poly
[3], &orth_delta
);
1519 point_sub(&poly
[3], &delta
);
1520 point_sub(&poly
[3], &delta
);
1521 point_sub(&poly
[3], &delta
);
1522 point_sub(&poly
[3], &delta
);
1525 /** Draw a concave triangle arrowhead.
1526 * @param renderer A renderer instance to draw into
1527 * @param to The point that the arrow points to.
1528 * @param from Where the arrow points from (e.g. end of stem)
1529 * @param length The length of the arrow
1530 * @param width The width of the arrow
1531 * @param linewidth The thickness of the lines used to draw the arrow.
1532 * @param fg_color The color used for drawing the arrowhead lines
1533 * @param bg_color The color used for drawing the arrowhead interior.
1536 draw_concave_triangle(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1537 real length
, real width
, real linewidth
,
1538 Color
*fg_color
, Color
*bg_color
)
1542 calculate_concave(poly
, to
, from
, length
, width
);
1544 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1545 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1546 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1548 if (fg_color
== bg_color
)
1549 DIA_RENDERER_GET_CLASS(renderer
)->fill_polygon(renderer
, poly
, 4, bg_color
);
1550 DIA_RENDERER_GET_CLASS(renderer
)->draw_polygon(renderer
, poly
, 4, fg_color
);
1553 /** Draw a rounded (half-circle) arrowhead.
1554 * @param renderer A renderer instance to draw into
1555 * @param to The point that the arrow points to.
1556 * @param from Where the arrow points from (e.g. end of stem)
1557 * @param length The length of the arrow
1558 * @param width The width of the arrow
1559 * @param linewidth The thickness of the lines used to draw the arrow.
1560 * @param fg_color The color used for drawing the arrowhead lines
1561 * @param bg_color Ignored.
1564 draw_rounded(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1565 real length
, real width
, real linewidth
,
1566 Color
*fg_color
, Color
*bg_color
)
1574 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1575 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1576 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1577 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1581 point_sub(&delta
, to
);
1583 len
= sqrt(point_dot(&delta
, &delta
)); /* line length */
1584 rayon
= (length
/ 2.0);
1585 rapport
= rayon
/ len
;
1587 p
.x
+= delta
.x
* rapport
;
1588 p
.y
+= delta
.y
* rapport
;
1590 angle_start
= 90.0 - asin((p
.y
- to
->y
) / rayon
) * (180.0 / 3.14);
1591 if (p
.x
- to
->x
< 0) { angle_start
= 360.0 - angle_start
; }
1593 DIA_RENDERER_GET_CLASS(renderer
)->draw_arc(renderer
, &p
, width
, length
, angle_start
, angle_start
- 180.0, fg_color
);
1595 p
.x
+= delta
.x
* rapport
;
1596 p
.y
+= delta
.y
* rapport
;
1597 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &p
, to
, fg_color
);
1600 /** Draw an open rounded arrowhead.
1601 * @param renderer A renderer instance to draw into
1602 * @param to The point that the arrow points to.
1603 * @param from Where the arrow points from (e.g. end of stem)
1604 * @param length The length of the arrow
1605 * @param width The width of the arrow
1606 * @param linewidth The thickness of the lines used to draw the arrow.
1607 * @param fg_color The color used for drawing the arrowhead lines
1608 * @param bg_color Ignored.
1609 * @todo Describe the arrowhead better.
1612 draw_open_rounded(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1613 real length
, real width
, real linewidth
,
1614 Color
*fg_color
, Color
*bg_color
)
1623 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1624 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1625 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1629 point_sub(&delta
, to
);
1631 len
= sqrt(point_dot(&delta
, &delta
)); /* line length */
1632 rayon
= (length
/ 2.0);
1633 rapport
= rayon
/ len
;
1635 p
.x
+= delta
.x
* rapport
;
1636 p
.y
+= delta
.y
* rapport
;
1638 angle_start
= 90.0 - asin((p
.y
- to
->y
) / rayon
) * (180.0 / 3.14);
1639 if (p
.x
- to
->x
< 0) { angle_start
= 360.0 - angle_start
; }
1642 p_line
.x
+= delta
.x
* rapport
;
1643 p_line
.y
+= delta
.y
* rapport
;
1645 DIA_RENDERER_GET_CLASS(renderer)->set_linewidth(renderer, linewidth * 2.0);
1646 DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &p_line, to, bg_color);
1648 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1649 DIA_RENDERER_GET_CLASS(renderer
)->draw_arc(renderer
, &p
, width
, length
, angle_start
- 180.0, angle_start
, fg_color
);
1652 /** Draw an arrowhead with a circle in front of a triangle, filled.
1653 * @param renderer A renderer instance to draw into
1654 * @param to The point that the arrow points to.
1655 * @param from Where the arrow points from (e.g. end of stem)
1656 * @param length The length of the arrow
1657 * @param width The width of the arrow
1658 * @param linewidth The thickness of the lines used to draw the arrow.
1659 * @param fg_color The color used for drawing the arrowhead lines
1660 * @param bg_color Ignored.
1663 draw_filled_dot_n_triangle(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1664 real length
, real width
, real linewidth
,
1665 Color
*fg_color
, Color
*bg_color
)
1667 Point p_dot
= *to
, p_tri
= *to
, delta
;
1672 DIA_RENDERER_GET_CLASS(renderer
)->set_linecaps(renderer
, LINECAPS_BUTT
);
1673 DIA_RENDERER_GET_CLASS(renderer
)->set_linejoin(renderer
, LINEJOIN_MITER
);
1674 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1675 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1679 point_sub(&delta
, to
);
1681 len
= sqrt(point_dot(&delta
, &delta
)); /* line length */
1684 rayon
= (width
/ 2.0);
1685 rapport
= rayon
/ len
;
1686 p_dot
.x
+= delta
.x
* rapport
;
1687 p_dot
.y
+= delta
.y
* rapport
;
1688 DIA_RENDERER_GET_CLASS(renderer
)->fill_ellipse(renderer
, &p_dot
,
1689 width
, width
, fg_color
);
1691 rapport
= width
/ len
;
1692 p_tri
.x
+= delta
.x
* rapport
;
1693 p_tri
.y
+= delta
.y
* rapport
;
1694 calculate_arrow(poly
, &p_tri
, from
, length
, width
);
1695 DIA_RENDERER_GET_CLASS(renderer
)->fill_polygon(renderer
, poly
, 3, fg_color
);
1698 /** Draw an arrowhead that is simply three dots (ellipsis)
1699 * @param renderer A renderer instance to draw into
1700 * @param to The point that the arrow points to.
1701 * @param from Where the arrow points from (e.g. end of stem)
1702 * @param length The length of the arrow
1703 * @param width The width of the arrow
1704 * @param linewidth The thickness of the lines used to draw the arrow.
1705 * @param fg_color The color used for drawing the arrowhead lines
1708 draw_three_dots(DiaRenderer
*renderer
, Point
*to
, Point
*from
,
1709 real length
, real width
, real linewidth
, Color
*fg_color
)
1716 Point delta
, dot_from
, dot_to
;
1719 point_sub(&delta
, from
);
1720 len
= point_len(&delta
);
1721 point_normalize(&delta
);
1723 if (len
> 4 * width
)
1725 dot_width
= width
* 0.2;
1726 hole_width
= width
/ 3 - dot_width
;
1728 DIA_RENDERER_GET_CLASS(renderer
)->set_linewidth(renderer
, linewidth
);
1729 DIA_RENDERER_GET_CLASS(renderer
)->set_linestyle(renderer
, LINESTYLE_SOLID
);
1731 for (i
= 0; i
< 3; i
++) {
1732 dot_from
.x
= to
->x
- i
* (dot_width
+ hole_width
) * delta
.x
;
1733 dot_from
.y
= to
->y
- i
* (dot_width
+ hole_width
) * delta
.y
;
1734 dot_to
.x
= to
->x
- ((i
+ 1) * dot_width
+ i
* hole_width
) * delta
.x
;
1735 dot_to
.y
= to
->y
- ((i
+ 1) * dot_width
+ i
* hole_width
) * delta
.y
;
1736 DIA_RENDERER_GET_CLASS(renderer
)->draw_line(renderer
, &dot_from
, &dot_to
, fg_color
);
1740 /** Draw any arrowhead.
1741 * @param renderer A renderer instance to draw into
1742 * @param type Which kind of arrowhead to draw.
1743 * @param to The point that the arrow points to.
1744 * @param from Where the arrow points from (e.g. end of stem)
1745 * @param length The length of the arrow
1746 * @param width The width of the arrow
1747 * @param linewidth The thickness of the lines used to draw the arrow.
1748 * @param fg_color The color used for drawing the arrowhead lines
1749 * @param bg_color The color used for drawing the arrowhead interior.
1752 arrow_draw(DiaRenderer
*renderer
, ArrowType type
,
1753 Point
*to
, Point
*from
,
1754 real length
, real width
, real linewidth
,
1755 Color
*fg_color
, Color
*bg_color
)
1761 draw_lines(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1763 case ARROW_HALF_HEAD
:
1764 draw_halfhead(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1766 case ARROW_HOLLOW_TRIANGLE
:
1767 fill_triangle(renderer
, to
, from
, length
, width
, bg_color
);
1768 draw_triangle(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1770 case ARROW_UNFILLED_TRIANGLE
:
1771 draw_triangle(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1773 case ARROW_FILLED_TRIANGLE
:
1774 fill_triangle(renderer
, to
, from
, length
, width
, fg_color
);
1776 case ARROW_HOLLOW_DIAMOND
:
1777 fill_diamond(renderer
, to
, from
, length
, width
, bg_color
);
1778 draw_diamond(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1780 case ARROW_FILLED_DIAMOND
:
1781 fill_diamond(renderer
, to
, from
, length
, width
, fg_color
);
1783 case ARROW_HALF_DIAMOND
:
1784 /* fill_diamond(renderer, to, from, length, width, bg_color);*/
1785 draw_half_diamond(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1787 case ARROW_SLASHED_CROSS
:
1788 draw_slashed_cross(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1790 case ARROW_FILLED_ELLIPSE
:
1791 draw_fill_ellipse(renderer
,to
,from
,length
,width
,linewidth
,
1794 case ARROW_HOLLOW_ELLIPSE
:
1795 draw_fill_ellipse(renderer
,to
,from
,length
,width
,linewidth
,
1798 case ARROW_DOUBLE_HOLLOW_TRIANGLE
:
1799 fill_double_triangle(renderer
, to
, from
, length
+(linewidth
/2), width
, bg_color
);
1800 draw_double_triangle(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1802 case ARROW_DOUBLE_FILLED_TRIANGLE
:
1803 fill_double_triangle(renderer
, to
, from
, length
, width
, fg_color
);
1805 case ARROW_FILLED_DOT
:
1806 draw_fill_dot(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,fg_color
);
1808 case ARROW_BLANKED_DOT
:
1809 draw_fill_dot(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1811 case ARROW_FILLED_BOX
:
1812 draw_fill_box(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,fg_color
);
1814 case ARROW_BLANKED_BOX
:
1815 draw_fill_box(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1817 case ARROW_DIMENSION_ORIGIN
:
1818 draw_fill_dot(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,NULL
);
1820 case ARROW_INTEGRAL_SYMBOL
:
1821 draw_integral(renderer
,to
,from
,length
,width
,linewidth
,fg_color
);
1823 case ARROW_SLASH_ARROW
:
1824 draw_slashed(renderer
,to
,from
,length
,width
,linewidth
,fg_color
);
1826 case ARROW_ONE_OR_MANY
:
1827 draw_one_or_many(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1829 case ARROW_NONE_OR_MANY
:
1830 draw_none_or_many(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1832 case ARROW_ONE_EXACTLY
:
1833 draw_one_exactly(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1835 case ARROW_ONE_OR_NONE
:
1836 draw_one_or_none(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1838 case ARROW_CROW_FOOT
:
1839 draw_crow_foot(renderer
,to
,from
,length
,width
,linewidth
,fg_color
,bg_color
);
1842 draw_cross(renderer
, to
, from
, length
, width
, linewidth
, fg_color
);
1844 case ARROW_FILLED_CONCAVE
:
1845 draw_concave_triangle(renderer
, to
, from
, length
, width
, linewidth
, fg_color
, fg_color
);
1847 case ARROW_BLANKED_CONCAVE
:
1848 draw_concave_triangle(renderer
, to
, from
, length
, width
, linewidth
, fg_color
, bg_color
);
1851 draw_rounded(renderer
, to
, from
, length
, width
, linewidth
, fg_color
, bg_color
);
1853 case ARROW_OPEN_ROUNDED
:
1854 draw_open_rounded(renderer
, to
, from
, length
, width
, linewidth
,
1855 fg_color
, bg_color
);
1857 case ARROW_FILLED_DOT_N_TRIANGLE
:
1858 draw_filled_dot_n_triangle(renderer
, to
, from
, length
, width
, linewidth
,
1859 fg_color
, bg_color
);
1861 case ARROW_BACKSLASH
:
1862 draw_backslash(renderer
,to
,from
,length
,width
,linewidth
,fg_color
);
1864 case ARROW_THREE_DOTS
:
1865 draw_three_dots(renderer
,to
,from
,length
,width
,linewidth
,fg_color
);
1867 case MAX_ARROW_TYPE
:
1872 /* *** Loading and saving arrows. *** */
1873 /** Makes sure an arrow object is within reasonable limits
1874 * @param arrow An arrow object. This object may be modified to comply with
1875 * restrictions of MIN_ARROW_DIMENSION on its length and width and to have a
1879 sanitize_arrow(Arrow
*arrow
)
1881 if (arrow
->length
< MIN_ARROW_DIMENSION
||
1882 arrow
->width
< MIN_ARROW_DIMENSION
||
1883 arrow
->type
< 0 || arrow
->type
> MAX_ARROW_TYPE
) {
1884 arrow
->type
= ARROW_NONE
;
1885 arrow
->width
= DEFAULT_ARROW_WIDTH
;
1886 arrow
->length
= DEFAULT_ARROW_LENGTH
;
1890 /** Save the arrow information into three attributes.
1891 * @param obj_node The XML node to save to.
1892 * @param arrow the arrow to save.
1893 * @param type_attribute the name of the attribute of the arrow type.
1894 * @param length_attribute the name of the attribute of the arrow length.
1895 * @param width_attribute the name of the attribte of the arrow width.
1898 save_arrow(ObjectNode obj_node
, Arrow
*arrow
, gchar
*type_attribute
,
1899 gchar
*length_attribute
, gchar
*width_attribute
)
1901 data_add_enum(new_attribute(obj_node
, type_attribute
),
1903 data_add_real(new_attribute(obj_node
, length_attribute
),
1905 data_add_real(new_attribute(obj_node
, width_attribute
),
1909 /** Load arrow information from three attributes.
1910 * @param obj_node The XML node to load from.
1911 * @param arrow the arrow to store the data info.
1912 * @param type_attribute the name of the attribute of the arrow type.
1913 * @param length_attribute the name of the attribute of the arrow length.
1914 * @param width_attribute the name of the attribte of the arrow width.
1917 load_arrow(ObjectNode obj_node
, Arrow
*arrow
, gchar
*type_attribute
,
1918 gchar
*length_attribute
, gchar
*width_attribute
)
1920 AttributeNode
*attr
;
1922 arrow
->type
= ARROW_NONE
;
1923 arrow
->length
= DEFAULT_ARROW_LENGTH
;
1924 arrow
->width
= DEFAULT_ARROW_WIDTH
;
1925 attr
= object_find_attribute(obj_node
, type_attribute
);
1927 arrow
->type
= data_enum(attribute_first_data(attr
));
1928 attr
= object_find_attribute(obj_node
, length_attribute
);
1930 arrow
->length
= data_real(attribute_first_data(attr
));
1931 attr
= object_find_attribute(obj_node
, width_attribute
);
1933 arrow
->width
= data_real(attribute_first_data(attr
));
1935 sanitize_arrow(arrow
);
1938 /** Returns the arrow type that corresponds to a given name.
1939 * @param name The name of an arrow type (case sensitive)
1940 * @returns The arrow type (@see ArrowType enum in arrows.h). Returns
1941 * ARROW_NONE if the name doesn't match any known arrow head type.
1944 arrow_type_from_name(gchar
*name
)
1947 for (i
= 0; arrow_types
[i
].name
!= NULL
; i
++) {
1948 if (!strcmp(arrow_types
[i
].name
, name
)) {
1949 return arrow_types
[i
].enum_value
;
1952 printf("Unknown arrow type %s\n", name
);
1956 /** Return the index into the arrow_types array (which is sorted by an
1957 * arbitrary order that we like) for a given arrow type.
1958 * @param atype An arrow type as defined in arrows.h
1959 * @returns An index into the arrow_types array.
1962 arrow_index_from_type(ArrowType atype
)
1966 for (i
= 0; arrow_types
[i
].name
!= NULL
; i
++) {
1967 if (arrow_types
[i
].enum_value
== atype
) {
1971 printf("Can't find arrow index for type %d\n", atype
);
1975 /** Get a list of all known arrow head names, in arrow_types order.
1976 * @returns A newly allocated list of the names. The list should be
1977 * freed after use, but the strings are owned by arrow_types.
1980 get_arrow_names(void)
1983 GList
*arrows
= NULL
;
1985 for (i
= 0; arrow_types
[i
].name
!= NULL
; i
++) {
1986 arrows
= g_list_append(arrows
, arrow_types
[i
].name
);