/*
* 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 Oct 18, 2006.
*/
package com.scriptographer.ai;
/**
* @author lehni
*/
public class GradientColor extends Color {
Gradient gradient;
Point origin;
Point destination;
/*
* For radial gradients only
*/
Point hilite;
/*
* The accumulated transformations of the gradient. It is not necessarily
* the same as the transformation matrix of the object containing the
* gradient. When a gradient is first applied to an object, the value is set
* to the identity matrix. When the user transforms the object, the user
* transformation matrix is concatenated to the gradient instance's matrix.
*/
Matrix matrix;
/**
* Called from the native environment
*/
protected GradientColor(int gradientHandle, Point origin, double angle,
double length, Matrix matrix, double hiliteAngle, double hiliteLength) {
gradient = Gradient.wrapHandle(gradientHandle, null);
this.origin = origin;
angle = angle * Math.PI / 180.0;
destination = new Point(
origin.x + Math.cos(angle) * length,
origin.y + Math.sin(angle) * length
);
// Hilite angle is relative to gradient angle
hiliteAngle = angle + hiliteAngle * Math.PI / 180.0;
// Hilite length is a factor of the total length.
// See #set
hiliteLength *= length;
hilite = new Point(
origin.x + Math.cos(hiliteAngle) * hiliteLength,
origin.y + Math.sin(hiliteAngle) * hiliteLength
);
this.matrix = matrix;
}
/**
* Creates a GradientColor object.
*
* Sample code:
* <code>
* // a radial gradient from white to black
* var gradient = new Gradient() {
* type: 'radial',
* stops: [
* new GradientStop(new GrayColor(0), 0),
* new GradientStop(new GrayColor(1), 1)
* ]
* };
*
* var origin = new Point(0, 0);
* var destination = new Point(0, 100);
* var gradientColor = new GradientColor(gradient, origin, destination);
*
* // create a circle filled with the gradient color
* var circle = new Path.Circle(new Point(0, 0), 100) {
* fillColor: gradientColor
* };
* </code>
*
* @param gradient the gradient
* @param origin the origin point
* @param destination the destination point
* @param hilite the hilite point (only for radial gradients)
* @param matrix the tranformation matrix
*/
public GradientColor(Gradient gradient, Point origin, Point destination,
Point hilite, Matrix matrix) {
this.gradient = gradient;
this.origin = new Point(origin);
this.destination = new Point(destination);
this.hilite = new Point(hilite != null ? hilite : origin);
this.matrix = new Matrix(matrix);
}
public GradientColor(Gradient gradient, Point origin, Point destination,
Point hilite) {
this(gradient, origin, destination, hilite, null);
}
public GradientColor(Gradient gradient, Point origin, Point destination) {
this(gradient, origin, destination, null);
}
/**
* Called from the native environment, to fill a native struct. This is the
* opposite of the above constructor that 's called from the native side
* only.
*
* @param struct
*/
protected void set(int pointer) {
// Convert to relative vectors
Point destination = this.destination.subtract(origin);
Point hilite = this.hilite.subtract(origin);
// Calculating hilite is a bit tricky: It's length is a factor
// of the total length of the gradient, between 0 and 1, and its
// angle is relative to the gradient's angle. This does the trick:
double length = destination.getLength();
double angle = destination.getAngleInDegrees();
// Divide by length to scale to range between 0 and 1:
double hiliteLength = hilite.getLength() / length;
// Subtract angle to get absolute angle:
double hiliteAngle = hilite.getAngleInDegrees() - angle;
// Make sure we're not above 1, since that's the maximum allowed value
// for hilite
if (hiliteLength > 1)
hiliteLength = 1;
nativeSetGradient(pointer, gradient.handle, origin, angle, length,
matrix, hiliteAngle, hiliteLength);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof GradientColor) {
GradientColor color = (GradientColor) obj;
return gradient.equals(color.gradient)
&& origin.equals(color.origin)
&& destination.equals(color.destination)
&& hilite.equals(color.hilite);
}
return false;
}
/**
* @jshide
*/
public float[] getComponents() {
throw new UnsupportedOperationException(
"Cannot convert gradient to components");
}
public java.awt.Color toAWTColor() {
throw new UnsupportedOperationException(
"Cannot convert gradient to AWT color");
}
public void setAlpha(Float alpha) {
throw new UnsupportedOperationException(
"Cannot set alpha on gradient");
}
/**
* The origin point of the gradient.
*/
public Point getOrigin() {
return origin;
}
public void setOrigin(Point origin) {
this.origin = new Point(origin);
}
/**
* The destination point of the gradient.
*/
public Point getDestination() {
return destination;
}
public void setDestination(Point destination) {
this.destination = destination;
}
public Gradient getGradient() {
return gradient;
}
public void setGradient(Gradient gradient) {
this.gradient = gradient;
}
/**
* The hilite of the gradient. The hilite is only visible in radial
* gradients and allows you to move the center of the gradient while leaving
* the boundaries of the gradient alone.
*/
public Point getHilite() {
return hilite;
}
public void setHilite(Point hilite) {
this.hilite = hilite;
}
public void set(Color color) {
throw new UnsupportedOperationException();
}
public Matrix getMatrix() {
return matrix;
}
public void setMatrix(Matrix matrix) {
this.matrix = new Matrix(matrix);
}
}