cz.vutbr.web.csskit.fn.GenericRadialGradient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jstyleparser Show documentation
Show all versions of jstyleparser Show documentation
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