From 7a7c389f2ffddb4e4170098e4f5facca1fa8b633 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Hannu=20Niemist=C3=B6?= Date: Mon, 19 Sep 2016 12:08:31 +0300 Subject: [PATCH] Merged changes from SVN --- .../internal/parsing/parser/SCL.grammar | 2 +- .../internal/parsing/parser/SCLLexer.java | 86 +++--- .../internal/parsing/parser/SCLParser.dat | Bin 21048 -> 21064 bytes .../internal/parsing/parser/SCLParser.java | 16 +- .../parsing/parser/SCLParserImpl.java | 5 +- .../internal/parsing/parser/SCLPostLexer.java | 7 +- .../simantics/scl/compiler/types/Types.java | 4 +- .../scl/compiler/tests/ActiveTests.java | 5 +- .../scl/compiler/tests/scl/EmptyLet.scl | 9 + .../utils/ui/color/ColorAlphaGradient.java | 256 ++++++++++++++++++ .../utils/ui/color/ColorGradient.java | 11 +- 11 files changed, 339 insertions(+), 62 deletions(-) create mode 100644 bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/EmptyLet.scl create mode 100644 bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorAlphaGradient.java diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar index 6821da83e..500cf3b20 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar @@ -187,7 +187,7 @@ stringLiteral ; statements - = LBRACE statement (SEMICOLON statement)* RBRACE # Statements + = LBRACE (statement (SEMICOLON statement)*)? RBRACE # Statements ; statement diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java index e23a9a17c..e31112790 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLLexer.java @@ -1,12 +1,12 @@ /* The following code was generated by JFlex 1.6.1 */ -package org.simantics.scl.compiler.internal.parsing.parser; - -import org.simantics.scl.compiler.internal.parsing.Token; -import org.simantics.scl.compiler.errors.Locations; -import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; -import gnu.trove.list.array.TIntArrayList; - +package org.simantics.scl.compiler.internal.parsing.parser; + +import org.simantics.scl.compiler.internal.parsing.Token; +import org.simantics.scl.compiler.errors.Locations; +import org.simantics.scl.compiler.internal.parsing.exceptions.SCLSyntaxErrorException; +import gnu.trove.list.array.TIntArrayList; + /** * This class is a scanner generated by @@ -562,20 +562,20 @@ public class SCLLexer { private int zzFinalHighSurrogate = 0; /* user code: */ - public SCLParserOptions options = SCLParserOptions.DEFAULT; - int stringStart; - TIntArrayList parenCountStack = new TIntArrayList(2); - int parenCount = 0; - TIntArrayList stateStack = new TIntArrayList(2); - - StringBuffer string = new StringBuffer(); - - private Token sym(int id) { - return new Token(id, yychar, yychar+yylength(), yytext()); - } - private Token sym(int id, String text) { - return new Token(id, yychar, yychar+yylength(), text); - } + public SCLParserOptions options = SCLParserOptions.DEFAULT; + int stringStart; + TIntArrayList parenCountStack = new TIntArrayList(2); + int parenCount = 0; + TIntArrayList stateStack = new TIntArrayList(2); + + StringBuffer string = new StringBuffer(); + + private Token sym(int id) { + return new Token(id, yychar, yychar+yylength(), yytext()); + } + private Token sym(int id, String text) { + return new Token(id, yychar, yychar+yylength(), text); + } /** @@ -900,7 +900,7 @@ public class SCLLexer { } case 278: break; default: - { return sym(SCLTerminals.EOF); + { return sym(SCLTerminals.EOF); } } } @@ -943,15 +943,15 @@ public class SCLLexer { } case 101: break; case 10: - { --parenCount; - if(parenCount == 0 && !parenCountStack.isEmpty()) { - parenCount = parenCountStack.removeAt(parenCountStack.size()-1); - string.setLength(0); - stringStart=yychar; - yybegin(stateStack.removeAt(stateStack.size()-1)); - return sym(SCLTerminals.CONTINUE_STRING); - } - else + { --parenCount; + if(parenCount == 0 && !parenCountStack.isEmpty()) { + parenCount = parenCountStack.removeAt(parenCountStack.size()-1); + string.setLength(0); + stringStart=yychar; + yybegin(stateStack.removeAt(stateStack.size()-1)); + return sym(SCLTerminals.CONTINUE_STRING); + } + else return sym(SCLTerminals.RPAREN); } case 102: break; @@ -1036,7 +1036,7 @@ public class SCLLexer { } case 122: break; case 31: - { yybegin(YYINITIAL); + { yybegin(YYINITIAL); return new Token(SCLTerminals.END_STRING, stringStart, yychar+1, string.toString()); } case 123: break; @@ -1113,10 +1113,10 @@ public class SCLLexer { } case 141: break; case 50: - { parenCountStack.add(parenCount); - parenCount = 1; - stateStack.add(STRING); - yybegin(YYINITIAL); + { parenCountStack.add(parenCount); + parenCount = 1; + stateStack.add(STRING); + yybegin(YYINITIAL); return new Token(SCLTerminals.SUSPEND_STRING, stringStart, yychar+1, string.toString()); } case 142: break; @@ -1129,10 +1129,10 @@ public class SCLLexer { } case 144: break; case 53: - { parenCountStack.add(parenCount); - parenCount = 1; - stateStack.add(LONG_STRING); - yybegin(YYINITIAL); + { parenCountStack.add(parenCount); + parenCount = 1; + stateStack.add(LONG_STRING); + yybegin(YYINITIAL); return new Token(SCLTerminals.SUSPEND_STRING, stringStart, yychar+1, string.toString()); } case 145: break; @@ -1145,12 +1145,12 @@ public class SCLLexer { } case 147: break; case 56: - { String text = yytext(); + { String text = yytext(); return sym(SCLTerminals.ID, text.substring(1, text.length()-1)); } case 148: break; case 57: - { String text = yytext(); + { String text = yytext(); return sym(SCLTerminals.SYMBOL, text.substring(1, text.length()-1)); } case 149: break; @@ -1171,7 +1171,7 @@ public class SCLLexer { } case 153: break; case 62: - { yybegin(YYINITIAL); + { yybegin(YYINITIAL); return new Token(SCLTerminals.END_STRING, stringStart, yychar+3, string.toString()); } case 154: break; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat index f17807cb50b5a65ac8b4185c1df3870340716c06..fe5dac3c46f78e291d2ee254261596d2fdb25b19 100644 GIT binary patch literal 21064 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 2) + for(int i=1;i alphaValues; + + + public ColorAlphaGradient() { + super(); + this.alphaValues = new ArrayList<>(); + } + + public ColorAlphaGradient(ColorAlphaGradient copyFrom) { + super(copyFrom); + this.alphaValues = copyFrom.alphaValues; + } + + public ColorAlphaGradient(ColorValue array[], int alphaArray[]) { + super(array); + if (array.length != alphaArray.length) + throw new IllegalArgumentException("Array lenghts do not match."); + this.alphaValues = new ArrayList<>(alphaArray.length); + for (int a : alphaArray) { + alphaValues.add(a); + } + } + + public ColorAlphaGradient(ColorValue array[], int alphaArray[], int type) { + super(array, type); + if (array.length != alphaArray.length) + throw new IllegalArgumentException("Array lenghts do not match."); + this.alphaValues = new ArrayList<>(alphaArray.length); + for (int a : alphaArray) { + alphaValues.add(a); + } + } + + public ColorAlphaGradient(Collection values, Collection alphaValues) { + super(values); + if (values.size() != alphaValues.size()) + throw new IllegalArgumentException("Array lenghts do not match."); + this.alphaValues = new ArrayList<>(alphaValues); + } + + public ColorAlphaGradient(Collection values, Collection alphaValues, int type) { + super(values, type); + if (values.size() != alphaValues.size()) + throw new IllegalArgumentException("Array lenghts do not match."); + this.alphaValues = new ArrayList<>(alphaValues); + } + + /** + * 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())), + (byte) Math.min(255.0, Math.floor(value * alphaValues.get(index) + valuei * alphaValues.get(index - 1)))}; + 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(), (byte) Math.min(255.0, Math.floor(value * alphaValues.get(index) + valuei * alphaValues.get(index - 1)))}; + + 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 * 4]; + if (values.size() > 1) { + for (int i = 0; i < size; i++) { + int index = i * 4; + 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]; + array[index + 3] = color[3]; + } + } 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(); + color[3] = (byte)(int)alphaValues.get(0); + 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]; + array[index + 3] = color[3]; + } + } else { + for (int i = 0; i < size; i++) { + int index = i * 4; + array[index] = (byte)255; + array[index + 1] = (byte)255; + array[index + 2] = (byte)255; + array[index + 3] = (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, byteColor[3] & 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, byteColor[3] & 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(), alphaValues.get(0)); + gc.setBackground(color); + gc.fillRectangle(0, 0, width, height); + color.dispose(); + } else { + gc.fillRectangle(0, 0, width, height); + } + gc.dispose(); + return image; + } + + @Override + public boolean equals(Object obj) { + if (super.equals(obj)) { + ColorAlphaGradient cg = (ColorAlphaGradient)obj; + return alphaValues.containsAll(cg.alphaValues); + } else { + return false; + } + } + +} diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java index a08010f20..56195ce0c 100644 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java @@ -38,9 +38,9 @@ public class ColorGradient { public static final int HSV = 1; - private ArrayList values; + protected ArrayList values; - private int type; + protected int type; public ColorGradient() { this.values = new ArrayList(); @@ -59,7 +59,7 @@ public class ColorGradient { } public ColorGradient(ColorValue array[]) { - this.values = new ArrayList(); + this.values = new ArrayList(array.length); for (ColorValue c : array) { values.add(c); } @@ -295,7 +295,10 @@ public class ColorGradient { @Override public boolean equals(Object obj) { - if (!(obj instanceof ColorGradient)) return false; + 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; -- 2.47.1