26 #include "config_auto.h" 29 #define FIRST_COLOUR ScrollView::RED //< first rainbow colour 30 #define LAST_COLOUR ScrollView::AQUAMARINE //< last rainbow colour 31 #define CHILD_COLOUR ScrollView::BROWN //< colour of children 34 "Attempted to scale an edgestep format word";
47 WERD::
WERD(C_BLOB_LIST *blob_list, uint8_t blank_count, const
char *text)
48 : blanks(blank_count),
52 C_BLOB_IT start_it = &cblobs;
53 C_BLOB_IT rej_cblob_it = &rej_cblobs;
54 C_OUTLINE_IT c_outline_it;
55 int16_t inverted_vote = 0;
56 int16_t non_inverted_vote = 0;
59 start_it.add_list_after(blob_list);
74 start_it.set_to_list(&cblobs);
77 for (start_it.mark_cycle_pt(); !start_it.cycled_list(); start_it.forward()) {
78 bool reject_blob =
false;
81 c_outline_it.set_to_list(start_it.data()->out_list());
83 for (c_outline_it.mark_cycle_pt();
84 !c_outline_it.cycled_list() && !reject_blob;
85 c_outline_it.forward()) {
86 reject_blob = c_outline_it.data()->flag(
COUT_INVERSE) != blob_inverted;
89 rej_cblob_it.add_after_then_move(start_it.extract());
100 start_it.set_to_list(&cblobs);
101 if (start_it.empty())
103 for (start_it.mark_cycle_pt(); !start_it.cycled_list(); start_it.forward()) {
104 c_outline_it.set_to_list(start_it.data()->out_list());
106 rej_cblob_it.add_after_then_move(start_it.extract());
121 script_id_(clone->script_id_),
122 correct(clone->correct) {
123 C_BLOB_IT start_it = blob_list;
124 C_BLOB_IT end_it = blob_list;
126 while (!end_it.at_last ())
128 (
reinterpret_cast<C_BLOB_LIST*
>(&cblobs))->assign_to_sublist(&start_it, &end_it);
130 blanks = clone->blanks;
137 C_BLOB_LIST temp_blobs;
138 C_BLOB_IT temp_it(&temp_blobs);
139 temp_it.add_after_then_move(blob);
140 WERD* blob_word =
new WERD(&temp_blobs,
this);
165 int bottom = box.
bottom();
168 C_BLOB_IT it(const_cast<C_BLOB_LIST*>(&rej_cblobs));
169 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
170 TBOX dot_box = it.data()->bounding_box();
171 if ((upper_dots || dot_box.
bottom() <= top) &&
172 (lower_dots || dot_box.
top() >= bottom)) {
183 C_BLOB_IT it(const_cast<C_BLOB_LIST*>(&cblobs));
184 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
185 box += it.data()->bounding_box();
198 C_BLOB_IT cblob_it(&cblobs);
200 for (cblob_it.mark_cycle_pt(); !cblob_it.cycled_list(); cblob_it.forward())
201 cblob_it.data()->move(
vec);
211 C_BLOB_IT blob_it(&cblobs);
212 C_BLOB_IT src_it(&other->cblobs);
213 C_BLOB_IT rej_cblob_it(&rej_cblobs);
214 C_BLOB_IT src_rej_it(&other->rej_cblobs);
216 while (!src_it.empty()) {
217 blob_it.add_to_end(src_it.extract());
220 while (!src_rej_it.empty()) {
221 rej_cblob_it.add_to_end(src_rej_it.extract());
222 src_rej_it.forward();
235 C_BLOB_IT c_blob_it(&cblobs);
240 c_blob_it.add_list_before(&c_blobs);
242 c_blob_it.move_to_last();
243 c_blob_it.add_list_after(&c_blobs);
245 if (!other->rej_cblobs.empty()) {
246 C_BLOB_IT rej_c_blob_it(&rej_cblobs);
247 C_BLOB_LIST new_rej_c_blobs;
251 rej_c_blob_it.add_list_before(&new_rej_c_blobs);
253 rej_c_blob_it.move_to_last();
254 rej_c_blob_it.add_list_after(&new_rej_c_blobs);
266 tprintf(
"Blanks= %d\n", blanks);
273 tprintf(
" W_NORMALIZED = %s\n",
275 tprintf(
" W_SCRIPT_HAS_XHEIGHT = %s\n",
277 tprintf(
" W_SCRIPT_IS_LATIN = %s\n",
284 tprintf(
"Rejected cblob count = %d\n", rej_cblobs.length());
285 tprintf(
"Script = %d\n", script_id_);
295 #ifndef GRAPHICS_DISABLED 297 C_BLOB_IT it = &cblobs;
298 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
299 it.data()->plot(window, colour, colour);
320 C_BLOB_IT it = &cblobs;
321 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
337 C_BLOB_IT it = &rej_cblobs;
338 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
342 #endif // GRAPHICS_DISABLED 354 new_word->blanks = blanks;
355 new_word->flags =
flags;
356 new_word->dummy = dummy;
357 new_word->correct = correct;
370 blanks = source.blanks;
371 flags = source.flags;
372 script_id_ = source.script_id_;
373 dummy = source.dummy;
374 correct = source.correct;
379 if (!rej_cblobs.empty())
394 const WERD *word1 = *
reinterpret_cast<const WERD* const*
>(word1p);
395 const WERD *word2 = *
reinterpret_cast<const WERD* const*
>(word2p);
412 C_BLOB_LIST* orphan_blobs) {
413 C_BLOB_LIST current_blob_list;
414 C_BLOB_IT werd_blobs_it(¤t_blob_list);
419 C_BLOB_LIST new_werd_blobs;
420 C_BLOB_IT new_blobs_it(&new_werd_blobs);
424 C_BLOB_LIST not_found_blobs;
425 C_BLOB_IT not_found_it(¬_found_blobs);
426 not_found_it.move_to_last();
428 werd_blobs_it.move_to_first();
429 for (werd_blobs_it.mark_cycle_pt(); !werd_blobs_it.cycled_list();
430 werd_blobs_it.forward()) {
431 C_BLOB* werd_blob = werd_blobs_it.extract();
437 C_BLOB_IT all_blobs_it(all_blobs);
438 for (all_blobs_it.mark_cycle_pt(); !all_blobs_it.cycled_list();
439 all_blobs_it.forward()) {
440 C_BLOB* a_blob = all_blobs_it.data();
445 tprintf(
"Bounding box couldn't be ascertained\n");
447 if (werd_blob_box.
contains(a_blob_box) ||
452 all_blobs_it.extract();
453 new_blobs_it.add_after_then_move(a_blob);
458 not_found_it.add_after_then_move(werd_blob);
466 not_found_it.move_to_first();
467 for (not_found_it.mark_cycle_pt(); !not_found_it.cycled_list();
468 not_found_it.forward()) {
469 C_BLOB* not_found = not_found_it.data();
471 C_BLOB_IT existing_blobs_it(new_blobs_it);
472 for (existing_blobs_it.mark_cycle_pt(); !existing_blobs_it.cycled_list();
473 existing_blobs_it.forward()) {
474 C_BLOB* a_blob = existing_blobs_it.data();
480 delete not_found_it.extract();
486 C_BLOB_IT orphan_blobs_it(orphan_blobs);
487 orphan_blobs_it.move_to_last();
488 orphan_blobs_it.add_list_after(¬_found_blobs);
492 WERD* new_werd =
nullptr;
493 if (!new_werd_blobs.empty()) {
494 new_werd =
new WERD(&new_werd_blobs,
this);
498 this_list_it.add_list_after(¬_found_blobs);
506 C_BLOB_IT blob_it(&cblobs);
507 C_BLOB_IT rej_it(&rej_cblobs);
508 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
509 C_BLOB* blob = blob_it.data();
510 C_OUTLINE_IT ol_it(blob->
out_list());
511 for (ol_it.mark_cycle_pt(); !ol_it.cycled_list(); ol_it.forward()) {
516 if (ol_size < size_threshold) {
520 rej_it.add_after_then_move(rej_blob);
523 if (blob->
out_list()->empty())
delete blob_it.extract();
530 C_BLOB_IT rej_it(&rej_cblobs);
531 for (rej_it.mark_cycle_pt(); !rej_it.empty(); rej_it.forward()) {
532 C_BLOB* blob = rej_it.extract();
533 C_OUTLINE_IT ol_it(blob->
out_list());
550 bool* make_next_word_fuzzy) {
551 bool outline_added_to_start =
false;
552 if (make_next_word_fuzzy !=
nullptr) *make_next_word_fuzzy =
false;
553 C_BLOB_IT rej_it(&rej_cblobs);
554 for (
int i = 0; i < outlines.
size(); ++i) {
556 if (outline ==
nullptr)
continue;
558 C_BLOB* target_blob = target_blobs[i];
560 if (target_blob ==
nullptr) {
561 target_blob =
new C_BLOB(outline);
563 C_BLOB_IT blob_it(&cblobs);
564 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list();
566 C_BLOB* blob = blob_it.data();
568 if (blob_box.
left() > noise_box.
left()) {
571 outline_added_to_start =
true;
573 blob_it.add_before_stay_put(target_blob);
577 if (blob_it.cycled_list()) {
578 blob_it.add_to_end(target_blob);
579 if (make_next_word_fuzzy !=
nullptr) *make_next_word_fuzzy =
true;
582 C_OUTLINE_IT ol_it(target_blob->
out_list());
583 while (i + 1 < outlines.
size() && wanted[i + 1] &&
584 target_blobs[i + 1] ==
nullptr) {
586 ol_it.add_to_end(outlines[i]);
590 C_OUTLINE_IT ol_it(target_blob->
out_list());
591 ol_it.add_to_end(outline);
595 rej_it.add_to_end(
new C_BLOB(outline));
598 return outline_added_to_start;
void CleanNoise(float size_threshold)
void plot_rej_blobs(ScrollView *window)
WERD & operator=(const WERD &source)
void move(const ICOORD vec)
const char * string() const
WERD * ConstructFromSingleBlob(bool bol, bool eol, C_BLOB *blob)
int word_comparator(const void *word1p, const void *word2p)
TBOX bounding_box() const
static ScrollView::Color NextColor(ScrollView::Color colour)
void GetNoiseOutlines(GenericVector< C_OUTLINE *> *outlines)
void plot(ScrollView *window, ScrollView::Color colour)
double y_overlap_fraction(const TBOX &box) const
void set_flag(WERD_FLAGS mask, bool value)
#define ELIST2IZE(CLASSNAME)
bool AddSelectedOutlines(const GenericVector< bool > &wanted, const GenericVector< C_BLOB *> &target_blobs, const GenericVector< C_OUTLINE *> &outlines, bool *make_next_word_fuzzy)
bool flag(WERD_FLAGS mask) const
bool major_overlap(const TBOX &box) const
const TBOX & bounding_box() const
DLLSYM void tprintf(const char *format,...)
C_BLOB_LIST * cblob_list()
void operator=(const ELIST2_LINK &)
TBOX bounding_box() const
TBOX restricted_bounding_box(bool upper_dots, bool lower_dots) const
bool contains(const FCOORD pt) const
C_OUTLINE_LIST * out_list()
const ERRCODE CANT_SCALE_EDGESTEPS
void copy_on(WERD *other)
void join_on(WERD *other)
WERD * ConstructWerdWithNewBlobs(C_BLOB_LIST *all_blobs, C_BLOB_LIST *orphan_blobs)
static C_BLOB * deep_copy(const C_BLOB *src)
TBOX true_bounding_box() const