tesseract  4.00.00dev
pgedit.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * File: pgedit.cpp (Formerly pgeditor.c)
3  * Description: Page structure file editor
4  * Author: Phil Cheatle
5  * Created: Thu Oct 10 16:25:24 BST 1991
6  *
7  *(C) Copyright 1991, 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 #ifdef _MSC_VER
21 #pragma warning(disable:4244) // Conversion warnings
22 #endif
23 
24 // Include automatically generated configuration file if running autoconf.
25 #ifdef HAVE_CONFIG_H
26 #include "config_auto.h"
27 #endif
28 
29 #include "pgedit.h"
30 
31 #include <ctype.h>
32 #include <math.h>
33 
34 #include "blread.h"
35 #include "control.h"
36 #include "paramsd.h"
37 #include "pageres.h"
38 #include "tordmain.h"
39 #include "scrollview.h"
40 #include "svmnode.h"
41 #include "statistc.h"
42 #include "tesseractclass.h"
43 #include "werdit.h"
44 
45 #ifndef GRAPHICS_DISABLED
46 #define ASC_HEIGHT (2 * kBlnBaselineOffset + kBlnXHeight)
47 #define X_HEIGHT (kBlnBaselineOffset + kBlnXHeight)
48 #define BL_HEIGHT kBlnBaselineOffset
49 #define DESC_HEIGHT 0
50 #define MAXSPACING 128 /*max expected spacing in pix */
51 
52 const ERRCODE EMPTYBLOCKLIST = "No blocks to edit";
53 
55 {
86 };
87 
99 };
100 
101 /*
102  *
103  * Some global data
104  *
105  */
106 
109 bool stillRunning = false;
110 
111 #ifdef __UNIX__
112 FILE *debug_window = NULL; // opened on demand
113 #endif
114 ScrollView* bln_word_window = NULL; // baseline norm words
115 
116 CMD_EVENTS mode = CHANGE_DISP_CMD_EVENT; // selected words op
117 
118 bool recog_done = false; // recog_all_words was called
119 
120 // These variables should remain global, since they are only used for the
121 // debug mode (in which only a single Tesseract thread/instance will be exist).
123 static ColorationMode color_mode = CM_RAINBOW;
127 
129 
130 STRING_VAR(editor_image_win_name, "EditorImage",
131  "Editor image window name");
132 INT_VAR(editor_image_xpos, 590, "Editor image X Pos");
133 INT_VAR(editor_image_ypos, 10, "Editor image Y Pos");
134 INT_VAR(editor_image_menuheight, 50, "Add to image height for menu bar");
136  "Word bounding box colour");
138  "Blob bounding box colour");
140  "Correct text colour");
141 
142 STRING_VAR(editor_dbwin_name, "EditorDBWin",
143  "Editor debug window name");
144 INT_VAR(editor_dbwin_xpos, 50, "Editor debug window X Pos");
145 INT_VAR(editor_dbwin_ypos, 500, "Editor debug window Y Pos");
146 INT_VAR(editor_dbwin_height, 24, "Editor debug window height");
147 INT_VAR(editor_dbwin_width, 80, "Editor debug window width");
148 
149 STRING_VAR(editor_word_name, "BlnWords", "BL normalized word window");
150 INT_VAR(editor_word_xpos, 60, "Word window X Pos");
151 INT_VAR(editor_word_ypos, 510, "Word window Y Pos");
152 INT_VAR(editor_word_height, 240, "Word window height");
153 INT_VAR(editor_word_width, 655, "Word window width");
154 
155 STRING_VAR(editor_debug_config_file, "", "Config file to apply to single words");
156 
158  public:
159  void Notify(const SVEvent* sv_event) {
160  if (sv_event->type == SVET_DESTROY)
161  bln_word_window = NULL;
162  else if (sv_event->type == SVET_CLICK)
163  show_point(current_page_res, sv_event->x, sv_event->y);
164  }
165 };
166 
172 ScrollView* bln_word_window_handle() { // return handle
173  // not opened yet
174  if (bln_word_window == NULL) {
175  pgeditor_msg("Creating BLN word window...");
176  bln_word_window = new ScrollView(editor_word_name.string(),
178  editor_word_height, 4000, 4000, true);
179  BlnEventHandler* a = new BlnEventHandler();
180  bln_word_window->AddEventHandler(a);
181  pgeditor_msg("Creating BLN word window...Done");
182  }
183  return bln_word_window;
184 }
185 
193 void build_image_window(int width, int height) {
194  delete image_win;
195  image_win = new ScrollView(editor_image_win_name.string(),
197  width + 1,
198  height + editor_image_menuheight + 1,
199  width,
200  height,
201  true);
202 }
203 
211  ScrollView::Color colour,
212  float scale_factor,
213  float y_offset,
214  float minx,
215  float maxx) {
216  window->Pen(colour);
217  window->Line(minx, y_offset + scale_factor * DESC_HEIGHT,
218  maxx, y_offset + scale_factor * DESC_HEIGHT);
219  window->Line(minx, y_offset + scale_factor * BL_HEIGHT,
220  maxx, y_offset + scale_factor * BL_HEIGHT);
221  window->Line(minx, y_offset + scale_factor * X_HEIGHT,
222  maxx, y_offset + scale_factor * X_HEIGHT);
223  window->Line(minx, y_offset + scale_factor * ASC_HEIGHT,
224  maxx, y_offset + scale_factor * ASC_HEIGHT);
225 }
226 
235 void PGEventHandler::Notify(const SVEvent* event) {
236  char myval = '0';
237  if (event->type == SVET_POPUP) {
238  pe->Notify(event);
239  } // These are handled by ParamsEditor
240  else if (event->type == SVET_EXIT) { stillRunning = false; }
241  else if (event->type == SVET_MENU) {
242  if (strcmp(event->parameter, "true") == 0) { myval = 'T'; }
243  else if (strcmp(event->parameter, "false") == 0) { myval = 'F'; }
244  tess_->process_cmd_win_event(event->command_id, &myval);
245  }
246  else {
247  tess_->process_image_event(*event);
248  }
249 }
250 
256 namespace tesseract {
257 SVMenuNode *Tesseract::build_menu_new() {
258  SVMenuNode* parent_menu;
259  SVMenuNode* root_menu_item = new SVMenuNode();
260 
261  SVMenuNode* modes_menu_item = root_menu_item->AddChild("MODES");
262 
263  modes_menu_item->AddChild("Change Display", CHANGE_DISP_CMD_EVENT);
264  modes_menu_item->AddChild("Dump Word", DUMP_WERD_CMD_EVENT);
265  modes_menu_item->AddChild("Show Point", SHOW_POINT_CMD_EVENT);
266  modes_menu_item->AddChild("Show BL Norm Word", SHOW_BLN_WERD_CMD_EVENT);
267  modes_menu_item->AddChild("Config Words", DEBUG_WERD_CMD_EVENT);
268  modes_menu_item->AddChild("Recog Words", RECOG_WERDS);
269  modes_menu_item->AddChild("Recog Blobs", RECOG_PSEUDO);
270  modes_menu_item->AddChild("Show Blob Features", SHOW_BLOB_FEATURES);
271 
272  parent_menu = root_menu_item->AddChild("DISPLAY");
273 
274  parent_menu->AddChild("Blamer", BLAMER_CMD_EVENT, FALSE);
275  parent_menu->AddChild("Bounding Boxes", BOUNDING_BOX_CMD_EVENT, FALSE);
276  parent_menu->AddChild("Correct Text", CORRECT_TEXT_CMD_EVENT, FALSE);
277  parent_menu->AddChild("Polygonal Approx", POLYGONAL_CMD_EVENT, FALSE);
278  parent_menu->AddChild("Baseline Normalized", BL_NORM_CMD_EVENT, FALSE);
279  parent_menu->AddChild("Edge Steps", BITMAP_CMD_EVENT, TRUE);
280  parent_menu->AddChild("Subscripts", SHOW_SUBSCRIPT_CMD_EVENT);
281  parent_menu->AddChild("Superscripts", SHOW_SUPERSCRIPT_CMD_EVENT);
282  parent_menu->AddChild("Italics", SHOW_ITALIC_CMD_EVENT);
283  parent_menu->AddChild("Bold", SHOW_BOLD_CMD_EVENT);
284  parent_menu->AddChild("Underline", SHOW_UNDERLINE_CMD_EVENT);
285  parent_menu->AddChild("FixedPitch", SHOW_FIXEDPITCH_CMD_EVENT);
286  parent_menu->AddChild("Serifs", SHOW_SERIF_CMD_EVENT);
287  parent_menu->AddChild("SmallCaps", SHOW_SMALLCAPS_CMD_EVENT);
288  parent_menu->AddChild("DropCaps", SHOW_DROPCAPS_CMD_EVENT);
289 
290 
291  parent_menu = root_menu_item->AddChild("OTHER");
292 
293  parent_menu->AddChild("Quit", QUIT_CMD_EVENT);
294  parent_menu->AddChild("Show Image", IMAGE_CMD_EVENT, FALSE);
295  parent_menu->AddChild("ShowBlock Outlines", BLOCKS_CMD_EVENT, FALSE);
296  parent_menu->AddChild("Show Baselines", BASELINES_CMD_EVENT, FALSE);
297  parent_menu->AddChild("Uniform Display", UNIFORM_DISP_CMD_EVENT);
298  parent_menu->AddChild("Refresh Display", REFRESH_CMD_EVENT);
299 
300  return root_menu_item;
301 }
302 
308 void Tesseract::do_re_display(
309  BOOL8 (tesseract::Tesseract::*word_painter)(PAGE_RES_IT* pr_it)) {
310  int block_count = 1;
311 
312  image_win->Clear();
313  if (display_image != 0) {
314  image_win->Image(pix_binary_, 0, 0);
315  }
316 
317  image_win->Brush(ScrollView::NONE);
318  PAGE_RES_IT pr_it(current_page_res);
319  for (WERD_RES* word = pr_it.word(); word != NULL; word = pr_it.forward()) {
320  (this->*word_painter)(&pr_it);
321  if (display_baselines && pr_it.row() != pr_it.prev_row())
322  pr_it.row()->row->plot_baseline(image_win, ScrollView::GREEN);
323  if (display_blocks && pr_it.block() != pr_it.prev_block())
324  pr_it.block()->block->plot(image_win, block_count++, ScrollView::RED);
325  }
326  image_win->Update();
327 }
328 
337 void Tesseract::pgeditor_main(int width, int height, PAGE_RES *page_res) {
338  current_page_res = page_res;
339  if (current_page_res->block_res_list.empty())
340  return;
341 
342  recog_done = false;
343  stillRunning = true;
344 
345  build_image_window(width, height);
346  word_display_mode.turn_on_bit(DF_EDGE_STEP);
348 #ifndef GRAPHICS_DISABLED
349  pe = new ParamsEditor(this, image_win);
350 #endif
351  PGEventHandler pgEventHandler(this);
352 
353  image_win->AddEventHandler(&pgEventHandler);
354  image_win->AddMessageBox();
355 
356  SVMenuNode* svMenuRoot = build_menu_new();
357 
358  svMenuRoot->BuildMenu(image_win);
359  image_win->SetVisible(true);
360 
361  image_win->AwaitEvent(SVET_DESTROY);
362  image_win->AddEventHandler(NULL);
363 }
364 } // namespace tesseract
365 
366 
373 void pgeditor_msg( // message display
374  const char *msg) {
375  image_win->AddMessage(msg);
376 }
377 
384 void pgeditor_show_point( // display coords
385  SVEvent *event) {
386  image_win->AddMessage("Pointing at(%d, %d)", event->x, event->y);
387 }
388 
396 namespace tesseract {
397 BOOL8 Tesseract::process_cmd_win_event( // UI command semantics
398  inT32 cmd_event, // which menu item?
399  char *new_value // any prompt data
400  ) {
401  char msg[160];
402  BOOL8 exit = FALSE;
403 
404  color_mode = CM_RAINBOW;
405 
406  // Run recognition on the full page if needed.
407  switch (cmd_event) {
408  case BLAMER_CMD_EVENT:
412  case SHOW_BOLD_CMD_EVENT:
418  if (!recog_done) {
419  recog_all_words(current_page_res, NULL, NULL, NULL, 0);
420  recog_done = true;
421  }
422  break;
423  default:
424  break;
425  }
426 
427  switch (cmd_event) {
428  case NULL_CMD_EVENT:
429  break;
430 
432  case DUMP_WERD_CMD_EVENT:
435  case RECOG_WERDS:
436  case RECOG_PSEUDO:
437  case SHOW_BLOB_FEATURES:
438  mode =(CMD_EVENTS) cmd_event;
439  break;
442  word_config_ = image_win->ShowInputDialog("Config File Name");
443  break;
445  if (new_value[0] == 'T')
446  word_display_mode.turn_on_bit(DF_BOX);
447  else
448  word_display_mode.turn_off_bit(DF_BOX);
450  break;
451  case BLAMER_CMD_EVENT:
452  if (new_value[0] == 'T')
453  word_display_mode.turn_on_bit(DF_BLAMER);
454  else
455  word_display_mode.turn_off_bit(DF_BLAMER);
456  do_re_display(&tesseract::Tesseract::word_display);
458  break;
460  if (new_value[0] == 'T')
461  word_display_mode.turn_on_bit(DF_TEXT);
462  else
463  word_display_mode.turn_off_bit(DF_TEXT);
465  break;
466  case POLYGONAL_CMD_EVENT:
467  if (new_value[0] == 'T')
468  word_display_mode.turn_on_bit(DF_POLYGONAL);
469  else
470  word_display_mode.turn_off_bit(DF_POLYGONAL);
472  break;
473  case BL_NORM_CMD_EVENT:
474  if (new_value[0] == 'T')
475  word_display_mode.turn_on_bit(DF_BN_POLYGONAL);
476  else
477  word_display_mode.turn_off_bit(DF_BN_POLYGONAL);
479  break;
480  case BITMAP_CMD_EVENT:
481  if (new_value[0] == 'T')
482  word_display_mode.turn_on_bit(DF_EDGE_STEP);
483  else
484  word_display_mode.turn_off_bit(DF_EDGE_STEP);
486  break;
489  break;
490  case IMAGE_CMD_EVENT:
491  display_image =(new_value[0] == 'T');
492  do_re_display(&tesseract::Tesseract::word_display);
493  break;
494  case BLOCKS_CMD_EVENT:
495  display_blocks =(new_value[0] == 'T');
496  do_re_display(&tesseract::Tesseract::word_display);
497  break;
498  case BASELINES_CMD_EVENT:
499  display_baselines =(new_value[0] == 'T');
500  do_re_display(&tesseract::Tesseract::word_display);
501  break;
503  color_mode = CM_SUBSCRIPT;
504  do_re_display(&tesseract::Tesseract::word_display);
505  break;
507  color_mode = CM_SUPERSCRIPT;
508  do_re_display(&tesseract::Tesseract::word_display);
509  break;
511  color_mode = CM_ITALIC;
512  do_re_display(&tesseract::Tesseract::word_display);
513  break;
514  case SHOW_BOLD_CMD_EVENT:
515  color_mode = CM_BOLD;
516  do_re_display(&tesseract::Tesseract::word_display);
517  break;
519  color_mode = CM_UNDERLINE;
520  do_re_display(&tesseract::Tesseract::word_display);
521  break;
523  color_mode = CM_FIXEDPITCH;
524  do_re_display(&tesseract::Tesseract::word_display);
525  break;
527  color_mode = CM_SERIF;
528  do_re_display(&tesseract::Tesseract::word_display);
529  break;
531  color_mode = CM_SMALLCAPS;
532  do_re_display(&tesseract::Tesseract::word_display);
533  break;
535  color_mode = CM_DROPCAPS;
536  do_re_display(&tesseract::Tesseract::word_display);
537  break;
538  case REFRESH_CMD_EVENT:
539  do_re_display(&tesseract::Tesseract::word_display);
540  break;
541  case QUIT_CMD_EVENT:
542  exit = TRUE;
544  break;
545 
546  default:
547  sprintf(msg, "Unrecognised event %" PRId32 "(%s)", cmd_event, new_value);
548  image_win->AddMessage(msg);
549  break;
550  }
551  return exit;
552 }
553 
554 
564 void Tesseract::process_image_event( // action in image win
565  const SVEvent &event) {
566  // The following variable should remain static, since it is used by
567  // debug editor, which uses a single Tesseract instance.
568  static ICOORD down;
569  ICOORD up;
570  TBOX selection_box;
571  char msg[80];
572 
573  switch(event.type) {
574 
575  case SVET_SELECTION:
576  if (event.type == SVET_SELECTION) {
577  down.set_x(event.x + event.x_size);
578  down.set_y(event.y + event.y_size);
579  if (mode == SHOW_POINT_CMD_EVENT)
580  show_point(current_page_res, event.x, event.y);
581  }
582 
583  up.set_x(event.x);
584  up.set_y(event.y);
585 
586  selection_box = TBOX(down, up);
587 
588  switch(mode) {
590  process_selected_words(
591  current_page_res,
592  selection_box,
594  break;
595  case DUMP_WERD_CMD_EVENT:
596  process_selected_words(current_page_res,
597  selection_box,
599  break;
601  process_selected_words(current_page_res,
602  selection_box,
604  break;
606  debug_word(current_page_res, selection_box);
607  break;
609  break; // ignore up event
610 
611  case RECOG_WERDS:
612  image_win->AddMessage("Recogging selected words");
613  this->process_selected_words(current_page_res,
614  selection_box,
615  &Tesseract::recog_interactive);
616  break;
617  case RECOG_PSEUDO:
618  image_win->AddMessage("Recogging selected blobs");
619  recog_pseudo_word(current_page_res, selection_box);
620  break;
621  case SHOW_BLOB_FEATURES:
622  blob_feature_display(current_page_res, selection_box);
623  break;
624 
625  default:
626  sprintf(msg, "Mode %d not yet implemented", mode);
627  image_win->AddMessage(msg);
628  break;
629  }
630  default:
631  break;
632  }
633 }
634 
640 void Tesseract::debug_word(PAGE_RES* page_res, const TBOX &selection_box) {
641  ResetAdaptiveClassifier();
642  recog_all_words(page_res, NULL, &selection_box, word_config_.string(), 0);
643 }
644 } // namespace tesseract
645 
646 
654 void show_point(PAGE_RES* page_res, float x, float y) {
655  FCOORD pt(x, y);
656  PAGE_RES_IT pr_it(page_res);
657 
658  const int kBufsize = 512;
659  char msg[kBufsize];
660  char *msg_ptr = msg;
661 
662  msg_ptr += sprintf(msg_ptr, "Pt:(%0.3f, %0.3f) ", x, y);
663 
664  for (WERD_RES* word = pr_it.word(); word != NULL; word = pr_it.forward()) {
665  if (pr_it.row() != pr_it.prev_row() &&
666  pr_it.row()->row->bounding_box().contains(pt)) {
667  msg_ptr += sprintf(msg_ptr, "BL(x)=%0.3f ",
668  pr_it.row()->row->base_line(x));
669  }
670  if (word->word->bounding_box().contains(pt)) {
671  TBOX box = word->word->bounding_box();
672  msg_ptr += sprintf(msg_ptr, "Wd(%d, %d)/(%d, %d) ",
673  box.left(), box.bottom(),
674  box.right(), box.top());
675  C_BLOB_IT cblob_it(word->word->cblob_list());
676  for (cblob_it.mark_cycle_pt();
677  !cblob_it.cycled_list();
678  cblob_it.forward()) {
679  C_BLOB* cblob = cblob_it.data();
680  box = cblob->bounding_box();
681  if (box.contains(pt)) {
682  msg_ptr += sprintf(msg_ptr,
683  "CBlb(%d, %d)/(%d, %d) ",
684  box.left(), box.bottom(),
685  box.right(), box.top());
686  }
687  }
688  }
689  }
690  image_win->AddMessage(msg);
691 }
692 
693 
694 /**********************************************************************
695  * WERD PROCESSOR FUNCTIONS
696  * ========================
697  *
698  * These routines are invoked by one or more of:
699  * process_all_words()
700  * process_selected_words()
701  * or
702  * process_all_words_it()
703  * process_selected_words_it()
704  * for each word to be processed
705  **********************************************************************/
706 
713 #endif // GRAPHICS_DISABLED
714 namespace tesseract {
715 #ifndef GRAPHICS_DISABLED
716 BOOL8 Tesseract:: word_blank_and_set_display(PAGE_RES_IT* pr_it) {
717  pr_it->word()->word->bounding_box().plot(image_win, ScrollView::BLACK,
719  return word_set_display(pr_it);
720 }
721 
722 
728 BOOL8 Tesseract::word_bln_display(PAGE_RES_IT* pr_it) {
729  WERD_RES* word_res = pr_it->word();
730  if (word_res->chopped_word == NULL) {
731  // Setup word normalization parameters.
732  word_res->SetupForRecognition(unicharset, this, BestPix(),
733  tessedit_ocr_engine_mode, NULL,
734  classify_bln_numeric_mode,
735  textord_use_cjk_fp_model,
736  poly_allow_detailed_fx,
737  pr_it->row()->row, pr_it->block()->block);
738  }
741  1.0, 0.0f, -1000.0f, 1000.0f);
742  C_BLOB_IT it(word_res->word->cblob_list());
744  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
745  it.data()->plot_normed(word_res->denorm, color, ScrollView::BROWN,
747  color = WERD::NextColor(color);
748  }
750  return TRUE;
751 }
752 
753 
754 
760 BOOL8 Tesseract::word_display(PAGE_RES_IT* pr_it) {
761  WERD_RES* word_res = pr_it->word();
762  WERD* word = word_res->word;
763  TBOX word_bb; // word bounding box
764  int word_height; // ht of word BB
765  BOOL8 displayed_something = FALSE;
766  float shift; // from bot left
767  C_BLOB_IT c_it; // cblob iterator
768 
769  if (color_mode != CM_RAINBOW && word_res->box_word != NULL) {
770  BoxWord* box_word = word_res->box_word;
771  WERD_CHOICE* best_choice = word_res->best_choice;
772  int length = box_word->length();
773  if (word_res->fontinfo == NULL) return false;
774  const FontInfo& font_info = *word_res->fontinfo;
775  for (int i = 0; i < length; ++i) {
777  switch (color_mode) {
778  case CM_SUBSCRIPT:
779  if (best_choice->BlobPosition(i) == SP_SUBSCRIPT)
780  color = ScrollView::RED;
781  break;
782  case CM_SUPERSCRIPT:
783  if (best_choice->BlobPosition(i) == SP_SUPERSCRIPT)
784  color = ScrollView::RED;
785  break;
786  case CM_ITALIC:
787  if (font_info.is_italic())
788  color = ScrollView::RED;
789  break;
790  case CM_BOLD:
791  if (font_info.is_bold())
792  color = ScrollView::RED;
793  break;
794  case CM_FIXEDPITCH:
795  if (font_info.is_fixed_pitch())
796  color = ScrollView::RED;
797  break;
798  case CM_SERIF:
799  if (font_info.is_serif())
800  color = ScrollView::RED;
801  break;
802  case CM_SMALLCAPS:
803  if (word_res->small_caps)
804  color = ScrollView::RED;
805  break;
806  case CM_DROPCAPS:
807  if (best_choice->BlobPosition(i) == SP_DROPCAP)
808  color = ScrollView::RED;
809  break;
810  // TODO(rays) underline is currently completely unsupported.
811  case CM_UNDERLINE:
812  default:
813  break;
814  }
815  image_win->Pen(color);
816  TBOX box = box_word->BlobBox(i);
817  image_win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
818  }
819  return true;
820  }
821  /*
822  Note the double coercions of(COLOUR)((inT32)editor_image_word_bb_color)
823  etc. are to keep the compiler happy.
824  */
825  // display bounding box
826  if (word->display_flag(DF_BOX)) {
827  word->bounding_box().plot(image_win,
831  editor_image_word_bb_color));
832 
835  image_win->Pen(c);
836  c_it.set_to_list(word->cblob_list());
837  for (c_it.mark_cycle_pt(); !c_it.cycled_list(); c_it.forward())
838  c_it.data()->bounding_box().plot(image_win);
839  displayed_something = TRUE;
840  }
841 
842  // display edge steps
843  if (word->display_flag(DF_EDGE_STEP)) { // edgesteps available
844  word->plot(image_win); // rainbow colors
845  displayed_something = TRUE;
846  }
847 
848  // display poly approx
849  if (word->display_flag(DF_POLYGONAL)) {
850  // need to convert
851  TWERD* tword = TWERD::PolygonalCopy(poly_allow_detailed_fx, word);
852  tword->plot(image_win);
853  delete tword;
854  displayed_something = TRUE;
855  }
856 
857  // Display correct text and blamer information.
858  STRING text;
859  STRING blame;
860  if (word->display_flag(DF_TEXT) && word->text() != NULL) {
861  text = word->text();
862  }
863  if (word->display_flag(DF_BLAMER) &&
864  !(word_res->blamer_bundle != NULL &&
866  text = "";
867  const BlamerBundle *blamer_bundle = word_res->blamer_bundle;
868  if (blamer_bundle == NULL) {
869  text += "NULL";
870  } else {
871  text = blamer_bundle->TruthString();
872  }
873  text += " -> ";
874  STRING best_choice_str;
875  if (word_res->best_choice == NULL) {
876  best_choice_str = "NULL";
877  } else {
878  word_res->best_choice->string_and_lengths(&best_choice_str, NULL);
879  }
880  text += best_choice_str;
881  IncorrectResultReason reason = (blamer_bundle == NULL) ?
882  IRR_PAGE_LAYOUT : blamer_bundle->incorrect_result_reason();
883  ASSERT_HOST(reason < IRR_NUM_REASONS)
884  blame += " [";
885  blame += BlamerBundle::IncorrectReasonName(reason);
886  blame += "]";
887  }
888  if (text.length() > 0) {
889  word_bb = word->bounding_box();
890  image_win->Pen(ScrollView::RED);
891  word_height = word_bb.height();
892  int text_height = 0.50 * word_height;
893  if (text_height > 20) text_height = 20;
894  image_win->TextAttributes("Arial", text_height, false, false, false);
895  shift = (word_height < word_bb.width()) ? 0.25 * word_height : 0.0f;
896  image_win->Text(word_bb.left() + shift,
897  word_bb.bottom() + 0.25 * word_height, text.string());
898  if (blame.length() > 0) {
899  image_win->Text(word_bb.left() + shift,
900  word_bb.bottom() + 0.25 * word_height - text_height,
901  blame.string());
902  }
903 
904  displayed_something = TRUE;
905  }
906 
907  if (!displayed_something) // display BBox anyway
908  word->bounding_box().plot(image_win,
911  editor_image_word_bb_color));
912  return TRUE;
913 }
914 #endif // GRAPHICS_DISABLED
915 
921 BOOL8 Tesseract::word_dumper(PAGE_RES_IT* pr_it) {
922  if (pr_it->block()->block != NULL) {
923  tprintf("\nBlock data...\n");
924  pr_it->block()->block->print(NULL, FALSE);
925  }
926  tprintf("\nRow data...\n");
927  pr_it->row()->row->print(NULL);
928  tprintf("\nWord data...\n");
929  WERD_RES* word_res = pr_it->word();
930  word_res->word->print();
931  if (word_res->blamer_bundle != NULL && wordrec_debug_blamer &&
933  tprintf("Current blamer debug: %s\n",
934  word_res->blamer_bundle->debug().string());
935  }
936  return TRUE;
937 }
938 
939 #ifndef GRAPHICS_DISABLED
940 
945 BOOL8 Tesseract::word_set_display(PAGE_RES_IT* pr_it) {
946  WERD* word = pr_it->word()->word;
947  word->set_display_flag(DF_BOX, word_display_mode.bit(DF_BOX));
948  word->set_display_flag(DF_TEXT, word_display_mode.bit(DF_TEXT));
949  word->set_display_flag(DF_POLYGONAL, word_display_mode.bit(DF_POLYGONAL));
950  word->set_display_flag(DF_EDGE_STEP, word_display_mode.bit(DF_EDGE_STEP));
952  word_display_mode.bit(DF_BN_POLYGONAL));
953  word->set_display_flag(DF_BLAMER, word_display_mode.bit(DF_BLAMER));
954  return word_display(pr_it);
955 }
956 
957 // page_res is non-const because the iterator doesn't know if you are going
958 // to change the items it points to! Really a const here though.
959 void Tesseract::blob_feature_display(PAGE_RES* page_res,
960  const TBOX& selection_box) {
961  PAGE_RES_IT* it = make_pseudo_word(page_res, selection_box);
962  if (it != NULL) {
963  WERD_RES* word_res = it->word();
964  word_res->x_height = it->row()->row->x_height();
965  word_res->SetupForRecognition(unicharset, this, BestPix(),
966  tessedit_ocr_engine_mode, NULL,
967  classify_bln_numeric_mode,
968  textord_use_cjk_fp_model,
969  poly_allow_detailed_fx,
970  it->row()->row, it->block()->block);
971  TWERD* bln_word = word_res->chopped_word;
972  TBLOB* bln_blob = bln_word->blobs[0];
973  INT_FX_RESULT_STRUCT fx_info;
976  Classify::ExtractFeatures(*bln_blob, classify_nonlinear_norm, &bl_features,
977  &cn_features, &fx_info, NULL);
978  // Display baseline features.
979  ScrollView* bl_win = CreateFeatureSpaceWindow("BL Features", 512, 0);
981  for (int f = 0; f < bl_features.size(); ++f)
982  RenderIntFeature(bl_win, &bl_features[f], ScrollView::GREEN);
983  bl_win->Update();
984  // Display cn features.
985  ScrollView* cn_win = CreateFeatureSpaceWindow("CN Features", 512, 0);
987  for (int f = 0; f < cn_features.size(); ++f)
988  RenderIntFeature(cn_win, &cn_features[f], ScrollView::GREEN);
989  cn_win->Update();
990 
991  it->DeleteCurrentWord();
992  delete it;
993  }
994 }
995 
996 
997 #endif // GRAPHICS_DISABLED
998 
999 } // namespace tesseract
1000 
1001 
1002 
static ScrollView::Color NextColor(ScrollView::Color colour)
Definition: werd.cpp:306
BOOL8 display_flag(uinT8 flag) const
Definition: werd.h:131
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:1033
void Line(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:538
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1858
char * editor_word_name
Definition: pgedit.cpp:149
void plot(ScrollView *fd) const
Definition: rect.h:278
char * parameter
Definition: scrollview.h:71
void Notify(const SVEvent *sve)
Definition: pgedit.cpp:235
SVEventType type
Definition: scrollview.h:64
#define TRUE
Definition: capi.h:45
const TBOX & BlobBox(int index) const
Definition: boxword.h:86
Definition: points.h:189
int32_t inT32
Definition: host.h:38
char * editor_debug_config_file
Definition: pgedit.cpp:155
const ERRCODE EMPTYBLOCKLIST
Definition: pgedit.cpp:52
void plot(ScrollView *window)
Definition: blobs.cpp:916
Definition: bits16.h:25
void set_display_flag(uinT8 flag, BOOL8 value)
Definition: werd.h:132
WERD_CHOICE * best_choice
Definition: pageres.h:219
void display_bln_lines(ScrollView *window, ScrollView::Color colour, float scale_factor, float y_offset, float minx, float maxx)
Definition: pgedit.cpp:210
int editor_word_ypos
Definition: pgedit.cpp:151
ROW_RES * prev_row() const
Definition: pageres.h:730
void Brush(Color color)
Definition: scrollview.cpp:732
BlamerBundle * blamer_bundle
Definition: pageres.h:230
void set_x(inT16 xin)
rewrite function
Definition: points.h:61
bool is_bold() const
Definition: fontinfo.h:112
BLOCK_RES_LIST block_res_list
Definition: pageres.h:62
void build_image_window(int width, int height)
Definition: pgedit.cpp:193
void print()
Definition: werd.cpp:266
int editor_image_text_color
Definition: pgedit.cpp:140
Definition: werd.h:55
int editor_image_word_bb_color
Definition: pgedit.cpp:136
#define tprintf(...)
Definition: tprintf.h:31
BLOCK * block
Definition: pageres.h:99
const char * string() const
Definition: strngs.cpp:198
Definition: werd.h:50
ROW * row
Definition: pageres.h:127
BOOL8 display_baselines
Definition: pgedit.cpp:126
tesseract::ScriptPos BlobPosition(int index) const
Definition: ratngs.h:320
void pgeditor_msg(const char *msg)
Definition: pgedit.cpp:373
#define X_HEIGHT
Definition: pgedit.cpp:47
float x_height() const
Definition: ocrrow.h:61
inT32 length() const
Definition: strngs.cpp:193
ScrollView * image_win
Definition: pgedit.cpp:107
void print(FILE *fp)
Definition: ocrrow.cpp:167
int editor_word_xpos
Definition: pgedit.cpp:150
int size() const
Definition: genericvector.h:72
void turn_off_bit(uinT8 bit_num)
Definition: bits16.h:42
char * ShowInputDialog(const char *msg)
Definition: scrollview.cpp:740
TBOX bounding_box() const
Definition: werd.cpp:160
tesseract::BoxWord * box_word
Definition: pageres.h:250
ParamsEditor * pe
Definition: pgedit.cpp:108
ScrollView * bln_word_window_handle()
Definition: pgedit.cpp:172
ROW_RES * row() const
Definition: pageres.h:739
#define ASSERT_HOST(x)
Definition: errcode.h:84
void string_and_lengths(STRING *word_str, STRING *word_lengths_str) const
Definition: ratngs.cpp:427
inT16 left() const
Definition: rect.h:68
#define DESC_HEIGHT
Definition: pgedit.cpp:49
BOOL8 word_bln_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:728
IncorrectResultReason incorrect_result_reason() const
Definition: blamer.h:106
ScrollView * bln_word_window
Definition: pgedit.cpp:114
int editor_image_xpos
Definition: pgedit.cpp:132
#define BL_HEIGHT
Definition: pgedit.cpp:48
int command_id
Definition: scrollview.h:70
Definition: blobs.h:395
void Clear()
Definition: scrollview.cpp:595
char * editor_image_win_name
Definition: pgedit.cpp:131
BOOL8 word_blank_and_set_display(PAGE_RES_IT *pr_its)
Definition: pgedit.cpp:716
int editor_dbwin_xpos
Definition: pgedit.cpp:144
void Notify(const SVEvent *sve)
Definition: paramsd.cpp:269
WERD_RES * forward()
Definition: pageres.h:716
const STRING & debug() const
Definition: blamer.h:116
BOOL8 display_image
Definition: pgedit.cpp:124
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1693
void plot_baseline(ScrollView *window, ScrollView::Color colour)
Definition: ocrrow.h:134
BOOL8 word_set_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:945
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
unsigned char BOOL8
Definition: host.h:44
PAGE_RES_IT * make_pseudo_word(PAGE_RES *page_res, const TBOX &selection_box)
Definition: werdit.cpp:31
int y_size
Definition: scrollview.h:69
Definition: strngs.h:45
#define FALSE
Definition: capi.h:46
const char int mode
Definition: ioapi.h:38
const FontInfo * fontinfo
Definition: pageres.h:288
static void Update()
Definition: scrollview.cpp:715
int y
Definition: scrollview.h:67
#define ASC_HEIGHT
Definition: pgedit.cpp:46
#define INT_VAR(name, val, comment)
Definition: params.h:276
const char * text() const
Definition: werd.h:125
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
Definition: scrollview.cpp:418
int editor_image_ypos
Definition: pgedit.cpp:133
bool contains(const FCOORD pt) const
Definition: rect.h:323
static void Exit()
Definition: scrollview.cpp:589
void DeleteCurrentWord()
Definition: pageres.cpp:1451
TBOX bounding_box() const
Definition: ocrrow.h:85
int x
Definition: scrollview.h:66
char * editor_dbwin_name
Definition: pgedit.cpp:143
void print(FILE *fp, BOOL8 dump)
dump whole table
Definition: ocrblock.cpp:197
inT16 top() const
Definition: rect.h:54
int editor_dbwin_ypos
Definition: pgedit.cpp:145
int editor_image_menuheight
Definition: pgedit.cpp:134
int editor_image_blob_bb_color
Definition: pgedit.cpp:138
bool recog_done
Definition: pgedit.cpp:118
Definition: rect.h:30
GenericVector< TBLOB * > blobs
Definition: blobs.h:436
ColorationMode
Definition: pgedit.cpp:88
CMD_EVENTS
Definition: pgedit.cpp:54
Definition: blobs.h:261
DENORM denorm
Definition: pageres.h:190
TBOX bounding_box() const
Definition: stepblob.cpp:250
C_BLOB_LIST * cblob_list()
Definition: werd.h:100
IncorrectResultReason
Definition: blamer.h:37
inT16 height() const
Definition: rect.h:104
void plot(ScrollView *window, inT32 serial, ScrollView::Color colour)
Definition: pdblock.cpp:177
bool small_caps
Definition: pageres.h:283
WERD * word
Definition: pageres.h:175
BOOL8 word_dumper(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:921
inT16 right() const
Definition: rect.h:75
void Notify(const SVEvent *sv_event)
Definition: pgedit.cpp:159
bool stillRunning
Definition: pgedit.cpp:109
inT16 width() const
Definition: rect.h:111
void Text(int x, int y, const char *mystring)
Definition: scrollview.cpp:658
bool is_italic() const
Definition: fontinfo.h:111
int editor_dbwin_height
Definition: pgedit.cpp:146
void pgeditor_show_point(SVEvent *event)
Definition: pgedit.cpp:384
bool SetupForRecognition(const UNICHARSET &unicharset_in, tesseract::Tesseract *tesseract, Pix *pix, int norm_mode, const TBOX *norm_box, bool numeric_mode, bool use_body_size, bool allow_detailed_fx, ROW *row, const BLOCK *block)
Definition: pageres.cpp:294
void Image(struct Pix *image, int x_pos, int y_pos)
Definition: scrollview.cpp:773
BOOL8 word_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:760
WERD_RES * word() const
Definition: pageres.h:736
inT16 bottom() const
Definition: rect.h:61
#define STRING_VAR(name, val, comment)
Definition: params.h:282
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
BOOL8 display_blocks
Definition: pgedit.cpp:125
void show_point(PAGE_RES *page_res, float x, float y)
Definition: pgedit.cpp:654
BOOL8 bit(uinT8 bit_num) const
Definition: bits16.h:56
bool is_fixed_pitch() const
Definition: fontinfo.h:113
static const char * IncorrectReasonName(IncorrectResultReason irr)
Definition: blamer.cpp:56
BLOCK_RES * prev_block() const
Definition: pageres.h:733
PAGE_RES * current_page_res
Definition: pgedit.cpp:128
float base_line(float xpos) const
Definition: ocrrow.h:56
int x_size
Definition: scrollview.h:68
void SetVisible(bool visible)
Definition: scrollview.cpp:555
int editor_word_width
Definition: pgedit.cpp:153
Definition: werd.h:60
void turn_on_bit(uinT8 bit_num)
Definition: bits16.h:37
TWERD * chopped_word
Definition: pageres.h:201
int editor_word_height
Definition: pgedit.cpp:152
Definition: werd.h:51
BITS16 word_display_mode
Definition: pgedit.cpp:122
void AddMessage(const char *format,...)
Definition: scrollview.cpp:567
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:121
float x_height
Definition: pageres.h:295
static TWERD * PolygonalCopy(bool allow_detailed_fx, WERD *src)
Definition: blobs.cpp:793
STRING TruthString() const
Definition: blamer.h:100
void set_y(inT16 yin)
rewrite function
Definition: points.h:65
int editor_dbwin_width
Definition: pgedit.cpp:147
void AddMessageBox()
Definition: scrollview.cpp:584
void Pen(Color color)
Definition: scrollview.cpp:726
void plot(ScrollView *window, ScrollView::Color colour)
Definition: werd.cpp:297
BLOCK_RES * block() const
Definition: pageres.h:742
bool is_serif() const
Definition: fontinfo.h:114
int length() const
Definition: boxword.h:85
integer coordinate
Definition: points.h:30
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:449
void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined)
Definition: scrollview.cpp:641