/** * Copyright 2010 The ForPlay Authors * * 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 forplay.html; import com.google.gwt.canvas.dom.client.CanvasGradient; import com.google.gwt.canvas.dom.client.CanvasPattern; import com.google.gwt.canvas.dom.client.Context2d; import com.google.gwt.canvas.dom.client.Context2d.Repetition; import com.google.gwt.canvas.dom.client.CssColor; import com.google.gwt.dom.client.CanvasElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.ImageElement; import com.google.gwt.dom.client.Style.Unit; import forplay.core.Asserts; import forplay.core.CanvasImage; import forplay.core.Gradient; import forplay.core.Graphics; import forplay.core.Image; import forplay.core.Path; import forplay.core.Pattern; public abstract class HtmlGraphics implements Graphics { static CssColor cssColor(int color) { return CssColor.make(cssColorString(color)); } static String cssColorString(int color) { double a = ((color >> 24) & 0xff) / 255.0; int r = (color >> 16) & 0xff; int g = (color >> 8) & 0xff; int b = (color >> 0) & 0xff; return "rgba(" + r + "," + g + "," + b + "," + a + ")"; } private static native void setLoadHandlers(ImageElement img, EventHandler onload, EventHandler onerror) /*-{ img.onload = function(e) { onload.@forplay.html.EventHandler::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e); }; img.onerror = function(e) { onerror.@forplay.html.EventHandler::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e); }; }-*/; protected CanvasElement dummyCanvas; protected Element rootElement; private final Context2d dummyCtx; protected HtmlGraphics() { Document doc = Document.get(); dummyCanvas = doc.createCanvasElement(); dummyCtx = dummyCanvas.getContext2d(); rootElement = doc.getElementById("forplay-root"); if (rootElement == null) { rootElement = doc.getBody(); } else { // clear the contents of the "forplay-root" element, if present rootElement.setInnerHTML(""); } } @Override public CanvasImage createImage(int w, int h) { HtmlCanvas surface = new HtmlCanvas(w, h); return new HtmlCanvasImage(surface); } @Override public Gradient createLinearGradient(float x0, float y0, float x1, float y1, int[] colors, float[] positions) { Asserts.checkArgument(colors.length == positions.length); CanvasGradient gradient = dummyCtx.createLinearGradient(x0, y0, x1, y1); for (int i = 0; i < colors.length; ++i) { gradient.addColorStop(positions[i], cssColorString(colors[i])); } return new HtmlGradient(gradient); } @Override public Path createPath() { return new HtmlPath(); } @Override public Pattern createPattern(Image image) { Asserts.checkArgument(image instanceof HtmlImage); HtmlImage htmlImage = (HtmlImage) image; ImageElement elem = htmlImage.img.cast(); CanvasPattern pattern = dummyCtx.createPattern(elem, Repetition.REPEAT); return new HtmlPattern(htmlImage, pattern); } @Override public Gradient createRadialGradient(float x, float y, float r, int[] colors, float[] positions) { Asserts.checkArgument(colors.length == positions.length); CanvasGradient gradient = dummyCtx.createRadialGradient(x, y, r, x, y, r); for (int i = 0; i < colors.length; ++i) { gradient.addColorStop(positions[i], cssColorString(colors[i])); } return new HtmlGradient(gradient); } @Override public int screenHeight() { return Document.get().getDocumentElement().getClientHeight(); } @Override public int screenWidth() { return Document.get().getDocumentElement().getClientWidth(); } @Override public void setSize(int width, int height) { rootElement.getStyle().setWidth(width, Unit.PX); rootElement.getStyle().setHeight(height, Unit.PX); } abstract void updateLayers(); abstract Element getRootElement(); }