Line data Source code
1 : /* File: pencil_classifier_painter.c; Copyright and License: see below */
2 :
3 : #include "pencil_classifier_painter.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_f64.h"
6 : #include "utf8stringbuf/utf8stringbuf.h"
7 : #include "utf8stringbuf/utf8string.h"
8 : #include <pango/pangocairo.h>
9 : #include <stdio.h>
10 : #include <stdlib.h>
11 : #include <assert.h>
12 :
13 0 : void pencil_classifier_painter_init( pencil_classifier_painter_t *this_ )
14 : {
15 0 : U8_TRACE_BEGIN();
16 :
17 0 : pencil_marker_init( &((*this_).marker) );
18 0 : draw_classifier_icon_init( &((*this_).draw_classifier_icon) );
19 0 : draw_classifier_label_init( &((*this_).draw_classifier_label) );
20 0 : draw_classifier_contour_init( &((*this_).draw_classifier_contour) );
21 0 : draw_stereotype_icon_init( &((*this_).draw_stereotype_icon) );
22 :
23 0 : U8_TRACE_END();
24 0 : }
25 :
26 0 : void pencil_classifier_painter_destroy( pencil_classifier_painter_t *this_ )
27 : {
28 0 : U8_TRACE_BEGIN();
29 :
30 0 : draw_classifier_icon_destroy( &((*this_).draw_classifier_icon) );
31 0 : draw_classifier_label_destroy( &((*this_).draw_classifier_label) );
32 0 : draw_classifier_contour_destroy( &((*this_).draw_classifier_contour) );
33 0 : draw_stereotype_icon_destroy( &((*this_).draw_stereotype_icon) );
34 0 : pencil_marker_destroy( &((*this_).marker) );
35 :
36 0 : U8_TRACE_END();
37 0 : }
38 :
39 0 : void pencil_classifier_painter_draw( pencil_classifier_painter_t *this_,
40 : const layout_visible_classifier_t *layouted_classifier,
41 : data_id_t mark_focused,
42 : data_id_t mark_highlighted,
43 : const data_small_set_t *mark_selected,
44 : const layout_visible_set_t *layout_data,
45 : const data_profile_part_t *profile,
46 : const pencil_size_t *pencil_size,
47 : PangoLayout *font_layout,
48 : cairo_t *cr )
49 : {
50 0 : U8_TRACE_BEGIN();
51 0 : assert( NULL != layouted_classifier );
52 0 : assert( NULL != mark_selected );
53 0 : assert( NULL != layout_data );
54 0 : assert( NULL != profile );
55 0 : assert( NULL != pencil_size );
56 0 : assert( NULL != font_layout );
57 0 : assert( NULL != cr );
58 :
59 : const data_visible_classifier_t *const visible_classifier
60 0 : = layout_visible_classifier_get_data_const( layouted_classifier );
61 : const geometry_rectangle_t *const classifier_symbol_box
62 0 : = layout_visible_classifier_get_symbol_box_const( layouted_classifier );
63 : const geometry_rectangle_t *const classifier_label_box
64 0 : = layout_visible_classifier_get_label_box_const( layouted_classifier );
65 : const geometry_rectangle_t *const classifier_icon_box
66 0 : = layout_visible_classifier_get_icon_box_const( layouted_classifier );
67 : const data_classifier_t *const classifier
68 0 : = data_visible_classifier_get_classifier_const( visible_classifier );
69 : const data_diagramelement_t *const diagramelement
70 0 : = data_visible_classifier_get_diagramelement_const( visible_classifier );
71 0 : const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
72 0 : const char *const classifier_stereotype = data_classifier_get_stereotype_const( classifier );
73 : const bool has_stereotype_image
74 0 : = draw_stereotype_icon_exists( &((*this_).draw_stereotype_icon), classifier_stereotype, profile );
75 : const data_diagramelement_flag_t display_flags
76 0 : = data_diagramelement_get_display_flags( diagramelement );
77 :
78 0 : const double gap = pencil_size_get_standard_object_border( pencil_size );
79 0 : const double std_line_width = pencil_size_get_standard_line_width( pencil_size );
80 : /* set the right drawing color */
81 : GdkRGBA foreground_color;
82 : {
83 0 : if ( data_id_equals_id( &mark_highlighted, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id( diagramelement ) ) )
84 : {
85 0 : foreground_color = pencil_size_get_highlight_color( pencil_size );
86 : }
87 0 : else if ( 0 != ( display_flags & DATA_DIAGRAMELEMENT_FLAG_GRAY_OUT ))
88 : {
89 0 : foreground_color = pencil_size_get_gray_out_color( pencil_size );
90 : }
91 : else
92 : {
93 0 : foreground_color = pencil_size_get_standard_color( pencil_size );
94 : }
95 : }
96 :
97 0 : U8_TRACE_INFO_INT("drawing classifier id", data_classifier_get_row_id( classifier ) );
98 :
99 : /* draw the stereotype image */
100 0 : bool icon_override = false; /* in case of a stereotype image, the icon shall not be drawn. */
101 0 : if ( has_stereotype_image )
102 : {
103 : /* check if the image is a small icon within a contour or if it is the full symbol */
104 0 : const bool has_contour = geometry_rectangle_is_containing( classifier_symbol_box, classifier_label_box );
105 :
106 0 : cairo_set_line_width( cr, std_line_width );
107 :
108 : u8_error_info_t err_info;
109 : const u8_error_t stereotype_err
110 0 : = draw_stereotype_icon_draw( &((*this_).draw_stereotype_icon),
111 : data_classifier_get_stereotype_const( classifier ),
112 : profile,
113 : &foreground_color,
114 : &err_info,
115 : has_contour ? classifier_icon_box : classifier_symbol_box,
116 : cr
117 : );
118 0 : if ( u8_error_info_is_error( &err_info ) )
119 : {
120 0 : U8_LOG_WARNING_INT( "stereotype image: unxpected token in svg path in line",
121 : u8_error_info_get_line( &err_info )
122 : );
123 : }
124 0 : icon_override = ( stereotype_err == U8_ERROR_NONE );
125 : }
126 :
127 : /* draw the classifier */
128 : {
129 : /* set line width */
130 0 : cairo_set_line_width( cr, std_line_width );
131 : /* set color */
132 0 : cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
133 :
134 : /* highlight */
135 0 : if ( 0 != ( display_flags & DATA_DIAGRAMELEMENT_FLAG_EMPHASIS ))
136 : {
137 0 : const GdkRGBA emph_color = pencil_size_get_emphasized_bgcolor( pencil_size );
138 0 : cairo_set_source_rgba( cr, emph_color.red, emph_color.green, emph_color.blue, emph_color.alpha );
139 0 : cairo_rectangle ( cr,
140 : geometry_rectangle_get_left( classifier_label_box ),
141 : geometry_rectangle_get_top( classifier_label_box ),
142 : geometry_rectangle_get_width( classifier_label_box ),
143 : geometry_rectangle_get_height( classifier_label_box )
144 : );
145 0 : cairo_fill (cr);
146 0 : cairo_set_source_rgba( cr, foreground_color.red, foreground_color.green, foreground_color.blue, foreground_color.alpha );
147 : }
148 :
149 : /* draw label */
150 0 : draw_classifier_label_draw_stereotype_and_name( &((*this_).draw_classifier_label),
151 : visible_classifier,
152 : ( ! has_stereotype_image ),
153 : &foreground_color,
154 : classifier_label_box,
155 : pencil_size,
156 : font_layout,
157 : cr
158 0 : );
159 :
160 : /* draw rectangle */
161 : geometry_rectangle_t classifier_symbol_border;
162 : {
163 0 : geometry_rectangle_copy( &classifier_symbol_border, classifier_symbol_box );
164 0 : geometry_rectangle_enlarge( &classifier_symbol_border, -2.0*gap, -2.0*gap );
165 0 : geometry_rectangle_shift( &classifier_symbol_border, gap, gap );
166 : }
167 0 : const double symbol_left = geometry_rectangle_get_left ( &classifier_symbol_border );
168 0 : const double symbol_top = geometry_rectangle_get_top ( &classifier_symbol_border );
169 0 : const double symbol_width = geometry_rectangle_get_width ( &classifier_symbol_border );
170 0 : const double symbol_height = geometry_rectangle_get_height ( &classifier_symbol_border );
171 0 : switch ( classifier_type )
172 : {
173 0 : case DATA_CLASSIFIER_TYPE_REQUIREMENT: /* SysML */
174 : case DATA_CLASSIFIER_TYPE_PART:
175 : {
176 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
177 : }
178 0 : break;
179 :
180 0 : case DATA_CLASSIFIER_TYPE_BLOCK: /* SysML */
181 : case DATA_CLASSIFIER_TYPE_CLASS:
182 : case DATA_CLASSIFIER_TYPE_OBJECT:
183 : case DATA_CLASSIFIER_TYPE_INTERFACE:
184 : case DATA_CLASSIFIER_TYPE_STEREOTYPE:
185 : {
186 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
187 0 : pencil_classifier_painter_private_draw_feature_compartments( this_,
188 : layouted_classifier,
189 : layout_data,
190 : pencil_size,
191 : cr
192 : );
193 : }
194 0 : break;
195 :
196 0 : case DATA_CLASSIFIER_TYPE_COMPONENT:
197 : {
198 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
199 :
200 : /* draw icon */
201 0 : const double component_icon_height = pencil_size_get_title_font_size( pencil_size );
202 : const geometry_rectangle_t icon_bounds
203 0 : = draw_classifier_icon_get_component_bounds( &((*this_).draw_classifier_icon),
204 0 : symbol_left + symbol_width - gap, /* x */
205 : symbol_top + gap, /* y */
206 : GEOMETRY_H_ALIGN_RIGHT,
207 : GEOMETRY_V_ALIGN_TOP,
208 : component_icon_height
209 : );
210 0 : if ( ! icon_override )
211 : {
212 0 : draw_classifier_icon_draw_component ( &((*this_).draw_classifier_icon), icon_bounds, cr );
213 : }
214 : }
215 0 : break;
216 :
217 0 : case DATA_CLASSIFIER_TYPE_ARTIFACT:
218 : {
219 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
220 :
221 : /* draw icon */
222 0 : const double artifact_icon_height = pencil_size_get_title_font_size( pencil_size );
223 : const geometry_rectangle_t icon_bounds
224 0 : = draw_classifier_icon_get_artifact_bounds( &((*this_).draw_classifier_icon),
225 0 : symbol_left + symbol_width - gap, /* x */
226 : symbol_top + gap, /* y */
227 : GEOMETRY_H_ALIGN_RIGHT,
228 : GEOMETRY_V_ALIGN_TOP,
229 : artifact_icon_height
230 : );
231 0 : if ( ! icon_override )
232 : {
233 0 : draw_classifier_icon_draw_artifact ( &((*this_).draw_classifier_icon), icon_bounds, cr );
234 : }
235 : }
236 0 : break;
237 :
238 0 : case DATA_CLASSIFIER_TYPE_ACTIVITY:
239 : case DATA_CLASSIFIER_TYPE_STATE:
240 : case DATA_CLASSIFIER_TYPE_CONSTRAINT_BLOCK:
241 : {
242 0 : draw_classifier_contour_draw_rounded_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, false, pencil_size, cr );
243 0 : pencil_classifier_painter_private_draw_feature_compartments( this_,
244 : layouted_classifier,
245 : layout_data,
246 : pencil_size,
247 : cr
248 : );
249 : }
250 0 : break;
251 :
252 0 : case DATA_CLASSIFIER_TYPE_DYN_INTERRUPTABLE_REGION:
253 : {
254 0 : draw_classifier_contour_draw_rounded_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, true, pencil_size, cr );
255 : }
256 0 : break;
257 :
258 0 : case DATA_CLASSIFIER_TYPE_USE_CASE:
259 : {
260 0 : draw_classifier_contour_draw_ellipse ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
261 0 : pencil_classifier_painter_private_draw_feature_compartments( this_,
262 : layouted_classifier,
263 : layout_data,
264 : pencil_size,
265 : cr
266 : );
267 : }
268 0 : break;
269 :
270 0 : case DATA_CLASSIFIER_TYPE_NODE:
271 : {
272 0 : draw_classifier_contour_draw_3d_box ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
273 : }
274 0 : break;
275 :
276 0 : case DATA_CLASSIFIER_TYPE_ACTOR:
277 : {
278 0 : if ( ! icon_override )
279 : {
280 0 : const double actor_height = symbol_height;
281 0 : const double half_width = 0.5 * symbol_width;
282 : const geometry_rectangle_t icon_bounds
283 0 : = draw_classifier_icon_get_actor_bounds( &((*this_).draw_classifier_icon),
284 : symbol_left + half_width,
285 : symbol_top,
286 : GEOMETRY_H_ALIGN_CENTER,
287 : GEOMETRY_V_ALIGN_TOP,
288 : actor_height
289 : );
290 0 : draw_classifier_icon_draw_actor ( &((*this_).draw_classifier_icon), icon_bounds, cr );
291 : }
292 : }
293 0 : break;
294 :
295 0 : case DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE:
296 : case DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE:
297 : case DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY:
298 : case DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY:
299 : {
300 0 : if ( ! icon_override )
301 : {
302 0 : const double circle_diameter = symbol_height;
303 0 : const double half_width = 0.5 * symbol_width;
304 : const geometry_rectangle_t icon_bounds
305 0 : = draw_classifier_icon_get_circle_bounds( &((*this_).draw_classifier_icon),
306 : symbol_left + half_width,
307 : symbol_top,
308 : GEOMETRY_H_ALIGN_CENTER,
309 : GEOMETRY_V_ALIGN_TOP,
310 : circle_diameter
311 : );
312 0 : const bool stroke = ( classifier_type != DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE );
313 0 : const bool fill = ( ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE )
314 0 : || ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE ) );
315 0 : const bool shallow_history = ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY );
316 0 : const bool deep_history = ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY );
317 0 : draw_classifier_icon_draw_circle( &((*this_).draw_classifier_icon),
318 : icon_bounds,
319 : pencil_size,
320 : stroke,
321 : fill,
322 : shallow_history,
323 : deep_history,
324 : cr
325 : );
326 : }
327 : }
328 0 : break;
329 :
330 0 : case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_EVENT :
331 : {
332 0 : draw_classifier_contour_draw_accept_event ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
333 : }
334 0 : break;
335 :
336 0 : case DATA_CLASSIFIER_TYPE_DYN_SEND_SIGNAL:
337 : {
338 0 : draw_classifier_contour_draw_send_signal ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
339 : }
340 0 : break;
341 :
342 0 : case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_TIME_EVENT:
343 : {
344 0 : if ( ! icon_override )
345 : {
346 0 : const double time_icon_height = symbol_height;
347 0 : const double half_width = 0.5 * symbol_width;
348 : const geometry_rectangle_t icon_bounds
349 0 : = draw_classifier_icon_get_time_bounds( &((*this_).draw_classifier_icon),
350 : symbol_left + half_width,
351 : symbol_top,
352 : GEOMETRY_H_ALIGN_CENTER,
353 : GEOMETRY_V_ALIGN_TOP,
354 : time_icon_height
355 : );
356 0 : draw_classifier_icon_draw_time ( &((*this_).draw_classifier_icon), icon_bounds, cr );
357 : }
358 : }
359 0 : break;
360 :
361 0 : case DATA_CLASSIFIER_TYPE_DYN_FORK_NODE:
362 : case DATA_CLASSIFIER_TYPE_DYN_JOIN_NODE:
363 : {
364 0 : if ( ! icon_override )
365 : {
366 0 : const double box_icon_height = symbol_height;
367 0 : const double half_width = 0.5 * symbol_width;
368 : const geometry_rectangle_t icon_bounds
369 0 : = draw_classifier_icon_get_sync_bounds( &((*this_).draw_classifier_icon),
370 : symbol_left + half_width,
371 : symbol_top,
372 : GEOMETRY_H_ALIGN_CENTER,
373 : GEOMETRY_V_ALIGN_TOP,
374 : box_icon_height,
375 : pencil_size
376 : );
377 0 : draw_classifier_icon_draw_sync ( &((*this_).draw_classifier_icon), icon_bounds, cr );
378 : }
379 : }
380 0 : break;
381 :
382 0 : case DATA_CLASSIFIER_TYPE_DYN_DECISION_NODE:
383 : {
384 0 : draw_classifier_contour_draw_rhombus ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
385 : }
386 0 : break;
387 :
388 0 : case DATA_CLASSIFIER_TYPE_SUBSYSTEM:
389 : {
390 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
391 : }
392 0 : break;
393 :
394 0 : case DATA_CLASSIFIER_TYPE_DIAGRAM_REFERENCE:
395 : {
396 0 : draw_classifier_contour_draw_diagram_ref ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
397 : }
398 0 : break;
399 :
400 0 : case DATA_CLASSIFIER_TYPE_PACKAGE:
401 : {
402 : geometry_rectangle_t label_and_icon_box;
403 0 : geometry_rectangle_init_by_bounds( &label_and_icon_box, classifier_label_box, classifier_icon_box );
404 0 : draw_classifier_contour_draw_package( &((*this_).draw_classifier_contour),
405 : classifier_symbol_box,
406 : &label_and_icon_box,
407 : pencil_size,
408 : cr
409 : );
410 0 : geometry_rectangle_destroy( &label_and_icon_box );
411 : }
412 0 : break;
413 :
414 0 : case DATA_CLASSIFIER_TYPE_COMMENT:
415 : {
416 0 : draw_classifier_contour_draw_comment ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
417 : }
418 0 : break;
419 :
420 0 : case DATA_CLASSIFIER_TYPE_IMAGE:
421 : {
422 0 : if ( ! icon_override )
423 : {
424 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
425 : }
426 : }
427 0 : break;
428 :
429 0 : default:
430 : {
431 : /* this case can happen if a model file of a new cfu version is opened with an older version of cfu */
432 0 : U8_LOG_ANOMALY("unknown data_classifier_type_t in pencil_classifier_painter_draw()");
433 : /* type is unknown, so one cannot decide if to draw rounded corners. */
434 0 : draw_classifier_contour_draw_cornerless( &((*this_).draw_classifier_contour),
435 : classifier_symbol_box,
436 : pencil_size,
437 : cr
438 : );
439 : }
440 0 : break;
441 : }
442 :
443 0 : if ( data_small_set_contains_row_id( mark_selected, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id(diagramelement) ) )
444 : {
445 0 : pencil_marker_mark_selected_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
446 : }
447 :
448 0 : if ( data_id_equals_id( &mark_focused, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row_id(diagramelement) )
449 0 : || data_id_equals_id( &mark_focused, DATA_TABLE_CLASSIFIER, data_classifier_get_row_id(classifier) ) )
450 : {
451 0 : pencil_marker_mark_focused_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
452 : }
453 : }
454 :
455 0 : U8_TRACE_END();
456 0 : }
457 :
458 0 : void pencil_classifier_painter_private_draw_feature_compartments( const pencil_classifier_painter_t *this_,
459 : const layout_visible_classifier_t *layouted_classifier,
460 : const layout_visible_set_t *layout_data,
461 : const pencil_size_t *pencil_size,
462 : cairo_t *cr )
463 : {
464 0 : U8_TRACE_BEGIN();
465 0 : assert( NULL != layouted_classifier );
466 0 : assert( NULL != layout_data );
467 0 : assert( NULL != pencil_size );
468 0 : assert( NULL != cr );
469 :
470 : /* define names for input data */
471 : const geometry_rectangle_t *const classifier_symbol_box
472 0 : = layout_visible_classifier_get_symbol_box_const( layouted_classifier );
473 : const geometry_rectangle_t *const classifier_space
474 0 : = layout_visible_classifier_get_space_const( layouted_classifier );
475 0 : const double gap = pencil_size_get_standard_object_border( pencil_size );
476 0 : const data_row_t diagele_id = layout_visible_classifier_get_diagramelement_id ( layouted_classifier );
477 :
478 : /* determine number of properties and operations */
479 0 : double compartment1_y = geometry_rectangle_get_top( classifier_space ) + gap;
480 0 : double compartment2_y = geometry_rectangle_get_top( classifier_space ) + 3.0 * gap;
481 0 : double compartment3_y = geometry_rectangle_get_top( classifier_space ) + 5.0 * gap;
482 0 : uint_fast32_t count_compartment_entries = 0;
483 :
484 0 : const uint32_t num_features = layout_visible_set_get_feature_count ( layout_data );
485 0 : for ( uint32_t f_probe_idx = 0; f_probe_idx < num_features; f_probe_idx ++ )
486 : {
487 0 : const layout_feature_t *const f_probe_layout = layout_visible_set_get_feature_const ( layout_data, f_probe_idx );
488 0 : assert ( NULL != f_probe_layout );
489 0 : const layout_visible_classifier_t *const probe_vis_classfy = layout_feature_get_classifier_const ( f_probe_layout );
490 0 : assert ( NULL != probe_vis_classfy );
491 :
492 : /* check if this f_probe_layout has the same diagram element id as the_feature */
493 0 : if ( diagele_id == layout_visible_classifier_get_diagramelement_id( probe_vis_classfy ) )
494 : {
495 : /* this is a feature of the current layouted_classifier */
496 0 : const data_feature_t *const f_probe_data = layout_feature_get_data_const( f_probe_layout );
497 0 : assert ( NULL != f_probe_data );
498 0 : const data_feature_type_t f_probe_type = data_feature_get_main_type( f_probe_data );
499 : const double f_probe_bottom
500 0 : = geometry_rectangle_get_bottom( layout_feature_get_symbol_box_const( f_probe_layout ) );
501 0 : if ( data_feature_type_inside_compartment( f_probe_type ) )
502 : {
503 0 : count_compartment_entries ++;
504 : }
505 0 : if ( DATA_FEATURE_TYPE_PROPERTY == f_probe_type )
506 : {
507 0 : compartment2_y = u8_f64_max2( compartment2_y, f_probe_bottom + gap );
508 0 : compartment3_y = u8_f64_max2( compartment3_y, f_probe_bottom + 3.0 * gap );
509 : }
510 0 : else if ( DATA_FEATURE_TYPE_OPERATION == f_probe_type )
511 : {
512 0 : compartment3_y = u8_f64_max2( compartment3_y, f_probe_bottom + gap );
513 : }
514 : }
515 : }
516 :
517 : /* draw compartments if there are features */
518 0 : if ( count_compartment_entries != 0 )
519 : {
520 : const data_visible_classifier_t *const visible_classifier
521 0 : = layout_visible_classifier_get_data_const( layouted_classifier );
522 : const data_classifier_t *const classifier
523 0 : = data_visible_classifier_get_classifier_const( visible_classifier );
524 0 : const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
525 :
526 0 : draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
527 : classifier_type,
528 : classifier_symbol_box,
529 : compartment1_y,
530 : pencil_size,
531 : cr
532 : );
533 0 : draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
534 : classifier_type,
535 : classifier_symbol_box,
536 : compartment2_y,
537 : pencil_size,
538 : cr
539 : );
540 0 : draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
541 : classifier_type,
542 : classifier_symbol_box,
543 : compartment3_y,
544 : pencil_size,
545 : cr
546 : );
547 : }
548 :
549 0 : U8_TRACE_END();
550 0 : }
551 :
552 :
553 : /*
554 : Copyright 2016-2025 Andreas Warnke
555 : http://www.apache.org/licenses/LICENSE-2.0
556 :
557 : Licensed under the Apache License, Version 2.0 (the "License");
558 : you may not use this file except in compliance with the License.
559 : You may obtain a copy of the License at
560 :
561 :
562 : Unless required by applicable law or agreed to in writing, software
563 : distributed under the License is distributed on an "AS IS" BASIS,
564 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
565 : See the License for the specific language governing permissions and
566 : limitations under the License.
567 : */
|