Line data Source code
1 : /* File: draw_feature_symbol.c; Copyright and License: see below */
2 :
3 : #include "draw/draw_feature_symbol.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_f64.h"
6 : #include <stdio.h>
7 : #include <stdlib.h>
8 : #include <assert.h>
9 : #include <math.h>
10 :
11 0 : void draw_feature_symbol_init( draw_feature_symbol_t *this_ )
12 : {
13 0 : U8_TRACE_BEGIN();
14 :
15 0 : (*this_).last_depth = 0;
16 0 : (*this_).last_location = INFINITY;
17 :
18 0 : U8_TRACE_END();
19 0 : }
20 :
21 0 : void draw_feature_symbol_reinit( draw_feature_symbol_t *this_ )
22 : {
23 0 : U8_TRACE_BEGIN();
24 :
25 0 : (*this_).last_depth = 0;
26 0 : (*this_).last_location = INFINITY;
27 :
28 0 : U8_TRACE_END();
29 0 : }
30 :
31 0 : void draw_feature_symbol_destroy( draw_feature_symbol_t *this_ )
32 : {
33 0 : U8_TRACE_BEGIN();
34 0 : U8_TRACE_END();
35 0 : }
36 :
37 :
38 0 : void draw_feature_symbol_draw_execution_spec( draw_feature_symbol_t *this_,
39 : const geometry_rectangle_t *bounds,
40 : double to_y,
41 : uint32_t depth,
42 : const pencil_size_t *pencil_size,
43 : cairo_t *cr )
44 : {
45 0 : U8_TRACE_BEGIN();
46 0 : assert ( NULL != bounds );
47 0 : assert ( NULL != pencil_size );
48 0 : assert ( NULL != cr );
49 :
50 0 : const double x = geometry_rectangle_get_center_x ( bounds );
51 0 : double top = geometry_rectangle_get_top ( bounds );
52 0 : double bottom = geometry_rectangle_get_bottom ( bounds );
53 0 : const double gap = pencil_size_get_preferred_object_distance( pencil_size );
54 0 : const double half_gap = 0.5 * gap;
55 :
56 : /* DRAW THE NON EXECUTION SPEC LIFELINES (DASHED LINE) */
57 : {
58 : double dashes[2];
59 0 : dashes[0] = 2.0 * pencil_size_get_line_dash_length( pencil_size );
60 0 : dashes[1] = 1.0 * pencil_size_get_line_dash_length( pencil_size );
61 0 : cairo_set_dash ( cr, dashes, 2, 0.0 );
62 : }
63 :
64 : /* do not fill the top gap with an execution specification bar */
65 0 : if (( to_y == ( -INFINITY ) )&&( depth != 0 ))
66 : {
67 0 : const double start_exec_bar = ( (*this_).last_location > ( top + gap ) ) ? ( top + gap ) : u8_f64_max2( (*this_).last_location, top );
68 :
69 0 : cairo_move_to ( cr, x, start_exec_bar );
70 0 : cairo_line_to ( cr, x, top );
71 0 : cairo_stroke (cr);
72 :
73 : /* overwrite top value by start_exec_bar */
74 0 : top = start_exec_bar;
75 : }
76 :
77 : /* do not fill the bottom gap with an execution specification bar */
78 0 : if (( (*this_).last_location == ( INFINITY ) )&&( depth != 0 ))
79 : {
80 0 : const double end_exec_bar = ( to_y < ( bottom - gap ) ) ? ( bottom - gap ) : u8_f64_min2( to_y, bottom );
81 :
82 0 : cairo_move_to ( cr, x, bottom );
83 0 : cairo_line_to ( cr, x, end_exec_bar );
84 0 : cairo_stroke (cr);
85 :
86 : /* overwrite bottom value by end_exec_bar */
87 0 : bottom = end_exec_bar;
88 : }
89 :
90 : /* draw a normal, dashed lifeline */
91 0 : if ( depth == 0 )
92 : {
93 0 : cairo_move_to ( cr, x, u8_f64_min2( (*this_).last_location, bottom ) );
94 0 : cairo_line_to ( cr, x, u8_f64_max2( to_y, top ) );
95 0 : cairo_stroke (cr);
96 : }
97 :
98 : /* restore cr drawing context */
99 : {
100 0 : cairo_set_dash ( cr, NULL, 0, 0.0 );
101 : }
102 :
103 : /* DRAW THE EXECUTION SPECIFICATION */
104 :
105 : /* draw the stacked activity bars */
106 0 : for ( int depth_run = 0; depth_run < depth; depth_run ++ )
107 : {
108 0 : cairo_move_to ( cr, x - half_gap + depth_run * half_gap, u8_f64_min2( (*this_).last_location, bottom ) );
109 0 : cairo_line_to ( cr, x - half_gap + depth_run * half_gap, u8_f64_max2( to_y, top ) );
110 0 : cairo_stroke (cr);
111 : }
112 0 : if ( depth > 0 )
113 : {
114 0 : cairo_move_to ( cr, x + half_gap * depth, u8_f64_min2( (*this_).last_location, bottom ) );
115 0 : cairo_line_to ( cr, x + half_gap * depth, u8_f64_max2( to_y, top ) );
116 0 : cairo_stroke (cr);
117 : }
118 :
119 : /* draw the top line of activity bars */
120 0 : const double half_line = 0.5 * pencil_size_get_standard_line_width( pencil_size );
121 0 : if (( to_y == ( -INFINITY ) )&&( depth != 0 ))
122 : {
123 0 : cairo_move_to ( cr, x - half_gap - half_line, top );
124 0 : cairo_line_to ( cr, x + depth * half_gap + half_line, top );
125 0 : cairo_stroke (cr);
126 : }
127 :
128 : /* draw the bottom line of activity bars */
129 0 : const int32_t keep_depth = u8_i32_min2( depth, (*this_).last_depth );
130 0 : const int32_t total_depth = u8_i32_max2( depth, (*this_).last_depth );
131 0 : if ( total_depth > keep_depth )
132 : {
133 0 : cairo_move_to ( cr, x - half_gap + keep_depth * half_gap - half_line, u8_f64_min2( (*this_).last_location, bottom ) );
134 0 : cairo_line_to ( cr, x + total_depth * half_gap + half_line, u8_f64_min2( (*this_).last_location, bottom ) );
135 0 : cairo_stroke (cr);
136 : }
137 :
138 0 : (*this_).last_depth = depth;
139 0 : (*this_).last_location = u8_f64_max2( to_y, top );
140 :
141 0 : U8_TRACE_END();
142 0 : }
143 :
144 0 : void draw_feature_symbol_draw_timeline( draw_feature_symbol_t *this_,
145 : const geometry_rectangle_t *bounds,
146 : double to_x,
147 : bool active,
148 : const pencil_size_t *pencil_size,
149 : cairo_t *cr )
150 : {
151 0 : U8_TRACE_BEGIN();
152 0 : assert ( NULL != bounds );
153 0 : assert ( NULL != pencil_size );
154 0 : assert ( NULL != cr );
155 :
156 0 : const double left = geometry_rectangle_get_left ( bounds );
157 0 : const double right = geometry_rectangle_get_right ( bounds );
158 0 : const double y = geometry_rectangle_get_center_y ( bounds );
159 :
160 0 : if ( ! active )
161 : {
162 : double dashes[2];
163 0 : dashes[0] = 2.0 * pencil_size_get_line_dash_length( pencil_size );
164 0 : dashes[1] = 1.0 * pencil_size_get_line_dash_length( pencil_size );
165 0 : cairo_set_dash ( cr, dashes, 2, 0.0 );
166 : }
167 : else
168 : {
169 0 : cairo_set_line_width( cr, pencil_size_get_bold_line_width( pencil_size ) );
170 : }
171 :
172 0 : cairo_move_to ( cr, u8_f64_min2( (*this_).last_location, right ), y );
173 0 : cairo_line_to ( cr, u8_f64_max2( to_x, left ), y );
174 0 : cairo_stroke (cr);
175 :
176 0 : cairo_set_dash ( cr, NULL, 0, 0.0 );
177 0 : cairo_set_line_width( cr, pencil_size_get_standard_line_width( pencil_size ) );
178 :
179 0 : (*this_).last_location = u8_f64_max2( to_x, left );
180 :
181 0 : U8_TRACE_END();
182 0 : }
183 :
184 0 : void draw_feature_symbol_draw_life_rectangle( const draw_feature_symbol_t *this_,
185 : const geometry_rectangle_t *bounds,
186 : bool highlighted,
187 : const pencil_size_t *pencil_size,
188 : cairo_t *cr )
189 : {
190 0 : U8_TRACE_BEGIN();
191 0 : assert ( NULL != bounds );
192 0 : assert ( NULL != pencil_size );
193 0 : assert ( NULL != cr );
194 :
195 0 : const double top = geometry_rectangle_get_top ( bounds );
196 0 : const double left = geometry_rectangle_get_left ( bounds );
197 0 : const double right = geometry_rectangle_get_right ( bounds );
198 0 : const double bottom = geometry_rectangle_get_bottom ( bounds );
199 :
200 0 : if ( highlighted )
201 : {
202 : double dashes[2];
203 0 : dashes[0] = 2.0 * pencil_size_get_line_dash_length( pencil_size );
204 0 : dashes[1] = 1.0 * pencil_size_get_line_dash_length( pencil_size );
205 0 : cairo_set_dash ( cr, dashes, 2, 0.0 );
206 :
207 0 : cairo_move_to ( cr, left, top );
208 0 : cairo_line_to ( cr, left, bottom );
209 0 : cairo_line_to ( cr, right, bottom );
210 0 : cairo_line_to ( cr, right, top );
211 0 : cairo_line_to ( cr, left, top );
212 0 : cairo_stroke (cr);
213 :
214 0 : cairo_set_dash ( cr, NULL, 0, 0.0 );
215 : }
216 :
217 0 : U8_TRACE_END();
218 0 : }
219 :
220 :
221 : /*
222 : Copyright 2026-2026 Andreas Warnke
223 : http://www.apache.org/licenses/LICENSE-2.0
224 :
225 : Licensed under the Apache License, Version 2.0 (the "License");
226 : you may not use this file except in compliance with the License.
227 : You may obtain a copy of the License at
228 :
229 :
230 : Unless required by applicable law or agreed to in writing, software
231 : distributed under the License is distributed on an "AS IS" BASIS,
232 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
233 : See the License for the specific language governing permissions and
234 : limitations under the License.
235 : */
|