Line data Source code
1 : /* File: pencil_floating_label_layouter.c; Copyright and License: see below */
2 :
3 : #include "pencil_floating_label_layouter.h"
4 : #include "layout/layout_quality.h"
5 : #include "u8/u8_trace.h"
6 : #include "utf8stringbuf/utf8string.h"
7 :
8 0 : void pencil_floating_label_layouter_init_void( pencil_floating_label_layouter_t *this_ )
9 : {
10 0 : U8_TRACE_BEGIN();
11 :
12 0 : (*this_).layout_data = NULL;
13 0 : (*this_).profile = NULL;
14 0 : (*this_).pencil_size = NULL;
15 0 : (*this_).font_layout = NULL;
16 :
17 0 : U8_TRACE_END();
18 0 : }
19 :
20 0 : void pencil_floating_label_layouter_reinit_void( pencil_floating_label_layouter_t *this_ )
21 : {
22 0 : U8_TRACE_BEGIN();
23 :
24 0 : (*this_).layout_data = NULL;
25 0 : (*this_).profile = NULL;
26 0 : (*this_).pencil_size = NULL;
27 0 : (*this_).font_layout = NULL;
28 :
29 0 : U8_TRACE_END();
30 0 : }
31 :
32 0 : void pencil_floating_label_layouter_reinit( pencil_floating_label_layouter_t *this_,
33 : layout_visible_set_t *layout_data,
34 : const data_profile_part_t *profile,
35 : const pencil_size_t *pencil_size,
36 : PangoLayout *font_layout )
37 : {
38 0 : U8_TRACE_BEGIN();
39 0 : assert( layout_data != NULL );
40 0 : assert( profile != NULL );
41 0 : assert( pencil_size != NULL );
42 0 : assert( font_layout != NULL );
43 :
44 0 : (*this_).layout_data = layout_data;
45 0 : (*this_).profile = profile;
46 0 : (*this_).pencil_size = pencil_size;
47 0 : (*this_).font_layout = font_layout;
48 :
49 0 : U8_TRACE_END();
50 0 : }
51 :
52 0 : void pencil_floating_label_layouter_destroy( pencil_floating_label_layouter_t *this_ )
53 : {
54 0 : U8_TRACE_BEGIN();
55 :
56 0 : U8_TRACE_END();
57 0 : }
58 :
59 0 : void pencil_floating_label_layouter_propose_solution_feat( const pencil_floating_label_layouter_t *this_,
60 : const geometry_anchor_t *anchor,
61 : const geometry_dimensions_t *preferred_dim,
62 : draw_feature_label_t *draw_estimator,
63 : const data_feature_t *feature,
64 : geometry_rectangle_t *out_solution )
65 : {
66 0 : U8_TRACE_BEGIN();
67 :
68 0 : pencil_floating_label_layouter_private_propose_solution( this_,
69 : anchor,
70 : preferred_dim,
71 : draw_estimator,
72 : feature,
73 : NULL,
74 : NULL,
75 : out_solution
76 : );
77 :
78 0 : U8_TRACE_END();
79 0 : }
80 :
81 0 : void pencil_floating_label_layouter_propose_solution_rel( const pencil_floating_label_layouter_t *this_,
82 : const geometry_anchor_t *anchor,
83 : const geometry_dimensions_t *preferred_dim,
84 : draw_relationship_label_t *draw_estimator,
85 : const data_relationship_t *relation,
86 : geometry_rectangle_t *out_solution )
87 : {
88 0 : U8_TRACE_BEGIN();
89 :
90 0 : pencil_floating_label_layouter_private_propose_solution( this_,
91 : anchor,
92 : preferred_dim,
93 : NULL,
94 : NULL,
95 : draw_estimator,
96 : relation,
97 : out_solution
98 : );
99 :
100 0 : U8_TRACE_END();
101 0 : }
102 :
103 0 : void pencil_floating_label_layouter_select_solution( pencil_floating_label_layouter_t *this_,
104 : geometry_point_t target_point,
105 : uint32_t solutions_count,
106 : const geometry_rectangle_t solutions[],
107 : uint32_t *out_index_of_best )
108 : {
109 0 : U8_TRACE_BEGIN();
110 0 : assert( NULL != (*this_).layout_data );
111 0 : assert( NULL != solutions );
112 0 : assert( solutions_count >= 1 );
113 0 : assert( NULL != out_index_of_best );
114 :
115 : /* get draw area */
116 : const layout_diagram_t *const diagram_layout
117 0 : = layout_visible_set_get_diagram_ptr( (*this_).layout_data );
118 :
119 : /* define potential solution and rating */
120 0 : uint32_t index_of_best = 0;
121 0 : double debts_of_best = DBL_MAX;
122 :
123 : /* evaluate the solutions by their overlaps with classifiers */
124 0 : for ( uint32_t solution_index = 0; solution_index < solutions_count; solution_index ++ )
125 : {
126 : /* evalute the debts of this solution */
127 0 : double debts_of_current = 0.0;
128 0 : const geometry_rectangle_t * const current_solution = &(solutions[solution_index]);
129 :
130 : /* avoid alternating solutions in case their debts are identical */
131 0 : debts_of_current += 0.1 * solution_index;
132 :
133 0 : const layout_quality_t quality = layout_quality_new( (*this_).pencil_size );
134 0 : debts_of_current += layout_quality_debts_label_diag( &quality, current_solution, &target_point, diagram_layout );
135 :
136 : /* iterate over all classifiers */
137 : const uint32_t count_classifiers
138 0 : = layout_visible_set_get_visible_classifier_count ( (*this_).layout_data );
139 0 : for ( uint32_t classifier_index = 0; classifier_index < count_classifiers; classifier_index ++ )
140 : {
141 : const layout_visible_classifier_t *const probe_classifier
142 0 : = layout_visible_set_get_visible_classifier_ptr( (*this_).layout_data, classifier_index );
143 :
144 0 : debts_of_current += layout_quality_debts_label_class( &quality, current_solution, probe_classifier );
145 : }
146 :
147 : /* iterate over all features */
148 : const uint32_t count_features
149 0 : = layout_visible_set_get_feature_count( (*this_).layout_data );
150 0 : for ( uint32_t feature_index = 0; feature_index < count_features; feature_index ++ )
151 : {
152 : const layout_feature_t *const probe_feature
153 0 : = layout_visible_set_get_feature_ptr( (*this_).layout_data, feature_index );
154 :
155 0 : debts_of_current += layout_quality_debts_label_feat( &quality, current_solution, probe_feature );
156 : }
157 :
158 : /* iterate over all relationships */
159 : const uint32_t count_relationships
160 0 : = layout_visible_set_get_relationship_count( (*this_).layout_data );
161 0 : for ( uint32_t relationship_index = 0; relationship_index < count_relationships; relationship_index ++ )
162 : {
163 : /* add debts if intersects */
164 : const layout_relationship_t *const probe_relationship
165 0 : = layout_visible_set_get_relationship_ptr( (*this_).layout_data, relationship_index );
166 :
167 0 : debts_of_current += layout_quality_debts_label_rel( &quality, current_solution, probe_relationship );
168 : }
169 :
170 : /* update best solution */
171 0 : if ( debts_of_current < debts_of_best )
172 : {
173 0 : index_of_best = solution_index;
174 0 : debts_of_best = debts_of_current;
175 : }
176 : }
177 :
178 : /* make all alternatives visible */
179 : #ifndef NDEBUG
180 : #if 0
181 : static unsigned int random;
182 : random ++;
183 : index_of_best = random % 13 % solutions_count;
184 : #endif
185 : #endif
186 :
187 : /* output the best */
188 0 : U8_TRACE_INFO_INT_INT("floating_label_layout index, debt:", index_of_best, (int32_t)debts_of_best)
189 0 : *out_index_of_best = index_of_best;
190 :
191 0 : U8_TRACE_END();
192 0 : }
193 :
194 :
195 : /*
196 : * Copyright 2019-2025 Andreas Warnke
197 : *
198 : * Licensed under the Apache License, Version 2.0 (the "License");
199 : * you may not use this file except in compliance with the License.
200 : * You may obtain a copy of the License at
201 : *
202 : * http://www.apache.org/licenses/LICENSE-2.0
203 : *
204 : * Unless required by applicable law or agreed to in writing, software
205 : * distributed under the License is distributed on an "AS IS" BASIS,
206 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
207 : * See the License for the specific language governing permissions and
208 : * limitations under the License.
209 : */
|