<commit_before>/*************************************************************************
 *
 *  $RCSfile: JavaCanvas.java,v $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// UNO
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.IQueryInterface;
import com.sun.star.lang.XInitialization;
import com.sun.star.lib.uno.helper.WeakBase;

// OOo AWT
import com.sun.star.awt.*;

// Canvas
import drafts.com.sun.star.rendering.*;
import drafts.com.sun.star.geometry.*;

// Java AWT
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

// system-dependent stuff
import sun.awt.*;


public class JavaCanvas
    extends CanvasBase
    implements com.sun.star.awt.XWindow,
               drafts.com.sun.star.rendering.XSpriteCanvas,
               com.sun.star.lang.XServiceInfo,
               com.sun.star.lang.XInitialization
{
    private WindowAdapter                   dummyFrame;
    private BackBuffer                      backBuffer;
    private java.awt.image.BufferStrategy   bufferStrategy;

    private java.awt.Font                   fpsFont;
    private long                            lastTime;

    public Graphics2D getGraphics()
    {
        return backBuffer.getGraphics();
    }

    //----------------------------------------------------------------------------------

    //
    // XInitialization
    // ===============
    //
    public void initialize( java.lang.Object[] arguments )
    {
        CanvasUtils.printLog( "JavaCanvas.initialize called!" );

        // Do that as the very first thing. The Java2D internal
        // classes choose their render path at initialization time,
        // thus this must happen before doing _any_ GUI.

        // TODO: Put those flags into javarc/java.ini, we're maybe
        // coming late into a running JVM!

        // now, we're getting slightly system dependent here.
        String os = (String) System.getProperty("os.name");

        CanvasUtils.printLog( "System detected: " + os );

        // tweak some speed knobs...
        if( os.startsWith("Windows") )
        {
            System.setProperty("sun.java2d.translaccel", "true");
            System.setProperty("sun.java2d.ddforcevram", "true");
            //System.setProperty("sun.java2d.accthreshold", "0");

            CanvasUtils.printLog( "Optimizing for Windows" );
        }
        else
        {
            System.setProperty("sun.java2d.opengl", "true");

            CanvasUtils.printLog( "Optimizing for Unix" );
        }

        /* we're initialized with the following array of anys:

           arguments[0] = pointer to VCL window
           arguments[1] = Integer (operating system window handle)
           arguments[2] = com.sun.star.awt.Rectangle (position and size within that OS window)
           arguments[3] = boolean (fullsize window or not)

           We then generate a dummy Java frame with that window as the
           parent, to fake a root window for the Java implementation.
        */
        try
        {
            com.sun.star.awt.Rectangle boundRect = (com.sun.star.awt.Rectangle) arguments[2];

            //boolean isFullScreen = arguments[1];
            boolean isFullScreen = true;
            //AnyConverter.toBoolean( arguments[3] ) );

            // fake a root for Java in VCL window. Pass the flag
            // whether we shall run fullscreen, too.
            dummyFrame = new WindowAdapter( AnyConverter.toInt( arguments[1] ), isFullScreen );

            if( isFullScreen )
            {
                // blow window up to fullscreen. Otherwise, we cannot clear the whole screen,
                // which results in ugly flickering
                Dimension screenSize = dummyFrame.frame.getToolkit().getScreenSize();
                boundRect.X      = 0;
                boundRect.Y      = 0;
                boundRect.Width  = screenSize.width-1;
                boundRect.Height = screenSize.height-1;
            }

            dummyFrame.setPosSize( boundRect.X, boundRect.Y, boundRect.Width, boundRect.Height, (short)0 );
            CanvasUtils.printLog( "Window size: " + boundRect.Width + ", " + boundRect.Height );

            backBuffer = new BackBuffer( (Graphics2D) dummyFrame.frame.getGraphics(),
                                         Math.max(1,boundRect.Width),
                                         Math.max(1,boundRect.Height) );

            // TODO: Maybe delay double buffer init until first sprite creation
            dummyFrame.frame.createBufferStrategy(2);
            bufferStrategy = dummyFrame.frame.getBufferStrategy();

            if( bufferStrategy.getCapabilities().isPageFlipping() )
                CanvasUtils.printLog( "JavaCanvas.initialize double buffering is using page flipping!" );
            else
                CanvasUtils.printLog( "JavaCanvas.initialize double buffering is using blitting!" );

            lastTime = System.currentTimeMillis();
            fpsFont = new java.awt.Font( "Times", Font.PLAIN, 20 );

            CanvasUtils.printLog( "JavaCanvas.initialize finished!" );
        }
        catch( com.sun.star.lang.IllegalArgumentException e )
        {
            CanvasUtils.printLog( "Cannot create EmbeddedFrame within VCL window hierarchy!" );
        }
    }

    //----------------------------------------------------------------------------------

    //
    // XComponent
    // ==========
    //
    public void dispose()
    {
        CanvasUtils.printLog( "JavaCanvas: disposed!" );

        // destroy all active sprites
        java.util.Set entries = activeSprites.entrySet();
        java.util.Iterator iter = entries.iterator();

        while( iter.hasNext() )
        {
            java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
            if( entry.getValue() != null )
                ((SpriteRep)entry.getValue()).dispose();
        }

        if( bufferStrategy != null )
            bufferStrategy.getDrawGraphics().dispose(); // really necessary?

        if( dummyFrame != null )
            dummyFrame.dispose();

        if( backBuffer != null)
            backBuffer.dispose();

        bufferStrategy = null;
        dummyFrame = null;
        backBuffer = null;

        super.dispose();
    }

    //----------------------------------------------------------------------------------

    public JavaCanvas( XComponentContext xContext )
    {
        CanvasUtils.printLog( "JavaCanvas constructor called!" );
        activeSprites = new java.util.HashMap( 33 );
    }

    //----------------------------------------------------------------------------------

    //
    // XWindow interface
    // =================
    //
    // This is delegated to WindowAdapter!
    //
    public synchronized void setPosSize( int X, int Y, int Width, int Height, short Flags )
    {
        if( dummyFrame != null )
        {
            dummyFrame.setPosSize( X, Y, Width, Height, Flags );

            Width = Math.max(1,Width);
            Height= Math.max(1,Height);

            CanvasUtils.printLog( "JavaCanvas graphics set to " + Width + "," + Height );
            backBuffer.setSize(Width,Height);
        }
    }

    public synchronized com.sun.star.awt.Rectangle getPosSize(  )
    {
        if( dummyFrame != null )
            return dummyFrame.getPosSize();

        return new com.sun.star.awt.Rectangle();
    }

    public synchronized void setVisible( boolean visible )
    {
        if( dummyFrame != null )
            dummyFrame.setVisible( visible );
    }

    public synchronized void setEnable( boolean enable )
    {
        if( dummyFrame != null )
            dummyFrame.setEnable( enable );
    }

    public synchronized void setFocus()
    {
        if( dummyFrame != null )
            dummyFrame.setFocus();
    }

    public synchronized void addWindowListener( XWindowListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addWindowListener( xListener );
    }

    public synchronized void removeWindowListener( XWindowListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeWindowListener( xListener );
    }

    public synchronized void addFocusListener( XFocusListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addFocusListener( xListener );
    }

    public synchronized void removeFocusListener( XFocusListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeFocusListener( xListener );
    }

    public synchronized void addKeyListener( XKeyListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addKeyListener( xListener );
    }

    public synchronized void removeKeyListener( XKeyListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeKeyListener( xListener );
    }

    public synchronized void addMouseListener( XMouseListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addMouseListener( xListener );
    }

    public synchronized void removeMouseListener( XMouseListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeMouseListener( xListener );
    }

    public synchronized void addMouseMotionListener( XMouseMotionListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addMouseMotionListener( xListener );
    }

    public synchronized void removeMouseMotionListener( XMouseMotionListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeMouseMotionListener( xListener );
    }

    public synchronized void addPaintListener( XPaintListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addPaintListener( xListener );
    }

    public synchronized void removePaintListener( XPaintListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removePaintListener( xListener );
    }

    //----------------------------------------------------------------------------------

    //
    // XBitmapCanvas impl
    // ==================
    //

    public synchronized void copyRect( drafts.com.sun.star.rendering.XBitmapCanvas  sourceCanvas,
                                       drafts.com.sun.star.geometry.RealRectangle2D sourceRect,
                                       drafts.com.sun.star.rendering.ViewState      sourceViewState,
                                       drafts.com.sun.star.rendering.RenderState    sourceRenderState,
                                       drafts.com.sun.star.geometry.RealRectangle2D destRect,
                                       drafts.com.sun.star.rendering.ViewState      destViewState,
                                       drafts.com.sun.star.rendering.RenderState    destRenderState )
    {
        CanvasUtils.printLog( "JavaCanvas.copyRect() called" );

        // TODO: create temp image when transform is non-trivial

        if( sourceCanvas == this )
        {
            // copy rectangle within the canvas
            getGraphics().copyArea((int)sourceRect.X1,
                                   (int)sourceRect.Y1,
                                   (int)(sourceRect.X2 - sourceRect.X1),
                                   (int)(sourceRect.Y2 - sourceRect.Y1),
                                   (int)(destRect.X1 - sourceRect.X1),
                                   (int)(destRect.Y1 - sourceRect.Y1) );
        }
        else
        {
            if( sourceCanvas instanceof JavaCanvas )
            {
                // cache
                CanvasUtils.setupGraphicsState( getGraphics(), destViewState, destRenderState, CanvasUtils.alsoSetupPaint );

                java.awt.Image backBuffer = ((JavaCanvas)sourceCanvas).backBuffer.getBackBuffer();

                // TODO: really extract correct source rect here
                getGraphics().drawImage( backBuffer, 0, 0, null);
                CanvasUtils.postRenderImageTreatment( backBuffer );
            }
            // TODO: foreign canvas
        }
    }

    //----------------------------------------------------------------------------------

    // a map of SpriteReps, with Sprite object as keys. Contains all
    // active (i.e. visible) sprites, the SpriteReps are used to
    // repaint the sprite content at any time.
    private java.util.HashMap activeSprites;

    //
    // XSpriteCanvas impl
    // ==================
    //

    public synchronized drafts.com.sun.star.rendering.XAnimatedSprite createSpriteFromAnimation( XAnimation animation )
    {
        CanvasUtils.printLog( "JavaCanvas.createSpriteFromAnimation called" );

        return new CanvasSprite( animation, this, (Graphics2D)dummyFrame.frame.getGraphics() );
    }

    public synchronized XAnimatedSprite createSpriteFromBitmaps( drafts.com.sun.star.rendering.XBitmap[] animationBitmaps,
                                                                 short interpolationMode )
    {
        return null;
    }

    public synchronized XCustomSprite createCustomSprite( RealSize2D spriteSize )
    {
        CanvasUtils.printLog( "JavaCanvas.createCustomSprite called" );

        return new CanvasCustomSprite( spriteSize, this, (Graphics2D)dummyFrame.frame.getGraphics() );
    }

    public synchronized XSprite createClonedSprite( XSprite original )
    {
        return new CanvasClonedSprite( this, original );
    }

    public synchronized boolean updateScreen()
    {
        redrawAllLayers();

        return true;
    }

    //----------------------------------------------------------------------------------

    //
    // XSpriteCanvas helper
    // ====================
    //
    public synchronized void renderAnimation( CanvasSprite sprite, XAnimation animation, double t )
    {
        SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite );
        if( spriteRep != null )
        {
            //Graphics2D graph = getWindowGraphics();

            // TODO: ensure update of graphics object externally, e.g. when
            // VCL moves the toplevel window.
            //java.awt.Rectangle bounds = dummyFrame.frame.getBounds();
            //graphics.setGraphics(graph, bounds.width, bounds.height);

            spriteRep.renderAnimation( animation, sprite.getViewState(), t );
        }
        else
        {
            CanvasUtils.printLog( "JavaCanvas.renderAnimation sprite not active!" );
        }
    }

    public synchronized void showSprite( SpriteBase sprite )
    {
        CanvasUtils.printLog( "JavaCanvas.showSprite() called" );

        SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite );
        if( spriteRep != null )
        {
            CanvasUtils.printLog( "JavaCanvas.showSprite sprite already active!" );
        }
        else
        {
            spriteRep = sprite.getSpriteRep();

            // a valid SpriteRep for a given Sprite in the
            // activeSprites hash denotes 'sprite active'
            activeSprites.put( sprite, spriteRep );

            // TODO: TEMP! Just for testing! Set empty cursor for presentation
//             dummyFrame.frame.setCursor( dummyFrame.frame.getToolkit().createCustomCursor(new java.awt.image.BufferedImage(0,0,
//                                                                                                                           java.awt.image.BufferedImage.TYPE_INT_RGB),
//                                                                                          new java.awt.Point(0,0),
//                                                                                          "") );
        }
    }

    public synchronized void hideSprite( SpriteBase sprite )
    {
        CanvasUtils.printLog( "JavaCanvas.hideSprite() called" );

        SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite );
        if( spriteRep != null )
        {
            activeSprites.put( sprite, null );
            redrawAllLayers();
        }
        else
        {
            CanvasUtils.printLog( "JavaCanvas.hideSprite sprite not active!" );
        }
    }

    private void redrawAllLayers()
    {
        // fetch the Graphics object to draw into (we're doing double
        // buffering here, the content is later shown via
        // bufferStrategy.show().
        Graphics2D graph = null;

        try
        {
            graph = (Graphics2D)bufferStrategy.getDrawGraphics();

            GraphicsDevice device = graph.getDeviceConfiguration().getDevice();
            CanvasUtils.printLog( "Available vram: " + device.getAvailableAcceleratedMemory() );

            // repaint background
            //backBuffer.redraw( graph );

            // repaint all active sprites
            java.util.Set entries = activeSprites.entrySet();
            java.util.Iterator iter = entries.iterator();
            while( iter.hasNext() )
            {
                java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
                if( entry.getValue() != null )
                    ((SpriteRep)entry.getValue()).redraw(graph);
            }

            long currTime = System.currentTimeMillis();
            graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) );
            graph.setFont( fpsFont );
            graph.setColor( java.awt.Color.black );

            try
            {
                String fps = new String( String.valueOf(1000.0/(currTime-lastTime)) );
                graph.drawString( fps.substring(0,5) + " fps", 0, 20);
                CanvasUtils.printLog( fps.substring(0,5) + " fps" );
            }
            catch( Exception e )
            {
                graph.drawString( "0 fps", 0, 20);
            }

            lastTime = currTime;
        }
        catch( Exception e )
        {
            CanvasUtils.printLog( "Exception thrown in redrawAllLayers" );
        }
        finally
        {
            if( graph != null )
                graph.dispose();
        }

        bufferStrategy.show();
    }

    //----------------------------------------------------------------------------------

    private static final String s_implName = "XCanvas.java.impl";
    private static final String s_serviceName = "drafts.com.sun.star.rendering.Canvas";

    //----------------------------------------------------------------------------------

    //
    // XServiceInfo impl
    // =================
    //
    public synchronized String getImplementationName()
    {
        return s_implName;<commit_msg>INTEGRATION: CWS presentationengine01 (1.2.2); FILE MERGED 2004/09/08 16:34:44 dbo 1.2.2.5: #110496# separate service names for all kinds of canvas implementations Issue number: Submitted by: Reviewed by: 2004/08/27 18:46:04 thb 1.2.2.4: #110496# Adapted to recent canvas API changes (XSpriteCanvas::updateScreen and sprite clip semantics 2004/07/28 10:44:58 thb 1.2.2.3: #110496# Brought javacanvas to comply with recent API changes 2004/04/12 15:12:22 thb 1.2.2.2: #110496# Adaptions after canvas01 merge 2004/04/05 15:57:55 thb 1.2.2.1: Resync with canvas01 changes<commit_after>/*************************************************************************
 *
 *  $RCSfile: JavaCanvas.java,v $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser 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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

// UNO
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.IQueryInterface;
import com.sun.star.lang.XInitialization;
import com.sun.star.lib.uno.helper.WeakBase;

// OOo AWT
import com.sun.star.awt.*;

// Canvas
import drafts.com.sun.star.rendering.*;
import drafts.com.sun.star.geometry.*;

// Java AWT
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

// system-dependent stuff
import sun.awt.*;


public class JavaCanvas
    extends CanvasBase
    implements com.sun.star.awt.XWindow,
               drafts.com.sun.star.rendering.XSpriteCanvas,
               drafts.com.sun.star.rendering.XIntegerBitmap,
               com.sun.star.lang.XServiceInfo,
               com.sun.star.lang.XInitialization
{
    private WindowAdapter                   dummyFrame;
    public BackBuffer                       backBuffer;
    private java.awt.image.BufferStrategy   bufferStrategy;

    private java.awt.Font                   fpsFont;
    private long                            lastTime;
    private com.sun.star.awt.Rectangle      boundRect;

    public Graphics2D getGraphics()
    {
        return backBuffer.getGraphics();
    }

    //----------------------------------------------------------------------------------

    //
    // XInitialization
    // ===============
    //
    public void initialize( java.lang.Object[] arguments )
    {
        CanvasUtils.printLog( "JavaCanvas.initialize called!" );

        // Do that as the very first thing. The Java2D internal
        // classes choose their render path at initialization time,
        // thus this must happen before doing _any_ GUI.

        // TODO: Put those flags into javarc/java.ini, we're maybe
        // coming late into a running JVM!

        // now, we're getting slightly system dependent here.
        String os = (String) System.getProperty("os.name");

        CanvasUtils.printLog( "System detected: " + os );

        // tweak some speed knobs...
//         if( os.startsWith("Windows") )
//         {
//             System.setProperty("sun.java2d.translaccel", "true");
//             System.setProperty("sun.java2d.ddforcevram", "true");
//             //System.setProperty("sun.java2d.accthreshold", "0");

//             CanvasUtils.printLog( "Optimizing for Windows" );
//         }
//         else
//         {
//             System.setProperty("sun.java2d.opengl", "true");

//             CanvasUtils.printLog( "Optimizing for Unix" );
//         }

        /* we're initialized with the following array of anys:

           arguments[0] = pointer to VCL window
           arguments[1] = Integer (operating system window handle)
           arguments[2] = com.sun.star.awt.Rectangle (position and size within that OS window)
           arguments[3] = boolean (fullsize window or not)

           We then generate a dummy Java frame with that window as the
           parent, to fake a root window for the Java implementation.
        */
        try
        {
            boundRect = (com.sun.star.awt.Rectangle) arguments[2];

            //boolean isFullScreen = arguments[1];
            boolean isFullScreen = true;
            //AnyConverter.toBoolean( arguments[3] ) );

            // fake a root for Java in VCL window. Pass the flag
            // whether we shall run fullscreen, too.
            dummyFrame = new WindowAdapter( AnyConverter.toInt( arguments[1] ), isFullScreen );

            if( isFullScreen )
            {
                // blow window up to fullscreen. Otherwise, we cannot clear the whole screen,
                // which results in ugly flickering
                Dimension screenSize = dummyFrame.frame.getToolkit().getScreenSize();
                boundRect.X      = 0;
                boundRect.Y      = 0;
                boundRect.Width  = screenSize.width-1;
                boundRect.Height = screenSize.height-1;
            }

            dummyFrame.setPosSize( boundRect.X, boundRect.Y, boundRect.Width, boundRect.Height, (short)0 );
            CanvasUtils.printLog( "Window size: " + boundRect.Width + ", " + boundRect.Height );

            backBuffer = new BackBuffer( (Graphics2D) dummyFrame.frame.getGraphics(),
                                         Math.max(1,boundRect.Width),
                                         Math.max(1,boundRect.Height) );

            // TODO: Maybe delay double buffer init until first sprite creation
            dummyFrame.frame.createBufferStrategy(2);
            bufferStrategy = dummyFrame.frame.getBufferStrategy();

            if( bufferStrategy.getCapabilities().isPageFlipping() )
                CanvasUtils.printLog( "JavaCanvas.initialize double buffering is using page flipping!" );
            else
                CanvasUtils.printLog( "JavaCanvas.initialize double buffering is using blitting!" );

            lastTime = System.currentTimeMillis();
            fpsFont = new java.awt.Font( "Times", Font.PLAIN, 20 );

            CanvasUtils.printLog( "JavaCanvas.initialize finished!" );
        }
        catch( com.sun.star.lang.IllegalArgumentException e )
        {
            CanvasUtils.printLog( "Cannot create EmbeddedFrame within VCL window hierarchy!" );
        }
    }

    //----------------------------------------------------------------------------------

    //
    // XComponent
    // ==========
    //
    public void dispose()
    {
        CanvasUtils.printLog( "JavaCanvas: disposed!" );

        // destroy all active sprites
        java.util.Set entries = activeSprites.entrySet();
        java.util.Iterator iter = entries.iterator();

        while( iter.hasNext() )
        {
            java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
            if( entry.getValue() != null )
                ((SpriteRep)entry.getValue()).dispose();
        }

        if( bufferStrategy != null )
            bufferStrategy.getDrawGraphics().dispose(); // really necessary?

        if( dummyFrame != null )
            dummyFrame.dispose();

        if( backBuffer != null)
            backBuffer.dispose();

        bufferStrategy = null;
        dummyFrame = null;
        backBuffer = null;

        super.dispose();
    }

    //----------------------------------------------------------------------------------

    public JavaCanvas( XComponentContext xContext )
    {
        CanvasUtils.printLog( "JavaCanvas constructor called!" );
        activeSprites = new java.util.HashMap( 33 );
    }

    //----------------------------------------------------------------------------------

    //
    // XWindow interface
    // =================
    //
    // This is delegated to WindowAdapter!
    //
    public synchronized void setPosSize( int X, int Y, int Width, int Height, short Flags )
    {
        if( dummyFrame != null )
        {
            dummyFrame.setPosSize( X, Y, Width, Height, Flags );

            Width = Math.max(1,Width);
            Height= Math.max(1,Height);

            CanvasUtils.printLog( "JavaCanvas graphics set to " + Width + "," + Height );
            backBuffer.setSize(Width,Height);
        }
    }

    public synchronized com.sun.star.awt.Rectangle getPosSize(  )
    {
        if( dummyFrame != null )
            return dummyFrame.getPosSize();

        return new com.sun.star.awt.Rectangle();
    }

    public synchronized void setVisible( boolean visible )
    {
        if( dummyFrame != null )
            dummyFrame.setVisible( visible );
    }

    public synchronized void setEnable( boolean enable )
    {
        if( dummyFrame != null )
            dummyFrame.setEnable( enable );
    }

    public synchronized void setFocus()
    {
        if( dummyFrame != null )
            dummyFrame.setFocus();
    }

    public synchronized void addWindowListener( XWindowListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addWindowListener( xListener );
    }

    public synchronized void removeWindowListener( XWindowListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeWindowListener( xListener );
    }

    public synchronized void addFocusListener( XFocusListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addFocusListener( xListener );
    }

    public synchronized void removeFocusListener( XFocusListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeFocusListener( xListener );
    }

    public synchronized void addKeyListener( XKeyListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addKeyListener( xListener );
    }

    public synchronized void removeKeyListener( XKeyListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeKeyListener( xListener );
    }

    public synchronized void addMouseListener( XMouseListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addMouseListener( xListener );
    }

    public synchronized void removeMouseListener( XMouseListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeMouseListener( xListener );
    }

    public synchronized void addMouseMotionListener( XMouseMotionListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addMouseMotionListener( xListener );
    }

    public synchronized void removeMouseMotionListener( XMouseMotionListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removeMouseMotionListener( xListener );
    }

    public synchronized void addPaintListener( XPaintListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.addPaintListener( xListener );
    }

    public synchronized void removePaintListener( XPaintListener xListener )
    {
        if( dummyFrame != null )
            dummyFrame.removePaintListener( xListener );
    }

    //----------------------------------------------------------------------------------

    //
    // XBitmapCanvas impl
    // ==================
    //

    public synchronized void copyRect( drafts.com.sun.star.rendering.XBitmapCanvas  sourceCanvas,
                                       drafts.com.sun.star.geometry.RealRectangle2D sourceRect,
                                       drafts.com.sun.star.rendering.ViewState      sourceViewState,
                                       drafts.com.sun.star.rendering.RenderState    sourceRenderState,
                                       drafts.com.sun.star.geometry.RealRectangle2D destRect,
                                       drafts.com.sun.star.rendering.ViewState      destViewState,
                                       drafts.com.sun.star.rendering.RenderState    destRenderState )
    {
        CanvasUtils.printLog( "JavaCanvas.copyRect() called" );

        // TODO: create temp image when transform is non-trivial

        if( sourceCanvas == this )
        {
            // copy rectangle within the canvas
            getGraphics().copyArea((int)sourceRect.X1,
                                   (int)sourceRect.Y1,
                                   (int)(sourceRect.X2 - sourceRect.X1),
                                   (int)(sourceRect.Y2 - sourceRect.Y1),
                                   (int)(destRect.X1 - sourceRect.X1),
                                   (int)(destRect.Y1 - sourceRect.Y1) );
        }
        else
        {
            if( sourceCanvas instanceof JavaCanvas )
            {
                // cache
                CanvasUtils.setupGraphicsState( getGraphics(), destViewState, destRenderState, CanvasUtils.alsoSetupPaint );

                java.awt.Image backBuffer = ((JavaCanvas)sourceCanvas).backBuffer.getBackBuffer();

                // TODO: really extract correct source rect here
                getGraphics().drawImage( backBuffer, 0, 0, null);
                CanvasUtils.postRenderImageTreatment( backBuffer );
            }
            // TODO: foreign canvas
        }
    }

    //----------------------------------------------------------------------------------

    // a map of SpriteReps, with Sprite object as keys. Contains all
    // active (i.e. visible) sprites, the SpriteReps are used to
    // repaint the sprite content at any time.
    private java.util.HashMap activeSprites;

    //
    // XSpriteCanvas impl
    // ==================
    //

    public synchronized drafts.com.sun.star.rendering.XAnimatedSprite createSpriteFromAnimation( XAnimation animation )
    {
        CanvasUtils.printLog( "JavaCanvas.createSpriteFromAnimation called" );

        return new CanvasSprite( animation, this, (Graphics2D)dummyFrame.frame.getGraphics() );
    }

    public synchronized XAnimatedSprite createSpriteFromBitmaps( drafts.com.sun.star.rendering.XBitmap[] animationBitmaps,
                                                                 byte interpolationMode )
    {
        return null;
    }

    public synchronized XCustomSprite createCustomSprite( RealSize2D spriteSize )
    {
        CanvasUtils.printLog( "JavaCanvas.createCustomSprite called" );

        return new CanvasCustomSprite( spriteSize, this, (Graphics2D)dummyFrame.frame.getGraphics() );
    }

    public synchronized XSprite createClonedSprite( XSprite original )
    {
        return new CanvasClonedSprite( this, original );
    }

    public synchronized boolean updateScreen( boolean bUpdateAll )
    {
        redrawAllLayers();

        return true;
    }

    //
    // XBitmap implementation
    // ======================
    //

    public synchronized IntegerSize2D getSize()
    {
        return new IntegerSize2D( boundRect.Width,
                                  boundRect.Height );
    }

    //----------------------------------------------------------------------------------

    public synchronized XBitmapCanvas queryBitmapCanvas()
    {
        return this;
    }

    //----------------------------------------------------------------------------------

    public synchronized drafts.com.sun.star.rendering.XBitmap getScaledBitmap( RealSize2D newSize, boolean beFast ) throws com.sun.star.lang.IllegalArgumentException, VolatileContentDestroyedException
    {
        // TODO
        return null;
    }

    //----------------------------------------------------------------------------------

    //
    // XIntegerBitmap implementation
    // =============================
    //

    public synchronized byte[] getData( IntegerRectangle2D rect )
    {
        // TODO
        return null;
    }

    //----------------------------------------------------------------------------------

    public synchronized void setData( byte[] data, IntegerBitmapLayout bitmapLayout, drafts.com.sun.star.geometry.IntegerRectangle2D rect )
    {
        // TODO
    }

    //----------------------------------------------------------------------------------

    public synchronized void setPixel( byte[] color, IntegerBitmapLayout bitmapLayout, drafts.com.sun.star.geometry.IntegerPoint2D pos )
    {
        // TODO
    }

    //----------------------------------------------------------------------------------

    public synchronized byte[] getPixel( IntegerPoint2D pos )
    {
        // TODO
        return null;
    }

    //----------------------------------------------------------------------------------

    public synchronized XBitmapPalette getPalette()
    {
        // TODO
        return null;
    }

    //----------------------------------------------------------------------------------

    public synchronized IntegerBitmapLayout getMemoryLayout()
    {
        // TODO: finish that one
        IntegerBitmapLayout layout = new IntegerBitmapLayout();

        layout.ScanLines = boundRect.Width;
        layout.ScanLineBytes = boundRect.Width*4;
        layout.ScanLineStride = layout.ScanLineBytes;
        layout.Format = 0;
        layout.NumComponents = 4;
        layout.ComponentMasks = null;
        layout.Endianness = 0;
        layout.IsPseudoColor = false;

        return layout;
    }

    //----------------------------------------------------------------------------------

    //
    // XSpriteCanvas helper
    // ====================
    //
    public synchronized void renderAnimation( CanvasSprite sprite, XAnimation animation, double t )
    {
        SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite );
        if( spriteRep != null )
        {
            //Graphics2D graph = getWindowGraphics();

            // TODO: ensure update of graphics object externally, e.g. when
            // VCL moves the toplevel window.
            //java.awt.Rectangle bounds = dummyFrame.frame.getBounds();
            //graphics.setGraphics(graph, bounds.width, bounds.height);

            spriteRep.renderAnimation( animation, sprite.getViewState(), t );
        }
        else
        {
            CanvasUtils.printLog( "JavaCanvas.renderAnimation sprite not active!" );
        }
    }

    public synchronized void showSprite( SpriteBase sprite )
    {
        CanvasUtils.printLog( "JavaCanvas.showSprite() called" );

        SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite );
        if( spriteRep != null )
        {
            CanvasUtils.printLog( "JavaCanvas.showSprite sprite already active!" );
        }
        else
        {
            spriteRep = sprite.getSpriteRep();

            // a valid SpriteRep for a given Sprite in the
            // activeSprites hash denotes 'sprite active'
            activeSprites.put( sprite, spriteRep );

            // TODO: TEMP! Just for testing! Set empty cursor for presentation
//             dummyFrame.frame.setCursor( dummyFrame.frame.getToolkit().createCustomCursor(new java.awt.image.BufferedImage(0,0,
//                                                                                                                           java.awt.image.BufferedImage.TYPE_INT_RGB),
//                                                                                          new java.awt.Point(0,0),
//                                                                                          "") );
        }
    }

    public synchronized void hideSprite( SpriteBase sprite )
    {
        CanvasUtils.printLog( "JavaCanvas.hideSprite() called" );

        SpriteRep spriteRep = (SpriteRep)activeSprites.get( sprite );
        if( spriteRep != null )
        {
            activeSprites.put( sprite, null );
            redrawAllLayers();
        }
        else
        {
            CanvasUtils.printLog( "JavaCanvas.hideSprite sprite not active!" );
        }
    }

    private void redrawAllLayers()
    {
        // fetch the Graphics object to draw into (we're doing double
        // buffering here, the content is later shown via
        // bufferStrategy.show().
        Graphics2D graph = null;

        try
        {
            graph = (Graphics2D)bufferStrategy.getDrawGraphics();

            GraphicsDevice device = graph.getDeviceConfiguration().getDevice();
            CanvasUtils.printLog( "Available vram: " + device.getAvailableAcceleratedMemory() );

            // repaint background
            backBuffer.redraw( graph );

            // repaint all active sprites
            java.util.Set entries = activeSprites.entrySet();
            java.util.Iterator iter = entries.iterator();
            while( iter.hasNext() )
            {
                java.util.Map.Entry entry = (java.util.Map.Entry)iter.next();
                if( entry.getValue() != null )
                    ((SpriteRep)entry.getValue()).redraw(graph);
            }

            long currTime = System.currentTimeMillis();
            graph.setComposite( AlphaComposite.getInstance(AlphaComposite.SRC_OVER) );
            graph.setFont( fpsFont );
            graph.setColor( java.awt.Color.black );

            try
            {
                String fps = new String( String.valueOf(1000.0/(currTime-lastTime)) );
                graph.drawString( fps.substring(0,5) + " fps", 0, 20);
                CanvasUtils.printLog( fps.substring(0,5) + " fps" );
            }
            catch( Exception e )
            {
                graph.drawString( "0 fps", 0, 20);
            }

            lastTime = currTime;
        }
        catch( Exception e )
        {
            CanvasUtils.printLog( "Exception thrown in redrawAllLayers" );
        }
        finally
        {
            if( graph != null )
                graph.dispose();
        }

        bufferStrategy.show();
    }

    //----------------------------------------------------------------------------------

    private static final String s_implName = "XCanvas.java.impl";
    private static final String s_serviceName = "drafts.com.sun.star.rendering.JavaCanvas";

    //----------------------------------------------------------------------------------

    //
    // XServiceInfo impl
    // =================
    //
    public synchronized String getImplementationName()
    {
        return s_implName;
{'fraction_non_alphanumeric': 0.1496741362378359, 'fraction_numerical': 0.008168913489866977, 'mean_word_length': 1.6961728246479721, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 5, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 63, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3291311', 'n_tokens_mistral': 11464, 'n_tokens_neox': 10794, 'n_words': 2867}