mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-14 07:47:12 -06:00
UIDefaultsLoader: added contrast() color function (inspired by Less CSS), which is useful to choose a foreground color that is readable, based on the luma (perceptual brightness) of a background color
This commit is contained in:
@@ -611,6 +611,7 @@ class UIDefaultsLoader
|
||||
case "mix": return parseColorMix( null, params, resolver, reportError );
|
||||
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
||||
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
||||
case "contrast": return parseColorContrast( params, resolver, reportError );
|
||||
}
|
||||
} finally {
|
||||
parseColorDepth--;
|
||||
@@ -804,14 +805,10 @@ class UIDefaultsLoader
|
||||
if( color1Str == null )
|
||||
color1Str = params.get( i++ );
|
||||
String color2Str = params.get( i++ );
|
||||
int weight = 50;
|
||||
|
||||
if( params.size() > i )
|
||||
weight = parsePercentage( params.get( i++ ) );
|
||||
int weight = (params.size() > i) ? parsePercentage( params.get( i ) ) : 50;
|
||||
|
||||
// parse second color
|
||||
String resolvedColor2Str = resolver.apply( color2Str );
|
||||
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolvedColor2Str, resolver, reportError );
|
||||
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolver.apply( color2Str ), resolver, reportError );
|
||||
if( color2 == null )
|
||||
return null;
|
||||
|
||||
@@ -822,6 +819,34 @@ class UIDefaultsLoader
|
||||
return parseFunctionBaseColor( color1Str, function, false, resolver, reportError );
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: contrast(color,dark,light[,threshold])
|
||||
* - color: a color to compare against
|
||||
* - dark: a designated dark color (e.g. #000) or a color function
|
||||
* - light: a designated light color (e.g. #fff) or a color function
|
||||
* - threshold: the threshold (in range 0-100%) to specify where the transition
|
||||
* from "dark" to "light" is (default is 43%)
|
||||
*/
|
||||
private static Object parseColorContrast( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
||||
String colorStr = params.get( 0 );
|
||||
String darkStr = params.get( 1 );
|
||||
String lightStr = params.get( 2 );
|
||||
int threshold = (params.size() > 3) ? parsePercentage( params.get( 3 ) ) : 43;
|
||||
|
||||
// parse color to compare against
|
||||
ColorUIResource color = (ColorUIResource) parseColorOrFunction( resolver.apply( colorStr ), resolver, reportError );
|
||||
if( color == null )
|
||||
return null;
|
||||
|
||||
// check luma and determine whether to use dark or light color
|
||||
String darkOrLightColor = (ColorFunctions.luma( color ) * 100 < threshold)
|
||||
? lightStr
|
||||
: darkStr;
|
||||
|
||||
// parse dark or light color
|
||||
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
||||
}
|
||||
|
||||
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
||||
boolean derived, Function<String, String> resolver, boolean reportError )
|
||||
{
|
||||
|
||||
@@ -79,6 +79,34 @@ public class ColorFunctions
|
||||
Math.round( a2 + ((a1 - a2) * weight) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the luma (perceptual brightness) of the given color.
|
||||
* <p>
|
||||
* Uses SMPTE C / Rec. 709 coefficients, as recommended in
|
||||
* <a href="https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef">WCAG 2.0</a>.
|
||||
*
|
||||
* @param color a color
|
||||
* @return the luma (in range 0-1)
|
||||
*
|
||||
* @see <a href="https://en.wikipedia.org/wiki/Luma_(video)">https://en.wikipedia.org/wiki/Luma_(video)</a>
|
||||
* @since 1.6
|
||||
*/
|
||||
public static float luma( Color color ) {
|
||||
// see https://en.wikipedia.org/wiki/Luma_(video)
|
||||
// see https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
// see https://github.com/less/less.js/blob/master/packages/less/src/less/tree/color.js
|
||||
float r = gammaCorrection( color.getRed() / 255f );
|
||||
float g = gammaCorrection( color.getGreen() / 255f );
|
||||
float b = gammaCorrection( color.getBlue() / 255f );
|
||||
return (0.2126f * r) + (0.7152f * g) + (0.0722f * b);
|
||||
}
|
||||
|
||||
private static float gammaCorrection( float value ) {
|
||||
return (value <= 0.03928f)
|
||||
? value / 12.92f
|
||||
: (float) Math.pow( (value + 0.055) / 1.055, 2.4 );
|
||||
}
|
||||
|
||||
//---- interface ColorFunction --------------------------------------------
|
||||
|
||||
public interface ColorFunction {
|
||||
|
||||
Reference in New Issue
Block a user