Line data Source code
1 : /* File: pencil_relationship_painter.c; Copyright and License: see below */
2 :
3 : #include "pencil_relationship_painter.h"
4 : #include "layout/layout_visible_set.h"
5 : #include "u8/u8_trace.h"
6 : #include "utf8stringbuf/utf8string.h"
7 : #include <pango/pangocairo.h>
8 : #include <stdio.h>
9 : #include <stdlib.h>
10 : #include <assert.h>
11 :
12 0 : void pencil_relationship_painter_init( pencil_relationship_painter_t *this_ )
13 : {
14 0 : U8_TRACE_BEGIN();
15 :
16 0 : pencil_marker_init( &((*this_).marker) );
17 0 : draw_relationship_label_init( &((*this_).draw_relationship_label) );
18 :
19 0 : U8_TRACE_END();
20 0 : }
21 :
22 0 : void pencil_relationship_painter_destroy( pencil_relationship_painter_t *this_ )
23 : {
24 0 : U8_TRACE_BEGIN();
25 :
26 0 : draw_relationship_label_destroy( &((*this_).draw_relationship_label) );
27 0 : pencil_marker_destroy( &((*this_).marker) );
28 :
29 0 : U8_TRACE_END();
30 0 : }
31 :
32 0 : void pencil_relationship_painter_draw ( pencil_relationship_painter_t *this_,
33 : const layout_relationship_t *layouted_relationship,
34 : bool mark_focused,
35 : bool mark_highlighted,
36 : bool mark_selected,
37 : const data_profile_part_t *profile,
38 : const pencil_size_t *pencil_size,
39 : PangoLayout *layout,
40 : cairo_t *cr )
41 : {
42 0 : U8_TRACE_BEGIN();
43 0 : assert( NULL != layouted_relationship );
44 0 : assert( NULL != profile );
45 0 : assert( NULL != pencil_size );
46 0 : assert( NULL != layout );
47 0 : assert( NULL != cr );
48 :
49 : const data_relationship_t *const the_relationship
50 0 : = layout_relationship_get_data_const( layouted_relationship );
51 : const geometry_connector_t *const connector_shape
52 0 : = layout_relationship_get_shape_const( layouted_relationship );
53 :
54 0 : if ( data_relationship_is_valid( the_relationship ) )
55 : {
56 0 : U8_TRACE_INFO_INT("drawing relationship id", data_relationship_get_row_id( the_relationship ) );
57 :
58 : /* set the right line width */
59 0 : const double std_line_width = pencil_size_get_standard_line_width( pencil_size );
60 0 : cairo_set_line_width( cr, std_line_width );
61 :
62 : /* set the right drawing color */
63 : GdkRGBA foreground_color;
64 : {
65 0 : if ( mark_highlighted )
66 : {
67 0 : foreground_color = pencil_size_get_highlight_color( pencil_size );
68 : }
69 0 : else if (( PENCIL_VISIBILITY_GRAY_OUT == layout_relationship_get_visibility( layouted_relationship ) )
70 0 : || ( PENCIL_VISIBILITY_IMPLICIT == layout_relationship_get_visibility( layouted_relationship ) ))
71 : {
72 0 : foreground_color = pencil_size_get_gray_out_color( pencil_size );
73 : }
74 : else
75 : {
76 0 : foreground_color = pencil_size_get_standard_color( pencil_size );
77 : }
78 :
79 0 : cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
80 : }
81 :
82 : /* get points */
83 0 : double p1x = geometry_connector_get_source_end_x ( connector_shape );
84 0 : double p1y = geometry_connector_get_source_end_y ( connector_shape );
85 0 : double p2x = geometry_connector_get_main_line_source_x ( connector_shape );
86 0 : double p2y = geometry_connector_get_main_line_source_y ( connector_shape );
87 0 : double p3x = geometry_connector_get_main_line_destination_x ( connector_shape );
88 0 : double p3y = geometry_connector_get_main_line_destination_y ( connector_shape );
89 0 : double p4x = geometry_connector_get_destination_end_x ( connector_shape );
90 0 : double p4y = geometry_connector_get_destination_end_y ( connector_shape );
91 0 : double center_x = (p2x+p3x)/2.0;
92 0 : double center_y = (p2y+p3y)/2.0;
93 :
94 : /* determine arrow direction */
95 : int arrow_clock_direction; /* wall-clock direction assuming ascending y direction to top */
96 0 : if ( fabs( p3x-p4x ) > 0.5 )
97 : {
98 0 : arrow_clock_direction = ( p3x < p4x ) ? 3 : 9;
99 : }
100 : else
101 : {
102 0 : if ( fabs( p3y-p4y ) > 0.5 )
103 : {
104 0 : arrow_clock_direction = ( p3y < p4y ) ? 0 : 6;
105 : }
106 : else
107 : {
108 : /* maybe the first segment is too short, take into account two segments */
109 0 : if ( fabs( p2x-p4x ) > 0.5 )
110 : {
111 0 : arrow_clock_direction = ( p2x < p4x ) ? 3 : 9;
112 : }
113 : else
114 : {
115 0 : if ( fabs( p2y-p4y ) > 0.5 )
116 : {
117 0 : arrow_clock_direction = ( p2y < p4y ) ? 0 : 6;
118 : }
119 : else
120 : {
121 : /* maybe the first two segments are too short, take into account all segments */
122 0 : if ( fabs( p1x-p4x ) > 0.5 )
123 : {
124 0 : arrow_clock_direction = ( p1x < p4x ) ? 3 : 9;
125 : }
126 : else
127 : {
128 0 : if ( fabs( p1y-p4y ) > 0.5 )
129 : {
130 0 : arrow_clock_direction = ( p1y < p4y ) ? 0 : 6;
131 : }
132 : else
133 : {
134 : /* connector has no length */
135 0 : arrow_clock_direction = 0;
136 : }
137 : }
138 : }
139 : }
140 : }
141 : }
142 :
143 : /* determine feathers direction */
144 : int feathers_clock_direction; /* wall-clock direction assuming ascending y direction to top */
145 0 : if ( fabs( p2x-p1x ) > 0.5 )
146 : {
147 0 : feathers_clock_direction = ( p2x < p1x ) ? 9 : 3;
148 : }
149 : else
150 : {
151 0 : if ( fabs( p2y-p1y ) > 0.5 )
152 : {
153 0 : feathers_clock_direction = ( p2y < p1y ) ? 0 : 6;
154 : }
155 : else
156 : {
157 : /* maybe the first segment is too short, take into account two segments */
158 0 : if ( fabs( p3x-p1x ) > 0.5 )
159 : {
160 0 : feathers_clock_direction = ( p3x < p1x ) ? 9 : 3;
161 : }
162 : else
163 : {
164 0 : if ( fabs( p3y-p1y ) > 0.5 )
165 : {
166 0 : feathers_clock_direction = ( p3y < p1y ) ? 0 : 6;
167 : }
168 : else
169 : {
170 : /* maybe the first two segments are too short, take into account all segments */
171 0 : if ( fabs( p4x-p1x ) > 0.5 )
172 : {
173 0 : feathers_clock_direction = ( p4x < p1x ) ? 9 : 3;
174 : }
175 : else
176 : {
177 0 : if ( fabs( p4y-p1y ) > 0.5 )
178 : {
179 0 : feathers_clock_direction = ( p4y < p1y ) ? 0 : 6;
180 : }
181 : else
182 : {
183 : /* connector has no length */
184 0 : feathers_clock_direction = 0;
185 : }
186 : }
187 : }
188 : }
189 : }
190 : }
191 :
192 : /* draw arrow */
193 0 : switch ( data_relationship_get_main_type( the_relationship ) )
194 : {
195 0 : case DATA_RELATIONSHIP_TYPE_UML_ASSOCIATION:
196 : case DATA_RELATIONSHIP_TYPE_UML_GENERALIZATION:
197 : case DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL:
198 : case DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL:
199 : case DATA_RELATIONSHIP_TYPE_UML_CONTROL_FLOW:
200 : case DATA_RELATIONSHIP_TYPE_UML_OBJECT_FLOW:
201 : case DATA_RELATIONSHIP_TYPE_UML_EXTEND: /* t.b.d. */
202 : case DATA_RELATIONSHIP_TYPE_UML_INCLUDE: /* t.b.d. */
203 : case DATA_RELATIONSHIP_TYPE_UML_DEPLOY:
204 : case DATA_RELATIONSHIP_TYPE_UML_MANIFEST: /* t.b.d. */
205 : case DATA_RELATIONSHIP_TYPE_UML_REALIZATION:
206 : case DATA_RELATIONSHIP_TYPE_UML_DEPENDENCY:
207 : case DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL:
208 : case DATA_RELATIONSHIP_TYPE_UML_REFINE:
209 : case DATA_RELATIONSHIP_TYPE_UML_TRACE:
210 : {
211 0 : const double half_stroke_length = 0.5 * pencil_size_get_arrow_stroke_length( pencil_size );
212 0 : const double part_stroke_length = pencil_size_get_arrow_stroke_087_length( pencil_size );
213 : bool close_path;
214 0 : if (( data_relationship_get_main_type( the_relationship ) == DATA_RELATIONSHIP_TYPE_UML_GENERALIZATION )
215 0 : || ( data_relationship_get_main_type( the_relationship ) == DATA_RELATIONSHIP_TYPE_UML_REALIZATION ))
216 : {
217 0 : close_path = true;
218 : }
219 : else
220 : {
221 0 : close_path = false;
222 : }
223 : switch ( arrow_clock_direction )
224 : {
225 0 : case 0: /* direction: 12 o clock */
226 : {
227 0 : cairo_move_to ( cr, p4x - half_stroke_length, p4y - part_stroke_length );
228 0 : cairo_line_to ( cr, p4x, p4y );
229 0 : cairo_line_to ( cr, p4x + half_stroke_length, p4y - part_stroke_length );
230 0 : if ( close_path )
231 : {
232 0 : cairo_line_to ( cr, p4x - half_stroke_length, p4y - part_stroke_length );
233 0 : p4y = p4y - part_stroke_length;
234 : /* if p3 == p4, also move p3 */
235 0 : if ( p3y > p4y )
236 : {
237 0 : p3y = p4y;
238 : }
239 : }
240 : }
241 0 : break;
242 :
243 0 : case 3:
244 : {
245 0 : cairo_move_to ( cr, p4x - part_stroke_length, p4y - half_stroke_length );
246 0 : cairo_line_to ( cr, p4x, p4y );
247 0 : cairo_line_to ( cr, p4x - part_stroke_length, p4y + half_stroke_length );
248 0 : if ( close_path )
249 : {
250 0 : cairo_line_to ( cr, p4x - part_stroke_length, p4y - half_stroke_length );
251 0 : p4x = p4x - part_stroke_length;
252 : /* if p3 == p4, also move p3 */
253 0 : if ( p3x > p4x )
254 : {
255 0 : p3x = p4x;
256 : }
257 : }
258 : }
259 0 : break;
260 :
261 0 : case 6:
262 : {
263 0 : cairo_move_to ( cr, p4x + half_stroke_length, p4y + part_stroke_length );
264 0 : cairo_line_to ( cr, p4x, p4y );
265 0 : cairo_line_to ( cr, p4x - half_stroke_length, p4y + part_stroke_length );
266 0 : if ( close_path )
267 : {
268 0 : cairo_line_to ( cr, p4x + half_stroke_length, p4y + part_stroke_length );
269 0 : p4y = p4y + part_stroke_length;
270 : /* if p3 == p4, also move p3 */
271 0 : if ( p3y < p4y )
272 : {
273 0 : p3y = p4y;
274 : }
275 : }
276 : }
277 0 : break;
278 :
279 0 : case 9:
280 : {
281 0 : cairo_move_to ( cr, p4x + part_stroke_length, p4y + half_stroke_length );
282 0 : cairo_line_to ( cr, p4x, p4y );
283 0 : cairo_line_to ( cr, p4x + part_stroke_length, p4y - half_stroke_length );
284 0 : if ( close_path )
285 : {
286 0 : cairo_line_to ( cr, p4x + part_stroke_length, p4y + half_stroke_length );
287 0 : p4x = p4x + part_stroke_length;
288 : /* if p3 == p4, also move p3 */
289 0 : if ( p3x < p4x )
290 : {
291 0 : p3x = p4x;
292 : }
293 : }
294 : }
295 0 : break;
296 :
297 0 : default:
298 : {
299 0 : U8_LOG_ERROR("illegal case");
300 : }
301 0 : break;
302 : }
303 0 : if (( data_relationship_get_main_type( the_relationship ) == DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL )
304 0 : || ( data_relationship_get_main_type( the_relationship ) == DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL ))
305 : {
306 0 : cairo_fill (cr);
307 : }
308 : else
309 : {
310 0 : cairo_stroke (cr);
311 : }
312 : }
313 0 : break;
314 :
315 0 : case DATA_RELATIONSHIP_TYPE_UML_AGGREGATION:
316 : case DATA_RELATIONSHIP_TYPE_UML_COMPOSITION:
317 : case DATA_RELATIONSHIP_TYPE_UML_CONTAINMENT:
318 : case DATA_RELATIONSHIP_TYPE_UML_COMMUNICATION_PATH:
319 : {
320 : /* no arrow tip */
321 : }
322 0 : break;
323 :
324 0 : default:
325 : {
326 0 : U8_LOG_ANOMALY("unknown data_relationship_type_t in pencil_relationship_painter_draw()");
327 : /* this may happen if a new database file has been read by an old program version */
328 : /* no arrow tip */
329 : }
330 0 : break;
331 : }
332 :
333 : /* draw feathers */
334 0 : switch ( data_relationship_get_main_type( the_relationship ) )
335 : {
336 0 : case DATA_RELATIONSHIP_TYPE_UML_AGGREGATION:
337 : case DATA_RELATIONSHIP_TYPE_UML_COMPOSITION:
338 : {
339 : /* rhomboid */
340 0 : const double half_stroke_length = 0.5 * pencil_size_get_arrow_stroke_length( pencil_size );
341 0 : const double part_stroke_length = pencil_size_get_arrow_stroke_087_length( pencil_size );
342 : switch ( feathers_clock_direction )
343 : {
344 0 : case 0: /* direction: 12 o clock */
345 : {
346 0 : cairo_move_to ( cr, p1x, p1y );
347 0 : cairo_line_to ( cr, p1x - half_stroke_length, p1y - part_stroke_length );
348 0 : cairo_line_to ( cr, p1x, p1y - 2.0 * part_stroke_length );
349 0 : cairo_line_to ( cr, p1x + half_stroke_length, p1y - part_stroke_length );
350 0 : cairo_line_to ( cr, p1x, p1y );
351 0 : p1y = p1y - 2.0 * part_stroke_length;
352 : /* if p2 == p1, also move p2 */
353 0 : if ( p2y > p1y )
354 : {
355 0 : p2y = p1y;
356 : }
357 : }
358 0 : break;
359 :
360 0 : case 3:
361 : {
362 0 : cairo_move_to ( cr, p1x, p1y );
363 0 : cairo_line_to ( cr, p1x + part_stroke_length, p1y - half_stroke_length );
364 0 : cairo_line_to ( cr, p1x + 2.0 * part_stroke_length, p1y );
365 0 : cairo_line_to ( cr, p1x + part_stroke_length, p1y + half_stroke_length );
366 0 : cairo_line_to ( cr, p1x, p1y );
367 0 : p1x = p1x + 2.0 * part_stroke_length;
368 : /* if p2 == p1, also move p2 */
369 0 : if ( p2x < p1x )
370 : {
371 0 : p2x = p1x;
372 : }
373 : }
374 0 : break;
375 :
376 0 : case 6:
377 : {
378 0 : cairo_move_to ( cr, p1x, p1y );
379 0 : cairo_line_to ( cr, p1x + half_stroke_length, p1y + part_stroke_length );
380 0 : cairo_line_to ( cr, p1x, p1y + 2.0 * part_stroke_length );
381 0 : cairo_line_to ( cr, p1x - half_stroke_length, p1y + part_stroke_length );
382 0 : cairo_line_to ( cr, p1x, p1y );
383 0 : p1y = p1y + 2.0 * part_stroke_length;
384 : /* if p2 == p1, also move p2 */
385 0 : if ( p2y < p1y )
386 : {
387 0 : p2y = p1y;
388 : }
389 : }
390 0 : break;
391 :
392 0 : case 9:
393 : {
394 0 : cairo_move_to ( cr, p1x, p1y );
395 0 : cairo_line_to ( cr, p1x - part_stroke_length, p1y + half_stroke_length );
396 0 : cairo_line_to ( cr, p1x - 2.0 * part_stroke_length, p1y );
397 0 : cairo_line_to ( cr, p1x - part_stroke_length, p1y - half_stroke_length );
398 0 : cairo_line_to ( cr, p1x, p1y );
399 0 : p1x = p1x - 2.0 * part_stroke_length;
400 : /* if p2 == p1, also move p2 */
401 0 : if ( p2x > p1x )
402 : {
403 0 : p2x = p1x;
404 : }
405 : }
406 0 : break;
407 :
408 0 : default:
409 : {
410 0 : U8_LOG_ERROR("illegal case");
411 : }
412 0 : break;
413 : }
414 0 : if ( data_relationship_get_main_type( the_relationship ) == DATA_RELATIONSHIP_TYPE_UML_COMPOSITION )
415 : {
416 0 : cairo_fill (cr);
417 : }
418 : else
419 : {
420 0 : cairo_stroke (cr);
421 : }
422 : }
423 0 : break;
424 :
425 0 : case DATA_RELATIONSHIP_TYPE_UML_CONTAINMENT:
426 : {
427 : /* circle with plus */
428 : /* const double stroke_length = pencil_size_get_arrow_stroke_length( pencil_size ); */
429 0 : const double half_stroke_length = 0.5 * pencil_size_get_arrow_stroke_length( pencil_size );
430 : switch ( feathers_clock_direction )
431 : {
432 0 : case 0: /* direction: 12 o clock */
433 : {
434 0 : cairo_new_sub_path (cr); /* to be called before arc */
435 0 : cairo_arc ( cr, p1x, p1y - half_stroke_length, half_stroke_length, 0.0, 2.0*M_PI );
436 0 : cairo_move_to ( cr, p1x - half_stroke_length, p1y - half_stroke_length );
437 0 : cairo_line_to ( cr, p1x + half_stroke_length, p1y - half_stroke_length );
438 0 : cairo_stroke (cr);
439 : }
440 0 : break;
441 :
442 0 : case 3:
443 : {
444 0 : cairo_new_sub_path (cr);
445 0 : cairo_arc ( cr, p1x + half_stroke_length, p1y, half_stroke_length, 0.0, 2.0*M_PI );
446 0 : cairo_move_to ( cr, p1x + half_stroke_length, p1y - half_stroke_length );
447 0 : cairo_line_to ( cr, p1x + half_stroke_length, p1y + half_stroke_length );
448 0 : cairo_stroke (cr);
449 : }
450 0 : break;
451 :
452 0 : case 6:
453 : {
454 0 : cairo_new_sub_path (cr);
455 0 : cairo_arc ( cr, p1x, p1y + half_stroke_length, half_stroke_length, 0.0, 2.0*M_PI );
456 0 : cairo_move_to ( cr, p1x - half_stroke_length, p1y + half_stroke_length );
457 0 : cairo_line_to ( cr, p1x + half_stroke_length, p1y + half_stroke_length );
458 0 : cairo_stroke (cr);
459 : }
460 0 : break;
461 :
462 0 : case 9:
463 : {
464 0 : cairo_new_sub_path (cr);
465 0 : cairo_arc ( cr, p1x - half_stroke_length, p1y, half_stroke_length, 0.0, 2.0*M_PI );
466 0 : cairo_move_to ( cr, p1x - half_stroke_length, p1y - half_stroke_length );
467 0 : cairo_line_to ( cr, p1x - half_stroke_length, p1y + half_stroke_length );
468 0 : cairo_stroke (cr);
469 : }
470 0 : break;
471 :
472 0 : default:
473 : {
474 0 : U8_LOG_ERROR("illegal case");
475 : }
476 0 : break;
477 : }
478 : }
479 0 : break;
480 :
481 0 : case DATA_RELATIONSHIP_TYPE_UML_ASSOCIATION:
482 : case DATA_RELATIONSHIP_TYPE_UML_GENERALIZATION:
483 : case DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL:
484 : case DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL:
485 : case DATA_RELATIONSHIP_TYPE_UML_COMMUNICATION_PATH:
486 : case DATA_RELATIONSHIP_TYPE_UML_CONTROL_FLOW:
487 : case DATA_RELATIONSHIP_TYPE_UML_OBJECT_FLOW:
488 : case DATA_RELATIONSHIP_TYPE_UML_EXTEND: /* t.b.d. */
489 : case DATA_RELATIONSHIP_TYPE_UML_INCLUDE: /* t.b.d. */
490 : case DATA_RELATIONSHIP_TYPE_UML_DEPLOY:
491 : case DATA_RELATIONSHIP_TYPE_UML_MANIFEST: /* t.b.d. */
492 : case DATA_RELATIONSHIP_TYPE_UML_REALIZATION:
493 : case DATA_RELATIONSHIP_TYPE_UML_DEPENDENCY:
494 : case DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL:
495 : case DATA_RELATIONSHIP_TYPE_UML_REFINE:
496 : case DATA_RELATIONSHIP_TYPE_UML_TRACE:
497 : {
498 : /* no rhomboid or other feathers */
499 : }
500 0 : break;
501 :
502 0 : default:
503 : {
504 0 : U8_LOG_ANOMALY("unknown data_relationship_type_t in pencil_relationship_painter_draw()");
505 : /* this may happen if a new database file has been read by an old program version */
506 : /* no rhomboid or other feathers */
507 : }
508 0 : break;
509 : }
510 :
511 : /* set the right line type: dashed/normal */
512 0 : switch ( data_relationship_get_main_type( the_relationship ) )
513 : {
514 0 : case DATA_RELATIONSHIP_TYPE_UML_ASSOCIATION:
515 : case DATA_RELATIONSHIP_TYPE_UML_AGGREGATION:
516 : case DATA_RELATIONSHIP_TYPE_UML_COMPOSITION:
517 : case DATA_RELATIONSHIP_TYPE_UML_GENERALIZATION:
518 : case DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL:
519 : case DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL:
520 : case DATA_RELATIONSHIP_TYPE_UML_COMMUNICATION_PATH:
521 : case DATA_RELATIONSHIP_TYPE_UML_CONTROL_FLOW:
522 : case DATA_RELATIONSHIP_TYPE_UML_OBJECT_FLOW:
523 : case DATA_RELATIONSHIP_TYPE_UML_CONTAINMENT:
524 : {
525 : /* no dashes */
526 0 : cairo_set_dash ( cr, NULL, 0, 0.0 );
527 : }
528 0 : break;
529 :
530 0 : case DATA_RELATIONSHIP_TYPE_UML_EXTEND: /* t.b.d. */
531 : case DATA_RELATIONSHIP_TYPE_UML_INCLUDE: /* t.b.d. */
532 : case DATA_RELATIONSHIP_TYPE_UML_DEPLOY:
533 : case DATA_RELATIONSHIP_TYPE_UML_MANIFEST: /* t.b.d. */
534 : case DATA_RELATIONSHIP_TYPE_UML_REALIZATION:
535 : case DATA_RELATIONSHIP_TYPE_UML_DEPENDENCY:
536 : case DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL:
537 : case DATA_RELATIONSHIP_TYPE_UML_REFINE:
538 : case DATA_RELATIONSHIP_TYPE_UML_TRACE:
539 : {
540 : double dashes[1];
541 0 : dashes[0] = pencil_size_get_line_dash_length( pencil_size );
542 0 : cairo_set_dash ( cr, dashes, 1, 0.0 );
543 : }
544 0 : break;
545 :
546 0 : default:
547 : {
548 0 : U8_LOG_ANOMALY("unknown data_relationship_type_t in pencil_relationship_painter_draw()");
549 : /* this may happen if a new database file has been read by an old program version */
550 : double error_dashes[1];
551 0 : error_dashes[0] = 0.2*pencil_size_get_line_dash_length( pencil_size );
552 0 : cairo_set_dash ( cr, error_dashes, 1, 0.0 );
553 : }
554 0 : break;
555 : }
556 :
557 : /* draw connector line */
558 : {
559 0 : const double radius = 2.0 * pencil_size_get_arrow_stroke_length( pencil_size );
560 : double dx;
561 : double dy;
562 0 : cairo_move_to ( cr, p1x, p1y );
563 0 : dx = p2x - p1x;
564 0 : dy = p2y - p1y;
565 0 : if ( dx > +radius ) { dx = +radius; }
566 0 : if ( dx < -radius ) { dx = -radius; }
567 0 : if ( dy > +radius ) { dy = +radius; }
568 0 : if ( dy < -radius ) { dy = -radius; }
569 0 : cairo_line_to ( cr, p2x - dx, p2y - dy );
570 0 : dx = center_x - p2x;
571 0 : dy = center_y - p2y;
572 0 : if ( dx > +radius ) { dx = +radius; }
573 0 : if ( dx < -radius ) { dx = -radius; }
574 0 : if ( dy > +radius ) { dy = +radius; }
575 0 : if ( dy < -radius ) { dy = -radius; }
576 0 : cairo_curve_to ( cr, p2x, p2y, p2x, p2y, p2x + dx, p2y + dy );
577 0 : dx = p3x - center_x;
578 0 : dy = p3y - center_y;
579 0 : if ( dx > +radius ) { dx = +radius; }
580 0 : if ( dx < -radius ) { dx = -radius; }
581 0 : if ( dy > +radius ) { dy = +radius; }
582 0 : if ( dy < -radius ) { dy = -radius; }
583 0 : cairo_line_to ( cr, p3x - dx, p3y - dy );
584 0 : dx = p4x - p3x;
585 0 : dy = p4y - p3y;
586 0 : if ( dx > +radius ) { dx = +radius; }
587 0 : if ( dx < -radius ) { dx = -radius; }
588 0 : if ( dy > +radius ) { dy = +radius; }
589 0 : if ( dy < -radius ) { dy = -radius; }
590 0 : cairo_curve_to ( cr, p3x, p3y, p3x, p3y, p3x + dx, p3y + dy );
591 0 : cairo_line_to ( cr, p4x, p4y );
592 0 : cairo_stroke (cr);
593 : }
594 :
595 : /* reset dashes */
596 0 : cairo_set_dash ( cr, NULL, 0, 0.0 );
597 :
598 : /* draw the label */
599 0 : draw_relationship_label_draw_type_and_name ( &((*this_).draw_relationship_label),
600 : the_relationship,
601 : profile,
602 : &foreground_color,
603 : layout_relationship_get_label_box_const( layouted_relationship ),
604 : pencil_size,
605 : layout,
606 : cr
607 : );
608 :
609 : /* draw markers */
610 0 : if ( mark_selected )
611 : {
612 : const geometry_rectangle_t bounds
613 0 : = geometry_connector_get_bounding_rectangle( connector_shape );
614 0 : pencil_marker_mark_selected_rectangle( &((*this_).marker), bounds, cr );
615 : }
616 :
617 0 : if ( mark_focused )
618 : {
619 : const geometry_rectangle_t bounds
620 0 : = geometry_connector_get_bounding_rectangle( connector_shape );
621 0 : pencil_marker_mark_focused_rectangle( &((*this_).marker), bounds, cr );
622 : }
623 : }
624 : else
625 : {
626 0 : U8_LOG_ERROR("invalid relationship in array!");
627 : }
628 :
629 0 : U8_TRACE_END();
630 0 : }
631 :
632 :
633 : /*
634 : Copyright 2017-2024 Andreas Warnke
635 :
636 : Licensed under the Apache License, Version 2.0 (the "License");
637 : you may not use this file except in compliance with the License.
638 : You may obtain a copy of the License at
639 :
640 : http://www.apache.org/licenses/LICENSE-2.0
641 :
642 : Unless required by applicable law or agreed to in writing, software
643 : distributed under the License is distributed on an "AS IS" BASIS,
644 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
645 : See the License for the specific language governing permissions and
646 : limitations under the License.
647 : */
|