blob: f0888bc71c9f5765bd48124ad592b50e7328d279 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.draw2d.geometry;
/**
* Stores an integer width and height. This class provides various methods for
* manipulating this Dimension or creating new derived Objects.
*/
public class Dimension implements Cloneable, java.io.Serializable, Translatable {
static final long serialVersionUID = 1;
/**
* A singleton for use in short calculations.
*/
public static final Dimension SINGLETON = new Dimension();
/**
* Creates a new Dimension representing the MAX of two provided Dimensions.
*
* @param d1
* first dimension
* @param d2
* second dimension
* @return A new Dimension representing the Max()
* @since 3.7
*/
public static Dimension max(Dimension d1, Dimension d2) {
return new Dimension(Math.max(d1.width(), d2.width()), Math.max(
d1.height(), d2.height()));
}
/**
* Creates a new Dimension representing the MIN of two provided Dimensions.
*
* @param d1
* first dimension
* @param d2
* second dimension
* @return A new Dimension representing the Min()
* @since 3.7
*/
public static Dimension min(Dimension d1, Dimension d2) {
return new Dimension(Math.min(d1.width(), d2.width()), Math.min(
d1.height(), d2.height()));
}
/**
* The width.
*/
public int width;
/**
* The height.
*/
public int height;
/**
* Constructs a Dimension of zero width and height.
*
* @since 2.0
*/
public Dimension() {
}
/**
* Constructs a Dimension with the width and height of the passed Dimension.
*
* @param d
* the Dimension supplying the initial values
* @since 2.0
*/
public Dimension(Dimension d) {
width = d.width();
height = d.height();
}
/**
* Constructs a Dimension with the supplied width and height values.
*
* @param w
* the width
* @param h
* the height
* @since 2.0
*/
public Dimension(int w, int h) {
width = w;
height = h;
}
/**
* Constructs a Dimension with the width and height of the Image supplied as
* input.
*
* @param image
* the image supplying the dimensions
* @since 2.0
*/
public Dimension(org.eclipse.swt.graphics.Image image) {
org.eclipse.swt.graphics.Rectangle r = image.getBounds();
width = r.width;
height = r.height;
}
/**
* Constructs a Dimension where the width and height are the x and y
* distances of the input point from the origin.
*
* @param p
* the Point supplying the initial values
* @since 2.0
*/
public Dimension(org.eclipse.swt.graphics.Point p) {
width = p.x;
height = p.y;
}
/**
* Returns <code>true</code> if the input Dimension fits into this
* Dimension. A Dimension of the same size is considered to "fit".
*
* @param d
* the dimension being tested
* @return <code>true</code> if this Dimension contains <i>d</i>
* @since 2.0
*/
public boolean contains(Dimension d) {
return width >= d.width() && height >= d.height();
}
/**
* Returns <code>true</code> if this Dimension properly contains the one
* specified. Proper containment is defined as containment using \"<\",
* instead of \"<=\".
*
* @param d
* the dimension being tested
* @return <code>true</code> if this Dimension properly contains the one
* specified
* @since 2.0
*/
public boolean containsProper(Dimension d) {
return width > d.width() && height > d.height();
}
/**
* Returns <code>true</code> if this Dimension's width and height are equal
* to the given width and height.
*
* @param w
* the width
* @param h
* the height
* @return <code>true</code> if this dimension's width and height are equal
* to those given.
* @since 2.0
*/
public boolean equals(int w, int h) {
return width == w && height == h;
}
/**
* Returns whether the input Object is equivalent to this Dimension.
* <code>true</code> if the Object is a Dimension and its width and height
* are equal to this Dimension's width and height, <code>false</code>
* otherwise.
*
* @param o
* the Object being tested for equality
* @return <code>true</code> if the given object is equal to this dimension
* @since 2.0
*/
public boolean equals(Object o) {
if (o instanceof Dimension) {
Dimension d = (Dimension) o;
return (d.width() == width && d.height() == height);
}
return false;
}
/**
* Expands the size of this Dimension by the specified amount.
*
* @param d
* the Dimension providing the expansion width and height
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension expand(Dimension d) {
return expand(d.width(), d.height());
}
/**
* Expands the size of this Dimension by the specified width and height.
*
* @param w
* Value by which the width should be increased
* @param h
* Value by which the height should be increased
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension expand(int w, int h) {
width += w;
height += h;
return this;
}
/**
* Expands the size of this Dimension by the specified amound.
*
* @param p
* the Point supplying the dimensional values
* @return <code>this</code> for convenience
* @since 2.0
* @deprecated Use {@link #expand(int, int)} instead.
*/
public Dimension expand(Point p) {
return expand(p.x(), p.y());
}
/**
* Returns the area of this Dimension.
*
* @return the area
* @since 2.0
*/
public int getArea() {
return width * height;
}
/**
* Creates and returns a copy of this Dimension.
*
* @return a copy of this Dimension
* @since 2.0
*/
public Dimension getCopy() {
return new Dimension(this);
}
/**
* Creates and returns a new Dimension representing the difference between
* this Dimension and the one specified.
*
* @param d
* the dimension being compared
* @return a new dimension representing the difference
* @since 2.0
* @deprecated Use {@link #getShrinked(Dimension)} instead.
*/
public Dimension getDifference(Dimension d) {
return getShrinked(d);
}
/**
* Creates and returns a Dimension representing the sum of this Dimension
* and the one specified.
*
* @param d
* the dimension providing the expansion width and height
* @return a new dimension expanded by <i>d</i>
* @since 2.0
*/
public Dimension getExpanded(Dimension d) {
return getCopy().expand(d);
}
/**
* Creates and returns a new Dimension representing the sum of this
* Dimension and the one specified.
*
* @param w
* value by which the width of this is to be expanded
* @param h
* value by which the height of this is to be expanded
* @return a new Dimension expanded by the given values
* @since 2.0
*/
public Dimension getExpanded(int w, int h) {
return getCopy().expand(w, h);
}
/**
* Creates and returns a new Dimension representing the intersection of this
* Dimension and the one specified.
*
* @param d
* the Dimension to intersect with
* @return A new Dimension representing the intersection
* @since 2.0
*/
public Dimension getIntersected(Dimension d) {
return getCopy().intersect(d);
}
/**
* Creates and returns a new Dimension with negated values.
*
* @return a new Dimension with negated values
* @since 2.0
*/
public Dimension getNegated() {
return getCopy().negate();
}
/**
* Creates a new Dimension with its width and height scaled by the specified
* value.
*
* @param amount
* Value by which the width and height are scaled
* @return a new dimension with the scale applied
* @since 2.0
*/
public Dimension getScaled(double amount) {
return getCopy().scale(amount);
}
/**
* Creates and returns a new Dimension whose size will be reduced by the
* width and height of the given Dimension.
*
* @param d
* the dimension whose width and height values will be considered
* @return a new dimension representing the difference
* @since 3.7
*/
public Dimension getShrinked(Dimension d) {
return getCopy().shrink(d);
}
/**
* Creates and returns a new Dimension whose size will be reduced by the
* width and height of the given Dimension.
*
* @param w
* the value by which the width is to be reduced
* @param h
* the value by which the height is to be reduced
* @return a new dimension representing the difference
* @since 3.7
*/
public Dimension getShrinked(int w, int h) {
return getCopy().shrink(w, h);
}
/**
* Creates a new Dimension with its height and width swapped. Useful in
* orientation change calculations.
*
* @return a new Dimension with its height and width swapped
* @since 2.0
*/
public Dimension getTransposed() {
return getCopy().transpose();
}
/**
* Creates a new Dimension representing the union of this Dimension with the
* one specified. Union is defined as the max() of the values from each
* Dimension.
*
* @param d
* the Dimension to be unioned
* @return a new Dimension
* @since 2.0
*/
public Dimension getUnioned(Dimension d) {
return getCopy().union(d);
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return (width * height) ^ (width + height);
}
/**
* Returns the height of this dimension.
*
* @return The current height
* @since 3.7
*/
public int height() {
return height;
}
/**
* This Dimension is intersected with the one specified. Intersection is
* performed by taking the min() of the values from each dimension.
*
* @param d
* the Dimension used to perform the min()
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension intersect(Dimension d) {
width = Math.min(d.width(), width);
height = Math.min(d.height(), height);
return this;
}
/**
* Returns <code>true</code> if either dimension is less than or equal to 0.
*
* @return <code>true</code> if either dimension is less than or equal to 0.
* @since 2.0
*/
public boolean isEmpty() {
return (width <= 0) || (height <= 0);
}
/**
* Negates the width and height of this Dimension.
*
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension negate() {
return scale(-1);
}
/**
* @see org.eclipse.draw2d.geometry.Translatable#performScale(double)
*/
public void performScale(double factor) {
scale(factor);
}
/**
* @see org.eclipse.draw2d.geometry.Translatable#performTranslate(int, int)
*/
public void performTranslate(int dx, int dy) {
// FIXME: actually Dimension are not translatable. Remove this
// method as soon as bug #307276 is resolved.
}
/**
* Returns <code>double</code> height
*
* @return <code>double</code> height
* @since 3.4
*/
public double preciseHeight() {
return height;
}
/**
* Returns <code>double</code> width
*
* @return <code>double</code> width
* @since 3.4
*/
public double preciseWidth() {
return width;
}
/**
* Scales the width and height of this Dimension by the amount supplied, and
* returns this for convenience.
*
* @param factor
* value by which this Dimension's width and height are to be
* scaled
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension scale(double factor) {
return scale(factor, factor);
}
/**
* Scales the width of this Dimension by <i>w</i> and scales the height of
* this Dimension by <i>h</i>. Returns this for convenience.
*
* @param widthFactor
* the value by which the width is to be scaled
* @param heightFactor
* the value by which the height is to be scaled
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension scale(double widthFactor, double heightFactor) {
width = (int) (Math.floor(width * widthFactor));
height = (int) (Math.floor(height * heightFactor));
return this;
}
/**
* Sets the height of this Rectangle to the specified one.
*
* @param height
* The new height
* @return this for convenience
* @since 3.7
*/
public Dimension setHeight(int height) {
this.height = height;
return this;
}
/**
* Copies the width and height values of the input Dimension to this
* Dimension.
*
* @param d
* the dimension supplying the values
* @since 2.0
*/
public void setSize(Dimension d) {
// TODO: This should for the sake of consistency also return this
// by convenience; however, this is regarded as API break so it
// may be done not sooner than in 4.0; if this is done, it has
// to be ensured that the overwritten method in PrecisionDimension
// is adjusted as well.
width = d.width();
height = d.height();
}
/**
* Sets the size of this dimension to the specified width and height.
*
* @param w
* The new width
* @param h
* The new height
* @since 3.7
*/
public Dimension setSize(int w, int h) {
width = w;
height = h;
return this;
}
/**
* Sets the width of this Rectangle to the specified one.
*
* @param width
* The new width
* @return this for convenience
* @since 3.7
*/
public Dimension setWidth(int width) {
this.width = width;
return this;
}
/**
* Shrinks the size of this Dimension by the width and height values of the
* given Dimension.
*
* @param d
* The dimension whose width and height values are to be used
* @return <code>this</code> for convenience
* @since 3.7
*/
public Dimension shrink(Dimension d) {
return shrink(d.width(), d.height());
}
/**
* Reduces the width of this Dimension by <i>w</i>, and reduces the height
* of this Dimension by <i>h</i>. Returns this for convenience.
*
* @param w
* the value by which the width is to be reduced
* @param h
* the value by which the height is to be reduced
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension shrink(int w, int h) {
width -= w;
height -= h;
return this;
}
/**
* @see Object#toString()
*/
public String toString() {
return "Dimension(" + //$NON-NLS-1$
width + ", " + //$NON-NLS-1$
height + ")"; //$NON-NLS-1$
}
/**
* Swaps the width and height of this Dimension, and returns this for
* convenience. Can be useful in orientation changes.
*
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension transpose() {
int temp = width;
width = height;
height = temp;
return this;
}
/**
* Sets the width of this Dimension to the greater of this Dimension's width
* and <i>d</i>.width. Likewise for this Dimension's height.
*
* @param d
* the Dimension to union with this Dimension
* @return <code>this</code> for convenience
* @since 2.0
*/
public Dimension union(Dimension d) {
width = Math.max(width, d.width());
height = Math.max(height, d.height());
return this;
}
/**
* Returns the width of this dimension
*
* @return the current width of this dimension
* @since 3.7
*/
public int width() {
return width;
}
}