pgedit.cpp

来自「一个google的OCR源码」· C++ 代码 · 共 1,866 行 · 第 1/4 页

CPP
1,866
字号
/********************************************************************** * File:        pgedit.cpp (Formerly pgeditor.c) * Description: Page structure file editor * Author:      Phil Cheatle * Created:     Thu Oct 10 16:25:24 BST 1991 * *(C) Copyright 1991, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0(the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http:// www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/#include          "pgedit.h"#include          <ctype.h>#include          <math.h>#include          "genblob.h"#include          "tessio.h"#include          "tessout.h"#include          "tordmain.h"#include          "statistc.h"#include          "debugwin.h"#include          "svshowim.h"#include          "mainblk.h"#include          "varabled.h"#include          "string.h"#include          "scrollview.h"#include          "svmnode.h"#include          "control.h"#define ASC_HEIGHT     (2 * bln_baseline_offset + bln_x_height)#define X_HEIGHT       (bln_baseline_offset + bln_x_height)#define BL_HEIGHT     bln_baseline_offset#define DESC_HEIGHT     0#define MAXSPACING      128      /*max expected spacing in pix */const ERRCODE EMPTYBLOCKLIST = "No blocks to edit";extern IMAGE page_image;enum CMD_EVENTS{  NULL_CMD_EVENT,  DELETE_CMD_EVENT,  COPY_CMD_EVENT,  CHANGE_DISP_CMD_EVENT,  CHANGE_TEXT_CMD_EVENT,  TOGGLE_SEG_CMD_EVENT,  DUMP_WERD_CMD_EVENT,  SHOW_POINT_CMD_EVENT,  ROW_SPACE_STAT_CMD_EVENT,  BLOCK_SPACE_STAT_CMD_EVENT,  SHOW_BLN_WERD_CMD_EVENT,  SEGMENT_WERD_CMD_EVENT,  BOUNDING_BOX_CMD_EVENT,  CORRECT_TEXT_CMD_EVENT,  POLYGONAL_CMD_EVENT,  BL_NORM_CMD_EVENT,  BITMAP_CMD_EVENT,  TIDY_CMD_EVENT,  VIEW_CMD_EVENT,  IMAGE_CMD_EVENT,  BLOCKS_CMD_EVENT,  BASELINES_CMD_EVENT,  WRITE_CMD_EVENT,  NEW_SOURCE_CMD_EVENT,  UNIFORM_DISP_CMD_EVENT,  REFRESH_CMD_EVENT,  QUIT_CMD_EVENT,  RECOG_WERDS,  RECOG_PSEUDO};/********************************************************************** * *  Some global data * **********************************************************************/ScrollView* image_win;#ifndef GRAPHICS_DISABLEDVariablesEditor* ve;#endifbool stillRunning = false;#ifdef __UNIX__FILE *debug_window = NULL;       // opened on demand#endif                                 // baseline norm wordsScrollView* bln_word_window = NULL;CMD_EVENTS mode = CHANGE_DISP_CMD_EVENT;                                 // Selected words opBITS16 word_display_mode;BOOL8 display_image = FALSE;BOOL8 display_blocks = FALSE;BOOL8 display_baselines = FALSE;BOOL8 viewing_source = TRUE;BLOCK_LIST *source_block_list = NULL;    // image blocksBLOCK_LIST target_block_list;    // target blocksBLOCK_LIST *other_block_list = &target_block_list;BOOL8 source_changed = FALSE;    // Changes not savedBOOL8 target_changed = FALSE;    // Changes not savedBOOL8 *other_image_changed = &target_changed;/* Public globals */#define EXTERNEXTERN BLOCK_LIST *current_block_list = NULL;EXTERN BOOL8 *current_image_changed = &source_changed;/* Variables */EXTERN STRING_VAR(editor_image_win_name, "EditorImage","Editor image window name");EXTERN INT_VAR(editor_image_xpos, 590, "Editor image X Pos");EXTERN INT_VAR(editor_image_ypos, 10, "Editor image Y Pos");EXTERN INT_VAR(editor_image_menuheight, 50, "Add to image height for menu bar");EXTERN INT_VAR(editor_image_word_bb_color, ScrollView::BLUE,"Word bounding box colour");EXTERN INT_VAR(editor_image_blob_bb_color, ScrollView::YELLOW,"Blob bounding box colour");EXTERN INT_VAR(editor_image_text_color, ScrollView::WHITE,"Correct text colour");EXTERN STRING_VAR(editor_dbwin_name, "EditorDBWin","Editor debug window name");EXTERN INT_VAR(editor_dbwin_xpos, 50, "Editor debug window X Pos");EXTERN INT_VAR(editor_dbwin_ypos, 500, "Editor debug window Y Pos");EXTERN INT_VAR(editor_dbwin_height, 24, "Editor debug window height");EXTERN INT_VAR(editor_dbwin_width, 80, "Editor debug window width");EXTERN STRING_VAR(editor_word_name, "BlnWords", "BL normalised word window");EXTERN INT_VAR(editor_word_xpos, 60, "Word window X Pos");EXTERN INT_VAR(editor_word_ypos, 510, "Word window Y Pos");EXTERN INT_VAR(editor_word_height, 240, "Word window height");EXTERN INT_VAR(editor_word_width, 655, "Word window width");EXTERN double_VAR(editor_smd_scale_factor, 1.0, "Scaling for smd image");/********************************************************************** *  add_word() * *  Inserts the a word into a specified block list. The list is searched for a *  block and row of the same file as those of the word to be added, which *  contain the bounding box of the word.  If such a row is found, the new *  word is inserted into the row in the correct X order.  If the *  block is found, but not the row, a copy of the word's old row is added to *  the block in the correct Y order, and the word is put in that row. *  If neither the row nor the block are found, then the word's old block is *  copied with only the word's row. It is added to the block list in the *  correct Y order. **********************************************************************/void add_word(                            // to block list              WERD *word,                  // word to be added              ROW *src_row,                // source row              BLOCK *src_block,            // source block              BLOCK_LIST *dest_block_list  // add to this             ) {  BLOCK_IT block_it(dest_block_list);  BLOCK *block;                  // current block  BLOCK *dest_block = NULL;      // destination block  ROW_IT row_it;  ROW *row;                      // destination row  ROW *dest_row = NULL;          // destination row  WERD_IT word_it;  TBOX word_box = word->bounding_box();  TBOX insert_point_word_box;  BOOL8 seen_blocks_for_current_file = FALSE;  block_it.mark_cycle_pt();  while(!block_it.cycled_list() &&(dest_block == NULL)) {    block = block_it.data();    if ((block->bounding_box().contains(word_box)) &&   (strcmp(block->name(), src_block->name()) == 0)) {      dest_block = block;        // found dest block      row_it.set_to_list(block->row_list());      row_it.mark_cycle_pt();      while((!row_it.cycled_list()) &&(dest_row == NULL)) {        row = row_it.data();        if (row->bounding_box().contains(word_box))          dest_row = row;        // found dest row        else          row_it.forward();      }    }    else      block_it.forward();  }  if (dest_block == NULL) {      // make a new one    dest_block = new BLOCK;    *dest_block = *src_block;    block_it.set_to_list(dest_block_list);    for (block_it.mark_cycle_pt();    !block_it.cycled_list(); block_it.forward()) {      block = block_it.data();      if (!seen_blocks_for_current_file &&       (strcmp(block->name(), dest_block->name()) == 0))        seen_blocks_for_current_file = TRUE;      if (seen_blocks_for_current_file &&       ((strcmp(block->name(), dest_block->name()) != 0) ||       (block->bounding_box().top() <        dest_block->bounding_box().top())))        break;    }    if (block_it.cycled_list())                                 // didn't find insrt pt      block_it.add_to_end(dest_block);    else                                 // did find insert pt      block_it.add_before_stay_put(dest_block);  }  if (dest_row == NULL) {        // make a new one    dest_row = new ROW;    *dest_row = *src_row;    row_it.set_to_list(dest_block->row_list());    for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {      if (row_it.data()->bounding_box().top() <        dest_row->bounding_box().top())        break;    }    if (row_it.cycled_list())                                 // didn't find insrt pt        row_it.add_to_end(dest_row);    else                                 // did find insert pt      row_it.add_before_stay_put(dest_row);  }  /* dest_block and dest_row are now found or built and inserted as necessesary    so add the word to dest row */  word_it.set_to_list(dest_row->word_list());  for (word_it.mark_cycle_pt(); !word_it.cycled_list(); word_it.forward()) {    if (word_it.data()->bounding_box().right() >= word_box.left())      break;  }  if (word_it.cycled_list())    word_it.add_to_end(word);   // didn't find insrt pt  else {                         // did find insert pt    insert_point_word_box = word_it.data()->bounding_box();    if (insert_point_word_box.contains(word_box) ||      word_box.contains(insert_point_word_box))      image_win->AddMessage("Refusing to add words which obliterate,"                               " or are obliterated by, others");    else {      if (word_it.data()->bounding_box().left() >        word->bounding_box().left())                                 // infront of insert pt        word_it.add_before_stay_put(word);      else                                 // behind insert pt        word_it.add_after_stay_put(word);    }  }}/********************************************************************** *  bln_word_window_handle() * *  Return a WINDOW for the word window, creating it if necessary **********************************************************************/class BlnEventHandler : public SVEventHandler { public:  void Notify(const SVEvent* sv_event) {    if (sv_event->type == SVET_DESTROY)      bln_word_window = NULL;    else if (sv_event->type == SVET_CLICK)      show_point(current_block_list, sv_event->x, sv_event->y);  }};ScrollView* bln_word_window_handle() {  // return handle                                 // not opened yet  if (bln_word_window == NULL) {    pgeditor_msg("Creating BLN word window...");    bln_word_window = new ScrollView(editor_word_name.string(),      editor_word_xpos, editor_word_ypos, editor_word_width,      editor_word_height, 4000, 4000, true);    BlnEventHandler* a = new BlnEventHandler();    bln_word_window->AddEventHandler(a);    pgeditor_msg("Creating BLN word window...Done");  }  return bln_word_window;}/********************************************************************** *  build_image_window() * *  Destroy the existing image window if there is one.  Work out how big the *  new window needs to be. Create it and re-display. **********************************************************************/void build_image_window(TBOX page_bounding_box) {  if (image_win != NULL) { delete image_win; }  image_win = new ScrollView(editor_image_win_name.string(),                             editor_image_xpos, editor_image_ypos,                             page_bounding_box.right() + 1,                             page_bounding_box.top() +                               editor_image_menuheight + 1,                             page_bounding_box.right() + 1,                             page_bounding_box.top() + 1,                             true);}/********************************************************************** *  build_menu() * *  Construct the menu tree used by the command window **********************************************************************/SVMenuNode *build_menu_new() {  SVMenuNode* parent_menu;  SVMenuNode* root_menu_item = new SVMenuNode();  SVMenuNode* modes_menu_item = root_menu_item->AddChild("MODES");  modes_menu_item->AddChild("Change Display",      CHANGE_DISP_CMD_EVENT);  modes_menu_item->AddChild("Delete",      DELETE_CMD_EVENT);  modes_menu_item->AddChild("Copy to TARGET",      COPY_CMD_EVENT);  modes_menu_item->AddChild("Change Text",      CHANGE_TEXT_CMD_EVENT);  modes_menu_item->AddChild("Toggle Correct Seg Flg",      TOGGLE_SEG_CMD_EVENT);  modes_menu_item->AddChild("Dump Word",      DUMP_WERD_CMD_EVENT);  modes_menu_item->AddChild("Show Point",      SHOW_POINT_CMD_EVENT);  modes_menu_item->AddChild("Row gaps hist",      ROW_SPACE_STAT_CMD_EVENT);  modes_menu_item->AddChild("Block gaps hist",      BLOCK_SPACE_STAT_CMD_EVENT);  modes_menu_item->AddChild("Show BL Norm Word",      SHOW_BLN_WERD_CMD_EVENT);  modes_menu_item->AddChild("Re-Segment Word",      SEGMENT_WERD_CMD_EVENT);  modes_menu_item->AddChild("Recog Words",      RECOG_WERDS);  modes_menu_item->AddChild("Recog Blobs",      RECOG_PSEUDO);  parent_menu = root_menu_item->AddChild("DISPLAY");  parent_menu->AddChild("Bounding Boxes",      BOUNDING_BOX_CMD_EVENT, TRUE);  parent_menu->AddChild("Correct Text",      CORRECT_TEXT_CMD_EVENT, FALSE);  parent_menu->AddChild("Polygonal Approx",      POLYGONAL_CMD_EVENT, FALSE);  parent_menu->AddChild("Baseline Normalised",      BL_NORM_CMD_EVENT, FALSE);  parent_menu->AddChild("Edge Steps",      BITMAP_CMD_EVENT, FALSE);  parent_menu = root_menu_item->AddChild("OTHER");  parent_menu->AddChild("Quit",      QUIT_CMD_EVENT);  parent_menu->AddChild("Tidy Target",      TIDY_CMD_EVENT);  parent_menu->AddChild("View TARGET",      VIEW_CMD_EVENT, FALSE);  parent_menu->AddChild("Show Image",      IMAGE_CMD_EVENT, FALSE);  parent_menu->AddChild("ShowBlock Outlines",      BLOCKS_CMD_EVENT, FALSE);  parent_menu->AddChild("Show Baselines",      BASELINES_CMD_EVENT, FALSE);  parent_menu->AddChild("Write File",      WRITE_CMD_EVENT,    imagebasename.string());  parent_menu->AddChild("New Source File",      NEW_SOURCE_CMD_EVENT,    imagebasename.string());  parent_menu->AddChild("Uniform Display",      UNIFORM_DISP_CMD_EVENT);  parent_menu->AddChild("Refresh Display",      REFRESH_CMD_EVENT);  return root_menu_item;}/********************************************************************** *  display_bln_lines() * *  Display normalised baseline, x-height, ascender limit and descender limit **********************************************************************/void display_bln_lines(ScrollView* window,                       ScrollView::Color colour,                       float scale_factor,                       float y_offset,                       float minx,                       float maxx) {  window->Pen(colour);  window->Line(minx, y_offset + scale_factor * DESC_HEIGHT,               maxx, y_offset + scale_factor * DESC_HEIGHT);  window->Line(minx, y_offset + scale_factor * BL_HEIGHT,               maxx, y_offset + scale_factor * BL_HEIGHT);  window->Line(minx, y_offset + scale_factor * X_HEIGHT,               maxx, y_offset + scale_factor * X_HEIGHT);  window->Line(minx, y_offset + scale_factor * ASC_HEIGHT,               maxx, y_offset + scale_factor * ASC_HEIGHT);}/********************************************************************** *  do_new_source() * *  Change to another source file.  Automatically tidy page first * **********************************************************************/void do_new_source(           // serialise                  ) {  FILE *infp;                    // input file  char* name = image_win->ShowInputDialog("New Source File name");  STRING name_str(name);  delete[] name;  if (source_changed) {    int a = image_win->ShowYesNoDialog(        "Source changes will be LOST.  Continue?(Y/N)");	if (a != 'y') { image_win->AddMessage("Write cancelled"); return; }  }                                 // if not file exists  if (!(infp = fopen(name_str.string(), "r"))) {     image_win->AddMessage("Cant open file " "%s" "", name_str.string());    return;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?