• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************************
2  * File:        drawtord.cpp  (Formerly drawto.c)
3  * Description: Draw things to do with textord.
4  * Author:		Ray Smith
5  * Created:		Thu Jul 30 15:40:57 BST 1992
6  *
7  * (C) Copyright 1992, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #include "mfcpch.h"
21 #include          "pithsync.h"
22 #include          "topitch.h"
23 #include          "drawtord.h"
24 #include          "debugwin.h"
25 
26 #define TO_WIN_XPOS     0       //default window pos
27 #define TO_WIN_YPOS     0
28 #define TO_WIN_NAME     "Textord"
29                                  //title of window
30 #define DEBUG_WIN_NAME    "TODebug"
31 #define DEBUG_XPOS      0
32 #define DEBUG_YPOS      120
33 #define DEBUG_XSIZE     80
34 #define DEBUG_YSIZE     32
35 #define YMAX        3508
36 #define XMAX        2550
37 
38 #define EXTERN
39 
40 EXTERN BOOL_VAR (textord_show_fixed_cuts, FALSE,
41 "Draw fixed pitch cell boundaries");
42 EXTERN STRING_VAR (to_debugfile, DEBUG_WIN_NAME, "Name of debugfile");
43 
44 EXTERN ScrollView* to_win = NULL;
45 EXTERN FILE *to_debug = NULL;
46 
47 /**********************************************************************
48  * create_to_win
49  *
50  * Create the to window used to show the fit.
51  **********************************************************************/
52 #ifndef GRAPHICS_DISABLED
53 
create_to_win(ICOORD page_tr)54 void create_to_win(ICOORD page_tr) {
55   to_win = new ScrollView(TO_WIN_NAME, TO_WIN_XPOS, TO_WIN_YPOS,
56                           page_tr.x() + 1, page_tr.y() + 1,
57                           page_tr.x(), page_tr.y(), true);
58 }
59 
60 
close_to_win()61 void close_to_win() {
62   // to_win is leaked, but this enables the user to view the contents.
63   if (to_win != NULL) {
64     to_win->Update();
65   }
66 }
67 
68 
69 /**********************************************************************
70  * create_todebug_win
71  *
72  * Create the to window used to show the fit.
73  **********************************************************************/
74 
create_todebug_win()75 void create_todebug_win() {  //make gradients win
76   if (strcmp (to_debugfile.string (), DEBUG_WIN_NAME) != 0)
77     //              create_debug_window();
78     //      else
79     to_debug = fopen (to_debugfile.string (), "w");
80 }
81 
82 
83 
84 /**********************************************************************
85  * plot_box_list
86  *
87  * Draw a list of blobs.
88  **********************************************************************/
89 
plot_box_list(ScrollView * win,BLOBNBOX_LIST * list,ScrollView::Color body_colour)90 void plot_box_list(                      //make gradients win
91                    ScrollView* win,           //window to draw in
92                    BLOBNBOX_LIST *list,  //blob list
93                    ScrollView::Color body_colour    //colour to draw
94                   ) {
95   BLOBNBOX_IT it = list;         //iterator
96 
97   win->Pen(body_colour);
98   win->Brush(ScrollView::NONE);
99   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
100     it.data ()->bounding_box ().plot (win);
101   }
102 }
103 
104 
105 /**********************************************************************
106  * plot_to_row
107  *
108  * Draw the blobs of a row in a given colour and draw the line fit.
109  **********************************************************************/
110 
plot_to_row(TO_ROW * row,ScrollView::Color colour,FCOORD rotation)111 void plot_to_row(                 //draw a row
112                  TO_ROW *row,     //row to draw
113                  ScrollView::Color colour,   //colour to draw in
114                  FCOORD rotation  //rotation for line
115                 ) {
116   FCOORD plot_pt;                //point to plot
117                                  //blobs
118   BLOBNBOX_IT it = row->blob_list ();
119   float left, right;             //end of row
120 
121   if (it.empty ()) {
122     tprintf ("No blobs in row at %g\n", row->parallel_c ());
123     return;
124   }
125   left = it.data ()->bounding_box ().left ();
126   it.move_to_last ();
127   right = it.data ()->bounding_box ().right ();
128   plot_blob_list (to_win, row->blob_list (), colour, ScrollView::BROWN);
129   to_win->Pen(colour);
130   plot_pt = FCOORD (left, row->line_m () * left + row->line_c ());
131   plot_pt.rotate (rotation);
132   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
133   plot_pt = FCOORD (right, row->line_m () * right + row->line_c ());
134   plot_pt.rotate (rotation);
135   to_win->DrawTo(plot_pt.x (), plot_pt.y ());
136 }
137 
138 
139 /**********************************************************************
140  * plot_parallel_row
141  *
142  * Draw the blobs of a row in a given colour and draw the line fit.
143  **********************************************************************/
144 
plot_parallel_row(TO_ROW * row,float gradient,inT32 left,ScrollView::Color colour,FCOORD rotation)145 void plot_parallel_row(                 //draw a row
146                        TO_ROW *row,     //row to draw
147                        float gradient,  //gradients of lines
148                        inT32 left,      //edge of block
149                        ScrollView::Color colour,   //colour to draw in
150                        FCOORD rotation  //rotation for line
151                       ) {
152   FCOORD plot_pt;                //point to plot
153                                  //blobs
154   BLOBNBOX_IT it = row->blob_list ();
155   float fleft = (float) left;    //floating version
156   float right;                   //end of row
157 
158   //      left=it.data()->bounding_box().left();
159   it.move_to_last ();
160   right = it.data ()->bounding_box ().right ();
161   plot_blob_list (to_win, row->blob_list (), colour, ScrollView::BROWN);
162   to_win->Pen(colour);
163   plot_pt = FCOORD (fleft, gradient * left + row->max_y ());
164   plot_pt.rotate (rotation);
165   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
166   plot_pt = FCOORD (fleft, gradient * left + row->min_y ());
167   plot_pt.rotate (rotation);
168   to_win->DrawTo(plot_pt.x (), plot_pt.y ());
169   plot_pt = FCOORD (fleft, gradient * left + row->parallel_c ());
170   plot_pt.rotate (rotation);
171   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
172   plot_pt = FCOORD (right, gradient * right + row->parallel_c ());
173   plot_pt.rotate (rotation);
174   to_win->DrawTo(plot_pt.x (), plot_pt.y ());
175 }
176 
177 
178 /**********************************************************************
179  * draw_occupation
180  *
181  * Draw the row occupation with points above the threshold in white
182  * and points below the threshold in black.
183  **********************************************************************/
184 
185 void
draw_occupation(inT32 xleft,inT32 ybottom,inT32 min_y,inT32 max_y,inT32 occupation[],inT32 thresholds[])186 draw_occupation (                //draw projection
187 inT32 xleft,                     //edge of block
188 inT32 ybottom,                   //bottom of block
189 inT32 min_y,                     //coordinate limits
190 inT32 max_y, inT32 occupation[], //projection counts
191 inT32 thresholds[]               //for drop out
192 ) {
193   inT32 line_index;              //pixel coord
194   ScrollView::Color colour;                 //of histogram
195   float fleft = (float) xleft;   //float version
196 
197   colour = ScrollView::WHITE;
198   to_win->Pen(colour);
199   to_win->SetCursor(fleft, (float) ybottom);
200   for (line_index = min_y; line_index <= max_y; line_index++) {
201     if (occupation[line_index - min_y] < thresholds[line_index - min_y]) {
202       if (colour != ScrollView::BLUE) {
203         colour = ScrollView::BLUE;
204 	to_win->Pen(colour);
205       }
206     }
207     else {
208       if (colour != ScrollView::WHITE) {
209         colour = ScrollView::WHITE;
210 	to_win->Pen(colour);
211       }
212     }
213   to_win->DrawTo(fleft + occupation[line_index - min_y] / 10.0,      (float) line_index);
214   }
215   colour=ScrollView::STEEL_BLUE;
216   to_win->Pen(colour);
217   to_win->SetCursor(fleft, (float) ybottom);
218   for (line_index = min_y; line_index <= max_y; line_index++) {
219      to_win->DrawTo(fleft + thresholds[line_index - min_y] / 10.0,      (float) line_index);
220   }
221 }
222 
223 
224 /**********************************************************************
225  * draw_meanlines
226  *
227  * Draw the meanlines of the given block in the given colour.
228  **********************************************************************/
229 
draw_meanlines(TO_BLOCK * block,float gradient,inT32 left,ScrollView::Color colour,FCOORD rotation)230 void draw_meanlines(                  //draw a block
231                     TO_BLOCK *block,  //block to draw
232                     float gradient,   //gradients of lines
233                     inT32 left,       //edge of block
234                     ScrollView::Color colour,    //colour to draw in
235                     FCOORD rotation   //rotation for line
236                    ) {
237   FCOORD plot_pt;                //point to plot
238                                  //rows
239   TO_ROW_IT row_it = block->get_rows ();
240   TO_ROW *row;                   //current row
241   BLOBNBOX_IT blob_it;           //blobs
242   float right;                   //end of row
243   to_win->Pen(colour);
244   for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
245     row = row_it.data ();
246     blob_it.set_to_list (row->blob_list ());
247     blob_it.move_to_last ();
248     right = blob_it.data ()->bounding_box ().right ();
249     plot_pt =
250       FCOORD ((float) left,
251       gradient * left + row->parallel_c () + row->xheight);
252     plot_pt.rotate (rotation);
253   to_win->SetCursor(plot_pt.x (), plot_pt.y ());
254     plot_pt =
255       FCOORD ((float) right,
256       gradient * right + row->parallel_c () + row->xheight);
257     plot_pt.rotate (rotation);
258     to_win->DrawTo (plot_pt.x (), plot_pt.y ());
259   }
260 }
261 
262 
263 /**********************************************************************
264  * plot_word_decisions
265  *
266  * Plot a row with words in different colours and fuzzy spaces
267  * highlighted.
268  **********************************************************************/
269 
plot_word_decisions(ScrollView * win,inT16 pitch,TO_ROW * row)270 void plot_word_decisions(              //draw words
271                          ScrollView* win,   //window tro draw in
272                          inT16 pitch,  //of block
273                          TO_ROW *row   //row to draw
274                         ) {
275   ScrollView::Color colour = ScrollView::MAGENTA;       //current colour
276   ScrollView::Color rect_colour;            //fuzzy colour
277   inT32 prev_x;                  //end of prev blob
278   inT16 blob_count;              //blobs in word
279   BLOBNBOX *blob;                //current blob
280   TBOX blob_box;                  //bounding box
281                                  //iterator
282   BLOBNBOX_IT blob_it = row->blob_list ();
283   BLOBNBOX_IT start_it = blob_it;//word start
284 
285   rect_colour = ScrollView::BLACK;
286   prev_x = -MAX_INT16;
287   blob_count = 0;
288   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
289     blob = blob_it.data ();
290     blob_box = blob->bounding_box ();
291     if (!blob->joined_to_prev ()
292     && blob_box.left () - prev_x > row->max_nonspace) {
293       if ((blob_box.left () - prev_x >= row->min_space
294         || blob_box.left () - prev_x > row->space_threshold)
295       && blob_count > 0) {
296         if (pitch > 0 && textord_show_fixed_cuts)
297           plot_fp_cells (win, colour, &start_it, pitch, blob_count,
298             &row->projection, row->projection_left,
299             row->projection_right,
300             row->xheight * textord_projection_scale);
301         blob_count = 0;
302         start_it = blob_it;
303       }
304       if (colour == ScrollView::MAGENTA)
305         colour = ScrollView::RED;
306       else
307         colour = (ScrollView::Color) (colour + 1);
308       if (blob_box.left () - prev_x < row->min_space) {
309         if (blob_box.left () - prev_x > row->space_threshold)
310           rect_colour = ScrollView::GOLDENROD;
311         else
312           rect_colour = ScrollView::CORAL;
313         //fill_color_index(win, rect_colour);
314         win->Brush(rect_colour);
315         win->Rectangle (prev_x, blob_box.bottom (),
316           blob_box.left (), blob_box.top ());
317       }
318     }
319     if (!blob->joined_to_prev ())
320       prev_x = blob_box.right ();
321     if (blob->blob () != NULL)
322                                  //draw it
323       blob->blob ()->plot (win, colour, colour);
324     if (blob->cblob () != NULL)
325       blob->cblob ()->plot (win, colour, colour);
326     if (!blob->joined_to_prev ()
327       && (blob->blob () != NULL || blob->cblob () != NULL))
328       blob_count++;
329   }
330   if (pitch > 0 && textord_show_fixed_cuts && blob_count > 0)
331     plot_fp_cells (win, colour, &start_it, pitch, blob_count,
332       &row->projection, row->projection_left,
333       row->projection_right,
334       row->xheight * textord_projection_scale);
335 }
336 
337 
338 /**********************************************************************
339  * plot_fp_cells
340  *
341  * Make a list of fixed pitch cuts and draw them.
342  **********************************************************************/
343 
plot_fp_cells(ScrollView * win,ScrollView::Color colour,BLOBNBOX_IT * blob_it,inT16 pitch,inT16 blob_count,STATS * projection,inT16 projection_left,inT16 projection_right,float projection_scale)344 void plot_fp_cells(                        //draw words
345                    ScrollView* win,             //window tro draw in
346                    ScrollView::Color colour,          //colour of lines
347                    BLOBNBOX_IT *blob_it,   //blobs
348                    inT16 pitch,            //of block
349                    inT16 blob_count,       //no of real blobs
350                    STATS *projection,      //vertical
351                    inT16 projection_left,  //edges //scale factor
352                    inT16 projection_right,
353                    float projection_scale) {
354   inT16 occupation;              //occupied cells
355   TBOX word_box;                  //bounding box
356   FPSEGPT_LIST seg_list;         //list of cuts
357   FPSEGPT_IT seg_it;
358   FPSEGPT *segpt;                //current point
359 
360   if (pitsync_linear_version)
361     check_pitch_sync2 (blob_it, blob_count, pitch, 2, projection,
362       projection_left, projection_right,
363       projection_scale, occupation, &seg_list, 0, 0);
364   else
365     check_pitch_sync (blob_it, blob_count, pitch, 2, projection, &seg_list);
366   word_box = blob_it->data ()->bounding_box ();
367   for (; blob_count > 0; blob_count--)
368     word_box += box_next (blob_it);
369   seg_it.set_to_list (&seg_list);
370   for (seg_it.mark_cycle_pt (); !seg_it.cycled_list (); seg_it.forward ()) {
371     segpt = seg_it.data ();
372     if (segpt->faked) {
373          colour = ScrollView::WHITE;
374          win->Pen(colour);  }
375     else {
376       win->Pen(colour); }
377     win->Line(segpt->position (), word_box.bottom (),segpt->position (), word_box.top ());
378   }
379 }
380 
381 
382 /**********************************************************************
383  * plot_fp_cells2
384  *
385  * Make a list of fixed pitch cuts and draw them.
386  **********************************************************************/
387 
plot_fp_cells2(ScrollView * win,ScrollView::Color colour,TO_ROW * row,FPSEGPT_LIST * seg_list)388 void plot_fp_cells2(                        //draw words
389                     ScrollView* win,             //window tro draw in
390                     ScrollView::Color colour,          //colour of lines
391                     TO_ROW *row,            //for location
392                     FPSEGPT_LIST *seg_list  //segments to plot
393                    ) {
394   TBOX word_box;                  //bounding box
395   FPSEGPT_IT seg_it = seg_list;
396                                  //blobs in row
397   BLOBNBOX_IT blob_it = row->blob_list ();
398   FPSEGPT *segpt;                //current point
399 
400   word_box = blob_it.data ()->bounding_box ();
401   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();)
402     word_box += box_next (&blob_it);
403   for (seg_it.mark_cycle_pt (); !seg_it.cycled_list (); seg_it.forward ()) {
404     segpt = seg_it.data ();
405     if (segpt->faked) {
406          colour = ScrollView::WHITE;
407          win->Pen(colour); }
408     else {
409      win->Pen(colour); }
410      win->Line(segpt->position (), word_box.bottom (),segpt->position (), word_box.top ());
411   }
412 }
413 
414 
415 /**********************************************************************
416  * plot_row_cells
417  *
418  * Make a list of fixed pitch cuts and draw them.
419  **********************************************************************/
420 
plot_row_cells(ScrollView * win,ScrollView::Color colour,TO_ROW * row,float xshift,ICOORDELT_LIST * cells)421 void plot_row_cells(                       //draw words
422                     ScrollView* win,            //window tro draw in
423                     ScrollView::Color colour,         //colour of lines
424                     TO_ROW *row,           //for location
425                     float xshift,          //amount of shift
426                     ICOORDELT_LIST *cells  //cells to draw
427                    ) {
428   TBOX word_box;                  //bounding box
429   ICOORDELT_IT cell_it = cells;
430                                  //blobs in row
431   BLOBNBOX_IT blob_it = row->blob_list ();
432   ICOORDELT *cell;               //current cell
433 
434   word_box = blob_it.data ()->bounding_box ();
435   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();)
436     word_box += box_next (&blob_it);
437   win->Pen(colour);
438   for (cell_it.mark_cycle_pt (); !cell_it.cycled_list (); cell_it.forward ()) {
439     cell = cell_it.data ();
440     win->Line(cell->x () + xshift, word_box.bottom (), cell->x () + xshift, word_box.top ());
441   }
442 }
443 
444 #endif  // GRAPHICS_DISABLED
445 
446