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 /**********************************************************************
24 * TBOX::TBOX() Constructor from 2 ICOORDS
25 *
26 **********************************************************************/
27
TBOX(const ICOORD pt1,const ICOORD pt2)28 TBOX::TBOX( //construtor
29 const ICOORD pt1, //one corner
30 const ICOORD pt2 //the other corner
31 ) {
32 if (pt1.x () <= pt2.x ()) {
33 if (pt1.y () <= pt2.y ()) {
34 bot_left = pt1;
35 top_right = pt2;
36 }
37 else {
38 bot_left = ICOORD (pt1.x (), pt2.y ());
39 top_right = ICOORD (pt2.x (), pt1.y ());
40 }
41 }
42 else {
43 if (pt1.y () <= pt2.y ()) {
44 bot_left = ICOORD (pt2.x (), pt1.y ());
45 top_right = ICOORD (pt1.x (), pt2.y ());
46 }
47 else {
48 bot_left = pt2;
49 top_right = pt1;
50 }
51 }
52 }
53
54 /**********************************************************************
55 * TBOX::TBOX() Constructor from 4 integer values.
56 * Note: It is caller's responsibility to provide values in the right
57 * order.
58 **********************************************************************/
59
TBOX(inT16 left,inT16 bottom,inT16 right,inT16 top)60 TBOX::TBOX( //constructor
61 inT16 left, inT16 bottom, inT16 right, inT16 top)
62 : bot_left(left, bottom), top_right(right, top) {
63 }
64
65 // rotate_large constructs the containing bounding box of all 4
66 // corners after rotating them. It therefore guarantees that all
67 // original content is contained within, but also slightly enlarges the box.
rotate_large(const FCOORD & vec)68 void TBOX::rotate_large(const FCOORD& vec) {
69 ICOORD top_left(bot_left.x(), top_right.y());
70 ICOORD bottom_right(top_right.x(), bot_left.y());
71 top_left.rotate(vec);
72 bottom_right.rotate(vec);
73 rotate(vec);
74 TBOX box2(top_left, bottom_right);
75 *this += box2;
76 }
77
78 /**********************************************************************
79 * TBOX::intersection() Build the largest box contained in both boxes
80 *
81 **********************************************************************/
82
intersection(const TBOX & box) const83 TBOX TBOX::intersection( //shared area box
84 const TBOX &box) const {
85 inT16 left;
86 inT16 bottom;
87 inT16 right;
88 inT16 top;
89 if (overlap (box)) {
90 if (box.bot_left.x () > bot_left.x ())
91 left = box.bot_left.x ();
92 else
93 left = bot_left.x ();
94
95 if (box.top_right.x () < top_right.x ())
96 right = box.top_right.x ();
97 else
98 right = top_right.x ();
99
100 if (box.bot_left.y () > bot_left.y ())
101 bottom = box.bot_left.y ();
102 else
103 bottom = bot_left.y ();
104
105 if (box.top_right.y () < top_right.y ())
106 top = box.top_right.y ();
107 else
108 top = top_right.y ();
109 }
110 else {
111 left = MAX_INT16;
112 bottom = MAX_INT16;
113 top = -MAX_INT16;
114 right = -MAX_INT16;
115 }
116 return TBOX (left, bottom, right, top);
117 }
118
119
120 /**********************************************************************
121 * TBOX::bounding_union() Build the smallest box containing both boxes
122 *
123 **********************************************************************/
124
bounding_union(const TBOX & box) const125 TBOX TBOX::bounding_union( //box enclosing both
126 const TBOX &box) const {
127 ICOORD bl; //bottom left
128 ICOORD tr; //top right
129
130 if (box.bot_left.x () < bot_left.x ())
131 bl.set_x (box.bot_left.x ());
132 else
133 bl.set_x (bot_left.x ());
134
135 if (box.top_right.x () > top_right.x ())
136 tr.set_x (box.top_right.x ());
137 else
138 tr.set_x (top_right.x ());
139
140 if (box.bot_left.y () < bot_left.y ())
141 bl.set_y (box.bot_left.y ());
142 else
143 bl.set_y (bot_left.y ());
144
145 if (box.top_right.y () > top_right.y ())
146 tr.set_y (box.top_right.y ());
147 else
148 tr.set_y (top_right.y ());
149 return TBOX (bl, tr);
150 }
151
152
153 /**********************************************************************
154 * TBOX::plot() Paint a box using specified settings
155 *
156 **********************************************************************/
157
158 #ifndef GRAPHICS_DISABLED
plot(ScrollView * fd,ScrollView::Color fill_colour,ScrollView::Color border_colour) const159 void TBOX::plot( //paint box
160 ScrollView* fd, //where to paint
161 ScrollView::Color fill_colour, //colour for inside
162 ScrollView::Color border_colour //colour for border
163 ) const {
164 fd->Brush(fill_colour);
165 fd->Pen(border_colour);
166 plot(fd);
167 }
168 #endif
169
170
171 /**********************************************************************
172 * operator+=
173 *
174 * Extend one box to include the other (In place union)
175 **********************************************************************/
176
177 DLLSYM TBOX &
operator +=(TBOX & op1,const TBOX & op2)178 operator+= ( //bounding bounding bx
179 TBOX & op1, //operands
180 const TBOX & op2) {
181 if (op2.bot_left.x () < op1.bot_left.x ())
182 op1.bot_left.set_x (op2.bot_left.x ());
183
184 if (op2.top_right.x () > op1.top_right.x ())
185 op1.top_right.set_x (op2.top_right.x ());
186
187 if (op2.bot_left.y () < op1.bot_left.y ())
188 op1.bot_left.set_y (op2.bot_left.y ());
189
190 if (op2.top_right.y () > op1.top_right.y ())
191 op1.top_right.set_y (op2.top_right.y ());
192
193 return op1;
194 }
195
196
197 /**********************************************************************
198 * operator-=
199 *
200 * Reduce one box to intersection with the other (In place intersection)
201 **********************************************************************/
202
203 DLLSYM TBOX &
operator -=(TBOX & op1,const TBOX & op2)204 operator-= ( //inplace intersection
205 TBOX & op1, //operands
206 const TBOX & op2) {
207 if (op1.overlap (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 else {
221 op1.bot_left.set_x (MAX_INT16);
222 op1.bot_left.set_y (MAX_INT16);
223 op1.top_right.set_x (-MAX_INT16);
224 op1.top_right.set_y (-MAX_INT16);
225 }
226 return op1;
227 }
228
229
230 /**********************************************************************
231 * TBOX::serialise_asc() Convert to ascii file.
232 *
233 **********************************************************************/
234
serialise_asc(FILE * f)235 void TBOX::serialise_asc( //convert to ascii
236 FILE *f //file to use
237 ) {
238 bot_left.serialise_asc (f);
239 top_right.serialise_asc (f);
240 }
241
242
243 /**********************************************************************
244 * TBOX::de_serialise_asc() Convert from ascii file.
245 *
246 **********************************************************************/
247
de_serialise_asc(FILE * f)248 void TBOX::de_serialise_asc( //convert from ascii
249 FILE *f //file to use
250 ) {
251 bot_left.de_serialise_asc (f);
252 top_right.de_serialise_asc (f);
253 }
254