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

cz.vutbr.web.csskit.fn.GenericRadialGradient Maven / Gradle / Ivy

Go to download

jStyleParser is a CSS parser written in Java. It has its own application interface that is designed to allow an efficient CSS processing in Java and mapping the values to the Java data types. It parses CSS 2.1 style sheets into structures that can be efficiently assigned to DOM elements. It is intended be the primary CSS parser for the CSSBox library. While handling errors, it is user agent conforming according to the CSS specification.

The newest version!
/**
 * GenericRadialGradient.java
 *
 * Created on 17. 5. 2018, 13:14:05 by burgetr
 */
package cz.vutbr.web.csskit.fn;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import cz.vutbr.web.css.CSSFactory;
import cz.vutbr.web.css.Term;
import cz.vutbr.web.css.TermFactory;
import cz.vutbr.web.css.TermIdent;
import cz.vutbr.web.css.TermLength;
import cz.vutbr.web.css.TermLengthOrPercent;
import cz.vutbr.web.css.TermList;
import cz.vutbr.web.css.TermPercent;

/**
 * Base class for both the radial and repating-radial gradient implementations.
 * 
 * @author burgetr
 */
public class GenericRadialGradient extends GenericGradient {
    
    //default property values
    private static final TermPercent DEFAULT_POSITION = CSSFactory.getTermFactory().createPercent(50.0f);
    private static final TermIdent DEFAULT_SHAPE = CSSFactory.getTermFactory().createIdent("ellipse");
    private static final TermIdent CIRCLE_SHAPE = CSSFactory.getTermFactory().createIdent("circle");
    private static final TermIdent DEFAULT_SIZE = CSSFactory.getTermFactory().createIdent("farthest-corner");
    
    private TermIdent shape;
    private TermLengthOrPercent[] size;
    private TermIdent sizeIdent;
    private TermLengthOrPercent[] position;
    
    public TermIdent getShape() {
        return shape;
    }
    
    public TermLengthOrPercent[] getSize() {
        return size;
    }

    public TermIdent getSizeIdent() {
        return sizeIdent;
    }

    public TermLengthOrPercent[] getPosition() {
        return position;
    }

    public TermList setValue(List> value) {
        super.setValue(value);
        List>> args = getSeparatedArgs(DEFAULT_ARG_SEP);
        if (args.size() > 1) {
            int firstStop = 0;
            //check for shape and size
            if (decodeShape(args.get(0))) {
                firstStop = 1;
            } else { //no shape info provided, use defaults
                sizeIdent = DEFAULT_SIZE;
                shape = DEFAULT_SHAPE;
                position = new TermLengthOrPercent[2];
                position[0] = position[1] = DEFAULT_POSITION;
            }
            //check for stops
            loadColorStops(args, firstStop);
            if (getColorStops() != null)
                setValid(true);
        }
        return this;
    }

    private boolean decodeShape(List> arglist) {
        List> args = new ArrayList<>(arglist);
        //determine the 'at' position
        int atpos = -1;
        for (int i = 0; i < args.size(); i++) {
            Term arg = args.get(i);
            if (arg instanceof TermIdent && ((TermIdent) arg).getValue().equalsIgnoreCase("at")) {
                atpos = i;
                break;
            }
        }
        if (atpos != -1) {
            List> posList = args.subList(atpos + 1, args.size());
            if (!decodePosition(posList))
                return false;
            args = args.subList(0, atpos);
        } else { //no position, use the default (center)
            position = new TermLengthOrPercent[2];
            position[0] = position[1] = DEFAULT_POSITION;
        }
        //determine the shape
        boolean isCircle = false;
        for (Iterator> it = args.iterator(); it.hasNext();)
        {
            Term arg = it.next();
            String idval = (arg instanceof TermIdent) ? ((TermIdent) arg).getValue() : null;
            if (idval != null && (idval.equalsIgnoreCase("circle") || idval.equalsIgnoreCase("ellipse"))) {
                shape = (TermIdent) arg;
                isCircle = idval.equalsIgnoreCase("circle");
                it.remove();
                break;
            }
        }
        //determine the size
        if (shape == null) { //shape not given
            if (args.size() == 0) {
                sizeIdent = DEFAULT_SIZE;
                shape = DEFAULT_SHAPE;
            } else if (args.size() == 1) {
                Term arg = args.get(0);
                if (isExtentKeyword(arg)) {
                    sizeIdent = (TermIdent) arg;
                    shape = DEFAULT_SHAPE; //see https://drafts.csswg.org/css-images-3/#radial-gradients
                } else if (arg instanceof TermLength) {
                    size = new TermLengthOrPercent[1];
                    size[0] = (TermLength) arg;
                    shape = CIRCLE_SHAPE;
                } else {
                    return false;
                }
            } else if (args.size() == 2) {
                size = new TermLengthOrPercent[2];
                int i = 0;
                for (Term arg : args) {
                    if (arg instanceof TermLengthOrPercent) {
                        size[i++] = (TermLengthOrPercent) arg;
                    } else {
                        size = null;
                        return false;
                    }
                }
                shape = DEFAULT_SHAPE;
            } else {
                return false;
            }
        } else if (!isCircle) { //ellipse
            if (args.size() == 0) {
                sizeIdent = DEFAULT_SIZE;
            } else if (args.size() == 1) {
                Term arg = args.get(0);
                if (isExtentKeyword(arg)) {
                    sizeIdent = (TermIdent) arg;
                } else {
                    return false;
                }
            } else if (args.size() == 2) {
                size = new TermLengthOrPercent[2];
                int i = 0;
                for (Term arg : args) {
                    if (arg instanceof TermLengthOrPercent) {
                        size[i++] = (TermLengthOrPercent) arg;
                    } else {
                        size = null;
                        return false;
                    }
                }
            } else {
                return false;
            }
        } else { //circle
            if (args.size() == 0) {
                sizeIdent = DEFAULT_SIZE;
            } else if (args.size() == 1) {
                Term arg = args.get(0);
                if (isExtentKeyword(arg)) {
                    sizeIdent = (TermIdent) arg;
                } else if (arg instanceof TermLength) {
                    size = new TermLengthOrPercent[1];
                    size[0] = (TermLength) arg;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
        //parsed ok
        return true;
    }
    
    private boolean decodePosition(List> arglist) {
        if (arglist.size() == 1 || arglist.size() == 2) {
            
            position = new TermLengthOrPercent[2];
            //distribute terms to position
            for (Term term : arglist) {
                if (term instanceof TermIdent || term instanceof TermLengthOrPercent) {
                    storeBackgroundPosition(position, term);
                } else {
                    return false;
                }
            }
            //check validity
            int assigned = 0;
            int valid = 0;
            for (int i = 0; i < 2; i++) {
                if (position[i] == null) {
                    position[i] = DEFAULT_POSITION;
                    valid++;
                } else if (position[i] instanceof TermLengthOrPercent) {
                    assigned++;
                    valid++;
                }
            }
            return (assigned > 0 && valid == 2);
            
        } else {
            return false;
        }
    }
    
    private void storeBackgroundPosition(Term[] storage, Term term) {
        
        if (term instanceof TermIdent) {
            String idval = ((TermIdent) term).getValue();
            TermFactory tf = CSSFactory.getTermFactory();
            if (idval.equalsIgnoreCase("left"))
                setPositionValue(storage, 0, tf.createPercent(0.0f));
            else if (idval.equalsIgnoreCase("right"))
                setPositionValue(storage, 0, tf.createPercent(100.0f));
            else if (idval.equalsIgnoreCase("top"))
                setPositionValue(storage, 1, tf.createPercent(0.0f));
            else if (idval.equalsIgnoreCase("bottom"))
                setPositionValue(storage, 1, tf.createPercent(100.0f));
            else if (idval.equalsIgnoreCase("center"))
                setPositionValue(storage, -1, tf.createPercent(50.0f));
        }
        else
            setPositionValue(storage, -1, term);
    }
    
    private void setPositionValue(Term[] s, int index, Term term) {
        switch (index) {
            case -1: if (s[0] == null) //any position - use the free position
                         s[0] = term;
                     else
                         s[1] = term;
                     break;
            case 0: if (s[0] != null) //if the position is occupied, move the old value
                        s[1] = s[0];
                    s[0] = term;
                    break;
            case 1: if (s[1] != null)
                        s[0] = s[1];
                    s[1] = term;
                    break;
        }
    }
    
    private boolean isExtentKeyword(Term term) {
        if (term instanceof TermIdent) {
            switch (((TermIdent) term).getValue()) {
                case "closest-corner":
                case "closest-side":
                case "farthest-corner":
                case "farthest-side":
                    return true;
                default:
                    return false;
            }
        } else {
            return false;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy