Mercurial > projects > dwt-addons
comparison dwtx/draw2d/geometry/PrecisionRectangle.d @ 98:95307ad235d9
Added Draw2d code, still work in progress
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 03 Aug 2008 00:52:14 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
96:b492ba44e44d | 98:95307ad235d9 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2003, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.draw2d.geometry.PrecisionRectangle; | |
14 | |
15 import dwt.dwthelper.utils; | |
16 import dwtx.draw2d.geometry.Rectangle; | |
17 import dwtx.draw2d.geometry.Insets; | |
18 import dwtx.draw2d.geometry.Point; | |
19 import dwtx.draw2d.geometry.Dimension; | |
20 import dwtx.draw2d.geometry.PrecisionPoint; | |
21 | |
22 /** | |
23 * A Rectangle implementation using floating point values which are truncated into the inherited | |
24 * integer fields. The use of floating point prevents rounding errors from accumulating. | |
25 * @author hudsonr | |
26 * Created on Apr 9, 2003 | |
27 */ | |
28 public final class PrecisionRectangle : Rectangle { | |
29 | |
30 /** Double value for height */ | |
31 public double preciseHeight_; | |
32 | |
33 /** Double value for width */ | |
34 public double preciseWidth_; | |
35 | |
36 /** Double value for X */ | |
37 public double preciseX_; | |
38 | |
39 /** Double value for Y */ | |
40 public double preciseY_; | |
41 | |
42 /** | |
43 * Constructs a new PrecisionRectangle with all values 0. | |
44 */ | |
45 public this() { } | |
46 | |
47 /** | |
48 * Constructs a new PrecisionRectangle from the given integer Rectangle. | |
49 * @param rect the base rectangle | |
50 */ | |
51 public this(Rectangle rect) { | |
52 preciseX_ = rect.preciseX(); | |
53 preciseY_ = rect.preciseY(); | |
54 preciseWidth_ = rect.preciseWidth(); | |
55 preciseHeight_ = rect.preciseHeight(); | |
56 updateInts(); | |
57 } | |
58 | |
59 /** | |
60 * @see dwtx.draw2d.geometry.Rectangle#getCopy() | |
61 */ | |
62 public Rectangle getCopy() { | |
63 return getPreciseCopy(); | |
64 } | |
65 | |
66 /** | |
67 * Returns a precise copy of this. | |
68 * @return a precise copy | |
69 */ | |
70 public PrecisionRectangle getPreciseCopy() { | |
71 PrecisionRectangle result = new PrecisionRectangle(); | |
72 result.preciseX_ = preciseX_; | |
73 result.preciseY_ = preciseY_; | |
74 result.preciseWidth_ = preciseWidth_; | |
75 result.preciseHeight_ = preciseHeight_; | |
76 result.updateInts(); | |
77 return result; | |
78 } | |
79 | |
80 /** | |
81 * @see dwtx.draw2d.geometry.Rectangle#crop(dwtx.draw2d.geometry.Insets) | |
82 */ | |
83 public Rectangle crop(Insets insets) { | |
84 if (insets is null) | |
85 return this; | |
86 setX(preciseX_ + insets.left); | |
87 setY(preciseY_ + insets.top); | |
88 setWidth(preciseWidth_ - (insets.getWidth())); | |
89 setHeight(preciseHeight_ - (insets.getHeight())); | |
90 | |
91 return this; | |
92 } | |
93 | |
94 /** | |
95 * @see Rectangle#equals(Object) | |
96 */ | |
97 public override int opEquals(Object o) { | |
98 if ( auto pr = cast(PrecisionRectangle)o ) { | |
99 return super.opEquals(o) | |
100 && Math.abs(pr.preciseX_ - preciseX_) < 0.000000001 | |
101 && Math.abs(pr.preciseY_ - preciseY_) < 0.000000001 | |
102 && Math.abs(pr.preciseWidth_ - preciseWidth_) < 0.000000001 | |
103 && Math.abs(pr.preciseHeight_ - preciseHeight_) < 0.00000001; | |
104 } | |
105 | |
106 return super.opEquals(o); | |
107 } | |
108 | |
109 /** | |
110 * @see dwtx.draw2d.geometry.Rectangle#performScale(double) | |
111 */ | |
112 public void performScale(double factor) { | |
113 preciseX_ *= factor; | |
114 preciseY_ *= factor; | |
115 preciseWidth_ *= factor; | |
116 preciseHeight_ *= factor; | |
117 updateInts(); | |
118 } | |
119 | |
120 /** | |
121 * @see dwtx.draw2d.geometry.Rectangle#performTranslate(int, int) | |
122 */ | |
123 public void performTranslate(int dx, int dy) { | |
124 preciseX_ += dx; | |
125 preciseY_ += dy; | |
126 x += dx; | |
127 y += dy; | |
128 } | |
129 | |
130 /** | |
131 * Returns the bottom coordinte in double precision. | |
132 * @return the precise bottom | |
133 */ | |
134 public double preciseBottom() { | |
135 return preciseHeight_ + preciseY_; | |
136 } | |
137 | |
138 /** | |
139 * Returns the right side in double precision. | |
140 * @return the precise right | |
141 */ | |
142 public double preciseRight() { | |
143 return preciseWidth_ + preciseX_; | |
144 } | |
145 | |
146 | |
147 /** | |
148 * @see dwtx.draw2d.geometry.Rectangle#resize(dwtx.draw2d.geometry.Dimension) | |
149 */ | |
150 public Rectangle resize(Dimension sizeDelta) { | |
151 preciseWidth_ += sizeDelta.preciseWidth(); | |
152 preciseHeight_ += sizeDelta.preciseHeight(); | |
153 updateInts(); | |
154 return this; | |
155 } | |
156 | |
157 /** | |
158 * Sets the height. | |
159 * @param value the new height | |
160 */ | |
161 public void setHeight(double value) { | |
162 preciseHeight_ = value; | |
163 height = cast(int)Math.floor(preciseHeight_ + 0.000000001); | |
164 } | |
165 | |
166 /** | |
167 * Sets the width. | |
168 * @param value the new width | |
169 */ | |
170 public void setWidth(double value) { | |
171 preciseWidth_ = value; | |
172 width = cast(int)Math.floor(preciseWidth_ + 0.000000001); | |
173 } | |
174 | |
175 /** | |
176 * Sets the x value. | |
177 * @param value the new x value | |
178 */ | |
179 public void setX(double value) { | |
180 preciseX_ = value; | |
181 x = cast(int)Math.floor(preciseX_ + 0.000000001); | |
182 } | |
183 | |
184 /** | |
185 * Sets the y value. | |
186 * @param value the new y value | |
187 */ | |
188 public void setY(double value) { | |
189 preciseY_ = value; | |
190 y = cast(int)Math.floor(preciseY_ + 0.000000001); | |
191 } | |
192 | |
193 /** | |
194 * @see dwtx.draw2d.geometry.Rectangle#translate(dwtx.draw2d.geometry.Point) | |
195 */ | |
196 public Rectangle translate(Point p) { | |
197 preciseX_ += p.preciseX(); | |
198 preciseY_ += p.preciseY(); | |
199 updateInts(); | |
200 return this; | |
201 } | |
202 | |
203 /** | |
204 * Unions the given PrecisionRectangle with this rectangle and returns <code>this</code> | |
205 * for convenience. | |
206 * @since 3.0 | |
207 * @param other the rectangle being unioned | |
208 * @return <code>this</code> for convenience | |
209 * @deprecated | |
210 * Use {@link #union(Rectangle)} instead | |
211 */ | |
212 public PrecisionRectangle union_(PrecisionRectangle other) { | |
213 double newright = Math.max(preciseRight(), other.preciseRight()); | |
214 double newbottom = Math.max(preciseBottom(), other.preciseBottom()); | |
215 preciseX_ = Math.min(preciseX_, other.preciseX_); | |
216 preciseY_ = Math.min(preciseY_, other.preciseY_); | |
217 preciseWidth_ = newright - preciseX_; | |
218 preciseHeight_ = newbottom - preciseY_; | |
219 updateInts(); | |
220 | |
221 return this; | |
222 } | |
223 | |
224 /** | |
225 * @see dwtx.draw2d.geometry.Rectangle#union(dwtx.draw2d.geometry.Rectangle) | |
226 */ | |
227 public Rectangle union_(Rectangle other) { | |
228 double newright = Math.max(preciseRight(), other.preciseX() + other.preciseWidth()); | |
229 double newbottom = Math.max(preciseBottom(), other.preciseY() + other.preciseHeight()); | |
230 preciseX_ = Math.min(preciseX_, other.preciseX()); | |
231 preciseY_ = Math.min(preciseY_, other.preciseY()); | |
232 preciseWidth_ = newright - preciseX_; | |
233 preciseHeight_ = newbottom - preciseY_; | |
234 updateInts(); | |
235 | |
236 return this; | |
237 } | |
238 | |
239 /** | |
240 * Updates the integer values based on the current precise values. The integer values ar | |
241 * the floor of the double values. This is called automatically when calling api which is | |
242 * overridden in this class. | |
243 * @since 3.0 | |
244 */ | |
245 public void updateInts() { | |
246 x = cast(int)Math.floor(preciseX_ + 0.000000001); | |
247 y = cast(int)Math.floor(preciseY_ + 0.000000001); | |
248 width = cast(int)Math.floor(preciseWidth_ + preciseX_ + 0.000000001) - x; | |
249 height = cast(int)Math.floor(preciseHeight_ + preciseY_ + 0.000000001) - y; | |
250 } | |
251 | |
252 /** | |
253 * @see dwtx.draw2d.geometry.Rectangle#union(dwtx.draw2d.geometry.Point) | |
254 */ | |
255 public void union_(Point p) { | |
256 if (p.preciseX() < preciseX_) { | |
257 preciseWidth_ += (preciseX_ - p.preciseX()); | |
258 preciseX_ = p.preciseX(); | |
259 } else { | |
260 double right = preciseX_ + preciseWidth_; | |
261 if (p.preciseX() > right) { | |
262 preciseWidth_ = p.preciseX() - preciseX_; | |
263 } | |
264 } | |
265 if (p.preciseY() < preciseY_) { | |
266 preciseHeight_ += (preciseY - p.preciseY()); | |
267 preciseY_ = p.preciseY(); | |
268 } else { | |
269 double bottom = preciseY_ + preciseHeight_; | |
270 if (p.preciseY() > bottom) { | |
271 preciseHeight_ = p.preciseY() - preciseY_; | |
272 } | |
273 } | |
274 updateInts(); | |
275 } | |
276 | |
277 /** | |
278 * @see dwtx.draw2d.geometry.Rectangle#transpose() | |
279 */ | |
280 public Rectangle transpose() { | |
281 double temp = preciseX_; | |
282 preciseX_ = preciseY_; | |
283 preciseY_ = temp; | |
284 temp = preciseWidth_; | |
285 preciseWidth_ = preciseHeight_; | |
286 preciseHeight_ = temp; | |
287 super.transpose(); | |
288 return this; | |
289 } | |
290 | |
291 /** | |
292 * @see dwtx.draw2d.geometry.Rectangle#setLocation(dwtx.draw2d.geometry.Point) | |
293 */ | |
294 public Rectangle setLocation(Point loc) { | |
295 preciseX_ = loc.preciseX(); | |
296 preciseY_ = loc.preciseY(); | |
297 updateInts(); | |
298 return this; | |
299 } | |
300 | |
301 /** | |
302 * Returns the precise geometric centre of the rectangle | |
303 * | |
304 * @return <code>PrecisionPoint</code> geometric center of the rectangle | |
305 * @since 3.4 | |
306 */ | |
307 public Point getCenter() { | |
308 return new PrecisionPoint(preciseX_ + preciseWidth_ / 2.0, preciseY_ + preciseHeight_ / 2.0); | |
309 } | |
310 | |
311 /** | |
312 * Shrinks the sides of this Rectangle by the horizontal and vertical values | |
313 * provided as input, and returns this Rectangle for convenience. The center of | |
314 * this Rectangle is kept constant. | |
315 * | |
316 * @param h Horizontal reduction amount | |
317 * @param v Vertical reduction amount | |
318 * @return <code>this</code> for convenience | |
319 * @since 3.4 | |
320 */ | |
321 public Rectangle shrink(double h, double v) { | |
322 preciseX_ += h; | |
323 preciseWidth_ -= (h + h); | |
324 preciseY_ += v; | |
325 preciseHeight_ -= (v + v); | |
326 updateInts(); | |
327 return this; | |
328 } | |
329 | |
330 /** | |
331 * Expands the horizontal and vertical sides of this Rectangle with the values | |
332 * provided as input, and returns this for convenience. The location of its | |
333 * center is kept constant. | |
334 * | |
335 * @param h Horizontal increment | |
336 * @param v Vertical increment | |
337 * @return <code>this</code> for convenience | |
338 * @since 3.4 | |
339 */ | |
340 public Rectangle expand(double h, double v) { | |
341 return shrink(-h, -v); | |
342 } | |
343 | |
344 /** | |
345 * @see dwtx.draw2d.geometry.Rectangle#shrink(int, int) | |
346 */ | |
347 public Rectangle shrink(int h, int v) { | |
348 return shrink(cast(double)h, cast(double)v); | |
349 } | |
350 | |
351 /** | |
352 * @see dwtx.draw2d.geometry.Rectangle#contains(dwtx.draw2d.geometry.Point) | |
353 */ | |
354 public bool contains(Point p) { | |
355 return preciseX_ <= p.preciseX() && p.preciseX() <= preciseX_ + preciseWidth_ | |
356 && preciseY_ <= p.preciseY() && p.preciseY() <= preciseY_ + preciseHeight_; | |
357 } | |
358 | |
359 /** | |
360 * @see dwtx.draw2d.geometry.Rectangle#preciseX() | |
361 */ | |
362 public double preciseX() { | |
363 return preciseX_; | |
364 } | |
365 | |
366 /** | |
367 * @see dwtx.draw2d.geometry.Rectangle#preciseY() | |
368 */ | |
369 public double preciseY() { | |
370 return preciseY_; | |
371 } | |
372 | |
373 /** | |
374 * @see dwtx.draw2d.geometry.Rectangle#preciseWidth() | |
375 */ | |
376 public double preciseWidth() { | |
377 return preciseWidth_; | |
378 } | |
379 | |
380 /** | |
381 * @see dwtx.draw2d.geometry.Rectangle#preciseHeight() | |
382 */ | |
383 public double preciseHeight() { | |
384 return preciseHeight_; | |
385 } | |
386 | |
387 /** | |
388 * @see dwtx.draw2d.geometry.Rectangle#setSize(dwtx.draw2d.geometry.Dimension) | |
389 */ | |
390 public Rectangle setSize(Dimension d) { | |
391 preciseWidth_ = d.preciseWidth(); | |
392 preciseHeight_ = d.preciseHeight(); | |
393 return super.setSize(d); | |
394 } | |
395 | |
396 } |