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( 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( 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 : }
188 0 : break;
189 :
190 0 : case DATA_CLASSIFIER_TYPE_COMPONENT:
191 : {
192 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
193 :
194 : /* draw icon */
195 0 : const double component_icon_height = pencil_size_get_title_font_size( pencil_size );
196 : const geometry_rectangle_t icon_bounds
197 0 : = draw_classifier_icon_get_component_bounds( &((*this_).draw_classifier_icon),
198 0 : symbol_left + symbol_width - gap, /* x */
199 : symbol_top + gap, /* y */
200 : GEOMETRY_H_ALIGN_RIGHT,
201 : GEOMETRY_V_ALIGN_TOP,
202 : component_icon_height
203 : );
204 0 : if ( ! icon_override )
205 : {
206 0 : draw_classifier_icon_draw_component ( &((*this_).draw_classifier_icon), icon_bounds, cr );
207 : }
208 : }
209 0 : break;
210 :
211 0 : case DATA_CLASSIFIER_TYPE_ARTIFACT:
212 : {
213 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
214 :
215 : /* draw icon */
216 0 : const double artifact_icon_height = pencil_size_get_title_font_size( pencil_size );
217 : const geometry_rectangle_t icon_bounds
218 0 : = draw_classifier_icon_get_artifact_bounds( &((*this_).draw_classifier_icon),
219 0 : symbol_left + symbol_width - gap, /* x */
220 : symbol_top + gap, /* y */
221 : GEOMETRY_H_ALIGN_RIGHT,
222 : GEOMETRY_V_ALIGN_TOP,
223 : artifact_icon_height
224 : );
225 0 : if ( ! icon_override )
226 : {
227 0 : draw_classifier_icon_draw_artifact ( &((*this_).draw_classifier_icon), icon_bounds, cr );
228 : }
229 : }
230 0 : break;
231 :
232 0 : case DATA_CLASSIFIER_TYPE_ACTIVITY:
233 : case DATA_CLASSIFIER_TYPE_STATE:
234 : case DATA_CLASSIFIER_TYPE_CONSTRAINT_BLOCK:
235 : {
236 0 : draw_classifier_contour_draw_rounded_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, false, pencil_size, cr );
237 : }
238 0 : break;
239 :
240 0 : case DATA_CLASSIFIER_TYPE_DYN_INTERRUPTABLE_REGION:
241 : {
242 0 : draw_classifier_contour_draw_rounded_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, true, pencil_size, cr );
243 : }
244 0 : break;
245 :
246 0 : case DATA_CLASSIFIER_TYPE_USE_CASE:
247 : {
248 0 : draw_classifier_contour_draw_ellipse ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
249 : }
250 0 : break;
251 :
252 0 : case DATA_CLASSIFIER_TYPE_NODE:
253 : {
254 0 : draw_classifier_contour_draw_3d_box ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
255 : }
256 0 : break;
257 :
258 0 : case DATA_CLASSIFIER_TYPE_ACTOR:
259 : {
260 0 : if ( ! icon_override )
261 : {
262 0 : const double actor_height = symbol_height;
263 0 : const double half_width = 0.5 * symbol_width;
264 : const geometry_rectangle_t icon_bounds
265 0 : = draw_classifier_icon_get_actor_bounds( &((*this_).draw_classifier_icon),
266 : symbol_left + half_width,
267 : symbol_top,
268 : GEOMETRY_H_ALIGN_CENTER,
269 : GEOMETRY_V_ALIGN_TOP,
270 : actor_height
271 : );
272 0 : draw_classifier_icon_draw_actor ( &((*this_).draw_classifier_icon), icon_bounds, cr );
273 : }
274 : }
275 0 : break;
276 :
277 0 : case DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE:
278 : case DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE:
279 : case DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY:
280 : case DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY:
281 : {
282 0 : if ( ! icon_override )
283 : {
284 0 : const double circle_diameter = symbol_height;
285 0 : const double half_width = 0.5 * symbol_width;
286 : const geometry_rectangle_t icon_bounds
287 0 : = draw_classifier_icon_get_circle_bounds( &((*this_).draw_classifier_icon),
288 : symbol_left + half_width,
289 : symbol_top,
290 : GEOMETRY_H_ALIGN_CENTER,
291 : GEOMETRY_V_ALIGN_TOP,
292 : circle_diameter
293 : );
294 0 : const bool stroke = ( classifier_type != DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE );
295 0 : const bool fill = ( ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_INITIAL_NODE )
296 0 : || ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_FINAL_NODE ) );
297 0 : const bool shallow_history = ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_SHALLOW_HISTORY );
298 0 : const bool deep_history = ( classifier_type == DATA_CLASSIFIER_TYPE_DYN_DEEP_HISTORY );
299 0 : draw_classifier_icon_draw_circle( &((*this_).draw_classifier_icon),
300 : icon_bounds,
301 : pencil_size,
302 : stroke,
303 : fill,
304 : shallow_history,
305 : deep_history,
306 : cr
307 : );
308 : }
309 : }
310 0 : break;
311 :
312 0 : case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_EVENT :
313 : {
314 0 : draw_classifier_contour_draw_accept_event ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
315 : }
316 0 : break;
317 :
318 0 : case DATA_CLASSIFIER_TYPE_DYN_SEND_SIGNAL:
319 : {
320 0 : draw_classifier_contour_draw_send_signal ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
321 : }
322 0 : break;
323 :
324 0 : case DATA_CLASSIFIER_TYPE_DYN_ACCEPT_TIME_EVENT:
325 : {
326 0 : if ( ! icon_override )
327 : {
328 0 : const double time_icon_height = symbol_height;
329 0 : const double half_width = 0.5 * symbol_width;
330 : const geometry_rectangle_t icon_bounds
331 0 : = draw_classifier_icon_get_time_bounds( &((*this_).draw_classifier_icon),
332 : symbol_left + half_width,
333 : symbol_top,
334 : GEOMETRY_H_ALIGN_CENTER,
335 : GEOMETRY_V_ALIGN_TOP,
336 : time_icon_height
337 : );
338 0 : draw_classifier_icon_draw_time ( &((*this_).draw_classifier_icon), icon_bounds, cr );
339 : }
340 : }
341 0 : break;
342 :
343 0 : case DATA_CLASSIFIER_TYPE_DYN_FORK_NODE:
344 : case DATA_CLASSIFIER_TYPE_DYN_JOIN_NODE:
345 : {
346 0 : if ( ! icon_override )
347 : {
348 0 : const double box_icon_height = symbol_height;
349 0 : const double half_width = 0.5 * symbol_width;
350 : const geometry_rectangle_t icon_bounds
351 0 : = draw_classifier_icon_get_sync_bounds( &((*this_).draw_classifier_icon),
352 : symbol_left + half_width,
353 : symbol_top,
354 : GEOMETRY_H_ALIGN_CENTER,
355 : GEOMETRY_V_ALIGN_TOP,
356 : box_icon_height,
357 : pencil_size
358 : );
359 0 : draw_classifier_icon_draw_sync ( &((*this_).draw_classifier_icon), icon_bounds, cr );
360 : }
361 : }
362 0 : break;
363 :
364 0 : case DATA_CLASSIFIER_TYPE_DYN_DECISION_NODE:
365 : {
366 0 : draw_classifier_contour_draw_rhombus ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
367 : }
368 0 : break;
369 :
370 0 : case DATA_CLASSIFIER_TYPE_SUBSYSTEM:
371 : {
372 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
373 : }
374 0 : break;
375 :
376 0 : case DATA_CLASSIFIER_TYPE_INTERACTION_USE:
377 : {
378 0 : draw_classifier_contour_draw_diagram_ref ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
379 : }
380 0 : break;
381 :
382 0 : case DATA_CLASSIFIER_TYPE_PACKAGE:
383 : {
384 : geometry_rectangle_t label_and_icon_box;
385 0 : geometry_rectangle_init_by_bounds( &label_and_icon_box, classifier_label_box, classifier_icon_box );
386 0 : draw_classifier_contour_draw_package( &((*this_).draw_classifier_contour),
387 : classifier_symbol_box,
388 : &label_and_icon_box,
389 : pencil_size,
390 : cr
391 : );
392 0 : geometry_rectangle_destroy( &label_and_icon_box );
393 : }
394 0 : break;
395 :
396 0 : case DATA_CLASSIFIER_TYPE_COMMENT:
397 : {
398 0 : draw_classifier_contour_draw_comment ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
399 : }
400 0 : break;
401 :
402 0 : case DATA_CLASSIFIER_TYPE_IMAGE:
403 : {
404 0 : if ( ! icon_override )
405 : {
406 0 : draw_classifier_contour_draw_rect ( &((*this_).draw_classifier_contour), classifier_symbol_box, pencil_size, cr );
407 : }
408 : }
409 0 : break;
410 :
411 0 : default:
412 : {
413 : /* this case can happen if a model file of a new cfu version is opened with an older version of cfu */
414 0 : U8_LOG_ANOMALY("unknown data_classifier_type_t in pencil_classifier_painter_draw()");
415 : /* type is unknown, so one cannot decide if to draw rounded corners. */
416 0 : draw_classifier_contour_draw_cornerless( &((*this_).draw_classifier_contour),
417 : classifier_symbol_box,
418 : pencil_size,
419 : cr
420 : );
421 : }
422 0 : break;
423 : }
424 :
425 : /* draw compartment separator lines */
426 0 : pencil_classifier_painter_private_draw_feature_compartments( this_,
427 : layouted_classifier,
428 : layout_data,
429 : &foreground_color,
430 : pencil_size,
431 : cr
432 : );
433 :
434 0 : if ( data_small_set_contains_row( mark_selected, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row(diagramelement) ) )
435 : {
436 0 : pencil_marker_mark_selected_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
437 : }
438 :
439 0 : if ( data_id_equals_id( &mark_focused, DATA_TABLE_DIAGRAMELEMENT, data_diagramelement_get_row(diagramelement) )
440 0 : || data_id_equals_id( &mark_focused, DATA_TABLE_CLASSIFIER, data_classifier_get_row(classifier) ) )
441 : {
442 0 : pencil_marker_mark_focused_rectangle( &((*this_).marker), *classifier_symbol_box, cr );
443 : }
444 : }
445 :
446 0 : U8_TRACE_END();
447 0 : }
448 :
449 0 : void pencil_classifier_painter_private_draw_feature_compartments( const pencil_classifier_painter_t *this_,
450 : const layout_visible_classifier_t *layouted_classifier,
451 : const layout_visible_set_t *layout_data,
452 : const GdkRGBA *foreground_color,
453 : const pencil_size_t *pencil_size,
454 : cairo_t *cr )
455 : {
456 0 : U8_TRACE_BEGIN();
457 0 : assert( NULL != layouted_classifier );
458 0 : assert( NULL != layout_data );
459 0 : assert( NULL != foreground_color );
460 0 : assert( NULL != pencil_size );
461 0 : assert( NULL != cr );
462 :
463 : /* define names for input data */
464 : const geometry_rectangle_t *const classifier_symbol_box
465 0 : = layout_visible_classifier_get_symbol_box_const( layouted_classifier );
466 : const geometry_rectangle_t *const classifier_compartments
467 0 : = layout_visible_classifier_get_compartments_const( layouted_classifier );
468 0 : const double gap = pencil_size_get_standard_object_border( pencil_size );
469 0 : const data_row_t diagele_id = layout_visible_classifier_get_diagramelement_id ( layouted_classifier );
470 :
471 : /* get classifier type */
472 : const data_visible_classifier_t *const visible_classifier
473 0 : = layout_visible_classifier_get_data_const( layouted_classifier );
474 : const data_classifier_t *const classifier
475 0 : = data_visible_classifier_get_classifier_const( visible_classifier );
476 0 : const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
477 :
478 : /* determine number of properties and operations */
479 0 : bool has_compartment_entries = false;
480 :
481 0 : const uint32_t num_features = layout_visible_set_get_feature_count ( layout_data );
482 0 : for ( uint32_t f_probe_idx = 0; f_probe_idx < num_features; f_probe_idx ++ )
483 : {
484 0 : const layout_feature_t *const f_probe_layout = layout_visible_set_get_feature_const ( layout_data, f_probe_idx );
485 0 : assert ( NULL != f_probe_layout );
486 0 : const layout_visible_classifier_t *const probe_vis_classfy = layout_feature_get_classifier_const ( f_probe_layout );
487 0 : assert ( NULL != probe_vis_classfy );
488 :
489 : /* check if this f_probe_layout has the same diagram element id as the_feature */
490 0 : if ( diagele_id == layout_visible_classifier_get_diagramelement_id( probe_vis_classfy ) )
491 : {
492 : /* this is a feature of the current layouted_classifier */
493 0 : const data_feature_t *const f_probe_data = layout_feature_get_data_const( f_probe_layout );
494 0 : assert ( NULL != f_probe_data );
495 0 : const data_feature_type_t f_probe_type = data_feature_get_main_type( f_probe_data );
496 0 : if ( data_feature_type_inside_compartment( f_probe_type ) )
497 : {
498 0 : has_compartment_entries = true;
499 : }
500 :
501 : const double f_probe_top
502 0 : = geometry_rectangle_get_top( layout_feature_get_symbol_box_const( f_probe_layout ) );
503 0 : const bool is_first_in_compartment = layout_feature_is_first_in_compartment( f_probe_layout );
504 0 : if ( data_feature_type_inside_compartment( f_probe_type ) && is_first_in_compartment )
505 : {
506 0 : draw_classifier_contour_draw_compartment_line( &((*this_).draw_classifier_contour),
507 : classifier_type,
508 : classifier_symbol_box,
509 0 : f_probe_top - 3.0 * gap, /* 2.0 * gap for compartment label */
510 : f_probe_type,
511 : foreground_color,
512 : pencil_size,
513 : cr
514 : );
515 : }
516 : }
517 : }
518 :
519 : /* draw compartments if there are features */
520 0 : if ( has_compartment_entries )
521 : {
522 0 : double compartment_bottom_line = geometry_rectangle_get_bottom( classifier_compartments ) - 1.0 * gap;
523 0 : draw_classifier_contour_draw_compartment_line ( &((*this_).draw_classifier_contour),
524 : classifier_type,
525 : classifier_symbol_box,
526 : compartment_bottom_line,
527 : DATA_FEATURE_TYPE_VOID,
528 : foreground_color,
529 : pencil_size,
530 : cr
531 : );
532 : }
533 :
534 0 : U8_TRACE_END();
535 0 : }
536 :
537 :
538 : /*
539 : Copyright 2016-2026 Andreas Warnke
540 : http://www.apache.org/licenses/LICENSE-2.0
541 :
542 : Licensed under the Apache License, Version 2.0 (the "License");
543 : you may not use this file except in compliance with the License.
544 : You may obtain a copy of the License at
545 :
546 :
547 : Unless required by applicable law or agreed to in writing, software
548 : distributed under the License is distributed on an "AS IS" BASIS,
549 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
550 : See the License for the specific language governing permissions and
551 : limitations under the License.
552 : */
|