mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-10 22:01:52 +09:00
Former-commit-id: 1647fa32ef6894bd7db44f741f07c2f4dcdf9054 Former-commit-id: 0e5810dcfbe1fd59b13e7cabe9f1e93c5542da2d
290 lines
6.4 KiB
Java
290 lines
6.4 KiB
Java
package org.newdawn.slick.svg;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import org.newdawn.slick.Color;
|
|
import org.newdawn.slick.Image;
|
|
import org.newdawn.slick.ImageBuffer;
|
|
import org.newdawn.slick.geom.Transform;
|
|
|
|
/**
|
|
* A gradient definition from an SVG file, includes the stops, name and transform.
|
|
*
|
|
* @author kevin
|
|
*/
|
|
public class Gradient {
|
|
/** The name/id given to the gradient */
|
|
private String name;
|
|
/** The steps in colour of the gradient */
|
|
private ArrayList steps = new ArrayList();
|
|
/** The first x coordiante given in the gradient (cx in radial) */
|
|
private float x1;
|
|
/** The second x coordiante given in the gradient (fx in radial) */
|
|
private float x2;
|
|
/** The first y coordiante given in the gradient (cy in radial) */
|
|
private float y1;
|
|
/** The first y coordiante given in the gradient (fy in radial) */
|
|
private float y2;
|
|
/** The radius given if any */
|
|
private float r;
|
|
/** The texture representing this gradient */
|
|
private Image image;
|
|
/** True if this gradient is radial in nature */
|
|
private boolean radial;
|
|
/** The transform specified for the gradient */
|
|
private Transform transform;
|
|
/** The name of the referenced gradient */
|
|
private String ref;
|
|
|
|
/**
|
|
* Create a new gradient definition
|
|
*
|
|
* @param name The name of the gradient
|
|
* @param radial True if the gradient is radial
|
|
*/
|
|
public Gradient(String name, boolean radial) {
|
|
this.name = name;
|
|
this.radial = radial;
|
|
}
|
|
|
|
/**
|
|
* Check if the gradient is radial
|
|
*
|
|
* @return True if the gradient is radial
|
|
*/
|
|
public boolean isRadial() {
|
|
return radial;
|
|
}
|
|
|
|
/**
|
|
* Set the transform given for this definition
|
|
*
|
|
* @param trans The transform given for this definition
|
|
*/
|
|
public void setTransform(Transform trans) {
|
|
this.transform = trans;
|
|
}
|
|
|
|
/**
|
|
* Get the transform to apply during this gradient application
|
|
*
|
|
* @return The transform given for this gradient
|
|
*/
|
|
public Transform getTransform() {
|
|
return transform;
|
|
}
|
|
|
|
/**
|
|
* Reference another gradient, i.e. use it's colour stops
|
|
*
|
|
* @param ref The name of the other gradient to reference
|
|
*/
|
|
public void reference(String ref) {
|
|
this.ref = ref;
|
|
}
|
|
|
|
/**
|
|
* Resolve the gradient reference
|
|
*
|
|
* @param diagram The diagram to resolve against
|
|
*/
|
|
public void resolve(Diagram diagram) {
|
|
if (ref == null) {
|
|
return;
|
|
}
|
|
|
|
Gradient other = diagram.getGradient(ref);
|
|
|
|
for (int i=0;i<other.steps.size();i++) {
|
|
steps.add(other.steps.get(i));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate the image used for texturing the gradient across shapes
|
|
*/
|
|
public void genImage() {
|
|
if (image == null) {
|
|
ImageBuffer buffer = new ImageBuffer(128,16);
|
|
for (int i=0;i<128;i++) {
|
|
Color col = getColorAt(i / 128.0f);
|
|
for (int j=0;j<16;j++) {
|
|
buffer.setRGBA(i, j, col.getRedByte(), col.getGreenByte(), col.getBlueByte(), col.getAlphaByte());
|
|
}
|
|
}
|
|
image = buffer.getImage();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the image generated for this gradient
|
|
*
|
|
* @return The image generated for the gradient
|
|
*/
|
|
public Image getImage() {
|
|
genImage();
|
|
|
|
return image;
|
|
}
|
|
|
|
/**
|
|
* Set the radius given in the SVG
|
|
*
|
|
* @param r The radius for radial gradients
|
|
*/
|
|
public void setR(float r) {
|
|
this.r = r;
|
|
}
|
|
|
|
/**
|
|
* Set the first x value given for the gradient (cx in the case of radial)
|
|
*
|
|
* @param x1 The first x value given for the gradient
|
|
*/
|
|
public void setX1(float x1) {
|
|
this.x1 = x1;
|
|
}
|
|
|
|
/**
|
|
* Set the second x value given for the gradient (fx in the case of radial)
|
|
*
|
|
* @param x2 The second x value given for the gradient
|
|
*/
|
|
public void setX2(float x2) {
|
|
this.x2 = x2;
|
|
}
|
|
|
|
/**
|
|
* Set the first y value given for the gradient (cy in the case of radial)
|
|
*
|
|
* @param y1 The first y value given for the gradient
|
|
*/
|
|
public void setY1(float y1) {
|
|
this.y1 = y1;
|
|
}
|
|
|
|
/**
|
|
* Set the second y value given for the gradient (fy in the case of radial)
|
|
*
|
|
* @param y2 The second y value given for the gradient
|
|
*/
|
|
public void setY2(float y2) {
|
|
this.y2 = y2;
|
|
}
|
|
|
|
/**
|
|
* Get the radius value given for this gradient
|
|
*
|
|
* @return The radius value given for this gradient
|
|
*/
|
|
public float getR() {
|
|
return r;
|
|
}
|
|
|
|
/**
|
|
* Get the first x value given for this gradient (cx in the case of radial)
|
|
*
|
|
* @return The first x value given for this gradient
|
|
*/
|
|
public float getX1() {
|
|
return x1;
|
|
}
|
|
|
|
/**
|
|
* Get the second x value given for this gradient (fx in the case of radial)
|
|
*
|
|
* @return The second x value given for this gradient
|
|
*/
|
|
public float getX2() {
|
|
return x2;
|
|
}
|
|
|
|
/**
|
|
* Get the first y value given for this gradient (cy in the case of radial)
|
|
*
|
|
* @return The first y value given for this gradient
|
|
*/
|
|
public float getY1() {
|
|
return y1;
|
|
}
|
|
|
|
/**
|
|
* Get the second y value given for this gradient (fy in the case of radial)
|
|
*
|
|
* @return The second y value given for this gradient
|
|
*/
|
|
public float getY2() {
|
|
return y2;
|
|
}
|
|
|
|
/**
|
|
* Add a colour step/stop to the gradient
|
|
*
|
|
* @param location The location on the gradient the colour affects
|
|
* @param c The color to apply
|
|
*/
|
|
public void addStep(float location, Color c) {
|
|
steps.add(new Step(location, c));
|
|
}
|
|
|
|
/**
|
|
* Get the intepolated colour at the given location on the gradient
|
|
*
|
|
* @param p The point of the gradient (0 >= n >= 1)
|
|
* @return The interpolated colour at the given location
|
|
*/
|
|
public Color getColorAt(float p) {
|
|
if (p <= 0) {
|
|
return ((Step) steps.get(0)).col;
|
|
}
|
|
if (p > 1) {
|
|
return ((Step) steps.get(steps.size()-1)).col;
|
|
}
|
|
|
|
for (int i=1;i<steps.size();i++) {
|
|
Step prev = ((Step) steps.get(i-1));
|
|
Step current = ((Step) steps.get(i));
|
|
|
|
if (p <= current.location) {
|
|
float dis = current.location - prev.location;
|
|
p -= prev.location;
|
|
float v = p / dis;
|
|
|
|
Color c = new Color(1,1,1,1);
|
|
c.a = (prev.col.a * (1 - v)) + (current.col.a * (v));
|
|
c.r = (prev.col.r * (1 - v)) + (current.col.r * (v));
|
|
c.g = (prev.col.g * (1 - v)) + (current.col.g * (v));
|
|
c.b = (prev.col.b * (1 - v)) + (current.col.b * (v));
|
|
|
|
return c;
|
|
}
|
|
}
|
|
|
|
// shouldn't ever happen
|
|
return Color.black;
|
|
}
|
|
|
|
/**
|
|
* The description of a single step on the gradient
|
|
*
|
|
* @author kevin
|
|
*/
|
|
private class Step {
|
|
/** The location on the gradient */
|
|
float location;
|
|
/** The colour applied */
|
|
Color col;
|
|
|
|
/**
|
|
* Create a new step
|
|
*
|
|
* @param location The location on the gradient the colour affects
|
|
* @param c The colour to apply
|
|
*/
|
|
public Step(float location, Color c) {
|
|
this.location = location;
|
|
this.col = c;
|
|
}
|
|
}
|
|
}
|