/*
ChibiPaint
Copyright (c) 2006-2008 Marc Schefer
This file is part of ChibiPaint.
ChibiPaint is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ChibiPaint is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ChibiPaint. If not, see <http://www.gnu.org/licenses/>.
*/
package com.chibipaint.util;
// left,mTop: upper left corner, mRight, mBottom: lower right corner,
// exclusive, right>left && bottom>top if not empty
public class CPRect implements Cloneable {
public int left, top, right, bottom;
public CPRect(int left, int top, int right, int bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public CPRect(int width, int height) {
left = 0;
top = 0;
right = width;
bottom = height;
}
public CPRect() {
makeEmpty();
}
public CPRect(CPRect r) {
set(r);
}
public void makeEmpty() {
left = 0;
top = 0;
right = 0;
bottom = 0;
}
public void union(CPRect rect) {
if (isEmpty())
set(rect);
else {
left = Math.min(left, rect.left);
top = Math.min(top, rect.top);
right = Math.max(right, rect.right);
bottom = Math.max(bottom, rect.bottom);
}
}
public void clip(CPRect rect) {
if (isEmpty())
return;
if (rect.isEmpty())
makeEmpty();
else {
left = Math.max(left, rect.left);
top = Math.max(top, rect.top);
right = Math.min(right, rect.right);
bottom = Math.min(bottom, rect.bottom);
}
}
public boolean isInside(CPRect rect) {
return left >= rect.left && top >= rect.top && right <= rect.right
&& bottom <= rect.bottom;
}
// First makes dstRect the same width and height (not modifying its top/left)
// Clips the dstRect with this rectangle and changes the srcRect so that
// it corresponds to the new clipped rectangle
public void clipSourceDest(CPRect srcRect, CPRect dstRect) {
dstRect.right = dstRect.left + srcRect.getWidth();
dstRect.bottom = dstRect.top + srcRect.getHeight();
if (isEmpty() || dstRect.left >= right || dstRect.top >= bottom
|| dstRect.right <= left || dstRect.bottom <= top) {
srcRect.makeEmpty();
dstRect.makeEmpty();
return;
}
// bottom/right
if (dstRect.right > right) {
srcRect.right -= dstRect.right - right;
dstRect.right = right;
}
if (dstRect.bottom > bottom) {
srcRect.bottom -= dstRect.bottom - bottom;
dstRect.bottom = bottom;
}
// top/left
if (dstRect.left < left) {
srcRect.left += left - dstRect.left;
dstRect.left = left;
}
if (dstRect.top < top) {
srcRect.top += top - dstRect.top;
dstRect.top = top;
}
}
public int getWidth() {
return right - left;
}
public int getHeight() {
return bottom - top;
}
public int getLeft() {
return left;
}
public int getTop() {
return top;
}
public int getRight() {
return right;
}
public int getBottom() {
return bottom;
}
public boolean isEmpty() {
return right <= left || bottom <= top;
}
public void set(CPRect r) {
left = r.left;
top = r.top;
right = r.right;
bottom = r.bottom;
}
@Override
public Object clone() {
try {
return super.clone();
} catch (Exception ignored) {
throw new Error("Uh oh");
}
}
public void translate(int x, int y) {
left += x;
right += x;
top += y;
bottom += y;
}
public void moveTo(int x, int y) {
translate(x - left, y - top);
}
@Override
public boolean equals(Object o) {
if (o instanceof CPRect) {
CPRect r = (CPRect) o;
return left == r.left && right == r.right && top == r.top
&& bottom == r.bottom;
}
return false;
}
};