com.adobe.xfa.ut.Rect Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
/*
* ADOBE CONFIDENTIAL
*
* Copyright 1994 Adobe Systems Incorporated All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual and
* technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or copyright
* law. Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe Systems Incorporated.
*
* @author Richard Devitt
*/
package com.adobe.xfa.ut;
/**
* A class to describe a rectangle. It consists of left, top, right, and, bottom
* extents.
*
* Instances of this class are immutable. All change operations
* return a new instance of this Rect
class.
*/
public final class Rect {
/** @exclude from published api. */
public static final Rect ZERO = new Rect();
private final UnitSpan mLeft;
private final UnitSpan mTop;
private final UnitSpan mRight;
private final UnitSpan mBottom;
/**
* Instantiates a Rect
of zero extents.
*/
public Rect() {
mLeft = UnitSpan.ZERO;
mTop = UnitSpan.ZERO;
mRight = UnitSpan.ZERO;
mBottom = UnitSpan.ZERO;
}
/**
* Instantiates a Rect
from the
* given Rect
.
*
* @param source
* the Rect
to copy to this object.
* @deprecated Rect is immutable, so there is no need to copy an instance.
*/
public Rect(Rect source) {
this(source.mLeft, source.mTop, source.mRight, source.mBottom);
}
/**
* Instantiates a Rect
* specified by the given CoordPair
.
*
* @param topLeft
* the top left coordinate of the rectangle.
* @param bottomRight
* the bottom right coordinate of the rectangle.
*/
public Rect(CoordPair topLeft, CoordPair bottomRight) {
this(topLeft.x(), topLeft.y(), bottomRight.x(), bottomRight.y());
}
/**
* Instantiates a Rect
* specified by the given UnitSpan
extents.
* The rectangle's extents are normalized such that:
*
* - the leftmost extent is set to
*
min(oLeft, oRight)
,
* - the rightmost extent is set to
*
max(oLeft, oRight)
,
* - the topmost extent is set to
*
min(oTop, oBottom)
,
* - the bottommost extent is set to
*
max(oTop, oBottom)
,
* - the width is set to
|oLeft - oRight|
, and,
* - the height is set to
|oTop - oBottom|
.
*
*
* @param left
* the left extent of the rectangle.
* @param top
* the top extent of the rectangle.
* @param right
* the right extent of the rectangle.
* @param bottom
* the bottom extent of the rectangle.
*/
public Rect(UnitSpan left, UnitSpan top, UnitSpan right, UnitSpan bottom) {
if (left.lte(right)) {
mLeft = left;
mRight = right;
} else {
mLeft = right;
mRight = left;
}
if (top.lte(bottom)) {
mTop = top;
mBottom = bottom;
} else {
mTop = bottom;
mBottom = top;
}
}
/**
* Gets this object's leftmost extent.
*
* @return
* the leftmost extent.
*/
public UnitSpan left() {
return mLeft;
}
/**
* Gets this object's topmost extent.
*
* @return
* the topmost extent.
*/
public UnitSpan top() {
return mTop;
}
/**
* Gets this object's rightmost extent.
*
* @return
* the rightmost extent.
*/
public UnitSpan right() {
return mRight;
}
/**
* Gets this object's bottommost extent.
*
* @return
* the bottommost extent.
*/
public UnitSpan bottom() {
return mBottom;
}
/**
* Returns a Rect
representing the
* change in width of this object by the given UnitSpan
extents.
* The left/right extends are normalized.
*
* @param newLeft
* the new left extent.
* @param newRight
* the new right extent.
* @return
* a rectangle of the changed width.
*/
public Rect leftRight(UnitSpan newLeft, UnitSpan newRight) {
return new Rect(newLeft, mTop, newRight, mBottom);
}
/**
* Returns a Rect
representing the
* change in height of this object by the given UnitSpan
extents.
*
* @param newTop
* the new left extent.
* @param newBottom
* the new bottom extent.
* @return
* a rectangle of the changed height.
*/
public Rect topBottom(UnitSpan newTop, UnitSpan newBottom) {
return new Rect(mLeft, newTop, mRight, newBottom);
}
/**
* Returns a Rect
representing the
* change in width of this object by the given UnitSpan
extents.
*
* @param newLeft
* the new left extent.
* @param newWidth
* the new width.
* @return
* a rectangle of the changed width.
*/
public Rect leftWidth(UnitSpan newLeft, UnitSpan newWidth) {
return leftRight(newLeft, newLeft.add(newWidth));
}
/**
* Returns a Rect
representing the
* change in width of this object by the given UnitSpan
extents.
*
* @param newRight
* the new right extent.
* @param newWidth
* the new width.
* @return
* a rectangle of the changed width.
*/
public Rect rightWidth(UnitSpan newRight, UnitSpan newWidth) {
return leftRight(newRight.subtract(newWidth), newRight);
}
/**
* Returns a Rect
representing the
* change in height of this object by the given UnitSpan
extents.
*
* @param newTop
* the new top extent.
* @param newHeight
* the new height.
* @return
* a rectangle of the changed height.
*/
public Rect topHeight(UnitSpan newTop, UnitSpan newHeight) {
return topBottom(newTop, newTop.add(newHeight));
}
/**
* Returns a Rect
representing the
* change in height of this object by the given UnitSpan
extents.
*
* @param newBottom
* the new bottom extent.
* @param newHeight
* the new height.
* @return
* a rectangle of the changed height.
*/
public Rect bottomHeight(UnitSpan newBottom, UnitSpan newHeight) {
return topBottom(newBottom.subtract(newHeight), newBottom);
}
/**
* Gets this object's top left coordinate.
*
* @return
* the top left coordinate.
*/
public CoordPair topLeft() {
return new CoordPair(mLeft, mTop);
}
/**
* Gets this object's top right coordinate.
*
* @return
* the top right coordinate.
*/
public CoordPair topRight() {
return new CoordPair(mRight, mTop);
}
/**
* Gets this object's bottom left coordinate.
*
* @return
* the bottom left coordinate.
*/
public CoordPair bottomLeft() {
return new CoordPair(mLeft, mBottom);
}
/**
* Gets this object's bottom right coordinate.
*
* @return
* the bottom right coordinate.
*/
public CoordPair bottomRight() {
return new CoordPair(mRight, mBottom);
}
/**
* Returns a Rect
representing the
* change of this object's unit span units to the given unit code.
*
* @param eNewUnits
* the new unit code.
* @return
* a rectangle of the change.
*/
public Rect changeUnits(int eNewUnits) {
return new Rect(mLeft.changeUnits(eNewUnits),
mTop.changeUnits(eNewUnits),
mRight.changeUnits(eNewUnits),
mBottom.changeUnits(eNewUnits));
}
/**
* Returns a Rect
representing the
* extention of this object using the given top left CoordPair
.
*
* @param newTopLeft
* the new top left coordinate.
* @return
* a rectangle of the extention.
*/
public Rect topLeft(CoordPair newTopLeft) {
return new Rect(newTopLeft.x(), newTopLeft.y(), mRight, mBottom);
}
/**
* Returns a Rect
representing the
* extention of this object using the given top right CoordPair
.
*
* @param newTopRight
* the new top right coordinate.
* @return
* a rectangle of the extention.
*/
public Rect topRight(CoordPair newTopRight) {
return new Rect(mLeft, newTopRight.y(), newTopRight.x(), mBottom);
}
/**
* Returns a Rect
representing the
* extention of this object using the given bottom left CoordPair
.
*
* @param newBottomLeft
* the new bottom left coordinate.
* @return
* a rectangle of the extention.
*/
public Rect bottomLeft(CoordPair newBottomLeft) {
return new Rect(newBottomLeft.x(), mTop, mRight, newBottomLeft.y());
}
/**
* Returns a Rect
representing the
* extention of this object using the given bottom right CoordPair
.
*
* @param newBottomRight
* the new bottom right coordinate.
* @return
* a rectangle of the extention.
*/
public Rect bottomRight(CoordPair newBottomRight) {
return new Rect(mLeft, mTop, newBottomRight.x(), newBottomRight.y());
}
/**
* Gets this object's height.
*
* @return
* the height.
*/
public UnitSpan height() {
return mBottom.subtract(mTop);
}
/**
* Gets this object's width.
*
* @return
* the width.
*/
public UnitSpan width() {
return mRight.subtract(mLeft);
}
/**
* Returns a Rect
representing the
* stretch in height of this object by the given UnitSpan
.
*
* @param newHeight
* the new height.
* @param bStretchTop
* stretch from the top when set; stretch from the bottom when not set.
* @return
* a rectangle of the stretched height.
*/
public Rect height(UnitSpan newHeight, boolean bStretchTop /* = false */) {
return bStretchTop ? bottomHeight(mBottom, newHeight)
: topHeight(mTop, newHeight);
}
/**
* Returns a Rect
representing the
* stretch in width of this object by the given UnitSpan
.
*
* @param newWidth
* the new width.
* @param bStretchLeft
* stretch from the left when set; stretch from the right when not set.
* @return
* a rectangle of the stretched width.
*/
public Rect width(UnitSpan newWidth, boolean bStretchLeft /* = false */) {
return bStretchLeft ? rightWidth(mRight, newWidth)
: leftWidth(mLeft, newWidth);
}
/**
* Gets this object's centre coordinate.
*
* @return
* the center of the rectangle.
*/
public CoordPair centre() {
return new CoordPair(mLeft.add(mRight).divide(2), mTop.add(mBottom).divide(2));
}
/**
* Determines if this object contains the given CoordPair
.
*
* @param point
* a coordinate.
* @return
* true if the coordinate is contained, false otherwise
*/
public boolean contains(CoordPair point) {
return point.x().gte(mLeft)
&& point.x().lte(mRight)
&& point.y().gte(mTop)
&& point.y().lte(mBottom);
}
/**
* Determines if this object contains the given Rect
.
*
* @param rect
* a rectangle.
* @return
* true if given the rectangle is contained, false otherwise
*/
public boolean contains(Rect rect) {
return (contains(rect.topLeft()) && contains(rect.bottomRight()));
}
/**
* Determines if this object overlaps the given Rect
.
*
* @param rect
* a rectangle.
* @return
* true if the rectangle overlaps, false otherwise
*/
public boolean overlaps(Rect rect) {
return rect.mRight.gte(mLeft)
&& rect.mLeft.lte(mRight)
&& rect.mBottom.gte(mTop)
&& rect.mTop.lte(mBottom);
}
/**
* Determines if this object is disjoint from the given Rect
.
* This is slightly different than the result of ! overlaps()
* in that, if the rectangles share an edge, this will return true.
*
* @param rect
* a rectangle.
* @return
* true if the rectangle is disjoint, false otherwise
* @see #overlaps(Rect)
*/
public boolean disjoint(Rect rect) {
return rect.mRight.lte(mLeft)
|| rect.mLeft.gte(mRight)
|| rect.mBottom.lte(mTop)
|| rect.mTop.gte(mBottom);
}
/**
* Determines if this object is degenerate.
* Only the zero rectangle is degenerate.
*
* @return
* true if this rectangle is degenerate, false otherwise
* @see #zero()
*/
public boolean isDegenerate() {
return mRight.lte(mLeft) || mBottom.lte(mTop);
}
/**
* Returns a Rect
representing the rotation
* of this object about the given CoordPair
* and Angle
of rotation.
*
* @param point
* the point of rotation.
* @param angle
* the angle of rotation.
* @return
* a rectangle of the rotation.
*/
public Rect rotate(CoordPair point, Angle angle) {
if (angle.degrees() == 0) {
return this;
}
//
// rotate the corners
//
CoordPair rTopLeft = topLeft().rotatePoint(point, angle);
CoordPair rTopRight = topRight().rotatePoint(point, angle);
CoordPair rBottomLeft = bottomLeft().rotatePoint(point, angle);
CoordPair rBottomRight = bottomRight().rotatePoint(point, angle);
//
// set the new edges
//
return new Rect(minUnit(rTopLeft.x(), rTopRight.x(), rBottomLeft.x(), rBottomRight.x()),
minUnit(rTopLeft.y(), rTopRight.y(), rBottomLeft.y(), rBottomRight.y()),
maxUnit(rTopLeft.x(), rTopRight.x(), rBottomLeft.x(), rBottomRight.x()),
maxUnit(rTopLeft.y(), rTopRight.y(), rBottomLeft.y(), rBottomRight.y()));
}
// public void ChangeUnits(UnitSpan.unitCode eNewUnits) {
// moLeft.changeUnits(eNewUnits);
// moTop.changeUnits(eNewUnits);
// moRight.changeUnits(eNewUnits);
// moBottom.changeUnits(eNewUnits);
// }
/**
* Determines if this object is equal to the given Object
.
* Comparisons with instances of non-Rect
objects are never equal.
*
* @param object
* the Object
to compare.
* @return
* true if equal, false otherwise.
*/
public boolean equals(Object object) {
if (this == object)
return true;
// This overrides Object.equals(boolean) directly, so...
if (object == null)
return false;
if (object.getClass() != getClass())
return false;
Rect cmp = (Rect) object;
return mLeft.equals(cmp.mLeft)
&& mTop.equals(cmp.mTop)
&& mRight.equals(cmp.mRight)
&& mBottom.equals(cmp.mBottom);
}
/**
* @exclude from published api.
*/
public int hashCode() {
int hash = 13;
hash = (hash * 31) ^ mLeft.hashCode();
hash = (hash * 31) ^ mTop.hashCode();
hash = (hash * 31) ^ mRight.hashCode();
hash = (hash * 31) ^ mBottom.hashCode();
return hash;
}
/**
* Determines if this object is not equal to the given Object
.
* Comparisons with instances of non-Rect
objects are always not equal.
*
* @param compare
* the Object
to compare.
* @return
* true if not equal, false otherwise
*/
public boolean notEquals(Object compare) {
return ! equals(compare);
}
/**
* Returns a Rect
representing the
* shift of this object by the given CoordPair
.
*
* @param add
* the CoordPair
to add.
* @return
* a rectangle of the shift.
*/
public Rect add(CoordPair add) {
return new Rect(mLeft.add(add.x()),
mTop.add(add.y()),
mRight.add(add.x()),
mBottom.add(add.y()));
}
/**
* Returns a Rect
representing the
* shift of this object and the given CoordPair
.
*
* @param subtract
* the CoordPair
to subtract.
* @return
* a rectangle of the shift.
*/
public Rect subtract(CoordPair subtract) {
return new Rect(mLeft.subtract(subtract.x()),
mTop.subtract(subtract.y()),
mRight.subtract(subtract.x()),
mBottom.subtract(subtract.y()));
}
/**
* Returns a Rect
representing the
* union of this object with the given Rect
.
*
* @param union
* the Rect
to unite with.
* @return
* a rectangle of the union.
*/
public Rect union(Rect union) {
return new Rect(minUnit(mLeft, union.mLeft),
minUnit(mTop, union.mTop),
maxUnit(mRight, union.mRight),
maxUnit(mBottom, union.mBottom));
}
/**
* Returns a Rect
representing the
* intersection of this object with the given Rect
.
*
* @param intersect
* the Rect
to intersect with.
* @return
* a rectangle of the intersection.
*/
public Rect intersection(Rect intersect) {
UnitSpan left = maxUnit(mLeft, intersect.mLeft);
UnitSpan top = maxUnit(mTop, intersect.mTop);
UnitSpan right = minUnit(mRight, intersect.mRight);
UnitSpan bottom = minUnit(mBottom, intersect.mBottom);
return (left.gt(right) || top.gt(bottom)) ? Rect.ZERO
: new Rect(left, top, right, bottom);
}
/**
* The zero rectangle.
*
* @return
* the rectangle equal to zero.
*/
public static Rect zero() {
return ZERO;
}
private UnitSpan minUnit(UnitSpan point1, UnitSpan point2) {
return point1.lt(point2) ? point1 : point2;
}
private UnitSpan maxUnit(UnitSpan point1, UnitSpan point2) {
return point1.gt(point2) ? point1 : point2;
}
private UnitSpan minUnit(UnitSpan point1, UnitSpan point2, UnitSpan point3, UnitSpan point4) {
return minUnit(minUnit(point1, point2), minUnit(point3, point4));
}
private UnitSpan maxUnit(UnitSpan point1, UnitSpan point2, UnitSpan point3, UnitSpan point4) {
return maxUnit(maxUnit(point1, point2), maxUnit(point3, point4));
}
}