// Copyright 2014-08-20 PlanBase Inc. & Glen Peterson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.planbase.pdf.layoutmanager;
/**
Represents a 2D coordinate in terms of X and Y where negative y is down from the upper left-hand
corner. Do not confuse this with an XyDim which represents positive width and height.
*/
public class XyOffset {
public static final XyOffset ORIGIN = new XyOffset(0f, 0f) {
@Override public int hashCode() { return 0; }
};
private final float x;
private final float y;
private XyOffset(float xCoord, float yCoord) { x = xCoord; y = yCoord; }
public static XyOffset of(float x, float y) {
if ((x == 0f) && (y == 0f)) { return ORIGIN; }
return new XyOffset(x, y);
}
public float x() { return x; }
public float y() { return y; }
public XyOffset x(float newX) { return of(newX, y); }
public XyOffset y(float newY) { return of(x, newY); }
// public XyOffset minus(XyOffset that) { return of(this.x - that.x(), this.y - that.y()); }
// public XyOffset plus(XyOffset that) { return of(this.x + that.x(), this.y + that.y()); }
public XyOffset plusXMinusY(XyOffset that) { return of(this.x + that.x(), this.y - that.y()); }
// public XyOffset maxXandY(XyOffset that) {
// if ((this.x >= that.x()) && (this.y >= that.y())) { return this; }
// if ((this.x <= that.x()) && (this.y <= that.y())) { return that; }
// return of((this.x > that.x()) ? this.x : that.x(),
// (this.y > that.y()) ? this.y : that.y());
// }
public XyOffset maxXMinY(XyOffset that) {
if ((this.x >= that.x()) && (this.y <= that.y())) { return this; }
if ((this.x <= that.x()) && (this.y >= that.y())) { return that; }
return of((this.x > that.x()) ? this.x : that.x(),
(this.y < that.y()) ? this.y : that.y());
}
/** Compares dimensions */
public boolean lte(XyOffset that) { return (this.x <= that.x()) && (this.y >= that.y()); }
@Override public String toString() { return "XyOffset(" + x + " " + y + ")"; }
@Override public int hashCode() { return Utils.floatHashCode(x) ^ Utils.floatHashCode(y); }
@Override public boolean equals(Object other) {
// Cheapest operation first...
if (this == other) { return true; }
if ( (other == null) ||
!(other instanceof XyOffset) ||
(this.hashCode() != other.hashCode()) ) {
return false;
}
// Details...
final XyOffset that = (XyOffset) other;
// Compare "significant" fields here.
return (x == that.x()) && (y == that.y());
}
}