32 #include "config_auto.h"
52 const char* description,
57 White, blamer_bundle);
59 BLOB_CHOICE_IT bc_it(choices);
60 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
61 bc_it.data()->set_matrix_cell(start, end);
69 template<
class BLOB_CHOICE>
71 const BLOB_CHOICE *p1 = *static_cast<const BLOB_CHOICE *const *>(void1);
72 const BLOB_CHOICE *p2 = *static_cast<const BLOB_CHOICE *const *>(void2);
77 template<
class BLOB_CHOICE>
79 const BLOB_CHOICE *p1 = *static_cast<const BLOB_CHOICE *const *>(void1);
80 const BLOB_CHOICE *p2 = *static_cast<const BLOB_CHOICE *const *>(void2);
101 BLOB_CHOICE_LIST *filtered_choices) {
102 BLOB_CHOICE_IT filtered_choices_it(filtered_choices);
103 BLOB_CHOICE_IT choices_it(choices);
105 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
106 choices_it.forward()) {
107 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
110 if (frag !=
nullptr && frag->
get_pos() == fragment_pos &&
116 b->set_unichar_id(original_unichar);
117 filtered_choices_it.add_to_end(b);
121 filtered_choices->sort(SortByUnicharID<BLOB_CHOICE>);
132 int16_t num_frag_parts,
133 BLOB_CHOICE_LIST *choice_lists,
135 auto *choice_lists_it =
new BLOB_CHOICE_IT[num_frag_parts];
137 for (
int i = 0; i < num_frag_parts; i++) {
138 choice_lists_it[i].set_to_list(&choice_lists[i]);
139 choice_lists_it[i].mark_cycle_pt();
142 BLOB_CHOICE_LIST *merged_choice = ratings->
get(row, column);
143 if (merged_choice ==
nullptr)
144 merged_choice =
new BLOB_CHOICE_LIST;
146 bool end_of_list =
false;
147 BLOB_CHOICE_IT merged_choice_it(merged_choice);
148 while (!end_of_list) {
151 UNICHAR_ID max_unichar_id = choice_lists_it[0].data()->unichar_id();
152 for (
int i = 0; i < num_frag_parts; i++) {
153 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
154 if (max_unichar_id < unichar_id) {
155 max_unichar_id = unichar_id;
161 for (
int i = 0; i < num_frag_parts; i++) {
162 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
163 while (!choice_lists_it[i].cycled_list() &&
164 unichar_id < max_unichar_id) {
165 choice_lists_it[i].forward();
166 unichar_id = choice_lists_it[i].data()->unichar_id();
168 if (choice_lists_it[i].cycled_list()) {
178 UNICHAR_ID first_unichar_id = choice_lists_it[0].data()->unichar_id();
179 bool same_unichar =
true;
180 for (
int i = 1; i < num_frag_parts; i++) {
181 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
182 if (unichar_id != first_unichar_id) {
183 same_unichar =
false;
190 UNICHAR_ID merged_unichar_id = first_unichar_id;
192 choice_lists_it[0].data()->fonts();
193 float merged_min_xheight = choice_lists_it[0].data()->min_xheight();
194 float merged_max_xheight = choice_lists_it[0].data()->max_xheight();
195 float positive_yshift = 0, negative_yshift = 0;
196 int merged_script_id = choice_lists_it[0].data()->script_id();
199 float merged_rating = 0, merged_certainty = 0;
200 for (
int i = 0; i < num_frag_parts; i++) {
201 float rating = choice_lists_it[i].data()->rating();
202 float certainty = choice_lists_it[i].data()->certainty();
204 if (i == 0 || certainty < merged_certainty)
205 merged_certainty = certainty;
206 merged_rating += rating;
208 choice_lists_it[i].forward();
209 if (choice_lists_it[i].cycled_list())
212 choice_lists_it[i].data()->max_xheight(),
213 &merged_min_xheight, &merged_max_xheight);
214 float yshift = choice_lists_it[i].data()->yshift();
215 if (yshift > positive_yshift) positive_yshift = yshift;
216 if (yshift < negative_yshift) negative_yshift = yshift;
220 choice_lists_it[i].data()->fonts();
221 for (
int f = 0; f < frag_fonts.
size(); ++f) {
223 for (merged_f = 0; merged_f < merged_fonts.
size() &&
224 merged_fonts[merged_f].fontinfo_id != frag_fonts[f].fontinfo_id;
226 if (merged_f == merged_fonts.
size()) {
228 }
else if (merged_fonts[merged_f].score > frag_fonts[f].score) {
229 merged_fonts[merged_f].score = frag_fonts[f].score;
234 float merged_yshift = positive_yshift != 0
235 ? (negative_yshift != 0 ? 0 : positive_yshift)
245 choice->set_fonts(merged_fonts);
246 merged_choice_it.add_to_end(choice);
254 if (merged_choice->empty())
255 delete merged_choice;
257 ratings->
put(row, column, merged_choice);
259 delete [] choice_lists_it;
275 int16_t start, int16_t num_frag_parts,
276 int16_t num_blobs,
MATRIX *ratings,
277 BLOB_CHOICE_LIST *choice_lists) {
278 if (current_frag == num_frag_parts) {
280 choice_lists, ratings);
284 for (int16_t x = current_row; x < num_blobs; x++) {
285 BLOB_CHOICE_LIST *choices = ratings->
get(current_row, x);
286 if (choices ==
nullptr)
290 &choice_lists[current_frag]);
291 if (!choice_lists[current_frag].empty()) {
293 num_blobs, ratings, choice_lists);
294 choice_lists[current_frag].clear();
308 for (int16_t start = 0; start < num_blobs; start++) {
312 ratings, choice_lists);
317 for (int16_t x = 0; x < num_blobs; x++) {
318 for (int16_t y = x; y < num_blobs; y++) {
319 BLOB_CHOICE_LIST *choices = ratings->
get(x, y);
320 if (choices !=
nullptr) {
321 BLOB_CHOICE_IT choices_it(choices);
322 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
323 choices_it.forward()) {
324 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
328 delete choices_it.extract();