All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mathiewz.slick.svg.Gradient Maven / Gradle / Ivy

Go to download

The main purpose of this libraryis to modernize and maintain the slick2D library.

The newest version!
package com.github.mathiewz.slick.svg;

import java.util.ArrayList;

import com.github.mathiewz.slick.Color;
import com.github.mathiewz.slick.Image;
import com.github.mathiewz.slick.ImageBuffer;
import com.github.mathiewz.slick.geom.Transform;

/**
 * A gradient definition from an SVG file, includes the stops, name and transform.
 *
 * @author kevin
 */
public class Gradient {
    /** The steps in colour of the gradient */
    private final 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 final 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.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) {
        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 steps.get(0).col;
        }
        if (p > 1) {
            return steps.get(steps.size() - 1).col;
        }
        
        for (int i = 1; i < steps.size(); i++) {
            Step prev = steps.get(i - 1);
            Step current = 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;
            col = c;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy