Path: blob/master/SLICK_HOME/src/org/newdawn/slick/svg/Gradient.java
1463 views
package org.newdawn.slick.svg;12import java.util.ArrayList;34import org.newdawn.slick.Color;5import org.newdawn.slick.Image;6import org.newdawn.slick.ImageBuffer;7import org.newdawn.slick.geom.Transform;89/**10* A gradient definition from an SVG file, includes the stops, name and transform.11*12* @author kevin13*/14public class Gradient {15/** The name/id given to the gradient */16private String name;17/** The steps in colour of the gradient */18private ArrayList steps = new ArrayList();19/** The first x coordiante given in the gradient (cx in radial) */20private float x1;21/** The second x coordiante given in the gradient (fx in radial) */22private float x2;23/** The first y coordiante given in the gradient (cy in radial) */24private float y1;25/** The first y coordiante given in the gradient (fy in radial) */26private float y2;27/** The radius given if any */28private float r;29/** The texture representing this gradient */30private Image image;31/** True if this gradient is radial in nature */32private boolean radial;33/** The transform specified for the gradient */34private Transform transform;35/** The name of the referenced gradient */36private String ref;3738/**39* Create a new gradient definition40*41* @param name The name of the gradient42* @param radial True if the gradient is radial43*/44public Gradient(String name, boolean radial) {45this.name = name;46this.radial = radial;47}4849/**50* Check if the gradient is radial51*52* @return True if the gradient is radial53*/54public boolean isRadial() {55return radial;56}5758/**59* Set the transform given for this definition60*61* @param trans The transform given for this definition62*/63public void setTransform(Transform trans) {64this.transform = trans;65}6667/**68* Get the transform to apply during this gradient application69*70* @return The transform given for this gradient71*/72public Transform getTransform() {73return transform;74}7576/**77* Reference another gradient, i.e. use it's colour stops78*79* @param ref The name of the other gradient to reference80*/81public void reference(String ref) {82this.ref = ref;83}8485/**86* Resolve the gradient reference87*88* @param diagram The diagram to resolve against89*/90public void resolve(Diagram diagram) {91if (ref == null) {92return;93}9495Gradient other = diagram.getGradient(ref);9697for (int i=0;i<other.steps.size();i++) {98steps.add(other.steps.get(i));99}100}101102/**103* Generate the image used for texturing the gradient across shapes104*/105public void genImage() {106if (image == null) {107ImageBuffer buffer = new ImageBuffer(128,16);108for (int i=0;i<128;i++) {109Color col = getColorAt(i / 128.0f);110for (int j=0;j<16;j++) {111buffer.setRGBA(i, j, col.getRedByte(), col.getGreenByte(), col.getBlueByte(), col.getAlphaByte());112}113}114image = buffer.getImage();115}116}117118/**119* Get the image generated for this gradient120*121* @return The image generated for the gradient122*/123public Image getImage() {124genImage();125126return image;127}128129/**130* Set the radius given in the SVG131*132* @param r The radius for radial gradients133*/134public void setR(float r) {135this.r = r;136}137138/**139* Set the first x value given for the gradient (cx in the case of radial)140*141* @param x1 The first x value given for the gradient142*/143public void setX1(float x1) {144this.x1 = x1;145}146147/**148* Set the second x value given for the gradient (fx in the case of radial)149*150* @param x2 The second x value given for the gradient151*/152public void setX2(float x2) {153this.x2 = x2;154}155156/**157* Set the first y value given for the gradient (cy in the case of radial)158*159* @param y1 The first y value given for the gradient160*/161public void setY1(float y1) {162this.y1 = y1;163}164165/**166* Set the second y value given for the gradient (fy in the case of radial)167*168* @param y2 The second y value given for the gradient169*/170public void setY2(float y2) {171this.y2 = y2;172}173174/**175* Get the radius value given for this gradient176*177* @return The radius value given for this gradient178*/179public float getR() {180return r;181}182183/**184* Get the first x value given for this gradient (cx in the case of radial)185*186* @return The first x value given for this gradient187*/188public float getX1() {189return x1;190}191192/**193* Get the second x value given for this gradient (fx in the case of radial)194*195* @return The second x value given for this gradient196*/197public float getX2() {198return x2;199}200201/**202* Get the first y value given for this gradient (cy in the case of radial)203*204* @return The first y value given for this gradient205*/206public float getY1() {207return y1;208}209210/**211* Get the second y value given for this gradient (fy in the case of radial)212*213* @return The second y value given for this gradient214*/215public float getY2() {216return y2;217}218219/**220* Add a colour step/stop to the gradient221*222* @param location The location on the gradient the colour affects223* @param c The color to apply224*/225public void addStep(float location, Color c) {226steps.add(new Step(location, c));227}228229/**230* Get the intepolated colour at the given location on the gradient231*232* @param p The point of the gradient (0 >= n >= 1)233* @return The interpolated colour at the given location234*/235public Color getColorAt(float p) {236if (p <= 0) {237return ((Step) steps.get(0)).col;238}239if (p > 1) {240return ((Step) steps.get(steps.size()-1)).col;241}242243for (int i=1;i<steps.size();i++) {244Step prev = ((Step) steps.get(i-1));245Step current = ((Step) steps.get(i));246247if (p <= current.location) {248float dis = current.location - prev.location;249p -= prev.location;250float v = p / dis;251252Color c = new Color(1,1,1,1);253c.a = (prev.col.a * (1 - v)) + (current.col.a * (v));254c.r = (prev.col.r * (1 - v)) + (current.col.r * (v));255c.g = (prev.col.g * (1 - v)) + (current.col.g * (v));256c.b = (prev.col.b * (1 - v)) + (current.col.b * (v));257258return c;259}260}261262// shouldn't ever happen263return Color.black;264}265266/**267* The description of a single step on the gradient268*269* @author kevin270*/271private class Step {272/** The location on the gradient */273float location;274/** The colour applied */275Color col;276277/**278* Create a new step279*280* @param location The location on the gradient the colour affects281* @param c The colour to apply282*/283public Step(float location, Color c) {284this.location = location;285this.col = c;286}287}288}289290291