textord/wordseg.cpp File Reference

#include "mfcpch.h"
#include "stderr.h"
#include "blobbox.h"
#include "ocrclass.h"
#include "lmedsq.h"
#include "statistc.h"
#include "drawtord.h"
#include "makerow.h"
#include "pitsync1.h"
#include "blobcmpl.h"
#include "tovars.h"
#include "topitch.h"
#include "tospace.h"
#include "fpchop.h"
#include "wordseg.h"

Go to the source code of this file.

Defines

Functions

Variables


Define Documentation

#define BLOCK_STATS_CLUSTERS   10

Definition at line 52 of file wordseg.cpp.

#define EXTERN

Note:
File: wordseg.cpp (Formerly wspace.c)
Code to segment the blobs into words.
Author:
Ray Smith
Date:
Oct 16 11:32:28 BST 1992
 * (C) Copyright 1992, 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.

Definition at line 42 of file wordseg.cpp.

#define FIXED_WIDTH_MULTIPLE   5

Definition at line 51 of file wordseg.cpp.


Function Documentation

WERD* make_real_word ( BLOBNBOX_IT *  box_it,
INT32  blobcount,
BOOL8  bol,
BOOL8  fuzzy_sp,
BOOL8  fuzzy_non,
UINT8  blanks 
)

Make a WERD.

Parameters:
box_it Iterator
blobcount Number of blobs to use
bol Start of line
fuzzy_sp Fuzzy space
fuzzy_non Fuzzy non-space
blanks Number of blanks
Returns:
werd
Construct a WERD from a given number of adjacent entries in a list of BLOBNBOXs.

Definition at line 566 of file wordseg.cpp.

References NULL, WERD::set_flag(), TRUE, W_BOL, W_EOL, W_FUZZY_NON, and W_FUZZY_SP.

Referenced by find_repeated_chars().

00573                       {
00574   OUTLINE_IT out_it;             //outlines
00575   C_OUTLINE_IT cout_it;
00576   PBLOB_LIST blobs;              //blobs in word
00577   C_BLOB_LIST cblobs;
00578   PBLOB_IT blob_it = &blobs;     //iterator
00579   C_BLOB_IT cblob_it = &cblobs;
00580   WERD *word;                    //new word
00581   BLOBNBOX *bblob;               //current blob
00582   INT32 blobindex;               //in row
00583 
00584   for (blobindex = 0; blobindex < blobcount; blobindex++) {
00585     bblob = box_it->extract ();
00586     if (bblob->joined_to_prev ()) {
00587       if (bblob->blob () != NULL) {
00588         out_it.set_to_list (blob_it.data ()->out_list ());
00589         out_it.move_to_last ();
00590         out_it.add_list_after (bblob->blob ()->out_list ());
00591         delete bblob->blob ();
00592       }
00593       else if (bblob->cblob () != NULL) {
00594         cout_it.set_to_list (cblob_it.data ()->out_list ());
00595         cout_it.move_to_last ();
00596         cout_it.add_list_after (bblob->cblob ()->out_list ());
00597         delete bblob->cblob ();
00598       }
00599     }
00600     else {
00601       if (bblob->blob () != NULL)
00602         blob_it.add_after_then_move (bblob->blob ());
00603       else if (bblob->cblob () != NULL)
00604         cblob_it.add_after_then_move (bblob->cblob ());
00605     }
00606     delete bblob;
00607     box_it->forward ();          //next one
00608   }
00609 
00610   if (blanks < 1)
00611     blanks = 1;
00612   if (!blob_it.empty ()) {
00613                                  //make real word
00614     word = new WERD (&blobs, blanks, NULL);
00615   }
00616   else {
00617     word = new WERD (&cblobs, blanks, NULL);
00618   }
00619   if (bol) {
00620     word->set_flag (W_BOL, TRUE);
00621   }
00622   if (fuzzy_sp)
00623                                  //probably space
00624     word->set_flag (W_FUZZY_SP, TRUE);
00625   else if (fuzzy_non)
00626                                  //probably not
00627     word->set_flag (W_FUZZY_NON, TRUE);
00628   if (box_it->at_first ()) {
00629     word->set_flag (W_EOL, TRUE);//at end of line
00630   }
00631   return word;
00632 }

void make_real_words ( TO_BLOCK block,
FCOORD  rotation 
)

Find lines.

Convert a TO_BLOCK to a BLOCK.

Definition at line 475 of file wordseg.cpp.

References ASSERT_HOST, TO_ROW::blob_list(), FALSE, make_prop_words(), make_rep_words(), NULL, PITCH_CORR_FIXED, PITCH_CORR_PROP, TO_ROW::pitch_decision, PITCH_DEF_FIXED, PITCH_DEF_PROP, TO_ROW::rep_words, and rotation.

Referenced by make_words().

00478                       {
00479   TO_ROW *row;                   //current row
00480   TO_ROW_IT row_it = block->get_rows ();
00481   ROW *real_row = NULL;          //output row
00482   ROW_IT real_row_it = block->block->row_list ();
00483 
00484   if (row_it.empty ())
00485     return;                      //empty block
00486   for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00487     row = row_it.data ();
00488     if (row->blob_list ()->empty () && !row->rep_words.empty ()) {
00489       real_row = make_rep_words (row, block);
00490     }
00491     else if (!row->blob_list ()->empty ()) {
00492       //  tprintf("Row pitch_decision=%d",row->pitch_decision);
00493       if (row->pitch_decision == PITCH_DEF_FIXED
00494         || row->pitch_decision == PITCH_CORR_FIXED)
00495         real_row = fixed_pitch_words (row, rotation);
00496       else if (row->pitch_decision == PITCH_DEF_PROP
00497         || row->pitch_decision == PITCH_CORR_PROP)
00498         real_row = make_prop_words (row, rotation);
00499       else
00500         ASSERT_HOST(FALSE); 
00501     }
00502     if (real_row != NULL) {
00503                                  //put row in block
00504       real_row_it.add_after_then_move (real_row);
00505     }
00506   }
00507   block->block->set_stats (block->fixed_pitch == 0, (INT16) block->kern_size,
00508     (INT16) block->space_size,
00509     (INT16) block->fixed_pitch);
00510   block->block->check_pitch ();
00511 }

ROW* make_rep_words ( TO_ROW row,
TO_BLOCK block 
)

Make a row.

Fabricate a real row from only the repeated blob words. Get the xheight from the block as it may be more meaningful.

Definition at line 520 of file wordseg.cpp.

References BOX::left(), TO_ROW::line_c(), TO_ROW::line_m(), NULL, ROW::recalc_bounding_box(), TO_ROW::rep_words, BOX::right(), ROW::word_list(), and TO_ROW::xheight.

Referenced by make_real_words().

00523                      {
00524   INT32 xstarts[2];              //ends of row
00525   ROW *real_row;                 //output row
00526   BOX word_box;                  //bounding box
00527   double coeffs[3];              //spline
00528                                  //iterator
00529   WERD_IT word_it = &row->rep_words;
00530 
00531   if (word_it.empty ())
00532     return NULL;
00533   word_box = word_it.data ()->bounding_box ();
00534   for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ())
00535     word_box += word_it.data ()->bounding_box ();
00536   xstarts[0] = word_box.left ();
00537   xstarts[1] = word_box.right ();
00538   coeffs[0] = 0;
00539   coeffs[1] = row->line_m ();
00540   coeffs[2] = row->line_c ();
00541   row->xheight = block->xheight;
00542   real_row = new ROW (row,
00543     (INT16) block->kern_size, (INT16) block->space_size);
00544   word_it.set_to_list (real_row->word_list ());
00545                                  //put words in row
00546   word_it.add_list_after (&row->rep_words);
00547   real_row->recalc_bounding_box ();
00548   return real_row;
00549 }

void make_words ( ICOORD  page_tr,
float  gradient,
BLOCK_LIST *  blocks,
TO_BLOCK_LIST *  land_blocks,
TO_BLOCK_LIST *  port_blocks 
)

Make words.

Arrange the blobs into words.

Definition at line 59 of file wordseg.cpp.

References compute_fixed_pitch(), cprintf(), f, global_monitor, make_real_words(), NULL, ETEXT_DESC::ocr_alive, ETEXT_DESC::progress, to_spacing(), and TRUE.

Referenced by textord_page().

00065                  {
00066   TO_BLOCK_IT block_it;          //iterator
00067   TO_BLOCK *block;               //current block;
00068 
00069 #ifdef TEXT_VERBOSE
00070   // gets a 'j', see ccmain/tesseractmain.dox
00071   cprintf("j");
00072 #endif
00073   compute_fixed_pitch (page_tr, port_blocks, gradient, FCOORD (0.0f, -1.0f),
00074     !(BOOL8) textord_test_landscape);
00075   if (global_monitor != NULL) {
00076     global_monitor->ocr_alive = TRUE;
00077     global_monitor->progress = 25;
00078   }
00079   to_spacing(page_tr, port_blocks); 
00080   block_it.set_to_list (port_blocks);
00081   for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
00082   block_it.forward ()) {
00083     block = block_it.data ();
00084     //   set_row_spaces(block,FCOORD(1,0),!(BOOL8)textord_test_landscape);
00085                             //make proper classes
00086     make_real_words (block, FCOORD (1.0f, 0.0f));
00087   }
00088 }

INT32 row_words ( TO_BLOCK block,
TO_ROW row,
INT32  maxwidth,
FCOORD  rotation,
BOOL8  testing_on 
)

Compute space size.

Compute the max nonspace and min space for the row.

Definition at line 148 of file wordseg.cpp.

References STATS::add(), TO_ROW::blob_list(), STATS::clear(), STATS::cluster(), BOX::contains(), FALSE, STATS::get_total(), STATS::ile(), TO_ROW::intercept(), TO_ROW::kern_size, BOX::left(), MAX_INT32, TO_ROW::max_nonspace, TO_ROW::min_space, STATS::print(), BOX::right(), STATS::smooth(), TO_ROW::space_size, TO_ROW::space_threshold, tprintf(), TRUE, BOX::width(), and TO_ROW::xheight.

00154                  {
00155   BOOL8 testing_row;             //contains testpt
00156   BOOL8 prev_valid;              //if decent size
00157   BOOL8 this_valid;              //current blob big enough
00158   INT32 prev_x;                  //end of prev blob
00159   INT32 min_gap;                 //min interesting gap
00160   INT32 cluster_count;           //no of clusters
00161   INT32 gap_index;               //which cluster
00162   INT32 smooth_factor;           //for smoothing stats
00163   BLOBNBOX *blob;                //current blob
00164   float lower, upper;            //clustering parameters
00165   float gaps[3];                 //gap clusers
00166   ICOORD testpt;
00167   BOX blob_box;                  //bounding box
00168                                  //iterator
00169   BLOBNBOX_IT blob_it = row->blob_list ();
00170   STATS gap_stats (0, maxwidth);
00171   STATS cluster_stats[4];        //clusters
00172 
00173   testpt = ICOORD (textord_test_x, textord_test_y);
00174   smooth_factor =
00175     (INT32) (block->xheight * textord_wordstats_smooth_factor + 1.5);
00176   //      if (testing_on)
00177   //    tprintf("Row smooth factor=%d\n",smooth_factor);
00178   prev_valid = FALSE;
00179   prev_x = -MAX_INT32;
00180   testing_row = FALSE;
00181   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
00182     blob = blob_it.data ();
00183     blob_box = blob->bounding_box ();
00184     if (blob_box.contains (testpt))
00185       testing_row = TRUE;
00186     gap_stats.add (blob_box.width (), 1);
00187   }
00188   min_gap = (INT32) floor (gap_stats.ile (textord_words_width_ile));
00189   gap_stats.clear ();
00190   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
00191     blob = blob_it.data ();
00192     if (!blob->joined_to_prev ()) {
00193       blob_box = blob->bounding_box ();
00194       //                      this_valid=blob_box.width()>=min_gap;
00195       this_valid = TRUE;
00196       if (this_valid && prev_valid
00197       && blob_box.left () - prev_x < maxwidth) {
00198         gap_stats.add (blob_box.left () - prev_x, 1);
00199       }
00200       prev_x = blob_box.right ();
00201       prev_valid = this_valid;
00202     }
00203   }
00204   if (gap_stats.get_total () == 0) {
00205     row->min_space = 0;          //no evidence
00206     row->max_nonspace = 0;
00207     return 0;
00208   }
00209   gap_stats.smooth (smooth_factor);
00210   lower = row->xheight * textord_words_initial_lower;
00211   upper = row->xheight * textord_words_initial_upper;
00212   cluster_count = gap_stats.cluster (lower, upper,
00213     textord_spacesize_ratioprop, 3,
00214     cluster_stats);
00215   while (cluster_count < 2 && ceil (lower) < floor (upper)) {
00216                                  //shrink gap
00217     upper = (upper * 3 + lower) / 4;
00218     lower = (lower * 3 + upper) / 4;
00219     cluster_count = gap_stats.cluster (lower, upper,
00220       textord_spacesize_ratioprop, 3,
00221       cluster_stats);
00222   }
00223   if (cluster_count < 2) {
00224     row->min_space = 0;          //no evidence
00225     row->max_nonspace = 0;
00226     return 0;
00227   }
00228   for (gap_index = 0; gap_index < cluster_count; gap_index++)
00229     gaps[gap_index] = cluster_stats[gap_index + 1].ile (0.5);
00230   //get medians
00231   if (cluster_count > 2) {
00232     if (testing_on && textord_show_initial_words) {
00233       tprintf ("Row at %g has 3 sizes of gap:%g,%g,%g\n",
00234         row->intercept (),
00235         cluster_stats[1].ile (0.5),
00236         cluster_stats[2].ile (0.5), cluster_stats[3].ile (0.5));
00237     }
00238     lower = gaps[0];
00239     if (gaps[1] > lower) {
00240       upper = gaps[1];           //prefer most frequent
00241       if (upper < block->xheight * textord_words_min_minspace
00242       && gaps[2] > gaps[1]) {
00243         upper = gaps[2];
00244       }
00245     }
00246     else if (gaps[2] > lower
00247       && gaps[2] >= block->xheight * textord_words_min_minspace)
00248       upper = gaps[2];
00249     else if (lower >= block->xheight * textord_words_min_minspace) {
00250       upper = lower;             //not nice
00251       lower = gaps[1];
00252       if (testing_on && textord_show_initial_words) {
00253         tprintf ("Had to switch most common from lower to upper!!\n");
00254         gap_stats.print (stdout, TRUE);
00255       }
00256     }
00257     else {
00258       row->min_space = 0;        //no evidence
00259       row->max_nonspace = 0;
00260       return 0;
00261     }
00262   }
00263   else {
00264     if (gaps[1] < gaps[0]) {
00265       if (testing_on && textord_show_initial_words) {
00266         tprintf ("Had to switch most common from lower to upper!!\n");
00267         gap_stats.print (stdout, TRUE);
00268       }
00269       lower = gaps[1];
00270       upper = gaps[0];
00271     }
00272     else {
00273       upper = gaps[1];
00274       lower = gaps[0];
00275     }
00276   }
00277   if (upper < block->xheight * textord_words_min_minspace) {
00278     row->min_space = 0;          //no evidence
00279     row->max_nonspace = 0;
00280     return 0;
00281   }
00282   if (upper * 3 < block->min_space * 2 + block->max_nonspace
00283   || lower * 3 > block->min_space * 2 + block->max_nonspace) {
00284     if (testing_on && textord_show_initial_words) {
00285       tprintf ("Disagreement between block and row at %g!!\n",
00286         row->intercept ());
00287       tprintf ("Lower=%g, upper=%g, Stats:\n", lower, upper);
00288       gap_stats.print (stdout, TRUE);
00289     }
00290   }
00291   row->min_space =
00292     (INT32) ceil (upper - (upper - lower) * textord_words_definite_spread);
00293   row->max_nonspace =
00294     (INT32) floor (lower + (upper - lower) * textord_words_definite_spread);
00295   row->space_threshold = (row->max_nonspace + row->min_space) / 2;
00296   row->space_size = upper;
00297   row->kern_size = lower;
00298   if (testing_on && textord_show_initial_words) {
00299     if (testing_row) {
00300       tprintf ("GAP STATS\n");
00301       gap_stats.print (stdout, TRUE);
00302       tprintf ("SPACE stats\n");
00303       cluster_stats[2].print (stdout, FALSE);
00304       tprintf ("NONSPACE stats\n");
00305       cluster_stats[1].print (stdout, FALSE);
00306     }
00307     tprintf ("Row at %g has minspace=%d(%g), max_non=%d(%g)\n",
00308       row->intercept (), row->min_space, upper,
00309       row->max_nonspace, lower);
00310   }
00311   return cluster_stats[2].get_total ();
00312 }

INT32 row_words2 ( TO_BLOCK block,
TO_ROW row,
INT32  maxwidth,
FCOORD  rotation,
BOOL8  testing_on 
)

Compute space size.

Compute the max nonspace and min space for the row.

Definition at line 320 of file wordseg.cpp.

References STATS::add(), TO_ROW::blob_list(), BLOCK_STATS_CLUSTERS, STATS::clear(), STATS::cluster(), FALSE, STATS::get_total(), TO_ROW::intercept(), TO_ROW::kern_size, BOX::left(), MAX_INT16, TO_ROW::max_nonspace, TO_ROW::min_space, STATS::print(), BOX::right(), STATS::smooth(), TO_ROW::space_size, TO_ROW::space_threshold, tprintf(), TRUE, and BOX::width().

00326                   {
00327   BOOL8 testing_row;             //contains testpt
00328   BOOL8 prev_valid;              //if decent size
00329   BOOL8 this_valid;              //current blob big enough
00330   INT32 prev_x;                  //end of prev blob
00331   INT32 min_width;               //min interesting width
00332   INT32 valid_count;             //good gaps
00333   INT32 total_count;             //total gaps
00334   INT32 cluster_count;           //no of clusters
00335   INT32 prev_count;              //previous cluster_count
00336   INT32 gap_index;               //which cluster
00337   INT32 smooth_factor;           //for smoothing stats
00338   BLOBNBOX *blob;                //current blob
00339   float lower, upper;            //clustering parameters
00340   ICOORD testpt;
00341   BOX blob_box;                  //bounding box
00342                                  //iterator
00343   BLOBNBOX_IT blob_it = row->blob_list ();
00344   STATS gap_stats (0, maxwidth);
00345                                  //gap sizes
00346   float gaps[BLOCK_STATS_CLUSTERS];
00347   STATS cluster_stats[BLOCK_STATS_CLUSTERS + 1];
00348   //clusters
00349 
00350   testpt = ICOORD (textord_test_x, textord_test_y);
00351   smooth_factor =
00352     (INT32) (block->xheight * textord_wordstats_smooth_factor + 1.5);
00353   //      if (testing_on)
00354   //              tprintf("Row smooth factor=%d\n",smooth_factor);
00355   prev_valid = FALSE;
00356   prev_x = -MAX_INT16;
00357   testing_row = FALSE;
00358                                  //min blob size
00359   min_width = (INT32) block->pr_space;
00360   total_count = 0;
00361   for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) {
00362     blob = blob_it.data ();
00363     if (!blob->joined_to_prev ()) {
00364       blob_box = blob->bounding_box ();
00365       this_valid = blob_box.width () >= min_width;
00366       this_valid = TRUE;
00367       if (this_valid && prev_valid
00368       && blob_box.left () - prev_x < maxwidth) {
00369         gap_stats.add (blob_box.left () - prev_x, 1);
00370       }
00371       total_count++;             //count possibles
00372       prev_x = blob_box.right ();
00373       prev_valid = this_valid;
00374     }
00375   }
00376   valid_count = gap_stats.get_total ();
00377   if (valid_count < total_count * textord_words_minlarge) {
00378     gap_stats.clear ();
00379     prev_x = -MAX_INT16;
00380     for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
00381     blob_it.forward ()) {
00382       blob = blob_it.data ();
00383       if (!blob->joined_to_prev ()) {
00384         blob_box = blob->bounding_box ();
00385         if (blob_box.left () - prev_x < maxwidth) {
00386           gap_stats.add (blob_box.left () - prev_x, 1);
00387         }
00388         prev_x = blob_box.right ();
00389       }
00390     }
00391   }
00392   if (gap_stats.get_total () == 0) {
00393     row->min_space = 0;          //no evidence
00394     row->max_nonspace = 0;
00395     return 0;
00396   }
00397 
00398   cluster_count = 0;
00399   lower = block->xheight * words_initial_lower;
00400   upper = block->xheight * words_initial_upper;
00401   gap_stats.smooth (smooth_factor);
00402   do {
00403     prev_count = cluster_count;
00404     cluster_count = gap_stats.cluster (lower, upper,
00405       textord_spacesize_ratioprop,
00406       BLOCK_STATS_CLUSTERS, cluster_stats);
00407   }
00408   while (cluster_count > prev_count && cluster_count < BLOCK_STATS_CLUSTERS);
00409   if (cluster_count < 1) {
00410     row->min_space = 0;
00411     row->max_nonspace = 0;
00412     return 0;
00413   }
00414   for (gap_index = 0; gap_index < cluster_count; gap_index++)
00415     gaps[gap_index] = cluster_stats[gap_index + 1].ile (0.5);
00416   //get medians
00417   if (testing_on) {
00418     tprintf ("cluster_count=%d:", cluster_count);
00419     for (gap_index = 0; gap_index < cluster_count; gap_index++)
00420       tprintf (" %g(%d)", gaps[gap_index],
00421         cluster_stats[gap_index + 1].get_total ());
00422     tprintf ("\n");
00423   }
00424 
00425   //Try to find proportional non-space and space for row.
00426   for (gap_index = 0; gap_index < cluster_count
00427     && gaps[gap_index] > block->max_nonspace; gap_index++);
00428   if (gap_index < cluster_count)
00429     lower = gaps[gap_index];     //most frequent below
00430   else {
00431     if (testing_on)
00432       tprintf ("No cluster below block threshold!, using default=%g\n",
00433         block->pr_nonsp);
00434     lower = block->pr_nonsp;
00435   }
00436   for (gap_index = 0; gap_index < cluster_count
00437     && gaps[gap_index] <= block->max_nonspace; gap_index++);
00438   if (gap_index < cluster_count)
00439     upper = gaps[gap_index];     //most frequent above
00440   else {
00441     if (testing_on)
00442       tprintf ("No cluster above block threshold!, using default=%g\n",
00443         block->pr_space);
00444     upper = block->pr_space;
00445   }
00446   row->min_space =
00447     (INT32) ceil (upper - (upper - lower) * textord_words_definite_spread);
00448   row->max_nonspace =
00449     (INT32) floor (lower + (upper - lower) * textord_words_definite_spread);
00450   row->space_threshold = (row->max_nonspace + row->min_space) / 2;
00451   row->space_size = upper;
00452   row->kern_size = lower;
00453   if (testing_on) {
00454     if (testing_row) {
00455       tprintf ("GAP STATS\n");
00456       gap_stats.print (stdout, TRUE);
00457       tprintf ("SPACE stats\n");
00458       cluster_stats[2].print (stdout, FALSE);
00459       tprintf ("NONSPACE stats\n");
00460       cluster_stats[1].print (stdout, FALSE);
00461     }
00462     tprintf ("Row at %g has minspace=%d(%g), max_non=%d(%g)\n",
00463       row->intercept (), row->min_space, upper,
00464       row->max_nonspace, lower);
00465   }
00466   return 1;
00467 }

void set_row_spaces ( TO_BLOCK block,
FCOORD  rotation,
BOOL8  testing_on 
)

Find space sizes.

Set the min_space and max_nonspace members of the row so that the blobs can be arranged into words.

Definition at line 97 of file wordseg.cpp.

References TO_ROW::fixed_pitch, TO_ROW::intercept(), TO_ROW::kern_size, TO_ROW::max_nonspace, TO_ROW::min_space, plot_word_decisions(), TO_ROW::pr_nonsp, TO_ROW::pr_space, TO_ROW::space_size, TO_ROW::space_threshold, to_win, and tprintf().

00101                      {
00102   INT32 maxwidth;                //of widest space
00103   TO_ROW *row;                   //current row
00104   TO_ROW_IT row_it = block->get_rows ();
00105 
00106   if (row_it.empty ())
00107     return;                      //empty block
00108   maxwidth = (INT32) ceil (block->xheight * textord_words_maxspace);
00109   for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
00110     row = row_it.data ();
00111     if (row->fixed_pitch == 0) {
00112       //       if (!textord_test_mode
00113       //       && row_words(block,row,maxwidth,rotation,testing_on)==0
00114       //       || textord_test_mode
00115       //       && row_words2(block,row,maxwidth,rotation,testing_on)==0)
00116       //       {
00117       row->min_space =
00118         (INT32) ceil (row->pr_space -
00119         (row->pr_space -
00120         row->pr_nonsp) * textord_words_definite_spread);
00121       row->max_nonspace =
00122         (INT32) floor (row->pr_nonsp +
00123         (row->pr_space -
00124         row->pr_nonsp) * textord_words_definite_spread);
00125       if (testing_on && textord_show_initial_words) {
00126         tprintf ("Assigning defaults %d non, %d space to row at %g\n",
00127           row->max_nonspace, row->min_space, row->intercept ());
00128       }
00129       row->space_threshold = (row->max_nonspace + row->min_space) / 2;
00130       row->space_size = row->pr_space;
00131       row->kern_size = row->pr_nonsp;
00132       //                      }
00133     }
00134 #ifndef GRAPHICS_DISABLED
00135     if (textord_show_initial_words && testing_on) {
00136       plot_word_decisions (to_win, (INT16) row->fixed_pitch, row);
00137     }
00138 #endif
00139   }
00140 }


Variable Documentation

ETEXT_DESC* global_monitor

progress monitor

Definition at line 98 of file tessedit.cpp.


Generated on Wed Feb 28 19:49:26 2007 for Tesseract by  doxygen 1.5.1