javauis/m2g_qt/javasrc/com/nokia/microedition/m2g/M2GScalableGraphics.java
author hgs
Fri, 29 Oct 2010 11:49:32 +0300
changeset 87 1627c337e51e
parent 80 d6dafc5d983f
permissions -rw-r--r--
v2.2.21_1

/*
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/


package com.nokia.microedition.m2g;

import com.nokia.microedition.m2g.M2GRunnableQt;
import javax.microedition.m2g.*;
import javax.microedition.m2g.ScalableGraphics;
import javax.microedition.lcdui.Graphics;
import java.lang.StringBuffer;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import com.nokia.mj.impl.utils.Logger;
import com.nokia.mj.impl.nokialcdui.LCDUIInvoker;
import org.eclipse.swt.internal.qt.GCData;
import org.eclipse.swt.internal.qt.graphics.GraphicsContext;
import org.eclipse.swt.internal.extension.GraphicsUtil;

/*
 * ScalableGraphics
 */
public class M2GScalableGraphics
        extends M2GObject
{
    //--------------------------------------------------
    // STATIC CONSTANTS
    //--------------------------------------------------

    // Transparency alpha max and min limits
    private static final float MAX_TRANSPARENCY_ALPHA = 1.0f;
    private static final float MIN_TRANSPARENCY_ALPHA = 0.0f;

    //--------------------------------------------------
    // VARIABLES
    //--------------------------------------------------
    private GC        iTargetGC      = null;
    private int iUseNativeClear = 0;
    private Graphics iTargetGraphics;
    private Rectangle iSurfaceRectangle;
    private Rectangle iFinalESWTSurfaceRectangle;

    int iSurfaceHandle;

    //--------------------------------------------------
    // METHODS
    //--------------------------------------------------
    /**
     * Constructor
     */
    public M2GScalableGraphics()
    {
        super();

        doConstruct();
    }
    /**
     * @see javax.microedition.m2g.ScalableGraphics#bindTarget()
     */
    public synchronized void bindTarget(Object target)
    {
        if (target == null)
        {
            throw new NullPointerException(/*SF*/"The target is null"/*SF*/);
        }

        if (target instanceof org.eclipse.swt.graphics.GC)
        {
            final GC finalGc = (GC)target;

            // Execute in UI thread
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {
                    iFinalESWTSurfaceRectangle = GraphicsUtil.startExternalRendering(finalGc);

                    // Get GCData from GC
                    iSurfaceHandle = GraphicsUtil.getWindowSurface(finalGc).getHandle();
                    _bind(getHandle(), iSurfaceHandle);
                }
            });

            iTargetGC = (GC)finalGc;
            // Handling for LCDUI Graphics
        }
        else if (target instanceof javax.microedition.lcdui.Graphics)
        {
            Graphics g = (Graphics)target;
            final Graphics finalG = g;
            iSurfaceRectangle = LCDUIInvoker.startExternalRendering(finalG);
            // Execute in UI thread
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {

                    iSurfaceHandle = LCDUIInvoker.getWindowSurface(finalG).getHandle();

                    // Flush Canvas
                    //M2GManager.flushDisplayBuffer();
                    _bind(getHandle(), iSurfaceHandle);
                }
            });

            iTargetGraphics  = (Graphics)finalG;
        }

        else
        {
            throw new IllegalArgumentException();
        }
    }

    /**
     * @see com.nokia.microedition.m2g.M2GObject#doConstruct()
     */
    public void doConstruct()
    {
        super.doConstruct();

        // Execute in UI thread
        Platform.executeInUIThread(
            new M2GRunnableQt()
        {
            public void doRun()
            {
                setHandle(_createRenderContext(
                              getNativeSVGProxyHandle()));
                // Add object to the live objects container
            }
        });
        register(this);
    }

    /**
     * @see com.nokia.microedition.m2g.M2GObject#doCleanup()
     */
    public synchronized void doCleanup()
    {

        // Execute in UI thread
        Platform.executeInUIThread(
            new M2GRunnableQt()
        {
            public void doRun()
            {
                _deleteRenderContext(
                    getHandle());
            }
        }
        );
        resetHandles();
        iTargetGC = null;
        iTargetGraphics = null;
    }

    /**
     * @see javax.microedition.m2g.ScalableGraphics#releaseTarget()
     */
    public synchronized void releaseTarget()
    {
        if (iTargetGC != null)
        {

            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {
                    GraphicsUtil.endExternalRendering(iTargetGC);
                    _release(iSurfaceHandle, getHandle());
                }
            });
            iTargetGC = null;
        }
        else if (iTargetGraphics != null)
        {
            final Graphics finalG = iTargetGraphics;
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {
                    _release(iSurfaceHandle, getHandle());
                }
            });
            LCDUIInvoker.endExternalRendering(iTargetGraphics);

            iTargetGraphics = null;
        }
        else
        {
            throw new IllegalStateException(/*SF*/"Target is not bound"/*SF*/);
        }

    }

    public synchronized void render(
        int x, int y, ScalableImage image, boolean aUseNativeClear)
    {
        iUseNativeClear = aUseNativeClear ? 1 : 0;
        render(x, y, image);
        iUseNativeClear = 0;

    }

    /**
     * @see javax.microedition.m2g.ScalableGraphics#render()
     */
    public synchronized void render(int x, int y, ScalableImage image)
    {

        if (image == null)
        {
            Logger.ELOG(Logger.EJavaUI, "render() - exception: "
                        + /*SF*/"The target is null"/*SF*/);
            throw new NullPointerException(/*SF*/"The target is null"/*SF*/);
        }
        if (iTargetGC != null)
        {
            final M2GDocument finalDoc = (M2GDocument)((SVGImage)image).getDocument();
            // Get synchronized svg image data
            final int finalSvgW  = image.getViewportWidth();
            final int finalSvgH = image.getViewportHeight();
            if ((finalSvgW == 0) || (finalSvgW == 0))
            {
                return;
            }

            Rectangle clipRect = iFinalESWTSurfaceRectangle;

            final int finalClipX = clipRect.x;
            final int finalClipY = clipRect.y;
            final int finalClipW = clipRect.width;
            final int finalClipH = clipRect.height;


            // if none of the svg image is visible due to clipping then don't
            // bother to call render
            if ((x >= (finalClipX + finalClipW)) || (y >= (finalClipY + finalClipH)))
            {
                Logger.LOG(Logger.EJavaUI, Logger.EInfo,
                           "render() - svg image isn't visible due to clipping");
                return;
            }
            if (((x + finalSvgW) < finalClipX) || ((y + finalSvgW) < finalClipY))
            {
                Logger.LOG(Logger.EJavaUI, Logger.EInfo,
                           "render() - svg image isn't visible due to clipping");
                return;
            }


            final int finalX = x;
            final int finalY = y;

            // Execute in UI thread
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {

                    final int[] finalData = _renderESWT(getHandle(),
                                                        finalDoc.getHandle(), finalX, finalY,
                                                        finalClipX, finalClipY, finalClipW, finalClipH, finalSvgW, finalSvgW,
                                                        finalDoc.getRootElement().getCurrentTime(),
                                                        iUseNativeClear);

                    int[] bitmapHandles;
                    bitmapHandles = new int[4];
                    for (int i = 0; i < 4; i++)
                    {
                        bitmapHandles[i] = finalData[i];
                    }
                    int[] renderData;
                    renderData = new int[6];
                    for (int i = 0; i < 6; i++)
                    {
                        renderData[i] = finalData[i+4];
                    }

                }
            });

        }//if(true)
        else if (iTargetGraphics != null)
        {


            final M2GDocument finalDoc = (M2GDocument)((SVGImage)image).getDocument();
            // Get synchronized svg image data
            final int finalSvgW  = image.getViewportWidth();
            final int finalSvgH = image.getViewportHeight();
            if ((finalSvgW == 0) || (finalSvgH == 0))
            {

                return;
            }

            final int finalClipX = iSurfaceRectangle.x;
            final int finalClipY = iSurfaceRectangle.y;
            final int finalClipW  = iSurfaceRectangle.width;
            final int finalClipH = iSurfaceRectangle.height;

            // if none of the svg image is visible due to clipping then don't
            // bother to call render
            if ((x >= (finalClipX + finalClipW)) || (y >= (finalClipY + finalClipH)))
            {
                Logger.LOG(Logger.EJavaUI, Logger.EInfo,
                           "render() - svg image isn't visible due to clipping");
                return;
            }
            if (((x + finalSvgW) < finalClipX) || ((y + finalSvgH) < finalClipY))
            {
                Logger.LOG(Logger.EJavaUI, Logger.EInfo,
                           "render() - svg image isn't visible due to clipping");
                return;
            }

            final int finalX = x;
            final int finalY = y;

            // Execute in UI thread
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {
                    _renderLCDUI(getHandle(), finalDoc.getHandle(), finalX, finalY,
                                 finalClipX, finalClipY, finalClipW, finalClipH, finalSvgW, finalSvgH,
                                 finalDoc.getRootElement().getCurrentTime());
                }
            });
        }

        else
        {
            Logger.ELOG(Logger.EJavaUI, "render() - exception: "
                        + /*SF*/"Target is not bound"/*SF*/);
            throw new IllegalStateException(/*SF*/"Target is not bound"/*SF*/);
        }

    }

    /**
     * @see javax.microedition.m2g.ScalableGraphics#setRenderingQuality(int)
     */
    public synchronized void setRenderingQuality(int mode)
    {
        if ((mode == ScalableGraphics.RENDERING_QUALITY_LOW) ||
                (mode == ScalableGraphics.RENDERING_QUALITY_HIGH))
        {
            final int finalMode = mode;
            // Execute in UI thread
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {
                    _setRenderingQuality(getHandle(), finalMode);
                }
            });
        }
        else
        {
            Logger.ELOG(Logger.EJavaUI,
                        "setRenderingQuality() - exception: " + /*SF*/"The mode is invalid"/*SF*/);
            throw new IllegalArgumentException(/*SF*/"The mode is invalid"/*SF*/);
        }
    }

    /**
     * @see javax.microedition.m2g.ScalableGraphics#setTransparency(float)
     */
    public synchronized void setTransparency(float alpha)
    {
        if (alpha >= MIN_TRANSPARENCY_ALPHA && alpha <= MAX_TRANSPARENCY_ALPHA)
        {
            final float finalAlpha = alpha;
            // Execute in UI thread
            Platform.executeInUIThread(
                new M2GRunnableQt()
            {
                public void doRun()
                {
                    _setTransparency(getHandle(), finalAlpha);
                }
            }
            );
        }
        else
        {
            Logger.ELOG(Logger.EJavaUI,
                        "setTransparency() - exception: " + /*SF*/"The alpha is out of range"/*SF*/);
            throw new IllegalArgumentException(/*SF*/"The alpha is out of range"/*SF*/);
        }
    }


    //--------------------------------------------------
    // NATIVE METHODS
    //--------------------------------------------------
    private native int _bind(
        int aRenderContextHandle, int aTargetHandle);
    private native int _createRenderContext(
        int aSVGProxyHandle);
    private native void _deleteRenderContext(
        int aRenderContextHandle);
    private native int _release(
        int aSurfaceHandle ,int aRenderContextHandle);
    private native int _renderLCDUI(
        int aRenderContextHandle, int aDocumentHandle,
        int aX, int aY, int aClipX, int aClipY, int aClipW, int aClipH,
        int aSvgW, int aSvgH, float aCurrentTime);
    private native int[] _renderESWT(
        int aRenderContextHandle, int aDocumentHandle,
        int aX, int aY, int aClipX, int aClipY, int aClipW, int aClipH,
        int aSvgW, int aSvgH, float aCurrentTime, int iUseNativeClear);
    private native void _setRenderingQuality(
        int aRenderContextHandle, int aMode);
    private native void _setTransparency(
        int aRenderContextHandle, float aAlpha);
}