/*
* Copyright 2005-2007
* Wolfgang S. Kechel, data2c GmbH (www.data2c.com)
*
* Author: Wolfgang S. Kechel - wolfgang.kechel@data2c.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hecl.midp20.lcdui;
import java.lang.StringBuffer;
import java.util.Vector;
import java.util.Stack;
//#ifdef j2se
//import java.awt.Color;
//import java.awt.Dimension;
//import java.awt.Font;
import java.awt.geom.Point2D;
//import java.awt.Rectangle;
//#else
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import org.awt.Color;
import org.awt.Dimension;
import org.awt.geom.Point2D;
import org.awt.Rectangle;
//#endif
import org.graphics.Draw;
import org.graphics.Drawable;
import org.hecl.DoubleThing;
import org.hecl.HeclException;
import org.hecl.Interp;
import org.hecl.IntThing;
import org.hecl.ListThing;
import org.hecl.ObjectThing;
import org.hecl.Properties;
import org.hecl.Thing;
import org.hecl.misc.HeclUtils;
public class GraphicsCmd extends OptionCmd {
public static void load(Interp ip) {
ip.addClassCmd(Drawable.class,cmd);
}
public static void unload(Interp ip) {
ip.removeClassCmd(Drawable.class);
}
public Thing cmdCode(Interp interp,Thing[] argv) throws HeclException {
throw new HeclException("Invalid direct call of GraphicsCmd.cmdCode");
};
public static Thing createDrawable(Graphics g,int width,int height) {
return ObjectThing.create(new Drawable(g,width,height));
}
protected GraphicsCmd() {}
public Thing cget(Interp ip,Object target,String optname) throws HeclException {
Drawable d = (Drawable)target;
if(optname.equals(WidgetInfo.NCLIPHEIGHT))
return IntThing.create(d.getClipBounds().height);
if(optname.equals(WidgetInfo.NCLIPWIDTH))
return IntThing.create(d.getClipBounds().width);
if(optname.equals(WidgetInfo.NCLIPX))
return IntThing.create(d.getClipBounds().x);
if(optname.equals(WidgetInfo.NCLIPY))
return IntThing.create(d.getClipBounds().y);
if(optname.equals(WidgetInfo.NCOLOR))
return WidgetInfo.fromColor(d.getColor());
if(optname.equals("-background"))
return WidgetInfo.fromColor(d.getColor());
if(optname.equals(WidgetInfo.NFONT))
return FontMap.fontThing(d.getFont());
if(optname.equals("-grayscale"))
return IntThing.create(d.getGrayScale());
//#ifdef notdef
if(optname.equals("-blue"))
return IntThing.create(d.getBlueComponent());
if(optname.equals("-green"))
return IntThing.create(d.getGreenComponent());
if(optname.equals("-red"))
return IntThing.create(d.getRedComponent());
//#endif
if(optname.equals(WidgetInfo.NLINETYPE))
return IntThing.create((int)d.getLineType());
//#ifdef notdef
if(optname.equals("-translatex"))
return DoubleThing.create(d.getTranslateX());
if(optname.equals("-translatey"))
return DoubleThing.create(d.getTranslateY());
//#endif
return super.cget(ip,target,optname);
}
public void cset(Interp ip,Object target,String optname,Thing optval)
throws HeclException {
Drawable d = (Drawable)target;
if(optname.equals(WidgetInfo.NCOLOR)) {
d.setColor(new Color(WidgetInfo.toColor(optval)));
return;
}
if(optname.equals("-background")) {
d.setBackground(new Color(WidgetInfo.toColor(optval)));
return;
}
if(optname.equals("-grayscale")) {
d.setGrayScale(IntThing.get(optval));
return;
}
if(optname.equals(WidgetInfo.NFONT)) {
d.setFont(FontMap.get(optval));
return;
}
if(optname.equals(WidgetInfo.NLINETYPE)) {
d.setLineStipple((short)HeclUtils.thing2int(optval,false,0));
return;
}
//#ifdef notdef
if(optname.equals("-translatex")) {
d.translate(IntThing.get(optval),d.getTranslateY());
return;
}
if(optname.equals("-translatey")) {
d.translate(d.getTranslateX(),IntThing.get(optval));
return;
}
//#endif
super.cset(ip,target,optname,optval);
}
public synchronized Thing handlecmd(Interp ip,Object target,
String subcmd, Thing[] argv,int startat)
throws HeclException {
return sequence(ip,new Stack(),(Drawable)target,subcmd,argv,startat);
}
private synchronized Thing sequence(Interp ip,Stack st,Drawable d,
String subcmd, Thing[] argv,int startat)
throws HeclException {
int n = startat;
// Stack manipulation
if(subcmd.equals("push")) {
st.push(new Context(d));
return null;
}
if(subcmd.equals("pop")) {
if(st.empty()) {
throw new HeclException("Empty context stack.");
}
((Context)st.pop()).restore(d);
return null;
}
if(subcmd.equals("draw")) {
StringBuffer errs = null;
for(; startat+1 <= argv.length; ++startat) {
Vector v = ListThing.get(argv[startat]);
int cmdlen = v.size();
for(int pos = 0; pos < cmdlen; ++pos) {
Vector cmd = ListThing.get((Thing)v.elementAt(pos));
Thing[] xargs = new Thing[cmd.size()];
cmd.copyInto(xargs);
try {
sequence(ip,st,d,xargs[0].toString().toLowerCase(),xargs,1);
}
catch (HeclException e) {
// OOPS, error
// We create a comfortable error message with index
// into command sequence and error message for the
// errorneous command.
if(errs == null) {
errs = new StringBuffer("Error in "+subcmd+":");
}
errs.append(' ').append(startat).append(',')
.append(pos).append('-').append(e.toString());
}
}
}
if(errs != null) {
throw new HeclException(errs.toString());
}
return null;
}
// Draw commands
if(subcmd.equals("arc")) {
/* point dimension arcw, arch */
if(startat+4 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension arcw arch");
d.drawArc(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
IntThing.get(argv[startat+2]),
IntThing.get(argv[startat+3]),
false);
return null;
}
if(subcmd.equals("clear")) {
d.clear();
return null;
}
if(subcmd.equals("copyarea")) {
/* vsrc(x,y), dim(w,h) vdst(x,y), anchor */
if(startat+3 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "psrc dimension pdst [anchor]");
int anchor = startat+3 < argv.length ?
WidgetInfo.toCanvasAnchor(argv[n]) : Graphics.BOTTOM|Graphics.LEFT;
//System.err.println("anchor="+Integer.toHexString(anchor));
d.copyArea(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
HeclUtils.thing2Point(argv,startat+2), anchor);
return null;
}
if(subcmd.equals("image")) {
// image, v(x,y), anchor
if(startat+2 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "an image point [anchor]");
int anchor = startat+2 < argv.length ?
WidgetInfo.toCanvasAnchor(argv[startat+2]) : Graphics.BOTTOM|Graphics.LEFT;
//System.err.println("anchor="+Integer.toHexString(anchor));
d.drawImage(GUICmds.asImage(argv[startat],false),
HeclUtils.thing2Point(argv,startat+1), anchor);
return null;
}
if(subcmd.equals("line")) {
// v0(x,y) v1(x,y)
if(startat+2 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "frompt topt");
Point2D v0 = new Point2D.Double();
Point2D v1 = new Point2D.Double();
HeclUtils.getPoint(v0,argv,startat);
HeclUtils.getPoint(v1,argv,startat+1);
d.drawLine(v0,v1);
return null;
}
if(subcmd.equals("xline")) {
// v0(x,y) v1(x,y) [...]
if(startat+2 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "frompt topt");
Point2D v0 = new Point2D.Double();
Point2D v1 = new Point2D.Double();
HeclUtils.getPoint(v0,argv,startat);
HeclUtils.getPoint(v1,argv,startat+1);
d.xline(v0,v1);
return null;
}
if(subcmd.equals("lines")) {
// v0(x,y) v1(x,y) [...]
if(startat+1 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point0 point1 [...]");
Point2D v0 = new Point2D.Double();
Point2D v1 = new Point2D.Double();
for(; startat+1 < argv.length; startat += 2) {
HeclUtils.getPoint(v0,argv,startat);
HeclUtils.getPoint(v1,argv,startat+1);
d.drawLine(v0,v1);
}
return null;
}
if(subcmd.equals("points")) {
// v0(x,y) [...]
Point2D p = new Point2D.Double();
for(; startat < argv.length; ++startat) {
d.drawPoint(HeclUtils.getPoint(p,argv,startat));
}
return null;
}
if(subcmd.equals("linestrip")) {
// p0 p1 [...]
if(startat+2 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "p0 p1 [...]");
Point2D v0 = HeclUtils.thing2Point(argv,startat);
Point2D v1 = new Point2D.Double();
for(++startat; startat < argv.length; ++startat) {
d.drawLine(v0,HeclUtils.getPoint(v1,argv,startat));
v0.setLocation(v1.getX(),v1.getY());
}
return null;
}
if(subcmd.equals("polygon")) {
if(startat+3 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "p0 p1 p2 [...]");
Point2D[] p = getPoints(argv,startat);
d.drawPolygon(p.length,p,false);
return null;
}
if(subcmd.equals("fpolygon")) {
if(startat+3 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "p0 p1 p2 [...]");
Point2D[] p = getPoints(argv,startat);
d.drawPolygon(p.length,p,true);
return null;
}
if(subcmd.equals("rect")) {
// point dimension
if(startat+2 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension");
d.drawRect(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
false);
return null;
}
if(subcmd.equals("string")) {
if(startat+2 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point text [anchor]");
int anchor = startat+2 < argv.length ?
WidgetInfo.toCanvasAnchor(argv[startat+2]) : Graphics.BOTTOM|Graphics.LEFT;
d.drawString(argv[startat+1].toString(),
HeclUtils.thing2Point(argv,startat), anchor);
return null;
}
if(subcmd.equals("htext")) {
if(startat+2 > argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point text [anchor]");
int anchor = startat+2 < argv.length ?
WidgetInfo.toCanvasAnchor(argv[startat+2]) : Graphics.BOTTOM|Graphics.LEFT;
d.drawVString(argv[startat+1].toString(),
HeclUtils.thing2Point(argv,startat));
return null;
}
if(subcmd.equals("rrect")) {
/* p dim arcw arch */
if(startat+4 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension arcw arch");
d.drawRoundRect(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
IntThing.get(argv[startat+2]),
IntThing.get(argv[startat+3]));
return null;
}
if(subcmd.equals("farc")) {
/* x, y, w, h, arcw, argh */
if(startat+4 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension arcw arch");
d.drawArc(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
IntThing.get(argv[startat+2]),
IntThing.get(argv[startat+3]),
true);
return null;
}
if(subcmd.equals("frect")) {
// point dim
if(startat+2 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension");
d.drawRect(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
true);
return null;
}
if(subcmd.equals("frrect")) {
// point dim
if(startat+4 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension arcw arch");
d.fillRoundRect(HeclUtils.thing2Point(argv,startat),
HeclUtils.thing2Dimension(argv,startat+1),
IntThing.get(argv[startat+2]),
IntThing.get(argv[startat+3]));
return null;
}
// Get commands...
if(subcmd.startsWith("get")) {
/* no arguments */
if(startat != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "");
//#ifdef notdef
if(subcmd.equals("getblue")) {
//ip.setResult(d.getBlueComponent());
return null;
}
if(subcmd.equals("getgreen")) {
//ip.setResult(d.getGreenComponent());
return null;
}
if(subcmd.equals("getred")) {
//ip.setResult(d.getRedComponent());
return null;
}
//#endif
if(subcmd.equals("getfont"))
return FontMap.fontThing(d.getFont());
if(subcmd.equals("getgrayscale"))
return IntThing.create(d.getGrayScale());
if(subcmd.equals("getlinetype"))
IntThing.create((int)d.getLineType());
if(subcmd.equals("getcolor"))
return WidgetInfo.fromColor(d.getColor());
if(subcmd.equals("getbackground"))
return WidgetInfo.fromColor(d.getBackground());
}
//#ifdef notdef
if(subcmd.equals("displaycolor")) {
n += 1;
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "<colorspec>");
Color c = new Color(WidgetInfo.toColor(argv[startat]));
return WidgetInfo.fromColor(d.getDisplayColor(c));
}
//#endif
// Set commands
if(subcmd.equals("background")) {
/* colorspec */
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "<colorspec>");
d.setBackground(new Color(WidgetInfo.toColor(argv[startat])));
return null;
}
if(subcmd.equals("color")) {
/* colorspec */
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "<colorspec>");
d.setColor(new Color(WidgetInfo.toColor(argv[startat])));
return null;
}
if(subcmd.equals("font")) {
/* font */
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "<font>");
d.setFont(FontMap.get(argv[startat]));
return null;
}
if(subcmd.equals("grayscale")) {
/* colorspec */
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "<greyspec>");
d.setGrayScale(IntThing.get(argv[startat]));
return null;
}
if(subcmd.equals("linetype")) {
/* linetype */
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "<linetype>");
d.setLineStipple((short)HeclUtils.thing2int(argv[startat],false,0));
return null;
}
// Misc commands
if(subcmd.equals("clip")) {
// {x, y} {w, h}
if(startat+2 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point dimension");
Point2D p = HeclUtils.thing2Point(argv,startat);
Dimension dim = HeclUtils.thing2Dimension(argv,startat+1);
d.setClip((int)Math.floor(.5+p.getX()),(int)Math.floor(.5+p.getY()),
dim.width,dim.height);
return null;
}
if(subcmd.equals("cliprect")) {
/* {x, y} {w, h} */
if(startat+2 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "x y w h");
Point2D p = HeclUtils.thing2Point(argv,startat);
Dimension dim = HeclUtils.thing2Dimension(argv,startat+1);
d.clipRect((int)Math.floor(.5+p.getX()),(int)Math.floor(.5+p.getY()),
dim.width,dim.height);
return null;
}
//#ifdef notdef
if(subcmd.equals("translate")) {
// point
if(startat+1 != argv.length)
throw HeclException.createWrongNumArgsException(
argv, startat, "point");
d.translate(HeclUtils.thing2Point(argv,startat));
return null;
}
//#endif
return super.handlecmd(ip,d,subcmd,argv,startat);
}
private Point2D[] getPoints(Thing[] argv,int startat)
throws HeclException {
int n = (argv.length - startat);
Point2D[] points = new Point2D[n];
for(int i=0; startat<argv.length; ++startat, ++i) {
points[i] = HeclUtils.thing2Point(argv,startat);
//System.out.println("point["+i+"]="+points[i].getX()+", "+points[i].getY());
}
return points;
}
protected boolean needflush = true;
//#ifdef notdef
private int mytx = 0;
private int myty = 0;
//#endif
private Drawable drawable;
private static GraphicsCmd cmd = new GraphicsCmd();
}
class Context {
protected Context(Drawable d) {
cliprect = new Rectangle();
Graphics g = d.getGraphics();
fcol = d.getColor();
bcol = d.getBackground();
gray = d.getGrayScale();
font = d.getFont();
linestipple = d.getLineStipple();
linewidth = d.getLineWidth();
d.getClipBounds(cliprect);
//#ifdef notdef
mytx = d.getTranslateX();
myty = d.getTranslateY();
//#endif
}
protected void restore(Drawable d) {
Graphics g = d.getGraphics();
d.setColor(fcol);
d.setBackground(bcol);
d.setGrayScale(gray);
d.setLineStipple(linestipple);
d.setLineWidth(linewidth);
d.setClip(cliprect);
d.setFont(font);
//#ifdef notdef
d.translate(mytx,myty);
//#endif
}
private Color fcol;
private Color bcol;
private int gray;
private Font font;
private short linestipple;
private int linewidth;
private Rectangle cliprect;
//#ifdef notdef
private double mytx;
private double myty;
//#endif
}
// Variables:
// mode:java
// coding:utf-8
// End: