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