4
4
import com .annimon .ownlang .lib .*;
5
5
import java .awt .Dimension ;
6
6
import java .lang .reflect .Modifier ;
7
+ import java .nio .IntBuffer ;
7
8
import java .util .Arrays ;
8
9
import java .util .HashMap ;
9
10
import java .util .Map ;
18
19
import javafx .scene .canvas .Canvas ;
19
20
import javafx .scene .canvas .GraphicsContext ;
20
21
import javafx .scene .effect .*;
22
+ import javafx .scene .image .Image ;
23
+ import javafx .scene .image .PixelReader ;
24
+ import javafx .scene .image .PixelWriter ;
25
+ import javafx .scene .image .WritableImage ;
26
+ import javafx .scene .image .WritablePixelFormat ;
21
27
import javafx .scene .input .DragEvent ;
22
28
import javafx .scene .input .KeyCode ;
23
29
import javafx .scene .input .KeyEvent ;
@@ -117,6 +123,7 @@ public void init() {
117
123
118
124
Functions .set ("addEventFilter" , new addEventFilter ());
119
125
Functions .set ("addEventHandler" , new addEventHandler ());
126
+ Functions .set ("createImage" , new createImage ());
120
127
121
128
final MapValue arcType = new MapValue (ArcType .values ().length );
122
129
for (ArcType value : ArcType .values ()) {
@@ -571,6 +578,83 @@ public Value execute(Value... args) {
571
578
}
572
579
//</editor-fold>
573
580
581
+ private static class ImageFXValue extends MapValue {
582
+
583
+ private final Image image ;
584
+
585
+ public ImageFXValue (Image image ) {
586
+ super (8 );
587
+ this .image = image ;
588
+ init ();
589
+ }
590
+
591
+ private void init () {
592
+ set (new StringValue ("width" ), NumberValue .of (image .getWidth ()));
593
+ set (new StringValue ("height" ), NumberValue .of (image .getHeight ()));
594
+ set (new StringValue ("preserveRatio" ), NumberValue .fromBoolean (image .isPreserveRatio ()));
595
+ set (new StringValue ("smooth" ), NumberValue .fromBoolean (image .isSmooth ()));
596
+ set (new StringValue ("getPixels" ), new FunctionValue (this ::getPixels ));
597
+ }
598
+
599
+ private Value getPixels (Value ... args ) {
600
+ final int w = (int ) image .getWidth ();
601
+ final int h = (int ) image .getHeight ();
602
+ final int size = w * h ;
603
+ final PixelReader pr = image .getPixelReader ();
604
+ final WritablePixelFormat <IntBuffer > format = WritablePixelFormat .getIntArgbInstance ();
605
+ final int [] buffer = new int [size ];
606
+ pr .getPixels (0 , 0 , w , h , format , buffer , 0 , w );
607
+
608
+ final ArrayValue result = new ArrayValue (size );
609
+ for (int i = 0 ; i < size ; i ++) {
610
+ result .set (i , NumberValue .of (buffer [i ]));
611
+ }
612
+ return result ;
613
+ }
614
+
615
+ @ Override
616
+ public String toString () {
617
+ return "JavaFX Image " + image ;
618
+ }
619
+ }
620
+
621
+ private static class createImage implements Function {
622
+
623
+ @ Override
624
+ public Value execute (Value ... args ) {
625
+ Arguments .checkAtLeast (1 , args .length );
626
+ final Image result ;
627
+ switch (args .length ) {
628
+ case 1 :
629
+ // createImage(url)
630
+ result = new Image (args [0 ].asString ());
631
+ break ;
632
+ case 2 :
633
+ default :
634
+ // createImage(width, height)
635
+ result = new WritableImage (args [0 ].asInt (), args [1 ].asInt ());
636
+ break ;
637
+ case 3 :
638
+ // createImage(w, h, pixels)
639
+ final int w = args [0 ].asInt ();
640
+ final int h = args [1 ].asInt ();
641
+ final int size = w * h ;
642
+ final WritableImage writableImage = new WritableImage (w , h );
643
+ final PixelWriter pw = writableImage .getPixelWriter ();
644
+ final WritablePixelFormat <IntBuffer > format = WritablePixelFormat .getIntArgbInstance ();
645
+ final int [] buffer = new int [size ];
646
+ final ArrayValue array = (ArrayValue ) args [2 ];
647
+ for (int i = 0 ; i < size ; i ++) {
648
+ buffer [i ] = array .get (i ).asInt ();
649
+ }
650
+ pw .setPixels (0 , 0 , w , h , format , buffer , 0 , w );
651
+ result = writableImage ;
652
+
653
+ }
654
+ return new ImageFXValue (result );
655
+ }
656
+ }
657
+
574
658
public static class GraphicsFXValue extends MapValue {
575
659
576
660
private final GraphicsContext graphics ;
@@ -592,6 +676,7 @@ private void init() {
592
676
functions .put ("clearRect" , this ::clearRect );
593
677
functions .put ("clip" , this ::clip );
594
678
functions .put ("closePath" , this ::closePath );
679
+ functions .put ("drawImage" , this ::drawImage );
595
680
functions .put ("fill" , this ::fill );
596
681
functions .put ("fillArc" , this ::fillArc );
597
682
functions .put ("fillOval" , this ::fillOval );
@@ -706,6 +791,36 @@ public Value closePath(Value... args) {
706
791
return NumberValue .ZERO ;
707
792
}
708
793
794
+ public Value drawImage (Value ... args ) {
795
+ Arguments .checkAtLeast (3 , args .length );
796
+ if (!(args [0 ] instanceof ImageFXValue )) {
797
+ throw new TypeException ("ImageFX expected" );
798
+ }
799
+ final Image image = ((ImageFXValue ) args [0 ]).image ;
800
+
801
+ if (args .length >= 9 ) {
802
+ graphics .drawImage (image ,
803
+ args [1 ].asNumber (), args [2 ].asNumber (),
804
+ args [3 ].asNumber (), args [4 ].asNumber (),
805
+ args [5 ].asNumber (), args [6 ].asNumber (),
806
+ args [7 ].asNumber (), args [8 ].asNumber ()
807
+ );
808
+ return NumberValue .ZERO ;
809
+ }
810
+
811
+ if (args .length >= 5 ) {
812
+ // x y w h
813
+ graphics .drawImage (image ,
814
+ args [1 ].asNumber (), args [2 ].asNumber (),
815
+ args [3 ].asNumber (), args [4 ].asNumber ()
816
+ );
817
+ return NumberValue .ZERO ;
818
+ }
819
+
820
+ graphics .drawImage (image , args [1 ].asNumber (), args [2 ].asNumber ());
821
+ return NumberValue .ZERO ;
822
+ }
823
+
709
824
public Value fill (Value ... args ) {
710
825
graphics .fill ();
711
826
return NumberValue .ZERO ;
0 commit comments