textord/underlin.cpp File Reference

#include "mfcpch.h"
#include "underlin.h"

Go to the source code of this file.

Defines

Functions


Define Documentation

#define EXTERN

Definition at line 28 of file underlin.cpp.

#define PROJECTION_MARGIN   10

Arbitrary.

Note:
File: underlin.cpp (Formerly undrline.c)
Code to chop blobs apart from underlines.
Author:
Ray Smith
Date:
Mon Aug 8 11:14:00 BST 1994
 * (C) Copyright 1994, 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 27 of file underlin.cpp.


Function Documentation

void find_underlined_blobs ( BLOBNBOX u_line,
QSPLINE baseline,
float  xheight,
float  baseline_offset,
ICOORDELT_LIST *  chop_cells 
)

Get chop points.

Find the start and end coords of blobs in the underline.

Definition at line 203 of file underlin.cpp.

References ASSERT_HOST, baseline, BOX::left(), NULL, BOX::right(), and vertical_cunderline_projection().

Referenced by restore_underlined_blobs().

00209                             {
00210   INT16 x, y;                    //sides of blob
00211   ICOORD blob_chop;              //sides of blob
00212   BOX blob_box = u_line->bounding_box ();
00213                                  //cell iterator
00214   ICOORDELT_IT cell_it = chop_cells;
00215   STATS upper_proj (blob_box.left (), blob_box.right () + 1);
00216   STATS middle_proj (blob_box.left (), blob_box.right () + 1);
00217   STATS lower_proj (blob_box.left (), blob_box.right () + 1);
00218   C_OUTLINE_IT out_it;           //outlines of blob
00219 
00220   ASSERT_HOST (u_line->cblob () != NULL);
00221 
00222   out_it.set_to_list (u_line->cblob ()->out_list ());
00223   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00224     vertical_cunderline_projection (out_it.data (),
00225       baseline, xheight, baseline_offset,
00226       &lower_proj, &middle_proj, &upper_proj);
00227   }
00228 
00229   for (x = blob_box.left (); x < blob_box.right (); x++) {
00230     if (middle_proj.pile_count (x) > 0) {
00231       for (y = x + 1;
00232         y < blob_box.right () && middle_proj.pile_count (y) > 0; y++);
00233       blob_chop = ICOORD (x, y);
00234       cell_it.add_after_then_move (new ICOORDELT (blob_chop));
00235       x = y;
00236     }
00237   }
00238 }

TO_ROW* most_overlapping_row ( TO_ROW_LIST *  rows,
BLOBNBOX blob 
)

Find best row.

Return the row which most overlaps the blob.

Definition at line 147 of file underlin.cpp.

References TO_ROW::ascrise, TO_ROW::baseline, TO_ROW::descdrop, MAX_INT32, NULL, TO_ROW::xheight, and QSPLINE::y().

00150                               {
00151   INT16 x = (blob->bounding_box ().left ()
00152     + blob->bounding_box ().right ()) / 2;
00153   TO_ROW_IT row_it = rows;       //row iterator
00154   TO_ROW *row;                   //current row
00155   TO_ROW *best_row;              //output row
00156   float overlap;                 //of blob & row
00157   float bestover;                //best overlap
00158 
00159   best_row = NULL;
00160   bestover = (float) -MAX_INT32;
00161   if (row_it.empty ())
00162     return NULL;
00163   row = row_it.data ();
00164   row_it.mark_cycle_pt ();
00165   while (row->baseline.y (x) + row->descdrop > blob->bounding_box ().top ()
00166   && !row_it.cycled_list ()) {
00167     best_row = row;
00168     bestover =
00169       blob->bounding_box ().top () - row->baseline.y (x) + row->descdrop;
00170     row_it.forward ();
00171     row = row_it.data ();
00172   }
00173   while (row->baseline.y (x) + row->xheight + row->ascrise
00174   >= blob->bounding_box ().bottom () && !row_it.cycled_list ()) {
00175     overlap = row->baseline.y (x) + row->xheight + row->ascrise;
00176     if (blob->bounding_box ().top () < overlap)
00177       overlap = blob->bounding_box ().top ();
00178     if (blob->bounding_box ().bottom () >
00179       row->baseline.y (x) + row->descdrop)
00180       overlap -= blob->bounding_box ().bottom ();
00181     else
00182       overlap -= row->baseline.y (x) + row->descdrop;
00183     if (overlap > bestover) {
00184       bestover = overlap;
00185       best_row = row;
00186     }
00187     row_it.forward ();
00188     row = row_it.data ();
00189   }
00190   if (bestover < 0
00191     && row->baseline.y (x) + row->xheight + row->ascrise
00192     - blob->bounding_box ().bottom () > bestover)
00193     best_row = row;
00194   return best_row;
00195 }

void restore_underlined_blobs ( TO_BLOCK block  ) 

Get chop points.

Find underlined blobs and put them back in the row.

Definition at line 42 of file underlin.cpp.

References ASSERT_HOST, TO_ROW::baseline, BOX::bottom(), FALSE, find_underlined_blobs(), TO_ROW::insert_blob(), BOX::left(), most_overlapping_row(), NULL, BOX::right(), split_to_blob(), BOX::top(), and TO_ROW::xheight.

Referenced by cleanup_rows().

00044                                {
00045   INT16 chop_coord;              //chop boundary
00046   BOX blob_box;                  //of underline
00047   BLOBNBOX *u_line;              //underline bit
00048   TO_ROW *row;                   //best row for blob
00049   ICOORDELT_LIST chop_cells;     //blobs to cut out
00050                                  //real underlines
00051   BLOBNBOX_LIST residual_underlines;
00052   OUTLINE_LIST left_outlines;    //in current blob
00053   OUTLINE_LIST right_outlines;   //for next blob
00054   C_OUTLINE_LIST left_coutlines;
00055   C_OUTLINE_LIST right_coutlines;
00056   ICOORDELT_IT cell_it = &chop_cells;
00057                                  //under lines
00058   BLOBNBOX_IT under_it = &block->underlines;
00059   BLOBNBOX_IT ru_it = &residual_underlines;
00060 
00061   if (block->get_rows()->empty())
00062     return;  // Don't crash if there are no rows.
00063   for (under_it.mark_cycle_pt (); !under_it.cycled_list ();
00064   under_it.forward ()) {
00065     u_line = under_it.extract ();
00066     blob_box = u_line->bounding_box ();
00067     row = most_overlapping_row (block->get_rows (), u_line);
00068     find_underlined_blobs (u_line, &row->baseline, row->xheight,
00069       row->xheight * textord_underline_offset,
00070       &chop_cells);
00071     cell_it.set_to_list (&chop_cells);
00072     for (cell_it.mark_cycle_pt (); !cell_it.cycled_list ();
00073     cell_it.forward ()) {
00074       chop_coord = cell_it.data ()->x ();
00075       if (cell_it.data ()->y () - chop_coord > textord_fp_chop_error + 1) {
00076         split_to_blob (u_line, chop_coord,
00077           textord_fp_chop_error + 0.5,
00078           &left_outlines, &left_coutlines,
00079           &right_outlines, &right_coutlines);
00080         if (!left_outlines.empty ())
00081           ru_it.
00082             add_after_then_move (new
00083             BLOBNBOX (new PBLOB (&left_outlines)));
00084         else if (!left_coutlines.empty ())
00085           ru_it.
00086               add_after_then_move (new
00087               BLOBNBOX (new
00088               C_BLOB (&left_coutlines)));
00089                                  //right edge of lbob
00090         chop_coord = cell_it.data ()->y ();
00091         split_to_blob (NULL, chop_coord,
00092           textord_fp_chop_error + 0.5,
00093           &left_outlines, &left_coutlines,
00094           &right_outlines, &right_coutlines);
00095         if (!left_outlines.empty ())
00096           row->insert_blob (new BLOBNBOX (new PBLOB (&left_outlines)));
00097         else if (!left_coutlines.empty ())
00098           row->
00099               insert_blob (new BLOBNBOX (new C_BLOB (&left_coutlines)));
00100         else {
00101           ASSERT_HOST(FALSE);
00102           fprintf (stderr,
00103             "Error:no outlines after chopping from %d to %d from (%d,%d)->(%d,%d)\n",
00104             cell_it.data ()->x (), cell_it.data ()->y (),
00105             blob_box.left (), blob_box.bottom (),
00106             blob_box.right (), blob_box.top ());
00107         }
00108         u_line = NULL;           //no more blobs to add
00109       }
00110       delete cell_it.extract ();
00111     }
00112     if (!right_outlines.empty () || !right_coutlines.empty ()) {
00113       split_to_blob (NULL, blob_box.right (),
00114         textord_fp_chop_error + 0.5,
00115         &left_outlines, &left_coutlines,
00116         &right_outlines, &right_coutlines);
00117       if (!left_outlines.empty ())
00118         ru_it.
00119           add_after_then_move (new BLOBNBOX (new PBLOB (&left_outlines)));
00120       else if (!left_coutlines.empty ())
00121         ru_it.
00122             add_after_then_move (new
00123             BLOBNBOX (new C_BLOB (&left_coutlines)));
00124     }
00125     if (u_line != NULL) {
00126       if (u_line->blob() != NULL)
00127         delete u_line->blob();
00128       if (u_line->cblob() != NULL)
00129         delete u_line->cblob();
00130       delete u_line;
00131     }
00132   }
00133   if (!ru_it.empty ()) {
00134     ru_it.move_to_first ();
00135     for (ru_it.mark_cycle_pt (); !ru_it.cycled_list (); ru_it.forward ()) {
00136       under_it.add_after_then_move (ru_it.extract ());
00137     }
00138   }
00139 }

void vertical_cunderline_projection ( C_OUTLINE outline,
QSPLINE baseline,
float  xheight,
float  baseline_offset,
STATS lower_proj,
STATS middle_proj,
STATS upper_proj 
)

Project outlines.

Compute the vertical projection of a outline from its outlines and add to the given STATS.

Definition at line 247 of file underlin.cpp.

References STATS::add(), baseline, vertical_cunderline_projection(), and ICOORD::y().

Referenced by find_underlined_blobs(), and vertical_cunderline_projection().

00255                            {
00256   ICOORD pos;                    //current point
00257   ICOORD step;                   //edge step
00258   INT16 lower_y, upper_y;        //region limits
00259   INT32 length;                  //of outline
00260   INT16 stepindex;               //current step
00261   C_OUTLINE_IT out_it = outline->child ();
00262 
00263   pos = outline->start_pos ();
00264   length = outline->pathlength ();
00265   for (stepindex = 0; stepindex < length; stepindex++) {
00266     step = outline->step (stepindex);
00267     if (step.x () > 0) {
00268       lower_y =
00269         (INT16) floor (baseline->y (pos.x ()) + baseline_offset + 0.5);
00270       upper_y =
00271         (INT16) floor (baseline->y (pos.x ()) + baseline_offset +
00272         xheight + 0.5);
00273       if (pos.y () >= lower_y) {
00274         lower_proj->add (pos.x (), -lower_y);
00275         if (pos.y () >= upper_y) {
00276           middle_proj->add (pos.x (), lower_y - upper_y);
00277           upper_proj->add (pos.x (), upper_y - pos.y ());
00278         }
00279         else
00280           middle_proj->add (pos.x (), lower_y - pos.y ());
00281       }
00282       else
00283         lower_proj->add (pos.x (), -pos.y ());
00284     }
00285     else if (step.x () < 0) {
00286       lower_y =
00287         (INT16) floor (baseline->y (pos.x () - 1) + baseline_offset +
00288         0.5);
00289       upper_y =
00290         (INT16) floor (baseline->y (pos.x () - 1) + baseline_offset +
00291         xheight + 0.5);
00292       if (pos.y () >= lower_y) {
00293         lower_proj->add (pos.x () - 1, lower_y);
00294         if (pos.y () >= upper_y) {
00295           middle_proj->add (pos.x () - 1, upper_y - lower_y);
00296           upper_proj->add (pos.x () - 1, pos.y () - upper_y);
00297         }
00298         else
00299           middle_proj->add (pos.x () - 1, pos.y () - lower_y);
00300       }
00301       else
00302         lower_proj->add (pos.x () - 1, pos.y ());
00303     }
00304     pos += step;
00305   }
00306 
00307   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00308     vertical_cunderline_projection (out_it.data (),
00309       baseline, xheight, baseline_offset,
00310       lower_proj, middle_proj, upper_proj);
00311   }
00312 }


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