tesseract  4.0.0-1-g2a2b
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 // Include automatically generated configuration file if running autoconf.
21 #ifdef HAVE_CONFIG_H
22 #include "config_auto.h"
23 #endif
24 
25 #include "pgedit.h"
26 
27 #include <cctype>
28 #include <cmath>
29 
30 #include "blread.h"
31 #include "control.h"
32 #include "paramsd.h"
33 #include "pageres.h"
34 #include "tordmain.h"
35 #include "scrollview.h"
36 #include "svmnode.h"
37 #include "statistc.h"
38 #include "tesseractclass.h"
39 #include "werdit.h"
40 
41 #ifndef GRAPHICS_DISABLED
42 #define ASC_HEIGHT (2 * kBlnBaselineOffset + kBlnXHeight)
43 #define X_HEIGHT (kBlnBaselineOffset + kBlnXHeight)
44 #define BL_HEIGHT kBlnBaselineOffset
45 #define DESC_HEIGHT 0
46 #define MAXSPACING 128 /*max expected spacing in pix */
47 
48 const ERRCODE EMPTYBLOCKLIST = "No blocks to edit";
49 
51 {
82 };
83 
95 };
96 
97 /*
98  *
99  * Some global data
100  *
101  */
102 
103 static ScrollView* image_win;
104 static ParamsEditor* pe;
105 static bool stillRunning = false;
106 
107 static ScrollView* bln_word_window = nullptr; // baseline norm words
108 
109 static CMD_EVENTS mode = CHANGE_DISP_CMD_EVENT; // selected words op
110 
111 static bool recog_done = false; // recog_all_words was called
112 
113 // These variables should remain global, since they are only used for the
114 // debug mode (in which only a single Tesseract thread/instance will exist).
116 static ColorationMode color_mode = CM_RAINBOW;
120 
122 
123 STRING_VAR(editor_image_win_name, "EditorImage",
124  "Editor image window name");
125 INT_VAR(editor_image_xpos, 590, "Editor image X Pos");
126 INT_VAR(editor_image_ypos, 10, "Editor image Y Pos");
127 INT_VAR(editor_image_menuheight, 50, "Add to image height for menu bar");
129  "Word bounding box colour");
131  "Blob bounding box colour");
133  "Correct text colour");
134 
135 STRING_VAR(editor_dbwin_name, "EditorDBWin",
136  "Editor debug window name");
137 INT_VAR(editor_dbwin_xpos, 50, "Editor debug window X Pos");
138 INT_VAR(editor_dbwin_ypos, 500, "Editor debug window Y Pos");
139 INT_VAR(editor_dbwin_height, 24, "Editor debug window height");
140 INT_VAR(editor_dbwin_width, 80, "Editor debug window width");
141 
142 STRING_VAR(editor_word_name, "BlnWords", "BL normalized word window");
143 INT_VAR(editor_word_xpos, 60, "Word window X Pos");
144 INT_VAR(editor_word_ypos, 510, "Word window Y Pos");
145 INT_VAR(editor_word_height, 240, "Word window height");
146 INT_VAR(editor_word_width, 655, "Word window width");
147 
148 STRING_VAR(editor_debug_config_file, "", "Config file to apply to single words");
149 
151  public:
152  void Notify(const SVEvent* sv_event) {
153  if (sv_event->type == SVET_DESTROY)
154  bln_word_window = nullptr;
155  else if (sv_event->type == SVET_CLICK)
156  show_point(current_page_res, sv_event->x, sv_event->y);
157  }
158 };
159 
165 ScrollView* bln_word_window_handle() { // return handle
166  // not opened yet
167  if (bln_word_window == nullptr) {
168  pgeditor_msg("Creating BLN word window...");
169  bln_word_window = new ScrollView(editor_word_name.string(),
171  editor_word_height, 4000, 4000, true);
172  BlnEventHandler* a = new BlnEventHandler();
173  bln_word_window->AddEventHandler(a);
174  pgeditor_msg("Creating BLN word window...Done");
175  }
176  return bln_word_window;
177 }
178 
186 void build_image_window(int width, int height) {
187  delete image_win;
188  image_win = new ScrollView(editor_image_win_name.string(),
190  width + 1,
191  height + editor_image_menuheight + 1,
192  width,
193  height,
194  true);
195 }
196 
203 static void display_bln_lines(ScrollView* window, ScrollView::Color colour,
204  float scale_factor, float y_offset,
205  float minx, float maxx) {
206  window->Pen(colour);
207  window->Line(minx, y_offset + scale_factor * DESC_HEIGHT,
208  maxx, y_offset + scale_factor * DESC_HEIGHT);
209  window->Line(minx, y_offset + scale_factor * BL_HEIGHT,
210  maxx, y_offset + scale_factor * BL_HEIGHT);
211  window->Line(minx, y_offset + scale_factor * X_HEIGHT,
212  maxx, y_offset + scale_factor * X_HEIGHT);
213  window->Line(minx, y_offset + scale_factor * ASC_HEIGHT,
214  maxx, y_offset + scale_factor * ASC_HEIGHT);
215 }
216 
225 void PGEventHandler::Notify(const SVEvent* event) {
226  char myval = '0';
227  if (event->type == SVET_POPUP) {
228  pe->Notify(event);
229  } // These are handled by ParamsEditor
230  else if (event->type == SVET_EXIT) { stillRunning = false; }
231  else if (event->type == SVET_MENU) {
232  if (strcmp(event->parameter, "true") == 0) { myval = 'T'; }
233  else if (strcmp(event->parameter, "false") == 0) { myval = 'F'; }
234  tess_->process_cmd_win_event(event->command_id, &myval);
235  }
236  else {
237  tess_->process_image_event(*event);
238  }
239 }
240 
246 namespace tesseract {
248  SVMenuNode* parent_menu;
249  SVMenuNode* root_menu_item = new SVMenuNode();
250 
251  SVMenuNode* modes_menu_item = root_menu_item->AddChild("MODES");
252 
253  modes_menu_item->AddChild("Change Display", CHANGE_DISP_CMD_EVENT);
254  modes_menu_item->AddChild("Dump Word", DUMP_WERD_CMD_EVENT);
255  modes_menu_item->AddChild("Show Point", SHOW_POINT_CMD_EVENT);
256  modes_menu_item->AddChild("Show BL Norm Word", SHOW_BLN_WERD_CMD_EVENT);
257  modes_menu_item->AddChild("Config Words", DEBUG_WERD_CMD_EVENT);
258  modes_menu_item->AddChild("Recog Words", RECOG_WERDS);
259  modes_menu_item->AddChild("Recog Blobs", RECOG_PSEUDO);
260  modes_menu_item->AddChild("Show Blob Features", SHOW_BLOB_FEATURES);
261 
262  parent_menu = root_menu_item->AddChild("DISPLAY");
263 
264  parent_menu->AddChild("Blamer", BLAMER_CMD_EVENT, FALSE);
265  parent_menu->AddChild("Bounding Boxes", BOUNDING_BOX_CMD_EVENT, FALSE);
266  parent_menu->AddChild("Correct Text", CORRECT_TEXT_CMD_EVENT, FALSE);
267  parent_menu->AddChild("Polygonal Approx", POLYGONAL_CMD_EVENT, FALSE);
268  parent_menu->AddChild("Baseline Normalized", BL_NORM_CMD_EVENT, FALSE);
269  parent_menu->AddChild("Edge Steps", BITMAP_CMD_EVENT, TRUE);
270  parent_menu->AddChild("Subscripts", SHOW_SUBSCRIPT_CMD_EVENT);
271  parent_menu->AddChild("Superscripts", SHOW_SUPERSCRIPT_CMD_EVENT);
272  parent_menu->AddChild("Italics", SHOW_ITALIC_CMD_EVENT);
273  parent_menu->AddChild("Bold", SHOW_BOLD_CMD_EVENT);
274  parent_menu->AddChild("Underline", SHOW_UNDERLINE_CMD_EVENT);
275  parent_menu->AddChild("FixedPitch", SHOW_FIXEDPITCH_CMD_EVENT);
276  parent_menu->AddChild("Serifs", SHOW_SERIF_CMD_EVENT);
277  parent_menu->AddChild("SmallCaps", SHOW_SMALLCAPS_CMD_EVENT);
278  parent_menu->AddChild("DropCaps", SHOW_DROPCAPS_CMD_EVENT);
279 
280 
281  parent_menu = root_menu_item->AddChild("OTHER");
282 
283  parent_menu->AddChild("Quit", QUIT_CMD_EVENT);
284  parent_menu->AddChild("Show Image", IMAGE_CMD_EVENT, FALSE);
285  parent_menu->AddChild("ShowBlock Outlines", BLOCKS_CMD_EVENT, FALSE);
286  parent_menu->AddChild("Show Baselines", BASELINES_CMD_EVENT, FALSE);
287  parent_menu->AddChild("Uniform Display", UNIFORM_DISP_CMD_EVENT);
288  parent_menu->AddChild("Refresh Display", REFRESH_CMD_EVENT);
289 
290  return root_menu_item;
291 }
292 
299  bool (tesseract::Tesseract::* word_painter)(PAGE_RES_IT* pr_it)) {
300  int block_count = 1;
301 
302  image_win->Clear();
303  if (display_image != 0) {
304  image_win->Image(pix_binary_, 0, 0);
305  }
306 
307  image_win->Brush(ScrollView::NONE);
309  for (WERD_RES* word = pr_it.word(); word != nullptr; word = pr_it.forward()) {
310  (this->*word_painter)(&pr_it);
311  if (display_baselines && pr_it.row() != pr_it.prev_row())
312  pr_it.row()->row->plot_baseline(image_win, ScrollView::GREEN);
313  if (display_blocks && pr_it.block() != pr_it.prev_block())
314  pr_it.block()->block->pdblk.plot(image_win, block_count++, ScrollView::RED);
315  }
316  image_win->Update();
317 }
318 
327 void Tesseract::pgeditor_main(int width, int height, PAGE_RES *page_res) {
328  current_page_res = page_res;
329  if (current_page_res->block_res_list.empty())
330  return;
331 
332  recog_done = false;
333  stillRunning = true;
334 
335  build_image_window(width, height);
338 #ifndef GRAPHICS_DISABLED
339  pe = new ParamsEditor(this, image_win);
340 #endif
341  PGEventHandler pgEventHandler(this);
342 
343  image_win->AddEventHandler(&pgEventHandler);
344  image_win->AddMessageBox();
345 
346  SVMenuNode* svMenuRoot = build_menu_new();
347 
348  svMenuRoot->BuildMenu(image_win);
349  image_win->SetVisible(true);
350 
351  image_win->AwaitEvent(SVET_DESTROY);
352  image_win->AddEventHandler(nullptr);
353 }
354 } // namespace tesseract
355 
356 
363 void pgeditor_msg( // message display
364  const char *msg) {
365  image_win->AddMessage(msg);
366 }
367 
374 void pgeditor_show_point( // display coords
375  SVEvent *event) {
376  image_win->AddMessage("Pointing at(%d, %d)", event->x, event->y);
377 }
378 
386 namespace tesseract {
387 bool Tesseract::process_cmd_win_event( // UI command semantics
388  int32_t cmd_event, // which menu item?
389  char* new_value // any prompt data
390 ) {
391  char msg[160];
392  bool exit = false;
393 
394  color_mode = CM_RAINBOW;
395 
396  // Run recognition on the full page if needed.
397  switch (cmd_event) {
398  case BLAMER_CMD_EVENT:
402  case SHOW_BOLD_CMD_EVENT:
408  if (!recog_done) {
409  recog_all_words(current_page_res, nullptr, nullptr, nullptr, 0);
410  recog_done = true;
411  }
412  break;
413  default:
414  break;
415  }
416 
417  char* parameter;
418 
419  switch (cmd_event) {
420  case NULL_CMD_EVENT:
421  break;
422 
424  case DUMP_WERD_CMD_EVENT:
427  case RECOG_WERDS:
428  case RECOG_PSEUDO:
429  case SHOW_BLOB_FEATURES:
430  mode =(CMD_EVENTS) cmd_event;
431  break;
433  mode = DEBUG_WERD_CMD_EVENT;
434  parameter = image_win->ShowInputDialog("Config File Name");
435  word_config_ = parameter;
436  delete[] parameter;
437  break;
439  if (new_value[0] == 'T')
441  else
443  mode = CHANGE_DISP_CMD_EVENT;
444  break;
445  case BLAMER_CMD_EVENT:
446  if (new_value[0] == 'T')
448  else
451  mode = CHANGE_DISP_CMD_EVENT;
452  break;
454  if (new_value[0] == 'T')
456  else
458  mode = CHANGE_DISP_CMD_EVENT;
459  break;
460  case POLYGONAL_CMD_EVENT:
461  if (new_value[0] == 'T')
463  else
465  mode = CHANGE_DISP_CMD_EVENT;
466  break;
467  case BL_NORM_CMD_EVENT:
468  if (new_value[0] == 'T')
470  else
472  mode = CHANGE_DISP_CMD_EVENT;
473  break;
474  case BITMAP_CMD_EVENT:
475  if (new_value[0] == 'T')
477  else
479  mode = CHANGE_DISP_CMD_EVENT;
480  break;
483  break;
484  case IMAGE_CMD_EVENT:
485  display_image =(new_value[0] == 'T');
487  break;
488  case BLOCKS_CMD_EVENT:
489  display_blocks =(new_value[0] == 'T');
491  break;
492  case BASELINES_CMD_EVENT:
493  display_baselines =(new_value[0] == 'T');
495  break;
497  color_mode = CM_SUBSCRIPT;
499  break;
501  color_mode = CM_SUPERSCRIPT;
503  break;
505  color_mode = CM_ITALIC;
507  break;
508  case SHOW_BOLD_CMD_EVENT:
509  color_mode = CM_BOLD;
511  break;
513  color_mode = CM_UNDERLINE;
515  break;
517  color_mode = CM_FIXEDPITCH;
519  break;
521  color_mode = CM_SERIF;
523  break;
525  color_mode = CM_SMALLCAPS;
527  break;
529  color_mode = CM_DROPCAPS;
531  break;
532  case REFRESH_CMD_EVENT:
534  break;
535  case QUIT_CMD_EVENT:
536  exit = true;
538  break;
539 
540  default:
541  snprintf(msg, sizeof(msg), "Unrecognised event %" PRId32 "(%s)",
542  cmd_event, new_value);
543  image_win->AddMessage(msg);
544  break;
545  }
546  return exit;
547 }
548 
549 
559 void Tesseract::process_image_event( // action in image win
560  const SVEvent &event) {
561  // The following variable should remain static, since it is used by
562  // debug editor, which uses a single Tesseract instance.
563  static ICOORD down;
564  ICOORD up;
565  TBOX selection_box;
566  char msg[80];
567 
568  switch(event.type) {
569 
570  case SVET_SELECTION:
571  if (event.type == SVET_SELECTION) {
572  down.set_x(event.x + event.x_size);
573  down.set_y(event.y + event.y_size);
574  if (mode == SHOW_POINT_CMD_EVENT)
575  show_point(current_page_res, event.x, event.y);
576  }
577 
578  up.set_x(event.x);
579  up.set_y(event.y);
580 
581  selection_box = TBOX(down, up);
582 
583  switch(mode) {
587  selection_box,
589  break;
590  case DUMP_WERD_CMD_EVENT:
592  selection_box,
594  break;
597  selection_box,
599  break;
601  debug_word(current_page_res, selection_box);
602  break;
604  break; // ignore up event
605 
606  case RECOG_WERDS:
607  #ifndef DISABLED_LEGACY_ENGINE
608  image_win->AddMessage("Recogging selected words");
609  this->process_selected_words(current_page_res,
610  selection_box,
612  #endif // ndef DISABLED_LEGACY_ENGINE
613  break;
614  case RECOG_PSEUDO:
615  image_win->AddMessage("Recogging selected blobs");
616  recog_pseudo_word(current_page_res, selection_box);
617  break;
618  case SHOW_BLOB_FEATURES:
619  blob_feature_display(current_page_res, selection_box);
620  break;
621 
622  default:
623  sprintf(msg, "Mode %d not yet implemented", mode);
624  image_win->AddMessage(msg);
625  break;
626  }
627  default:
628  break;
629  }
630 }
631 
637 void Tesseract::debug_word(PAGE_RES* page_res, const TBOX &selection_box) {
638 #ifndef DISABLED_LEGACY_ENGINE
640 #endif
641  recog_all_words(page_res, nullptr, &selection_box, word_config_.string(), 0);
642 }
643 } // namespace tesseract
644 
645 
653 void show_point(PAGE_RES* page_res, float x, float y) {
654  FCOORD pt(x, y);
655  PAGE_RES_IT pr_it(page_res);
656 
657  const int kBufsize = 512;
658  char msg[kBufsize];
659  char *msg_ptr = msg;
660 
661  msg_ptr += sprintf(msg_ptr, "Pt:(%0.3f, %0.3f) ", x, y);
662 
663  for (WERD_RES* word = pr_it.word(); word != nullptr; word = pr_it.forward()) {
664  if (pr_it.row() != pr_it.prev_row() &&
665  pr_it.row()->row->bounding_box().contains(pt)) {
666  msg_ptr += sprintf(msg_ptr, "BL(x)=%0.3f ",
667  pr_it.row()->row->base_line(x));
668  }
669  if (word->word->bounding_box().contains(pt)) {
670  TBOX box = word->word->bounding_box();
671  msg_ptr += sprintf(msg_ptr, "Wd(%d, %d)/(%d, %d) ",
672  box.left(), box.bottom(),
673  box.right(), box.top());
674  C_BLOB_IT cblob_it(word->word->cblob_list());
675  for (cblob_it.mark_cycle_pt();
676  !cblob_it.cycled_list();
677  cblob_it.forward()) {
678  C_BLOB* cblob = cblob_it.data();
679  box = cblob->bounding_box();
680  if (box.contains(pt)) {
681  msg_ptr += sprintf(msg_ptr,
682  "CBlb(%d, %d)/(%d, %d) ",
683  box.left(), box.bottom(),
684  box.right(), box.top());
685  }
686  }
687  }
688  }
689  image_win->AddMessage(msg);
690 }
691 
692 
693 /**********************************************************************
694  * WERD PROCESSOR FUNCTIONS
695  * ========================
696  *
697  * These routines are invoked by one or more of:
698  * process_all_words()
699  * process_selected_words()
700  * or
701  * process_all_words_it()
702  * process_selected_words_it()
703  * for each word to be processed
704  **********************************************************************/
705 
712 #endif // GRAPHICS_DISABLED
713 namespace tesseract {
714 #ifndef GRAPHICS_DISABLED
716  pr_it->word()->word->bounding_box().plot(image_win, ScrollView::BLACK,
718  return word_set_display(pr_it);
719 }
720 
721 
728  WERD_RES* word_res = pr_it->word();
729  if (word_res->chopped_word == nullptr) {
730  // Setup word normalization parameters.
731  word_res->SetupForRecognition(unicharset, this, BestPix(),
732  tessedit_ocr_engine_mode, nullptr,
736  pr_it->row()->row, pr_it->block()->block);
737  }
739  display_bln_lines(bln_word_window_handle(), ScrollView::CYAN,
740  1.0, 0.0f, -1000.0f, 1000.0f);
741  C_BLOB_IT it(word_res->word->cblob_list());
743  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
744  it.data()->plot_normed(word_res->denorm, color, ScrollView::BROWN,
746  color = WERD::NextColor(color);
747  }
749  return true;
750 }
751 
752 
753 
760  WERD_RES* word_res = pr_it->word();
761  WERD* word = word_res->word;
762  TBOX word_bb; // word bounding box
763  int word_height; // ht of word BB
764  bool displayed_something = false;
765  float shift; // from bot left
766 
767  if (color_mode != CM_RAINBOW && word_res->box_word != nullptr) {
768  BoxWord* box_word = word_res->box_word;
769  WERD_CHOICE* best_choice = word_res->best_choice;
770  int length = box_word->length();
771  if (word_res->fontinfo == nullptr) return false;
772  const FontInfo& font_info = *word_res->fontinfo;
773  for (int i = 0; i < length; ++i) {
775  switch (color_mode) {
776  case CM_SUBSCRIPT:
777  if (best_choice->BlobPosition(i) == SP_SUBSCRIPT)
778  color = ScrollView::RED;
779  break;
780  case CM_SUPERSCRIPT:
781  if (best_choice->BlobPosition(i) == SP_SUPERSCRIPT)
782  color = ScrollView::RED;
783  break;
784  case CM_ITALIC:
785  if (font_info.is_italic())
786  color = ScrollView::RED;
787  break;
788  case CM_BOLD:
789  if (font_info.is_bold())
790  color = ScrollView::RED;
791  break;
792  case CM_FIXEDPITCH:
793  if (font_info.is_fixed_pitch())
794  color = ScrollView::RED;
795  break;
796  case CM_SERIF:
797  if (font_info.is_serif())
798  color = ScrollView::RED;
799  break;
800  case CM_SMALLCAPS:
801  if (word_res->small_caps)
802  color = ScrollView::RED;
803  break;
804  case CM_DROPCAPS:
805  if (best_choice->BlobPosition(i) == SP_DROPCAP)
806  color = ScrollView::RED;
807  break;
808  // TODO(rays) underline is currently completely unsupported.
809  case CM_UNDERLINE:
810  default:
811  break;
812  }
813  image_win->Pen(color);
814  TBOX box = box_word->BlobBox(i);
815  image_win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
816  }
817  return true;
818  }
819  /*
820  Note the double coercions of(COLOUR)((int32_t)editor_image_word_bb_color)
821  etc. are to keep the compiler happy.
822  */
823  // display bounding box
824  if (word->display_flag(DF_BOX)) {
825  word->bounding_box().plot(image_win,
826  (ScrollView::Color)((int32_t)
828  (ScrollView::Color)((int32_t)
830 
832  ((int32_t) editor_image_blob_bb_color);
833  image_win->Pen(c);
834  // cblob iterator
835  C_BLOB_IT c_it(word->cblob_list());
836  for (c_it.mark_cycle_pt(); !c_it.cycled_list(); c_it.forward())
837  c_it.data()->bounding_box().plot(image_win);
838  displayed_something = true;
839  }
840 
841  // display edge steps
842  if (word->display_flag(DF_EDGE_STEP)) { // edgesteps available
843  word->plot(image_win); // rainbow colors
844  displayed_something = true;
845  }
846 
847  // display poly approx
848  if (word->display_flag(DF_POLYGONAL)) {
849  // need to convert
851  tword->plot(image_win);
852  delete tword;
853  displayed_something = true;
854  }
855 
856  // Display correct text and blamer information.
857  STRING text;
858  STRING blame;
859  if (word->display_flag(DF_TEXT) && word->text() != nullptr) {
860  text = word->text();
861  }
862  if (word->display_flag(DF_BLAMER) &&
863  !(word_res->blamer_bundle != nullptr &&
865  text = "";
866  const BlamerBundle *blamer_bundle = word_res->blamer_bundle;
867  if (blamer_bundle == nullptr) {
868  text += "NULL";
869  } else {
870  text = blamer_bundle->TruthString();
871  }
872  text += " -> ";
873  STRING best_choice_str;
874  if (word_res->best_choice == nullptr) {
875  best_choice_str = "NULL";
876  } else {
877  word_res->best_choice->string_and_lengths(&best_choice_str, nullptr);
878  }
879  text += best_choice_str;
880  IncorrectResultReason reason = (blamer_bundle == nullptr) ?
881  IRR_PAGE_LAYOUT : blamer_bundle->incorrect_result_reason();
882  ASSERT_HOST(reason < IRR_NUM_REASONS)
883  blame += " [";
884  blame += BlamerBundle::IncorrectReasonName(reason);
885  blame += "]";
886  }
887  if (text.length() > 0) {
888  word_bb = word->bounding_box();
889  image_win->Pen(ScrollView::RED);
890  word_height = word_bb.height();
891  int text_height = 0.50 * word_height;
892  if (text_height > 20) text_height = 20;
893  image_win->TextAttributes("Arial", text_height, false, false, false);
894  shift = (word_height < word_bb.width()) ? 0.25 * word_height : 0.0f;
895  image_win->Text(word_bb.left() + shift,
896  word_bb.bottom() + 0.25 * word_height, text.string());
897  if (blame.length() > 0) {
898  image_win->Text(word_bb.left() + shift,
899  word_bb.bottom() + 0.25 * word_height - text_height,
900  blame.string());
901  }
902 
903  displayed_something = true;
904  }
905 
906  if (!displayed_something) // display BBox anyway
907  word->bounding_box().plot(image_win,
909  (ScrollView::Color)((int32_t)
911  return true;
912 }
913 #endif // GRAPHICS_DISABLED
914 
921  if (pr_it->block()->block != nullptr) {
922  tprintf("\nBlock data...\n");
923  pr_it->block()->block->print(nullptr, false);
924  }
925  tprintf("\nRow data...\n");
926  pr_it->row()->row->print(nullptr);
927  tprintf("\nWord data...\n");
928  WERD_RES* word_res = pr_it->word();
929  word_res->word->print();
930  if (word_res->blamer_bundle != nullptr && wordrec_debug_blamer &&
932  tprintf("Current blamer debug: %s\n",
933  word_res->blamer_bundle->debug().string());
934  }
935  return true;
936 }
937 
938 #ifndef GRAPHICS_DISABLED
939 
945  WERD* word = pr_it->word()->word;
953  return word_display(pr_it);
954 }
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.
960  const TBOX& selection_box) {
961 #ifndef DISABLED_LEGACY_ENGINE
962  PAGE_RES_IT* it = make_pseudo_word(page_res, selection_box);
963  if (it != nullptr) {
964  WERD_RES* word_res = it->word();
965  word_res->x_height = it->row()->row->x_height();
966  word_res->SetupForRecognition(unicharset, this, BestPix(),
967  tessedit_ocr_engine_mode, nullptr,
971  it->row()->row, it->block()->block);
972  TWERD* bln_word = word_res->chopped_word;
973  TBLOB* bln_blob = bln_word->blobs[0];
974  INT_FX_RESULT_STRUCT fx_info;
977  Classify::ExtractFeatures(*bln_blob, classify_nonlinear_norm, &bl_features,
978  &cn_features, &fx_info, nullptr);
979  // Display baseline features.
980  ScrollView* bl_win = CreateFeatureSpaceWindow("BL Features", 512, 0);
982  for (int f = 0; f < bl_features.size(); ++f)
983  RenderIntFeature(bl_win, &bl_features[f], ScrollView::GREEN);
984  bl_win->Update();
985  // Display cn features.
986  ScrollView* cn_win = CreateFeatureSpaceWindow("CN Features", 512, 0);
988  for (int f = 0; f < cn_features.size(); ++f)
989  RenderIntFeature(cn_win, &cn_features[f], ScrollView::GREEN);
990  cn_win->Update();
991 
992  it->DeleteCurrentWord();
993  delete it;
994  }
995 #endif // ndef DISABLED_LEGACY_ENGINE
996 }
997 
998 
999 #endif // GRAPHICS_DISABLED
1000 
1001 } // namespace tesseract
BLOCK_RES * block() const
Definition: pageres.h:757
int editor_image_blob_bb_color
Definition: pgedit.cpp:131
BOOL8 display_baselines
Definition: pgedit.cpp:119
const STRING & debug() const
Definition: blamer.h:128
int editor_dbwin_width
Definition: pgedit.cpp:140
const ERRCODE EMPTYBLOCKLIST
Definition: pgedit.cpp:48
void plot_baseline(ScrollView *window, ScrollView::Color colour)
Definition: ocrrow.h:137
void AddMessageBox()
Definition: scrollview.cpp:580
void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined)
Definition: scrollview.cpp:637
int size() const
Definition: genericvector.h:71
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:998
#define TRUE
Definition: capi.h:51
Definition: blobs.h:402
ROW_RES * row() const
Definition: pageres.h:754
static void ExtractFeatures(const TBLOB &blob, bool nonlinear_norm, GenericVector< INT_FEATURE_STRUCT > *bl_features, GenericVector< INT_FEATURE_STRUCT > *cn_features, INT_FX_RESULT_STRUCT *results, GenericVector< int > *outline_cn_counts)
Definition: intfx.cpp:444
int editor_dbwin_xpos
Definition: pgedit.cpp:137
#define STRING_VAR(name, val, comment)
Definition: params.h:282
BOOL8 display_image
Definition: pgedit.cpp:117
CMD_EVENTS
Definition: pgedit.cpp:50
void SetVisible(bool visible)
Definition: scrollview.cpp:551
IncorrectResultReason
Definition: blamer.h:49
PAGE_RES * current_page_res
Definition: pgedit.cpp:121
bool word_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:759
void print(FILE *fp)
Definition: ocrrow.cpp:167
void set_x(int16_t xin)
rewrite function
Definition: points.h:62
int editor_image_text_color
Definition: pgedit.cpp:133
const char * string() const
Definition: strngs.cpp:196
char * editor_dbwin_name
Definition: pgedit.cpp:136
BOOL8 display_blocks
Definition: pgedit.cpp:118
TBOX bounding_box() const
Definition: werd.cpp:159
static ScrollView::Color NextColor(ScrollView::Color colour)
Definition: werd.cpp:305
float base_line(float xpos) const
Definition: ocrrow.h:59
bool classify_bln_numeric_mode
Definition: classify.h:541
int editor_dbwin_ypos
Definition: pgedit.cpp:138
void plot(ScrollView *window, ScrollView::Color colour)
Definition: werd.cpp:296
Definition: rect.h:34
int editor_image_ypos
Definition: pgedit.cpp:126
void do_re_display(bool(tesseract::Tesseract::*word_painter)(PAGE_RES_IT *pr_it))
Definition: pgedit.cpp:298
ColorationMode
Definition: pgedit.cpp:84
Definition: werd.h:54
const FontInfo * fontinfo
Definition: pageres.h:304
void blob_feature_display(PAGE_RES *page_res, const TBOX &selection_box)
Definition: pgedit.cpp:959
Definition: werd.h:49
int x
Definition: scrollview.h:66
void turn_off_bit(uint8_t bit_num)
Definition: bits16.h:43
bool is_bold() const
Definition: fontinfo.h:112
void build_image_window(int width, int height)
Definition: pgedit.cpp:186
void process_image_event(const SVEvent &event)
Definition: pgedit.cpp:559
BLOCK_RES_LIST block_res_list
Definition: pageres.h:81
static const char * IncorrectReasonName(IncorrectResultReason irr)
Definition: blamer.cpp:61
static void Update()
Definition: scrollview.cpp:711
void pgeditor_show_point(SVEvent *event)
Definition: pgedit.cpp:374
const TBOX & BlobBox(int index) const
Definition: boxword.h:84
void plot(ScrollView *window, int32_t serial, ScrollView::Color colour)
Definition: pdblock.cpp:180
Pix * BestPix() const
bool classify_nonlinear_norm
Definition: classify.h:457
int editor_word_height
Definition: pgedit.cpp:145
static void Exit()
Definition: scrollview.cpp:585
bool small_caps
Definition: pageres.h:299
bool bit(uint8_t bit_num) const
Definition: bits16.h:57
int editor_image_menuheight
Definition: pgedit.cpp:127
char * editor_debug_config_file
Definition: pgedit.cpp:148
int16_t width() const
Definition: rect.h:115
#define X_HEIGHT
Definition: pgedit.cpp:43
void print()
Definition: werd.cpp:265
void Notify(const SVEvent *sve)
Definition: paramsd.cpp:265
BLOCK * block
Definition: pageres.h:117
int16_t left() const
Definition: rect.h:72
void plot(ScrollView *fd) const
Definition: rect.h:286
void turn_on_bit(uint8_t bit_num)
Definition: bits16.h:38
void print(FILE *fp, bool dump)
dump whole table
Definition: ocrblock.cpp:194
int16_t top() const
Definition: rect.h:58
ROW_RES * prev_row() const
Definition: pageres.h:745
DENORM denorm
Definition: pageres.h:204
ScrollView * bln_word_window_handle()
Definition: pgedit.cpp:165
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:445
float x_height() const
Definition: ocrrow.h:64
const char * text() const
Definition: werd.h:123
int editor_image_xpos
Definition: pgedit.cpp:125
char * ShowInputDialog(const char *msg)
Definition: scrollview.cpp:736
#define BL_HEIGHT
Definition: pgedit.cpp:44
UNICHARSET unicharset
Definition: ccutil.h:68
integer coordinate
Definition: points.h:32
bool word_blank_and_set_display(PAGE_RES_IT *pr_its)
Definition: pgedit.cpp:715
bool is_italic() const
Definition: fontinfo.h:111
#define FALSE
Definition: capi.h:52
void pgeditor_main(int width, int height, PAGE_RES *page_res)
Definition: pgedit.cpp:327
int y_size
Definition: scrollview.h:69
void Text(int x, int y, const char *mystring)
Definition: scrollview.cpp:654
bool recog_all_words(PAGE_RES *page_res, ETEXT_DESC *monitor, const TBOX *target_word_box, const char *word_config, int dopasses)
Definition: control.cpp:308
SVMenuNode * build_menu_new()
Definition: pgedit.cpp:247
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:58
IncorrectResultReason incorrect_result_reason() const
Definition: blamer.h:118
int x_size
Definition: scrollview.h:68
bool process_cmd_win_event(int32_t cmd_event, char *new_value)
Definition: pgedit.cpp:387
bool word_bln_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:727
void show_point(PAGE_RES *page_res, float x, float y)
Definition: pgedit.cpp:653
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
Definition: scrollview.cpp:416
STRING TruthString() const
Definition: blamer.h:112
bool word_set_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:944
void plot(ScrollView *window)
Definition: blobs.cpp:907
WERD_RES * word() const
Definition: pageres.h:751
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:308
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1628
SVEventType type
Definition: scrollview.h:64
Definition: werd.h:59
bool display_flag(uint8_t flag) const
Definition: werd.h:129
TBOX bounding_box() const
Definition: ocrrow.h:88
void Image(struct Pix *image, int x_pos, int y_pos)
Definition: scrollview.cpp:768
unsigned char BOOL8
Definition: host.h:34
int editor_word_width
Definition: pgedit.cpp:146
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:37
int editor_word_xpos
Definition: pgedit.cpp:143
C_BLOB_LIST * cblob_list()
Definition: werd.h:98
BLOCK_RES * prev_block() const
Definition: pageres.h:748
void Notify(const SVEvent *sv_event)
Definition: pgedit.cpp:152
GenericVector< TBLOB * > blobs
Definition: blobs.h:443
void string_and_lengths(STRING *word_str, STRING *word_lengths_str) const
Definition: ratngs.cpp:449
#define DESC_HEIGHT
Definition: pgedit.cpp:45
void recog_pseudo_word(PAGE_RES *page_res, TBOX &selection_box)
Definition: control.cpp:67
int editor_dbwin_height
Definition: pgedit.cpp:139
bool word_dumper(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:920
float x_height
Definition: pageres.h:311
Definition: strngs.h:45
int command_id
Definition: scrollview.h:70
TBOX bounding_box() const
Definition: stepblob.cpp:255
void DeleteCurrentWord()
Definition: pageres.cpp:1450
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1789
char * parameter
Definition: scrollview.h:71
bool contains(const FCOORD pt) const
Definition: rect.h:333
int length() const
Definition: boxword.h:83
BlamerBundle * blamer_bundle
Definition: pageres.h:246
char * editor_word_name
Definition: pgedit.cpp:142
Definition: points.h:189
void Clear()
Definition: scrollview.cpp:591
PAGE_RES_IT * make_pseudo_word(PAGE_RES *page_res, const TBOX &selection_box)
Definition: werdit.cpp:35
bool is_serif() const
Definition: fontinfo.h:114
tesseract::ScriptPos BlobPosition(int index) const
Definition: ratngs.h:322
void process_selected_words(PAGE_RES *page_res, TBOX &selection_box, bool(tesseract::Tesseract::*word_processor)(PAGE_RES_IT *pr_it))
Definition: pagewalk.cpp:30
int16_t right() const
Definition: rect.h:79
Definition: bits16.h:25
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:602
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:120
WERD_RES * forward()
Definition: pageres.h:731
bool is_fixed_pitch() const
Definition: fontinfo.h:113
Definition: blobs.h:268
void pgeditor_msg(const char *msg)
Definition: pgedit.cpp:363
bool wordrec_debug_blamer
Definition: wordrec.h:236
static TWERD * PolygonalCopy(bool allow_detailed_fx, WERD *src)
Definition: blobs.cpp:786
char * editor_image_win_name
Definition: pgedit.cpp:124
int editor_word_ypos
Definition: pgedit.cpp:144
TWERD * chopped_word
Definition: pageres.h:215
bool recog_interactive(PAGE_RES_IT *pr_it)
Definition: control.cpp:82
int y
Definition: scrollview.h:67
void Pen(Color color)
Definition: scrollview.cpp:722
void set_y(int16_t yin)
rewrite function
Definition: points.h:66
void Notify(const SVEvent *sve)
Definition: pgedit.cpp:225
int16_t bottom() const
Definition: rect.h:65
Definition: werd.h:50
PDBLK pdblk
Definition: ocrblock.h:192
int32_t length() const
Definition: strngs.cpp:191
WERD_CHOICE * best_choice
Definition: pageres.h:235
int16_t height() const
Definition: rect.h:108
tesseract::BoxWord * box_word
Definition: pageres.h:266
void set_display_flag(uint8_t flag, bool value)
Definition: werd.h:130
#define INT_VAR(name, val, comment)
Definition: params.h:276
void Line(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:534
int editor_image_word_bb_color
Definition: pgedit.cpp:129
ROW * row
Definition: pageres.h:143
void AddMessage(const char *format,...)
Definition: scrollview.cpp:563
#define ASSERT_HOST(x)
Definition: errcode.h:84
void debug_word(PAGE_RES *page_res, const TBOX &selection_box)
Definition: pgedit.cpp:637
#define ASC_HEIGHT
Definition: pgedit.cpp:42
WERD * word
Definition: pageres.h:189
void Brush(Color color)
Definition: scrollview.cpp:728
BITS16 word_display_mode
Definition: pgedit.cpp:115