ccstruct/werd.cpp

Go to the documentation of this file.
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                                  //last rainbow colour
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 (                     //constructor
00075 C_BLOB_LIST * blob_list,         //in word order
00076 UINT8 blank_count,               //blanks in front
00077 const char *text                 //correct text
00078 ):
00079 flags (0),
00080 correct(text) { 
00081   C_BLOB_IT start_it = blob_list;//iterator
00082   C_BLOB_IT end_it = blob_list;  //another
00083                                  //rejected blobs in wd
00084   C_BLOB_IT rej_cblob_it = &rej_cblobs;
00085   C_OUTLINE_IT c_outline_it;     //coutline iterator
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 ();           //move to last
00093                                  //move to our list
00094   cblobs.assign_to_sublist (&start_it, &end_it);
00095   blanks = blank_count;
00096 
00097     /* Set white on black flag for the WERD */
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 (                     //constructor
00142 PBLOB_LIST * blob_list,          //in word order
00143 UINT8 blank_count,               //blanks in front
00144 const char *text                 //correct text
00145 ):
00146 flags (0),
00147 correct(text) { 
00148   PBLOB_IT start_it = blob_list; //iterator
00149   PBLOB_IT end_it = blob_list;   //another
00150 
00151   while (!end_it.at_last ())
00152     end_it.forward ();           //move to last
00153   ((PBLOB_LIST *) (&cblobs))->assign_to_sublist (&start_it, &end_it);
00154   //move to our list
00155                                  //it's a polygon
00156   flags.set_bit (W_POLYGON, TRUE);
00157   blanks = blank_count;
00158   //      fprintf(stderr,"Wrong constructor!!!!\n");
00159 }
00160 
00161 
00167 WERD::WERD (                     //constructor
00168 PBLOB_LIST * blob_list,          //in word order
00169 WERD * clone                     //sorce of flags
00170 ):flags (clone->flags), correct (clone->correct) {
00171   PBLOB_IT start_it = blob_list; //iterator
00172   PBLOB_IT end_it = blob_list;   //another
00173 
00174   while (!end_it.at_last ())
00175     end_it.forward ();           //move to last
00176   ((PBLOB_LIST *) (&cblobs))->assign_to_sublist (&start_it, &end_it);
00177   //move to our list
00178   blanks = clone->blanks;
00179   //      fprintf(stderr,"Wrong constructor!!!!\n");
00180 }
00181 
00182 
00188 WERD::WERD (                     //constructor
00189 C_BLOB_LIST * blob_list,         //in word order
00190 WERD * clone                     //sorce of flags
00191 ):flags (clone->flags), correct (clone->correct) {
00192   C_BLOB_IT start_it = blob_list;//iterator
00193   C_BLOB_IT end_it = blob_list;  //another
00194 
00195   while (!end_it.at_last ())
00196     end_it.forward ();           //move to last
00197   ((C_BLOB_LIST *) (&cblobs))->assign_to_sublist (&start_it, &end_it);
00198   //move to our list
00199   blanks = clone->blanks;
00200   //      fprintf(stderr,"Wrong constructor!!!!\n");
00201 }
00202 
00203 
00209 WERD *WERD::poly_copy(               //make a poly copy
00210                       float xheight  //row height
00211                      ) {
00212   PBLOB *blob;                   //new blob
00213   WERD *result = new WERD;       //output word
00214   C_BLOB_IT src_it = &cblobs;    //iterator
00215   //      LARC_BLOB_IT                            larc_it=(LARC_BLOB_LIST*)(&cblobs);
00216   PBLOB_IT dest_it = (PBLOB_LIST *) (&result->cblobs);
00217   //another
00218 
00219   if (flags.bit (W_POLYGON)) {
00220     *result = *this;             //just copy it
00221   }
00222   else {
00223     result->flags = flags;
00224     result->correct = correct;   //copy info
00225     result->dummy = dummy;
00226     if (!src_it.empty ()) {
00227       //      if (flags.bit(W_LINEARC))
00228       //      {
00229       //         do
00230       //         {
00231       //             blob=new PBLOB;
00232       //             poly_linearc_outlines(larc_it.data()->out_list(),
00233       //                blob->out_list());      //convert outlines
00234       //             dest_it.add_after_then_move(blob); //add to dest list
00235       //             larc_it.forward();
00236       //         }
00237       //         while (!larc_it.at_first());
00238       //       }
00239       //         else
00240       //       {
00241       do {
00242         blob = new PBLOB (src_it.data (), xheight);
00243         //convert blob
00244                                  //add to dest list
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       /* Polygonal approx of reject blobs */
00253       src_it.set_to_list (&rej_cblobs);
00254       dest_it = (PBLOB_LIST *) (&result->rej_cblobs);
00255       do {
00256                                  //convert blob
00257         blob = new PBLOB (src_it.data (), xheight);
00258                                  //add to dest list
00259         dest_it.add_after_then_move (blob);
00260         src_it.forward ();
00261       }
00262       while (!src_it.at_first ());
00263     }
00264                                  //polygon now
00265     result->flags.set_bit (W_POLYGON, TRUE);
00266     result->blanks = blanks;
00267   }
00268   return result;
00269 }
00270 
00271 
00283 BOX WERD::bounding_box() {  //bounding box
00284   BOX box;                       //box being built
00285                                  //rejected blobs in wd
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                                  //polygons
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;      //blobs of WERD
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(                  // reposition WERD
00318                 const ICOORD vec  // by vector
00319                ) {
00320   PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00321   // blob iterator
00322   //      LARC_BLOB_IT   lblob_it((LARC_BLOB_LIST*)&cblobs);
00323   C_BLOB_IT cblob_it(&cblobs);  // cblob iterator
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   //      else if (flags.bit(W_LINEARC))
00330   //              for( lblob_it.mark_cycle_pt();
00331   //                      !lblob_it.cycled_list();
00332   //                      lblob_it.forward() )
00333   //                      lblob_it.data()->move( vec );
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(               // scale WERD
00345                  const float f  // by multiplier
00346                 ) {
00347   PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00348   // blob iterator
00349   //      LARC_BLOB_IT    lblob_it((LARC_BLOB_LIST*)&cblobs);
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   //      else if (flags.bit(W_LINEARC))
00356   //              for (lblob_it.mark_cycle_pt();
00357   //                              !lblob_it.cycled_list();
00358   //                              lblob_it.forward() )
00359   //                      lblob_it.data()->scale( f );
00360   else
00361     CANT_SCALE_EDGESTEPS.error ("WERD::scale", ABORT, NULL);
00362 }
00363 
00364 
00368 void WERD::join_on(              // join WERD
00369                    WERD *&other  //other word
00370                   ) {
00371   PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00372   // blob iterator
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(              //copy blobs
00392                    WERD *&other  //from other
00393                   ) {
00394   if (flags.bit (W_POLYGON)) {
00395     PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00396     // blob iterator
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   //      else if (flags.bit(W_LINEARC))
00404   //      {
00405   //         LARC_BLOB_IT    larc_blob_it( (LARC_BLOB_LIST*)&cblobs );
00406   //         LARC_BLOB_LIST  larc_blobs;
00407 
00408   //         larc_blobs.deep_copy((LARC_BLOB_LIST*)(&other->cblobs));
00409   //         larc_blob_it.move_to_last();
00410   //         larc_blob_it.add_list_after( &larc_blobs );
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( // Tess style BL Norm
00442                               ROW *row,
00443                               DENORM *denorm  //antidote
00444                              ) {
00445   baseline_normalise_x (row, row->x_height (), denorm);
00446   //Use standard x ht
00447 }
00448 
00449 
00463 void WERD::baseline_normalise_x(                 // Tess style BL Norm
00464                                 ROW *row,
00465                                 float x_height,  //non standard value
00466                                 DENORM *denorm   //antidote
00467                                ) {
00468   BOOL8 using_row;               //as baseline
00469   float blob_x_centre;           //middle of blob
00470   float blob_offset;             //bottom miss
00471   float top_offset;              //top miss
00472   float blob_x_height;           //xh for this blob
00473   INT16 segments;                //no of segments
00474   INT16 segment;                 //current segment
00475   DENORM_SEG *segs;              //array of segments
00476   float mean_x;                  //mean xheight
00477   INT32 x_count;                 //no of xs
00478   BOX word_box = bounding_box ();//word bounding box
00479   BOX blob_box;                  //blob bounding box
00480   PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00481   // blob iterator
00482   PBLOB *blob;
00483   LLSQ line;                     //fitted line
00484   double line_m, line_c;         //fitted line
00485                                  //inverse norm
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;  // For scaling to baseline normalised size.
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       // Constrain the scale factor as target numbers should be either
00513       // cap height already or xheight.
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                                  //Repeat for rej blobs
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                                  //Repeat for rej blobs
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           //fix it later
00598         }
00599         else {
00600                                  //not a goer
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           //fix it later
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     //     printf("mean x=%g, count=%d, line_m=%g, line_c=%g\n",
00643     //             mean_x,x_count,line_m,line_c);
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       //   printf("Blob sf=%g, top=%d, bot=%d, base=%g\n",
00662       //                     segs[segments].scale_factor,blob_box.top(),
00663       //                     blob_box.bottom(),blob_offset);
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                                  //Repeat for rej blobs
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                                  //it's normalised
00702   flags.set_bit (W_NORMALIZED, TRUE);
00703 }
00704 
00705 
00717 void WERD::baseline_denormalise(       // Tess style BL Norm
00718                                 const DENORM *denorm  //antidote
00719                                ) {
00720   PBLOB_IT blob_it ((PBLOB_LIST *) & cblobs);
00721   // blob iterator
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                                  //denormalise it
00732     blob->baseline_denormalise (denorm);
00733   }
00734 
00735                                  //Repeat for rej blobs
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                                  //denormalise it
00740     blob->baseline_denormalise (denorm);
00741   }
00742 
00743                                  //it's not normalised
00744   flags.set_bit (W_NORMALIZED, FALSE);
00745 }
00746 
00747 
00751 void WERD::print(        //print
00752                  FILE *  //file to print on
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(                //draw it
00784                 WINDOW window,  //window to draw in
00785                 COLOUR colour,  //colour to draw in
00786                 BOOL8 solid     //draw larcs solid
00787                ) {
00788   if (flags.bit (W_POLYGON)) {
00789                                  //polygons
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   //      else if (flags.bit(W_LINEARC))
00797   //      {
00798   //          LARC_BLOB_IT  it=(LARC_BLOB_LIST*)(&cblobs);
00799 
00800   //          for ( it.mark_cycle_pt(); !it.cycled_list(); it.forward() )
00801   //          {
00802   //             it.data()->plot(window,solid,colour,solid ? BLACK : colour);
00803   //          }
00804   //      }
00805   else {
00806     C_BLOB_IT it = &cblobs;      //blobs of WERD
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(                //draw it
00822                 WINDOW window,  //window to draw in
00823                 BOOL8 solid     //draw larcs solid
00824                ) {
00825   COLOUR colour = FIRST_COLOUR;  //current colour
00826   if (flags.bit (W_POLYGON)) {
00827                                  //polygons
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;   //cycle round
00835     }
00836   }
00837   //  else if (flags.bit(W_LINEARC))
00838   //  {
00839   //      LARC_BLOB_IT   it=(LARC_BLOB_LIST*)(&cblobs);
00840 
00841   //      for ( it.mark_cycle_pt(); !it.cycled_list(); it.forward() )
00842   //      {
00843   //         it.data()->plot(window,solid,colour,solid ? BLACK : CHILD_COLOUR);
00844   //         colour=(COLOUR)(colour+1);
00845   //         if (colour==LAST_COLOUR)
00846   //                 colour=FIRST_COLOUR;
00847   //      }
00848   else {
00849     C_BLOB_IT it = &cblobs;      //blobs of WERD
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;   //cycle round
00856     }
00857   }
00858   plot_rej_blobs(window, solid); 
00859 }
00860 #endif
00861 
00862 
00867 #ifndef GRAPHICS_DISABLED
00868 void WERD::plot_rej_blobs(                //draw it
00869                           WINDOW window,  //window to draw in
00870                           BOOL8 solid     //draw larcs solid
00871                          ) {
00872   if (flags.bit (W_POLYGON)) {
00873     PBLOB_IT it = (PBLOB_LIST *) (&rej_cblobs);
00874     //polygons
00875 
00876     for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00877       it.data ()->plot (window, GREY, GREY);
00878     }
00879   }
00880   //  else if (flags.bit(W_LINEARC))
00881   //  {
00882   //      LARC_BLOB_IT    it=(LARC_BLOB_LIST*)(&rej_cblobs);
00883   //      for ( it.mark_cycle_pt(); !it.cycled_list(); it.forward() )
00884   //      {
00885   //          it.data()->plot(window,solid,GREY,solid ? BLACK : GREY);
00886   //      }
00887   else {
00888     C_BLOB_IT it = &rej_cblobs;  //blobs of WERD
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() {  //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= (         //assign words
00916 const WERD & source              //from this
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   //  else if (flags.bit(W_LINEARC))
00935   //  {
00936   //      if ( !cblobs.empty() )
00937   //          ((LARC_BLOB_LIST*)(&cblobs))->clear();
00938   //      ((LARC_BLOB_LIST*)(&cblobs))->deep_copy(
00939   //          (LARC_BLOB_LIST*)(&source.cblobs));
00940 
00941   //      if ( !rej_cblobs.empty() )
00942   //          rej_cblobs.clear();
00943   //      rej_cblobs.deep_copy( &source.rej_cblobs );
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 \brief word comparator used to sort a word list so that words are in increasing
00960 order of left edge.
00961 */
00962 int word_comparator(                     //sort blobs
00963                     const void *word1p,  //ptr to ptr to word1
00964                     const void *word2p   //ptr to ptr to word2
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 }

Generated on Wed Feb 28 19:49:08 2007 for Tesseract by  doxygen 1.5.1