Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
drawtord.cpp
Go to the documentation of this file.
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
25 // Include automatically generated configuration file if running autoconf.
26 #ifdef HAVE_CONFIG_H
27 #include "config_auto.h"
28 #endif
29
30 #define TO_WIN_XPOS 0 //default window pos
31 #define TO_WIN_YPOS 0
32 #define TO_WIN_NAME "Textord"
33 //title of window
34
35 #define EXTERN
36
37 EXTERN BOOL_VAR (textord_show_fixed_cuts, FALSE,
38 "Draw fixed pitch cell boundaries");
39
40 EXTERN ScrollView* to_win = NULL;
41
42 /**********************************************************************
43 * create_to_win
44 *
45 * Create the to window used to show the fit.
46 **********************************************************************/
47 #ifndef GRAPHICS_DISABLED
48
49 void create_to_win(ICOORD page_tr) {
50 to_win = new ScrollView(TO_WIN_NAME, TO_WIN_XPOS, TO_WIN_YPOS,
51 page_tr.x() + 1, page_tr.y() + 1,
52 page_tr.x(), page_tr.y(), true);
53 }
54
55
56 void close_to_win() {
57 // to_win is leaked, but this enables the user to view the contents.
58 if (to_win != NULL) {
59 to_win->Update();
60 }
61 }
62
63
64 /**********************************************************************
65 * plot_box_list
66 *
67 * Draw a list of blobs.
68 **********************************************************************/
69
70 void plot_box_list( //make gradients win
71 ScrollView* win, //window to draw in
72 BLOBNBOX_LIST *list, //blob list
73 ScrollView::Color body_colour //colour to draw
74 ) {
75 BLOBNBOX_IT it = list; //iterator
76
77 win->Pen(body_colour);
78 win->Brush(ScrollView::NONE);
79 for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
80 it.data ()->bounding_box ().plot (win);
81 }
82 }
83
84
85 /**********************************************************************
86 * plot_to_row
87 *
88 * Draw the blobs of a row in a given colour and draw the line fit.
89 **********************************************************************/
90
91 void plot_to_row( //draw a row
92 TO_ROW *row, //row to draw
93 ScrollView::Color colour, //colour to draw in
94 FCOORD rotation //rotation for line
95 ) {
96 FCOORD plot_pt; //point to plot
97 //blobs
98 BLOBNBOX_IT it = row->blob_list ();
99 float left, right; //end of row
100
101 if (it.empty ()) {
102 tprintf ("No blobs in row at %g\n", row->parallel_c ());
103 return;
104 }
105 left = it.data ()->bounding_box ().left ();
106 it.move_to_last ();
107 right = it.data ()->bounding_box ().right ();
108 plot_blob_list (to_win, row->blob_list (), colour, ScrollView::BROWN);
109 to_win->Pen(colour);
110 plot_pt = FCOORD (left, row->line_m () * left + row->line_c ());
111 plot_pt.rotate (rotation);
112 to_win->SetCursor(plot_pt.x (), plot_pt.y ());
113 plot_pt = FCOORD (right, row->line_m () * right + row->line_c ());
114 plot_pt.rotate (rotation);
115 to_win->DrawTo(plot_pt.x (), plot_pt.y ());
116 }
117
118
119 /**********************************************************************
120 * plot_parallel_row
121 *
122 * Draw the blobs of a row in a given colour and draw the line fit.
123 **********************************************************************/
124
125 void plot_parallel_row( //draw a row
126 TO_ROW *row, //row to draw
127 float gradient, //gradients of lines
128 inT32 left, //edge of block
129 ScrollView::Color colour, //colour to draw in
130 FCOORD rotation //rotation for line
131 ) {
132 FCOORD plot_pt; //point to plot
133 //blobs
134 BLOBNBOX_IT it = row->blob_list ();
135 float fleft = (float) left; //floating version
136 float right; //end of row
137
138 // left=it.data()->bounding_box().left();
139 it.move_to_last ();
140 right = it.data ()->bounding_box ().right ();
141 plot_blob_list (to_win, row->blob_list (), colour, ScrollView::BROWN);
142 to_win->Pen(colour);
143 plot_pt = FCOORD (fleft, gradient * left + row->max_y ());
144 plot_pt.rotate (rotation);
145 to_win->SetCursor(plot_pt.x (), plot_pt.y ());
146 plot_pt = FCOORD (fleft, gradient * left + row->min_y ());
147 plot_pt.rotate (rotation);
148 to_win->DrawTo(plot_pt.x (), plot_pt.y ());
149 plot_pt = FCOORD (fleft, gradient * left + row->parallel_c ());
150 plot_pt.rotate (rotation);
151 to_win->SetCursor(plot_pt.x (), plot_pt.y ());
152 plot_pt = FCOORD (right, gradient * right + row->parallel_c ());
153 plot_pt.rotate (rotation);
154 to_win->DrawTo(plot_pt.x (), plot_pt.y ());
155 }
156
157
158 /**********************************************************************
159 * draw_occupation
160 *
161 * Draw the row occupation with points above the threshold in white
162 * and points below the threshold in black.
163 **********************************************************************/
164
165 void
166 draw_occupation ( //draw projection
167 inT32 xleft, //edge of block
168 inT32 ybottom, //bottom of block
169 inT32 min_y, //coordinate limits
170 inT32 max_y, inT32 occupation[], //projection counts
171 inT32 thresholds[] //for drop out
172 ) {
173 inT32 line_index; //pixel coord
174 ScrollView::Color colour; //of histogram
175 float fleft = (float) xleft; //float version
176
177 colour = ScrollView::WHITE;
178 to_win->Pen(colour);
179 to_win->SetCursor(fleft, (float) ybottom);
180 for (line_index = min_y; line_index <= max_y; line_index++) {
181 if (occupation[line_index - min_y] < thresholds[line_index - min_y]) {
182 if (colour != ScrollView::BLUE) {
183 colour = ScrollView::BLUE;
184 to_win->Pen(colour);
185 }
186 }
187 else {
188 if (colour != ScrollView::WHITE) {
189 colour = ScrollView::WHITE;
190 to_win->Pen(colour);
191 }
192 }
193 to_win->DrawTo(fleft + occupation[line_index - min_y] / 10.0, (float) line_index);
194 }
195 colour=ScrollView::STEEL_BLUE;
196 to_win->Pen(colour);
197 to_win->SetCursor(fleft, (float) ybottom);
198 for (line_index = min_y; line_index <= max_y; line_index++) {
199 to_win->DrawTo(fleft + thresholds[line_index - min_y] / 10.0, (float) line_index);
200 }
201 }
202
203
204 /**********************************************************************
205 * draw_meanlines
206 *
207 * Draw the meanlines of the given block in the given colour.
208 **********************************************************************/
209
210 void draw_meanlines( //draw a block
211 TO_BLOCK *block, //block to draw
212 float gradient, //gradients of lines
213 inT32 left, //edge of block
214 ScrollView::Color colour, //colour to draw in
215 FCOORD rotation //rotation for line
216 ) {
217 FCOORD plot_pt; //point to plot
218 //rows
219 TO_ROW_IT row_it = block->get_rows ();
220 TO_ROW *row; //current row
221 BLOBNBOX_IT blob_it; //blobs
222 float right; //end of row
223 to_win->Pen(colour);
224 for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
225 row = row_it.data ();
226 blob_it.set_to_list (row->blob_list ());
227 blob_it.move_to_last ();
228 right = blob_it.data ()->bounding_box ().right ();
229 plot_pt =
230 FCOORD ((float) left,
231 gradient * left + row->parallel_c () + row->xheight);
232 plot_pt.rotate (rotation);
233 to_win->SetCursor(plot_pt.x (), plot_pt.y ());
234 plot_pt =
235 FCOORD ((float) right,
236 gradient * right + row->parallel_c () + row->xheight);
237 plot_pt.rotate (rotation);
238 to_win->DrawTo (plot_pt.x (), plot_pt.y ());
239 }
240 }
241
242
243 /**********************************************************************
244 * plot_word_decisions
245 *
246 * Plot a row with words in different colours and fuzzy spaces
247 * highlighted.
248 **********************************************************************/
249
250 void plot_word_decisions( //draw words
251 ScrollView* win, //window tro draw in
252 inT16 pitch, //of block
253 TO_ROW *row //row to draw
254 ) {
255 ScrollView::Color colour = ScrollView::MAGENTA; //current colour
256 ScrollView::Color rect_colour; //fuzzy colour
257 inT32 prev_x; //end of prev blob
258 inT16 blob_count; //blobs in word
259 BLOBNBOX *blob; //current blob
260 TBOX blob_box; //bounding box
261 //iterator
262 BLOBNBOX_IT blob_it = row->blob_list ();
263 BLOBNBOX_IT start_it = blob_it;//word start
264
265 rect_colour = ScrollView::BLACK;
266 prev_x = -MAX_INT16;
267 blob_count = 0;
268 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
269 blob = blob_it.data ();
270 blob_box = blob->bounding_box ();
271 if (!blob->joined_to_prev ()
272 && blob_box.left () - prev_x > row->max_nonspace) {
273 if ((blob_box.left () - prev_x >= row->min_space
274 || blob_box.left () - prev_x > row->space_threshold)
275 && blob_count > 0) {
276 if (pitch > 0 && textord_show_fixed_cuts)
277 plot_fp_cells (win, colour, &start_it, pitch, blob_count,
278 &row->projection, row->projection_left,
279 row->projection_right,
280 row->xheight * textord_projection_scale);
281 blob_count = 0;
282 start_it = blob_it;
283 }
284 if (colour == ScrollView::MAGENTA)
285 colour = ScrollView::RED;
286 else
287 colour = (ScrollView::Color) (colour + 1);
288 if (blob_box.left () - prev_x < row->min_space) {
289 if (blob_box.left () - prev_x > row->space_threshold)
290 rect_colour = ScrollView::GOLDENROD;
291 else
292 rect_colour = ScrollView::CORAL;
293 //fill_color_index(win, rect_colour);
294 win->Brush(rect_colour);
295 win->Rectangle (prev_x, blob_box.bottom (),
296 blob_box.left (), blob_box.top ());
297 }
298 }
299 if (!blob->joined_to_prev())
300 prev_x = blob_box.right();
301 if (blob->cblob () != NULL)
302 blob->cblob ()->plot (win, colour, colour);
303 if (!blob->joined_to_prev() && blob->cblob() != NULL)
304 blob_count++;
305 }
306 if (pitch > 0 && textord_show_fixed_cuts && blob_count > 0)
307 plot_fp_cells (win, colour, &start_it, pitch, blob_count,
308 &row->projection, row->projection_left,
309 row->projection_right,
310 row->xheight * textord_projection_scale);
311 }
312
313
314 /**********************************************************************
315 * plot_fp_cells
316 *
317 * Make a list of fixed pitch cuts and draw them.
318 **********************************************************************/
319
320 void plot_fp_cells( //draw words
321 ScrollView* win, //window tro draw in
322 ScrollView::Color colour, //colour of lines
323 BLOBNBOX_IT *blob_it, //blobs
324 inT16 pitch, //of block
325 inT16 blob_count, //no of real blobs
326 STATS *projection, //vertical
327 inT16 projection_left, //edges //scale factor
328 inT16 projection_right,
329 float projection_scale) {
330 inT16 occupation; //occupied cells
331 TBOX word_box; //bounding box
332 FPSEGPT_LIST seg_list; //list of cuts
333 FPSEGPT_IT seg_it;
334 FPSEGPT *segpt; //current point
335
336 if (pitsync_linear_version)
337 check_pitch_sync2 (blob_it, blob_count, pitch, 2, projection,
338 projection_left, projection_right,
339 projection_scale, occupation, &seg_list, 0, 0);
340 else
341 check_pitch_sync (blob_it, blob_count, pitch, 2, projection, &seg_list);
342 word_box = blob_it->data ()->bounding_box ();
343 for (; blob_count > 0; blob_count--)
344 word_box += box_next (blob_it);
345 seg_it.set_to_list (&seg_list);
346 for (seg_it.mark_cycle_pt (); !seg_it.cycled_list (); seg_it.forward ()) {
347 segpt = seg_it.data ();
348 if (segpt->faked) {
349 colour = ScrollView::WHITE;
350 win->Pen(colour); }
351 else {
352 win->Pen(colour); }
353 win->Line(segpt->position (), word_box.bottom (),segpt->position (), word_box.top ());
354 }
355 }
356
357
358 /**********************************************************************
359 * plot_fp_cells2
360 *
361 * Make a list of fixed pitch cuts and draw them.
362 **********************************************************************/
363
364 void plot_fp_cells2( //draw words
365 ScrollView* win, //window tro draw in
366 ScrollView::Color colour, //colour of lines
367 TO_ROW *row, //for location
368 FPSEGPT_LIST *seg_list //segments to plot
369 ) {
370 TBOX word_box; //bounding box
371 FPSEGPT_IT seg_it = seg_list;
372 //blobs in row
373 BLOBNBOX_IT blob_it = row->blob_list ();
374 FPSEGPT *segpt; //current point
375
376 word_box = blob_it.data ()->bounding_box ();
377 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();)
378 word_box += box_next (&blob_it);
379 for (seg_it.mark_cycle_pt (); !seg_it.cycled_list (); seg_it.forward ()) {
380 segpt = seg_it.data ();
381 if (segpt->faked) {
382 colour = ScrollView::WHITE;
383 win->Pen(colour); }
384 else {
385 win->Pen(colour); }
386 win->Line(segpt->position (), word_box.bottom (),segpt->position (), word_box.top ());
387 }
388 }
389
390
391 /**********************************************************************
392 * plot_row_cells
393 *
394 * Make a list of fixed pitch cuts and draw them.
395 **********************************************************************/
396
397 void plot_row_cells( //draw words
398 ScrollView* win, //window tro draw in
399 ScrollView::Color colour, //colour of lines
400 TO_ROW *row, //for location
401 float xshift, //amount of shift
402 ICOORDELT_LIST *cells //cells to draw
403 ) {
404 TBOX word_box; //bounding box
405 ICOORDELT_IT cell_it = cells;
406 //blobs in row
407 BLOBNBOX_IT blob_it = row->blob_list ();
408 ICOORDELT *cell; //current cell
409
410 word_box = blob_it.data ()->bounding_box ();
411 for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();)
412 word_box += box_next (&blob_it);
413 win->Pen(colour);
414 for (cell_it.mark_cycle_pt (); !cell_it.cycled_list (); cell_it.forward ()) {
415 cell = cell_it.data ();
416 win->Line(cell->x () + xshift, word_box.bottom (), cell->x () + xshift, word_box.top ());
417 }
418 }
419
420 #endif // GRAPHICS_DISABLED
421