();
- for (ColorValue c : array) {
- values.add(c);
- }
- Collections.sort(this.values, new ColorValueComparator());
- this.type = type;
- }
-
- /**
- * Interpolates color in RGB space
- *
- * @param value
- * @return
- */
- private byte[] getRGBColor(double value) {
- int index = 1;
- while (values.get(index).getValue() <= value && index < values.size()-1)
- index++;
-
- value -= values.get(index - 1).getValue();
- value /= (values.get(index).getValue() - values.get(index - 1).getValue());
- double valuei = 1.0 - value;
- byte color[] = new byte[] {
- (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getR() + valuei * values.get(index - 1).getColor().getR())),
- (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getG() + valuei * values.get(index - 1).getColor().getG())),
- (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getB() + valuei * values.get(index - 1).getColor().getB())) };
- return color;
-
- }
-
- /**
- * Interpolates color in HSV space
- *
- * @param value
- * @return
- */
- private byte[] getHSVColor(double value) {
- int index = 1;
- while (values.get(index).getValue() <= value && index < values.size()-1)
- index++;
-
- value -= values.get(index - 1).getValue();
- value /= (values.get(index).getValue() - values.get(index - 1).getValue());
- double valuei = 1.0 - value;
- double h;
- if (Float.isNaN(values.get(index).getColor().getH())) {
- h = values.get(index-1).getColor().getH();
- } else if (Float.isNaN(values.get(index-1).getColor().getH())) {
- h = values.get(index).getColor().getH();
- } else {
- // selecting shortest direction between hues
- float angle = values.get(index).getColor().getH() - values.get(index - 1).getColor().getH();
- if (angle > 180.f)
- angle -= 360.f;
- else if (angle < -180.f)
- angle += 360.f;
- h = values.get(index - 1).getColor().getH() + value * angle;
- if (h > 360.f)
- h -= 360.f;
- else if (h < 0.f)
- h+= 360.f;
- }
- org.simantics.utils.ui.color.Color interpolated = new org.simantics.utils.ui.color.Color(h, value * values.get(index).getColor().getS() + valuei * values.get(index - 1).getColor().getS(),
- value * values.get(index).getColor().getV() + valuei * values.get(index - 1).getColor().getV());
- byte color[] = new byte[] { (byte) interpolated.getR(), (byte) interpolated.getG(), (byte) interpolated.getB() };
-
- return color;
-
- }
-
- /**
- *
- * Returns gradient in array of bytes. Array is RGB order and int contains 3 * requested size of bytes.
- *
- *
- * If gradient contains only one color array is filled with that color
- *
- *
- * if gradient has no colors array is filled with white
- *
- * @param size number of pixels
- * @return gradient in array of bytes
- */
- public byte[] getGradientArray(int size) {
- byte array[] = new byte[size * 3];
- if (values.size() > 1) {
- for (int i = 0; i < size; i++) {
- int index = i * 3;
- double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) i / (double) size;
- byte color[];
- if (type == RGB)
- color = getRGBColor(value);
- else
- color = getHSVColor(value);
- array[index] = color[0];
- array[index + 1] = color[1];
- array[index + 2] = color[2];
- }
- } else if (values.size() == 1) {
- byte color[] = new byte[3];
- color[0] = (byte)values.get(0).getColor().getR();
- color[1] = (byte)values.get(0).getColor().getG();
- color[2] = (byte)values.get(0).getColor().getB();
- for (int i = 0; i < size; i++) {
- int index = i * 3;
- array[index] = color[0];
- array[index + 1] = color[1];
- array[index + 2] = color[2];
- }
- } else {
- for (int i = 0; i < size; i++) {
- int index = i * 3;
- array[index] = (byte)255;
- array[index + 1] = (byte)255;
- array[index + 2] = (byte)255;
- }
- }
- return array;
- }
-
- /**
- *
- * Returns gradient in image.
- *
- *
- * If gradient contains only one color image is filled with that color
- *
- *
- * if gradient has no colors image is filled with white
- *
- *
- * Style must be set to SWT.HORIZONTAL
or SWT.VERTICAL
- *
- * @param size number of pixels
- * @return gradient in array of bytes
- */
-
- public Image getGradientImage(int width, int height, int style) {
- Image image = new Image(Display.getCurrent(), width, height);
- GC gc = new GC(image);
- gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
- gc.fillRectangle(0, 0, width, height);
- if (values.size() > 1) {
- if (SWT.HORIZONTAL == (style | SWT.HORIZONTAL)) {
- for (int x = 0; x < width; x++) {
- double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) x
- / (double) (width - 1);
- byte byteColor[];
- if (type == RGB)
- byteColor = getRGBColor(value);
- else
- byteColor = getHSVColor(value);
- Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff);
- gc.setForeground(color);
- gc.drawLine(x, 0, x, height);
- color.dispose();
- }
- } else if (SWT.VERTICAL == (style | SWT.VERTICAL)){
- for (int y = 0; y < height; y++) {
- double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) y
- / (double) (height - 1);
- byte byteColor[];
- if (type == RGB)
- byteColor = getRGBColor(value);
- else
- byteColor = getHSVColor(value);
- Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff);
- gc.setForeground(color);
- gc.drawLine(0, y, width, y);
- color.dispose();
- }
- } else {
- gc.dispose();
- image.dispose();
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- }
- } else if (values.size() == 1) {
- Color color = new Color(Display.getCurrent(), values.get(0).getColor().getR(), values.get(0).getColor().getG(), values.get(0).getColor().getB());
- gc.setBackground(color);
- gc.fillRectangle(0, 0, width, height);
- color.dispose();
- } else {
- gc.fillRectangle(0, 0, width, height);
- }
- gc.dispose();
- return image;
- }
-
- public int getType() {
- return type;
- }
-
- public List getColorValues() {
- return values;
- }
-
- public ColorValue[] getColorValueArray() {
- return values.toArray(new ColorValue[values.size()]);
- }
-
- @Deprecated
- public void addCastorColorValue(ColorValue value) {
- values.add(value);
- Collections.sort(this.values, new ColorValueComparator());
- }
-
- @Deprecated
- public void setCastorType(int type) {
- this.type = type;
- }
-
- @Override
- public int hashCode() {
- int hash = 0x58fb3;
- for (ColorValue cv : values)
- hash ^= cv.hashCode();
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null)
- return false;
- if (obj.getClass() != getClass())
- return false;
- ColorGradient cg = (ColorGradient) obj;
- if (cg.type != type) return false;
- if (values.size()!=cg.values.size()) return false;
- if (!values.containsAll(cg.values)) return false;
- return true;
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.utils.ui.color;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ *
+ *
+ * Color gradient between multiple colors
+ *
+ *
+ * Supports RGB and HSV linear interpolation between colors
+ *
+ *
+ * @author Marko Luukkainen
+ *
+ */
+public class ColorGradient {
+ public static final int RGB = 0;
+
+ public static final int HSV = 1;
+
+ protected ArrayList values;
+
+ protected int type;
+
+ public ColorGradient() {
+ this.values = new ArrayList();
+ this.type = RGB;
+ }
+
+ public ColorGradient(ColorGradient copyFrom) {
+ this.values = new ArrayList(copyFrom.values);
+ this.type = copyFrom.type;
+ }
+
+ public ColorGradient(Collection values) {
+ this.values = new ArrayList(values);
+ Collections.sort(this.values, new ColorValueComparator());
+ this.type = RGB;
+ }
+
+ public ColorGradient(ColorValue array[]) {
+ this.values = new ArrayList(array.length);
+ for (ColorValue c : array) {
+ values.add(c);
+ }
+ Collections.sort(this.values, new ColorValueComparator());
+ this.type = RGB;
+ }
+
+ public ColorGradient(Collection values, int type) {
+ this.values = new ArrayList(values);
+ Collections.sort(this.values, new ColorValueComparator());
+ this.type = type;
+ }
+
+ public ColorGradient(ColorValue array[], int type) {
+ this.values = new ArrayList();
+ for (ColorValue c : array) {
+ values.add(c);
+ }
+ Collections.sort(this.values, new ColorValueComparator());
+ this.type = type;
+ }
+
+ /**
+ * Interpolates color in RGB space
+ *
+ * @param value
+ * @return
+ */
+ private byte[] getRGBColor(double value) {
+ int index = 1;
+ while (values.get(index).getValue() <= value && index < values.size()-1)
+ index++;
+
+ value -= values.get(index - 1).getValue();
+ value /= (values.get(index).getValue() - values.get(index - 1).getValue());
+ double valuei = 1.0 - value;
+ byte color[] = new byte[] {
+ (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getR() + valuei * values.get(index - 1).getColor().getR())),
+ (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getG() + valuei * values.get(index - 1).getColor().getG())),
+ (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getB() + valuei * values.get(index - 1).getColor().getB())) };
+ return color;
+
+ }
+
+ /**
+ * Interpolates color in HSV space
+ *
+ * @param value
+ * @return
+ */
+ private byte[] getHSVColor(double value) {
+ int index = 1;
+ while (values.get(index).getValue() <= value && index < values.size()-1)
+ index++;
+
+ value -= values.get(index - 1).getValue();
+ value /= (values.get(index).getValue() - values.get(index - 1).getValue());
+ double valuei = 1.0 - value;
+ double h;
+ if (Float.isNaN(values.get(index).getColor().getH())) {
+ h = values.get(index-1).getColor().getH();
+ } else if (Float.isNaN(values.get(index-1).getColor().getH())) {
+ h = values.get(index).getColor().getH();
+ } else {
+ // selecting shortest direction between hues
+ float angle = values.get(index).getColor().getH() - values.get(index - 1).getColor().getH();
+ if (angle > 180.f)
+ angle -= 360.f;
+ else if (angle < -180.f)
+ angle += 360.f;
+ h = values.get(index - 1).getColor().getH() + value * angle;
+ if (h > 360.f)
+ h -= 360.f;
+ else if (h < 0.f)
+ h+= 360.f;
+ }
+ org.simantics.utils.ui.color.Color interpolated = new org.simantics.utils.ui.color.Color(h, value * values.get(index).getColor().getS() + valuei * values.get(index - 1).getColor().getS(),
+ value * values.get(index).getColor().getV() + valuei * values.get(index - 1).getColor().getV());
+ byte color[] = new byte[] { (byte) interpolated.getR(), (byte) interpolated.getG(), (byte) interpolated.getB() };
+
+ return color;
+
+ }
+
+ /**
+ *
+ * Returns gradient in array of bytes. Array is RGB order and int contains 3 * requested size of bytes.
+ *
+ *
+ * If gradient contains only one color array is filled with that color
+ *
+ *
+ * if gradient has no colors array is filled with white
+ *
+ * @param size number of pixels
+ * @return gradient in array of bytes
+ */
+ public byte[] getGradientArray(int size) {
+ byte array[] = new byte[size * 3];
+ if (values.size() > 1) {
+ for (int i = 0; i < size; i++) {
+ int index = i * 3;
+ double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) i / (double) size;
+ byte color[];
+ if (type == RGB)
+ color = getRGBColor(value);
+ else
+ color = getHSVColor(value);
+ array[index] = color[0];
+ array[index + 1] = color[1];
+ array[index + 2] = color[2];
+ }
+ } else if (values.size() == 1) {
+ byte color[] = new byte[3];
+ color[0] = (byte)values.get(0).getColor().getR();
+ color[1] = (byte)values.get(0).getColor().getG();
+ color[2] = (byte)values.get(0).getColor().getB();
+ for (int i = 0; i < size; i++) {
+ int index = i * 3;
+ array[index] = color[0];
+ array[index + 1] = color[1];
+ array[index + 2] = color[2];
+ }
+ } else {
+ for (int i = 0; i < size; i++) {
+ int index = i * 3;
+ array[index] = (byte)255;
+ array[index + 1] = (byte)255;
+ array[index + 2] = (byte)255;
+ }
+ }
+ return array;
+ }
+
+ /**
+ *
+ * Returns gradient in image.
+ *
+ *
+ * If gradient contains only one color image is filled with that color
+ *
+ *
+ * if gradient has no colors image is filled with white
+ *
+ *
+ * Style must be set to SWT.HORIZONTAL
or SWT.VERTICAL
+ *
+ * @param size number of pixels
+ * @return gradient in array of bytes
+ */
+
+ public Image getGradientImage(int width, int height, int style) {
+ Image image = new Image(Display.getCurrent(), width, height);
+ GC gc = new GC(image);
+ gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ gc.fillRectangle(0, 0, width, height);
+ if (values.size() > 1) {
+ if (SWT.HORIZONTAL == (style | SWT.HORIZONTAL)) {
+ for (int x = 0; x < width; x++) {
+ double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) x
+ / (double) (width - 1);
+ byte byteColor[];
+ if (type == RGB)
+ byteColor = getRGBColor(value);
+ else
+ byteColor = getHSVColor(value);
+ Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff);
+ gc.setForeground(color);
+ gc.drawLine(x, 0, x, height);
+ color.dispose();
+ }
+ } else if (SWT.VERTICAL == (style | SWT.VERTICAL)){
+ for (int y = 0; y < height; y++) {
+ double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) y
+ / (double) (height - 1);
+ byte byteColor[];
+ if (type == RGB)
+ byteColor = getRGBColor(value);
+ else
+ byteColor = getHSVColor(value);
+ Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff);
+ gc.setForeground(color);
+ gc.drawLine(0, y, width, y);
+ color.dispose();
+ }
+ } else {
+ gc.dispose();
+ image.dispose();
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ } else if (values.size() == 1) {
+ Color color = new Color(Display.getCurrent(), values.get(0).getColor().getR(), values.get(0).getColor().getG(), values.get(0).getColor().getB());
+ gc.setBackground(color);
+ gc.fillRectangle(0, 0, width, height);
+ color.dispose();
+ } else {
+ gc.fillRectangle(0, 0, width, height);
+ }
+ gc.dispose();
+ return image;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public List getColorValues() {
+ return values;
+ }
+
+ public ColorValue[] getColorValueArray() {
+ return values.toArray(new ColorValue[values.size()]);
+ }
+
+ @Deprecated
+ public void addCastorColorValue(ColorValue value) {
+ values.add(value);
+ Collections.sort(this.values, new ColorValueComparator());
+ }
+
+ @Deprecated
+ public void setCastorType(int type) {
+ this.type = type;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0x58fb3;
+ for (ColorValue cv : values)
+ hash ^= cv.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null)
+ return false;
+ if (obj.getClass() != getClass())
+ return false;
+ ColorGradient cg = (ColorGradient) obj;
+ if (cg.type != type) return false;
+ if (values.size()!=cg.values.size()) return false;
+ if (!values.containsAll(cg.values)) return false;
+ return true;
+ }
+
+}