/* * Copyright (c) 2005, 2006 data2c GmbH (www.data2c.com) * * Author: Wolfgang S. Kechel - wolfgang.kechel@data2c.com */ package org.graphics; import java.io.IOException; import java.util.Hashtable; //#ifdef j2se import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Point2D; import java.awt.Image; import java.awt.image.ImageObserver; import java.awt.Point; import java.awt.Rectangle; //#else import org.awt.Color; import org.awt.Dimension; import org.awt.geom.Point2D; import org.awt.image.ImageObserver; import org.awt.Point; import org.awt.Rectangle; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; //#endif import org.graphics.Draw; import org.graphics.VFont; /* * A Drawable operates on virtual device coordinates with 0,0 in the lower * left corner! */ public class Drawable { public static final short LT_SOLID = (short)0xffff; public static final short LT_DOTTED = (short)0xaaaa; public Drawable(Graphics agraphics,int width,int height) { super(); g = agraphics; resize(width,height); setColor(Color.BLACK); bgcol = Color.WHITE; tx = ty = .0; setDrawParams(); //Draw.translate(g,0,0); currvf = null; //#ifdef j2se setFont(new Font("SansSerif",Font.PLAIN,12)); //#else setFont(Font.getFont(Font.FACE_PROPORTIONAL,Font.STYLE_PLAIN,Font.SIZE_SMALL)); //#endif try { // currvf = loadVFont(defvfont,null); } catch(Exception e) { } } public void clear() { //System.err.println("-->Drawable.clear()"); // save status, erase, restore status Rectangle r = getClipBounds(); //System.err.println("old clip=" + r.x + "," + r.y + "," + r.width + "," + r.height); //double x = getTranslateX(); //double y = getTranslateY(); Color oldfg = getColor(); setColor(bgcol); //translate(0,0); g.setClip(0,0,w,h); g.fillRect(0,0,w,h); setColor(oldfg); //translate(x,y); setClip(r); //System.err.println("trans="+x+","+y +", clip=("+r.x+","+r.y+","+r.width+","+r.height+")"); this.needflush = true; } public void clipRect(int x,int y,int width,int height) { g.clipRect(toX(x), toY(y), width, height); } public void clipRect(Rectangle r) { clipRect(r.x, r.y, r.width, r.height); } public void copyArea(Point2D p,Dimension d,Point2D dst,int anchor) { //#ifdef j2se g.copyArea(toX(p),toY(p),d.width,d.height,toX(dst),toY(dst)); //#else g.copyArea(toX(p),toY(p),d.width,d.height,toX(dst),toY(dst),anchor); //#endif this.needflush = true; } public void drawArc(Point2D p,Dimension d,int startAngle,int arcAngle,boolean filled) { int x = toX(p); int y = toY(p); if(filled) g.fillArc(x,y,d.width,d.height,startAngle,arcAngle); g.drawArc(x,y,d.width,d.height,startAngle,arcAngle); this.needflush = true; } public void drawChar(char character, int x,int y, int anchor) { //#ifdef j2se // ignore anchor char[] cbuf = new char[1]; cbuf[0] = character; g.drawChars(cbuf,0,1,toX(x),toY(y)); //#else g.drawChar(character,toX(x),toY(y),anchor); //#endif } public void drawChar(char character, Point2D p, int anchor) { drawChar(character,round(p.getX()),round(p.getY()),anchor); } public void drawChars(char[] data,int offset, int length, int x, int y, int anchor) { //#ifdef j2se // ignore anchor g.drawChars(data,offset,length,toX(x),toY(y)); //#else g.drawChars(data,offset,length,toX(x),toY(y),anchor); //#endif } public void drawChars(char[] data,int offset, int length, Point2D p, int anchor) { drawChars(data,offset,length,round(p.getX()),round(p.getY()),anchor); } public void drawImage(Image img, int x, int y, ImageObserver observer) { //#ifdef j2se g.drawImage(img,toX(x),toY(y),observer); //#else g.drawImage(img,toX(x),toY(y),Graphics.TOP|Graphics.LEFT); //#endif this.needflush = true; } public void drawImage(Image img, Point2D p, ImageObserver observer) { drawImage(img,round(p.getX()),round(p.getY()),observer); } public void drawImage(Image img, int x, int y, int anchor) { //#ifdef j2se drawImage(img,x,y,null); //#else g.drawImage(img,toX(x),toY(y),anchor); //#endif } public void drawImage(Image img, Point2D p, int anchor) { drawImage(img,round(p.getX()),round(p.getY()),anchor); } public void drawPoint(Point2D p) { int x = toX(p); int y = toY(p); g.drawLine(x,y,x,y); this.needflush = true; } public void drawLine(int fromx,int fromy,int tox,int toy) { g.drawLine(toX(fromx),toY(fromy),toX(tox),toY(toy)); this.needflush = true; } public void drawLine(Point2D from,Point2D to) { g.drawLine(toX(from),toY(from),toX(to),toY(to)); this.needflush = true; } public void xline(Point2D from,Point2D to) { xline(round(from.getX()),round(from.getY()), round(to.getX()),round(to.getY())); } public void xline(int fromx,int fromy,int tox,int toy) { g.drawLine(fromx,fromy,tox,toy); this.needflush = true; } public void drawPolygon(int n,Point2D[] points,boolean filled) { Point[] p = new Point[n]; for(int i=0; i<n; ++i) { p[i] = new Point(toX(points[i]),toY(points[i])); } Draw.drawPolygon(g,n,p,filled); } public void drawRect(int x,int y,int width,int height, boolean filled) { int dx = toX(x); int dy = toY(y+height); if(filled) g.fillRect(dx, dy, width, height); g.drawRect(dx, dy, width, height); this.needflush = true; } public void drawRect(Point2D p,Dimension d,boolean filled) { drawRect(round(p.getX()), round(p.getY()), d.width, d.height,filled); } public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { g.drawRoundRect(toX(x),toY(y+height), width,height,arcHeight,arcHeight); this.needflush = true; } public void drawRoundRect(Point2D p,Dimension d, int arcWidth, int arcHeight) { drawRoundRect(round(p.getX()),round(p.getY()),d.width,d.height,arcHeight,arcHeight); } public void drawString(String str, int x, int y, int anchor) { //#ifdef j2se // ignore anchor g.drawString(str,toX(x),toY(y)); //#else g.drawString(str,toX(x),toY(y),anchor); //#endif this.needflush = true; } public void drawString(String str, Point2D p, int anchor) { //#ifdef j2se // ignore anchor g.drawString(str,toX(p),toY(p)); //#else g.drawString(str,toX(p),toY(p),anchor); //#endif this.needflush = true; } public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { g.fillRoundRect(toX(x),toY(y+height-1),width,height,arcHeight,arcHeight); this.needflush = true; } public void fillRoundRect(Point2D p, Dimension d, int arcWidth, int arcHeight) { fillRoundRect(round(p.getX()),round(p.getY()),d.width,d.height,arcHeight,arcHeight); } public Font getFont() { return g.getFont(); } public VFont getVFont() { return currvf; } //#ifndef j2se public void drawRegion(Image src, int srcx,int srcy,int width,int height, int transform, int dstx,int dsty, int anchor) { g.drawRegion(src,srcx,srcy,width,height,transform,toX(dstx),toY(dsty),anchor); this.needflush = true; } public void drawRegion(Image src, Point2D psrc, Dimension d, int transform, Point2D dest, int anchor) { drawRegion(src,round(psrc.getX()),round(psrc.getY()), d.width,d.height,transform, round(dest.getX()),round(dest.getY()),anchor); } public void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha) { g.drawRGB(rgbData,offset,scanlength,toX(x),toY(y),width,height,processAlpha); this.needflush = true; } public void drawRGB(int[] rgbData, int offset, int scanlength, Point2D p,Dimension d, boolean processAlpha) { drawRGB(rgbData,offset,scanlength,round(p.getX()),round(p.getY()),d.width,d.height,processAlpha); } public Rectangle getClipBounds(Rectangle r) { r.width = g.getClipWidth(); r.height = g.getClipHeight(); r.x = fromX(g.getClipX()); r.y = fromY(g.getClipY() + (r.height > 0 ? r.height - 1 : 0)); //#ifdef DEBUG System.err.println("Drawable.getclipbounds clip=" + r.x + ", " + r.y + " - " + g.getClipY() + ", " + r.width + ", " + r.height); //#endif return r; } public int getGrayScale() { return g.getGrayScale(); } public Graphics getGraphics() { return g; } public int getLineType() { return g.getStrokeStyle(); } public void fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) { g.fillTriangle(toX(x1),toY(y1),toX(x2),toY(y2),toX(x3),toY(y3)); this.needflush = true; } public void fillTriangle(Point p1,Point p2,Point p3) { fillTriangle(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y); } public void resize(int newWidth,int newHeight) { w = newWidth; h = newHeight; h1 = h - 1; setClip(0,0,w,h); } public void setGrayScale(int value) { g.setGrayScale(value); } //#else public Rectangle getClipBounds(Rectangle r) { Rectangle r = g.getClipBounds(r); r.y = fromY(g.getClipY()) + (r.height > 0 ? r.height-1 : 0); return r; } //#endif public void drawVString(String str, Point2D p) { drawVString(str,p,VFont.BOTTOM|VFont.LEFT); } public void drawVString(String str, Point2D p,int anchor) { if(currvf == null) return; currvf.drawString(str,toX(p),toY(p),null,g); this.needflush = true; } public void drawVString(String str, Point2D p,int anchor, double sx,double sy, double rotindegree,double slantintanrad) { if(currvf == null) return; currvf.drawString(str,toX(p),toY(p),anchor,sx,sy,rotindegree,slantintanrad,null,g); this.needflush = true; } public Rectangle extentVString(String str, Point2D p,int anchor,Rectangle r) { if(currvf == null) return null; r = currvf.extent(str,toX(p),toY(p),anchor,r); r.y = fromY(r.y); return r; } public Color getBackground() { return bgcol; } public Rectangle getClipBounds() { return getClipBounds(new Rectangle()); } public Color getColor() { return fgcol; } public short getLineStipple() { return linestipple; } public int getLineWidth() { return linewidth; } /* public double getTranslateX() { return tx; } public double getTranslateY() { return ty; } */ public boolean needsFlush() { return needflush; } public void flush() { needflush = false; } public void setClip(int x, int y, int width, int height) { //#ifdef DEBUG SYSTEM.err.println("Drawable.setClip to: "+x+" - "+toX(x) +", "+y+" - "+toY(y+(height > 0 ? height-1:0)) +", "+width +", "+height); //#endif g.setClip(toX(x),toY(y+(height > 0 ? height-1:0)),width,height); } public void setClip(Rectangle r) { setClip(r.x,r.y,r.width,r.height); } public void setColor(Color c) { fgcol = c; //#ifdef j2se g.setColor(c); //#else g.setColor(c.getRGB()); //#endif } public void setBackground(Color c) { if(c != bgcol) { bgcol = c; } } public void setFont(Font f) { g.setFont(f); } public void setVFont(String name) { VFont vf = loadVFont(name,null); } public void setVFont(VFont vf) { if(vf != null) currvf = vf; } public void setLineStipple(short stipple) { setLineStipple(linestipplefactor,stipple); } public void setLineStipple(int factor,short stipple) { if(stipple != linestipple || factor != linestipplefactor) { linestipple = stipple; factor = factor; setDrawParams(); } } public void setLineWidth(int width) { if(width != linewidth) { linewidth = width; setDrawParams(); } } /* public void translate(int x, int y) { translate((double)x,(double)y); } public void translate(double x, double y) { tx = x; ty = y; Draw.translate(g,round(tx),toY(round(ty))); } public void translate(Point2D p) { translate(p.getX(),p.getY()); } */ private static VFont loadVFont(String name,String resname) { VFont vf = (VFont)vfonttab.get(name); if(vf == null) { String myname = resname; if(resname == null) myname = "/"+name+".vf"; try { vf = new VFont(name,myname); } catch(IOException e) { e.printStackTrace(); } if(vf != null) vfonttab.put(name,vf); } return vf; } protected int toX(Point2D p) { return round(p.getX()); } protected int toX(int x) { return x; } protected int fromX(int x) { return x; } protected int toY(Point2D p) { return toY(round(p.getY())); } protected int toY(int y) { //System.err.println("toY("+y+") - h="+h+ ", h1="+h1+ " --> " + (h1-y)); return h1-y; } protected int fromY(int y) { return y-h1; } protected static int round(double x) { return (int)Math.floor(.5+x); } private void setDrawParams() { //#ifdef j2se if(linestipple == LT_SOLID) ((Graphics2D)g).setStroke(new BasicStroke(linewidth)); else { // everything else is dotted! float[] dashes = new float[2]; dashes[0] = linestipplefactor; dashes[1] = linestipplefactor; ((Graphics2D)g).setStroke(new BasicStroke(linewidth, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, dashes,.0f)); } //#else g.setStrokeStyle(linestipple == LT_SOLID ? Graphics.SOLID : Graphics.DOTTED); //#endif } public static final String defvfont = "futural"; //public static final String defvfont = "timesr"; protected static Hashtable vfonttab = new Hashtable(); protected Graphics g = null; protected int w = 1; // screen width protected int h = 1; // screen height private int h1 = 0; // screen height-1 protected short linestipple = LT_SOLID; // line stipple protected int linestipplefactor = 1; protected int linewidth = 1; protected double tx = 0; // x translation protected double ty = 0; // y translation protected Color fgcol = Color.black; // foreground color protected Color bgcol = Color.white; // background color protected VFont currvf = null; protected Font currf = null; protected boolean needflush = true; }