FileDocCategorySizeDatePackage
DirtyAreaManager.javaAPI DocphoneME MR2 API (J2ME)15557Wed May 02 18:00:36 BST 2007com.sun.perseus.model

DirtyAreaManager

public class DirtyAreaManager extends UpdateAdapter

The DirtyAreaManager abstraction is responsible for tracking areas of the document tree which need to be repainted.

version
$Id: DirtyAreaManager.java,v 1.16 2006/06/29 10:47:30 ln156897 Exp $

Fields Summary
public static boolean
ON
TEMPORARY: GLOBAL VARIABLE ALLOWING US TO CONTROL WHETHER DIRTY AREA TRACKING IS ON OR OFF.
public static final int
DEFAULT_TILE_MIN_SIZE
The minimal tile width or height.
Vector
dirtyNodes
The list of modified nodes. Some may have been removed from the tree.
TileElement
rootTile
The Root tile representing this surface.
Viewport
vp
The associated viewport, which defines the size of the rendering area.
int
tileMinSize
The minimal size, in both dimensions, for dirty area tiles.
int
lastWidth
Width of the viewport last time it was painted.
int
lastHeight
Height of the viewport last time it was painted.
com.sun.perseus.j2d.RenderGraphics
lastRG
The last RenderGraphics for which dirty areas were checked.
Constructors Summary
public DirtyAreaManager(Viewport vp)

param
vp the associated viewport.


              
       
        setViewport(vp);
    
Methods Summary
public com.sun.perseus.model.DirtyAreaManager$TileElementgetDirtyAreas(com.sun.perseus.j2d.RenderGraphics rg)
It is the responsibility of the dirty area manager to compute the list of dirty areas which need to be re-painted. The minimum includes the area covered by the modified node's old and new bounds. For efficiency purposes, the implementation may collapse the rectangles into a few ones.

param
rg the RenderGraphics for which dirty areas are queried. The first tile a RenderGraphics is passed to this method, the full area is considered dirty.
return
the set of rectangles to render, based on the list of node whose rendering has changed.

        int vw = vp.width;
        int vh = vp.height;

        if (lastWidth != vw || lastHeight != vh) {
            // System.err.println(">>>>>>> lastWidth was : " + lastWidth 
            //                      + " lastHeight was " + lastHeight);
            // System.err.println(">>>>>>> new width is  : " + vw 
            //                      + " new height is " + vh);

            lastWidth = vw;
            lastHeight = vh;
            if (vw >= (2 * tileMinSize) 
                && 
                vh >= (2 * tileMinSize)) {
                rootTile = new TileQuadrant(null, tileMinSize, 0, 0, vw, vh);
            } else {
                rootTile = new TileElement(null, 0, 0, vw, vh);
            }

            // This is the first rendering or the viewport dimensions have
            // changed.  Everything is dirty. We need to repaint the full
            // canvas.
            dirtyNodes.removeAllElements();
            lastRG = rg;
            return rootTile;
        }

        // If it is the first time we render in this RenderGraphics, we consider
        // the complete area dirty.
        if (lastRG != rg) {
            System.err.println(">>>> RenderGraphics changed");
            lastRG = rg;
            dirtyNodes.removeAllElements();
            return rootTile;
        }

        // Unmark all areas
        rootTile.clear();

        final int nn = dirtyNodes.size();
        Tile nb = null;
        ModelNode n = null;
        for (int i = 0; i < nn && !rootTile.hit; i++) {
            n = (ModelNode) dirtyNodes.elementAt(i);

            // First, check the previous rendering's tile.
            rootTile.checkHit(n.getLastRenderedTile());

            // Clear the last rendered tile so that the area is not
            // unnecessarily repainted in the future, in case this node is, for
            // example, hidden for a while before being repainted.
            n.clearLastRenderedTile();

            // Now, compute the current rendering tile and check the 
            // area it hits.
            if (n.parent != null && (n.canRenderState == 0)) {
                rootTile.checkHit(n.getRenderingTile());
            } 
        }

        dirtyNodes.removeAllElements();

        return rootTile.getHitTiles(null); 
    
public voidmodifyingNodeRendering(ModelNode node)
Invoked when a node's Rendering is about to be modified

param
node the node which is about to be modified

        if (!dirtyNodes.contains(node)) {
            dirtyNodes.addElement(node);
        }
    
public voidnodeInserted(ModelNode node)
Invoked when a node has been inserted into the tree

param
node the newly inserted node

        // We only keep track of nodes which actually have a rendering.
        if (!dirtyNodes.contains(node) && node.hasNodeRendering()) {
            dirtyNodes.addElement(node);
        }
    
public voidrefresh(ModelNode mn, com.sun.perseus.j2d.RenderGraphics rg, com.sun.perseus.j2d.RGB clearPaint)
Asks the DirtyAreaManager to repaint all the diry areas on the given RenderGraphics

param
mn the model node to render, typically, the DocumentNode.
param
rg the RenderGraphics to render to.
param
clearPaint the color to use to clear the background

        TileElement dirtyAreaList = getDirtyAreas(rg);
        TileElement curTile = dirtyAreaList;
        int nTiles = 0;
        while (curTile != null) {
            // System.err.println("Painting tile : " + curTile 
            //         + " in thread " + Thread.currentThread());
            // System.err.println("clearing with paint : " + clearPaint);
            // System.err.println("Painting on buffer of size : " 
            //         + rg.bi.getWidth() + "/" + rg.bi.getHeight());
            rg.setRenderingTile(curTile);
            rg.clearRect(curTile.x, 
                         curTile.y, 
                         curTile.maxX - curTile.x + 1, 
                         curTile.maxY - curTile.y + 1,
                         clearPaint);
            mn.paint(rg);
            curTile = curTile.next;

            /*
            javax.swing.JOptionPane.showMessageDialog(
                    null, 
                    "Current Offscreen : " + rg.bi.getWidth() + " / " 
                        + rg.bi.getHeight(), 
                    "Debug",
                    0, 
                    new javax.swing.ImageIcon(rg.bi));
            */
        }
    
public voidsetTileMinSize(int tileMinSize)

param
tileMinSize the minimal size for a rendering tile.

        if (tileMinSize < 1) {
            throw new IllegalArgumentException();
        }

        this.tileMinSize = tileMinSize;
        lastWidth = -1;
        lastHeight = -1;
    
public voidsetViewport(Viewport vp)

param
vp the new associated viewport.

        if (vp == this.vp) {
            return;
        }

        this.vp = vp;

        // Reset the lastWidth and lastHeight values to force a full repaint
        // on the first getDirtyAreas call.
        lastWidth = -1;
        lastHeight = -1;