Tesseract  3.02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 "svshowim.h"
37 #include "paramsd.h"
38 #include "pageres.h"
39 #include "tordmain.h"
40 #include "scrollview.h"
41 #include "svmnode.h"
42 #include "statistc.h"
43 #include "tesseractclass.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 {
85 };
86 
98 };
99 
100 /*
101  *
102  * Some global data
103  *
104  */
105 
108 bool stillRunning = false;
109 
110 #ifdef __UNIX__
111 FILE *debug_window = NULL; // opened on demand
112 #endif
113 ScrollView* bln_word_window = NULL; // baseline norm words
114 
115 CMD_EVENTS mode = CHANGE_DISP_CMD_EVENT; // selected words op
116 
117 bool recog_done = false; // recog_all_words was called
118 
119 // These variables should remain global, since they are only used for the
120 // debug mode (in which only a single Tesseract thread/instance will be exist).
122 static ColorationMode color_mode = CM_RAINBOW;
126 
128 
129 STRING_VAR(editor_image_win_name, "EditorImage",
130  "Editor image window name");
131 INT_VAR(editor_image_xpos, 590, "Editor image X Pos");
132 INT_VAR(editor_image_ypos, 10, "Editor image Y Pos");
133 INT_VAR(editor_image_menuheight, 50, "Add to image height for menu bar");
135  "Word bounding box colour");
137  "Blob bounding box colour");
139  "Correct text colour");
140 
141 STRING_VAR(editor_dbwin_name, "EditorDBWin",
142  "Editor debug window name");
143 INT_VAR(editor_dbwin_xpos, 50, "Editor debug window X Pos");
144 INT_VAR(editor_dbwin_ypos, 500, "Editor debug window Y Pos");
145 INT_VAR(editor_dbwin_height, 24, "Editor debug window height");
146 INT_VAR(editor_dbwin_width, 80, "Editor debug window width");
147 
148 STRING_VAR(editor_word_name, "BlnWords", "BL normalized word window");
149 INT_VAR(editor_word_xpos, 60, "Word window X Pos");
150 INT_VAR(editor_word_ypos, 510, "Word window Y Pos");
151 INT_VAR(editor_word_height, 240, "Word window height");
152 INT_VAR(editor_word_width, 655, "Word window width");
153 
154 STRING_VAR(editor_debug_config_file, "", "Config file to apply to single words");
155 
157  public:
158  void Notify(const SVEvent* sv_event) {
159  if (sv_event->type == SVET_DESTROY)
160  bln_word_window = NULL;
161  else if (sv_event->type == SVET_CLICK)
162  show_point(current_page_res, sv_event->x, sv_event->y);
163  }
164 };
165 
171 ScrollView* bln_word_window_handle() { // return handle
172  // not opened yet
173  if (bln_word_window == NULL) {
174  pgeditor_msg("Creating BLN word window...");
175  bln_word_window = new ScrollView(editor_word_name.string(),
177  editor_word_height, 4000, 4000, true);
178  BlnEventHandler* a = new BlnEventHandler();
179  bln_word_window->AddEventHandler(a);
180  pgeditor_msg("Creating BLN word window...Done");
181  }
182  return bln_word_window;
183 }
184 
192 void build_image_window(int width, int height) {
193  if (image_win != NULL) { delete image_win; }
194  image_win = new ScrollView(editor_image_win_name.string(),
196  width + 1,
197  height + editor_image_menuheight + 1,
198  width,
199  height,
200  true);
201 }
202 
210  ScrollView::Color colour,
211  float scale_factor,
212  float y_offset,
213  float minx,
214  float maxx) {
215  window->Pen(colour);
216  window->Line(minx, y_offset + scale_factor * DESC_HEIGHT,
217  maxx, y_offset + scale_factor * DESC_HEIGHT);
218  window->Line(minx, y_offset + scale_factor * BL_HEIGHT,
219  maxx, y_offset + scale_factor * BL_HEIGHT);
220  window->Line(minx, y_offset + scale_factor * X_HEIGHT,
221  maxx, y_offset + scale_factor * X_HEIGHT);
222  window->Line(minx, y_offset + scale_factor * ASC_HEIGHT,
223  maxx, y_offset + scale_factor * ASC_HEIGHT);
224 }
225 
234 void PGEventHandler::Notify(const SVEvent* event) {
235  char myval = '0';
236  if (event->type == SVET_POPUP) {
237  pe->Notify(event);
238  } // These are handled by ParamsEditor
239  else if (event->type == SVET_EXIT) { stillRunning = false; }
240  else if (event->type == SVET_MENU) {
241  if (strcmp(event->parameter, "true") == 0) { myval = 'T'; }
242  else if (strcmp(event->parameter, "false") == 0) { myval = 'F'; }
243  tess_->process_cmd_win_event(event->command_id, &myval);
244  }
245  else {
246  tess_->process_image_event(*event);
247  }
248 }
249 
255 namespace tesseract {
257  SVMenuNode* parent_menu;
258  SVMenuNode* root_menu_item = new SVMenuNode();
259 
260  SVMenuNode* modes_menu_item = root_menu_item->AddChild("MODES");
261 
262  modes_menu_item->AddChild("Change Display", CHANGE_DISP_CMD_EVENT);
263  modes_menu_item->AddChild("Dump Word", DUMP_WERD_CMD_EVENT);
264  modes_menu_item->AddChild("Show Point", SHOW_POINT_CMD_EVENT);
265  modes_menu_item->AddChild("Show BL Norm Word", SHOW_BLN_WERD_CMD_EVENT);
266  modes_menu_item->AddChild("Config Words", DEBUG_WERD_CMD_EVENT);
267  modes_menu_item->AddChild("Recog Words", RECOG_WERDS);
268  modes_menu_item->AddChild("Recog Blobs", RECOG_PSEUDO);
269 
270  parent_menu = root_menu_item->AddChild("DISPLAY");
271 
272  parent_menu->AddChild("Blamer", BLAMER_CMD_EVENT, FALSE);
273  parent_menu->AddChild("Bounding Boxes", BOUNDING_BOX_CMD_EVENT, FALSE);
274  parent_menu->AddChild("Correct Text", CORRECT_TEXT_CMD_EVENT, FALSE);
275  parent_menu->AddChild("Polygonal Approx", POLYGONAL_CMD_EVENT, FALSE);
276  parent_menu->AddChild("Baseline Normalized", BL_NORM_CMD_EVENT, FALSE);
277  parent_menu->AddChild("Edge Steps", BITMAP_CMD_EVENT, TRUE);
278  parent_menu->AddChild("Subscripts", SHOW_SUBSCRIPT_CMD_EVENT);
279  parent_menu->AddChild("Superscripts", SHOW_SUPERSCRIPT_CMD_EVENT);
280  parent_menu->AddChild("Italics", SHOW_ITALIC_CMD_EVENT);
281  parent_menu->AddChild("Bold", SHOW_BOLD_CMD_EVENT);
282  parent_menu->AddChild("Underline", SHOW_UNDERLINE_CMD_EVENT);
283  parent_menu->AddChild("FixedPitch", SHOW_FIXEDPITCH_CMD_EVENT);
284  parent_menu->AddChild("Serifs", SHOW_SERIF_CMD_EVENT);
285  parent_menu->AddChild("SmallCaps", SHOW_SMALLCAPS_CMD_EVENT);
286  parent_menu->AddChild("DropCaps", SHOW_DROPCAPS_CMD_EVENT);
287 
288 
289  parent_menu = root_menu_item->AddChild("OTHER");
290 
291  parent_menu->AddChild("Quit", QUIT_CMD_EVENT);
292  parent_menu->AddChild("Show Image", IMAGE_CMD_EVENT, FALSE);
293  parent_menu->AddChild("ShowBlock Outlines", BLOCKS_CMD_EVENT, FALSE);
294  parent_menu->AddChild("Show Baselines", BASELINES_CMD_EVENT, FALSE);
295  parent_menu->AddChild("Uniform Display", UNIFORM_DISP_CMD_EVENT);
296  parent_menu->AddChild("Refresh Display", REFRESH_CMD_EVENT);
297 
298  return root_menu_item;
299 }
300 
307  BOOL8 (tesseract::Tesseract::*word_painter)(BLOCK* block,
308  ROW* row,
309  WERD_RES* word_res)) {
310  PAGE_RES_IT pr_it(current_page_res);
311  int block_count = 1;
312 
313  image_win->Clear();
314  if (display_image != 0) {
315  image_win->Image(pix_binary_, 0, 0);
316  }
317 
318  for (WERD_RES* word = pr_it.word(); word != NULL; word = pr_it.forward()) {
319  (this->*word_painter)(pr_it.block()->block, pr_it.row()->row, word);
320  if (display_baselines && pr_it.row() != pr_it.prev_row())
321  pr_it.row()->row->plot_baseline(image_win, ScrollView::GREEN);
322  if (display_blocks && pr_it.block() != pr_it.prev_block())
323  pr_it.block()->block->plot(image_win, block_count++, ScrollView::RED);
324  }
325  image_win->Update();
326 }
327 
336 void Tesseract::pgeditor_main(int width, int height, PAGE_RES *page_res) {
337  current_page_res = page_res;
338  if (current_page_res->block_res_list.empty())
339  return;
340 
341  recog_done = false;
342  stillRunning = true;
343 
344  build_image_window(width, height);
345  word_display_mode.turn_on_bit(DF_EDGE_STEP);
347 #ifndef GRAPHICS_DISABLED
348  pe = new ParamsEditor(this, image_win);
349 #endif
350  PGEventHandler pgEventHandler(this);
351 
352  image_win->AddEventHandler(&pgEventHandler);
353  image_win->AddMessageBox();
354 
355  SVMenuNode* svMenuRoot = build_menu_new();
356 
357  svMenuRoot->BuildMenu(image_win);
358  image_win->SetVisible(true);
359 
360  image_win->AwaitEvent(SVET_DESTROY);
361  image_win->AddEventHandler(NULL);
362 }
363 } // namespace tesseract
364 
365 
372 void pgeditor_msg( // message display
373  const char *msg) {
374  image_win->AddMessage(msg);
375 }
376 
383 void pgeditor_show_point( // display coords
384  SVEvent *event) {
385  image_win->AddMessage("Pointing at(%d, %d)", event->x, event->y);
386 }
387 
395 namespace tesseract {
396 BOOL8 Tesseract::process_cmd_win_event( // UI command semantics
397  inT32 cmd_event, // which menu item?
398  char *new_value // any prompt data
399  ) {
400  char msg[160];
401  BOOL8 exit = FALSE;
402 
403  color_mode = CM_RAINBOW;
404 
405  // Run recognition on the full page if needed.
406  switch (cmd_event) {
407  case BLAMER_CMD_EVENT:
411  case SHOW_BOLD_CMD_EVENT:
417  if (!recog_done) {
418  recog_all_words(current_page_res, NULL, NULL, NULL, 0);
419  recog_done = true;
420  }
421  break;
422  default:
423  break;
424  }
425 
426  switch (cmd_event) {
427  case NULL_CMD_EVENT:
428  break;
429 
431  case DUMP_WERD_CMD_EVENT:
434  case RECOG_WERDS:
435  case RECOG_PSEUDO:
436  mode =(CMD_EVENTS) cmd_event;
437  break;
440  word_config_ = image_win->ShowInputDialog("Config File Name");
441  break;
443  if (new_value[0] == 'T')
444  word_display_mode.turn_on_bit(DF_BOX);
445  else
446  word_display_mode.turn_off_bit(DF_BOX);
448  break;
449  case BLAMER_CMD_EVENT:
450  if (new_value[0] == 'T')
451  word_display_mode.turn_on_bit(DF_BLAMER);
452  else
453  word_display_mode.turn_off_bit(DF_BLAMER);
456  break;
458  if (new_value[0] == 'T')
459  word_display_mode.turn_on_bit(DF_TEXT);
460  else
461  word_display_mode.turn_off_bit(DF_TEXT);
463  break;
464  case POLYGONAL_CMD_EVENT:
465  if (new_value[0] == 'T')
466  word_display_mode.turn_on_bit(DF_POLYGONAL);
467  else
468  word_display_mode.turn_off_bit(DF_POLYGONAL);
470  break;
471  case BL_NORM_CMD_EVENT:
472  if (new_value[0] == 'T')
473  word_display_mode.turn_on_bit(DF_BN_POLYGONAL);
474  else
475  word_display_mode.turn_off_bit(DF_BN_POLYGONAL);
477  break;
478  case BITMAP_CMD_EVENT:
479  if (new_value[0] == 'T')
480  word_display_mode.turn_on_bit(DF_EDGE_STEP);
481  else
482  word_display_mode.turn_off_bit(DF_EDGE_STEP);
484  break;
487  break;
488  case IMAGE_CMD_EVENT:
489  display_image =(new_value[0] == 'T');
491  break;
492  case BLOCKS_CMD_EVENT:
493  display_blocks =(new_value[0] == 'T');
495  break;
496  case BASELINES_CMD_EVENT:
497  display_baselines =(new_value[0] == 'T');
499  break;
501  color_mode = CM_SUBSCRIPT;
503  break;
505  color_mode = CM_SUPERSCRIPT;
507  break;
509  color_mode = CM_ITALIC;
511  break;
512  case SHOW_BOLD_CMD_EVENT:
513  color_mode = CM_BOLD;
515  break;
517  color_mode = CM_UNDERLINE;
519  break;
521  color_mode = CM_FIXEDPITCH;
523  break;
525  color_mode = CM_SERIF;
527  break;
529  color_mode = CM_SMALLCAPS;
531  break;
533  color_mode = CM_DROPCAPS;
535  break;
536  case REFRESH_CMD_EVENT:
538  break;
539  case QUIT_CMD_EVENT:
540  exit = TRUE;
542  break;
543 
544  default:
545  sprintf(msg, "Unrecognised event " INT32FORMAT "(%s)",
546  cmd_event, new_value);
547  image_win->AddMessage(msg);
548  break;
549  }
550  return exit;
551 }
552 
553 
563 void Tesseract::process_image_event( // action in image win
564  const SVEvent &event) {
565  // The following variable should remain static, since it is used by
566  // debug editor, which uses a single Tesseract instance.
567  static ICOORD down;
568  ICOORD up;
569  TBOX selection_box;
570  char msg[80];
571 
572  switch(event.type) {
573 
574  case SVET_SELECTION:
575  if (event.type == SVET_SELECTION) {
576  down.set_x(event.x + event.x_size);
577  down.set_y(event.y + event.y_size);
578  if (mode == SHOW_POINT_CMD_EVENT)
579  show_point(current_page_res, event.x, event.y);
580  }
581 
582  up.set_x(event.x);
583  up.set_y(event.y);
584 
585  selection_box = TBOX(down, up);
586 
587  switch(mode) {
590  current_page_res,
591  selection_box,
593  break;
594  case DUMP_WERD_CMD_EVENT:
595  process_selected_words(current_page_res,
596  selection_box,
598  break;
600  process_selected_words(current_page_res,
601  selection_box,
603  break;
605  debug_word(current_page_res, selection_box);
606  break;
608  break; // ignore up event
609 
610  case RECOG_WERDS:
611  image_win->AddMessage("Recogging selected words");
612  this->process_selected_words(current_page_res,
613  selection_box,
615  break;
616  case RECOG_PSEUDO:
617  image_win->AddMessage("Recogging selected blobs");
618  recog_pseudo_word(current_page_res, selection_box);
619  break;
620 
621  default:
622  sprintf(msg, "Mode %d not yet implemented", mode);
623  image_win->AddMessage(msg);
624  break;
625  }
626  default:
627  break;
628  }
629 }
630 
636 void Tesseract::debug_word(PAGE_RES* page_res, const TBOX &selection_box) {
638  recog_all_words(page_res, NULL, &selection_box, word_config_.string(), 0);
639 }
640 } // namespace tesseract
641 
642 
650 void show_point(PAGE_RES* page_res, float x, float y) {
651  FCOORD pt(x, y);
652  PAGE_RES_IT pr_it(page_res);
653 
654  char msg[160];
655  char *msg_ptr = msg;
656 
657  msg_ptr += sprintf(msg_ptr, "Pt:(%0.3f, %0.3f) ", x, y);
658 
659  for (WERD_RES* word = pr_it.word(); word != NULL; word = pr_it.forward()) {
660  if (pr_it.row() != pr_it.prev_row() &&
661  pr_it.row()->row->bounding_box().contains(pt)) {
662  msg_ptr += sprintf(msg_ptr, "BL(x)=%0.3f ",
663  pr_it.row()->row->base_line(x));
664  }
665  if (word->word->bounding_box().contains(pt)) {
666  TBOX box = word->word->bounding_box();
667  msg_ptr += sprintf(msg_ptr, "Wd(%d, %d)/(%d, %d) ",
668  box.left(), box.bottom(),
669  box.right(), box.top());
670  C_BLOB_IT cblob_it(word->word->cblob_list());
671  for (cblob_it.mark_cycle_pt();
672  !cblob_it.cycled_list();
673  cblob_it.forward()) {
674  C_BLOB* cblob = cblob_it.data();
675  box = cblob->bounding_box();
676  if (box.contains(pt)) {
677  msg_ptr += sprintf(msg_ptr,
678  "CBlb(%d, %d)/(%d, %d) ",
679  box.left(), box.bottom(),
680  box.right(), box.top());
681  }
682  }
683  }
684  }
685  image_win->AddMessage(msg);
686 }
687 
688 
689 /**********************************************************************
690  * WERD PROCESSOR FUNCTIONS
691  * ========================
692  *
693  * These routines are invoked by one or more of:
694  * process_all_words()
695  * process_selected_words()
696  * or
697  * process_all_words_it()
698  * process_selected_words_it()
699  * for each word to be processed
700  **********************************************************************/
701 
708 #endif // GRAPHICS_DISABLED
709 namespace tesseract {
710 #ifndef GRAPHICS_DISABLED
712  WERD_RES* word_res) {
713  word_res->word->bounding_box().plot(image_win, ScrollView::BLACK,
715  return word_set_display(block, row, word_res);
716 }
717 
718 
725  TWERD *bln_word = word_res->chopped_word;
726  if (bln_word == NULL) {
727  word_res->SetupForTessRecognition(unicharset, this, BestPix(), false,
729  row, block);
730  bln_word = word_res->chopped_word;
731  }
734  1.0, 0.0f, -1000.0f, 1000.0f);
735  bln_word->plot(bln_word_window_handle());
737  return TRUE;
738 }
739 
740 
741 
747 BOOL8 Tesseract::word_display(BLOCK* block, ROW* row, WERD_RES* word_res) {
748  WERD* word = word_res->word;
749  TBOX word_bb; // word bounding box
750  int word_height; // ht of word BB
751  BOOL8 displayed_something = FALSE;
752  float shift; // from bot left
753  C_BLOB_IT c_it; // cblob iterator
754 
755  if (color_mode != CM_RAINBOW && word_res->box_word != NULL) {
756  BoxWord* box_word = word_res->box_word;
757  int length = box_word->length();
758  if (word_res->fontinfo == NULL) return false;
759  const FontInfo& font_info = *word_res->fontinfo;
760  for (int i = 0; i < length; ++i) {
762  switch (color_mode) {
763  case CM_SUBSCRIPT:
764  if (box_word->BlobPosition(i) == SP_SUBSCRIPT)
765  color = ScrollView::RED;
766  break;
767  case CM_SUPERSCRIPT:
768  if (box_word->BlobPosition(i) == SP_SUPERSCRIPT)
769  color = ScrollView::RED;
770  break;
771  case CM_ITALIC:
772  if (font_info.is_italic())
773  color = ScrollView::RED;
774  break;
775  case CM_BOLD:
776  if (font_info.is_bold())
777  color = ScrollView::RED;
778  break;
779  case CM_FIXEDPITCH:
780  if (font_info.is_fixed_pitch())
781  color = ScrollView::RED;
782  break;
783  case CM_SERIF:
784  if (font_info.is_serif())
785  color = ScrollView::RED;
786  break;
787  case CM_SMALLCAPS:
788  if (word_res->small_caps)
789  color = ScrollView::RED;
790  break;
791  case CM_DROPCAPS:
792  if (box_word->BlobPosition(i) == SP_DROPCAP)
793  color = ScrollView::RED;
794  break;
795  // TODO(rays) underline is currently completely unsupported.
796  case CM_UNDERLINE:
797  default:
798  break;
799  }
800  image_win->Pen(color);
801  TBOX box = box_word->BlobBox(i);
802  image_win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
803  }
804  return true;
805  }
806  /*
807  Note the double coercions of(COLOUR)((inT32)editor_image_word_bb_color)
808  etc. are to keep the compiler happy.
809  */
810  // display bounding box
811  if (word->display_flag(DF_BOX)) {
812  word->bounding_box().plot(image_win,
816  editor_image_word_bb_color));
817 
820  image_win->Pen(c);
821  c_it.set_to_list(word->cblob_list());
822  for (c_it.mark_cycle_pt(); !c_it.cycled_list(); c_it.forward())
823  c_it.data()->bounding_box().plot(image_win);
824  displayed_something = TRUE;
825  }
826 
827  // display edge steps
828  if (word->display_flag(DF_EDGE_STEP)) { // edgesteps available
829  word->plot(image_win); // rainbow colors
830  displayed_something = TRUE;
831  }
832 
833  // display poly approx
834  if (word->display_flag(DF_POLYGONAL)) {
835  // need to convert
836  TWERD* tword = TWERD::PolygonalCopy(word);
837  tword->plot(image_win);
838  delete tword;
839  displayed_something = TRUE;
840  }
841 
842  // Display correct text and blamer information.
843  STRING text;
844  STRING blame;
845  if (word->display_flag(DF_TEXT) && word->text() != NULL) {
846  text = word->text();
847  }
848  if (word->display_flag(DF_BLAMER) &&
849  !(word_res->blamer_bundle != NULL &&
851  text = "";
852  const BlamerBundle *blamer_bundle = word_res->blamer_bundle;
853  if (blamer_bundle == NULL) {
854  text += "NULL";
855  } else {
856  for (int i = 0; i < blamer_bundle->truth_text.length(); ++i) {
857  text += blamer_bundle->truth_text[i];
858  }
859  }
860  text += " -> ";
861  STRING best_choice_str;
862  if (word_res->best_choice == NULL) {
863  best_choice_str = "NULL";
864  } else {
865  word_res->best_choice->string_and_lengths(&best_choice_str, NULL);
866  }
867  text += best_choice_str;
868  IncorrectResultReason reason = (blamer_bundle == NULL) ?
869  IRR_PAGE_LAYOUT : blamer_bundle->incorrect_result_reason;
870  ASSERT_HOST(reason < IRR_NUM_REASONS)
871  blame += " [";
872  blame += BlamerBundle::IncorrectReasonName(reason);
873  blame += "]";
874  }
875  if (text.length() > 0) {
876  word_bb = word->bounding_box();
877  image_win->Pen(ScrollView::RED);
878  word_height = word_bb.height();
879  int text_height = 0.50 * word_height;
880  if (text_height > 20) text_height = 20;
881  image_win->TextAttributes("Arial", text_height, false, false, false);
882  shift = (word_height < word_bb.width()) ? 0.25 * word_height : 0.0f;
883  image_win->Text(word_bb.left() + shift,
884  word_bb.bottom() + 0.25 * word_height, text.string());
885  if (blame.length() > 0) {
886  image_win->Text(word_bb.left() + shift,
887  word_bb.bottom() + 0.25 * word_height - text_height,
888  blame.string());
889  }
890 
891  displayed_something = TRUE;
892  }
893 
894  if (!displayed_something) // display BBox anyway
895  word->bounding_box().plot(image_win,
898  editor_image_word_bb_color));
899  return TRUE;
900 }
901 #endif // GRAPHICS_DISABLED
902 
908 BOOL8 Tesseract::word_dumper(BLOCK* block, ROW* row, WERD_RES* word_res) {
909  if (block != NULL) {
910  tprintf("\nBlock data...\n");
911  block->print(NULL, FALSE);
912  }
913  tprintf("\nRow data...\n");
914  row->print(NULL);
915  tprintf("\nWord data...\n");
916  word_res->word->print();
917  if (word_res->blamer_bundle != NULL && wordrec_debug_blamer &&
919  tprintf("Current blamer debug: %s\n",
920  word_res->blamer_bundle->debug.string());
921  }
922  return TRUE;
923 }
924 
925 #ifndef GRAPHICS_DISABLED
926 
932  WERD* word = word_res->word;
933  word->set_display_flag(DF_BOX, word_display_mode.bit(DF_BOX));
934  word->set_display_flag(DF_TEXT, word_display_mode.bit(DF_TEXT));
935  word->set_display_flag(DF_POLYGONAL, word_display_mode.bit(DF_POLYGONAL));
936  word->set_display_flag(DF_EDGE_STEP, word_display_mode.bit(DF_EDGE_STEP));
938  word_display_mode.bit(DF_BN_POLYGONAL));
939  word->set_display_flag(DF_BLAMER, word_display_mode.bit(DF_BLAMER));
940  return word_display(block, row, word_res);
941 }
942 #endif // GRAPHICS_DISABLED
943 
944 } // namespace tesseract
945 
946 
947