org.gwtwidgets.client.ui.canvas.impl.IECanvasImpl Maven / Gradle / Ivy
/*
* Copyright 2007 Robert Hanson
*
* 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.gwtwidgets.client.ui.canvas.impl;
import org.gwtwidgets.client.ui.canvas.Canvas;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
/**
* Implementation of canvas for Internet Explorer 6.0+ based on VML.
* In order for this implementation to function, VML rendering must be enabled
* on the HTML page:
*
* <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
* <head>
* <style> v\:* { behavior: url(#default#VML); }</style >
* </head>
* ...
* </html>
*
* @author George Georgovassilis g.georgovassilis[at]gmail.com
*
*/
public class IECanvasImpl extends Canvas{
private final static String[] polyLineAtts = {"points", "filled"};
private final static String[] drawArcAtts = {"startangle","endangle"};
private final static String[] noStrokeAtts ={"stroked","filled","strokeweight"};
private final static String[] noStokeVals = {"false","false","0"};
private final StringArray sb = new StringArray();
private int width;
private int height;
private double offsetLeft;
private double offsetTop;
private String rotation = "";
private double strokeAlpha = 1;
private Element bufferTemplate;
private Element buffer;
private final Element eFill = DOM.createElement("v:fill");
private final Element eStroke = DOM.createElement("v:stroke");
private org.gwtwidgets.client.ui.canvas.Font font;
private final static String getColor(int red, int green, int blue){
return "rgb("+red+","+green+","+blue+")";
}
private native Element cloneElement(Element elem)/*-{
return elem.cloneNode(false);
}-*/;
private void clearContent(Element e){
DOM.setInnerHTML(e, "");
}
private void applyClipping(Element e){
DOM.setStyleAttribute(e, "clip", "rect(0 "+width+" "+height+" 0)");
DOM.setStyleAttribute(e, "overflow", "hidden");
}
private Element addElementPlain(String sElem, String left, String top, String width, String height, String[] attributes, String[] values) {
Element elem = DOM.createElement(sElem);
DOM.setStyleAttribute(elem, "left", left);
DOM.setStyleAttribute(elem, "top", top);
DOM.setStyleAttribute(elem, "width", width);
DOM.setStyleAttribute(elem, "height", height);
for (int i=0;i toAngle){
fromAngle-=(1+Math.floor((fromAngle-toAngle)/(Math.PI*2.0)))*Math.PI*2.0;
}
addElement("v:arc", ""+(centerLeft-radiusX+offsetLeft), ""+(centerTop-radiusY+offsetTop), ""+(radiusX*2.0), ""+(radiusY*2.0),
drawArcAtts,
new String[]{""+(fromAngle * 180.0 / Math.PI),""+(toAngle * 180.0 / Math.PI)}
);
}
public void setStrokeWeight(double weight) {
DOM.setElementAttribute(eStroke, "weight", ""+(weight));
}
public void drawPolyLine(double[] x, double[] y) {
int length = x.length;
// Unfortunately IE rotates shapes around their center and not around the coordinate system's
// offset, thus the shape has to be translated manually. Translation is time consuming, so perform it only when an offset or rotation has
// been specified.
if (getRotation()!=0 || offsetLeft!=0 || offsetTop!=0){
x = Utils.copy(x);
y = Utils.copy(y);
translate(x,y,getRotation(),offsetLeft, offsetTop);
}
for (int i = 0; i < length; i++)
sb.append(x[i]+offsetLeft).append(y[i]+offsetTop);
addElement("v:polyline", "0", "0", "1", "1",
polyLineAtts,
new String[]{sb.toString(), "false"}
);
sb.clear();
}
public void clear() {
setOffset(0,0);
setRotation(0);
clearContent(buffer);
setStroke(0, 0, 0, 1);
setFill(255, 255, 255, 1);
setStrokeWeight(1);
}
private Element createBufferTemplate(){
Element buffer = DOM.createElement("v:group");
DOM.setStyleAttribute(buffer, "position", "absolute");
DOM.setStyleAttribute(buffer, "width", width+"px");
DOM.setStyleAttribute(buffer, "height", height+"px");
DOM.setElementAttribute(buffer, "coordsize", width+","+height);
DOM.setElementAttribute(buffer, "width", width+"px");
DOM.setElementAttribute(buffer, "height", height+"px");
return buffer;
}
private void newBuffer() {
buffer = cloneElement(bufferTemplate);
}
public void flush() {
Element e = getElement();
clearContent(e);
DOM.appendChild(e, buffer);
newBuffer();
setOffset(0,0);
}
public void setFill(int red, int green, int blue, double alpha) {
DOM.setElementAttribute(eFill, "color", getColor(red, green, blue));
DOM.setElementAttribute(eFill, "opacity", ""+(alpha));
}
public void setStroke(int red, int green, int blue, double alpha) {
DOM.setElementAttribute(eStroke, "color", getColor(red, green, blue));
DOM.setElementAttribute(eStroke, "opacity", ""+(alpha));
this.strokeAlpha = alpha;
}
public void drawPolygon(double[] x, double[] y) {
// Translation is time consuming, so perform it only when an offset or rotation has
// been specified.
if (getRotation()!=0 || offsetLeft!=0 || offsetTop!=0){
x = Utils.copy(x);
y = Utils.copy(y);
translate(x,y,getRotation(),offsetLeft, offsetTop);
}
int mod = x.length;
int length = mod+1;
for (int i = 0; i < length; i++) {
sb.append(x[i % mod]+offsetLeft).append(y[i % mod]+offsetTop);
}
Element e = addElementPlain("v:polyline", "0", "0", "1", "1",
polyLineAtts,
new String[]{sb.toString(),"true"}
);
sb.clear();
addStroke(e);
addFill(e);
}
public void setRotation(double angle) {
super.setRotation(angle);
rotation = (angle*180.0/Math.PI)+"deg";
}
//TODO: fix opacity for images
public void drawImage(Element image, double sx, double sy, double swidth, double sheight, double dx, double dy, double dwidth, double dheight) {
double imageWidth = Utils.getWidth(image);
double imageHeight = Utils.getHeight(image);
double relativeOffsetLeft = sx/imageWidth;
double relativeOffsetRight = (imageWidth-swidth-sx)/imageWidth;
double relativeOffsetTop = sy/imageHeight;
double relativeOffsetBottom = (imageHeight-sheight-sy)/imageHeight;
Element rect = addElementPlain("v:rect", ""+(dx+offsetLeft), ""+(dy+offsetTop), ""+(dwidth), ""+(dheight),
noStrokeAtts,
noStokeVals
);
// painting transparent png images with alpha components causes ugly results
if (strokeAlpha!=1)
DOM.setStyleAttribute(rect, "filter","alpha(opacity="+(strokeAlpha*100)+")");
addRotation(rect);
Element eImageData = DOM.createElement("v:imagedata");
DOM.setElementAttribute(eImageData, "src", DOM.getImgSrc(image));
DOM.setElementAttribute(eImageData, "CropLeft", ""+(relativeOffsetLeft));
DOM.setElementAttribute(eImageData, "CropRight", ""+(relativeOffsetRight));
DOM.setElementAttribute(eImageData, "CropTop", ""+(relativeOffsetTop));
DOM.setElementAttribute(eImageData, "CropBottom", ""+(relativeOffsetBottom));
DOM.appendChild(rect, eImageData);
}
public void drawText(String text, double x, double y) {
font.drawText(text, this, x, y);
}
public void setFont(org.gwtwidgets.client.ui.canvas.Font font) {
this.font = font;
}
public Element prepareImage(Element image) {
return image;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy