/**
* Copyright 2007-2010 非也
* All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License v3 as published by the Free Software
* Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
*
*/
package org.fireflow.designer.swing.mxgraphext.canvas;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import org.fireflow.clientwidget.servlet.Constants;
import org.fireflow.clientwidget.tag.ClientWidgetBase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.mxgraph.canvas.mxVmlCanvas;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxUtils;
/**
*
* @author 非也 nychen2000@163.com
* Fire Workflow 官方网站:www.firesoa.com 或者 www.fireflow.org
*
*/
public class VmlCanvasEx extends mxVmlCanvas {
private int width = 100;
private int height = 100;
private String clientWidgetServletPath = ClientWidgetBase.Fireflow_ClientWidget_Servlet_Path;
private String contextPath = "";
// /**
// *
// */
// public VmlCanvasEx() {
// super();
// // TODO Auto-generated constructor stub
// }
/**
* @param document
*/
public VmlCanvasEx(Document document,int width,int height,String clientWidgetServletPath,String contextPath,String vmlId) {
super(document);
this.width = width;
this.height = height;
this.clientWidgetServletPath = clientWidgetServletPath;
this.contextPath = contextPath;
if (this.contextPath==null)this.contextPath = "";
if (this.clientWidgetServletPath==null) this.clientWidgetServletPath="";
if (this.contextPath.endsWith("/") && this.clientWidgetServletPath.startsWith("/")){
this.contextPath = this.contextPath.substring(0,contextPath.length()-1);
}
//构造document根元素
Element root = document.createElement("v:group");
root.setAttribute("id", vmlId);
document.appendChild(root);
StringBuffer styleBuf = new StringBuffer();
styleBuf.append("position:relative;")
.append("width:").append(width).append("px;")
.append("height:").append(height).append("px;");
root.setAttribute("style", styleBuf.toString());
StringBuffer coordSizeBuf = new StringBuffer();
coordSizeBuf.append(width).append(",").append(height);
root.setAttribute("coordsize", coordSizeBuf.toString());
}
public void appendVmlElement(Element node)
{
if (document != null)
{
// Node body = document.getDocumentElement().getFirstChild()
// .getNextSibling();
Node body = document.getDocumentElement();
if (body != null)
{
body.appendChild(node);
}
}
}
public Element drawShape(int x, int y, int w, int h,
Map<String, Object> style)
{
String fillColor = mxUtils
.getString(style, mxConstants.STYLE_FILLCOLOR);
String strokeColor = mxUtils.getString(style,
mxConstants.STYLE_STROKECOLOR);
float strokeWidth = (float) (mxUtils.getFloat(style,
mxConstants.STYLE_STROKEWIDTH, 1) * scale);
// Draws the shape
String shape = mxUtils.getString(style, mxConstants.STYLE_SHAPE);
Element elem = null;
if (shape.equals(mxConstants.SHAPE_IMAGE))
{
String img = getImageForStyle(style);
String imgUri = contextPath+this.clientWidgetServletPath+img;
if (img != null)
{
elem = document.createElement("v:image");
elem.setAttribute("src", imgUri);
}
}
else if (shape.equals(mxConstants.SHAPE_LINE))
{
String direction = mxUtils.getString(style,
mxConstants.STYLE_DIRECTION, mxConstants.DIRECTION_EAST);
String points = null;
if (direction.equals(mxConstants.DIRECTION_EAST)
|| direction.equals(mxConstants.DIRECTION_WEST))
{
int mid = Math.round(h / 2);
points = "m 0 " + mid + " l " + w + " " + mid;
}
else
{
int mid = Math.round(w / 2);
points = "m " + mid + " 0 L " + mid + " " + h;
}
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_ELLIPSE))
{
elem = document.createElement("v:oval");
}
else if (shape.equals(mxConstants.SHAPE_DOUBLE_ELLIPSE))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
int inset = (int) ((3 + strokeWidth) * scale);
String points = "ar 0 0 " + w + " " + h + " 0 " + (h / 2) + " "
+ (w / 2) + " " + (h / 2) + " e ar " + inset + " " + inset
+ " " + (w - inset) + " " + (h - inset) + " 0 " + (h / 2)
+ " " + (w / 2) + " " + (h / 2);
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_RHOMBUS))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
String points = "m " + (w / 2) + " 0 l " + w + " " + (h / 2)
+ " l " + (w / 2) + " " + h + " l 0 " + (h / 2);
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_TRIANGLE))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
String direction = mxUtils.getString(style,
mxConstants.STYLE_DIRECTION, "");
String points = null;
if (direction.equals(mxConstants.DIRECTION_NORTH))
{
points = "m 0 " + h + " l " + (w / 2) + " 0 " + " l " + w + " "
+ h;
}
else if (direction.equals(mxConstants.DIRECTION_SOUTH))
{
points = "m 0 0 l " + (w / 2) + " " + h + " l " + w + " 0";
}
else if (direction.equals(mxConstants.DIRECTION_WEST))
{
points = "m " + w + " 0 l " + w + " " + (h / 2) + " l " + w
+ " " + h;
}
else
// east
{
points = "m 0 0 l " + w + " " + (h / 2) + " l 0 " + h;
}
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_HEXAGON))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
String direction = mxUtils.getString(style,
mxConstants.STYLE_DIRECTION, "");
String points = null;
if (direction.equals(mxConstants.DIRECTION_NORTH)
|| direction.equals(mxConstants.DIRECTION_SOUTH))
{
points = "m " + (int) (0.5 * w) + " 0 l " + w + " "
+ (int) (0.25 * h) + " l " + w + " " + (int) (0.75 * h)
+ " l " + (int) (0.5 * w) + " " + h + " l 0 "
+ (int) (0.75 * h) + " l 0 " + (int) (0.25 * h);
}
else
{
points = "m " + (int) (0.25 * w) + " 0 l " + (int) (0.75 * w)
+ " 0 l " + w + " " + (int) (0.5 * h) + " l "
+ (int) (0.75 * w) + " " + h + " l " + (int) (0.25 * w)
+ " " + h + " l 0 " + (int) (0.5 * h);
}
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_CLOUD))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
String points = "m " + (int) (0.25 * w) + " " + (int) (0.25 * h)
+ " c " + (int) (0.05 * w) + " " + (int) (0.25 * h) + " 0 "
+ (int) (0.5 * h) + " " + (int) (0.16 * w) + " "
+ (int) (0.55 * h) + " c 0 " + (int) (0.66 * h) + " "
+ (int) (0.18 * w) + " " + (int) (0.9 * h) + " "
+ (int) (0.31 * w) + " " + (int) (0.8 * h) + " c "
+ (int) (0.4 * w) + " " + (h) + " " + (int) (0.7 * w) + " "
+ (h) + " " + (int) (0.8 * w) + " " + (int) (0.8 * h)
+ " c " + (w) + " " + (int) (0.8 * h) + " " + (w) + " "
+ (int) (0.6 * h) + " " + (int) (0.875 * w) + " "
+ (int) (0.5 * h) + " c " + (w) + " " + (int) (0.3 * h)
+ " " + (int) (0.8 * w) + " " + (int) (0.1 * h) + " "
+ (int) (0.625 * w) + " " + (int) (0.2 * h) + " c "
+ (int) (0.5 * w) + " " + (int) (0.05 * h) + " "
+ (int) (0.3 * w) + " " + (int) (0.05 * h) + " "
+ (int) (0.25 * w) + " " + (int) (0.25 * h);
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_ACTOR))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
double width3 = w / 3;
String points = "m 0 " + (h) + " C 0 " + (3 * h / 5) + " 0 "
+ (2 * h / 5) + " " + (w / 2) + " " + (2 * h / 5) + " c "
+ (int) (w / 2 - width3) + " " + (2 * h / 5) + " "
+ (int) (w / 2 - width3) + " 0 " + (w / 2) + " 0 c "
+ (int) (w / 2 + width3) + " 0 " + (int) (w / 2 + width3)
+ " " + (2 * h / 5) + " " + (w / 2) + " " + (2 * h / 5)
+ " c " + (w) + " " + (2 * h / 5) + " " + (w) + " "
+ (3 * h / 5) + " " + (w) + " " + (h);
elem.setAttribute("path", points + " x e");
}
else if (shape.equals(mxConstants.SHAPE_CYLINDER))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
double dy = Math.min(40, Math.floor(h / 5));
String points = "m 0 " + (int) (dy) + " C 0 " + (int) (dy / 3)
+ " " + (w) + " " + (int) (dy / 3) + " " + (w) + " "
+ (int) (dy) + " L " + (w) + " " + (int) (h - dy) + " C "
+ (w) + " " + (int) (h + dy / 3) + " 0 "
+ (int) (h + dy / 3) + " 0 " + (int) (h - dy) + " x e"
+ " m 0 " + (int) (dy) + " C 0 " + (int) (2 * dy) + " "
+ (w) + " " + (int) (2 * dy) + " " + (w) + " " + (int) (dy);
elem.setAttribute("path", points + " e");
}
/*
else if (shape.equals(CommentShape.SHAPE_FIREFLOW_COMMENT))
{
elem = document.createElement("v:shape");
elem.setAttribute("coordsize", w + " " + h);
String points = "m " + (w / 3) + " 0 l 0 0" +
" l " + (0) + " " + h + " l "+(w/3) +" " +(h );
elem.setAttribute("path", points + " x e");
}
*/
else
{
if (mxUtils.isTrue(style, mxConstants.STYLE_ROUNDED, false))
{
elem = document.createElement("v:roundrect");
elem.setAttribute("arcsize",
(mxConstants.RECTANGLE_ROUNDING_FACTOR * 100) + "%");
}
else
{
elem = document.createElement("v:rect");
}
}
String s = "position:absolute;left:" + String.valueOf(x) + "px;top:"
+ String.valueOf(y) + "px;width:" + String.valueOf(w)
+ "px;height:" + String.valueOf(h) + "px;";
// Applies rotation
double rotation = mxUtils.getDouble(style, mxConstants.STYLE_ROTATION);
if (rotation != 0)
{
s += "rotation:" + rotation + ";";
}
elem.setAttribute("style", s);
// Adds the shadow element
if (mxUtils.isTrue(style, mxConstants.STYLE_SHADOW, false)
&& fillColor != null)
{
Element shadow = document.createElement("v:shadow");
shadow.setAttribute("on", "true");
shadow.setAttribute("color", mxConstants.W3C_SHADOWCOLOR);
elem.appendChild(shadow);
}
float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY, 100);
// Applies opacity to fill
if (fillColor != null)
{
Element fill = document.createElement("v:fill");
fill.setAttribute("color", fillColor);
if (opacity != 100)
{
fill.setAttribute("opacity", String.valueOf(opacity / 100));
}
elem.appendChild(fill);
}
else
{
elem.setAttribute("filled", "false");
}
// Applies opacity to stroke
if (strokeColor != null)
{
elem.setAttribute("strokecolor", strokeColor);
Element stroke = document.createElement("v:stroke");
if (opacity != 100)
{
stroke.setAttribute("opacity", String.valueOf(opacity / 100));
}
elem.appendChild(stroke);
}
else
{
elem.setAttribute("stroked", "false");
}
elem.setAttribute("strokeweight", String.valueOf(strokeWidth) + "px");
appendVmlElement(elem);
return elem;
}
public Element drawText(String text, int x, int y, int w, int h,
Map<String, Object> style)
{
if(text==null || text.trim().equals("")){
return null;
}
Element table = mxUtils.createTable(document, text, x, y, w, h, scale,
style);
appendVmlElement(table);
return table;
}
}