X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Futil%2FColorUtils.java;h=16ff25927b4e0dafa19e35be927cd774e6393d4a;hb=37651a9d177de05ff938276071c16ba95ac44c73;hp=d7829dfdc01507e022ea430ab57c59cb033b0559;hpb=136c0793b90b72b928c4d77dc109dd5c644e00d3;p=jalview.git diff --git a/src/jalview/util/ColorUtils.java b/src/jalview/util/ColorUtils.java index d7829df..16ff259 100644 --- a/src/jalview/util/ColorUtils.java +++ b/src/jalview/util/ColorUtils.java @@ -25,10 +25,20 @@ package jalview.util; import java.awt.Color; +import java.util.HashMap; +import java.util.Map; import java.util.Random; public class ColorUtils { + // constant borrowed from java.awt.Color + private static final float FACTOR = 0.7f; + + private static final int MAX_CACHE_SIZE = 1729; + /* + * a cache for colours generated from text strings + */ + static Map myColours = new HashMap<>(); /** * Generates a random color, will mix with input color. Code taken from @@ -134,12 +144,12 @@ public class ColorUtils * prop = proportion of the way value is from minValue to maxValue */ float prop = (value - minValue) / (maxValue - minValue); - float r = minColour.getRed() + prop - * (maxColour.getRed() - minColour.getRed()); - float g = minColour.getGreen() + prop - * (maxColour.getGreen() - minColour.getGreen()); - float b = minColour.getBlue() + prop - * (maxColour.getBlue() - minColour.getBlue()); + float r = minColour.getRed() + + prop * (maxColour.getRed() - minColour.getRed()); + float g = minColour.getGreen() + + prop * (maxColour.getGreen() - minColour.getGreen()); + float b = minColour.getBlue() + + prop * (maxColour.getBlue() - minColour.getBlue()); return new Color(r / 255, g / 255, b / 255); } @@ -210,7 +220,7 @@ public class ColorUtils return null; } colour = colour.trim(); - + Color col = null; try { @@ -219,12 +229,12 @@ public class ColorUtils } catch (NumberFormatException ex) { } - + if (col == null) { col = ColorUtils.getAWTColorFromName(colour); } - + if (col == null) { try @@ -242,7 +252,7 @@ public class ColorUtils // non-numeric token or out of 0-255 range } } - + return col; } @@ -260,35 +270,46 @@ public class ColorUtils { return Color.white; } + if (myColours.containsKey(name)) + { + return myColours.get(name); + } int lsize = name.length(); int start = 0; int end = lsize / 3; - + int rgbOffset = Math.abs(name.hashCode() % 10) * 15; // 0-135 - + /* * red: first third */ - int r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20; + int r = Math.abs(name.substring(start, end).hashCode() + rgbOffset) + % 210 + 20; start = end; end += lsize / 3; if (end > lsize) { end = lsize; } - + /* * green: second third */ - int g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) % 210 + 20; - + int g = Math.abs(name.substring(start, end).hashCode() + rgbOffset) + % 210 + 20; + /* * blue: third third */ int b = Math.abs(name.substring(end).hashCode() + rgbOffset) % 210 + 20; - + Color color = new Color(r, g, b); - + + if (myColours.size() < MAX_CACHE_SIZE) + { + myColours.put(name, color); + } + return color; } @@ -307,7 +328,7 @@ public class ColorUtils } Color col = null; name = name.toLowerCase(); - + // or make a static map; or use reflection on the field name switch (name) { @@ -351,7 +372,66 @@ public class ColorUtils col = Color.yellow; break; } - + return col; } + + /** + * Generates a colour that is interpolated between + * colour.darker() and colour.brighter() in + * proportion as value is between min and + * max. Note that the 'neutral point' (unchanged colour) is + * closer to 'brighter' than to 'darker'as this is a geometric range. + * + * @param value + * @param min + * @param max + * @param colour + * @return + */ + public static Color getGraduatedColour(float value, float min, float max, + Color colour) + { + /* + * this computes the equivalent of + * getGraduatedColour(value, min, colour.darker(), max, colour.brighter()) + * but avoiding object creation except for the return value + */ + if (value < min) + { + value = min; + } + if (value > max) + { + value = max; + } + + int r = colour.getRed(); + int g = colour.getGreen(); + int b = colour.getBlue(); + + /* + * rgb for colour.darker(): + */ + float minR = r * FACTOR; + float minG = g * FACTOR; + float minB = b * FACTOR; + + /* + * rgb for colour.brighter(): + */ + float maxR = Math.min(255f, r / FACTOR); + float maxG = Math.min(255f, g / FACTOR); + float maxB = Math.min(255f, b / FACTOR); + + /* + * interpolation + */ + float p = (value - min) / (max - min); + int newR = (int) (minR + p * (maxR - minR)); + int newG = (int) (minG + p * (maxG - minG)); + int newB = (int) (minB + p * (maxB - minB)); + + return new Color(newR, newG, newB, colour.getAlpha()); + } }