tesseract 4.1.1
Loading...
Searching...
No Matches
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 "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
32TBOX::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
64TBOX::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.
72void 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
87TBOX 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
129TBOX 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
163void 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.
175void 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.
185bool 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.
192bool 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
204DLLSYM TBOX &
205operator+= ( //bounding bounding bx
206TBOX & op1, //operands
207const 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
230TBOX& 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
253bool 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
258bool 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}
TBOX & operator&=(TBOX &op1, const TBOX &op2)
Definition: rect.cpp:230
DLLSYM TBOX & operator+=(TBOX &op1, const TBOX &op2)
Definition: rect.cpp:205
#define DLLSYM
Definition: platform.h:21
integer coordinate
Definition: points.h:32
void set_x(int16_t xin)
rewrite function
Definition: points.h:61
int16_t y() const
access_function
Definition: points.h:56
bool Serialize(FILE *fp) const
Definition: points.cpp:61
void set_y(int16_t yin)
rewrite function
Definition: points.h:65
int16_t x() const
access function
Definition: points.h:52
void rotate(const FCOORD &vec)
Definition: points.h:536
bool DeSerialize(bool swap, FILE *fp)
Definition: points.cpp:67
Definition: points.h:189
Definition: rect.h:34
bool x_almost_equal(const TBOX &box, int tolerance) const
Definition: rect.cpp:253
bool almost_equal(const TBOX &box, int tolerance) const
Definition: rect.cpp:258
void plot(ScrollView *fd) const
Definition: rect.h:286
bool Serialize(FILE *fp) const
Definition: rect.cpp:185
void rotate(const FCOORD &vec)
Definition: rect.h:197
void rotate_large(const FCOORD &vec)
Definition: rect.cpp:72
int16_t top() const
Definition: rect.h:58
void print_to_str(STRING *str) const
Definition: rect.cpp:175
bool overlap(const TBOX &box) const
Definition: rect.h:355
int16_t left() const
Definition: rect.h:72
int16_t bottom() const
Definition: rect.h:65
TBOX bounding_union(const TBOX &box) const
Definition: rect.cpp:129
TBOX intersection(const TBOX &box) const
Definition: rect.cpp:87
TBOX()
Definition: rect.h:36
bool DeSerialize(bool swap, FILE *fp)
Definition: rect.cpp:192
int16_t right() const
Definition: rect.h:79
Definition: strngs.h:45
void add_str_int(const char *str, int number)
Definition: strngs.cpp:377
void Pen(Color color)
Definition: scrollview.cpp:719
void Brush(Color color)
Definition: scrollview.cpp:725