Tesseract  3.02
tesseract-ocr/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 "mfcpch.h"
00021 #include          "ocrrow.h"
00022 #include          "blobbox.h"
00023 
00024 // Include automatically generated configuration file if running autoconf.
00025 #ifdef HAVE_CONFIG_H
00026 #include "config_auto.h"
00027 #endif
00028 
00029 ELISTIZE (ROW)
00030 /**********************************************************************
00031  * ROW::ROW
00032  *
00033  * Constructor to build a ROW. Only the stats stuff are given here.
00034  * The words are added directly.
00035  **********************************************************************/
00036 ROW::ROW (                       //constructor
00037 inT32 spline_size,               //no of segments
00038 inT32 * xstarts,                 //segment boundaries
00039 double *coeffs,                  //coefficients
00040 float x_height,                  //line height
00041 float ascenders,                 //ascender size
00042 float descenders,                //descender drop
00043 inT16 kern,                      //char gap
00044 inT16 space                      //word gap
00045 )
00046     : baseline(spline_size, xstarts, coeffs),
00047       para_(NULL) {
00048   kerning = kern;                //just store stuff
00049   spacing = space;
00050   xheight = x_height;
00051   ascrise = ascenders;
00052   bodysize = 0.0f;
00053   descdrop = descenders;
00054   has_drop_cap_ = false;
00055   lmargin_ = 0;
00056   rmargin_ = 0;
00057 }
00058 
00059 
00060 /**********************************************************************
00061  * ROW::ROW
00062  *
00063  * Constructor to build a ROW. Only the stats stuff are given here.
00064  * The words are added directly.
00065  **********************************************************************/
00066 
00067 ROW::ROW(                 //constructor
00068          TO_ROW *to_row,  //source row
00069          inT16 kern,      //char gap
00070          inT16 space      //word gap
00071         ) : para_(NULL) {
00072   kerning = kern;                //just store stuff
00073   spacing = space;
00074   xheight = to_row->xheight;
00075   bodysize = to_row->body_size;
00076   ascrise = to_row->ascrise;
00077   descdrop = to_row->descdrop;
00078   baseline = to_row->baseline;
00079   has_drop_cap_ = false;
00080   lmargin_ = 0;
00081   rmargin_ = 0;
00082 }
00083 
00084 
00085 /**********************************************************************
00086  * ROW::recalc_bounding_box
00087  *
00088  * Set the bounding box correctly
00089  **********************************************************************/
00090 
00091 void ROW::recalc_bounding_box() {  //recalculate BB
00092   WERD *word;                    //current word
00093   WERD_IT it = &words;           //words of ROW
00094   inT16 left;                    //of word
00095   inT16 prev_left;               //old left
00096 
00097   if (!it.empty ()) {
00098     word = it.data ();
00099     prev_left = word->bounding_box ().left ();
00100     it.forward ();
00101     while (!it.at_first ()) {
00102       word = it.data ();
00103       left = word->bounding_box ().left ();
00104       if (left < prev_left) {
00105         it.move_to_first ();
00106                                  //words in BB order
00107         it.sort (word_comparator);
00108         break;
00109       }
00110       prev_left = left;
00111       it.forward ();
00112     }
00113   }
00114   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00115     word = it.data ();
00116     if (it.at_first ())
00117       word->set_flag (W_BOL, TRUE);
00118     else
00119                                  //not start of line
00120       word->set_flag (W_BOL, FALSE);
00121     if (it.at_last ())
00122       word->set_flag (W_EOL, TRUE);
00123     else
00124                                  //not end of line
00125       word->set_flag (W_EOL, FALSE);
00126                                  //extend BB as reqd
00127     bound_box += word->bounding_box ();
00128   }
00129 }
00130 
00131 
00132 /**********************************************************************
00133  * ROW::move
00134  *
00135  * Reposition row by vector
00136  **********************************************************************/
00137 
00138 void ROW::move(                  // reposition row
00139                const ICOORD vec  // by vector
00140               ) {
00141   WERD_IT it(&words);  // word iterator
00142 
00143   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00144     it.data ()->move (vec);
00145 
00146   bound_box.move (vec);
00147   baseline.move (vec);
00148 }
00149 
00150 
00151 /**********************************************************************
00152  * ROW::print
00153  *
00154  * Display members
00155  **********************************************************************/
00156 
00157 void ROW::print(          //print
00158                 FILE *fp  //file to print on
00159                ) {
00160   tprintf("Kerning= %d\n", kerning);
00161   tprintf("Spacing= %d\n", spacing);
00162   bound_box.print();
00163   tprintf("Xheight= %f\n", xheight);
00164   tprintf("Ascrise= %f\n", ascrise);
00165   tprintf("Descdrop= %f\n", descdrop);
00166   tprintf("has_drop_cap= %d\n", has_drop_cap_);
00167   tprintf("lmargin= %d, rmargin= %d\n", lmargin_, rmargin_);
00168 }
00169 
00170 
00171 /**********************************************************************
00172  * ROW::plot
00173  *
00174  * Draw the ROW in the given colour.
00175  **********************************************************************/
00176 
00177 #ifndef GRAPHICS_DISABLED
00178 void ROW::plot(                //draw it
00179                ScrollView* window,  //window to draw in
00180                ScrollView::Color colour   //colour to draw in
00181               ) {
00182   WERD *word;                    //current word
00183   WERD_IT it = &words;           //words of ROW
00184 
00185   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00186     word = it.data ();
00187     word->plot (window, colour); //all in one colour
00188   }
00189 }
00190 #endif
00191 
00192 /**********************************************************************
00193  * ROW::plot
00194  *
00195  * Draw the ROW in rainbow colours.
00196  **********************************************************************/
00197 
00198 #ifndef GRAPHICS_DISABLED
00199 void ROW::plot(               //draw it
00200                ScrollView* window  //window to draw in
00201               ) {
00202   WERD *word;                    //current word
00203   WERD_IT it = &words;           //words of ROW
00204 
00205   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00206     word = it.data ();
00207     word->plot (window);         //in rainbow colours
00208   }
00209 }
00210 #endif
00211 
00212 /**********************************************************************
00213  * ROW::operator=
00214  *
00215  * Assign rows by duplicating the row structure but NOT the WERDLIST
00216  **********************************************************************/
00217 
00218 ROW & ROW::operator= (const ROW & source) {
00219   this->ELIST_LINK::operator= (source);
00220   kerning = source.kerning;
00221   spacing = source.spacing;
00222   xheight = source.xheight;
00223   bodysize = source.bodysize;
00224   ascrise = source.ascrise;
00225   descdrop = source.descdrop;
00226   if (!words.empty ())
00227     words.clear ();
00228   baseline = source.baseline;    //QSPLINES must do =
00229   bound_box = source.bound_box;
00230   has_drop_cap_ = source.has_drop_cap_;
00231   lmargin_ = source.lmargin_;
00232   rmargin_ = source.rmargin_;
00233   para_ = source.para_;
00234   return *this;
00235 }