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