1717 */
1818public class ImageDrawingGrid extends Canvas {
1919 public enum DrawingMode { NONE , DOT , LINE , OUTLINE_RECT , FILLED_RECT , OUTLINE_CIRCLE , FLOOD_FILL , SELECTION }
20- private final BmpDataManager bitmap ;
21- private final PortablePalette palette ;
20+ private BmpDataManager bitmap ;
21+ private PortablePalette palette ;
2222 private final boolean editMode ;
2323 private BiConsumer <Integer , Integer > positionConsumer ;
2424 private DrawingMode mode = DrawingMode .NONE ;
@@ -45,16 +45,23 @@ public ImageDrawingGrid(BmpDataManager bitmap, PortablePalette palette, boolean
4545 xStart = (int ) (event .getX () / fitWidth * bitmap .getPixelWidth ());
4646 yStart = (int ) (event .getY () / fitHeight * bitmap .getPixelHeight ());
4747 mode = currentShape == DrawingMode .FLOOD_FILL ? DrawingMode .FLOOD_FILL : DrawingMode .DOT ;
48+ if (currentShape == DrawingMode .DOT ) {
49+ recordChange ();
50+ bitmap .setDataAt (xStart , yStart , colorIndex );
51+ onPaintSurface (getGraphicsContext2D ());
52+ }
4853 });
4954
5055 setOnMouseDragged (event -> {
5156 mode = currentShape ;
5257
5358 xNow = (int ) (event .getX () / fitWidth * bitmap .getPixelWidth ());
5459 yNow = (int ) (event .getY () / fitHeight * bitmap .getPixelHeight ());
55- if (xNow > bitmap .getPixelWidth () || yNow > bitmap .getPixelHeight ()) return ;
60+ if (xNow >= bitmap .getPixelWidth () || yNow >= bitmap .getPixelHeight () || xNow < 0 || yNow < 0 ) return ;
5661 if (mode == DrawingMode .SELECTION ) {
5762 imageSelection = new OrderedRect (xStart , yStart , xNow , yNow );
63+ } else if (mode == DrawingMode .DOT ) {
64+ bitmap .setDataAt (xNow , yNow , colorIndex );
5865 }
5966
6067 onPaintSurface (getGraphicsContext2D ());
@@ -71,11 +78,9 @@ public ImageDrawingGrid(BmpDataManager bitmap, PortablePalette palette, boolean
7178 setOnMouseReleased (event -> {
7279 int xEnd = (int ) (event .getX () / fitWidth * bitmap .getPixelWidth ());
7380 int yEnd = (int ) (event .getY () / fitHeight * bitmap .getPixelHeight ());
74- if (xEnd >= bitmap .getPixelWidth () || yEnd >= bitmap .getPixelHeight ()) return ;
81+ if (xEnd >= bitmap .getPixelWidth () || yEnd >= bitmap .getPixelHeight () || xEnd < 0 || yEnd < 0 ) return ;
7582 if (mode == DrawingMode .DOT ) {
76- recordChange ();
7783 bitmap .setDataAt (xEnd , yEnd , colorIndex );
78- onPaintSurface (getGraphicsContext2D ());
7984 } else if (mode == DrawingMode .FILLED_RECT ) {
8085 recordChange ();
8186 filledRectangle (bitmap , xStart , yStart , xEnd , yEnd );
@@ -111,24 +116,28 @@ public void floodFill(int x, int y, int startingCol) {
111116 floodFill (x + 1 , y , startingCol );
112117 }
113118
119+ public void drawBoxOutline (BmpDataManager bitmapToDraw , int xStart , int yStart , int xEnd , int yEnd ) {
120+ drawLine (bitmapToDraw , xStart , yStart , xEnd , yStart );
121+ drawLine (bitmapToDraw , xEnd , yStart , xEnd , yEnd );
122+ drawLine (bitmapToDraw , xStart , yEnd , xEnd , yEnd );
123+ drawLine (bitmapToDraw , xStart , yStart , xStart , yEnd );
124+ }
125+
114126 public void drawBoxOutline (int xEnd , int yEnd ) {
115- drawLine (xStart , yStart , xEnd , yStart );
116- drawLine (xEnd , yStart , xEnd , yEnd );
117- drawLine (xStart , yEnd , xEnd , yEnd );
118- drawLine (xStart , yStart , xStart , yEnd );
127+ drawBoxOutline (bitmap , xStart , yStart , xEnd , yEnd );
119128 }
120129
121- public void drawCircle (int x0 , int y0 , int r ) {
130+ public void drawCircle (BmpDataManager bitmapToDraw , int x0 , int y0 , int r ) {
122131 int f = 1 - r ;
123132 int ddF_x = 1 ;
124133 int ddF_y = -2 * r ;
125134 int x = 0 ;
126135 int y = r ;
127136
128- bitmap .setDataAt (x0 , y0 + r , colorIndex );
129- bitmap .setDataAt (x0 , y0 - r , colorIndex );
130- bitmap .setDataAt (x0 + r , y0 , colorIndex );
131- bitmap .setDataAt (x0 - r , y0 , colorIndex );
137+ bitmapToDraw .setDataAt (x0 , y0 + r , colorIndex );
138+ bitmapToDraw .setDataAt (x0 , y0 - r , colorIndex );
139+ bitmapToDraw .setDataAt (x0 + r , y0 , colorIndex );
140+ bitmapToDraw .setDataAt (x0 - r , y0 , colorIndex );
132141
133142 while (x < y ) {
134143 if (f >= 0 ) {
@@ -140,17 +149,21 @@ public void drawCircle(int x0, int y0, int r) {
140149 ddF_x += 2 ;
141150 f += ddF_x ;
142151
143- bitmap .setDataAt (x0 + x , y0 + y , colorIndex );
144- bitmap .setDataAt (x0 - x , y0 + y , colorIndex );
145- bitmap .setDataAt (x0 + x , y0 - y , colorIndex );
146- bitmap .setDataAt (x0 - x , y0 - y , colorIndex );
147- bitmap .setDataAt (x0 + y , y0 + x , colorIndex );
148- bitmap .setDataAt (x0 - y , y0 + x , colorIndex );
149- bitmap .setDataAt (x0 + y , y0 - x , colorIndex );
150- bitmap .setDataAt (x0 - y , y0 - x , colorIndex );
152+ bitmapToDraw .setDataAt (x0 + x , y0 + y , colorIndex );
153+ bitmapToDraw .setDataAt (x0 - x , y0 + y , colorIndex );
154+ bitmapToDraw .setDataAt (x0 + x , y0 - y , colorIndex );
155+ bitmapToDraw .setDataAt (x0 - x , y0 - y , colorIndex );
156+ bitmapToDraw .setDataAt (x0 + y , y0 + x , colorIndex );
157+ bitmapToDraw .setDataAt (x0 - y , y0 + x , colorIndex );
158+ bitmapToDraw .setDataAt (x0 + y , y0 - x , colorIndex );
159+ bitmapToDraw .setDataAt (x0 - y , y0 - x , colorIndex );
151160 }
152161 }
153162
163+ public void drawCircle (int x0 , int y0 , int r ) {
164+ drawCircle (bitmap , x0 , y0 , r );
165+ }
166+
154167 private void recordChange () {
155168 dirty = true ;
156169 changed = true ;
@@ -181,7 +194,7 @@ public void filledRectangle(BmpDataManager bitmap, int xStart, int yStart, int x
181194 }
182195 }
183196
184- public void drawLine (int x0 , int y0 , int x1 , int y1 ) {
197+ public void drawLine (BmpDataManager bitmapToDraw , int x0 , int y0 , int x1 , int y1 ) {
185198 // roughly copied from Adafruit_GFX, Thanks!
186199 boolean steep = Math .abs (y1 - y0 ) > Math .abs (x1 - x0 );
187200 if (steep ) {
@@ -219,9 +232,9 @@ public void drawLine(int x0, int y0, int x1, int y1) {
219232
220233 for (; x0 <= x1 ; x0 ++) {
221234 if (steep ) {
222- bitmap .setDataAt (y0 , x0 , colorIndex );
235+ bitmapToDraw .setDataAt (y0 , x0 , colorIndex );
223236 } else {
224- bitmap .setDataAt (x0 , y0 , colorIndex );
237+ bitmapToDraw .setDataAt (x0 , y0 , colorIndex );
225238 }
226239 err -= dy ;
227240 if (err < 0 ) {
@@ -231,6 +244,10 @@ public void drawLine(int x0, int y0, int x1, int y1) {
231244 }
232245 }
233246
247+ public void drawLine (int x0 , int y0 , int x1 , int y1 ) {
248+ drawLine (bitmap , x0 , y0 , x1 , y1 );
249+ }
250+
234251 public void setCurrentColor (int paletteIdx ) {
235252 colorIndex = paletteIdx ;
236253 }
@@ -267,16 +284,26 @@ public void onPaintSurface(GraphicsContext gc) {
267284
268285 if (!editMode ) return ;
269286
270- gc .setStroke (Color .BLUE );
271- gc .setLineWidth (3 );
272- gc .setLineDashes (10 , 3 );
273-
274- double wid = ((xNow - xStart ) + 1 ) * perSquareX ;
275- double hei = ((yNow - yStart ) + 1 ) * perSquareY ;
276- if (mode == DrawingMode .FILLED_RECT || mode == DrawingMode .OUTLINE_RECT || mode == DrawingMode .OUTLINE_CIRCLE ) {
277- gc .strokeRect (xStart * perSquareX , yStart * perSquareY , wid , hei );
278- } else if (mode == DrawingMode .LINE ) {
279- gc .strokeLine (xStart * perSquareX , yStart * perSquareY , xNow * perSquareX , yNow * perSquareY );
287+ if (mode == DrawingMode .FILLED_RECT || mode == DrawingMode .OUTLINE_RECT || mode == DrawingMode .OUTLINE_CIRCLE || mode == DrawingMode .LINE ) {
288+ gc .setFill (ControlColor .asFxColor (palette .getColorAt (colorIndex )));
289+ var tempBmp = bitmap .createNew (bitmap .getPixelWidth (), bitmap .getPixelHeight ());
290+ if (mode == DrawingMode .LINE ) {
291+ drawLine (tempBmp , xStart , yStart , xNow , yNow );
292+ } else if (mode == DrawingMode .FILLED_RECT ) {
293+ filledRectangle (tempBmp , xStart , yStart , xNow , yNow );
294+ } else if (mode == DrawingMode .OUTLINE_RECT ) {
295+ drawBoxOutline (tempBmp , xStart , yStart , xNow , yNow );
296+ } else if (mode == DrawingMode .OUTLINE_CIRCLE ) {
297+ int halfX = (xNow - xStart ) / 2 ;
298+ drawCircle (tempBmp , xStart + halfX , yStart + halfX , halfX );
299+ }
300+ for (int y = 0 ; y < tempBmp .getPixelHeight (); y ++) {
301+ for (int x = 0 ; x < tempBmp .getPixelWidth (); x ++) {
302+ if (tempBmp .getDataAt (x , y ) != 0 ) {
303+ gc .fillRect (x * perSquareX , y * perSquareY , perSquareX + 0.6 , perSquareY + 0.6 );
304+ }
305+ }
306+ }
280307 } else if (currentShape == DrawingMode .SELECTION && imageSelection != null ) {
281308 gc .setStroke (Color .GREENYELLOW );
282309 gc .setLineWidth (4 );
@@ -353,12 +380,17 @@ public void setFont(EmbeddedFont font) {
353380 this .embeddedFont = font ;
354381 }
355382
383+ public void setBitmap (BmpDataManager bitmap , PortablePalette palette ) {
384+ this .bitmap = bitmap ;
385+ this .palette = palette ;
386+ }
387+
356388 public void printChar (int code ) {
357389 if (embeddedFont == null ) return ;
358390 var g = embeddedFont .getGlyph (code );
359391 if (g == null ) return ;
360392
361- if (cursorX + g .calculatedWidth () > 320 ) {
393+ if (cursorX + g .calculatedWidth () > bitmap . getPixelWidth () ) {
362394 cursorX = 0 ;
363395 cursorY += embeddedFont .getYAdvance ();
364396 }
0 commit comments