33 #include "config_auto.h"
53 const char* description,
58 White, blamer_bundle);
60 BLOB_CHOICE_IT bc_it(choices);
61 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
62 bc_it.data()->set_matrix_cell(start, end);
70 template<
class BLOB_CHOICE>
78 template<
class BLOB_CHOICE>
102 BLOB_CHOICE_LIST *filtered_choices) {
103 BLOB_CHOICE_IT filtered_choices_it(filtered_choices);
104 BLOB_CHOICE_IT choices_it(choices);
106 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
107 choices_it.forward()) {
108 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
111 if (frag !=
nullptr && frag->
get_pos() == fragment_pos &&
117 b->set_unichar_id(original_unichar);
118 filtered_choices_it.add_to_end(b);
122 filtered_choices->sort(SortByUnicharID<BLOB_CHOICE>);
133 int16_t num_frag_parts,
134 BLOB_CHOICE_LIST *choice_lists,
136 auto *choice_lists_it =
new BLOB_CHOICE_IT[num_frag_parts];
138 for (
int i = 0; i < num_frag_parts; i++) {
139 choice_lists_it[i].set_to_list(&choice_lists[i]);
140 choice_lists_it[i].mark_cycle_pt();
143 BLOB_CHOICE_LIST *merged_choice = ratings->
get(row, column);
144 if (merged_choice ==
nullptr)
145 merged_choice =
new BLOB_CHOICE_LIST;
147 bool end_of_list =
false;
148 BLOB_CHOICE_IT merged_choice_it(merged_choice);
149 while (!end_of_list) {
152 UNICHAR_ID max_unichar_id = choice_lists_it[0].data()->unichar_id();
153 for (
int i = 0; i < num_frag_parts; i++) {
154 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
155 if (max_unichar_id < unichar_id) {
156 max_unichar_id = unichar_id;
162 for (
int i = 0; i < num_frag_parts; i++) {
163 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
164 while (!choice_lists_it[i].cycled_list() &&
165 unichar_id < max_unichar_id) {
166 choice_lists_it[i].forward();
167 unichar_id = choice_lists_it[i].data()->unichar_id();
169 if (choice_lists_it[i].cycled_list()) {
179 UNICHAR_ID first_unichar_id = choice_lists_it[0].data()->unichar_id();
180 bool same_unichar =
true;
181 for (
int i = 1; i < num_frag_parts; i++) {
182 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
183 if (unichar_id != first_unichar_id) {
184 same_unichar =
false;
191 UNICHAR_ID merged_unichar_id = first_unichar_id;
193 choice_lists_it[0].data()->fonts();
194 float merged_min_xheight = choice_lists_it[0].data()->min_xheight();
195 float merged_max_xheight = choice_lists_it[0].data()->max_xheight();
196 float positive_yshift = 0, negative_yshift = 0;
197 int merged_script_id = choice_lists_it[0].data()->script_id();
200 float merged_rating = 0, merged_certainty = 0;
201 for (
int i = 0; i < num_frag_parts; i++) {
202 float rating = choice_lists_it[i].data()->rating();
203 float certainty = choice_lists_it[i].data()->certainty();
205 if (i == 0 || certainty < merged_certainty)
206 merged_certainty = certainty;
207 merged_rating += rating;
209 choice_lists_it[i].forward();
210 if (choice_lists_it[i].cycled_list())
213 choice_lists_it[i].data()->max_xheight(),
214 &merged_min_xheight, &merged_max_xheight);
215 float yshift = choice_lists_it[i].data()->yshift();
216 if (yshift > positive_yshift) positive_yshift = yshift;
217 if (yshift < negative_yshift) negative_yshift = yshift;
221 choice_lists_it[i].data()->fonts();
222 for (
int f = 0; f < frag_fonts.
size(); ++f) {
224 for (merged_f = 0; merged_f < merged_fonts.
size() &&
225 merged_fonts[merged_f].fontinfo_id != frag_fonts[f].fontinfo_id;
227 if (merged_f == merged_fonts.
size()) {
229 }
else if (merged_fonts[merged_f].score > frag_fonts[f].score) {
230 merged_fonts[merged_f].score = frag_fonts[f].score;
235 float merged_yshift = positive_yshift != 0
236 ? (negative_yshift != 0 ? 0 : positive_yshift)
246 choice->set_fonts(merged_fonts);
247 merged_choice_it.add_to_end(choice);
255 if (merged_choice->empty())
256 delete merged_choice;
258 ratings->
put(row, column, merged_choice);
260 delete [] choice_lists_it;
276 int16_t start, int16_t num_frag_parts,
277 int16_t num_blobs,
MATRIX *ratings,
278 BLOB_CHOICE_LIST *choice_lists) {
279 if (current_frag == num_frag_parts) {
281 choice_lists, ratings);
285 for (int16_t x = current_row; x < num_blobs; x++) {
286 BLOB_CHOICE_LIST *choices = ratings->
get(current_row, x);
287 if (choices ==
nullptr)
291 &choice_lists[current_frag]);
292 if (!choice_lists[current_frag].empty()) {
294 num_blobs, ratings, choice_lists);
295 choice_lists[current_frag].clear();
309 for (int16_t start = 0; start < num_blobs; start++) {
313 ratings, choice_lists);
318 for (int16_t x = 0; x < num_blobs; x++) {
319 for (int16_t y = x; y < num_blobs; y++) {
320 BLOB_CHOICE_LIST *choices = ratings->
get(x, y);
321 if (choices !=
nullptr) {
322 BLOB_CHOICE_IT choices_it(choices);
323 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
324 choices_it.forward()) {
325 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
329 delete choices_it.extract();