|
tesseract 3.04.01
|
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 }