00001
00020 #include "mfcpch.h"
00021 #include "blckerr.h"
00022 #include "linlsq.h"
00023 #include "werd.h"
00024
00025 #define FIRST_COLOUR RED //first rainbow colour
00026
00027 #define LAST_COLOUR AQUAMARINE
00028 #define CHILD_COLOUR BROWN //colour of children
00029
00030 const ERRCODE CANT_SCALE_EDGESTEPS =
00031 "Attempted to scale an edgestep format word";
00032
00033 #define EXTERN
00034
00037 EXTERN BOOL_VAR (bln_numericmode, 0, "Optimize for numbers");
00038 EXTERN INT_VAR (bln_x_height, 128, "Baseline Normalisation X-height");
00039 EXTERN INT_VAR (bln_baseline_offset, 64, "Baseline Norm. offset of baseline");
00040 EXTERN double_VAR (bln_blshift_maxshift, -1.0,
00041 "Fraction of xh before shifting");
00042 EXTERN double_VAR (bln_blshift_xfraction, 0.75,
00043 "Size fraction of xh before shifting");
00046 ELISTIZE_S (WERD)
00047
00048
00074 WERD::WERD (
00075 C_BLOB_LIST * blob_list,
00076 UINT8 blank_count,
00077 const char *text
00078 ):
00079 flags (0),
00080 correct(text) {
00081 C_BLOB_IT start_it = blob_list;
00082 C_BLOB_IT end_it = blob_list;
00083
00084 C_BLOB_IT rej_cblob_it = &rej_cblobs;
00085 C_OUTLINE_IT c_outline_it;
00086 BOOL8 blob_inverted;
00087 BOOL8 reject_blob;
00088 INT16 inverted_vote = 0;
00089 INT16 non_inverted_vote = 0;
00090
00091 while (!end_it.at_last ())
00092 end_it.forward ();
00093
00094 cblobs.assign_to_sublist (&start_it, &end_it);
00095 blanks = blank_count;
00096
00097
00098 start_it.set_to_list (&cblobs);
00099 if (start_it.empty ())
00100 return;
00101 for (start_it.mark_cycle_pt ();
00102 !start_it.cycled_list (); start_it.forward ()) {
00103 c_outline_it.set_to_list (start_it.data ()->out_list ());
00104 blob_inverted = c_outline_it.data ()->flag (COUT_INVERSE);
00105 reject_blob = FALSE;
00106 for (c_outline_it.mark_cycle_pt ();
00107 !c_outline_it.cycled_list () && !reject_blob;
00108 c_outline_it.forward ()) {
00109 reject_blob =
00110 c_outline_it.data ()->flag (COUT_INVERSE) != blob_inverted;
00111 }
00112 if (reject_blob)
00113 rej_cblob_it.add_after_then_move (start_it.extract ());
00114 else {
00115 if (blob_inverted)
00116 inverted_vote++;
00117 else
00118 non_inverted_vote++;
00119 }
00120 }
00121
00122 flags.set_bit (W_INVERSE, (inverted_vote > non_inverted_vote));
00123
00124 start_it.set_to_list (&cblobs);
00125 if (start_it.empty ())
00126 return;
00127 for (start_it.mark_cycle_pt ();
00128 !start_it.cycled_list (); start_it.forward ()) {
00129 c_outline_it.set_to_list (start_it.data ()->out_list ());
00130 if (c_outline_it.data ()->flag (COUT_INVERSE) != flags.bit (W_INVERSE))
00131 rej_cblob_it.add_after_then_move (start_it.extract ());
00132 }
00133 }
00134
00135
00141 WERD::WERD (
00142 PBLOB_LIST * blob_list,
00143 UINT8 blank_count,
00144 const char *text
00145 ):
00146 flags (0),
00147 correct(text) {
00148 PBLOB_IT start_it = blob_list;
00149 PBLOB_IT end_it = blob_list;
00150
00151 while (!end_it.at_last ())
00152 end_it.forward ();
00153 ((PBLOB_LIST *) (&cblobs))->assign_to_sublist (&start_it, &end_it);
00154
00155
00156 flags.set_bit (W_POLYGON, TRUE);
00157 blanks = blank_count;
00158
00159 }
00160
00161
00167 WERD::WERD (
00168 PBLOB_LIST * blob_list,
00169 WERD * clone
00170 ):flags (clone->flags), correct (clone->correct) {
00171 PBLOB_IT start_it = blob_list;
00172 PBLOB_IT end_it = blob_list;
00173
00174 while (!end_it.at_last ())
00175 end_it.forward ();
00176 ((PBLOB_LIST *) (&cblobs))->assign_to_sublist (&start_it, &end_it);
00177
00178 blanks = clone->blanks;
00179
00180 }
00181
00182
00188 WERD::WERD (
00189 C_BLOB_LIST * blob_list,
00190 WERD * clone
00191 ):flags (clone->flags), correct (clone->correct) {
00192 C_BLOB_IT start_it = blob_list;
00193 C_BLOB_IT end_it = blob_list;
00194
00195 while (!end_it.at_last ())
00196 end_it.forward ();
00197 ((C_BLOB_LIST *) (&cblobs))->assign_to_sublist (&start_it, &end_it);
00198
00199 blanks = clone->blanks;
00200
00201 }
00202
00203
00209 WERD *WERD::poly_copy(
00210 float xheight
00211 ) {
00212 PBLOB *blob;
00213 WERD *result = new WERD;
00214 C_BLOB_IT src_it = &cblobs;
00215
00216 PBLOB_IT dest_it = (PBLOB_LIST *) (&result->cblobs);
00217
00218
00219 if (flags.bit (W_POLYGON)) {
00220 *result = *this;
00221 }
00222 else {
00223 result->flags = flags;
00224 result->correct = correct;
00225 result->dummy = dummy;
00226 if (!src_it.empty ()) {
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 do {
00242 blob = new PBLOB (src_it.data (), xheight);
00243
00244
00245 dest_it.add_after_then_move (blob);
00246 src_it.forward ();
00247 }
00248 while (!src_it.at_first ());
00249
00250 }
00251 if (!rej_cblobs.empty ()) {
00252
00253 src_it.set_to_list (&rej_cblobs);
00254 dest_it = (PBLOB_LIST *) (&result->rej_cblobs);
00255 do {
00256
00257 blob = new PBLOB (src_it.data (), xheight);
00258
00259 dest_it.add_after_then_move (blob);
00260 src_it.forward ();
00261 }
00262 while (!src_it.at_first ());
00263 }
00264
00265 result->flags.set_bit (W_POLYGON, TRUE);
00266 result->blanks = blanks;
00267 }
00268 return result;
00269 }
00270
00271
00283 BOX WERD::bounding_box() {
00284 BOX box;
00285
00286 C_BLOB_IT rej_cblob_it = &rej_cblobs;
00287
00288 for (rej_cblob_it.mark_cycle_pt ();
00289 !rej_cblob_it.cycled_list (); rej_cblob_it.forward ()) {
00290 box += rej_cblob_it.data ()->bounding_box ();
00291 }
00292
00293 if (flags.bit (W_POLYGON)) {
00294
00295 PBLOB_IT it = (PBLOB_LIST *) (&cblobs);
00296
00297 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00298 box += it.data ()->bounding_box ();
00299 }
00300 }
00301 else {
00302 C_BLOB_IT it = &cblobs;
00303
00304 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00305 box += it.data ()->bounding_box ();
00306 }
00307 }
00308 return box;
00309 }
00310
00311
00317 void WERD::move(
00318 const ICOORD vec
00319 ) {
00320 PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00321
00322
00323 C_BLOB_IT cblob_it(&cblobs);
00324
00325 if (flags.bit (W_POLYGON))
00326 for (blob_it.mark_cycle_pt ();
00327 !blob_it.cycled_list (); blob_it.forward ())
00328 blob_it.data ()->move (vec);
00329
00330
00331
00332
00333
00334 else
00335 for (cblob_it.mark_cycle_pt ();
00336 !cblob_it.cycled_list (); cblob_it.forward ())
00337 cblob_it.data ()->move (vec);
00338 }
00339
00340
00344 void WERD::scale(
00345 const float f
00346 ) {
00347 PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00348
00349
00350
00351 if (flags.bit (W_POLYGON))
00352 for (blob_it.mark_cycle_pt ();
00353 !blob_it.cycled_list (); blob_it.forward ())
00354 blob_it.data ()->scale (f);
00355
00356
00357
00358
00359
00360 else
00361 CANT_SCALE_EDGESTEPS.error ("WERD::scale", ABORT, NULL);
00362 }
00363
00364
00368 void WERD::join_on(
00369 WERD *&other
00370 ) {
00371 PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00372
00373 PBLOB_IT src_it ((PBLOB_LIST *) & other->cblobs);
00374 C_BLOB_IT rej_cblob_it(&rej_cblobs);
00375 C_BLOB_IT src_rej_it (&other->rej_cblobs);
00376
00377 while (!src_it.empty ()) {
00378 blob_it.add_to_end (src_it.extract ());
00379 src_it.forward ();
00380 }
00381 while (!src_rej_it.empty ()) {
00382 rej_cblob_it.add_to_end (src_rej_it.extract ());
00383 src_rej_it.forward ();
00384 }
00385 }
00386
00387
00391 void WERD::copy_on(
00392 WERD *&other
00393 ) {
00394 if (flags.bit (W_POLYGON)) {
00395 PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00396
00397 PBLOB_LIST blobs;
00398
00399 blobs.deep_copy ((PBLOB_LIST *) (&other->cblobs));
00400 blob_it.move_to_last ();
00401 blob_it.add_list_after (&blobs);
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 else {
00413 C_BLOB_IT c_blob_it(&cblobs);
00414 C_BLOB_LIST c_blobs;
00415
00416 c_blobs.deep_copy (&other->cblobs);
00417 c_blob_it.move_to_last ();
00418 c_blob_it.add_list_after (&c_blobs);
00419 }
00420 if (!other->rej_cblobs.empty ()) {
00421 C_BLOB_IT rej_c_blob_it(&rej_cblobs);
00422 C_BLOB_LIST new_rej_c_blobs;
00423
00424 new_rej_c_blobs.deep_copy (&other->rej_cblobs);
00425 rej_c_blob_it.move_to_last ();
00426 rej_c_blob_it.add_list_after (&new_rej_c_blobs);
00427 }
00428 }
00429
00430
00441 void WERD::baseline_normalise(
00442 ROW *row,
00443 DENORM *denorm
00444 ) {
00445 baseline_normalise_x (row, row->x_height (), denorm);
00446
00447 }
00448
00449
00463 void WERD::baseline_normalise_x(
00464 ROW *row,
00465 float x_height,
00466 DENORM *denorm
00467 ) {
00468 BOOL8 using_row;
00469 float blob_x_centre;
00470 float blob_offset;
00471 float top_offset;
00472 float blob_x_height;
00473 INT16 segments;
00474 INT16 segment;
00475 DENORM_SEG *segs;
00476 float mean_x;
00477 INT32 x_count;
00478 BOX word_box = bounding_box ();
00479 BOX blob_box;
00480 PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00481
00482 PBLOB *blob;
00483 LLSQ line;
00484 double line_m, line_c;
00485
00486 DENORM antidote (word_box.left () +
00487
00488 (word_box.right () - word_box.left ()) / 2.0,
00489 bln_x_height / x_height, row);
00490
00491 if (!flags.bit (W_POLYGON)) {
00492 WRONG_WORD.error ("WERD::baseline_normalise", ABORT,
00493 "Need to poly approx");
00494 }
00495
00496 if (flags.bit (W_NORMALIZED)) {
00497 WRONG_WORD.error ("WERD::baseline_normalise", ABORT,
00498 "Baseline unnormalised");
00499 }
00500
00501 if (bln_numericmode) {
00502 segs = new DENORM_SEG[blob_it.length ()];
00503 segments = 0;
00504 float factor;
00505 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00506 blob_it.forward ()) {
00507 blob = blob_it.data ();
00508 blob_box = blob->bounding_box ();
00509 blob->move (FCOORD (-antidote.origin (),
00510 -blob_box.bottom ()));
00511 factor = bln_x_height * 4.0f / (3 * blob_box.height ());
00512
00513
00514 if (factor < antidote.scale())
00515 factor = antidote.scale();
00516 else if (factor > antidote.scale() * 1.5f)
00517 factor = antidote.scale() * 1.5f;
00518 blob->scale (factor);
00519 blob->move (FCOORD (0.0, bln_baseline_offset));
00520 segs[segments].xstart = blob->bounding_box().left();
00521 segs[segments].ycoord = blob_box.bottom();
00522 segs[segments++].scale_factor = factor;
00523 }
00524 antidote = DENORM (antidote.origin (), antidote.scale (),
00525 0.0f, 0.0f, segments, segs, true, row);
00526 delete [] segs;
00527
00528
00529 blob_it.set_to_list ((PBLOB_LIST *) & rej_cblobs);
00530 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00531 blob_it.forward ()) {
00532 blob = blob_it.data ();
00533 blob_box = blob->bounding_box ();
00534 blob->move (FCOORD (-antidote.origin (),
00535 -blob_box.bottom ()));
00536 blob->scale (bln_x_height * 4.0f / (3 * blob_box.height ()));
00537 blob->move (FCOORD (0.0, bln_baseline_offset));
00538 }
00539 }
00540 else if (bln_blshift_maxshift < 0) {
00541 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00542 blob_it.forward ()) {
00543 blob = blob_it.data ();
00544 blob_box = blob->bounding_box ();
00545 blob_x_centre = blob_box.left () +
00546 (blob_box.right () - blob_box.left ()) / 2.0;
00547 blob->move (FCOORD (-antidote.origin (),
00548 -(row->base_line (blob_x_centre))));
00549 blob->scale (antidote.scale ());
00550 blob->move (FCOORD (0.0, bln_baseline_offset));
00551 }
00552
00553
00554 blob_it.set_to_list ((PBLOB_LIST *) & rej_cblobs);
00555 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00556 blob_it.forward ()) {
00557 blob = blob_it.data ();
00558 blob_box = blob->bounding_box ();
00559 blob_x_centre = blob_box.left () +
00560 (blob_box.right () - blob_box.left ()) / 2.0;
00561 blob->move (FCOORD (-antidote.origin (),
00562 -(row->base_line (blob_x_centre))));
00563 blob->scale (antidote.scale ());
00564 blob->move (FCOORD (0.0, bln_baseline_offset));
00565 }
00566
00567 }
00568 else {
00569 mean_x = x_height;
00570 x_count = 1;
00571 segs = new DENORM_SEG[blob_it.length ()];
00572 segments = 0;
00573 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00574 blob_it.forward ()) {
00575 blob = blob_it.data ();
00576 blob_box = blob->bounding_box ();
00577 if (blob_box.height () > bln_blshift_xfraction * x_height) {
00578 blob_x_centre = blob_box.left () +
00579 (blob_box.right () - blob_box.left ()) / 2.0;
00580 blob_offset =
00581 blob_box.bottom () - row->base_line (blob_x_centre);
00582 top_offset = blob_offset + blob_box.height () - x_height - 1;
00583 blob_x_height = top_offset + x_height;
00584 if (top_offset < 0)
00585 top_offset = -top_offset;
00586 if (blob_offset < 0)
00587 blob_offset = -blob_offset;
00588 if (blob_offset < bln_blshift_maxshift * x_height) {
00589 segs[segments].ycoord = blob_box.bottom ();
00590 line.add (blob_x_centre, blob_box.bottom ());
00591 if (top_offset < bln_blshift_maxshift * x_height) {
00592 segs[segments].scale_factor = blob_box.height () - 1.0f;
00593 x_count++;
00594 }
00595 else
00596 segs[segments].scale_factor = 0.0f;
00597
00598 }
00599 else {
00600
00601 segs[segments].ycoord = -MAX_INT32;
00602 if (top_offset < bln_blshift_maxshift * x_height) {
00603 segs[segments].scale_factor = blob_x_height;
00604 x_count++;
00605 }
00606 else
00607 segs[segments].scale_factor = 0.0f;
00608
00609 }
00610 }
00611 else {
00612 segs[segments].scale_factor = 0.0f;
00613 segs[segments].ycoord = -MAX_INT32;
00614 }
00615 segs[segments].xstart = blob_box.left ();
00616 segments++;
00617 }
00618 using_row = line.count () <= 1;
00619 if (!using_row) {
00620 line_m = line.m ();
00621 line_c = line.c (line_m);
00622 }
00623 else
00624 line_m = line_c = 0;
00625 segments = 0;
00626 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00627 blob_it.forward ()) {
00628 blob = blob_it.data ();
00629 blob_box = blob->bounding_box ();
00630 blob_x_centre = blob_box.left () +
00631 (blob_box.right () - blob_box.left ()) / 2.0;
00632 if (segs[segments].ycoord == -MAX_INT32
00633 && segs[segments].scale_factor != 0 && !using_row) {
00634 blob_offset = line_m * blob_x_centre + line_c;
00635 segs[segments].scale_factor = blob_box.top () - blob_offset;
00636 }
00637 if (segs[segments].scale_factor != 0)
00638 mean_x += segs[segments].scale_factor;
00639 segments++;
00640 }
00641 mean_x /= x_count;
00642
00643
00644 segments = 0;
00645 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00646 blob_it.forward ()) {
00647 blob = blob_it.data ();
00648 blob_box = blob->bounding_box ();
00649 blob_x_centre = blob_box.left () +
00650 (blob_box.right () - blob_box.left ()) / 2.0;
00651 if (segs[segments].ycoord != -MAX_INT32)
00652 blob_offset = (float) segs[segments].ycoord;
00653 else if (using_row)
00654 blob_offset = row->base_line (blob_x_centre);
00655 else
00656 blob_offset = line_m * blob_x_centre + line_c;
00657 if (segs[segments].scale_factor == 0)
00658 segs[segments].scale_factor = mean_x;
00659 segs[segments].scale_factor =
00660 bln_x_height / segs[segments].scale_factor;
00661
00662
00663
00664 blob->move (FCOORD (-antidote.origin (), -blob_offset));
00665 blob->
00666 scale (FCOORD (antidote.scale (), segs[segments].scale_factor));
00667 blob->move (FCOORD (0.0, bln_baseline_offset));
00668 segments++;
00669 }
00670
00671
00672 blob_it.set_to_list ((PBLOB_LIST *) & rej_cblobs);
00673 segment = 0;
00674 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00675 blob_it.forward ()) {
00676 blob = blob_it.data ();
00677 blob_box = blob->bounding_box ();
00678 blob_x_centre = blob_box.left () +
00679 (blob_box.right () - blob_box.left ()) / 2.0;
00680 while (segment < segments - 1
00681 && segs[segment + 1].xstart <= blob_x_centre)
00682 segment++;
00683 if (segs[segment].ycoord != -MAX_INT32)
00684 blob_offset = (float) segs[segment].ycoord;
00685 else if (using_row)
00686 blob_offset = row->base_line (blob_x_centre);
00687 else
00688 blob_offset = line_m * blob_x_centre + line_c;
00689 blob->move (FCOORD (-antidote.origin (), -blob_offset));
00690 blob->
00691 scale (FCOORD (antidote.scale (), segs[segment].scale_factor));
00692 blob->move (FCOORD (0.0, bln_baseline_offset));
00693 }
00694 if (line.count () > 0 || x_count > 1)
00695 antidote = DENORM (antidote.origin (), antidote.scale (),
00696 line_m, line_c, segments, segs, using_row, row);
00697 delete[]segs;
00698 }
00699 if (denorm != NULL)
00700 *denorm = antidote;
00701
00702 flags.set_bit (W_NORMALIZED, TRUE);
00703 }
00704
00705
00717 void WERD::baseline_denormalise(
00718 const DENORM *denorm
00719 ) {
00720 PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00721
00722 PBLOB *blob;
00723
00724 if (!flags.bit (W_NORMALIZED)) {
00725 WRONG_WORD.error ("WERD::baseline_denormalise", ABORT,
00726 "Baseline normalised");
00727 }
00728
00729 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
00730 blob = blob_it.data ();
00731
00732 blob->baseline_denormalise (denorm);
00733 }
00734
00735
00736 blob_it.set_to_list ((PBLOB_LIST *) & rej_cblobs);
00737 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
00738 blob = blob_it.data ();
00739
00740 blob->baseline_denormalise (denorm);
00741 }
00742
00743
00744 flags.set_bit (W_NORMALIZED, FALSE);
00745 }
00746
00747
00751 void WERD::print(
00752 FILE *
00753 ) {
00754 tprintf ("Blanks= %d\n", blanks);
00755 bounding_box ().print ();
00756 tprintf ("Flags = %d = 0%o\n", flags.val, flags.val);
00757 tprintf (" W_SEGMENTED = %s\n",
00758 flags.bit (W_SEGMENTED) ? "TRUE" : "FALSE ");
00759 tprintf (" W_ITALIC = %s\n", flags.bit (W_ITALIC) ? "TRUE" : "FALSE ");
00760 tprintf (" W_BOL = %s\n", flags.bit (W_BOL) ? "TRUE" : "FALSE ");
00761 tprintf (" W_EOL = %s\n", flags.bit (W_EOL) ? "TRUE" : "FALSE ");
00762 tprintf (" W_NORMALIZED = %s\n",
00763 flags.bit (W_NORMALIZED) ? "TRUE" : "FALSE ");
00764 tprintf (" W_POLYGON = %s\n", flags.bit (W_POLYGON) ? "TRUE" : "FALSE ");
00765 tprintf (" W_LINEARC = %s\n", flags.bit (W_LINEARC) ? "TRUE" : "FALSE ");
00766 tprintf (" W_DONT_CHOP = %s\n",
00767 flags.bit (W_DONT_CHOP) ? "TRUE" : "FALSE ");
00768 tprintf (" W_REP_CHAR = %s\n",
00769 flags.bit (W_REP_CHAR) ? "TRUE" : "FALSE ");
00770 tprintf (" W_FUZZY_SP = %s\n",
00771 flags.bit (W_FUZZY_SP) ? "TRUE" : "FALSE ");
00772 tprintf (" W_FUZZY_NON = %s\n",
00773 flags.bit (W_FUZZY_NON) ? "TRUE" : "FALSE ");
00774 tprintf ("Correct= %s\n", correct.string ());
00775 tprintf ("Rejected cblob count = %d\n", rej_cblobs.length ());
00776 }
00777
00778
00782 #ifndef GRAPHICS_DISABLED
00783 void WERD::plot(
00784 WINDOW window,
00785 COLOUR colour,
00786 BOOL8 solid
00787 ) {
00788 if (flags.bit (W_POLYGON)) {
00789
00790 PBLOB_IT it = (PBLOB_LIST *) (&cblobs);
00791
00792 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00793 it.data ()->plot (window, colour, colour);
00794 }
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 else {
00806 C_BLOB_IT it = &cblobs;
00807
00808 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00809 it.data ()->plot (window, colour, colour);
00810 }
00811 }
00812 plot_rej_blobs(window, solid);
00813 }
00814 #endif
00815
00816
00820 #ifndef GRAPHICS_DISABLED
00821 void WERD::plot(
00822 WINDOW window,
00823 BOOL8 solid
00824 ) {
00825 COLOUR colour = FIRST_COLOUR;
00826 if (flags.bit (W_POLYGON)) {
00827
00828 PBLOB_IT it = (PBLOB_LIST *) (&cblobs);
00829
00830 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00831 it.data ()->plot (window, colour, CHILD_COLOUR);
00832 colour = (COLOUR) (colour + 1);
00833 if (colour == LAST_COLOUR)
00834 colour = FIRST_COLOUR;
00835 }
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 else {
00849 C_BLOB_IT it = &cblobs;
00850
00851 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00852 it.data ()->plot (window, colour, CHILD_COLOUR);
00853 colour = (COLOUR) (colour + 1);
00854 if (colour == LAST_COLOUR)
00855 colour = FIRST_COLOUR;
00856 }
00857 }
00858 plot_rej_blobs(window, solid);
00859 }
00860 #endif
00861
00862
00867 #ifndef GRAPHICS_DISABLED
00868 void WERD::plot_rej_blobs(
00869 WINDOW window,
00870 BOOL8 solid
00871 ) {
00872 if (flags.bit (W_POLYGON)) {
00873 PBLOB_IT it = (PBLOB_LIST *) (&rej_cblobs);
00874
00875
00876 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00877 it.data ()->plot (window, GREY, GREY);
00878 }
00879 }
00880
00881
00882
00883
00884
00885
00886
00887 else {
00888 C_BLOB_IT it = &rej_cblobs;
00889
00890 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00891 it.data ()->plot (window, GREY, GREY);
00892 }
00893 }
00894 }
00895 #endif
00896
00897
00901 WERD *WERD::shallow_copy() {
00902 WERD *new_word = new WERD;
00903
00904 new_word->blanks = blanks;
00905 new_word->flags = flags;
00906 new_word->dummy = dummy;
00907 new_word->correct = correct;
00908 return new_word;
00909 }
00910
00911
00915 WERD & WERD::operator= (
00916 const WERD & source
00917 ) {
00918 this->ELIST_LINK::operator= (source);
00919 blanks = source.blanks;
00920 flags = source.flags;
00921 dummy = source.dummy;
00922 correct = source.correct;
00923 if (flags.bit (W_POLYGON)) {
00924 if (!cblobs.empty ())
00925 ((PBLOB_LIST *) (&cblobs))->clear ();
00926 ((PBLOB_LIST *) (&cblobs))->deep_copy ((PBLOB_LIST *) (&source.cblobs));
00927
00928 if (!rej_cblobs.empty ())
00929 ((PBLOB_LIST *) (&rej_cblobs))->clear ();
00930 ((PBLOB_LIST *) (&rej_cblobs))->deep_copy ((PBLOB_LIST *) (&source.
00931 rej_cblobs));
00932
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 else {
00946 if (!cblobs.empty ())
00947 cblobs.clear ();
00948 cblobs.deep_copy (&source.cblobs);
00949
00950 if (!rej_cblobs.empty ())
00951 rej_cblobs.clear ();
00952 rej_cblobs.deep_copy (&source.rej_cblobs);
00953 }
00954 return *this;
00955 }
00956
00957
00958
00959
00960
00961
00962 int word_comparator(
00963 const void *word1p,
00964 const void *word2p
00965 ) {
00966 WERD *
00967 word1 = *(WERD **) word1p;
00968 WERD *
00969 word2 = *(WERD **) word2p;
00970
00971 return word1->bounding_box ().left () - word2->bounding_box ().left ();
00972 }