tesseract 3.04.01

ccstruct/ocrrow.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        ocrrow.cpp  (Formerly row.c)
00003  * Description: Code for the ROW class.
00004  * Author:                                      Ray Smith
00005  * Created:                                     Tue Oct 08 15:58:04 BST 1991
00006  *
00007  * (C) Copyright 1991, Hewlett-Packard Ltd.
00008  ** Licensed under the Apache License, Version 2.0 (the "License");
00009  ** you may not use this file except in compliance with the License.
00010  ** You may obtain a copy of the License at
00011  ** http://www.apache.org/licenses/LICENSE-2.0
00012  ** Unless required by applicable law or agreed to in writing, software
00013  ** distributed under the License is distributed on an "AS IS" BASIS,
00014  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  ** See the License for the specific language governing permissions and
00016  ** limitations under the License.
00017  *
00018  **********************************************************************/
00019 
00020 #include          "ocrrow.h"
00021 #include          "blobbox.h"
00022 
00023 // Include automatically generated configuration file if running autoconf.
00024 #ifdef HAVE_CONFIG_H
00025 #include "config_auto.h"
00026 #endif
00027 
00028 ELISTIZE (ROW)
00029 /**********************************************************************
00030  * ROW::ROW
00031  *
00032  * Constructor to build a ROW. Only the stats stuff are given here.
00033  * The words are added directly.
00034  **********************************************************************/
00035 ROW::ROW (                       //constructor
00036 inT32 spline_size,               //no of segments
00037 inT32 * xstarts,                 //segment boundaries
00038 double *coeffs,                  //coefficients
00039 float x_height,                  //line height
00040 float ascenders,                 //ascender size
00041 float descenders,                //descender drop
00042 inT16 kern,                      //char gap
00043 inT16 space                      //word gap
00044 )
00045     : baseline(spline_size, xstarts, coeffs),
00046       para_(NULL) {
00047   kerning = kern;                //just store stuff
00048   spacing = space;
00049   xheight = x_height;
00050   ascrise = ascenders;
00051   bodysize = 0.0f;
00052   descdrop = descenders;
00053   has_drop_cap_ = false;
00054   lmargin_ = 0;
00055   rmargin_ = 0;
00056 }
00057 
00058 
00059 /**********************************************************************
00060  * ROW::ROW
00061  *
00062  * Constructor to build a ROW. Only the stats stuff are given here.
00063  * The words are added directly.
00064  **********************************************************************/
00065 
00066 ROW::ROW(                 //constructor
00067          TO_ROW *to_row,  //source row
00068          inT16 kern,      //char gap
00069          inT16 space      //word gap
00070         ) : para_(NULL) {
00071   kerning = kern;                //just store stuff
00072   spacing = space;
00073   xheight = to_row->xheight;
00074   bodysize = to_row->body_size;
00075   ascrise = to_row->ascrise;
00076   descdrop = to_row->descdrop;
00077   baseline = to_row->baseline;
00078   has_drop_cap_ = false;
00079   lmargin_ = 0;
00080   rmargin_ = 0;
00081 }
00082 
00083 // Returns the bounding box including the desired combination of upper and
00084 // lower noise/diacritic elements.
00085 TBOX ROW::restricted_bounding_box(bool upper_dots, bool lower_dots) const {
00086   TBOX box;
00087   // This is a read-only iteration of the words in the row.
00088   WERD_IT it(const_cast<WERD_LIST *>(&words));
00089   for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
00090     box += it.data()->restricted_bounding_box(upper_dots, lower_dots);
00091   }
00092   return box;
00093 }
00094 
00095 /**********************************************************************
00096  * ROW::recalc_bounding_box
00097  *
00098  * Set the bounding box correctly
00099  **********************************************************************/
00100 
00101 void ROW::recalc_bounding_box() {  //recalculate BB
00102   WERD *word;                    //current word
00103   WERD_IT it = &words;           //words of ROW
00104   inT16 left;                    //of word
00105   inT16 prev_left;               //old left
00106 
00107   if (!it.empty ()) {
00108     word = it.data ();
00109     prev_left = word->bounding_box ().left ();
00110     it.forward ();
00111     while (!it.at_first ()) {
00112       word = it.data ();
00113       left = word->bounding_box ().left ();
00114       if (left < prev_left) {
00115         it.move_to_first ();
00116                                  //words in BB order
00117         it.sort (word_comparator);
00118         break;
00119       }
00120       prev_left = left;
00121       it.forward ();
00122     }
00123   }
00124   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00125     word = it.data ();
00126     if (it.at_first ())
00127       word->set_flag (W_BOL, TRUE);
00128     else
00129                                  //not start of line
00130       word->set_flag (W_BOL, FALSE);
00131     if (it.at_last ())
00132       word->set_flag (W_EOL, TRUE);
00133     else
00134                                  //not end of line
00135       word->set_flag (W_EOL, FALSE);
00136                                  //extend BB as reqd
00137     bound_box += word->bounding_box ();
00138   }
00139 }
00140 
00141 
00142 /**********************************************************************
00143  * ROW::move
00144  *
00145  * Reposition row by vector
00146  **********************************************************************/
00147 
00148 void ROW::move(                  // reposition row
00149                const ICOORD vec  // by vector
00150               ) {
00151   WERD_IT it(&words);  // word iterator
00152 
00153   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00154     it.data ()->move (vec);
00155 
00156   bound_box.move (vec);
00157   baseline.move (vec);
00158 }
00159 
00160 
00161 /**********************************************************************
00162  * ROW::print
00163  *
00164  * Display members
00165  **********************************************************************/
00166 
00167 void ROW::print(          //print
00168                 FILE *fp  //file to print on
00169                ) {
00170   tprintf("Kerning= %d\n", kerning);
00171   tprintf("Spacing= %d\n", spacing);
00172   bound_box.print();
00173   tprintf("Xheight= %f\n", xheight);
00174   tprintf("Ascrise= %f\n", ascrise);
00175   tprintf("Descdrop= %f\n", descdrop);
00176   tprintf("has_drop_cap= %d\n", has_drop_cap_);
00177   tprintf("lmargin= %d, rmargin= %d\n", lmargin_, rmargin_);
00178 }
00179 
00180 
00181 /**********************************************************************
00182  * ROW::plot
00183  *
00184  * Draw the ROW in the given colour.
00185  **********************************************************************/
00186 
00187 #ifndef GRAPHICS_DISABLED
00188 void ROW::plot(                //draw it
00189                ScrollView* window,  //window to draw in
00190                ScrollView::Color colour   //colour to draw in
00191               ) {
00192   WERD *word;                    //current word
00193   WERD_IT it = &words;           //words of ROW
00194 
00195   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00196     word = it.data ();
00197     word->plot (window, colour); //all in one colour
00198   }
00199 }
00200 
00201 /**********************************************************************
00202  * ROW::plot
00203  *
00204  * Draw the ROW in rainbow colours.
00205  **********************************************************************/
00206 
00207 void ROW::plot(               //draw it
00208                ScrollView* window  //window to draw in
00209               ) {
00210   WERD *word;                    //current word
00211   WERD_IT it = &words;           //words of ROW
00212 
00213   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00214     word = it.data ();
00215     word->plot (window);         //in rainbow colours
00216   }
00217 }
00218 #endif  // GRAPHICS_DISABLED
00219 
00220 /**********************************************************************
00221  * ROW::operator=
00222  *
00223  * Assign rows by duplicating the row structure but NOT the WERDLIST
00224  **********************************************************************/
00225 
00226 ROW & ROW::operator= (const ROW & source) {
00227   this->ELIST_LINK::operator= (source);
00228   kerning = source.kerning;
00229   spacing = source.spacing;
00230   xheight = source.xheight;
00231   bodysize = source.bodysize;
00232   ascrise = source.ascrise;
00233   descdrop = source.descdrop;
00234   if (!words.empty ())
00235     words.clear ();
00236   baseline = source.baseline;    //QSPLINES must do =
00237   bound_box = source.bound_box;
00238   has_drop_cap_ = source.has_drop_cap_;
00239   lmargin_ = source.lmargin_;
00240   rmargin_ = source.rmargin_;
00241   para_ = source.para_;
00242   return *this;
00243 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines