Revision: 4746 http://sourceforge.net/p/vexi/code/4746 Author: mkpg2 Date: 2014-11-13 00:43:17 +0000 (Thu, 13 Nov 2014) Log Message: ----------- Improve canvas. - load/save support. - anti alias drawing
Modified Paths: -------------- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Canvas.java branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/AWTBase.java Added Paths: ----------- branches/vexi3/org.vexi-vexi.demo/src_main/org/vexi/demo/image/block_mask_20x20.png branches/vexi3/org.vexi-vexi.demo/src_poke/poke/ branches/vexi3/org.vexi-vexi.demo/src_poke/poke/core/ branches/vexi3/org.vexi-vexi.demo/src_poke/poke/core/canvas.t Removed Paths: ------------- branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/core/canvas.t Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Canvas.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Canvas.java 2014-11-12 13:16:54 UTC (rev 4745) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/core/Canvas.java 2014-11-13 00:43:17 UTC (rev 4746) @@ -3,11 +3,11 @@ import java.awt.BasicStroke; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.ObjectOutputStream; import javax.imageio.ImageIO; @@ -28,20 +28,36 @@ private BufferedImage buffer; private float strokeWidth = 1; private int drawColor = 0xffffffff; + private float dotsPerPixel = 1; + private boolean antialias = true; public Canvas(){ visual = new BoxVisual(); - visual.texture = this; + visual.texture = this; + // REMARK necessary otherwise box will attempt to scale the image + // It is confusing because there is no tiling. In a normal + // vexi box tile=true shrink=true will result in a box the size of + // the image. For the canvas the image will resize to be the size + // of the Canvas. + set(TILE_IMAGE); } public Object getImage() { return getBuffer(); } - public int getWidth() { return width; } - public int getHeight() { return height; } + public int getWidth() { return scale(width); } + public int getHeight() { return scale(height); } + private int scale(int coord){ + return (int)(dotsPerPixel*coord); + } + @Override public JS get(JS name) throws JSExn { String nameStr = JSU.toString(name); if("drawLine".equals(nameStr)) return METHOD; if("drawColor".equals(nameStr)) return JSU.S(Color.colorToString(drawColor)); - if("drawWidth".equals(nameStr)) return JSU.N(strokeWidth); + if("drawWidth".equals(nameStr)) return JSU.N(strokeWidth); + if("antialias".equals(nameStr)) return JSU.B(antialias); + if("dotsPerPixel".equals(nameStr)) return JSU.N(dotsPerPixel); + if("load".equals(nameStr)) return METHOD; + if("save".equals(nameStr)) return METHOD; return super.get(name); } @@ -55,6 +71,14 @@ strokeWidth = (float)JSU.toDouble(value); return; } + if("antialias".equals(nameStr)){ + antialias = JSU.isTruthy(value); + return; + } + if("dotsPerPixel".equals(nameStr)){ + dotsPerPixel = (float)JSU.getNumber(value).toDouble(); + return; + } super.put(name, value); } @@ -68,10 +92,24 @@ Graphics2D graphics2D = (Graphics2D)getBuffer().getGraphics(); graphics2D.setColor(Color.intToColor(drawColor)); graphics2D.setStroke(new BasicStroke(strokeWidth)); - graphics2D.drawLine(x1, y1, x2, y2); - dirty(); + graphics2D.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + antialias?RenderingHints.VALUE_ANTIALIAS_ON:RenderingHints.VALUE_ANTIALIAS_OFF); + graphics2D.drawLine( + scale(x1), + scale(y1), + scale(x2), + scale(y2)); + dirty(); // dirty(this, x1-1,y1-1,x2+1,y2+1); return null; + }else if("save".equals(nameStr)){ + String format = JSU.expectArg_string(args, 0); + return getStream(format); + }else if("load".equals(nameStr)){ + JS file = JSU.expectArg(args, 0); + setStream(file); + return null; } return super.callMethod(this_, method, args); } @@ -82,8 +120,10 @@ }else if(buffer==null){ buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); }else{ - if(buffer.getHeight()!=height || buffer.getWidth()!=width){ - BufferedImage buffer1 = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + final int heightPixels = (int)(height*dotsPerPixel); + final int widthPixels = (int)(width*dotsPerPixel); + if(buffer.getHeight()!=(heightPixels) || buffer.getWidth()!=(widthPixels)){ + BufferedImage buffer1 = new BufferedImage(widthPixels, heightPixels, BufferedImage.TYPE_INT_ARGB); Graphics2D g0 = (Graphics2D)buffer.getGraphics(); Graphics2D g1 = (Graphics2D)buffer1.getGraphics(); g1.drawImage(buffer, 0, 0, null); @@ -100,32 +140,41 @@ getBuffer(); } - public JS getStream() { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + public JS getStream(){ + return getStream("png"); + } + + public JS getStream(String format) { try{ - ObjectOutputStream oos = new ObjectOutputStream(baos); - ImageIO.write(getBuffer(),"png",ImageIO.createImageOutputStream(oos)); - oos.flush(); - oos.close(); - return new Fountain.ByteArray(baos.toByteArray()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageIO.write(getBuffer(),format,ImageIO.createImageOutputStream(baos)); + baos.flush(); + baos.close(); + byte[] bytes = baos.toByteArray(); + return new Fountain.ByteArray(bytes); }catch(Exception e){ throw new Error(e); } } - synchronized public void setStream(JS f) throws IOException{ - InputStream is = JSU.getInputStream(f); - Image img= ImageIO.read(ImageIO.createImageInputStream(is)); - - BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); - - // Draw the image on to the buffered image - Graphics2D bGr = bimage.createGraphics(); - bGr.drawImage(img, 0, 0, null); - bGr.dispose(); - - // Return the buffered image - buffer = bimage; + synchronized public void setStream(JS f) throws JSExn { + try{ + InputStream is = JSU.getInputStream(f); + Image img= ImageIO.read(ImageIO.createImageInputStream(is)); + + BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); + + // Draw the image on to the buffered image + Graphics2D bGr = bimage.createGraphics(); + bGr.drawImage(img, 0, 0, null); + bGr.dispose(); + + // Return the buffered image + buffer = bimage; + dirty(); + }catch(IOException e){ + throw new JSExn(e); + } } public boolean isLoaded() { return true; } Modified: branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/AWTBase.java =================================================================== --- branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/AWTBase.java 2014-11-12 13:16:54 UTC (rev 4745) +++ branches/vexi3/org.vexi-core.main/src/main/java/org/vexi/plat/AWTBase.java 2014-11-13 00:43:17 UTC (rev 4746) @@ -346,7 +346,7 @@ /** draw an scaled image */ public void drawPicture(Texture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) { - ((AWTPicture)source).init(); + source.init(); g.drawImage((Image)source.getImage(), dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null); } Added: branches/vexi3/org.vexi-vexi.demo/src_main/org/vexi/demo/image/block_mask_20x20.png =================================================================== (Binary files differ) Index: branches/vexi3/org.vexi-vexi.demo/src_main/org/vexi/demo/image/block_mask_20x20.png =================================================================== --- branches/vexi3/org.vexi-vexi.demo/src_main/org/vexi/demo/image/block_mask_20x20.png 2014-11-12 13:16:54 UTC (rev 4745) +++ branches/vexi3/org.vexi-vexi.demo/src_main/org/vexi/demo/image/block_mask_20x20.png 2014-11-13 00:43:17 UTC (rev 4746) Property changes on: branches/vexi3/org.vexi-vexi.demo/src_main/org/vexi/demo/image/block_mask_20x20.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Copied: branches/vexi3/org.vexi-vexi.demo/src_poke/poke/core/canvas.t (from rev 4744, branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/core/canvas.t) =================================================================== --- branches/vexi3/org.vexi-vexi.demo/src_poke/poke/core/canvas.t (rev 0) +++ branches/vexi3/org.vexi-vexi.demo/src_poke/poke/core/canvas.t 2014-11-13 00:43:17 UTC (rev 4746) @@ -0,0 +1,105 @@ +<!-- public domain --> + +<vexi xmlns:ui="vexi://ui" + xmlns:w="vexi.widget" + xmlns:image="org.vexi.demo.image" + xmlns:demo="org.vexi.demo"> + <w:surface /> + <ui:box frameheight="600" framewidth="500" orient="vertical"> + <w:bevel form="down" shrink="true"> + <ui:Box layout="layer" + width="400" + height="400" > + <ui:Box id="background" fill=":image.block_mask_20x20"/> + <ui:Canvas id="canvas" + tile="false" + dotsPerPixel="1"> + drawColor = "black"; + drawWidth = 2; + + var draw = false; + var x0; + var y0; + thisbox.Press1 ++= function(v){ + cascade = v; + draw = true; + const s = surface; + const frameToThis = s.frame.distanceto(thisbox); + const m = s.frame.mouse; + x0 = m.x-frameToThis.x; + y0 = m.y-frameToThis.y; + drawLine(x0,y0,x0,y0); + } + + thisbox.Release1 ++= function(v){ + cascade = v; + draw = false; + }; + + thisbox.Enter ++= function(v){ + cascade = v; + if(draw){ + const s = surface; + const frameToThis = s.frame.distanceto(thisbox); + const m = s.frame.mouse; + x0 = m.x-frameToThis.x; + y0 = m.y-frameToThis.y; + } + }; + + + thisbox.Move ++= function(v){ + cascade = v; + if(draw){ + const s = surface; + const frameToThis = s.frame.distanceto(thisbox); + const m = s.frame.mouse; + var x1 = m.x-frameToThis.x; + var y1 = m.y-frameToThis.y; + drawLine(x0,y0,x1,y1); + x0 = x1; + y0 = y1; + } + } + </ui:Canvas> + + </ui:Box> + </w:bevel> + <ui:Box height="50"> + <w:button text="Save" id="save"/> + <w:button text="Load" id="load"/> + <w:button text="Load Background" id="loadbg"/> + </ui:Box> + + var suffix = "png"; + + $save.action ++= function(v){ + vexi.thread = function(){ + var file = vexi.file.save("canvas."+suffix); + if(file!=null){ + var png = $canvas.save(suffix); + vexi.stream.pipe(png, file); + } + } + }; + + + $load.action ++= function(v){ + vexi.thread = function(){ + var file = vexi.file.load(); + $canvas.load(file); + } + }; + + + + $loadbg.action ++= function(v){ + vexi.thread = function(){ + var file = vexi.file.load(); + $background.fill = file; + } + }; + + vexi.ui.frame = thisbox; + </ui:box> +</vexi> \ No newline at end of file Deleted: branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/core/canvas.t =================================================================== --- branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/core/canvas.t 2014-11-12 13:16:54 UTC (rev 4745) +++ branches/vexi3/org.vexi-vexi.widgets/src_poke/poke/core/canvas.t 2014-11-13 00:43:17 UTC (rev 4746) @@ -1,58 +0,0 @@ -<!-- public domain --> - -<vexi xmlns:ui="vexi://ui" xmlns:w="vexi.widget"> - <w:surface /> - <ui:box frameheight="500" framewidth="500"> - <ui:Canvas width="400" height="400"> - drawColor = "black"; - drawWidth = 2; - - var draw = false; - var x0; - var y0; - thisbox.Press1 ++= function(v){ - cascade = v; - draw = true; - const s = surface; - const frameToThis = s.frame.distanceto(thisbox); - const m = s.frame.mouse; - x0 = m.x-frameToThis.x; - y0 = m.y-frameToThis.y; - drawLine(x0,y0,x0,y0); - } - - thisbox.Release1 ++= function(v){ - cascade = v; - draw = false; - }; - - thisbox.Enter ++= function(v){ - cascade = v; - if(draw){ - const s = surface; - const frameToThis = s.frame.distanceto(thisbox); - const m = s.frame.mouse; - x0 = m.x-frameToThis.x; - y0 = m.y-frameToThis.y; - } - }; - - - thisbox.Move ++= function(v){ - cascade = v; - if(draw){ - const s = surface; - const frameToThis = s.frame.distanceto(thisbox); - const m = s.frame.mouse; - var x1 = m.x-frameToThis.x; - var y1 = m.y-frameToThis.y; - drawLine(x0,y0,x1,y1); - x0 = x1; - y0 = y1; - } - } - </ui:Canvas> - - vexi.ui.frame = thisbox; - </ui:box> -</vexi> \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Comprehensive Server Monitoring with Site24x7. Monitor 10 servers for $9/Month. Get alerted through email, SMS, voice calls or mobile push notifications. Take corrective actions from your mobile device. http://pubads.g.doubleclick.net/gampad/clk?id=154624111&iu=/4140/ostg.clktrk _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn