org.catrobat.html5player.client.Scene.java Source code

Java tutorial

Introduction

Here is the source code for org.catrobat.html5player.client.Scene.java

Source

/**
 *  Catroid: An on-device visual programming system for Android devices
 *  Copyright (C) 2010-2014 The Catrobat Team
 *  (<http://developer.catrobat.org/credits>)
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  An additional term exception under section 7 of the GNU Affero
 *  General Public License, version 3, is available at
 *  http://developer.catrobat.org/license_additional_term
 *
 *  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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.catrobat.html5player.client;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.CanvasPixelArray;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.canvas.dom.client.ImageData;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.dom.client.ImageElement;
import com.google.gwt.user.client.ui.Image;

public class Scene {

    private static Scene instance = null;

    private Canvas sceneCanvas;
    private boolean isSceneCreated;
    private CssColor fillColor;

    private int sceneWidth = 0;
    private int sceneHeight = 0;

    //##########################################################################

    private Scene() {
        isSceneCreated = false;
    }

    /**
     *
     */
    public static Scene get() {
        if (instance == null) {
            instance = new Scene();
        }

        return instance;
    }

    //##########################################################################

    /**
     * Create a canvas
     * @return true if scene is created or was already created, false if canvas
     * is not supported
     */
    public boolean createScene() {

        if (!isSceneCreated) {
            sceneCanvas = Canvas.createIfSupported();

            if (sceneCanvas == null)
                return false;

            isSceneCreated = true;
            fillColor = CssColor.make("rgb(255,255,255)");
        }

        CatrobatDebug.info("Scene created");

        return true;
    }

    /**
     * Create a canvas with the given measures
     * @param sceneWidth
     * @param sceneHeight
     * @return true if scene is created or was already created, false if canvas
     * is not supported
     */
    public boolean createScene(int sceneWidth, int sceneHeight) {

        if (createScene()) {
            setSceneMeasures(sceneWidth, sceneHeight);
            CatrobatDebug.info("Scene created with width: " + sceneWidth + " and height: " + sceneHeight);
            return true;
        }

        return false;
    }

    /**
     * Sets the given measures for front and back canvas
     * @param sceneWidth
     * @param sceneHeight
     */
    public void setSceneMeasures(int sceneWidth, int sceneHeight) {

        if (isSceneCreated) {
            clearCanvas();

            this.sceneWidth = sceneWidth;
            this.sceneHeight = sceneHeight;

            sceneCanvas.setWidth(sceneWidth + "px");
            sceneCanvas.setHeight(sceneHeight + "px");

            sceneCanvas.setCoordinateSpaceWidth(this.sceneWidth);
            sceneCanvas.setCoordinateSpaceHeight(this.sceneHeight);

            //         back.getContext2d().translate(sceneWidth/2, sceneHeight/2);

            CatrobatDebug
                    .debug("Scene got measures - width: " + this.sceneWidth + " and height: " + this.sceneHeight);
        }
    }

    public void zoomScene(double zoomValue) {

        this.sceneWidth = (int) (this.sceneWidth * zoomValue);
        this.sceneHeight = (int) (this.sceneHeight * zoomValue);

        sceneCanvas.setWidth(this.sceneWidth + "px");
        sceneCanvas.setHeight(this.sceneHeight + "px");

    }

    //############################ DRAW IMAGE ##################################

    /**
     *
     * @param image
     * @param x
     * @param y
     * @param width
     * @param height
     */
    public void drawImage(Image image, double x, double y, double width, double height, double alpha) {
        ImageElement imageElement = (ImageElement) image.getElement().cast();

        drawImageElement(imageElement, x, y, width, height, alpha);
    }

    /**
     *
     * @param imageElement
     * @param x
     * @param y
     * @param width
     * @param height
     */
    public void drawImageElement(ImageElement imageElement, double x, double y, double width, double height,
            double alpha) {

        long start = System.currentTimeMillis();

        Context2d context = sceneCanvas.getContext2d();
        context.save();
        context.setGlobalAlpha(alpha);
        context.drawImage(imageElement, x, y, width, height);
        context.restore();

        CatrobatDebug.debug("drawImageElement-execution took " + (System.currentTimeMillis() - start) + " ms");
    }

    /**
     *
     * @param image
     * @param translateX
     * @param translateY
     * @param x
     * @param y
     * @param width
     * @param height
     * @param degrees
     * @param xSize
     * @param ySize
     */
    public void drawImage(Image image, double translateX, double translateY, double x, double y, double width,
            double height, double degrees, double xSize, double ySize, double alpha) {

        long start = System.currentTimeMillis();

        ImageElement imageElement = (ImageElement) image.getElement().cast();

        drawImageElement(imageElement, translateX, translateY, x, y, width, height, degrees, xSize, ySize, alpha);

        CatrobatDebug.debug("drawImage-execution took " + (System.currentTimeMillis() - start) + " ms");
    }

    /**
     *
     * @param imageElement
     * @param translateX
     * @param translateY
     * @param x
     * @param y
     * @param width
     * @param height
     * @param degrees
     * @param xSize
     * @param ySize
     */
    public void drawImageElement(ImageElement imageElement, double translateX, double translateY, double x,
            double y, double width, double height, double degrees, double xSize, double ySize, double alpha) {

        long start = System.currentTimeMillis();

        Context2d context = sceneCanvas.getContext2d();

        context.save();
        context.setGlobalAlpha(alpha);
        context.translate(translateX, translateY);
        context.rotate(Math.toRadians(degrees));
        context.scale(xSize, ySize);
        context.drawImage(imageElement, x, y, width, height);

        //for testing - draws a rectangular around the sprite
        //      context.strokeRect(x, y, width, height);
        //

        context.restore();

        CatrobatDebug.debug("drawImageElement-execution took " + (System.currentTimeMillis() - start) + " ms");
    }

    //############################### TEXT #####################################

    /**
     *
     * @param fontSetting
     */
    public void setFont(String fontSetting) {
        sceneCanvas.getContext2d().setFont(fontSetting);
    }

    /**
     *
     * @param text
     * @param x
     * @param y
     */
    public void write(String text, double x, double y) {
        Context2d context = sceneCanvas.getContext2d();
        context.fillText(text, x, y);
    }

    /**
     *
     * @param text
     * @param x
     * @param y
     * @param align
     */
    public void write(String text, double x, double y, String align) {
        Context2d context = sceneCanvas.getContext2d();
        context.setTextAlign(align);
        context.fillText(text, x, y);
    }

    //############################### BRIGHTNESS ###############################

    /**
     *
     * @param image
     * @param translateX
     * @param translateY
     * @param x
     * @param y
     * @param width
     * @param height
     * @param degrees
     * @param xSize
     * @param ySize
     */
    public void drawImageBrightness(Image image, double translateX, double translateY, double x, double y,
            double width, double height, double degrees, double alpha, double brightness)
            throws JavaScriptException {
        ImageElement imageElement = (ImageElement) image.getElement().cast();

        try {
            drawImageElementBrightness(imageElement, translateX, translateY, x, y, width, height, degrees, alpha,
                    brightness);
        } catch (JavaScriptException exception) {
            throw exception;
        }
    }

    /**
     *
     * @param imageElement
     * @param translateX
     * @param translateY
     * @param x
     * @param y
     * @param width
     * @param height
     * @param degrees
     * @param xSize
     * @param ySize
     */
    public void drawImageElementBrightness(ImageElement imageElement, double translateX, double translateY,
            double x, double y, double width, double height, double degrees, double alpha, double brightness)
            throws JavaScriptException {
        Context2d context = sceneCanvas.getContext2d();
        context.save();
        context.setGlobalAlpha(alpha);
        context.translate(translateX, translateY);
        context.rotate(degrees * Math.PI / 180);

        try {
            Canvas adjustedImage = adjustImageBrightness(imageElement, brightness);
            context.drawImage(adjustedImage.getCanvasElement(), x, y, width, height);
            context.restore();
        } catch (JavaScriptException exception) {
            context.restore();
            throw exception;
        }
    }

    /**
     *
     * @param imageElement
     * @param brightness
     * @return Canvas canvas with the adjusted image
     */
    private Canvas adjustImageBrightness(ImageElement imageElement, double brightness) {

        int width = imageElement.getWidth();
        int height = imageElement.getHeight();

        Canvas temp = Canvas.createIfSupported();
        temp.setCoordinateSpaceWidth(width);
        temp.setCoordinateSpaceHeight(height);

        Context2d context = temp.getContext2d();

        context.drawImage(imageElement, 0, 0);

        ImageData imageData = context.getImageData(0, 0, width, height);

        CanvasPixelArray pixelsData = imageData.getData();

        int index = 0;

        System.out.println(pixelsData.getLength());

        int brightnessAdj = (int) (255d * brightness) - 255;

        if (brightnessAdj != 0) {
            while (index < pixelsData.getLength()) {
                if ((index + 1) % 4 != 0) {
                    int r = checkColorRange(pixelsData.get(index) + brightnessAdj); //red channel
                    pixelsData.set(index, r);

                    int g = checkColorRange(pixelsData.get(++index) + brightnessAdj); //green channel
                    pixelsData.set(index, g);

                    int b = checkColorRange(pixelsData.get(++index) + brightnessAdj); //blue channel
                    pixelsData.set(index, b);

                    index++; //alpha channel
                }
                index++;
            }
        }

        context.putImageData(imageData, 0, 0);

        return temp;
    }

    /**
     * Checks if the given color value is within the range 0...255
     * @param colorValue
     * @return 0 if the value is lesser or equal than 0 <br />
     *         255 if the value is greater or equal than 255 <br />
     *         otherwise the value itself
     */
    private int checkColorRange(int colorValue) {
        if (colorValue <= 0)
            return 0;
        else if (colorValue >= 255) {
            return 255;
        } else {
            return colorValue;
        }
    }

    //############################### JSNI #####################################

    /**
     *
     * @param image
     * @param translateX
     * @param translateY
     * @param x
     * @param y
     * @param width
     * @param height
     * @param degrees
     * @param xSize
     * @param ySize
     * @param alpha
     */
    public void drawImageJSNI(Image image, double translateX, double translateY, double x, double y, double width,
            double height, double degrees, double alpha) {
        ImageElement imageElement = (ImageElement) image.getElement().cast();
        Context2d context = sceneCanvas.getContext2d();

        this.drawImageJSNI(imageElement, translateX, translateY, x, y, width, height, degrees, alpha, context);
    }

    /**
     *
     * @param image
     * @param translateX
     * @param translateY
     * @param x
     * @param y
     * @param width
     * @param height
     * @param degrees
     * @param xSize
     * @param ySize
     * @param alpha
     * @param context
     */
    private native void drawImageJSNI(ImageElement image, double translateX, double translateY, double x, double y,
            double width, double height, double degrees, double alpha, Context2d context) /*-{
                                                                                          context.save();
                                                                                          context.globalAlpha = alpha;
                                                                                          context.translate(translateX, translateY);
                                                                                          context.rotate(degrees * Math.PI / 180);
                                                                                          context.drawImage(image, x, y, width, height);
                                                                                          context.restore();
                                                                                          }-*/;

    //##########################################################################

    /**
     *
     */
    public void clearCanvas() {

        long start = System.currentTimeMillis();

        Context2d context = sceneCanvas.getContext2d();
        context.save();
        context.setFillStyle(fillColor);
        context.fillRect(0, 0, this.sceneWidth, this.sceneHeight);
        context.restore();

        CatrobatDebug.debug("clearCanvas-execution took " + (System.currentTimeMillis() - start) + " ms");
    }

    //##########################################################################

    /**
     *
     * @return Canvas canvas
     */
    public Canvas getCanvas() {
        return sceneCanvas;
    }

    /**
     *
     */
    public boolean isSceneCreated() {
        return isSceneCreated;
    }

    /**
     *
     */
    public int getSceneWidth() {
        return this.sceneWidth;
    }

    /**
     *
     */
    public int getSceneHeight() {
        return this.sceneHeight;
    }

    //##########################################################################

    /**
     * FOR UNIT-TESING
     */
    public void reset() {
        instance = null;
    }

    /**
     * FOR TESING
     */
    public void drawAxis() {
        Context2d ctx = sceneCanvas.getContext2d();

        ctx.beginPath();
        ctx.moveTo(getSceneWidth() / 2, 0);
        ctx.lineTo(getSceneWidth() / 2, getSceneHeight());
        ctx.stroke();
        ctx.closePath();

        ctx.beginPath();
        ctx.moveTo(0, getSceneHeight() / 2);
        ctx.lineTo(getSceneWidth(), getSceneHeight() / 2);
        ctx.stroke();
        ctx.closePath();
    }
}