tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/ccstruct/rect.cpp
Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        rect.c  (Formerly box.c)
00003  * Description: Bounding box class definition.
00004  * Author:                                      Phil Cheatle
00005  * Created:                                     Wed Oct 16 15:18:45 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          "rect.h"
00021 
00022 // Include automatically generated configuration file if running autoconf.
00023 #ifdef HAVE_CONFIG_H
00024 #include "config_auto.h"
00025 #endif
00026 
00027 /**********************************************************************
00028  * TBOX::TBOX()  Constructor from 2 ICOORDS
00029  *
00030  **********************************************************************/
00031 
00032 TBOX::TBOX(                   //construtor
00033          const ICOORD pt1,  //one corner
00034          const ICOORD pt2   //the other corner
00035         ) {
00036   if (pt1.x () <= pt2.x ()) {
00037     if (pt1.y () <= pt2.y ()) {
00038       bot_left = pt1;
00039       top_right = pt2;
00040     }
00041     else {
00042       bot_left = ICOORD (pt1.x (), pt2.y ());
00043       top_right = ICOORD (pt2.x (), pt1.y ());
00044     }
00045   }
00046   else {
00047     if (pt1.y () <= pt2.y ()) {
00048       bot_left = ICOORD (pt2.x (), pt1.y ());
00049       top_right = ICOORD (pt1.x (), pt2.y ());
00050     }
00051     else {
00052       bot_left = pt2;
00053       top_right = pt1;
00054     }
00055   }
00056 }
00057 
00058 /**********************************************************************
00059  * TBOX::TBOX()  Constructor from 4 integer values.
00060  *  Note: It is caller's responsibility to provide values in the right
00061  *        order.
00062  **********************************************************************/
00063 
00064 TBOX::TBOX(                    //constructor
00065     inT16 left, inT16 bottom, inT16 right, inT16 top)
00066     : bot_left(left, bottom), top_right(right, top) {
00067 }
00068 
00069 // rotate_large constructs the containing bounding box of all 4
00070 // corners after rotating them. It therefore guarantees that all
00071 // original content is contained within, but also slightly enlarges the box.
00072 void TBOX::rotate_large(const FCOORD& vec) {
00073   ICOORD top_left(bot_left.x(), top_right.y());
00074   ICOORD bottom_right(top_right.x(), bot_left.y());
00075   top_left.rotate(vec);
00076   bottom_right.rotate(vec);
00077   rotate(vec);
00078   TBOX box2(top_left, bottom_right);
00079   *this += box2;
00080 }
00081 
00082 /**********************************************************************
00083  * TBOX::intersection()  Build the largest box contained in both boxes
00084  *
00085  **********************************************************************/
00086 
00087 TBOX TBOX::intersection(  //shared area box
00088                       const TBOX &box) const {
00089   inT16 left;
00090   inT16 bottom;
00091   inT16 right;
00092   inT16 top;
00093   if (overlap (box)) {
00094     if (box.bot_left.x () > bot_left.x ())
00095       left = box.bot_left.x ();
00096     else
00097       left = bot_left.x ();
00098 
00099     if (box.top_right.x () < top_right.x ())
00100       right = box.top_right.x ();
00101     else
00102       right = top_right.x ();
00103 
00104     if (box.bot_left.y () > bot_left.y ())
00105       bottom = box.bot_left.y ();
00106     else
00107       bottom = bot_left.y ();
00108 
00109     if (box.top_right.y () < top_right.y ())
00110       top = box.top_right.y ();
00111     else
00112       top = top_right.y ();
00113   }
00114   else {
00115     left = MAX_INT16;
00116     bottom = MAX_INT16;
00117     top = -MAX_INT16;
00118     right = -MAX_INT16;
00119   }
00120   return TBOX (left, bottom, right, top);
00121 }
00122 
00123 
00124 /**********************************************************************
00125  * TBOX::bounding_union()  Build the smallest box containing both boxes
00126  *
00127  **********************************************************************/
00128 
00129 TBOX TBOX::bounding_union(  //box enclosing both
00130                         const TBOX &box) const {
00131   ICOORD bl;                     //bottom left
00132   ICOORD tr;                     //top right
00133 
00134   if (box.bot_left.x () < bot_left.x ())
00135     bl.set_x (box.bot_left.x ());
00136   else
00137     bl.set_x (bot_left.x ());
00138 
00139   if (box.top_right.x () > top_right.x ())
00140     tr.set_x (box.top_right.x ());
00141   else
00142     tr.set_x (top_right.x ());
00143 
00144   if (box.bot_left.y () < bot_left.y ())
00145     bl.set_y (box.bot_left.y ());
00146   else
00147     bl.set_y (bot_left.y ());
00148 
00149   if (box.top_right.y () > top_right.y ())
00150     tr.set_y (box.top_right.y ());
00151   else
00152     tr.set_y (top_right.y ());
00153   return TBOX (bl, tr);
00154 }
00155 
00156 
00157 /**********************************************************************
00158  * TBOX::plot()  Paint a box using specified settings
00159  *
00160  **********************************************************************/
00161 
00162 #ifndef GRAPHICS_DISABLED
00163 void TBOX::plot(                      //paint box
00164                ScrollView* fd,       //where to paint
00165                ScrollView::Color fill_colour,   //colour for inside
00166                ScrollView::Color border_colour  //colour for border
00167               ) const {
00168   fd->Brush(fill_colour);
00169   fd->Pen(border_colour);
00170   plot(fd);
00171 }
00172 #endif
00173 
00174 // Appends the bounding box as (%d,%d)->(%d,%d) to a STRING.
00175 void TBOX::print_to_str(STRING *str) const {
00176   // "(%d,%d)->(%d,%d)", left(), bottom(), right(), top()
00177   str->add_str_int("(", left());
00178   str->add_str_int(",", bottom());
00179   str->add_str_int(")->(", right());
00180   str->add_str_int(",", top());
00181   *str += ')';
00182 }
00183 
00184 // Writes to the given file. Returns false in case of error.
00185 bool TBOX::Serialize(FILE* fp) const {
00186   if (!bot_left.Serialize(fp)) return false;
00187   if (!top_right.Serialize(fp)) return false;
00188   return true;
00189 }
00190 // Reads from the given file. Returns false in case of error.
00191 // If swap is true, assumes a big/little-endian swap is needed.
00192 bool TBOX::DeSerialize(bool swap, FILE* fp) {
00193   if (!bot_left.DeSerialize(swap, fp)) return false;
00194   if (!top_right.DeSerialize(swap, fp)) return false;
00195   return true;
00196 }
00197 
00198 /**********************************************************************
00199  * operator+=
00200  *
00201  * Extend one box to include the other  (In place union)
00202  **********************************************************************/
00203 
00204 DLLSYM TBOX &
00205 operator+= (                     //bounding bounding bx
00206 TBOX & op1,                       //operands
00207 const TBOX & op2) {
00208   if (op2.bot_left.x () < op1.bot_left.x ())
00209     op1.bot_left.set_x (op2.bot_left.x ());
00210 
00211   if (op2.top_right.x () > op1.top_right.x ())
00212     op1.top_right.set_x (op2.top_right.x ());
00213 
00214   if (op2.bot_left.y () < op1.bot_left.y ())
00215     op1.bot_left.set_y (op2.bot_left.y ());
00216 
00217   if (op2.top_right.y () > op1.top_right.y ())
00218     op1.top_right.set_y (op2.top_right.y ());
00219 
00220   return op1;
00221 }
00222 
00223 
00224 /**********************************************************************
00225  * operator&=
00226  *
00227  * Reduce one box to intersection with the other  (In place intersection)
00228  **********************************************************************/
00229 
00230 TBOX& operator&=(TBOX& op1, const TBOX& op2) {
00231   if (op1.overlap (op2)) {
00232     if (op2.bot_left.x () > op1.bot_left.x ())
00233       op1.bot_left.set_x (op2.bot_left.x ());
00234 
00235     if (op2.top_right.x () < op1.top_right.x ())
00236       op1.top_right.set_x (op2.top_right.x ());
00237 
00238     if (op2.bot_left.y () > op1.bot_left.y ())
00239       op1.bot_left.set_y (op2.bot_left.y ());
00240 
00241     if (op2.top_right.y () < op1.top_right.y ())
00242       op1.top_right.set_y (op2.top_right.y ());
00243   }
00244   else {
00245     op1.bot_left.set_x (MAX_INT16);
00246     op1.bot_left.set_y (MAX_INT16);
00247     op1.top_right.set_x (-MAX_INT16);
00248     op1.top_right.set_y (-MAX_INT16);
00249   }
00250   return op1;
00251 }
00252 
00253 bool TBOX::x_almost_equal(const TBOX &box, int tolerance) const {
00254   return (abs(left() - box.left()) <= tolerance &&
00255            abs(right() - box.right()) <= tolerance);
00256 }
00257 
00258 bool TBOX::almost_equal(const TBOX &box, int tolerance) const {
00259   return (abs(left() - box.left()) <= tolerance &&
00260           abs(right() - box.right()) <= tolerance &&
00261           abs(top() - box.top()) <= tolerance &&
00262           abs(bottom() - box.bottom()) <= tolerance);
00263 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines