Project

General

Profile

Download (25.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2003, 2010 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
 *******************************************************************************/
11
package org.eclipse.draw2d.geometry;
12

    
13
/**
14
 * A Rectangle implementation using floating point values which are truncated
15
 * into the inherited integer fields. The use of floating point prevents
16
 * rounding errors from accumulating.
17
 * 
18
 * @author hudsonr Created on Apr 9, 2003
19
 */
20
public final class PrecisionRectangle extends Rectangle {
21

    
22
	/**
23
	 * Double value for height
24
	 * 
25
	 * @noreference
26
	 * @deprecated Use {@link #setPreciseHeight(double)} and
27
	 *             {@link #preciseHeight()} instead. This field will become
28
	 *             private in the future.
29
	 */
30
	public double preciseHeight;
31

    
32
	/**
33
	 * Double value for width
34
	 * 
35
	 * @noreference
36
	 * @deprecated Use {@link #setPreciseWidth(double)} and
37
	 *             {@link #preciseWidth()} instead. This field will become
38
	 *             private in the future.
39
	 */
40
	public double preciseWidth;
41

    
42
	/**
43
	 * Double value for X
44
	 * 
45
	 * @noreference
46
	 * @deprecated Use {@link #setPreciseX(double)} and {@link #preciseX()}
47
	 *             instead. This field will become private in the future.
48
	 */
49
	public double preciseX;
50

    
51
	/**
52
	 * Double value for Y
53
	 * 
54
	 * @noreference
55
	 * @deprecated Use {@link #setPreciseX(double)} and {@link #preciseY()}
56
	 *             instead. This field will become private in the future.
57
	 */
58
	public double preciseY;
59

    
60
	/**
61
	 * Constructs a new PrecisionRectangle with all values 0.
62
	 */
63
	public PrecisionRectangle() {
64
	}
65

    
66
	/**
67
	 * Constructs a PrecisionRectangle with the provided values.
68
	 * 
69
	 * @param x
70
	 *            X location
71
	 * @param y
72
	 *            Y location
73
	 * @param width
74
	 *            Width of the rectangle
75
	 * @param height
76
	 *            Height of the rectangle
77
	 * @since 3.7
78
	 */
79
	public PrecisionRectangle(double x, double y, double width, double height) {
80
		setPreciseLocation(x, y);
81
		setPreciseSize(width, height);
82
	}
83

    
84
	/**
85
	 * 
86
	 * Constructs a new PrecisionRectangle from a given Point and a Dimension
87
	 * 
88
	 * @param p
89
	 *            The Point to specify x and y location of the
90
	 *            PrecisionRectangle
91
	 * @param d
92
	 *            The Dimension to use for width and height of the
93
	 *            PrecisionRectangle
94
	 * @since 3.7
95
	 */
96
	public PrecisionRectangle(Point p, Dimension d) {
97
		this(p.preciseX(), p.preciseY(), d.preciseWidth(), d.preciseHeight());
98
	}
99

    
100
	/**
101
	 * Constructs a new PrecisionRectangle from the given integer Rectangle.
102
	 * 
103
	 * @param rect
104
	 *            the base rectangle
105
	 */
106
	public PrecisionRectangle(Rectangle rect) {
107
		this(rect.preciseX(), rect.preciseY(), rect.preciseWidth(), rect
108
				.preciseHeight());
109
	}
110

    
111
	/**
112
	 * @see org.eclipse.draw2d.geometry.Rectangle#contains(int, int)
113
	 */
114
	public boolean contains(int x, int y) {
115
		return containsPrecise(x, y);
116
	}
117

    
118
	/**
119
	 * @see org.eclipse.draw2d.geometry.Rectangle#contains(org.eclipse.draw2d.geometry.Point)
120
	 */
121
	public boolean contains(Point p) {
122
		return containsPrecise(p.preciseX(), p.preciseY());
123
	}
124

    
125
	/**
126
	 * @see org.eclipse.draw2d.geometry.Rectangle#contains(org.eclipse.draw2d.geometry.Rectangle)
127
	 */
128
	public boolean contains(Rectangle rect) {
129
		return preciseX() <= rect.preciseX() && preciseY() <= rect.preciseY()
130
				&& right() >= rect.right() && bottom() >= rect.bottom();
131
	}
132

    
133
	/**
134
	 * Returns whether the given coordinates are within the boundaries of this
135
	 * Rectangle. The boundaries are inclusive of the top and left edges, but
136
	 * exclusive of the bottom and right edges.
137
	 * 
138
	 * @param x
139
	 *            X value
140
	 * @param y
141
	 *            Y value
142
	 * @return true if the coordinates are within this Rectangle
143
	 * @since 3.7
144
	 */
145
	private boolean containsPrecise(double x, double y) {
146
		return y >= preciseY() && y < preciseY() + preciseHeight()
147
				&& x >= preciseX() && x < preciseX() + preciseWidth();
148
	}
149

    
150
	/**
151
	 * @see Rectangle#equals(Object)
152
	 */
153
	public boolean equals(Object o) {
154
		if (o instanceof PrecisionRectangle) {
155
			PrecisionRectangle rect = (PrecisionRectangle) o;
156
			return super.equals(o)
157
					&& Math.abs(rect.preciseX() - preciseX()) < 0.000000001
158
					&& Math.abs(rect.preciseY() - preciseY()) < 0.000000001
159
					&& Math.abs(rect.preciseWidth() - preciseWidth()) < 0.000000001
160
					&& Math.abs(rect.preciseHeight() - preciseHeight()) < 0.00000001;
161
		}
162

    
163
		return super.equals(o);
164
	}
165

    
166
	/**
167
	 * Expands the horizontal and vertical sides of this Rectangle with the
168
	 * values provided as input, and returns this for convenience. The location
169
	 * of its center is kept constant.
170
	 * 
171
	 * @param h
172
	 *            Horizontal increment
173
	 * @param v
174
	 *            Vertical increment
175
	 * @return <code>this</code> for convenience
176
	 * @since 3.4
177
	 * @deprecated Use {@link #expandPrecise(double, double)} instead.
178
	 */
179
	public Rectangle expand(double h, double v) {
180
		return shrink(-h, -v);
181
	}
182

    
183
	/**
184
	 * @see org.eclipse.draw2d.geometry.Rectangle#expand(org.eclipse.draw2d.geometry.Insets)
185
	 */
186
	public Rectangle expand(Insets insets) {
187
		if (insets == null)
188
			return this;
189
		setPreciseX(preciseX() - insets.left);
190
		setPreciseY(preciseY() - insets.top);
191
		setPreciseWidth(preciseWidth() + insets.getWidth());
192
		setPreciseHeight(preciseHeight() + insets.getHeight());
193
		return this;
194
	}
195

    
196
	/**
197
	 * @see org.eclipse.draw2d.geometry.Rectangle#expand(int, int)
198
	 */
199
	public Rectangle expand(int h, int v) {
200
		return expandPrecise(h, v);
201
	}
202

    
203
	/**
204
	 * Expands the horizontal and vertical sides of this Rectangle with the
205
	 * values provided as input, and returns this for convenience. The location
206
	 * of its center is kept constant.
207
	 * 
208
	 * @param h
209
	 *            Horizontal increment
210
	 * @param v
211
	 *            Vertical increment
212
	 * @return <code>this</code> for convenience
213
	 * @since 3.7
214
	 */
215
	private PrecisionRectangle expandPrecise(double h, double v) {
216
		return shrinkPrecise(-h, -v);
217
	}
218

    
219
	/**
220
	 * @see org.eclipse.draw2d.geometry.Rectangle#getBottom()
221
	 */
222
	public Point getBottom() {
223
		return new PrecisionPoint(preciseX() + preciseWidth() / 2, bottom());
224
	}
225

    
226
	/**
227
	 * @see org.eclipse.draw2d.geometry.Rectangle#getBottomLeft()
228
	 */
229
	public Point getBottomLeft() {
230
		return new PrecisionPoint(preciseX(), preciseY() + preciseHeight());
231
	}
232

    
233
	/**
234
	 * @see org.eclipse.draw2d.geometry.Rectangle#getBottomRight()
235
	 */
236
	public Point getBottomRight() {
237
		return new PrecisionPoint(preciseX() + preciseWidth(), preciseY()
238
				+ preciseHeight());
239
	}
240

    
241
	/**
242
	 * @see org.eclipse.draw2d.geometry.Rectangle#getCenter()
243
	 */
244
	public Point getCenter() {
245
		return new PrecisionPoint(preciseX() + preciseWidth() / 2.0, preciseY()
246
				+ preciseHeight() / 2.0);
247
	}
248

    
249
	/**
250
	 * @see org.eclipse.draw2d.geometry.Rectangle#getCopy()
251
	 */
252
	public Rectangle getCopy() {
253
		return getPreciseCopy();
254
	}
255

    
256
	/**
257
	 * Returns a precise copy of this.
258
	 * 
259
	 * @return a precise copy
260
	 */
261
	public PrecisionRectangle getPreciseCopy() {
262
		return new PrecisionRectangle(preciseX(), preciseY(), preciseWidth(),
263
				preciseHeight());
264
	}
265

    
266
	/**
267
	 * @see org.eclipse.draw2d.geometry.Rectangle#getTop()
268
	 */
269
	public Point getTop() {
270
		return new PrecisionPoint(preciseX() + preciseWidth() / 2, preciseY());
271
	}
272

    
273
	/**
274
	 * @see org.eclipse.draw2d.geometry.Rectangle#getTopLeft()
275
	 */
276
	public Point getTopLeft() {
277
		return new PrecisionPoint(preciseX(), preciseY());
278
	}
279

    
280
	/**
281
	 * @see org.eclipse.draw2d.geometry.Rectangle#getTopRight()
282
	 */
283
	public Point getTopRight() {
284
		return new PrecisionPoint(preciseX() + preciseWidth(), preciseY());
285
	}
286

    
287
	/**
288
	 * @see org.eclipse.draw2d.geometry.Rectangle#intersect(org.eclipse.draw2d.geometry.Rectangle)
289
	 */
290
	public Rectangle intersect(Rectangle rect) {
291
		return intersectPrecise(rect);
292
	}
293

    
294
	/**
295
	 * Sets the size of this Rectangle to the intersection region with the
296
	 * Rectangle supplied as input, and returns this for convenience. The
297
	 * location and dimensions are set to zero if there is no intersection with
298
	 * the input Rectangle.
299
	 * 
300
	 * @param rect
301
	 *            Rectangle for the calculating intersection.
302
	 * @return <code>this</code> for convenience
303
	 * @since 3.7
304
	 */
305
	private PrecisionRectangle intersectPrecise(Rectangle rect) {
306
		double x1 = Math.max(preciseX(), rect.preciseX());
307
		double x2 = Math.min(preciseX() + preciseWidth(), rect.preciseX()
308
				+ rect.preciseWidth());
309
		double y1 = Math.max(preciseY(), rect.preciseY());
310
		double y2 = Math.min(preciseY() + preciseHeight(), rect.preciseY()
311
				+ rect.preciseHeight());
312
		if (((x2 - x1) < 0) || ((y2 - y1) < 0))
313
			return setPreciseBounds(0, 0, 0, 0); // no intersection
314
		else {
315
			return setPreciseBounds(x1, y1, x2 - x1, y2 - y1);
316
		}
317
	}
318

    
319
	/**
320
	 * @see org.eclipse.draw2d.geometry.Rectangle#performScale(double)
321
	 */
322
	public void performScale(double factor) {
323
		setPreciseX(preciseX() * factor);
324
		setPreciseY(preciseY() * factor);
325
		setPreciseWidth(preciseWidth() * factor);
326
		setPreciseHeight(preciseHeight() * factor);
327
	}
328

    
329
	/**
330
	 * @see org.eclipse.draw2d.geometry.Rectangle#performTranslate(int, int)
331
	 */
332
	public void performTranslate(int dx, int dy) {
333
		setPreciseX(preciseX() + dx);
334
		setPreciseY(preciseY() + dy);
335
	}
336

    
337
	/**
338
	 * Returns the bottom coordinte in double precision.
339
	 * 
340
	 * @return the precise bottom
341
	 */
342
	public double preciseBottom() {
343
		return preciseHeight() + preciseY();
344
	}
345

    
346
	/**
347
	 * @see org.eclipse.draw2d.geometry.Rectangle#preciseHeight()
348
	 */
349
	public double preciseHeight() {
350
		updatePreciseHeightDouble();
351
		return preciseHeight;
352
	}
353

    
354
	/**
355
	 * Returns the right side in double precision.
356
	 * 
357
	 * @return the precise right
358
	 */
359
	public double preciseRight() {
360
		return preciseWidth() + preciseX();
361
	}
362

    
363
	/**
364
	 * @see org.eclipse.draw2d.geometry.Rectangle#preciseWidth()
365
	 */
366
	public double preciseWidth() {
367
		updatePreciseWidthDouble();
368
		return preciseWidth;
369
	}
370

    
371
	/**
372
	 * @see org.eclipse.draw2d.geometry.Rectangle#preciseX()
373
	 */
374
	public double preciseX() {
375
		updatePreciseXDouble();
376
		return preciseX;
377
	}
378

    
379
	/**
380
	 * @see org.eclipse.draw2d.geometry.Rectangle#preciseY()
381
	 */
382
	public double preciseY() {
383
		updatePreciseYDouble();
384
		return preciseY;
385
	}
386

    
387
	/**
388
	 * @see org.eclipse.draw2d.geometry.Rectangle#resize(org.eclipse.draw2d.geometry.Dimension)
389
	 */
390
	public Rectangle resize(Dimension d) {
391
		return resizePrecise(d.preciseWidth(), d.preciseHeight());
392
	}
393

    
394
	/**
395
	 * @see org.eclipse.draw2d.geometry.Rectangle#resize(int, int)
396
	 */
397
	public Rectangle resize(int w, int h) {
398
		return resizePrecise(w, h);
399
	}
400

    
401
	/**
402
	 * Resizes this Rectangle by adding the values supplied, returning this for
403
	 * convenience.
404
	 * 
405
	 * @param w
406
	 *            Amount by which width is to be resized
407
	 * @param h
408
	 *            Amount by which height is to be resized
409
	 * @return <code>this</code> for convenience
410
	 * @since 3.7
411
	 */
412
	private PrecisionRectangle resizePrecise(double w, double h) {
413
		setPreciseWidth(preciseWidth() + w);
414
		setPreciseHeight(preciseHeight() + h);
415
		return this;
416
	}
417

    
418
	/**
419
	 * @see org.eclipse.draw2d.geometry.Rectangle#setBounds(int, int, int, int)
420
	 */
421
	public Rectangle setBounds(int x, int y, int width, int height) {
422
		return setPreciseBounds(x, y, width, height);
423
	}
424

    
425
	/**
426
	 * @see org.eclipse.draw2d.geometry.Rectangle#setBounds(org.eclipse.draw2d.geometry.Point,
427
	 *      org.eclipse.draw2d.geometry.Dimension)
428
	 */
429
	public Rectangle setBounds(Point location, Dimension size) {
430
		return setPreciseBounds(location.preciseX(), location.preciseY(),
431
				size.preciseWidth(), size.preciseHeight());
432
	}
433

    
434
	/**
435
	 * @see org.eclipse.draw2d.geometry.Rectangle#setBounds(org.eclipse.draw2d.geometry.Rectangle)
436
	 */
437
	public Rectangle setBounds(Rectangle rect) {
438
		return setPreciseBounds(rect.preciseX(), rect.preciseY(),
439
				rect.preciseWidth(), rect.preciseHeight());
440
	}
441

    
442
	/**
443
	 * Sets the height.
444
	 * 
445
	 * @param value
446
	 *            the new height
447
	 * @deprecated Use {@link #setPreciseHeight(double)} instead.
448
	 */
449
	public void setHeight(double value) {
450
		setPreciseHeight(value);
451
	}
452

    
453
	/**
454
	 * @see org.eclipse.draw2d.geometry.Rectangle#setHeight(int)
455
	 */
456
	public Rectangle setHeight(int height) {
457
		return setPreciseHeight(height);
458
	}
459

    
460
	/**
461
	 * @see org.eclipse.draw2d.geometry.Rectangle#setLocation(int, int)
462
	 */
463
	public Rectangle setLocation(int x, int y) {
464
		return setPreciseLocation(x, y);
465
	}
466

    
467
	/**
468
	 * @see org.eclipse.draw2d.geometry.Rectangle#setLocation(org.eclipse.draw2d.geometry.Point)
469
	 */
470
	public Rectangle setLocation(Point loc) {
471
		return setPreciseLocation(loc.preciseX(), loc.preciseY());
472
	}
473

    
474
	/**
475
	 * Sets the preciseX, preciseY, preciseWidth, and preciseHeight values of
476
	 * this PrecisionRectangle to the provided values and updates the integer
477
	 * values of x, y, width, and height accordingly.
478
	 * 
479
	 * @param x
480
	 *            The new x
481
	 * @param y
482
	 *            The new y
483
	 * @param width
484
	 *            The new width
485
	 * @param height
486
	 *            The new height
487
	 * @return this for convenience
488
	 * @since 3.7
489
	 */
490
	public PrecisionRectangle setPreciseBounds(double x, double y,
491
			double width, double height) {
492
		setPreciseLocation(x, y);
493
		setPreciseSize(width, height);
494
		return this;
495
	}
496

    
497
	/**
498
	 * Sets the height of this PrecisionRectangle to the specified value.
499
	 * 
500
	 * @param value
501
	 *            The new height.
502
	 * @return this for convenience
503
	 * @since 3.7
504
	 */
505
	public PrecisionRectangle setPreciseHeight(double value) {
506
		preciseHeight = value;
507
		updateHeightInt();
508
		return this;
509
	}
510

    
511
	/**
512
	 * Sets the preciseX and preciseY values of this PrecisionRectangle to the
513
	 * provided values and updates the integer values of x and y accordingly.
514
	 * 
515
	 * @param x
516
	 *            The new x value
517
	 * @param y
518
	 *            The new y value
519
	 * @return this for convenience
520
	 * @since 3.7
521
	 */
522
	public PrecisionRectangle setPreciseLocation(double x, double y) {
523
		setPreciseX(x);
524
		setPreciseY(y);
525
		return this;
526
	}
527

    
528
	/**
529
	 * Sets the precise location of this PrecisionRectangle
530
	 * 
531
	 * @param loc
532
	 *            The new location
533
	 * @return this for convenience.
534
	 * @since 3.7
535
	 */
536
	public PrecisionRectangle setPreciseLocation(PrecisionPoint loc) {
537
		return setPreciseLocation(loc.preciseX(), loc.preciseY());
538
	}
539

    
540
	/**
541
	 * Sets the preciseWidth and preciseHeight values of this PrecisionRectangle
542
	 * to the provided values and updates the integer values of width and height
543
	 * accordingly.
544
	 * 
545
	 * @param w
546
	 *            The new width
547
	 * @param h
548
	 *            The new height
549
	 * @return this for convenience.
550
	 * @since 3.7
551
	 */
552
	public PrecisionRectangle setPreciseSize(double w, double h) {
553
		setPreciseWidth(w);
554
		setPreciseHeight(h);
555
		return this;
556
	}
557

    
558
	/**
559
	 * Set the size of this PrecisionRectangle to the given dimension's width
560
	 * and height. Returns this for convenience.
561
	 * 
562
	 * @param size
563
	 *            The new size
564
	 * @return this for convenience.
565
	 * @since 3.7
566
	 */
567
	public PrecisionRectangle setPreciseSize(PrecisionDimension size) {
568
		return setPreciseSize(size.preciseWidth(), size.preciseHeight());
569
	}
570

    
571
	/**
572
	 * Sets the width of this PrecisionRectangle to the specified one.
573
	 * 
574
	 * @param value
575
	 *            The new width
576
	 * @return this for convenience
577
	 * @since 3.7
578
	 */
579
	public PrecisionRectangle setPreciseWidth(double value) {
580
		preciseWidth = value;
581
		updateWidthInt();
582
		return this;
583
	}
584

    
585
	/**
586
	 * Sets the x value.
587
	 * 
588
	 * @param value
589
	 *            The new x value
590
	 * @return this for convenience
591
	 * @since 3.7
592
	 */
593
	public PrecisionRectangle setPreciseX(double value) {
594
		preciseX = value;
595
		updateXInt();
596
		return this;
597
	}
598

    
599
	/**
600
	 * Sets the y value.
601
	 * 
602
	 * @param value
603
	 *            the new y value
604
	 * @return this for convenience
605
	 * @since 3.7
606
	 */
607
	public PrecisionRectangle setPreciseY(double value) {
608
		preciseY = value;
609
		updateYInt();
610
		return this;
611
	}
612

    
613
	/**
614
	 * @see org.eclipse.draw2d.geometry.Rectangle#setSize(org.eclipse.draw2d.geometry.Dimension)
615
	 */
616
	public Rectangle setSize(Dimension d) {
617
		return setPreciseSize(d.preciseWidth(), d.preciseHeight());
618
	}
619

    
620
	/**
621
	 * @see org.eclipse.draw2d.geometry.Rectangle#setSize(int, int)
622
	 */
623
	public Rectangle setSize(int w, int h) {
624
		return setPreciseSize(w, h);
625
	}
626

    
627
	/**
628
	 * Sets the width.
629
	 * 
630
	 * @param value
631
	 *            the new width
632
	 * @deprecated Use {@link #setPreciseWidth(double)} instead.
633
	 */
634
	public void setWidth(double value) {
635
		setPreciseWidth(value);
636
	}
637

    
638
	/**
639
	 * @see org.eclipse.draw2d.geometry.Rectangle#setWidth(int)
640
	 */
641
	public Rectangle setWidth(int width) {
642
		return setPreciseWidth(width);
643
	}
644

    
645
	/**
646
	 * Sets the x value.
647
	 * 
648
	 * @param value
649
	 *            the new x value
650
	 * @deprecated Use {@link #setPreciseX(double)} instead.
651
	 */
652
	public void setX(double value) {
653
		setPreciseX(value);
654
	}
655

    
656
	/**
657
	 * @see org.eclipse.draw2d.geometry.Rectangle#setX(int)
658
	 */
659
	public Rectangle setX(int value) {
660
		return setPreciseX(value);
661
	}
662

    
663
	/**
664
	 * Sets the y value.
665
	 * 
666
	 * @param value
667
	 *            the new y value
668
	 * @deprecated Use {@link #setPreciseX(double)} instead.
669
	 */
670
	public void setY(double value) {
671
		setPreciseY(value);
672
	}
673

    
674
	/**
675
	 * @see org.eclipse.draw2d.geometry.Rectangle#setY(int)
676
	 */
677
	public Rectangle setY(int value) {
678
		return setPreciseY(value);
679
	}
680

    
681
	/**
682
	 * Shrinks the sides of this Rectangle by the horizontal and vertical values
683
	 * provided as input, and returns this Rectangle for convenience. The center
684
	 * of this Rectangle is kept constant.
685
	 * 
686
	 * @param h
687
	 *            Horizontal reduction amount
688
	 * @param v
689
	 *            Vertical reduction amount
690
	 * @return <code>this</code> for convenience
691
	 * @since 3.4
692
	 * @deprecated Use {@link #shrink(int, int)} or
693
	 *             {@link #shrinkPrecise(double, double)} instead.
694
	 */
695
	public Rectangle shrink(double h, double v) {
696
		return shrinkPrecise(h, v);
697
	}
698

    
699
	/**
700
	 * @see org.eclipse.draw2d.geometry.Rectangle#shrink(org.eclipse.draw2d.geometry.Insets)
701
	 */
702
	public Rectangle shrink(Insets insets) {
703
		if (insets == null)
704
			return this;
705
		setPreciseX(preciseX() + insets.left);
706
		setPreciseY(preciseY() + insets.top);
707
		setPreciseWidth(preciseWidth() - insets.getWidth());
708
		setPreciseHeight(preciseHeight() - insets.getHeight());
709
		return this;
710
	}
711

    
712
	/**
713
	 * @see org.eclipse.draw2d.geometry.Rectangle#shrink(int, int)
714
	 */
715
	public Rectangle shrink(int h, int v) {
716
		return shrinkPrecise(h, v);
717
	}
718

    
719
	/**
720
	 * Shrinks the sides of this Rectangle by the horizontal and vertical values
721
	 * provided as input, and returns this Rectangle for convenience. The center
722
	 * of this Rectangle is kept constant.
723
	 * 
724
	 * @param h
725
	 *            Horizontal reduction amount
726
	 * @param v
727
	 *            Vertical reduction amount
728
	 * @return <code>this</code> for convenience
729
	 * @since 3.7
730
	 */
731
	private PrecisionRectangle shrinkPrecise(double h, double v) {
732
		setPreciseX(preciseX() + h);
733
		setPreciseWidth(preciseWidth() - (h + h));
734
		setPreciseY(preciseY() + v);
735
		setPreciseHeight(preciseHeight() - (v + v));
736
		return this;
737
	}
738

    
739
	/**
740
	 * @see org.eclipse.draw2d.geometry.Rectangle#touches(org.eclipse.draw2d.geometry.Rectangle)
741
	 */
742
	public boolean touches(Rectangle rect) {
743
		return rect.preciseX() <= preciseX() + preciseWidth()
744
				&& rect.preciseY() <= preciseY() + preciseHeight()
745
				&& rect.preciseX() + rect.preciseWidth() >= preciseX()
746
				&& rect.preciseY() + rect.preciseHeight() >= preciseY();
747
	}
748

    
749
	/**
750
	 * @see org.eclipse.draw2d.geometry.Rectangle#translate(int, int)
751
	 */
752
	public Rectangle translate(int dx, int dy) {
753
		return translatePrecise(dx, dy);
754
	}
755

    
756
	/**
757
	 * @see org.eclipse.draw2d.geometry.Rectangle#translate(org.eclipse.draw2d.geometry.Point)
758
	 */
759
	public Rectangle translate(Point p) {
760
		return translatePrecise(p.preciseX(), p.preciseY());
761
	}
762

    
763
	/**
764
	 * Moves this Rectangle horizontally by dx and vertically by dy, then
765
	 * returns this Rectangle for convenience.
766
	 * 
767
	 * @param dx
768
	 *            Shift along X axis
769
	 * @param dy
770
	 *            Shift along Y axis
771
	 * @return <code>this</code> for convenience
772
	 * @since 3.7
773
	 */
774
	private PrecisionRectangle translatePrecise(double dx, double dy) {
775
		setPreciseX(preciseX() + dx);
776
		setPreciseY(preciseY() + dy);
777
		return this;
778
	}
779

    
780
	/**
781
	 * @see org.eclipse.draw2d.geometry.Rectangle#transpose()
782
	 */
783
	public Rectangle transpose() {
784
		double temp = preciseX();
785
		setPreciseX(preciseY());
786
		setPreciseY(temp);
787
		temp = preciseWidth();
788
		setPreciseWidth(preciseHeight());
789
		setPreciseHeight(temp);
790
		return this;
791
	}
792

    
793
	/**
794
	 * @see org.eclipse.draw2d.geometry.Rectangle#union(int, int)
795
	 */
796
	public Rectangle union(int x, int y) {
797
		return unionPrecise(x, y);
798
	}
799

    
800
	/**
801
	 * @see org.eclipse.draw2d.geometry.Rectangle#union(org.eclipse.draw2d.geometry.Point)
802
	 */
803
	public void union(Point p) {
804
		unionPrecise(p.preciseX(), p.preciseY());
805
	}
806

    
807
	/**
808
	 * Unions the given PrecisionRectangle with this rectangle and returns
809
	 * <code>this</code> for convenience.
810
	 * 
811
	 * @since 3.0
812
	 * @param rect
813
	 *            the rectangle being unioned
814
	 * @return <code>this</code> for convenience
815
	 * @deprecated Use {@link #union(Rectangle)} instead
816
	 */
817
	public PrecisionRectangle union(PrecisionRectangle rect) {
818
		if (rect == null || rect.isEmpty()) {
819
			return this;
820
		}
821
		return unionPrecise(rect.preciseX(), rect.preciseY(),
822
				rect.preciseWidth(), rect.preciseHeight());
823
	}
824

    
825
	/**
826
	 * @see org.eclipse.draw2d.geometry.Rectangle#union(org.eclipse.draw2d.geometry.Rectangle)
827
	 */
828
	public Rectangle union(Rectangle rect) {
829
		if (rect == null || rect.isEmpty())
830
			return this;
831
		return unionPrecise(rect.preciseX(), rect.preciseY(),
832
				rect.preciseWidth(), rect.preciseHeight());
833
	}
834

    
835
	/**
836
	 * Updates this Rectangle's bounds to the minimum size which can hold both
837
	 * this Rectangle and the coordinate (x,y).
838
	 * 
839
	 * @return <code>this</code> for convenience
840
	 * @param x
841
	 *            X coordinate
842
	 * @param y
843
	 *            Y coordinate
844
	 * @since 3.7
845
	 */
846
	private PrecisionRectangle unionPrecise(double x, double y) {
847
		if (x < preciseX()) {
848
			setPreciseWidth(preciseWidth() + (preciseX() - x));
849
			setPreciseX(x);
850
		} else {
851
			double right = preciseX() + preciseWidth();
852
			if (x > right) {
853
				setPreciseWidth(x - preciseX());
854
			}
855
		}
856
		if (y < preciseY()) {
857
			setPreciseHeight(preciseHeight() + (preciseY() - y));
858
			setPreciseY(y);
859
		} else {
860
			double bottom = preciseY() + preciseHeight();
861
			if (y > bottom) {
862
				setPreciseHeight(y - preciseY());
863
			}
864
		}
865
		return this;
866
	}
867

    
868
	/**
869
	 * Updates this Rectangle's dimensions to the minimum size which can hold
870
	 * both this Rectangle and the rectangle (x, y, w, h).
871
	 * 
872
	 * @param x
873
	 *            X coordinate of desired union.
874
	 * @param y
875
	 *            Y coordinate of desired union.
876
	 * @param w
877
	 *            Width of desired union.
878
	 * @param h
879
	 *            Height of desired union.
880
	 * @return <code>this</code> for convenience
881
	 * @since 3.7
882
	 */
883
	private PrecisionRectangle unionPrecise(double x, double y, double w,
884
			double h) {
885
		double right = Math.max(preciseX() + preciseWidth(), x + w);
886
		double bottom = Math.max(preciseY() + preciseHeight(), y + h);
887
		setPreciseX(Math.min(preciseX(), x));
888
		setPreciseY(Math.min(preciseY(), y));
889
		setPreciseWidth(right - preciseX());
890
		setPreciseHeight(bottom - preciseY());
891
		return this;
892
	}
893

    
894
	/**
895
	 * Updates the height integer field using the value of preciseHeight.
896
	 */
897
	private final void updateHeightInt() {
898
		height = PrecisionGeometry.doubleToInteger(preciseHeight);
899
	}
900

    
901
	/**
902
	 * Updates the integer values based on the current precise values.
903
	 * 
904
	 * @deprecated This method should not be accessed by clients any more (it
905
	 *             will be made private in future releases). The update of
906
	 *             integer and precision fields is performed automatically if
907
	 *             {@link #preciseX}, {@link #preciseY}, {@link #preciseWidth},
908
	 *             and {@link #preciseHeight} field values are not manipulated
909
	 *             directly, but only via respective methods offered by this
910
	 *             class.
911
	 * 
912
	 * @since 3.0
913
	 */
914
	public void updateInts() {
915
		updateXInt();
916
		updateYInt();
917
		updateWidthInt();
918
		updateHeightInt();
919
	}
920

    
921
	/**
922
	 * Updates the preciseHeight double field using the value of height.
923
	 */
924
	private final void updatePreciseHeightDouble() {
925
		if (height != PrecisionGeometry.doubleToInteger(preciseHeight)) {
926
			preciseHeight = height;
927
		}
928
	}
929

    
930
	/**
931
	 * Updates the preciseWidth double field using the value of width.
932
	 */
933
	private final void updatePreciseWidthDouble() {
934
		if (width != PrecisionGeometry.doubleToInteger(preciseWidth)) {
935
			preciseWidth = width;
936
		}
937
	}
938

    
939
	/**
940
	 * Updates the preciseX double field using the value of x.
941
	 */
942
	private final void updatePreciseXDouble() {
943
		if (x != PrecisionGeometry.doubleToInteger(preciseX)) {
944
			preciseX = x;
945
		}
946
	}
947

    
948
	/**
949
	 * Updates the preciseY double field using the value of y.
950
	 */
951
	private final void updatePreciseYDouble() {
952
		if (y != PrecisionGeometry.doubleToInteger(preciseY)) {
953
			preciseY = y;
954
		}
955
	}
956

    
957
	/**
958
	 * Updates the width integer field using the value of preciseWidth.
959
	 */
960
	private final void updateWidthInt() {
961
		width = PrecisionGeometry.doubleToInteger(preciseWidth);
962
	}
963

    
964
	/**
965
	 * Updates the x integer field using the value of preciseX.
966
	 */
967
	private final void updateXInt() {
968
		x = PrecisionGeometry.doubleToInteger(preciseX);
969
	}
970

    
971
	/**
972
	 * Updates the y integer field using the value of preciseY.
973
	 */
974
	private final void updateYInt() {
975
		y = PrecisionGeometry.doubleToInteger(preciseY);
976
	}
977

    
978
}
(9-9/17)