Tesseract
3.02
|
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