/*
* Scriptographer
*
* This file is part of Scriptographer, a Scripting Plugin for Adobe Illustrator
* http://scriptographer.org/
*
* Copyright (c) 2002-2010, Juerg Lehni
* http://scratchdisk.com/
*
* All rights reserved. See LICENSE file for details.
*
* File created on Dec 22, 2007.
*/
package com.scriptographer.ai;
import com.scratchdisk.script.ArgumentReader;
import com.scratchdisk.script.ChangeEmitter;
import com.scriptographer.ScriptographerEngine;
/**
* @author lehni
*/
public class Size implements ChangeEmitter {
protected double width;
protected double height;
public Size() {
width = height = 0;
}
/**
* Creates a Size object with the given width and height.
*
* @param width The width of the Size {@default 0}
* @param height The height of the Size {@default 0}
*/
public Size(double width, double height) {
set(width, height);
}
public Size(float width, float height) {
set(width, height);
}
/**
* Creates a Size object with the given value for both width and height.
*
* @param size The width and height of the Size
*/
public Size(double size) {
set(size, size);
}
/**
* Creates a Size object using the x and y coordinates of the given Point
* object.
*
* Sample code:
* <code>
* var point = new Point(50, 50);
* var size = new Size(point);
* print(size.width); // 50
* print(size.height); // 50
* </code>
*
* @param point
*/
public Size(Point point) {
this(point.x, point.y);
}
/**
* Creates a Size object using the width and height of the given Size
* object.
*
* @param size
*/
public Size(Size size) {
this(size.width, size.height);
}
/**
* @jshide
*/
public Size(ArgumentReader reader) {
this(reader.has("width") ? reader.readDouble("width", 0) : reader.readDouble("x", 0),
reader.has("height") ? reader.readDouble("height", 0) : reader.readDouble("y", 0));
}
/**
* @jshide
*/
public void set(double width, double height) {
this.width = width;
this.height = height;
}
/**
* The width of the size.
*/
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
/**
* The height of the size.
*/
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
/**
* @jshide
*/
public Size add(double w, double h) {
return new Size(width + w, height + h);
}
/**
* Returns the addition of the width and height of the supplied size to the
* size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var firstSize = new Size(8, 10);
* var secondSize = new Size(2, 5);
* var result = firstSize + secondSize;
* print(result); // { width: 10.0, height: 15.0 }
* </code>
*
* @param size The addition of the two sizes as a new size
*/
public Size add(Size size) {
return add(size.width, size.height);
}
/**
* Returns the addition of the supplied value to the width and height of the
* size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var point = new Size(10, 20);
* var result = size + 5;
* print(result); // { width: 15.0, height: 25.0 }
* </code>
*
* @param value
* @return the addition of the size and the value as a new size
*/
public Size add(double value) {
return add(value, value);
}
/**
* @jshide
*/
public Size subtract(double w, double h) {
return new Size(width - w, height - h);
}
/**
* Returns the subtraction of the width and height of the supplied size from
* the size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var firstSize = new Size(8, 10);
* var secondSize = new Size(2, 5);
* var result = firstSize - secondSize;
* print(result); // { width: 6.0, height: 5.0 }
* </code>
*
* @param size The subtraction of the two sizes as a new size
*/
public Size subtract(Size size) {
return subtract(size.width, size.height);
}
/**
* Returns the subtraction of the supplied value from the width and height
* of the size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var point = new Size(10, 20);
* var result = size - 5;
* print(result); // { width: 5.0, height: 15.0 }
* </code>
*
* @param value
* @return the subtraction of the value from the size as a new size
*/
public Size subtract(double value) {
return subtract(value, value);
}
/**
* @jshide
*/
public Size multiply(double w, double h) {
return new Size(width * w, height * h);
}
/**
* Returns the multiplication of the width and height of the supplied size
* with the size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var firstSize = new Size(8, 10);
* var secondSize = new Size(2, 5);
* var result = firstSize * secondSize;
* print(result); // { width: 16.0, height: 50.0 }
* </code>
*
* @param size The multiplication of the two sizes as a new size
*/
public Size multiply(Size size) {
return multiply(size.width, size.height);
}
/**
* Returns the multiplication of the supplied value with the width and
* height of the size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var point = new Size(10, 20);
* var result = size * 2;
* print(result); // { width: 20.0, height: 40.0 }
* </code>
*
* @param value
* @return the multiplication of the size by the value as a new size
*/
public Size multiply(double value) {
return multiply(value, value);
}
/**
* @jshide
*/
public Size divide(double w, double h) {
return new Size(width / w, height / h);
}
/**
* Returns the division of the width and height of the supplied size by the
* size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var firstSize = new Size(8, 10);
* var secondSize = new Size(2, 5);
* var result = firstSize / secondSize;
* print(result); // { width: 4.0, height: 2.0 }
* </code>
*
* @param size The division of the two sizes as a new size
*/
public Size divide(Size size) {
return divide(size.width, size.height);
}
/**
* Returns the division of the supplied value by the width and height of the
* size as a new size. The object itself is not modified!
*
* Sample code:
* <code>
* var point = new Size(10, 20);
* var result = size / 2;
* print(result); // { width: 5.0, height: 10.0 }
* </code>
*
* @param value
* @return the division of the size by the value as a new size
*/
public Size divide(double value) {
return divide(value, value);
}
/**
* @jshide
*/
public Size modulo(double w, double h) {
return new Size(this.width % w, this.height % h);
}
/**
* The modulo operator returns the integer remainders of dividing the size
* by the supplied size as a new size.
*
* Sample code:
* <code>
* var size = new Size(12, 6);
* print(size % new Size(5, 2)); // {width: 2, height: 0}
* </code>
*
* @param size
* @return the integer remainders of dividing the sizes by each other as a
* new size
*/
public Size modulo(Size size) {
return modulo(size.width, size.height);
}
/**
* The modulo operator returns the integer remainders of dividing the size
* by the supplied value as a new size.
*
* Sample code:
* <code>
* var size = new Size(12, 6);
* print(size % 5); // {width: 2, height: 1}
* </code>
*
* @param value
* @return the integer remainders of dividing the size by the value as a new size
*/
public Size modulo(double value) {
return modulo(value, value);
}
/**
* @jshide
*/
public Size negate() {
return new Size(-width, -height);
}
/**
* Returns a copy of the size.
* This is useful as the following code only generates a flat copy:
*
* <code>
* var size2 = new Size();
* var size2 = size1;
* size2.x = 1; // also changes size1.x
*
* var size2 = size1.clone();
* size2.x = 1; // doesn't change size1.x
* </code>
*
* @return the cloned size object
*/
public Object clone() {
return new Size(this);
}
/**
* Checks whether the width and height of the size are equal to those of the
* supplied size.
*
* Sample code:
* <code>
* var size = new Size(5, 10);
* print(size == new Size(5, 10)); // true
* print(size == new Size(1, 1)); // false
* print(size != new Size(1, 1)); // true
* </code>
*/
public boolean equals(Object object) {
if (object instanceof Size) {
Size size = (Size) object;
return size.width == width && size.height == height;
}
// TODO: support other point types?
return false;
}
/**
* {@grouptitle Math Functions}
*
* Returns a new size with rounded {@link #width} and {@link #height}
* values. The object itself is not modified!
*
* Sample code:
* <code>
* var size = new Size(10.2, 10.9);
* var roundSize = size.round();
* print(roundSize); // { width: 10.0, height: 11.0 }
* </code>
*/
public Size round() {
return new Size(Math.round(width), Math.round(height));
}
/**
* Returns a new size with the nearest greater non-fractional values to the
* specified {@link #width} and {@link #height} values. The object itself is not
* modified!
*
* Sample code:
* <code>
* var size = new Size(10.2, 10.9);
* var ceilSize = size.ceil();
* print(ceilSize); // { width: 11.0, height: 11.0 }
* </code>
*/
public Size ceil() {
return new Size(Math.ceil(width), Math.ceil(height));
}
/**
* Returns a new size with the nearest smaller non-fractional values to the
* specified {@link #width} and {@link #height} values. The object itself is
* not modified!
*
* Sample code:
* <code>
* var size = new Size(10.2, 10.9);
* var floorSize = size.floor();
* print(floorSize); // { width: 10.0, height: 10.0 }
* </code>
*/
public Size floor() {
return new Size(Math.floor(width), Math.floor(height));
}
/**
* Returns a new size with the absolute values of the specified
* {@link #width} and {@link #height} values. The object itself is not
* modified!
*
* Sample code:
* <code>
* var size = new Size(-5, 10);
* var absSize = size.abs();
* print(absSize); // { width: 5.0, height: 10.0 }
* </code>
*/
public Size abs() {
return new Size(Math.abs(width), Math.abs(height));
}
/**
* Returns a new size object with the smallest {@link #width} and
* {@link #height} of the supplied sizes.
*
* Sample code:
* <code>
* var size1 = new Size(10, 100);
* var size2 = new Size(200, 5);
* var minSize = Size.min(size1, size2);
* print(minSize); // { width: 10.0, height: 5.0 }
* </code>
*
* @param size1
* @param size2
* @return The newly created size object
*/
public static Size min(Size size1, Size size2) {
return new Size(
Math.min(size1.width, size2.width),
Math.min(size1.height, size2.height));
}
/**
* Returns a new size object with the largest {@link #width} and
* {@link #height} of the supplied sizes.
*
* Sample code:
* <code>
* var size1 = new Size(10, 100);
* var size2 = new Size(200, 5);
* var maxSize = Size.max(size1, size2);
* print(maxSize); // { width: 200.0, height: 100.0 }
* </code>
*
* @param size1
* @param size2
* @return The newly created size object
*/
public static Size max(Size size1, Size size2) {
return new Size(
Math.max(size1.width, size2.width),
Math.max(size1.height, size2.height));
}
/**
* Returns a size object with random {@link #width} and {@link #height}
* values between {@code 0} and {@code 1}.
*
* Sample code:
* <code>
* var maxSize = new Size(100, 100);
* var randomSize = Size.random();
* var size = maxSize * randomSize;
* </code>
*/
public static Size random() {
return new Size(Math.random(), Math.random());
}
public String toString() {
return "{ width: " + ScriptographerEngine.numberFormat.format(width)
+ ", height: " + ScriptographerEngine.numberFormat.format(height)
+ " }";
}
}