Tesseract  3.02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rect.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * File: rect.c (Formerly box.c)
3  * Description: Bounding box class definition.
4  * Author: Phil Cheatle
5  * Created: Wed Oct 16 15:18:45 BST 1991
6  *
7  * (C) Copyright 1991, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #include "mfcpch.h" // precompiled headers
21 #include "rect.h"
22 
23 // Include automatically generated configuration file if running autoconf.
24 #ifdef HAVE_CONFIG_H
25 #include "config_auto.h"
26 #endif
27 
28 /**********************************************************************
29  * TBOX::TBOX() Constructor from 2 ICOORDS
30  *
31  **********************************************************************/
32 
33 TBOX::TBOX( //construtor
34  const ICOORD pt1, //one corner
35  const ICOORD pt2 //the other corner
36  ) {
37  if (pt1.x () <= pt2.x ()) {
38  if (pt1.y () <= pt2.y ()) {
39  bot_left = pt1;
40  top_right = pt2;
41  }
42  else {
43  bot_left = ICOORD (pt1.x (), pt2.y ());
44  top_right = ICOORD (pt2.x (), pt1.y ());
45  }
46  }
47  else {
48  if (pt1.y () <= pt2.y ()) {
49  bot_left = ICOORD (pt2.x (), pt1.y ());
50  top_right = ICOORD (pt1.x (), pt2.y ());
51  }
52  else {
53  bot_left = pt2;
54  top_right = pt1;
55  }
56  }
57 }
58 
59 /**********************************************************************
60  * TBOX::TBOX() Constructor from 4 integer values.
61  * Note: It is caller's responsibility to provide values in the right
62  * order.
63  **********************************************************************/
64 
65 TBOX::TBOX( //constructor
66  inT16 left, inT16 bottom, inT16 right, inT16 top)
67  : bot_left(left, bottom), top_right(right, top) {
68 }
69 
70 // rotate_large constructs the containing bounding box of all 4
71 // corners after rotating them. It therefore guarantees that all
72 // original content is contained within, but also slightly enlarges the box.
73 void TBOX::rotate_large(const FCOORD& vec) {
74  ICOORD top_left(bot_left.x(), top_right.y());
75  ICOORD bottom_right(top_right.x(), bot_left.y());
76  top_left.rotate(vec);
77  bottom_right.rotate(vec);
78  rotate(vec);
79  TBOX box2(top_left, bottom_right);
80  *this += box2;
81 }
82 
83 /**********************************************************************
84  * TBOX::intersection() Build the largest box contained in both boxes
85  *
86  **********************************************************************/
87 
88 TBOX TBOX::intersection( //shared area box
89  const TBOX &box) const {
90  inT16 left;
91  inT16 bottom;
92  inT16 right;
93  inT16 top;
94  if (overlap (box)) {
95  if (box.bot_left.x () > bot_left.x ())
96  left = box.bot_left.x ();
97  else
98  left = bot_left.x ();
99 
100  if (box.top_right.x () < top_right.x ())
101  right = box.top_right.x ();
102  else
103  right = top_right.x ();
104 
105  if (box.bot_left.y () > bot_left.y ())
106  bottom = box.bot_left.y ();
107  else
108  bottom = bot_left.y ();
109 
110  if (box.top_right.y () < top_right.y ())
111  top = box.top_right.y ();
112  else
113  top = top_right.y ();
114  }
115  else {
116  left = MAX_INT16;
117  bottom = MAX_INT16;
118  top = -MAX_INT16;
119  right = -MAX_INT16;
120  }
121  return TBOX (left, bottom, right, top);
122 }
123 
124 
125 /**********************************************************************
126  * TBOX::bounding_union() Build the smallest box containing both boxes
127  *
128  **********************************************************************/
129 
130 TBOX TBOX::bounding_union( //box enclosing both
131  const TBOX &box) const {
132  ICOORD bl; //bottom left
133  ICOORD tr; //top right
134 
135  if (box.bot_left.x () < bot_left.x ())
136  bl.set_x (box.bot_left.x ());
137  else
138  bl.set_x (bot_left.x ());
139 
140  if (box.top_right.x () > top_right.x ())
141  tr.set_x (box.top_right.x ());
142  else
143  tr.set_x (top_right.x ());
144 
145  if (box.bot_left.y () < bot_left.y ())
146  bl.set_y (box.bot_left.y ());
147  else
148  bl.set_y (bot_left.y ());
149 
150  if (box.top_right.y () > top_right.y ())
151  tr.set_y (box.top_right.y ());
152  else
153  tr.set_y (top_right.y ());
154  return TBOX (bl, tr);
155 }
156 
157 
158 /**********************************************************************
159  * TBOX::plot() Paint a box using specified settings
160  *
161  **********************************************************************/
162 
163 #ifndef GRAPHICS_DISABLED
164 void TBOX::plot( //paint box
165  ScrollView* fd, //where to paint
166  ScrollView::Color fill_colour, //colour for inside
167  ScrollView::Color border_colour //colour for border
168  ) const {
169  fd->Brush(fill_colour);
170  fd->Pen(border_colour);
171  plot(fd);
172 }
173 #endif
174 
175 // Writes to the given file. Returns false in case of error.
176 bool TBOX::Serialize(FILE* fp) const {
177  if (!bot_left.Serialize(fp)) return false;
178  if (!top_right.Serialize(fp)) return false;
179  return true;
180 }
181 // Reads from the given file. Returns false in case of error.
182 // If swap is true, assumes a big/little-endian swap is needed.
183 bool TBOX::DeSerialize(bool swap, FILE* fp) {
184  if (!bot_left.DeSerialize(swap, fp)) return false;
185  if (!top_right.DeSerialize(swap, fp)) return false;
186  return true;
187 }
188 
189 /**********************************************************************
190  * operator+=
191  *
192  * Extend one box to include the other (In place union)
193  **********************************************************************/
194 
195 DLLSYM TBOX &
196 operator+= ( //bounding bounding bx
197 TBOX & op1, //operands
198 const TBOX & op2) {
199  if (op2.bot_left.x () < op1.bot_left.x ())
200  op1.bot_left.set_x (op2.bot_left.x ());
201 
202  if (op2.top_right.x () > op1.top_right.x ())
203  op1.top_right.set_x (op2.top_right.x ());
204 
205  if (op2.bot_left.y () < op1.bot_left.y ())
206  op1.bot_left.set_y (op2.bot_left.y ());
207 
208  if (op2.top_right.y () > op1.top_right.y ())
209  op1.top_right.set_y (op2.top_right.y ());
210 
211  return op1;
212 }
213 
214 
215 /**********************************************************************
216  * operator&=
217  *
218  * Reduce one box to intersection with the other (In place intersection)
219  **********************************************************************/
220 
221 TBOX& operator&=(TBOX& op1, const TBOX& op2) {
222  if (op1.overlap (op2)) {
223  if (op2.bot_left.x () > op1.bot_left.x ())
224  op1.bot_left.set_x (op2.bot_left.x ());
225 
226  if (op2.top_right.x () < op1.top_right.x ())
227  op1.top_right.set_x (op2.top_right.x ());
228 
229  if (op2.bot_left.y () > op1.bot_left.y ())
230  op1.bot_left.set_y (op2.bot_left.y ());
231 
232  if (op2.top_right.y () < op1.top_right.y ())
233  op1.top_right.set_y (op2.top_right.y ());
234  }
235  else {
236  op1.bot_left.set_x (MAX_INT16);
237  op1.bot_left.set_y (MAX_INT16);
238  op1.top_right.set_x (-MAX_INT16);
239  op1.top_right.set_y (-MAX_INT16);
240  }
241  return op1;
242 }
243 
244 bool TBOX::x_almost_equal(const TBOX &box, int tolerance) const {
245  return (abs(left() - box.left()) <= tolerance &&
246  abs(right() - box.right()) <= tolerance);
247 }
248 
249 bool TBOX::almost_equal(const TBOX &box, int tolerance) const {
250  return (abs(left() - box.left()) <= tolerance &&
251  abs(right() - box.right()) <= tolerance &&
252  abs(top() - box.top()) <= tolerance &&
253  abs(bottom() - box.bottom()) <= tolerance);
254 }