From af4eddf184e35b7e56c8bae07c2675411192bf20 Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 24 May 2016 15:05:46 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5?= =?UTF-8?q?=20canvasfx=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B8=D0=B7=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/canvas/fx_image.own | 6 + examples/canvas/fx_image_negate.own | 22 ++++ .../annimon/ownlang/lib/modules/canvasfx.java | 115 ++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 examples/canvas/fx_image.own create mode 100644 examples/canvas/fx_image_negate.own diff --git a/examples/canvas/fx_image.own b/examples/canvas/fx_image.own new file mode 100644 index 0000000..a2f1cec --- /dev/null +++ b/examples/canvas/fx_image.own @@ -0,0 +1,6 @@ +use "canvasfx" + +g = window("JavaFX Image demo", 400, 200) +img = createImage("http://lorempixel.com/400/200/") +g.drawImage(img, 0, 0) +repaint() \ No newline at end of file diff --git a/examples/canvas/fx_image_negate.own b/examples/canvas/fx_image_negate.own new file mode 100644 index 0000000..2338a0c --- /dev/null +++ b/examples/canvas/fx_image_negate.own @@ -0,0 +1,22 @@ +use "std" +use "canvasfx" + +graphics = window("JavaFX Image negation demo", 400, 400) +imgSource = createImage("http://lorempixel.com/400/200/") +pixels = imgSource.getPixels() +size = length(pixels) +for i = 0, i < size, i++ { + pixel = pixels[i] + r = (pixel >> 16) & 0xFF + g = (pixel >> 8) & 0xFF + b = pixel & 0xFF + r = 255 - r + g = 255 - g + b = 255 - b + pixels[i] = 0xFF000000 | (r << 16) | (g << 8) | b +} +imgNegate = createImage(imgSource.width, imgSource.height, pixels) + +graphics.drawImage(imgSource, 0, 0) +graphics.drawImage(imgNegate, 0, 200) +repaint() \ No newline at end of file diff --git a/src/com/annimon/ownlang/lib/modules/canvasfx.java b/src/com/annimon/ownlang/lib/modules/canvasfx.java index ecb4683..d4cc2f4 100644 --- a/src/com/annimon/ownlang/lib/modules/canvasfx.java +++ b/src/com/annimon/ownlang/lib/modules/canvasfx.java @@ -4,6 +4,7 @@ import com.annimon.ownlang.exceptions.TypeException; import com.annimon.ownlang.lib.*; import java.awt.Dimension; import java.lang.reflect.Modifier; +import java.nio.IntBuffer; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -18,6 +19,11 @@ import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.effect.*; +import javafx.scene.image.Image; +import javafx.scene.image.PixelReader; +import javafx.scene.image.PixelWriter; +import javafx.scene.image.WritableImage; +import javafx.scene.image.WritablePixelFormat; import javafx.scene.input.DragEvent; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; @@ -117,6 +123,7 @@ public final class canvasfx implements Module { Functions.set("addEventFilter", new addEventFilter()); Functions.set("addEventHandler", new addEventHandler()); + Functions.set("createImage", new createImage()); final MapValue arcType = new MapValue(ArcType.values().length); for (ArcType value : ArcType.values()) { @@ -571,6 +578,83 @@ public final class canvasfx implements Module { } // + private static class ImageFXValue extends MapValue { + + private final Image image; + + public ImageFXValue(Image image) { + super(8); + this.image = image; + init(); + } + + private void init() { + set(new StringValue("width"), NumberValue.of(image.getWidth())); + set(new StringValue("height"), NumberValue.of(image.getHeight())); + set(new StringValue("preserveRatio"), NumberValue.fromBoolean(image.isPreserveRatio())); + set(new StringValue("smooth"), NumberValue.fromBoolean(image.isSmooth())); + set(new StringValue("getPixels"), new FunctionValue(this::getPixels)); + } + + private Value getPixels(Value... args) { + final int w = (int) image.getWidth(); + final int h = (int) image.getHeight(); + final int size = w * h; + final PixelReader pr = image.getPixelReader(); + final WritablePixelFormat format = WritablePixelFormat.getIntArgbInstance(); + final int[] buffer = new int[size]; + pr.getPixels(0, 0, w, h, format, buffer, 0, w); + + final ArrayValue result = new ArrayValue(size); + for (int i = 0; i < size; i++) { + result.set(i, NumberValue.of(buffer[i])); + } + return result; + } + + @Override + public String toString() { + return "JavaFX Image " + image; + } + } + + private static class createImage implements Function { + + @Override + public Value execute(Value... args) { + Arguments.checkAtLeast(1, args.length); + final Image result; + switch (args.length) { + case 1: + // createImage(url) + result = new Image(args[0].asString()); + break; + case 2: + default: + // createImage(width, height) + result = new WritableImage(args[0].asInt(), args[1].asInt()); + break; + case 3: + // createImage(w, h, pixels) + final int w = args[0].asInt(); + final int h = args[1].asInt(); + final int size = w * h; + final WritableImage writableImage = new WritableImage(w, h); + final PixelWriter pw = writableImage.getPixelWriter(); + final WritablePixelFormat format = WritablePixelFormat.getIntArgbInstance(); + final int[] buffer = new int[size]; + final ArrayValue array = (ArrayValue) args[2]; + for (int i = 0; i < size; i++) { + buffer[i] = array.get(i).asInt(); + } + pw.setPixels(0, 0, w, h, format, buffer, 0, w); + result = writableImage; + + } + return new ImageFXValue(result); + } + } + public static class GraphicsFXValue extends MapValue { private final GraphicsContext graphics; @@ -592,6 +676,7 @@ public final class canvasfx implements Module { functions.put("clearRect", this::clearRect); functions.put("clip", this::clip); functions.put("closePath", this::closePath); + functions.put("drawImage", this::drawImage); functions.put("fill", this::fill); functions.put("fillArc", this::fillArc); functions.put("fillOval", this::fillOval); @@ -706,6 +791,36 @@ public final class canvasfx implements Module { return NumberValue.ZERO; } + public Value drawImage(Value... args) { + Arguments.checkAtLeast(3, args.length); + if (!(args[0] instanceof ImageFXValue)) { + throw new TypeException("ImageFX expected"); + } + final Image image = ((ImageFXValue) args[0]).image; + + if (args.length >= 9) { + graphics.drawImage(image, + args[1].asNumber(), args[2].asNumber(), + args[3].asNumber(), args[4].asNumber(), + args[5].asNumber(), args[6].asNumber(), + args[7].asNumber(), args[8].asNumber() + ); + return NumberValue.ZERO; + } + + if (args.length >= 5) { + // x y w h + graphics.drawImage(image, + args[1].asNumber(), args[2].asNumber(), + args[3].asNumber(), args[4].asNumber() + ); + return NumberValue.ZERO; + } + + graphics.drawImage(image, args[1].asNumber(), args[2].asNumber()); + return NumberValue.ZERO; + } + public Value fill(Value... args) { graphics.fill(); return NumberValue.ZERO;