Updated graphics output for new java-based display

git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@136 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
theraysmith 2008-02-01 00:33:18 +00:00
parent d543e8c2bc
commit 10265fb9cc
17 changed files with 3637 additions and 173 deletions

View File

@ -3,7 +3,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/ccutil -I$(top_srcdir)/ccstruct \
-I$(top_srcdir)/image -I$(top_srcdir)/viewer \
-I$(top_srcdir)/ccops -I$(top_srcdir)/dict \
-I$(top_srcdir)/classify -I$(top_srcdir)/display \
-I$(top_srcdir)/classify \
-I$(top_srcdir)/wordrec -I$(top_srcdir)/cutil \
-I$(top_srcdir)/textord
@ -13,7 +13,8 @@ include_HEADERS = \
control.h docqual.h expandblob.h fixspace.h fixxht.h \
imgscale.h matmatch.h output.h paircmp.h reject.h scaleimg.h \
tessbox.h tessedit.h tesseractmain.h tessvars.h tfacep.h \
tessembedded.h tfacepp.h tstruct.h werdit.h
pagewalk.h pgedit.h varabled.h \
tessembedded.h tessio.h tfacepp.h tstruct.h werdit.h
lib_LIBRARIES = libtesseract_main.a libtesseract_full.a
libtesseract_main_a_SOURCES = \
@ -23,12 +24,13 @@ libtesseract_main_a_SOURCES = \
docqual.cpp expandblob.cpp fixspace.cpp fixxht.cpp \
imgscale.cpp matmatch.cpp output.cpp paircmp.cpp \
reject.cpp scaleimg.cpp tessbox.cpp tessvars.cpp \
pagewalk.cpp pgedit.cpp varabled.cpp \
tfacepp.cpp tstruct.cpp werdit.cpp
libtesseract_full_a_SOURCES = tesseractfull.cc
libtesseract_full.o: tesseractfull.o \
libtesseract_main.a \
../display/libtesseract_display.a \
../textord/libtesseract_textord.a \
../pageseg/libtesseract_pageseg.a \
../wordrec/libtesseract_wordrec.a \
../classify/libtesseract_classify.a \
../dict/libtesseract_dict.a \
@ -39,8 +41,8 @@ libtesseract_full.o: tesseractfull.o \
../ccutil/libtesseract_ccutil.a
ld -r -o libtesseract_full.o tesseractfull.o \
libtesseract_main.a \
../display/libtesseract_display.a \
../textord/libtesseract_textord.a \
../pageseg/libtesseract_pageseg.a \
../wordrec/libtesseract_wordrec.a \
../classify/libtesseract_classify.a \
../dict/libtesseract_dict.a \

View File

@ -75,14 +75,14 @@ RANLIB = @RANLIB@
VERSION = @VERSION@
SUBDIRS =
AM_CPPFLAGS = -I$(top_srcdir)/ccutil -I$(top_srcdir)/ccstruct -I$(top_srcdir)/image -I$(top_srcdir)/viewer -I$(top_srcdir)/ccops -I$(top_srcdir)/dict -I$(top_srcdir)/classify -I$(top_srcdir)/display -I$(top_srcdir)/wordrec -I$(top_srcdir)/cutil -I$(top_srcdir)/textord
AM_CPPFLAGS = -I$(top_srcdir)/ccutil -I$(top_srcdir)/ccstruct -I$(top_srcdir)/image -I$(top_srcdir)/viewer -I$(top_srcdir)/ccops -I$(top_srcdir)/dict -I$(top_srcdir)/classify -I$(top_srcdir)/wordrec -I$(top_srcdir)/cutil -I$(top_srcdir)/textord
include_HEADERS = adaptions.h applybox.h baseapi.h blobcmp.h callnet.h charcut.h control.h docqual.h expandblob.h fixspace.h fixxht.h imgscale.h matmatch.h output.h paircmp.h reject.h scaleimg.h tessbox.h tessedit.h tesseractmain.h tessvars.h tfacep.h tessembedded.h tfacepp.h tstruct.h werdit.h
include_HEADERS = adaptions.h applybox.h baseapi.h blobcmp.h callnet.h charcut.h control.h docqual.h expandblob.h fixspace.h fixxht.h imgscale.h matmatch.h output.h paircmp.h reject.h scaleimg.h tessbox.h tessedit.h tesseractmain.h tessvars.h tfacep.h pagewalk.h pgedit.h varabled.h tessembedded.h tessio.h tfacepp.h tstruct.h werdit.h
lib_LIBRARIES = libtesseract_main.a libtesseract_full.a
libtesseract_main_a_SOURCES = tessedit.cpp adaptions.cpp applybox.cpp baseapi.cpp blobcmp.cpp callnet.cpp charcut.cpp charsample.cpp control.cpp docqual.cpp expandblob.cpp fixspace.cpp fixxht.cpp imgscale.cpp matmatch.cpp output.cpp paircmp.cpp reject.cpp scaleimg.cpp tessbox.cpp tessvars.cpp tfacepp.cpp tstruct.cpp werdit.cpp
libtesseract_main_a_SOURCES = tessedit.cpp adaptions.cpp applybox.cpp baseapi.cpp blobcmp.cpp callnet.cpp charcut.cpp charsample.cpp control.cpp docqual.cpp expandblob.cpp fixspace.cpp fixxht.cpp imgscale.cpp matmatch.cpp output.cpp paircmp.cpp reject.cpp scaleimg.cpp tessbox.cpp tessvars.cpp pagewalk.cpp pgedit.cpp varabled.cpp tfacepp.cpp tstruct.cpp werdit.cpp
libtesseract_full_a_SOURCES = tesseractfull.cc
@ -104,8 +104,8 @@ libtesseract_main_a_LIBADD =
libtesseract_main_a_OBJECTS = tessedit.o adaptions.o applybox.o \
baseapi.o blobcmp.o callnet.o charcut.o charsample.o control.o \
docqual.o expandblob.o fixspace.o fixxht.o imgscale.o matmatch.o \
output.o paircmp.o reject.o scaleimg.o tessbox.o tessvars.o tfacepp.o \
tstruct.o werdit.o
output.o paircmp.o reject.o scaleimg.o tessbox.o tessvars.o pagewalk.o \
pgedit.o varabled.o tfacepp.o tstruct.o werdit.o
libtesseract_full_a_LIBADD =
libtesseract_full_a_OBJECTS = tesseractfull.o
AR = ar
@ -131,9 +131,10 @@ DEP_FILES = .deps/adaptions.P .deps/applybox.P .deps/baseapi.P \
.deps/blobcmp.P .deps/callnet.P .deps/charcut.P .deps/charsample.P \
.deps/control.P .deps/docqual.P .deps/expandblob.P .deps/fixspace.P \
.deps/fixxht.P .deps/imgscale.P .deps/matmatch.P .deps/output.P \
.deps/paircmp.P .deps/reject.P .deps/scaleimg.P .deps/tessbox.P \
.deps/tessedit.P .deps/tesseractfull.P .deps/tesseractmain.P \
.deps/tessvars.P .deps/tfacepp.P .deps/tstruct.P .deps/werdit.P
.deps/pagewalk.P .deps/paircmp.P .deps/pgedit.P .deps/reject.P \
.deps/scaleimg.P .deps/tessbox.P .deps/tessedit.P .deps/tesseractfull.P \
.deps/tesseractmain.P .deps/tessvars.P .deps/tfacepp.P .deps/tstruct.P \
.deps/varabled.P .deps/werdit.P
SOURCES = $(libtesseract_main_a_SOURCES) $(libtesseract_full_a_SOURCES) $(tesseract_SOURCES)
OBJECTS = $(libtesseract_main_a_OBJECTS) $(libtesseract_full_a_OBJECTS) $(tesseract_OBJECTS)
@ -526,8 +527,8 @@ mostlyclean distclean maintainer-clean
libtesseract_full.o: tesseractfull.o \
libtesseract_main.a \
../display/libtesseract_display.a \
../textord/libtesseract_textord.a \
../pageseg/libtesseract_pageseg.a \
../wordrec/libtesseract_wordrec.a \
../classify/libtesseract_classify.a \
../dict/libtesseract_dict.a \
@ -538,8 +539,8 @@ libtesseract_full.o: tesseractfull.o \
../ccutil/libtesseract_ccutil.a
ld -r -o libtesseract_full.o tesseractfull.o \
libtesseract_main.a \
../display/libtesseract_display.a \
../textord/libtesseract_textord.a \
../pageseg/libtesseract_pageseg.a \
../wordrec/libtesseract_wordrec.a \
../classify/libtesseract_classify.a \
../dict/libtesseract_dict.a \

View File

@ -41,6 +41,8 @@
INT32 demo_word = 0;
#define WINDOWNAMESIZE 13 /*max size of name */
#define EXTERN
EXTERN BOOL_VAR (tessedit_reject_ems, FALSE, "Reject all m's");
@ -507,7 +509,7 @@ void adapt_to_good_ems(WERD_RES *word,
static INT32 word_number = 0;
#ifndef GRAPHICS_DISABLED
WINDOW demo_win = NULL;
ScrollView* demo_win = NULL;
#endif
INT32 resolution = page_image.get_res ();
@ -745,7 +747,7 @@ void adapt_to_good_samples(WERD_RES *word,
static INT32 word_number = 0;
#ifndef GRAPHICS_DISABLED
WINDOW demo_win = NULL;
ScrollView* demo_win = NULL;
#endif
INT32 resolution = page_image.get_res ();

View File

@ -20,9 +20,10 @@
#include "mfcpch.h"
#include "charcut.h"
#include "imgs.h"
#include "showim.h"
#include "evnts.h"
#include "svshowim.h"
//#include "evnts.h"
#include "notdll.h"
#include "scrollview.h"
#define LARGEST(a,b) ( (a) > (b) ? (a) : (b) )
#define SMALLEST(a,b) ( (a) > (b) ? (b) : (a) )
@ -96,7 +97,7 @@ PIXROW::PIXROW(INT16 pos, INT16 count, PBLOB *blob) {
*************************************************************************/
#ifndef GRAPHICS_DISABLED
void PIXROW::plot(WINDOW fd //where to paint
void PIXROW::plot(ScrollView* fd //where to paint
) const {
INT16 i;
INT16 y_coord;
@ -104,7 +105,7 @@ void PIXROW::plot(WINDOW fd //where to paint
for (i = 0; i < row_count; i++) {
y_coord = row_offset + i;
if (min[i] <= max[i]) {
rectangle (fd, min[i], y_coord, max[i] + 1, y_coord + 1);
fd->Rectangle(min[i], y_coord, max[i] + 1, y_coord + 1);
}
}
}
@ -574,12 +575,12 @@ IMAGELINE *generate_imlines( //get some imagelines
*************************************************************************/
#ifndef GRAPHICS_DISABLED
WINDOW display_clip_image(WERD *word, //word to be processed
ScrollView* display_clip_image(WERD *word, //word to be processed
IMAGE &bin_image, //whole image
PIXROW_LIST *pixrow_list, //pixrows built
BOX &pix_box //box of subimage
) {
WINDOW clip_window; //window for debug
ScrollView* clip_window; //window for debug
BOX word_box = word->bounding_box ();
int border = word_box.height () / 2;
BOX display_box = word_box;
@ -593,23 +594,19 @@ WINDOW display_clip_image(WERD *word, //word to be processed
bin_image.get_ysize () - BUG_OFFSET));
pgeditor_msg ("Creating Clip window...");
clip_window =
create_window ("Clipped Blobs",
SCROLLINGWIN,
clip_window = new ScrollView("Clipped Blobs",
editor_word_xpos, editor_word_ypos,
3 * (word_box.width () + 2 * border),
3 * (word_box.height () + 2 * border),
//window width,height
// xmin, xmax
display_box.left (), display_box.right (),
display_box.bottom () - BUG_OFFSET,
display_box.left () + display_box.right (),
display_box.bottom () - BUG_OFFSET +
display_box.top () - BUG_OFFSET,
true);
// ymin, ymax
TRUE, FALSE, FALSE, TRUE); // down event & key only
pgeditor_msg ("Creating Clip window...Done");
clear_view_surface(clip_window);
show_sub_image (&bin_image,
clip_window->Clear();
sv_show_sub_image (&bin_image,
display_box.left (),
display_box.bottom (),
display_box.width (),
@ -617,11 +614,10 @@ WINDOW display_clip_image(WERD *word, //word to be processed
clip_window,
display_box.left (), display_box.bottom () - BUG_OFFSET);
word->plot (clip_window, RED);
word_box.plot (clip_window, INT_HOLLOW, TRUE, BLUE, BLUE);
pix_box.plot (clip_window, INT_HOLLOW, TRUE, BLUE, BLUE);
word->plot (clip_window, ScrollView::RED);
word_box.plot (clip_window, ScrollView::BLUE, ScrollView::BLUE);
pix_box.plot (clip_window, ScrollView::BLUE, ScrollView::BLUE);
plot_pixrows(pixrow_list, clip_window);
overlap_picture_ops(TRUE);
return clip_window;
}
@ -633,55 +629,54 @@ WINDOW display_clip_image(WERD *word, //word to be processed
*************************************************************************/
void display_images(IMAGE &clip_image, IMAGE &scaled_image) {
WINDOW clip_im_window; //window for debug
WINDOW scale_im_window; //window for debug
ScrollView* clip_im_window; //window for debug
ScrollView* scale_im_window; //window for debug
INT16 i;
GRAPHICS_EVENT event; // c;
// xmin xmax ymin ymax
clip_im_window = create_window ("Clipped Blob", SCROLLINGWIN, editor_word_xpos - 20, editor_word_ypos - 100, 5 * clip_image.get_xsize (), 5 * clip_image.get_ysize (), 0, clip_image.get_xsize (), 0, clip_image.get_ysize (),
TRUE, FALSE, FALSE, TRUE); // down event & key only
clip_im_window = new ScrollView ("Clipped Blob", editor_word_xpos - 20,
editor_word_ypos - 100, 5 * clip_image.get_xsize (),
5 * clip_image.get_ysize (), clip_image.get_xsize (),
clip_image.get_ysize (), true);
clear_view_surface(clip_im_window);
show_sub_image (&clip_image,
sv_show_sub_image (&clip_image,
0, 0,
clip_image.get_xsize (), clip_image.get_ysize (),
clip_im_window, 0, 0);
line_color_index(clip_im_window, RED);
clip_im_window->Pen(255,0,0);
for (i = 1; i < clip_image.get_xsize (); i++) {
move2d (clip_im_window, i, 0);
draw2d (clip_im_window, i, clip_image.get_xsize ());
clip_im_window->SetCursor(i,0);
clip_im_window->DrawTo(i, clip_image.get_xsize ());
}
for (i = 1; i < clip_image.get_ysize (); i++) {
move2d (clip_im_window, 0, i);
draw2d (clip_im_window, clip_image.get_xsize (), i);
clip_im_window->SetCursor(0,i);
clip_im_window->DrawTo(clip_image.get_xsize (),i);
}
// xmin xmax ymin ymax
scale_im_window = create_window ("Scaled Blob", SCROLLINGWIN, editor_word_xpos + 300, editor_word_ypos - 100, 5 * scaled_image.get_xsize (), 5 * scaled_image.get_ysize (), 0, scaled_image.get_xsize (), 0, scaled_image.get_ysize (),
TRUE, FALSE, FALSE, TRUE); // down event & key only
scale_im_window = new ScrollView ("Scaled Blob", editor_word_xpos + 300,
editor_word_ypos - 100, 5 * scaled_image.get_xsize (),
5 * scaled_image.get_ysize (), scaled_image.get_xsize (),
scaled_image.get_ysize (), true);
clear_view_surface(scale_im_window);
show_sub_image (&scaled_image,
sv_show_sub_image (&scaled_image,
0, 0,
scaled_image.get_xsize (), scaled_image.get_ysize (),
scale_im_window, 0, 0);
line_color_index(scale_im_window, RED);
scale_im_window->Pen(255,0,0);
for (i = 1; i < scaled_image.get_xsize (); i++) {
move2d (scale_im_window, i, 0);
draw2d (scale_im_window, i, scaled_image.get_xsize ());
scale_im_window->SetCursor(i,0);
scale_im_window->DrawTo(i, scaled_image.get_xsize ());
}
for (i = 1; i < scaled_image.get_ysize (); i++) {
move2d (scale_im_window, 0, i);
draw2d (scale_im_window, scaled_image.get_xsize (), i);
scale_im_window->SetCursor(0,i);
scale_im_window->DrawTo(scaled_image.get_xsize (),i);
}
overlap_picture_ops(TRUE);
await_event(scale_im_window, TRUE, ANY_EVENT, &event);
destroy_window(clip_im_window);
destroy_window(scale_im_window);
ScrollView::Update();
}
@ -692,17 +687,16 @@ void display_images(IMAGE &clip_image, IMAGE &scaled_image) {
void plot_pixrows( //plot for all blobs
PIXROW_LIST *pixrow_list,
WINDOW win) {
ScrollView* win) {
PIXROW_IT pixrow_it(pixrow_list);
INT16 colour = RED;
INT16 colour = ScrollView::RED;
for (pixrow_it.mark_cycle_pt ();
!pixrow_it.cycled_list (); pixrow_it.forward ()) {
if (colour > RED + 7)
colour = RED;
if (colour > ScrollView::RED + 7)
colour = ScrollView::RED;
perimeter_color_index (win, (COLOUR) colour);
interior_style(win, INT_HOLLOW, TRUE);
win->Pen((ScrollView::Color) colour);
pixrow_it.data ()->plot (win);
colour++;
}

View File

@ -23,6 +23,7 @@
#include "pgedit.h"
#include "notdll.h"
#include "notdll.h"
class ScrollView;
/*************************************************************************
* CLASS PIXROW
@ -63,7 +64,7 @@ class PIXROW:public ELIST_LINK
}
void plot( //use current settings
WINDOW fd) const; //where to paint
ScrollView* fd) const; //where to paint
BOX bounding_box() const; //return bounding box
//return true if box exceeds image
@ -107,7 +108,7 @@ IMAGELINE *generate_imlines( //get some imagelines
IMAGE &bin_image, //from here
BOX &pix_box);
//word to be processed
WINDOW display_clip_image(WERD *word,
ScrollView* display_clip_image(WERD *word,
IMAGE &bin_image, //whole image
PIXROW_LIST *pixrow_list, //pixrows built
BOX &pix_box //box of subimage
@ -115,5 +116,5 @@ WINDOW display_clip_image(WERD *word,
void display_images(IMAGE &clip_image, IMAGE &scaled_image);
void plot_pixrows( //plot for all blobs
PIXROW_LIST *pixrow_list,
WINDOW win);
ScrollView* win);
#endif

View File

@ -143,6 +143,8 @@ EXTERN BOOL_VAR (tessedit_global_adaption, FALSE,
EXTERN BOOL_VAR (tessedit_matcher_log, FALSE, "Log matcher activity");
EXTERN INT_VAR (tessedit_test_adaption_mode, 3,
"Adaptation decision algorithm for tess");
BOOL_VAR (save_best_choices, FALSE, "Save the results of the recognition step"
" (blob_choices) within the corresponding WERD_CHOICE");
EXTERN BOOL_VAR (test_pt, FALSE, "Test for point");
EXTERN double_VAR (test_pt_x, 99999.99, "xcoord");
@ -582,7 +584,8 @@ void classify_word_pass1( //recog one word
CHAR_SAMPLE_LIST *chars_waiting) {
WERD *bln_word; //baseline norm copy
//detailed results
BLOB_CHOICE_LIST_CLIST blob_choices;
BLOB_CHOICE_LIST_CLIST local_blob_choices;
BLOB_CHOICE_LIST_CLIST *blob_choices;
BOOL8 adapt_ok;
const char *rejmap;
INT16 index;
@ -590,6 +593,11 @@ void classify_word_pass1( //recog one word
char *match_string;
char word_string[1024];
if (save_best_choices)
blob_choices = new BLOB_CHOICE_LIST_CLIST();
else
blob_choices = &local_blob_choices;
if (matcher_fp != NULL) {
fgets (word_string, 1023, correct_fp);
if ((match_string = strchr (word_string, '\r')) != NULL)
@ -610,7 +618,7 @@ void classify_word_pass1( //recog one word
word->best_choice = tess_segment_pass1 (bln_word, &word->denorm,
tess_default_matcher,
word->raw_choice, &blob_choices,
word->raw_choice, blob_choices,
word->outword);
/*
Test for TESS screw up on word. Recog_word has already ensured that the
@ -629,17 +637,17 @@ void classify_word_pass1( //recog one word
word->tess_failed = FALSE;
if ((word->best_choice->lengths ().length () !=
word->outword->blob_list ()->length ()) ||
(word->best_choice->lengths ().length () != blob_choices.length ())) {
(word->best_choice->lengths ().length () != blob_choices->length ())) {
tprintf
("ASSERT FAIL String:\"%s\"; Strlen=%d; #Blobs=%d; #Choices=%d\n",
word->best_choice->string ().string (),
word->best_choice->lengths ().length (),
word->outword->blob_list ()->length (), blob_choices.length ());
word->outword->blob_list ()->length (), blob_choices->length ());
}
ASSERT_HOST (word->best_choice->lengths ().length () ==
word->outword->blob_list ()->length ());
ASSERT_HOST (word->best_choice->lengths ().length () ==
blob_choices.length ());
blob_choices->length ());
/*
The adaption step used to be here. It has been moved to after
@ -657,10 +665,10 @@ void classify_word_pass1( //recog one word
else {
fix_quotes (word->best_choice,
//turn to double
word->outword, &blob_choices);
word->outword, blob_choices);
if (tessedit_fix_hyphens)
//turn 2 to 1
fix_hyphens (word->best_choice, word->outword, &blob_choices);
fix_hyphens (word->best_choice, word->outword, blob_choices);
record_certainty (word->best_choice->certainty (), 1);
//accounting
@ -671,7 +679,7 @@ void classify_word_pass1( //recog one word
word->best_choice,
word->raw_choice);
// Also sets word->done flag
make_reject_map (word, &blob_choices, row, 1);
make_reject_map (word, blob_choices, row, 1);
adapt_ok = word_adaptable (word, tessedit_tess_adaption_mode);
@ -702,7 +710,7 @@ void classify_word_pass1( //recog one word
if (tessedit_enable_doc_dict)
tess_add_doc_word (word->best_choice);
set_word_fonts(word, &blob_choices);
set_word_fonts(word, blob_choices);
}
}
#if 0
@ -712,7 +720,12 @@ void classify_word_pass1( //recog one word
}
#endif
delete bln_word;
blob_choices.deep_clear ();
// Save best choices in the WERD_CHOICE if needed
if (blob_choices != &local_blob_choices)
word->best_choice->set_blob_choices(blob_choices);
else
blob_choices->deep_clear();
}
@ -885,11 +898,12 @@ void classify_word_pass2( //word to do
}
#ifndef GRAPHICS_DISABLED
if (tessedit_draw_outwords) {
if (fx_win == NO_WINDOW)
if (fx_win == NULL)
create_fx_win();
clear_fx_win();
word->outword->plot (fx_win);
make_picture_current(fx_win);
//make_picture_current(fx_win);
ScrollView::Update();
}
#endif
@ -916,7 +930,13 @@ void match_word_pass2( //recog one word
float x_height) {
WERD *bln_word; //baseline norm copy
//detailed results
BLOB_CHOICE_LIST_CLIST blob_choices;
BLOB_CHOICE_LIST_CLIST local_blob_choices;
BLOB_CHOICE_LIST_CLIST *blob_choices;
if (save_best_choices)
blob_choices = new BLOB_CHOICE_LIST_CLIST();
else
blob_choices = &local_blob_choices;
set_global_subsubloc_code(SUBSUBLOC_OTHER);
if (matcher_fp != NULL) {
@ -933,25 +953,25 @@ void match_word_pass2( //recog one word
tess_default_matcher,
tess_training_tester,
word->raw_choice,
&blob_choices, word->outword);
blob_choices, word->outword);
else if (tessedit_dump_choices)
word->best_choice = test_segment_pass2 (bln_word,
&word->denorm,
tess_default_matcher,
choice_dump_tester,
word->raw_choice,
&blob_choices, word->outword);
blob_choices, word->outword);
// else if (tessedit_training_wiseowl)
// best_choice=correct_segment_pass2( word, &denorm,
// tess_default_matcher,wo_learn,
// raw_choice,&blob_choices,outword);
// raw_choice,blob_choices,outword);
// else if (tessedit_matcher_is_wiseowl)
// best_choice=tess_segment_pass2( word, &denorm, wo_classify,
// raw_choice, &blob_choices, outword);
// raw_choice, blob_choices, outword);
else {
word->best_choice = tess_segment_pass2 (bln_word, &word->denorm,
tess_default_matcher,
word->raw_choice, &blob_choices,
word->raw_choice, blob_choices,
word->outword);
}
set_global_subsubloc_code(SUBSUBLOC_OTHER);
@ -971,17 +991,17 @@ void match_word_pass2( //recog one word
else {
if ((word->best_choice->lengths ().length () !=
word->outword->blob_list ()->length ()) ||
(word->best_choice->lengths ().length () != blob_choices.length ())) {
(word->best_choice->lengths ().length () != blob_choices->length ())) {
tprintf
("ASSERT FAIL String:\"%s\"; Strlen=%d; #Blobs=%d; #Choices=%d\n",
word->best_choice->string ().string (),
word->best_choice->lengths ().length (),
word->outword->blob_list ()->length (), blob_choices.length ());
word->outword->blob_list ()->length (), blob_choices->length ());
}
ASSERT_HOST (word->best_choice->lengths ().length () ==
word->outword->blob_list ()->length ());
ASSERT_HOST (word->best_choice->lengths ().length () ==
blob_choices.length ());
blob_choices->length ());
word->tess_failed = FALSE;
if (word->word->flag (W_REP_CHAR)) {
@ -989,37 +1009,43 @@ void match_word_pass2( //recog one word
}
else {
fix_quotes (word->best_choice,
word->outword, &blob_choices);
word->outword, blob_choices);
if (tessedit_fix_hyphens)
fix_hyphens (word->best_choice,
word->outword, &blob_choices);
word->outword, blob_choices);
/* Dont trust fix_quotes! - though I think I've fixed the bug */
if ((word->best_choice->lengths ().length () !=
word->outword->blob_list ()->length ()) ||
(word->best_choice->lengths ().length () !=
blob_choices.length ())) {
blob_choices->length ())) {
#ifndef SECURE_NAMES
tprintf
("POST FIX_QUOTES FAIL String:\"%s\"; Strlen=%d; #Blobs=%d; #Choices=%d\n",
word->best_choice->string ().string (),
word->best_choice->lengths ().length (),
word->outword->blob_list ()->length (),
blob_choices.length ());
blob_choices->length ());
#endif
}
ASSERT_HOST (word->best_choice->lengths ().length () ==
word->outword->blob_list ()->length ());
ASSERT_HOST (word->best_choice->lengths ().length () ==
blob_choices.length ());
blob_choices->length ());
word->tess_accepted = tess_acceptable_word (word->best_choice,
word->raw_choice);
make_reject_map (word, &blob_choices, row, 2);
make_reject_map (word, blob_choices, row, 2);
}
}
blob_choices.deep_clear ();
// Save best choices in the WERD_CHOICE if needed
if (blob_choices != &local_blob_choices)
word->best_choice->set_blob_choices(blob_choices);
else
blob_choices->deep_clear();
delete bln_word;
assert (word->raw_choice != NULL);
}
@ -1136,7 +1162,8 @@ void fix_quotes( //make double quotes
if (str[offset + choice->lengths()[i]] != '\0' &&
is_simple_quote(str + offset, choice->lengths()[i]) &&
is_simple_quote(str + offset + choice->lengths()[i],
choice->lengths()[i + 1])) {
choice->lengths()[i + 1]) &&
unicharset.contains_unichar("\"")) {
str[offset] = '"'; //turn to double
strcpy (str + offset + 1,
str + offset + choice->lengths()[i] +
@ -1736,17 +1763,17 @@ void font_recognition_pass( //good chars in word
count = word->italic;
if (count < 0)
count = -count;
if (!(count == length || length > 3 && count >= length * 3 / 4))
if (!(count == length || (length > 3 && count >= length * 3 / 4)))
word->italic = doc_italic > 0 ? 1 : -1;
count = word->bold;
if (count < 0)
count = -count;
if (!(count == length || length > 3 && count >= length * 3 / 4))
if (!(count == length || (length > 3 && count >= length * 3 / 4)))
word->bold = doc_bold > 0 ? 1 : -1;
count = word->font1_count;
if (!(count == length || length > 3 && count >= length * 3 / 4)) {
if (!(count == length || (length > 3 && count >= length * 3 / 4))) {
word->font1 = doc_font;
word->font1_count = doc_font_count;
}

View File

@ -28,14 +28,15 @@
#include "tessvars.h"
#include "stderr.h"
#include "img.h"
#include "evnts.h"
#include "showim.h"
//#include "evnts.h"
//#include "showim.h"
#include "hosthplb.h"
#include "grphics.h"
#include "evnts.h"
#include "scrollview.h"
//#include "evnts.h"
#include "adaptions.h"
#include "matmatch.h"
#include "secname.h"
#include "svshowim.h"
#define EXTERN
@ -285,78 +286,68 @@ float match1( /* returns match score */
#ifndef GRAPHICS_DISABLED
void display_images(IMAGE *image_w, IMAGE *image_n, IMAGE *match_image) {
WINDOW w_im_window;
WINDOW n_im_window;
WINDOW match_window;
GRAPHICS_EVENT event; //output event
ScrollView* w_im_window;
ScrollView* n_im_window;
ScrollView* match_window;
INT16 i;
// xmin xmax ymin ymax
w_im_window = create_window ("Image 1", SCROLLINGWIN, 20, 100, 10 * image_w->get_xsize (), 10 * image_w->get_ysize (), 0, image_w->get_xsize (), 0, image_w->get_ysize (),
TRUE, FALSE, FALSE, TRUE); // down event & key only
w_im_window = new ScrollView("Image 1", 20, 100,
10 * image_w->get_xsize (), 10 * image_w->get_ysize (),
image_w->get_xsize (), image_w->get_ysize ());
clear_view_surface(w_im_window);
show_sub_image (image_w,
sv_show_sub_image (image_w,
0, 0,
image_w->get_xsize (), image_w->get_ysize (),
w_im_window, 0, 0);
line_color_index(w_im_window, RED);
w_im_window->Pen(255,0,0);
for (i = 1; i < image_w->get_xsize (); i++) {
move2d (w_im_window, i, 0);
draw2d (w_im_window, i, image_w->get_ysize ());
w_im_window->Line(i, 0, i, image_w->get_ysize ());
}
for (i = 1; i < image_w->get_ysize (); i++) {
move2d (w_im_window, 0, i);
draw2d (w_im_window, image_w->get_xsize (), i);
w_im_window->Line(0, i, image_w->get_xsize (), i);
}
// xmin xmax ymin ymax
n_im_window = create_window ("Image 2", SCROLLINGWIN, 240, 100, 10 * image_n->get_xsize (), 10 * image_n->get_ysize (), 0, image_n->get_xsize (), 0, image_n->get_ysize (),
TRUE, FALSE, FALSE, TRUE); // down event & key only
n_im_window = new ScrollView ("Image 2", 240, 100,
10 * image_n->get_xsize (), 10 * image_n->get_ysize (),
image_n->get_xsize (), image_n->get_ysize ());
clear_view_surface(n_im_window);
show_sub_image (image_n,
sv_show_sub_image (image_n,
0, 0,
image_n->get_xsize (), image_n->get_ysize (),
n_im_window, 0, 0);
line_color_index(n_im_window, RED);
n_im_window->Pen(255,0,0);
for (i = 1; i < image_n->get_xsize (); i++) {
move2d (n_im_window, i, 0);
draw2d (n_im_window, i, image_n->get_ysize ());
n_im_window->Line(i, 0, i, image_n->get_ysize ());
}
for (i = 1; i < image_n->get_ysize (); i++) {
move2d (n_im_window, 0, i);
draw2d (n_im_window, image_n->get_xsize (), i);
n_im_window->Line(0, i, image_n->get_xsize (), i);
}
overlap_picture_ops(TRUE);
// xmin xmax ymin ymax
match_window = create_window ("Match Result", SCROLLINGWIN, 460, 100, 10 * match_image->get_xsize (), 10 * match_image->get_ysize (), 0, match_image->get_xsize (), 0, match_image->get_ysize (),
TRUE, FALSE, FALSE, TRUE); // down event & key only
match_window = new ScrollView ("Match Result", 460, 100,
10 * match_image->get_xsize (), 10 * match_image->get_ysize (),
match_image->get_xsize (), match_image->get_ysize ());
clear_view_surface(match_window);
show_sub_image (match_image,
match_window->Clear();
sv_show_sub_image (match_image,
0, 0,
match_image->get_xsize (), match_image->get_ysize (),
match_window, 0, 0);
line_color_index(match_window, RED);
match_window->Pen(255,0,0);
for (i = 1; i < match_image->get_xsize (); i++) {
move2d (match_window, i, 0);
draw2d (match_window, i, match_image->get_ysize ());
match_window->Line(i, 0, i, match_image->get_ysize ());
}
for (i = 1; i < match_image->get_ysize (); i++) {
move2d (match_window, 0, i);
draw2d (match_window, match_image->get_xsize (), i);
match_window->Line(0, i, match_image->get_xsize (), i);
}
overlap_picture_ops(TRUE);
SVEvent* sve = match_window->AwaitEvent(SVET_DESTROY);
delete sve;
await_event(match_window, TRUE, ANY_EVENT, &event);
destroy_window(w_im_window);
destroy_window(n_im_window);
destroy_window(match_window);
delete w_im_window;
delete n_im_window;
delete match_window;
}
@ -367,37 +358,33 @@ void display_images(IMAGE *image_w, IMAGE *image_n, IMAGE *match_image) {
*
*************************************************************************/
WINDOW display_image(IMAGE *image,
ScrollView* display_image(IMAGE *image,
const char *title,
INT32 x,
INT32 y,
BOOL8 wait) {
WINDOW im_window;
ScrollView* im_window;
INT16 i;
GRAPHICS_EVENT event; //output event
// xmin xmax ymin ymax
im_window = create_window (title, SCROLLINGWIN, x, y, 10 * image->get_xsize (), 10 * image->get_ysize (), 0, image->get_xsize (), 0, image->get_ysize (),
TRUE, FALSE, FALSE, TRUE); // down event & key only
im_window = new ScrollView (title, x, y,
10 * image->get_xsize (), 10 * image->get_ysize (),
image->get_xsize (), image->get_ysize ());
clear_view_surface(im_window);
show_sub_image (image,
sv_show_sub_image (image,
0, 0,
image->get_xsize (), image->get_ysize (), im_window, 0, 0);
line_color_index(im_window, RED);
im_window->Pen(255,0,0);
for (i = 1; i < image->get_xsize (); i++) {
move2d (im_window, i, 0);
draw2d (im_window, i, image->get_ysize ());
im_window->SetCursor(i, 0);
im_window->DrawTo(i, image->get_ysize());
}
for (i = 1; i < image->get_ysize (); i++) {
move2d (im_window, 0, i);
draw2d (im_window, image->get_xsize (), i);
im_window->SetCursor(0, i);
im_window->DrawTo(image->get_xsize(),i);
}
overlap_picture_ops(TRUE);
if (wait)
await_event(im_window, TRUE, ANY_EVENT, &event);
if (wait) { delete im_window->AwaitEvent(SVET_CLICK); }
return im_window;
}

View File

@ -40,7 +40,7 @@ float match1( /* returns match score */
IMAGE *image_w,
IMAGE *image_n);
void display_images(IMAGE *image_w, IMAGE *image_n, IMAGE *match_image);
WINDOW display_image(IMAGE *image,
ScrollView* display_image(IMAGE *image,
const char *title,
INT32 x,
INT32 y,

666
ccmain/pagewalk.cpp Normal file
View File

@ -0,0 +1,666 @@
/**********************************************************************
* File: pagewalk.cpp (Formerly walkers.c)
* Description: Block list processors
* 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 "pagewalk.h"
#define EXTERN
EXTERN BOOL_VAR (current_word_quit, FALSE, "Stop processing this word");
DLLSYM BOOL_VAR (selection_quit, FALSE, "Stop processing this selection");
/**********************************************************************
* block_list_bounding_box()
*
* Scan block list to find the bounding box of all blocks.
**********************************************************************/
BOX block_list_bounding_box( //find bounding box
BLOCK_LIST *block_list //of this block list
) {
BLOCK_IT block_it(block_list);
BOX enclosing_box;
for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
block_it.forward ())
enclosing_box += block_it.data ()->bounding_box ();
return enclosing_box;
}
/**********************************************************************
* block_list_compress()
*
* Pack a block list to occupy a smaller space by compressing each block and
* moving the compressed blocks one above the other.
* The compressed block list has the same top left point as the uncompressed
* first. Blocks are reordered so that the source names are in alphabetic
* order. (This gathers together, but does not combine, blocks from the same
* file.)
* The enclosing box of the compressed block list is returned.
**********************************************************************/
const BOX block_list_compress( //shuffle up blocks
BLOCK_LIST *block_list) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ICOORD initial_top_left;
ICOORD block_spacing (0, BLOCK_SPACING);
BOX enclosing_box; //for full display
initial_top_left = block_it.data ()->bounding_box ().topleft ();
//group srcfile blks
block_it.sort (block_name_order);
/* Compress the target block list into an area starting from the top left of
the first block on the list */
enclosing_box = BOX (initial_top_left, initial_top_left);
enclosing_box.move_bottom_edge (BLOCK_SPACING);
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
block->compress (enclosing_box.botleft () - block_spacing -
block->bounding_box ().topleft ());
enclosing_box += block->bounding_box ();
}
return enclosing_box;
}
/**********************************************************************
* block_list_move()
*
* Move all the blocks in the list by a vector
**********************************************************************/
void block_list_move( //move
BLOCK_LIST *block_list, //this list
ICOORD vec //by this vector
) {
BLOCK_IT block_it(block_list);
for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
block_it.forward ())
block_it.data ()->move (vec);
}
/**********************************************************************
* block_name_order()
*
* Block comparator used to sort a block list so that blocks from the same
* filename are located together, and blocks from the same file are ordered
* by vertical position.
**********************************************************************/
int block_name_order( //sort blocks
const void *block1p, //ptr to ptr to block1
const void *block2p //ptr to ptr to block2
) {
int result;
BLOCK *block1 = *(BLOCK **) block1p;
BLOCK *block2 = *(BLOCK **) block2p;
result = strcmp (block1->name (), block2->name ());
if (result == 0)
result = block2->bounding_box ().top () - block1->bounding_box ().top ();
return result;
}
/**********************************************************************
* process_all_blobs()
*
* Walk the current block list applying the specified blob processor function
* to all blobs
**********************************************************************/
void
process_all_blobs ( //process blobs
BLOCK_LIST * block_list, //blocks to check
BOOL8 blob_processor ( //function to call
//function to call
BLOCK *, ROW *, WERD *, PBLOB *), BOOL8 c_blob_processor (
BLOCK
*,
ROW
*,
WERD
*,
C_BLOB
*)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
WERD_IT word_it;
WERD *word;
PBLOB_IT blob_it;
PBLOB *blob;
C_BLOB_IT c_blob_it;
C_BLOB *c_blob;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
word_it.set_to_list (row->word_list ());
for (word_it.mark_cycle_pt ();
!word_it.cycled_list (); word_it.forward ()) {
word = word_it.data ();
if (word->flag (W_POLYGON)) {
if (blob_processor != NULL) {
blob_it.set_to_list (word->blob_list ());
for (blob_it.mark_cycle_pt ();
!blob_it.cycled_list (); blob_it.forward ()) {
blob = blob_it.data ();
if (!blob_processor (block, row, word, blob) ||
selection_quit)
return;
}
}
}
else {
if (c_blob_processor != NULL) {
c_blob_it.set_to_list (word->cblob_list ());
for (c_blob_it.mark_cycle_pt ();
!c_blob_it.cycled_list (); c_blob_it.forward ()) {
c_blob = c_blob_it.data ();
if (!c_blob_processor (block, row, word, c_blob) ||
selection_quit)
return;
}
}
}
}
}
}
}
/**********************************************************************
* process_selected_blobs()
*
* Walk the current block list applying the specified blob processor function
* to each selected blob
**********************************************************************/
void
process_selected_blobs ( //process blobs
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 blob_processor (
//function to call
BLOCK *, ROW *, WERD *, PBLOB *), BOOL8 c_blob_processor (
BLOCK
*,
ROW
*,
WERD
*,
C_BLOB
*)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
WERD_IT word_it;
WERD *word;
PBLOB_IT blob_it;
PBLOB *blob;
C_BLOB_IT c_blob_it;
C_BLOB *c_blob;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (block->bounding_box ().overlap (selection_box)) {
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt ();
!row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (row->bounding_box ().overlap (selection_box)) {
word_it.set_to_list (row->word_list ());
for (word_it.mark_cycle_pt ();
!word_it.cycled_list (); word_it.forward ()) {
word = word_it.data ();
if (word->bounding_box ().overlap (selection_box)) {
if (word->flag (W_POLYGON)) {
if (blob_processor != NULL) {
blob_it.set_to_list (word->blob_list ());
for (blob_it.mark_cycle_pt ();
!blob_it.cycled_list ();
blob_it.forward ()) {
blob = blob_it.data ();
if (blob->bounding_box ().
overlap (selection_box)) {
if (!blob_processor
(block, row, word, blob)
|| selection_quit)
return;
}
}
}
}
else {
if (c_blob_processor != NULL) {
c_blob_it.set_to_list (word->cblob_list ());
for (c_blob_it.mark_cycle_pt ();
!c_blob_it.cycled_list ();
c_blob_it.forward ()) {
c_blob = c_blob_it.data ();
if (c_blob->
bounding_box ().
overlap (selection_box)) {
if (!c_blob_processor
(block, row, word, c_blob)
|| selection_quit)
return;
}
}
}
}
}
}
}
}
}
}
}
/**********************************************************************
* process_all_words()
*
* Walk the current block list applying the specified word processor function
* to all words
**********************************************************************/
void
process_all_words ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 word_processor ( //function to call
BLOCK *, ROW *, WERD *)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
WERD_IT word_it;
WERD *word;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
word_it.set_to_list (row->word_list ());
for (word_it.mark_cycle_pt ();
!word_it.cycled_list (); word_it.forward ()) {
word = word_it.data ();
if (!word_processor (block, row, word) || selection_quit)
return;
}
}
}
}
/**********************************************************************
* process_selected_words()
*
* Walk the current block list applying the specified word processor function
* to each word selected.
**********************************************************************/
void
process_selected_words ( //process words
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 word_processor (
BLOCK *,
ROW *,
WERD *)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
WERD_IT word_it;
WERD *word;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (block->bounding_box ().overlap (selection_box)) {
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt ();
!row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (row->bounding_box ().overlap (selection_box)) {
word_it.set_to_list (row->word_list ());
for (word_it.mark_cycle_pt ();
!word_it.cycled_list (); word_it.forward ()) {
word = word_it.data ();
if (word->bounding_box ().overlap (selection_box)) {
if (!word_processor (block, row, word) ||
selection_quit)
return;
}
}
}
}
}
}
}
/**********************************************************************
* process_all_words_it() PASS ITERATORS
*
* Walk the current block list applying the specified word processor function
* to all words
**********************************************************************/
void
process_all_words_it ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 word_processor ( //function to call
BLOCK *,
ROW *,
WERD *,
BLOCK_IT &,
ROW_IT &, WERD_IT &)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
WERD_IT word_it;
WERD *word;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
word_it.set_to_list (row->word_list ());
for (word_it.mark_cycle_pt ();
!word_it.cycled_list (); word_it.forward ()) {
word = word_it.data ();
if (!word_processor
(block, row, word, block_it, row_it, word_it)
|| selection_quit)
return;
}
}
}
}
/**********************************************************************
* process_selected_words_it() PASS ITERATORS
*
* Walk the current block list applying the specified word processor function
* to each word selected.
**********************************************************************/
void
process_selected_words_it ( //process words
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 word_processor (
BLOCK
*,
ROW *,
WERD
*,
BLOCK_IT
&,
ROW_IT
&,
WERD_IT
&)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
WERD_IT word_it;
WERD *word;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (block->bounding_box ().overlap (selection_box)) {
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt ();
!row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (row->bounding_box ().overlap (selection_box)) {
word_it.set_to_list (row->word_list ());
for (word_it.mark_cycle_pt ();
!word_it.cycled_list (); word_it.forward ()) {
word = word_it.data ();
if (word->bounding_box ().overlap (selection_box)) {
if (!word_processor (block, row, word,
block_it, row_it, word_it) ||
selection_quit)
return;
}
}
}
}
}
}
}
/**********************************************************************
* process_all_blocks()
*
* Walk the current block list applying the specified block processor function
* to each block.
**********************************************************************/
void
process_all_blocks ( //process blocks
BLOCK_LIST * block_list, //blocks to check
BOOL8 block_processor ( //function to call
BLOCK *)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (!block_processor (block) || selection_quit)
return;
}
}
/**********************************************************************
* process_selected_blocks()
*
* Walk the current block list applying the specified block processor function
* to each block selected.
**********************************************************************/
void
process_selected_blocks ( //process blocks
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 block_processor (
BLOCK
*)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (block->bounding_box ().overlap (selection_box)) {
if (!block_processor (block) || selection_quit)
return;
}
}
}
/**********************************************************************
* process_all_rows()
*
* Walk the current block list applying the specified row processor function
* to all rows
**********************************************************************/
void
process_all_rows ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 row_processor ( //function to call
BLOCK *, ROW *)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (!row_processor (block, row) || selection_quit)
return;
}
}
}
/**********************************************************************
* process_selected_rows()
*
* Walk the current block list applying the specified row processor function
* to each row selected.
**********************************************************************/
void
process_selected_rows ( //process rows
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 row_processor (
BLOCK *,
ROW *)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (block->bounding_box ().overlap (selection_box)) {
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt ();
!row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (row->bounding_box ().overlap (selection_box)) {
if (!row_processor (block, row) || selection_quit)
return;
}
}
}
}
}
/**********************************************************************
* process_all_rows_it() PASS ITERATORS
*
* Walk the current block list applying the specified row processor function
* to all rows
**********************************************************************/
void
process_all_rows_it ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 row_processor ( //function to call
BLOCK *,
ROW *, BLOCK_IT &, ROW_IT &)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (!row_processor (block, row, block_it, row_it) || selection_quit)
return;
}
}
}
/**********************************************************************
* process_selected_rows_it() PASS ITERATORS
*
* Walk the current block list applying the specified row processor function
* to each row selected.
**********************************************************************/
void
process_selected_rows_it ( //process rows
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 row_processor (
BLOCK *,
ROW *,
BLOCK_IT
&,
ROW_IT
&)) {
BLOCK_IT block_it(block_list);
BLOCK *block;
ROW_IT row_it;
ROW *row;
for (block_it.mark_cycle_pt ();
!block_it.cycled_list (); block_it.forward ()) {
block = block_it.data ();
if (block->bounding_box ().overlap (selection_box)) {
row_it.set_to_list (block->row_list ());
for (row_it.mark_cycle_pt ();
!row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
if (row->bounding_box ().overlap (selection_box)) {
if (!row_processor (block, row, block_it, row_it) ||
selection_quit)
return;
}
}
}
}
}

155
ccmain/pagewalk.h Normal file
View File

@ -0,0 +1,155 @@
/**********************************************************************
* File: pagewalk.h (Formerly walkers.h)
* Description: Structure processors
* 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.
*
**********************************************************************/
#ifndef PAGEWALK_H
#define PAGEWALK_H
#include "ocrblock.h"
#include "ocrrow.h"
#include "werd.h"
#include "polyblob.h"
#include "stepblob.h"
#include "rect.h"
#include "varable.h"
#include "notdll.h"
#define BLOCK_SPACING 20
extern BOOL_VAR_H (current_word_quit, FALSE, "Stop processing this word");
extern DLLSYM BOOL_VAR_H (selection_quit, FALSE,
"Stop processing this selection");
BOX block_list_bounding_box( //find bounding box
BLOCK_LIST *block_list //of this block list
);
const BOX block_list_compress( //shuffle up blocks
BLOCK_LIST *block_list);
void block_list_move( //move
BLOCK_LIST *block_list, //this list
ICOORD vec //by this vector
);
int block_name_order( //sort blocks
const void *block1p, //ptr to ptr to block1
const void *block2p //ptr to ptr to block2
);
void process_all_blobs ( //process blobs
BLOCK_LIST * block_list, //blocks to check
BOOL8 blob_processor ( //function to call
//function to call
BLOCK *, ROW *, WERD *, PBLOB *), BOOL8 c_blob_processor (
BLOCK
*,
ROW
*,
WERD
*,
C_BLOB
*));
void process_selected_blobs ( //process blobs
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 blob_processor (
//function to call
BLOCK *, ROW *, WERD *, PBLOB *), BOOL8 c_blob_processor (
BLOCK
*,
ROW
*,
WERD
*,
C_BLOB
*));
void process_all_words ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 word_processor ( //function to call
BLOCK *, ROW *, WERD *));
void process_selected_words ( //process words
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 word_processor (
BLOCK
*,
ROW
*,
WERD
*));
void process_all_words_it ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 word_processor ( //function to call
BLOCK *,
ROW *,
WERD *,
BLOCK_IT &,
ROW_IT &, WERD_IT &));
void process_selected_words_it ( //process words
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 word_processor (
BLOCK
*,
ROW
*,
WERD
*,
BLOCK_IT
&,
ROW_IT
&,
WERD_IT
&));
void process_all_blocks ( //process blocks
BLOCK_LIST * block_list, //blocks to check
BOOL8 block_processor ( //function to call
BLOCK *));
void process_selected_blocks ( //process blocks
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 block_processor (
BLOCK
*));
void process_all_rows ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 row_processor ( //function to call
BLOCK *, ROW *));
void process_selected_rows ( //process rows
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 row_processor (
BLOCK
*,
ROW
*));
void process_all_rows_it ( //process words
BLOCK_LIST * block_list, //blocks to check
BOOL8 row_processor ( //function to call
BLOCK *,
ROW *,
BLOCK_IT &, ROW_IT &));
void process_selected_rows_it ( //process rows
BLOCK_LIST * block_list, //blocks to check
//function to call
BOX & selection_box, BOOL8 row_processor (
BLOCK
*,
ROW
*,
BLOCK_IT
&,
ROW_IT
&));
#endif

1863
ccmain/pgedit.cpp Executable file

File diff suppressed because it is too large Load Diff

181
ccmain/pgedit.h Executable file
View File

@ -0,0 +1,181 @@
///////////////////////////////////////////////////////////////////////
// File: pgedit.h
// Description: Page structure file editor
// Author: Joern Wanke
// Created: Wed Jul 18 10:05:01 PDT 2007
//
// (C) Copyright 2007, Google Inc.
// 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.
//
///////////////////////////////////////////////////////////////////////
#ifndef PGEDIT_H
#define PGEDIT_H
#include "ocrblock.h"
#include "ocrrow.h"
#include "werd.h"
#include "rect.h"
#include "pagewalk.h"
#include "varable.h"
#include "notdll.h"
class ScrollView;
class SVMenuNode;
struct SVEvent;
// A small event handler class to process incoming events to
// this window.
class PGEventHandler : public SVEventHandler {
public:
void Notify(const SVEvent* sve);
};
extern BLOCK_LIST *current_block_list;
extern BOOL8 *current_image_changed;
extern STRING_VAR_H (editor_image_win_name, "EditorImage",
"Editor image window name");
extern INT_VAR_H (editor_image_xpos, 590, "Editor image X Pos");
extern INT_VAR_H (editor_image_ypos, 10, "Editor image Y Pos");
extern INT_VAR_H (editor_image_height, 680, "Editor image height");
extern INT_VAR_H (editor_image_width, 655, "Editor image width");
extern INT_VAR_H (editor_image_word_bb_color, BLUE,
"Word bounding box colour");
extern INT_VAR_H (editor_image_blob_bb_color, YELLOW,
"Blob bounding box colour");
extern INT_VAR_H (editor_image_text_color, WHITE, "Correct text colour");
extern STRING_VAR_H (editor_dbwin_name, "EditorDBWin",
"Editor debug window name");
extern INT_VAR_H (editor_dbwin_xpos, 50, "Editor debug window X Pos");
extern INT_VAR_H (editor_dbwin_ypos, 500, "Editor debug window Y Pos");
extern INT_VAR_H (editor_dbwin_height, 24, "Editor debug window height");
extern INT_VAR_H (editor_dbwin_width, 80, "Editor debug window width");
extern STRING_VAR_H (editor_word_name, "BlnWords",
"BL normalised word window");
extern INT_VAR_H (editor_word_xpos, 60, "Word window X Pos");
extern INT_VAR_H (editor_word_ypos, 510, "Word window Y Pos");
extern INT_VAR_H (editor_word_height, 240, "Word window height");
extern INT_VAR_H (editor_word_width, 655, "Word window width");
extern double_VAR_H (editor_smd_scale_factor, 1.0, "Scaling for smd image");
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
);
ScrollView* bln_word_window_handle(); //return handle
void build_image_window(BOX page_bounding_box);
SVMenuNode *build_menu_new();
void display_bln_lines(ScrollView window,
ScrollView::Color colour,
float scale_factor,
float y_offset,
float minx,
float maxx);
void do_new_source( //serialise
char *name //file name
);
//function to call
void do_re_display (BOOL8 word_painter (
BLOCK *, ROW *, WERD *));
const BOX do_tidy_cmd(); //tidy
void do_view_cmd();
void do_write_file( //serialise
char *name //file name
);
void pgeditor_main(BLOCK_LIST *blocks);
void pgeditor_msg( //message display
const char *msg);
//of serialised file
void pgeditor_read_file(STRING &name,
BLOCK_LIST *blocks //block list to add to
);
void pgeditor_show_point( //display coords
SVEvent *event);
void pgeditor_write_file( //serialise
char *name, //file name
BLOCK_LIST *blocks //block list to write
);
BOOL8 process_cmd_win_event( //UI command semantics
INT32 cmd_event, //which menu item?
char *new_value //any prompt data
);
void process_image_event( //action in image win
const SVEvent &event);
//put bln word in box
float re_scale_and_move_bln_word(WERD *norm_word, //BL normalised word
const BOX &box //destination box
);
void re_segment_word( //break/join words
BLOCK_LIST *block_list, //blocks to check
BOX &selection_box);
void block_space_stat( //show space stats
BLOCK_LIST *block_list, //blocks to check
BOX &selection_box);
void row_space_stat( //show space stats
BLOCK_LIST *block_list, //blocks to check
BOX &selection_box);
void show_point( //display posn of bloba word
BLOCK_LIST *block_list, //blocks to check
float x,
float y);
//display a word
BOOL8 word_blank_and_set_display(BLOCK *block, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_bln_display( //bln & display
BLOCK *, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_change_text( //change correct text
BLOCK *block, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_copy( //copy a word
BLOCK *block, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_delete( //delete a word
BLOCK *block, //block holding word
ROW *row, //row holding word
WERD *word, //word to be processed
BLOCK_IT &block_it, //block list iterator
ROW_IT &row_it, //row list iterator
WERD_IT &word_it //word list iterator
);
BOOL8 word_display( // display a word
BLOCK *, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_dumper( //dump word
BLOCK *block, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_set_display( //display a word
BLOCK *block, //block holding word
ROW *row, //row holding word
WERD *word //word to be processed
);
BOOL8 word_toggle_seg( //toggle seg flag
BLOCK *, //block holding word
ROW *, //row holding word
WERD *word //word to be processed
);
void do_check_mem( //do it
INT32 level);
#endif

View File

@ -279,11 +279,11 @@ void set_done( //set done flag
if (word->done &&
(pass == 1) &&
((word->best_choice->permuter () != SYSTEM_DAWG_PERM) &&
(((word->best_choice->permuter () != SYSTEM_DAWG_PERM) &&
(word->best_choice->permuter () != FREQ_DAWG_PERM) &&
(word->best_choice->permuter () != USER_DAWG_PERM) &&
(word->best_choice->permuter () != NUMBER_PERM)) ||
(test_ambig_word (word))) {
(test_ambig_word (word)))) {
#ifndef SECURE_NAMES
if (tessedit_rejection_debug)
tprintf ("\nVETO Tess accepting poor word \"%s\"\n",
@ -303,11 +303,11 @@ void set_done( //set done flag
word->done = FALSE;
if (word->done &&
((word->best_choice->permuter () != SYSTEM_DAWG_PERM) &&
(((word->best_choice->permuter () != SYSTEM_DAWG_PERM) &&
(word->best_choice->permuter () != FREQ_DAWG_PERM) &&
(word->best_choice->permuter () != USER_DAWG_PERM) &&
(word->best_choice->permuter () != NUMBER_PERM)) ||
(test_ambig_word (word))) {
(test_ambig_word (word)))) {
#ifndef SECURE_NAMES
if (tessedit_rejection_debug)
tprintf ("\nVETO Tess accepting poor word \"%s\"\n",
@ -1054,7 +1054,7 @@ void nn_match_word( //Match a word
IMAGELINE *imlines; //lines of the image
BOX pix_box; //box of imlines extent
#ifndef GRAPHICS_DISABLED
WINDOW win = NULL;
ScrollView* win = NULL;
#endif
IMAGE clip_image;
IMAGE scaled_image;
@ -1185,8 +1185,8 @@ void nn_match_word( //Match a word
if (show_char_clipping)
display_images(clip_image, scaled_image);
#endif
clip_image.destroy ();
scaled_image.destroy ();
clip_image.destroy();
scaled_image.destroy();
}
delete[]imlines; // Free array of imlines
@ -1194,7 +1194,9 @@ void nn_match_word( //Match a word
#ifndef GRAPHICS_DISABLED
if (show_char_clipping) {
destroy_window(win);
// destroy_window(win);
// win->Destroy();
delete win;
}
#endif
}
@ -1749,7 +1751,7 @@ void flip_0O(WERD_RES *word) {
str[offset - lengths[i - 1] - lengths[i - 2]] == 'O')
str[offset - lengths[i - 1] - lengths[i - 2]] = '0';
while (lengths[i] == 1 &&
(str[offset] == 'O') || (str[offset] == '0')) {
((str[offset] == 'O') || (str[offset] == '0'))) {
str[offset] = '0';
offset += lengths[i++];
}

View File

@ -29,7 +29,7 @@
#include <string.h>
#include "fileerr.h"
#include "tprintf.h"
#include "grphics.h"
//#include "grphics.h"
#include "img.h"
//#include "basefile.h"
#include "imgscale.h"

110
ccmain/tessio.h Normal file
View File

@ -0,0 +1,110 @@
/**********************************************************************
* File: tessio.h (Formerly tessread.h)
* Description: Read/write Tesseract format row files.
* Author: Ray Smith
* Created: Wed Oct 09 15:02:46 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.
*
**********************************************************************/
#ifndef TESSIO_H
#define TESSIO_H
#include <stdio.h>
#include "tessclas.h"
#include "notdll.h"
TEXTROW *get_tess_row_file( //open read & close
const char *name, //file name
TPOINT *topright //corner
);
TBLOB *get_tess_blob_file( //open read & close
const char *name, //file name
TPOINT *topright //corner
);
TEXTROW *readrows( //read row file
int gphfd, /*file to read */
int count, /*number expected */
TPOINT *imagesize //size of image
);
TWERD *readwords( //read some words
int gphfd, /*file to read */
int count, /*number expected */
TEXTROW *row, /*row it comes from */
TPOINT *imagesize /*size of image */
);
TBLOB *readblobs( //read some blobs
int gphfd, /*file to read */
int count, /*number expected */
TPOINT *imagesize /*size of image */
);
char *readratings( //get a string
int gphfd, /*file to read */
int ratingspace /*size to read */
);
void readoutlines( //read some outlines
int gphfd, /*file to read */
TESSLINE **outlines, /*array of ptrs */
int outlinecount /*no to read */
);
int readgph( //read with testing
int fd, /*file to read */
void *start, /*buffer to write */
int size, /*amount to write */
int checkeof /*give error on eof? */
);
void write_row( //write a row
FILE *name, //file to write
TEXTROW *row /*row to write */
);
void write_error_row( //write special row
FILE *name, /*file name */
TEXTROW *row, /*row to write */
int wordcount /*no of words to go */
);
void write_error_blob( //write special blob
FILE *name, /*file name */
TBLOB *blob, /*blob to write */
char *charlist, /*true chars */
int charcount /*no of true chars */
);
void write_error_word( //write special word
FILE *name, /*file name */
TWERD *word, /*word to write */
char *charlist, /*true chars */
int charcount /*no of true chars */
);
void writeblob( //write a blob
FILE *name, /*file to write */
TBLOB *blob /*blob to write */
);
void serial_outlines( //serialize
FILE *name, /*file to write to */
TBLOB *blob, /*current blob */
register TESSLINE *outline, /*current outline */
int *outlineno /*current serial no */
);
int countloop( //count loopsize
register BYTEVEC *vector /*vectors to count */
);
int outlineserial( //get serial no
register TESSLINE *outline, /*start of serach */
register TESSLINE *target, /*outline to find */
int serial /*serial no so far */
);
void writegph( //interface to fwrite
FILE *name, /*file to write */
void *start, /*buffer to write */
int size /*amount to write */
);
#endif

350
ccmain/varabled.cpp Normal file
View File

@ -0,0 +1,350 @@
///////////////////////////////////////////////////////////////////////
// File: varabled.cpp
// Description: Variables Editor
// Author: Joern Wanke
// Created: Wed Jul 18 10:05:01 PDT 2007
//
// (C) Copyright 2007, Google Inc.
// 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.
//
///////////////////////////////////////////////////////////////////////
//
// The variables editor is used to edit all the variables used within
// tesseract from the ui.
#ifndef GRAPHICS_DISABLED
#include "varabled.h"
#ifdef WIN32
#else
#include <stdlib.h>
#include <stdio.h>
#endif
#include <iostream>
#include <map>
#include <list>
#include "scrollview.h"
#include "svmnode.h"
#include "varable.h"
#include "mainblk.h"
#define VARDIR "configs/" /*variables files */
#define MAX_ITEMS_IN_SUBMENU 30
const ERRCODE NO_VARIABLES_TO_EDIT = "No Variables defined to edit";
// Contains the mappings from unique VC ids to their actual pointers.
static std::map<int, VariableContent*> vcMap;
static int nrVariables = 0;
static int writeCommands[2];
// Constructors for the various VarTypes.
VariableContent::VariableContent(STRING_VARIABLE* it) {
my_id_ = nrVariables;
nrVariables++;
var_type_ = VT_STRING;
sIt = it;
vcMap[my_id_] = this;
}
// Constructors for the various VarTypes.
VariableContent::VariableContent(INT_VARIABLE* it) {
my_id_ = nrVariables;
nrVariables++;
var_type_ = VT_INTEGER;
iIt = it;
vcMap[my_id_] = this;
}
// Constructors for the various VarTypes.
VariableContent::VariableContent(BOOL_VARIABLE* it) {
my_id_ = nrVariables;
nrVariables++;
var_type_ = VT_BOOLEAN;
bIt = it;
vcMap[my_id_] = this;
}
// Constructors for the various VarTypes.
VariableContent::VariableContent(double_VARIABLE* it) {
my_id_ = nrVariables;
nrVariables++;
var_type_ = VT_DOUBLE;
dIt = it;
vcMap[my_id_] = this;
}
// Gets a VC object identified by its ID.
VariableContent* VariableContent::GetVariableContentById(int id) {
return vcMap[id];
}
// Copy the first N words from the source string to the target string.
// Words are delimited by "_".
void VariablesEditor::GetFirstWords(
const char *s, // source string
int n, // number of words
char *t // target string
) {
int full_length = strlen(s);
int reqd_len = 0; // No. of chars requird
const char *next_word = s;
while ((n > 0) && reqd_len < full_length) {
reqd_len += strcspn(next_word, "_") + 1;
next_word += reqd_len;
n--;
}
strncpy(t, s, reqd_len);
t[reqd_len] = '\0'; // ensure null terminal
}
// Getter for the name.
const char* VariableContent::GetName() {
if (var_type_ == VT_INTEGER) { return iIt->name_str(); }
else if (var_type_ == VT_BOOLEAN) { return bIt->name_str(); }
else if (var_type_ == VT_DOUBLE) { return dIt->name_str(); }
else if (var_type_ == VT_STRING) { return sIt->name_str(); }
else
return "ERROR: VariableContent::GetName()";
}
// Getter for the description.
const char* VariableContent::GetDescription() {
if (var_type_ == VT_INTEGER) { return iIt->info_str(); }
else if (var_type_ == VT_BOOLEAN) { return bIt->info_str(); }
else if (var_type_ == VT_DOUBLE) { return dIt->info_str(); }
else if (var_type_ == VT_STRING) { return sIt->info_str(); }
else return NULL;
}
// Getter for the value.
const char* VariableContent::GetValue() {
char* msg = new char[1024];
if (var_type_ == VT_INTEGER) {
sprintf(msg, "%d", ((INT32) *(iIt)));
} else if (var_type_ == VT_BOOLEAN) {
sprintf(msg, "%d", ((BOOL8) * (bIt)));
} else if (var_type_ == VT_DOUBLE) {
sprintf(msg, "%g", ((double) * (dIt)));
} else if (var_type_ == VT_STRING) {
if (((STRING) * (sIt)).string() != NULL) {
sprintf(msg, "%s", ((STRING) * (sIt)).string());
} else {
strcpy(msg, "Null");
}
}
return msg;
}
// Setter for the value.
void VariableContent::SetValue(const char* val) {
// TODO (wanke) Test if the values actually are properly converted.
// (Quickly visible impacts?)
changed_ = TRUE;
if (var_type_ == VT_INTEGER) {
iIt->set_value(atoi(val));
} else if (var_type_ == VT_BOOLEAN) {
bIt->set_value(atoi(val));
} else if (var_type_ == VT_DOUBLE) {
dIt->set_value(strtod(val, NULL));
} else if (var_type_ == VT_STRING) {
sIt->set_value(val);
}
}
// Gets the up to the first 3 prefixes from s (split by _).
// For example, tesseract_foo_bar will be split into tesseract,foo and bar.
void VariablesEditor::GetPrefixes(const char* s, std::string* level_one,
std::string* level_two,
std::string* level_three) {
char* p = new char[1024];
GetFirstWords(s, 1, p);
level_one->assign(p);
GetFirstWords(s, 2, p);
level_two->assign(p);
GetFirstWords(s, 3, p);
level_three->assign(p);
delete[] p;
}
// Compare two VC objects by their name.
bool VariableContent::Compare(VariableContent* one, VariableContent* two) {
return (strcmp(one->GetName(), two->GetName()) < 0);
}
// Find all editable variables used within tesseract and create a
// SVMenuNode tree from it.
// TODO (wanke): This is actually sort of hackish.
SVMenuNode* VariablesEditor::BuildListOfAllLeaves() { // find all variables.
SVMenuNode* mr = new SVMenuNode();
std::list<VariableContent*> vclist;
std::map<std::string, int> amount; //to count the # of entries for a specifc char*.
INT_VARIABLE_C_IT int_it(INT_VARIABLE::get_head());
BOOL_VARIABLE_C_IT bool_it(BOOL_VARIABLE::get_head());
STRING_VARIABLE_C_IT str_it(STRING_VARIABLE::get_head());
double_VARIABLE_C_IT dbl_it(double_VARIABLE::get_head());
// Add all variables to a list.
for (int_it.mark_cycle_pt(); !int_it.cycled_list(); int_it.forward()) {
VariableContent* vc = (new VariableContent(int_it.data()));
vclist.push_back(vc);
}
for (bool_it.mark_cycle_pt(); !bool_it.cycled_list(); bool_it.forward()) {
VariableContent* vc = (new VariableContent(bool_it.data()));
vclist.push_back(vc);
}
for (str_it.mark_cycle_pt(); !str_it.cycled_list(); str_it.forward()) {
VariableContent* vc = (new VariableContent(str_it.data()));
vclist.push_back(vc);
}
for (dbl_it.mark_cycle_pt(); !dbl_it.cycled_list(); dbl_it.forward()) {
VariableContent* vc = (new VariableContent(dbl_it.data()));
vclist.push_back(vc);
}
// Count the # of entries starting with a specific prefix.
for (std::list<VariableContent*>::iterator iterator = vclist.begin();
iterator != vclist.end();
++iterator) {
VariableContent* vc = *iterator;
std::string tag;
std::string tag2;
std::string tag3;
GetPrefixes(vc->GetName(), &tag, &tag2, &tag3);
amount[tag]++;
amount[tag2]++;
amount[tag3]++;
}
vclist.sort(VariableContent::Compare); // Sort the list alphabetically.
SVMenuNode* other = mr->AddChild("OTHER");
// go through the list again and this time create the menu structure.
for (std::list<VariableContent*>::iterator iterator = vclist.begin();
iterator != vclist.end();
++iterator) {
VariableContent* vc = *iterator;
std::string tag;
std::string tag2;
std::string tag3;
GetPrefixes(vc->GetName(), &tag, &tag2, &tag3);
if (amount[tag] == 1) { other->AddChild(vc->GetName(), vc->GetId(),
vc->GetValue(),
vc->GetDescription());
} else { // More than one would use this submenu -> create submenu.
SVMenuNode* sv = mr->AddChild(tag.c_str());
if ((amount[tag] <= MAX_ITEMS_IN_SUBMENU) || (amount[tag2] <= 1)) {
sv->AddChild(vc->GetName(), vc->GetId(),
vc->GetValue(), vc->GetDescription());
} else { // Make subsubmenus.
SVMenuNode* sv2 = sv->AddChild(tag2.c_str());
sv2->AddChild(vc->GetName(), vc->GetId(),
vc->GetValue(), vc->GetDescription());
}
}
}
return mr;
}
// Event listener. Waits for SVET_POPUP events and processes them.
void VariablesEditor::Notify(const SVEvent* sve) {
if (sve->type == SVET_POPUP) { // only catch SVET_POPUP!
char* param = sve->parameter;
if (sve->command_id == writeCommands[0]) {
WriteVars(param, false);
} else if (sve->command_id == writeCommands[1]) {
WriteVars(param, true);
} else {
VariableContent* vc = VariableContent::GetVariableContentById(
sve->command_id);
vc->SetValue(param);
sv_window_->AddMessage("Setting %s to %s",
vc->GetName(), vc->GetValue());
}
}
}
// Integrate the variables editor as popupmenu into the existing scrollview
// window (usually the pg editor). If sv == null, create a new empty
// empty window and attach the variables editor to that window (ugly).
VariablesEditor::VariablesEditor(ScrollView* sv) {
if (sv == NULL) {
const char* name = "VarEditorMAIN";
sv = new ScrollView(name, 1, 1, 200, 200, 300, 200);
}
sv_window_ = sv;
//Only one event handler per window.
//sv->AddEventHandler((SVEventHandler*) this);
SVMenuNode* svMenuRoot = BuildListOfAllLeaves();
STRING varfile;
varfile = datadir;
varfile += VARDIR; // variables dir
varfile += "edited"; // actual name
SVMenuNode* std_menu = svMenuRoot->AddChild ("Build Config File");
writeCommands[0] = nrVariables+1;
std_menu->AddChild("All Variables", writeCommands[0],
varfile.string(), "Config file name?");
writeCommands[1] = nrVariables+2;
std_menu->AddChild ("changed_ Variables Only", writeCommands[1],
varfile.string(), "Config file name?");
svMenuRoot->BuildMenu(sv, false);
}
// Write all (changed_) variables to a config file.
void VariablesEditor::WriteVars(char *filename, // in this file
bool changes_only // changed_ vars only?
) {
FILE *fp; // input file
char msg_str[255];
// if file exists
if ((fp = fopen (filename, "r")) != NULL) {
fclose(fp);
sprintf (msg_str, "Overwrite file " "%s" "? (Y/N)", filename);
int a = sv_window_->ShowYesNoDialog(msg_str);
if (a == 'n') { return; } // dont write
}
fp = fopen (filename, "w"); // can we write to it?
if (fp == NULL) {
sv_window_->AddMessage("Cant write to file " "%s" "", filename);
return;
}
for (std::map<int, VariableContent*>::iterator iter = vcMap.begin();
iter != vcMap.end();
++iter) {
VariableContent* cur = iter->second;
if (!changes_only || cur->HasChanged()) {
fprintf (fp, "%-25s %-12s # %s\n",
cur->GetName(), cur->GetValue(), cur->GetDescription());
}
}
fclose(fp);
}
#endif

123
ccmain/varabled.h Normal file
View File

@ -0,0 +1,123 @@
///////////////////////////////////////////////////////////////////////
// File: varabled.cpp
// Description: Variables Editor
// Author: Joern Wanke
// Created: Wed Jul 18 10:05:01 PDT 2007
//
// (C) Copyright 2007, Google Inc.
// 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.
//
///////////////////////////////////////////////////////////////////////
//
// The variables editor is used to edit all the variables used within
// tesseract from the ui.
#ifndef GRAPHICS_DISABLED
#ifndef VARABLED_H
#define VARABLED_H
#include <string>
#include <map>
#include "scrollview.h"
#include "varable.h"
class SVMenuNode;
// A list of all possible variable types used.
enum VarType {
VT_INTEGER,
VT_BOOLEAN,
VT_STRING,
VT_DOUBLE
};
// A rather hackish helper structure which can take any kind of variable input
// (defined by VarType) and do a couple of common operations on them, like
// comparisond or getting its value. It is used in the context of the
// VariablesEditor as a bridge from the internal tesseract variables to the
// ones displayed by the ScrollView server.
class VariableContent {
public:
// Compare two VC objects by their name.
static bool Compare(VariableContent* one, VariableContent* two);
// Gets a VC object identified by its ID.
static VariableContent* GetVariableContentById(int id);
// Constructors for the various VarTypes.
VariableContent(STRING_VARIABLE* it);
VariableContent(INT_VARIABLE* it);
VariableContent(BOOL_VARIABLE* it);
VariableContent(double_VARIABLE* it);
// Getters and Setters.
void SetValue(const char* val);
const char* GetValue();
const char* GetName();
const char* GetDescription();
int GetId() { return my_id_; }
bool HasChanged() { return changed_; }
private:
// The unique ID of this VC object.
int my_id_;
// Whether the variable was changed_ and thus needs to be rewritten.
bool changed_;
// The actual vartype of this VC object.
VarType var_type_;
STRING_VARIABLE* sIt;
INT_VARIABLE* iIt;
BOOL_VARIABLE* bIt;
double_VARIABLE* dIt;
};
// The variables editor enables the user to edit all the variables used within
// tesseract. It can be invoked on its own, but is supposed to be invoked by
// the program editor.
class VariablesEditor : public SVEventHandler {
public:
// Integrate the variables editor as popupmenu into the existing scrollview
// window (usually the pg editor). If sv == null, create a new empty
// empty window and attach the variables editor to that window (ugly).
VariablesEditor(ScrollView* sv = NULL);
// Event listener. Waits for SVET_POPUP events and processes them.
void Notify(const SVEvent* sve);
private:
// Gets the up to the first 3 prefixes from s (split by _).
// For example, tesseract_foo_bar will be split into tesseract,foo and bar.
void GetPrefixes(const char* s, std::string* level_one,
std::string* level_two, std::string* level_three);
// Gets the first n words (split by _) and puts them in t.
// For example, tesseract_foo_bar with N=2 will yield tesseract_foo_.
void GetFirstWords( //copy first N words
const char *s, //source string
int n, //number of words
char *t //target string
);
// Find all editable variables used within tesseract and create a
// SVMenuNode tree from it.
SVMenuNode *BuildListOfAllLeaves();
// Write all (changed_) variables to a config file.
void WriteVars(char* filename, bool changes_only);
ScrollView* sv_window_;
};
#endif
#endif