ccstruct/pdblock.cpp

Go to the documentation of this file.
00001 
00020 #include "mfcpch.h"
00021 #include          <stdlib.h>
00022 #include          "blckerr.h"
00023 #include          "pdblock.h"
00024 #include          "showim.h"
00025 
00026 #include          "hpddef.h"     //must be last (handpd.dll)
00027 
00029 #define BLOCK_LABEL_HEIGHT  150
00030 
00031 CLISTIZE (PDBLK)
00035 PDBLK::PDBLK (                   //rectangular block
00036 INT16 xmin,                      //bottom left
00037 INT16 ymin, INT16 xmax,          //top right
00038 INT16 ymax):    box (ICOORD (xmin, ymin), ICOORD (xmax, ymax)) {
00039                                  //boundaries
00040   ICOORDELT_IT left_it = &leftside;
00041   ICOORDELT_IT right_it = &rightside;
00042 
00043   hand_block = NULL;
00044   hand_poly = NULL;
00045   left_it.set_to_list (&leftside);
00046   right_it.set_to_list (&rightside);
00047                                  //make default box
00048   left_it.add_to_end (new ICOORDELT (xmin, ymin));
00049   left_it.add_to_end (new ICOORDELT (xmin, ymax));
00050   right_it.add_to_end (new ICOORDELT (xmax, ymin));
00051   right_it.add_to_end (new ICOORDELT (xmax, ymax));
00052 }
00053 
00054 
00060 void PDBLK::set_sides(                       //set vertex lists
00061                       ICOORDELT_LIST *left,  //left vertices
00062                       ICOORDELT_LIST *right  //right vertices
00063                      ) {
00064                                  //boundaries
00065   ICOORDELT_IT left_it = &leftside;
00066   ICOORDELT_IT right_it = &rightside;
00067 
00068   leftside.clear ();
00069   left_it.move_to_first ();
00070   left_it.add_list_before (left);
00071   rightside.clear ();
00072   right_it.move_to_first ();
00073   right_it.add_list_before (right);
00074 }
00075 
00076 
00082 BOOL8 PDBLK::contains(           //test containment
00083                       ICOORD pt  //point to test
00084                      ) {
00085   BLOCK_RECT_IT it = this;       //rectangle iterator
00086   ICOORD bleft, tright;          //corners of rectangle
00087 
00088   for (it.start_block (); !it.cycled_rects (); it.forward ()) {
00089                                  //get rectangle
00090     it.bounding_box (bleft, tright);
00091                                  //inside rect
00092     if (pt.x () >= bleft.x () && pt.x () <= tright.x ()
00093       && pt.y () >= bleft.y () && pt.y () <= tright.y ())
00094       return TRUE;               //is inside
00095   }
00096   return FALSE;                  //not inside
00097 }
00098 
00099 
00103 void PDBLK::move(                  // reposition block
00104                  const ICOORD vec  // by vector
00105                 ) {
00106   ICOORDELT_IT it(&leftside); 
00107 
00108   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00109     *(it.data ()) += vec;
00110 
00111   it.set_to_list (&rightside);
00112 
00113   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00114     *(it.data ()) += vec;
00115 
00116   box.move (vec);
00117 }
00118 
00119 
00123 #ifndef GRAPHICS_DISABLED
00124 void PDBLK::plot(                //draw outline
00125                  WINDOW window,  //window to draw in
00126                  INT32 serial,   //serial number
00127                  COLOUR colour   //colour to draw in
00128                 ) {
00129   ICOORD startpt;                //start of outline
00130   ICOORD endpt;                  //end of outline
00131   ICOORD prevpt;                 //previous point
00132   ICOORDELT_IT it = &leftside;   //iterator
00133 
00134                                  //set the colour
00135   line_color_index(window, colour); 
00136   text_color_index(window, colour); 
00137   character_height (window, (float) BLOCK_LABEL_HEIGHT);
00138   text_font_index (window, 6);
00139 
00140   if (!leftside.empty ()) {
00141     startpt = *(it.data ());     //bottom left corner
00142     //              tprintf("Block %d bottom left is (%d,%d)\n",
00143     //                      serial,startpt.x(),startpt.y());
00144     char temp_buff[34];
00145     #ifdef __UNIX__
00146     sprintf(temp_buff, INT32FORMAT, serial); 
00147     #else
00148     ultoa (serial, temp_buff, 10);
00149     #endif
00150     text2d (window, startpt.x (), startpt.y (), temp_buff, 0, FALSE);
00151 
00152     move2d (window, startpt.x (), startpt.y ());
00153     do {
00154       prevpt = *(it.data ());    //previous point
00155       it.forward ();             //move to next point
00156                                  //draw round corner
00157       draw2d (window, prevpt.x (), it.data ()->y ());
00158       draw2d (window, it.data ()->x (), it.data ()->y ());
00159     }
00160     while (!it.at_last ());      //until end of list
00161     endpt = *(it.data ());       //end point
00162 
00163                                  //other side of boundary
00164     move2d (window, startpt.x (), startpt.y ());
00165     it.set_to_list (&rightside);
00166     prevpt = startpt;
00167     for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00168                                  //draw round corner
00169       draw2d (window, prevpt.x (), it.data ()->y ());
00170       draw2d (window, it.data ()->x (), it.data ()->y ());
00171       prevpt = *(it.data ());    //previous point
00172     }
00173                                  //close boundary
00174     draw2d (window, endpt.x (), endpt.y ());
00175     if (hand_block != NULL)
00176       hand_block->plot (window, colour, serial);
00177   }
00178 }
00179 #endif
00180 
00181 
00187 #ifndef GRAPHICS_DISABLED
00188 void PDBLK::show(               //show image block
00189                  IMAGE *image,  //image to show
00190                  WINDOW window  //window to show in
00191                 ) {
00192   BLOCK_RECT_IT it = this;       //rectangle iterator
00193   ICOORD bleft, tright;          //corners of rectangle
00194 
00195   for (it.start_block (); !it.cycled_rects (); it.forward ()) {
00196                                  //get rectangle
00197     it.bounding_box (bleft, tright);
00198     //              tprintf("Drawing a block with a bottom left of (%d,%d)\n",
00199     //                      bleft.x(),bleft.y());
00200                                  //show it
00201     show_sub_image (image, bleft.x (), bleft.y (), tright.x () - bleft.x (), tright.y () - bleft.y (), window, bleft.x (), bleft.y ());
00202   }
00203 }
00204 #endif
00205 
00206 
00212 PDBLK & PDBLK::operator= (       //assignment
00213 const PDBLK & source             //from this
00214 ) {
00215   //      this->ELIST_LINK::operator=(source);
00216   if (!leftside.empty ())
00217     leftside.clear ();
00218   if (!rightside.empty ())
00219     rightside.clear ();
00220   leftside.deep_copy (&source.leftside);
00221   rightside.deep_copy (&source.rightside);
00222   box = source.box;
00223   return *this;
00224 }
00225 
00226 
00232 BLOCK_RECT_IT::BLOCK_RECT_IT (
00233 PDBLK * blkptr                   //from block
00234 ):left_it (&blkptr->leftside), right_it (&blkptr->rightside) {
00235   block = blkptr;                //remember block
00236                                  //non empty list
00237   if (!blkptr->leftside.empty ()) {
00238     start_block();  //ready for iteration
00239   }
00240 }
00241 
00242 
00246 void BLOCK_RECT_IT::set_to_block(                  //start (new) block
00247                                  PDBLK *blkptr) {  //block to start
00248   block = blkptr;                //remember block
00249                                  //set iterators
00250   left_it.set_to_list (&blkptr->leftside);
00251   right_it.set_to_list (&blkptr->rightside);
00252   if (!blkptr->leftside.empty ())
00253     start_block();  //ready for iteration
00254 }
00255 
00256 
00260 void BLOCK_RECT_IT::start_block() {  //start (new) block
00261   left_it.move_to_first ();
00262   right_it.move_to_first ();
00263   left_it.mark_cycle_pt ();
00264   right_it.mark_cycle_pt ();
00265   ymin = left_it.data ()->y ();  //bottom of first box
00266   ymax = left_it.data_relative (1)->y ();
00267   if (right_it.data_relative (1)->y () < ymax)
00268                                  //smallest step
00269     ymax = right_it.data_relative (1)->y ();
00270 }
00271 
00272 
00278 void BLOCK_RECT_IT::forward() {  //next rectangle
00279   if (!left_it.empty ()) {       //non-empty list
00280     if (left_it.data_relative (1)->y () == ymax)
00281       left_it.forward ();        //move to meet top
00282     if (right_it.data_relative (1)->y () == ymax)
00283       right_it.forward ();
00284                                  //last is special
00285     if (left_it.at_last () || right_it.at_last ()) {
00286       left_it.move_to_first ();  //restart
00287       right_it.move_to_first ();
00288                                  //now at bottom
00289       ymin = left_it.data ()->y ();
00290     }
00291     else {
00292       ymin = ymax;               //new bottom
00293     }
00294                                  //next point
00295     ymax = left_it.data_relative (1)->y ();
00296     if (right_it.data_relative (1)->y () < ymax)
00297                                  //least step forward
00298       ymax = right_it.data_relative (1)->y ();
00299   }
00300 }
00301 
00302 
00308 INT16 BLOCK_LINE_IT::get_line(             //get a line
00309                               INT16 y,     //line to get
00310                               INT16 &xext  //output extent
00311                              ) {
00312   ICOORD bleft;                  //bounding box
00313   ICOORD tright;                 //of block & rect
00314 
00315                                  //get block box
00316   block->bounding_box (bleft, tright);
00317   if (y < bleft.y () || y >= tright.y ()) {
00318     //              block->print(stderr,FALSE);
00319     BADBLOCKLINE.error ("BLOCK_LINE_IT::get_line", ABORT, "Y=%d", y);
00320   }
00321 
00322                                  //get rectangle box
00323   rect_it.bounding_box (bleft, tright);
00324                                  //inside rectangle
00325   if (y >= bleft.y () && y < tright.y ()) {
00326                                  //width of line
00327     xext = tright.x () - bleft.x ();
00328     return bleft.x ();           //start of line
00329   }
00330   for (rect_it.start_block (); !rect_it.cycled_rects (); rect_it.forward ()) {
00331                                  //get rectangle box
00332     rect_it.bounding_box (bleft, tright);
00333                                  //inside rectangle
00334     if (y >= bleft.y () && y < tright.y ()) {
00335                                  //width of line
00336       xext = tright.x () - bleft.x ();
00337       return bleft.x ();         //start of line
00338     }
00339   }
00340   LOSTBLOCKLINE.error ("BLOCK_LINE_IT::get_line", ABORT, "Y=%d", y);
00341   return 0;                      //dummy to stop warning
00342 }

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