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