Tesseract  3.02
tesseract-ocr/textord/drawtord.cpp
Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        drawtord.cpp  (Formerly drawto.c)
00003  * Description: Draw things to do with textord.
00004  * Author:              Ray Smith
00005  * Created:             Thu Jul 30 15:40:57 BST 1992
00006  *
00007  * (C) Copyright 1992, Hewlett-Packard Ltd.
00008  ** Licensed under the Apache License, Version 2.0 (the "License");
00009  ** you may not use this file except in compliance with the License.
00010  ** You may obtain a copy of the License at
00011  ** http://www.apache.org/licenses/LICENSE-2.0
00012  ** Unless required by applicable law or agreed to in writing, software
00013  ** distributed under the License is distributed on an "AS IS" BASIS,
00014  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  ** See the License for the specific language governing permissions and
00016  ** limitations under the License.
00017  *
00018  **********************************************************************/
00019 
00020 #include "mfcpch.h"
00021 #include          "pithsync.h"
00022 #include          "topitch.h"
00023 #include          "drawtord.h"
00024 
00025 // Include automatically generated configuration file if running autoconf.
00026 #ifdef HAVE_CONFIG_H
00027 #include "config_auto.h"
00028 #endif
00029 
00030 #define TO_WIN_XPOS     0       //default window pos
00031 #define TO_WIN_YPOS     0
00032 #define TO_WIN_NAME     "Textord"
00033                                  //title of window
00034 
00035 #define EXTERN
00036 
00037 EXTERN BOOL_VAR (textord_show_fixed_cuts, FALSE,
00038 "Draw fixed pitch cell boundaries");
00039 
00040 EXTERN ScrollView* to_win = NULL;
00041 
00042 /**********************************************************************
00043  * create_to_win
00044  *
00045  * Create the to window used to show the fit.
00046  **********************************************************************/
00047 #ifndef GRAPHICS_DISABLED
00048 
00049 void create_to_win(ICOORD page_tr) {
00050   to_win = new ScrollView(TO_WIN_NAME, TO_WIN_XPOS, TO_WIN_YPOS,
00051                           page_tr.x() + 1, page_tr.y() + 1,
00052                           page_tr.x(), page_tr.y(), true);
00053 }
00054 
00055 
00056 void close_to_win() {
00057   // to_win is leaked, but this enables the user to view the contents.
00058   if (to_win != NULL) {
00059     to_win->Update();
00060   }
00061 }
00062 
00063 
00064 /**********************************************************************
00065  * plot_box_list
00066  *
00067  * Draw a list of blobs.
00068  **********************************************************************/
00069 
00070 void plot_box_list(                      //make gradients win
00071                    ScrollView* win,           //window to draw in
00072                    BLOBNBOX_LIST *list,  //blob list
00073                    ScrollView::Color body_colour    //colour to draw
00074                   ) {
00075   BLOBNBOX_IT it = list;         //iterator
00076 
00077   win->Pen(body_colour);
00078   win->Brush(ScrollView::NONE);
00079   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00080     it.data ()->bounding_box ().plot (win);
00081   }
00082 }
00083 
00084 
00085 /**********************************************************************
00086  * plot_to_row
00087  *
00088  * Draw the blobs of a row in a given colour and draw the line fit.
00089  **********************************************************************/
00090 
00091 void plot_to_row(                 //draw a row
00092                  TO_ROW *row,     //row to draw
00093                  ScrollView::Color colour,   //colour to draw in
00094                  FCOORD rotation  //rotation for line
00095                 ) {
00096   FCOORD plot_pt;                //point to plot
00097                                  //blobs
00098   BLOBNBOX_IT it = row->blob_list ();
00099   float left, right;             //end of row
00100 
00101   if (it.empty ()) {
00102     tprintf ("No blobs in row at %g\n", row->parallel_c ());
00103     return;
00104   }
00105   left = it.data ()->bounding_box ().left ();
00106   it.move_to_last ();
00107   right = it.data ()->bounding_box ().right ();
00108   plot_blob_list (to_win, row->blob_list (), colour, ScrollView::BROWN);
00109   to_win->Pen(colour);
00110   plot_pt = FCOORD (left, row->line_m () * left + row->line_c ());
00111   plot_pt.rotate (rotation);
00112   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
00113   plot_pt = FCOORD (right, row->line_m () * right + row->line_c ());
00114   plot_pt.rotate (rotation);
00115   to_win->DrawTo(plot_pt.x (), plot_pt.y ());
00116 }
00117 
00118 
00119 /**********************************************************************
00120  * plot_parallel_row
00121  *
00122  * Draw the blobs of a row in a given colour and draw the line fit.
00123  **********************************************************************/
00124 
00125 void plot_parallel_row(                 //draw a row
00126                        TO_ROW *row,     //row to draw
00127                        float gradient,  //gradients of lines
00128                        inT32 left,      //edge of block
00129                        ScrollView::Color colour,   //colour to draw in
00130                        FCOORD rotation  //rotation for line
00131                       ) {
00132   FCOORD plot_pt;                //point to plot
00133                                  //blobs
00134   BLOBNBOX_IT it = row->blob_list ();
00135   float fleft = (float) left;    //floating version
00136   float right;                   //end of row
00137 
00138   //      left=it.data()->bounding_box().left();
00139   it.move_to_last ();
00140   right = it.data ()->bounding_box ().right ();
00141   plot_blob_list (to_win, row->blob_list (), colour, ScrollView::BROWN);
00142   to_win->Pen(colour);
00143   plot_pt = FCOORD (fleft, gradient * left + row->max_y ());
00144   plot_pt.rotate (rotation);
00145   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
00146   plot_pt = FCOORD (fleft, gradient * left + row->min_y ());
00147   plot_pt.rotate (rotation);
00148   to_win->DrawTo(plot_pt.x (), plot_pt.y ());
00149   plot_pt = FCOORD (fleft, gradient * left + row->parallel_c ());
00150   plot_pt.rotate (rotation);
00151   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
00152   plot_pt = FCOORD (right, gradient * right + row->parallel_c ());
00153   plot_pt.rotate (rotation);
00154   to_win->DrawTo(plot_pt.x (), plot_pt.y ());
00155 }
00156 
00157 
00158 /**********************************************************************
00159  * draw_occupation
00160  *
00161  * Draw the row occupation with points above the threshold in white
00162  * and points below the threshold in black.
00163  **********************************************************************/
00164 
00165 void
00166 draw_occupation (                //draw projection
00167 inT32 xleft,                     //edge of block
00168 inT32 ybottom,                   //bottom of block
00169 inT32 min_y,                     //coordinate limits
00170 inT32 max_y, inT32 occupation[], //projection counts
00171 inT32 thresholds[]               //for drop out
00172 ) {
00173   inT32 line_index;              //pixel coord
00174   ScrollView::Color colour;                 //of histogram
00175   float fleft = (float) xleft;   //float version
00176 
00177   colour = ScrollView::WHITE;
00178   to_win->Pen(colour);
00179   to_win->SetCursor(fleft, (float) ybottom);
00180   for (line_index = min_y; line_index <= max_y; line_index++) {
00181     if (occupation[line_index - min_y] < thresholds[line_index - min_y]) {
00182       if (colour != ScrollView::BLUE) {
00183         colour = ScrollView::BLUE;
00184         to_win->Pen(colour);
00185       }
00186     }
00187     else {
00188       if (colour != ScrollView::WHITE) {
00189         colour = ScrollView::WHITE;
00190         to_win->Pen(colour);
00191       }
00192     }
00193   to_win->DrawTo(fleft + occupation[line_index - min_y] / 10.0,      (float) line_index);
00194   }
00195   colour=ScrollView::STEEL_BLUE;
00196   to_win->Pen(colour);
00197   to_win->SetCursor(fleft, (float) ybottom);
00198   for (line_index = min_y; line_index <= max_y; line_index++) {
00199      to_win->DrawTo(fleft + thresholds[line_index - min_y] / 10.0,      (float) line_index);
00200   }
00201 }
00202 
00203 
00204 /**********************************************************************
00205  * draw_meanlines
00206  *
00207  * Draw the meanlines of the given block in the given colour.
00208  **********************************************************************/
00209 
00210 void draw_meanlines(                  //draw a block
00211                     TO_BLOCK *block,  //block to draw
00212                     float gradient,   //gradients of lines
00213                     inT32 left,       //edge of block
00214                     ScrollView::Color colour,    //colour to draw in
00215                     FCOORD rotation   //rotation for line
00216                    ) {
00217   FCOORD plot_pt;                //point to plot
00218                                  //rows
00219   TO_ROW_IT row_it = block->get_rows ();
00220   TO_ROW *row;                   //current row
00221   BLOBNBOX_IT blob_it;           //blobs
00222   float right;                   //end of row
00223   to_win->Pen(colour);
00224   for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00225     row = row_it.data ();
00226     blob_it.set_to_list (row->blob_list ());
00227     blob_it.move_to_last ();
00228     right = blob_it.data ()->bounding_box ().right ();
00229     plot_pt =
00230       FCOORD ((float) left,
00231       gradient * left + row->parallel_c () + row->xheight);
00232     plot_pt.rotate (rotation);
00233   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
00234     plot_pt =
00235       FCOORD ((float) right,
00236       gradient * right + row->parallel_c () + row->xheight);
00237     plot_pt.rotate (rotation);
00238     to_win->DrawTo (plot_pt.x (), plot_pt.y ());
00239   }
00240 }
00241 
00242 
00243 /**********************************************************************
00244  * plot_word_decisions
00245  *
00246  * Plot a row with words in different colours and fuzzy spaces
00247  * highlighted.
00248  **********************************************************************/
00249 
00250 void plot_word_decisions(              //draw words
00251                          ScrollView* win,   //window tro draw in
00252                          inT16 pitch,  //of block
00253                          TO_ROW *row   //row to draw
00254                         ) {
00255   ScrollView::Color colour = ScrollView::MAGENTA;       //current colour
00256   ScrollView::Color rect_colour;            //fuzzy colour
00257   inT32 prev_x;                  //end of prev blob
00258   inT16 blob_count;              //blobs in word
00259   BLOBNBOX *blob;                //current blob
00260   TBOX blob_box;                  //bounding box
00261                                  //iterator
00262   BLOBNBOX_IT blob_it = row->blob_list ();
00263   BLOBNBOX_IT start_it = blob_it;//word start
00264 
00265   rect_colour = ScrollView::BLACK;
00266   prev_x = -MAX_INT16;
00267   blob_count = 0;
00268   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
00269     blob = blob_it.data ();
00270     blob_box = blob->bounding_box ();
00271     if (!blob->joined_to_prev ()
00272     && blob_box.left () - prev_x > row->max_nonspace) {
00273       if ((blob_box.left () - prev_x >= row->min_space
00274         || blob_box.left () - prev_x > row->space_threshold)
00275       && blob_count > 0) {
00276         if (pitch > 0 && textord_show_fixed_cuts)
00277           plot_fp_cells (win, colour, &start_it, pitch, blob_count,
00278             &row->projection, row->projection_left,
00279             row->projection_right,
00280             row->xheight * textord_projection_scale);
00281         blob_count = 0;
00282         start_it = blob_it;
00283       }
00284       if (colour == ScrollView::MAGENTA)
00285         colour = ScrollView::RED;
00286       else
00287         colour = (ScrollView::Color) (colour + 1);
00288       if (blob_box.left () - prev_x < row->min_space) {
00289         if (blob_box.left () - prev_x > row->space_threshold)
00290           rect_colour = ScrollView::GOLDENROD;
00291         else
00292           rect_colour = ScrollView::CORAL;
00293         //fill_color_index(win, rect_colour);
00294         win->Brush(rect_colour);
00295         win->Rectangle (prev_x, blob_box.bottom (),
00296           blob_box.left (), blob_box.top ());
00297       }
00298     }
00299     if (!blob->joined_to_prev())
00300       prev_x = blob_box.right();
00301     if (blob->cblob () != NULL)
00302       blob->cblob ()->plot (win, colour, colour);
00303     if (!blob->joined_to_prev() && blob->cblob() != NULL)
00304       blob_count++;
00305   }
00306   if (pitch > 0 && textord_show_fixed_cuts && blob_count > 0)
00307     plot_fp_cells (win, colour, &start_it, pitch, blob_count,
00308       &row->projection, row->projection_left,
00309       row->projection_right,
00310       row->xheight * textord_projection_scale);
00311 }
00312 
00313 
00314 /**********************************************************************
00315  * plot_fp_cells
00316  *
00317  * Make a list of fixed pitch cuts and draw them.
00318  **********************************************************************/
00319 
00320 void plot_fp_cells(                        //draw words
00321                    ScrollView* win,             //window tro draw in
00322                    ScrollView::Color colour,          //colour of lines
00323                    BLOBNBOX_IT *blob_it,   //blobs
00324                    inT16 pitch,            //of block
00325                    inT16 blob_count,       //no of real blobs
00326                    STATS *projection,      //vertical
00327                    inT16 projection_left,  //edges //scale factor
00328                    inT16 projection_right,
00329                    float projection_scale) {
00330   inT16 occupation;              //occupied cells
00331   TBOX word_box;                  //bounding box
00332   FPSEGPT_LIST seg_list;         //list of cuts
00333   FPSEGPT_IT seg_it;
00334   FPSEGPT *segpt;                //current point
00335 
00336   if (pitsync_linear_version)
00337     check_pitch_sync2 (blob_it, blob_count, pitch, 2, projection,
00338       projection_left, projection_right,
00339       projection_scale, occupation, &seg_list, 0, 0);
00340   else
00341     check_pitch_sync (blob_it, blob_count, pitch, 2, projection, &seg_list);
00342   word_box = blob_it->data ()->bounding_box ();
00343   for (; blob_count > 0; blob_count--)
00344     word_box += box_next (blob_it);
00345   seg_it.set_to_list (&seg_list);
00346   for (seg_it.mark_cycle_pt (); !seg_it.cycled_list (); seg_it.forward ()) {
00347     segpt = seg_it.data ();
00348     if (segpt->faked) {
00349          colour = ScrollView::WHITE;
00350          win->Pen(colour);  }
00351     else {
00352       win->Pen(colour); }
00353     win->Line(segpt->position (), word_box.bottom (),segpt->position (), word_box.top ());
00354   }
00355 }
00356 
00357 
00358 /**********************************************************************
00359  * plot_fp_cells2
00360  *
00361  * Make a list of fixed pitch cuts and draw them.
00362  **********************************************************************/
00363 
00364 void plot_fp_cells2(                        //draw words
00365                     ScrollView* win,             //window tro draw in
00366                     ScrollView::Color colour,          //colour of lines
00367                     TO_ROW *row,            //for location
00368                     FPSEGPT_LIST *seg_list  //segments to plot
00369                    ) {
00370   TBOX word_box;                  //bounding box
00371   FPSEGPT_IT seg_it = seg_list;
00372                                  //blobs in row
00373   BLOBNBOX_IT blob_it = row->blob_list ();
00374   FPSEGPT *segpt;                //current point
00375 
00376   word_box = blob_it.data ()->bounding_box ();
00377   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();)
00378     word_box += box_next (&blob_it);
00379   for (seg_it.mark_cycle_pt (); !seg_it.cycled_list (); seg_it.forward ()) {
00380     segpt = seg_it.data ();
00381     if (segpt->faked) {
00382          colour = ScrollView::WHITE;
00383          win->Pen(colour); }
00384     else {
00385      win->Pen(colour); }
00386      win->Line(segpt->position (), word_box.bottom (),segpt->position (), word_box.top ());
00387   }
00388 }
00389 
00390 
00391 /**********************************************************************
00392  * plot_row_cells
00393  *
00394  * Make a list of fixed pitch cuts and draw them.
00395  **********************************************************************/
00396 
00397 void plot_row_cells(                       //draw words
00398                     ScrollView* win,            //window tro draw in
00399                     ScrollView::Color colour,         //colour of lines
00400                     TO_ROW *row,           //for location
00401                     float xshift,          //amount of shift
00402                     ICOORDELT_LIST *cells  //cells to draw
00403                    ) {
00404   TBOX word_box;                  //bounding box
00405   ICOORDELT_IT cell_it = cells;
00406                                  //blobs in row
00407   BLOBNBOX_IT blob_it = row->blob_list ();
00408   ICOORDELT *cell;               //current cell
00409 
00410   word_box = blob_it.data ()->bounding_box ();
00411   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();)
00412     word_box += box_next (&blob_it);
00413   win->Pen(colour);
00414   for (cell_it.mark_cycle_pt (); !cell_it.cycled_list (); cell_it.forward ()) {
00415     cell = cell_it.data ();
00416     win->Line(cell->x () + xshift, word_box.bottom (), cell->x () + xshift, word_box.top ());
00417   }
00418 }
00419 
00420 #endif  // GRAPHICS_DISABLED
00421