Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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 }