Skip to content

Commit

Permalink
[GEOT-5713] Add support for lesscss color operation functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aaime committed Apr 23, 2017
1 parent f77c5c1 commit bc8d6aa
Show file tree
Hide file tree
Showing 23 changed files with 1,290 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,55 @@ private void validateArguments() throws IllegalArgumentException {
}
}
}

/**
* Evaluates a specific argument against the context, checking for required values and
* proper conversion.
*
* @param object
* @param argumentIndex
* @return
*/
protected Object getParameterValue(Object object, int argumentIndex) {
Parameter<?> parameter = getFunctionName().getArguments().get(argumentIndex);
if (params.size() <= argumentIndex) {
if (parameter.getMinOccurs() == 0) {
return null;
} else {
throw new IllegalArgumentException(
String.format("No arguments specified for arg " + "%s, minOccurs = %d",
parameter.getName().toString(), parameter.getMinOccurs()));
}
}

final Expression expression = params.get(argumentIndex);
Object value = expression.evaluate(object, parameter.getType());
if (value == null && expression.evaluate(object) != null) {
throw new IllegalArgumentException(String.format(
"Failure converting value for "
+ "argument %s. %s could not be converted to %s",
parameter.getName(), expression.toString(), parameter.getType().getName()));
}
return value;
}

/**
* Evaluates a specific argument against the context, checking for required values and
* proper conversion. This version accepts a default value
*
* @param object
* @param argumentIndex
* @param defaultValue
* @return
*/
protected Object getParameterValue(Object object, int argumentIndex, Object defaultValue) {
Object value = getParameterValue(object, argumentIndex);
if(value == null) {
return defaultValue;
} else {
return value;
}
}

/**
* Gathers up and groups the parameters to the function based on the declared parameters.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2017, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.filter.function.color;

import static org.geotools.filter.capability.FunctionNameImpl.parameter;

import java.awt.Color;

import org.geotools.filter.FunctionImpl;
import org.geotools.filter.capability.FunctionNameImpl;
import org.opengis.filter.capability.FunctionName;

/**
* Base for lesscss.org HSL color manipulation functions
*
* @author Andrea Aime - GeoSolutions
*/
public abstract class AbstractHSLFunction extends FunctionImpl {

enum Method {
absolute, relative
};

public static FunctionName NAME = new FunctionNameImpl("abstractHSL",
parameter("result", Color.class), parameter("color", Color.class),
parameter("amount", Float.class), parameter("method", Method.class, 0, 1));

public AbstractHSLFunction(String name) {
this.functionName = new FunctionNameImpl(name, NAME.getReturn(), NAME.getArguments());
}

@Override
public Object evaluate(Object object) {
Color source = (Color) getParameterValue(object, 0);
float amount = (Float) getParameterValue(object, 1);
Method method = (Method) getParameterValue(object, 2, Method.absolute);

HSLColor hsl = new HSLColor(source);
if (method == Method.absolute) {
adjustAbsolute(amount, hsl);
} else {
adjstRelative(amount, hsl);
}

return hsl.toRGB();
}

protected abstract void adjstRelative(float amount, HSLColor hsl);

protected abstract void adjustAbsolute(float amount, HSLColor hsl);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2017, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.filter.function.color;

import static org.geotools.filter.capability.FunctionNameImpl.parameter;

import java.awt.Color;

import org.geotools.filter.FunctionImpl;
import org.geotools.filter.capability.FunctionNameImpl;
import org.opengis.filter.capability.FunctionName;

/**
* Contrast lesscss.org color function. Returns the color with highest contrast with a given reference
*
* @author Andrea Aime - GeoSolutions
*/
public class ConstrastFunction extends FunctionImpl {

public static FunctionName NAME = new FunctionNameImpl("contrast",
parameter("result", Color.class), parameter("reference", Color.class),
parameter("color1", Color.class, 0, 1), parameter("color2", Color.class, 0, 1),
parameter("threshold", Double.class, 0, 1));

public ConstrastFunction() {
this.functionName = NAME;
}

@Override
public Object evaluate(Object object) {
Color reference = (Color) getParameterValue(object, 0);
Color color1 = (Color) getParameterValue(object, 1, Color.BLACK);
Color color2 = (Color) getParameterValue(object, 2, Color.WHITE);
double threshold = (Double) getParameterValue(object, 3, 0.43);

double luma1 = luma(color1);
double luma2 = luma(color2);
Color light, dark;
if (luma1 > luma2) {
light = color1;
dark = color2;
} else {
light = color2;
dark = color1;
}

if (luma(reference) < threshold) {
return light;
} else {
return dark;
}
}

private double luma(Color color) {
double r = color.getRed() / 255d;
double g = color.getGreen() / 255d;
double b = color.getBlue() / 255d;

r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);

return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2017, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.filter.function.color;

/**
* Implements the lesscss.org darken function
*
* @author Andrea Aime - GeoSolutions
*/
public class DarkenFunction extends AbstractHSLFunction {

public DarkenFunction() {
super("darken");
}

protected void adjstRelative(float amount, HSLColor hsl) {
hsl.setLightness(hsl.getLightness() * (1 - amount));
}

protected void adjustAbsolute(float amount, HSLColor hsl) {
hsl.setLightness(hsl.getLightness() - amount);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2017, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.filter.function.color;

/**
* Implements the lesscss.org desaturate function
*
* @author Andrea Aime - GeoSolutions
*/
public class DesaturateFunction extends AbstractHSLFunction {

public DesaturateFunction() {
super("desaturate");
}

protected void adjstRelative(float amount, HSLColor hsl) {
hsl.setSaturation(hsl.getSaturation() * (1 - amount));
}

protected void adjustAbsolute(float amount, HSLColor hsl) {
hsl.setSaturation(hsl.getSaturation() - amount);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2017, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.filter.function.color;

import static org.geotools.filter.capability.FunctionNameImpl.parameter;

import java.awt.Color;

import org.geotools.filter.FunctionImpl;
import org.geotools.filter.capability.FunctionNameImpl;
import org.opengis.filter.capability.FunctionName;

/**
* Tint lesscss.org color function. Takes one colors and mixes it with white based on a weight (and their eventual alpha)
*
* @author Andrea Aime - GeoSolutions
*/
public class GrayscaleFunction extends FunctionImpl {

public static FunctionName NAME = new FunctionNameImpl("grayscale",
parameter("result", Color.class), parameter("color", Color.class));

public GrayscaleFunction() {
this.functionName = NAME;
}

@Override
public Object evaluate(Object object) {
Color color = (Color) getParameterValue(object, 0);

HSLColor hsl = new HSLColor(color);
hsl.setSaturation(0);
return hsl.toRGB();
}

}

0 comments on commit bc8d6aa

Please sign in to comment.