📄 pgedit.cpp
字号:
/********************************************************************** * 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 "mfcpch.h"#include <ctype.h>#include <math.h>#include "cmndwin.h"#include "genblob.h"#include "pgedit.h"#include "pgeditx.h"#include "tessio.h"#include "tessout.h"#include "submen.h"#include "varblwin.h"#include "tordmain.h"#include "statistc.h"#include "debugwin.h"#include "showim.h"#include "mainblk.h"#include "evnts.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, SMD_CMD_EVENT, NEW_SOURCE_CMD_EVENT, UNIFORM_DISP_CMD_EVENT, REFRESH_CMD_EVENT, QUIT_CMD_EVENT};#define EXTENDED_MODES_BASE 1000 //for extended cmd ids#define EXTENDED_OTHER_BASE 2000/********************************************************************** * * Some global data * **********************************************************************/RADIO_MENU *modes_menu_item;RADIO_MENU_LEAF *change_display_menu_item;SIMPLE_MENU_LEAF *view_menu_item;RADIO_MENU_LEAF *copy_menu_item;VARIABLE_MENU_LEAF *write_menu_item;#ifdef __UNIX__FILE *debug_window = NULL; //opened on demand#endif //baseline norm wordsWINDOW bln_word_window = NO_WINDOW;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 EXTERN //image windowEXTERN WINDOW image_win = NO_WINDOW;EXTERN COMMAND_WINDOW *command_window;EXTERN BLOCK_LIST *current_block_list = NULL;EXTERN BOOL8 *current_image_changed = &source_changed;EXTERN void (*show_pt_handler) (GRAPHICS_EVENT *) = NULL;/* 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_height, 680, "Editor image height");EXTERN INT_VAR (editor_image_width, 655, "Editor image width");EXTERN INT_VAR (editor_image_word_bb_color, BLUE, "Word bounding box colour");EXTERN INT_VAR (editor_image_blob_bb_color, YELLOW,"Blob bounding box colour");EXTERN INT_VAR (editor_image_text_color, 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; BOX word_box = word->bounding_box (); BOX 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)) command_window-> msg ("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 **********************************************************************/WINDOW bln_word_window_handle() { //return handle //not opened yet if (bln_word_window == NO_WINDOW) { pgeditor_msg ("Creating BLN word window..."); // xmin, xmax bln_word_window = create_window (editor_word_name.string (), SCROLLINGWIN, editor_word_xpos, editor_word_ypos, editor_word_width, editor_word_height, -2000.0, 2000.0, DESC_HEIGHT - 30.0f, ASC_HEIGHT + 30.0f, // ymin, ymax TRUE, FALSE, FALSE, FALSE); // down event only 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(BOX page_bounding_box) { if (image_win != NO_WINDOW) destroy_window(image_win); // xmin image_win = create_window (editor_image_win_name.string (), SCROLLINGWIN, editor_image_xpos, editor_image_ypos, editor_image_width, editor_image_height, 0.0, (float) page_bounding_box.right () + 1, // xmax 0.0, // ymin (float) page_bounding_box.top () + 1, // ymax TRUE, FALSE, TRUE, FALSE); //down and up only}/********************************************************************** * build_menu() * * Construct the menu tree used by the command window **********************************************************************/MENU_ROOT *build_menu() { NON_RADIO_MENU *parent_menu; MENU_ROOT *root_menu_item; root_menu_item = new MENU_ROOT (); modes_menu_item = new RADIO_MENU ("MODES"); root_menu_item->add_child (modes_menu_item); change_display_menu_item = new RADIO_MENU_LEAF ("Change Display", CHANGE_DISP_CMD_EVENT); modes_menu_item->add_child (change_display_menu_item); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Delete", DELETE_CMD_EVENT)); copy_menu_item = new RADIO_MENU_LEAF ("Copy to TARGET", COPY_CMD_EVENT); modes_menu_item->add_child (copy_menu_item); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Change Text", CHANGE_TEXT_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Toggle Correct Seg Flg", TOGGLE_SEG_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Dump Word", DUMP_WERD_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Show Point", SHOW_POINT_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Row gaps hist", ROW_SPACE_STAT_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Block gaps hist", BLOCK_SPACE_STAT_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Show BL Norm Word", SHOW_BLN_WERD_CMD_EVENT)); modes_menu_item->add_child (new RADIO_MENU_LEAF ("Re-Segment Word", SEGMENT_WERD_CMD_EVENT)); parent_menu = new NON_RADIO_MENU ("DISPLAY"); root_menu_item->add_child (parent_menu); parent_menu->add_child (new TOGGLE_MENU_LEAF ("Bounding Boxes", BOUNDING_BOX_CMD_EVENT, TRUE)); parent_menu->add_child (new TOGGLE_MENU_LEAF ("Correct Text", CORRECT_TEXT_CMD_EVENT, FALSE)); parent_menu->add_child (new TOGGLE_MENU_LEAF ("Polygonal Approx", POLYGONAL_CMD_EVENT, FALSE)); parent_menu->add_child (new TOGGLE_MENU_LEAF ("Baseline Normalised", BL_NORM_CMD_EVENT, FALSE)); parent_menu->add_child (new TOGGLE_MENU_LEAF ("Edge Steps", BITMAP_CMD_EVENT, FALSE)); parent_menu = new NON_RADIO_MENU ("OTHER"); root_menu_item->add_child (parent_menu);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -