tesseract  5.0.0
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  *
6  * (C) Copyright 1992, Hewlett-Packard Ltd.
7  ** Licensed under the Apache License, Version 2.0 (the "License");
8  ** you may not use this file except in compliance with the License.
9  ** You may obtain a copy of the License at
10  ** http://www.apache.org/licenses/LICENSE-2.0
11  ** Unless required by applicable law or agreed to in writing, software
12  ** distributed under the License is distributed on an "AS IS" BASIS,
13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  ** See the License for the specific language governing permissions and
15  ** limitations under the License.
16  *
17  **********************************************************************/
18 
19 #ifdef HAVE_CONFIG_H
20 # include "config_auto.h"
21 #endif
22 
23 #include "drawtord.h"
24 
25 #include "pithsync.h"
26 #include "topitch.h"
27 
28 namespace tesseract {
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 BOOL_VAR(textord_show_fixed_cuts, false, "Draw fixed pitch cell boundaries");
36 
37 ScrollView *to_win = nullptr;
38 
39 #ifndef GRAPHICS_DISABLED
40 
41 /**********************************************************************
42  * create_to_win
43  *
44  * Create the to window used to show the fit.
45  **********************************************************************/
46 
48  if (to_win != nullptr) {
49  return to_win;
50  }
51  to_win = new ScrollView(TO_WIN_NAME, TO_WIN_XPOS, TO_WIN_YPOS, page_tr.x() + 1, page_tr.y() + 1,
52  page_tr.x(), page_tr.y(), true);
53  return to_win;
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 != nullptr) {
59  to_win->Update();
60  }
61 }
62 
63 /**********************************************************************
64  * plot_box_list
65  *
66  * Draw a list of blobs.
67  **********************************************************************/
68 
69 void plot_box_list( // make gradients win
70  ScrollView *win, // window to draw in
71  BLOBNBOX_LIST *list, // blob list
72  ScrollView::Color body_colour // colour to draw
73 ) {
74  BLOBNBOX_IT it = list; // iterator
75 
76  win->Pen(body_colour);
77  win->Brush(ScrollView::NONE);
78  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
79  it.data()->bounding_box().plot(win);
80  }
81 }
82 
83 /**********************************************************************
84  * plot_to_row
85  *
86  * Draw the blobs of a row in a given colour and draw the line fit.
87  **********************************************************************/
88 
89 void plot_to_row( // draw a row
90  TO_ROW *row, // row to draw
91  ScrollView::Color colour, // colour to draw in
92  FCOORD rotation // rotation for line
93 ) {
94  FCOORD plot_pt; // point to plot
95  // blobs
96  BLOBNBOX_IT it = row->blob_list();
97  float left, right; // end of row
98 
99  if (it.empty()) {
100  tprintf("No blobs in row at %g\n", row->parallel_c());
101  return;
102  }
103  left = it.data()->bounding_box().left();
104  it.move_to_last();
105  right = it.data()->bounding_box().right();
107  to_win->Pen(colour);
108  plot_pt = FCOORD(left, row->line_m() * left + row->line_c());
109  plot_pt.rotate(rotation);
110  to_win->SetCursor(plot_pt.x(), plot_pt.y());
111  plot_pt = FCOORD(right, row->line_m() * right + row->line_c());
112  plot_pt.rotate(rotation);
113  to_win->DrawTo(plot_pt.x(), plot_pt.y());
114 }
115 
116 /**********************************************************************
117  * plot_parallel_row
118  *
119  * Draw the blobs of a row in a given colour and draw the line fit.
120  **********************************************************************/
121 
122 void plot_parallel_row( // draw a row
123  TO_ROW *row, // row to draw
124  float gradient, // gradients of lines
125  int32_t left, // edge of block
126  ScrollView::Color colour, // colour to draw in
127  FCOORD rotation // rotation for line
128 ) {
129  FCOORD plot_pt; // point to plot
130  // blobs
131  BLOBNBOX_IT it = row->blob_list();
132  auto fleft = static_cast<float>(left); // floating version
133  float right; // end of row
134 
135  // left=it.data()->bounding_box().left();
136  it.move_to_last();
137  right = it.data()->bounding_box().right();
139  to_win->Pen(colour);
140  plot_pt = FCOORD(fleft, gradient * left + row->max_y());
141  plot_pt.rotate(rotation);
142  to_win->SetCursor(plot_pt.x(), plot_pt.y());
143  plot_pt = FCOORD(fleft, gradient * left + row->min_y());
144  plot_pt.rotate(rotation);
145  to_win->DrawTo(plot_pt.x(), plot_pt.y());
146  plot_pt = FCOORD(fleft, gradient * left + row->parallel_c());
147  plot_pt.rotate(rotation);
148  to_win->SetCursor(plot_pt.x(), plot_pt.y());
149  plot_pt = FCOORD(right, gradient * right + row->parallel_c());
150  plot_pt.rotate(rotation);
151  to_win->DrawTo(plot_pt.x(), plot_pt.y());
152 }
153 
154 /**********************************************************************
155  * draw_occupation
156  *
157  * Draw the row occupation with points above the threshold in white
158  * and points below the threshold in black.
159  **********************************************************************/
160 
161 void draw_occupation( // draw projection
162  int32_t xleft, // edge of block
163  int32_t ybottom, // bottom of block
164  int32_t min_y, // coordinate limits
165  int32_t max_y, int32_t occupation[], // projection counts
166  int32_t thresholds[] // for drop out
167 ) {
168  int32_t line_index; // pixel coord
169  ScrollView::Color colour; // of histogram
170  auto fleft = static_cast<float>(xleft); // float version
171 
172  colour = ScrollView::WHITE;
173  to_win->Pen(colour);
174  to_win->SetCursor(fleft, static_cast<float>(ybottom));
175  for (line_index = min_y; line_index <= max_y; line_index++) {
176  if (occupation[line_index - min_y] < thresholds[line_index - min_y]) {
177  if (colour != ScrollView::BLUE) {
178  colour = ScrollView::BLUE;
179  to_win->Pen(colour);
180  }
181  } else {
182  if (colour != ScrollView::WHITE) {
183  colour = ScrollView::WHITE;
184  to_win->Pen(colour);
185  }
186  }
187  to_win->DrawTo(fleft + occupation[line_index - min_y] / 10.0, static_cast<float>(line_index));
188  }
189  colour = ScrollView::STEEL_BLUE;
190  to_win->Pen(colour);
191  to_win->SetCursor(fleft, static_cast<float>(ybottom));
192  for (line_index = min_y; line_index <= max_y; line_index++) {
193  to_win->DrawTo(fleft + thresholds[line_index - min_y] / 10.0, static_cast<float>(line_index));
194  }
195 }
196 
197 /**********************************************************************
198  * draw_meanlines
199  *
200  * Draw the meanlines of the given block in the given colour.
201  **********************************************************************/
202 
203 void draw_meanlines( // draw a block
204  TO_BLOCK *block, // block to draw
205  float gradient, // gradients of lines
206  int32_t left, // edge of block
207  ScrollView::Color colour, // colour to draw in
208  FCOORD rotation // rotation for line
209 ) {
210  FCOORD plot_pt; // point to plot
211  // rows
212  TO_ROW_IT row_it = block->get_rows();
213  TO_ROW *row; // current row
214  BLOBNBOX_IT blob_it; // blobs
215  float right; // end of row
216  to_win->Pen(colour);
217  for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
218  row = row_it.data();
219  blob_it.set_to_list(row->blob_list());
220  blob_it.move_to_last();
221  right = blob_it.data()->bounding_box().right();
222  plot_pt = FCOORD(static_cast<float>(left), gradient * left + row->parallel_c() + row->xheight);
223  plot_pt.rotate(rotation);
224  to_win->SetCursor(plot_pt.x(), plot_pt.y());
225  plot_pt = FCOORD(right, gradient * right + row->parallel_c() + row->xheight);
226  plot_pt.rotate(rotation);
227  to_win->DrawTo(plot_pt.x(), plot_pt.y());
228  }
229 }
230 
231 /**********************************************************************
232  * plot_word_decisions
233  *
234  * Plot a row with words in different colours and fuzzy spaces
235  * highlighted.
236  **********************************************************************/
237 
238 void plot_word_decisions( // draw words
239  ScrollView *win, // window tro draw in
240  int16_t pitch, // of block
241  TO_ROW *row // row to draw
242 ) {
243  ScrollView::Color colour = ScrollView::MAGENTA; // current colour
244  ScrollView::Color rect_colour; // fuzzy colour
245  int32_t prev_x; // end of prev blob
246  int16_t blob_count; // blobs in word
247  BLOBNBOX *blob; // current blob
248  TBOX blob_box; // bounding box
249  // iterator
250  BLOBNBOX_IT blob_it = row->blob_list();
251  BLOBNBOX_IT start_it = blob_it; // word start
252 
253  rect_colour = ScrollView::BLACK;
254  prev_x = -INT16_MAX;
255  blob_count = 0;
256  for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
257  blob = blob_it.data();
258  blob_box = blob->bounding_box();
259  if (!blob->joined_to_prev() && blob_box.left() - prev_x > row->max_nonspace) {
260  if ((blob_box.left() - prev_x >= row->min_space ||
261  blob_box.left() - prev_x > row->space_threshold) &&
262  blob_count > 0) {
263  if (pitch > 0 && textord_show_fixed_cuts) {
264  plot_fp_cells(win, colour, &start_it, pitch, blob_count, &row->projection,
267  }
268  blob_count = 0;
269  start_it = blob_it;
270  }
271  if (colour == ScrollView::MAGENTA) {
272  colour = ScrollView::RED;
273  } else {
274  colour = static_cast<ScrollView::Color>(colour + 1);
275  }
276  if (blob_box.left() - prev_x < row->min_space) {
277  if (blob_box.left() - prev_x > row->space_threshold) {
278  rect_colour = ScrollView::GOLDENROD;
279  } else {
280  rect_colour = ScrollView::CORAL;
281  }
282  // fill_color_index(win, rect_colour);
283  win->Brush(rect_colour);
284  win->Rectangle(prev_x, blob_box.bottom(), blob_box.left(), blob_box.top());
285  }
286  }
287  if (!blob->joined_to_prev()) {
288  prev_x = blob_box.right();
289  }
290  if (blob->cblob() != nullptr) {
291  blob->cblob()->plot(win, colour, colour);
292  }
293  if (!blob->joined_to_prev() && blob->cblob() != nullptr) {
294  blob_count++;
295  }
296  }
297  if (pitch > 0 && textord_show_fixed_cuts && blob_count > 0) {
298  plot_fp_cells(win, colour, &start_it, pitch, blob_count, &row->projection, row->projection_left,
300  }
301 }
302 
303 /**********************************************************************
304  * plot_fp_cells
305  *
306  * Make a list of fixed pitch cuts and draw them.
307  **********************************************************************/
308 
309 void plot_fp_cells( // draw words
310  ScrollView *win, // window tro draw in
311  ScrollView::Color colour, // colour of lines
312  BLOBNBOX_IT *blob_it, // blobs
313  int16_t pitch, // of block
314  int16_t blob_count, // no of real blobs
315  STATS *projection, // vertical
316  int16_t projection_left, // edges //scale factor
317  int16_t projection_right, float projection_scale) {
318  int16_t occupation; // occupied cells
319  TBOX word_box; // bounding box
320  FPSEGPT_LIST seg_list; // list of cuts
321  FPSEGPT_IT seg_it;
322  FPSEGPT *segpt; // current point
323 
325  check_pitch_sync2(blob_it, blob_count, pitch, 2, projection, projection_left, projection_right,
326  projection_scale, occupation, &seg_list, 0, 0);
327  } else {
328  check_pitch_sync(blob_it, blob_count, pitch, 2, projection, &seg_list);
329  }
330  word_box = blob_it->data()->bounding_box();
331  for (; blob_count > 0; blob_count--) {
332  word_box += box_next(blob_it);
333  }
334  seg_it.set_to_list(&seg_list);
335  for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
336  segpt = seg_it.data();
337  if (segpt->faked) {
338  colour = ScrollView::WHITE;
339  win->Pen(colour);
340  } else {
341  win->Pen(colour);
342  }
343  win->Line(segpt->position(), word_box.bottom(), segpt->position(), word_box.top());
344  }
345 }
346 
347 /**********************************************************************
348  * plot_fp_cells2
349  *
350  * Make a list of fixed pitch cuts and draw them.
351  **********************************************************************/
352 
353 void plot_fp_cells2( // draw words
354  ScrollView *win, // window tro draw in
355  ScrollView::Color colour, // colour of lines
356  TO_ROW *row, // for location
357  FPSEGPT_LIST *seg_list // segments to plot
358 ) {
359  TBOX word_box; // bounding box
360  FPSEGPT_IT seg_it = seg_list;
361  // blobs in row
362  BLOBNBOX_IT blob_it = row->blob_list();
363  FPSEGPT *segpt; // current point
364 
365  word_box = blob_it.data()->bounding_box();
366  for (blob_it.mark_cycle_pt(); !blob_it.cycled_list();) {
367  word_box += box_next(&blob_it);
368  }
369  for (seg_it.mark_cycle_pt(); !seg_it.cycled_list(); seg_it.forward()) {
370  segpt = seg_it.data();
371  if (segpt->faked) {
372  colour = ScrollView::WHITE;
373  win->Pen(colour);
374  } else {
375  win->Pen(colour);
376  }
377  win->Line(segpt->position(), word_box.bottom(), segpt->position(), word_box.top());
378  }
379 }
380 
381 /**********************************************************************
382  * plot_row_cells
383  *
384  * Make a list of fixed pitch cuts and draw them.
385  **********************************************************************/
386 
387 void plot_row_cells( // draw words
388  ScrollView *win, // window tro draw in
389  ScrollView::Color colour, // colour of lines
390  TO_ROW *row, // for location
391  float xshift, // amount of shift
392  ICOORDELT_LIST *cells // cells to draw
393 ) {
394  TBOX word_box; // bounding box
395  ICOORDELT_IT cell_it = cells;
396  // blobs in row
397  BLOBNBOX_IT blob_it = row->blob_list();
398  ICOORDELT *cell; // current cell
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  }
404  win->Pen(colour);
405  for (cell_it.mark_cycle_pt(); !cell_it.cycled_list(); cell_it.forward()) {
406  cell = cell_it.data();
407  win->Line(cell->x() + xshift, word_box.bottom(), cell->x() + xshift, word_box.top());
408  }
409 }
410 
411 #endif // !GRAPHICS_DISABLED
412 
413 } // namespace tesseract
#define BOOL_VAR(name, val, comment)
Definition: params.h:359
#define TO_WIN_YPOS
Definition: drawtord.cpp:31
#define TO_WIN_NAME
Definition: drawtord.cpp:32
#define TO_WIN_XPOS
Definition: drawtord.cpp:30
void plot_fp_cells(ScrollView *win, ScrollView::Color colour, BLOBNBOX_IT *blob_it, int16_t pitch, int16_t blob_count, STATS *projection, int16_t projection_left, int16_t projection_right, float projection_scale)
Definition: drawtord.cpp:309
void plot_fp_cells2(ScrollView *win, ScrollView::Color colour, TO_ROW *row, FPSEGPT_LIST *seg_list)
Definition: drawtord.cpp:353
void tprintf(const char *format,...)
Definition: tprintf.cpp:41
bool textord_show_fixed_cuts
Definition: drawtord.cpp:35
int pitsync_linear_version
Definition: pitsync1.cpp:26
ScrollView * to_win
Definition: drawtord.cpp:37
void close_to_win()
Definition: drawtord.cpp:56
double textord_projection_scale
Definition: topitch.cpp:49
void plot_blob_list(ScrollView *win, BLOBNBOX_LIST *list, ScrollView::Color body_colour, ScrollView::Color child_colour)
Definition: blobbox.cpp:1071
double check_pitch_sync2(BLOBNBOX_IT *blob_it, int16_t blob_count, int16_t pitch, int16_t pitch_error, STATS *projection, int16_t projection_left, int16_t projection_right, float projection_scale, int16_t &occupation_count, FPSEGPT_LIST *seg_list, int16_t start, int16_t end)
Definition: pithsync.cpp:292
void plot_box_list(ScrollView *win, BLOBNBOX_LIST *list, ScrollView::Color body_colour)
Definition: drawtord.cpp:69
void plot_to_row(TO_ROW *row, ScrollView::Color colour, FCOORD rotation)
Definition: drawtord.cpp:89
void plot_parallel_row(TO_ROW *row, float gradient, int32_t left, ScrollView::Color colour, FCOORD rotation)
Definition: drawtord.cpp:122
void draw_meanlines(TO_BLOCK *block, float gradient, int32_t left, ScrollView::Color colour, FCOORD rotation)
Definition: drawtord.cpp:203
void plot_word_decisions(ScrollView *win, int16_t pitch, TO_ROW *row)
Definition: drawtord.cpp:238
ScrollView * create_to_win(ICOORD page_tr)
Definition: drawtord.cpp:47
void plot_row_cells(ScrollView *win, ScrollView::Color colour, TO_ROW *row, float xshift, ICOORDELT_LIST *cells)
Definition: drawtord.cpp:387
double check_pitch_sync(BLOBNBOX_IT *blob_it, int16_t blob_count, int16_t pitch, int16_t pitch_error, STATS *projection, FPSEGPT_LIST *seg_list)
Definition: pitsync1.cpp:138
TBOX box_next(BLOBNBOX_IT *it)
Definition: blobbox.cpp:638
void draw_occupation(int32_t xleft, int32_t ybottom, int32_t min_y, int32_t max_y, int32_t occupation[], int32_t thresholds[])
Definition: drawtord.cpp:161
const TBOX & bounding_box() const
Definition: blobbox.h:239
C_BLOB * cblob() const
Definition: blobbox.h:277
bool joined_to_prev() const
Definition: blobbox.h:265
float max_y() const
Definition: blobbox.h:568
int32_t min_space
Definition: blobbox.h:669
int32_t max_nonspace
Definition: blobbox.h:670
STATS projection
Definition: blobbox.h:677
float min_y() const
Definition: blobbox.h:571
float line_m() const
Definition: blobbox.h:580
int32_t space_threshold
Definition: blobbox.h:671
float parallel_c() const
Definition: blobbox.h:589
BLOBNBOX_LIST * blob_list()
Definition: blobbox.h:608
int16_t projection_left
Definition: blobbox.h:654
float line_c() const
Definition: blobbox.h:583
int16_t projection_right
Definition: blobbox.h:655
TO_ROW_LIST * get_rows()
Definition: blobbox.h:709
integer coordinate
Definition: points.h:36
TDimension y() const
access_function
Definition: points.h:62
TDimension x() const
access function
Definition: points.h:58
void rotate(const FCOORD vec)
Definition: points.h:712
float y() const
Definition: points.h:209
float x() const
Definition: points.h:206
TDimension left() const
Definition: rect.h:82
TDimension top() const
Definition: rect.h:68
TDimension right() const
Definition: rect.h:89
TDimension bottom() const
Definition: rect.h:75
void plot(ScrollView *window, ScrollView::Color blob_colour, ScrollView::Color child_colour)
Definition: stepblob.cpp:526
int32_t position()
Definition: pitsync1.h:49
void Line(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:511
void Pen(Color color)
Definition: scrollview.cpp:723
static void Update()
Definition: scrollview.cpp:713
void Brush(Color color)
Definition: scrollview.cpp:729
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:589
void SetCursor(int x, int y)
Definition: scrollview.cpp:498
void DrawTo(int x, int y)
Definition: scrollview.cpp:504