javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/org/eclipse/swt/internal/qt/graphics/JavaCommandBuffer.java
changeset 48 e0d6e9bd3ca7
parent 47 f40128debb5d
child 53 3035d69b481d
child 61 bf7ee68962da
equal deleted inserted replaced
47:f40128debb5d 48:e0d6e9bd3ca7
     1 /*******************************************************************************
     1 /******************************************************************************* * Copyright (c) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: *     Nokia Corporation - initial implementation *******************************************************************************/
     2  * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved. This program and the accompanying materials
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  *
       
     8  * Contributors:
       
     9  *     Nokia Corporation - initial implementation
       
    10  *******************************************************************************/
       
    11 package org.eclipse.swt.internal.qt.graphics;
     2 package org.eclipse.swt.internal.qt.graphics;
    12 
     3 import java.util.Vector;import java.util.Enumeration;
    13 import java.util.Vector;
     4 /** * This class implements a command buffer that can be bound by GraphicsContext * to collect the drawing operations. Contents of the command buffer can be replayed to * GraphicsContext target with GraphicsContext.render() method. * * When JavaCommandBuffer is set as the target of GraphicsContext some of the methods * provided by GraphicsContext are not supported, e.g. getters, since the JavaCommandBuffer * does not have a real rendering target from which to query related data. To find out what is * supported see the methods of this class. In principal GraphicsContext supports all draw and set operations, * when JavaCommandBuffer is set as rendering target. */
    14 import java.util.Enumeration;
     5 public final class JavaCommandBuffer {    // All collected drawing operations and their parameters    private int[] intParams;    private int intCount;    private StringBuffer strParams;    // Container for images    private Vector images;
    15 
     6     // Container for rgbData    private Vector rgbData;
    16 /**
     7     // This flag is indicates if this buffer is bound by some GraphicsContext    private boolean bound;
    17  * This class implements a command buffer that can be bound by GraphicsContext
     8     // This flag indicates if this buffer is empty or not    private boolean containsData;
    18  * to collect the drawing operations. Contents of the command buffer can be replayed to
     9     // This flag indicates if this buffer has any draw commands in it    private boolean containsPrimitiveData;
    19  * GraphicsContext target with GraphicsContext.render() method.
    10     // Memory management configuration constants    private static final int INT_BUF_GRANULARITY         = 10;    private static final int INT_BUF_INITIAL_SIZE        = 250;    private static final int IMAGE_BUF_INITIAL_SIZE      = 3;    private static final int IMAGE_BUF_GRANULARITY       = 2;    private static final int STRING_BUFFER_INITIAL_SIZE  = 10;
    20  *
    11     // Prefixes for different categories of op codes, stored in MSB    final static int DRAW_PREFIX = 0;    final static int FILL_PREFIX = 1;    final static int SET_PREFIX = 2;    final static int MISC_PREFIX = 3;
    21  * When JavaCommandBuffer is set as the target of GraphicsContext some of the methods
    12     // Unique operation codes for all the gc operations that can be buffered.    static final int OP_DRAWARC            = ((DRAW_PREFIX << 24) | 1);    static final int OP_DRAWFOCUS          = ((DRAW_PREFIX << 24) | 2);    static final int OP_DRAWIMAGE1         = ((DRAW_PREFIX << 24) | 3);    static final int OP_DRAWIMAGE2         = ((DRAW_PREFIX << 24) | 4);    static final int OP_DRAWLINE           = ((DRAW_PREFIX << 24) | 5);    static final int OP_DRAWELLIPSE        = ((DRAW_PREFIX << 24) | 6);    static final int OP_DRAWPOINT          = ((DRAW_PREFIX << 24) | 7);    static final int OP_DRAWPOLYGON        = ((DRAW_PREFIX << 24) | 8);    static final int OP_DRAWPOLYLINE       = ((DRAW_PREFIX << 24) | 9);    static final int OP_DRAWRECT           = ((DRAW_PREFIX << 24) | 10);    static final int OP_DRAWRGB_INT        = ((DRAW_PREFIX << 24) | 11);    static final int OP_DRAWRGB_BYTE       = ((DRAW_PREFIX << 24) | 12);    static final int OP_DRAWRGB_SHORT      = ((DRAW_PREFIX << 24) | 13);    static final int OP_DRAWROUNDRECT      = ((DRAW_PREFIX << 24) | 14);    static final int OP_DRAWSTRING         = ((DRAW_PREFIX << 24) | 15);    static final int OP_FILLARC            = ((FILL_PREFIX << 24) | 16);    static final int OP_FILLGRADIENTRECT   = ((FILL_PREFIX << 24) | 17);    static final int OP_FILLELLIPSE        = ((FILL_PREFIX << 24) | 18);    static final int OP_FILLPOLYGON        = ((FILL_PREFIX << 24) | 19);    static final int OP_FILLRECT           = ((FILL_PREFIX << 24) | 20);    static final int OP_FILLROUNDRECT      = ((FILL_PREFIX << 24) | 21);    static final int OP_SETBACKGROUNDALPHA = ((SET_PREFIX << 24) | 22);    static final int OP_SETBACKGROUNDCOLOR = ((SET_PREFIX << 24) | 23);    static final int OP_SETBLENDINGMODE    = ((SET_PREFIX << 24) | 24);    static final int OP_SETCLIP            = ((SET_PREFIX << 24) | 25);    static final int OP_CANCELCLIPPING     = ((SET_PREFIX << 24) | 26);    static final int OP_SETFONT            = ((SET_PREFIX << 24) | 27);    static final int OP_SETFOREGROUNDALPHA = ((SET_PREFIX << 24) | 28);    static final int OP_SETFOREGROUNDCOLOR = ((SET_PREFIX << 24) | 29);    static final int OP_SETSTROKESTYLE     = ((SET_PREFIX << 24) | 30);    static final int OP_SETSTROKEWIDTH     = ((SET_PREFIX << 24) | 31);    static final int OP_TRANSLATE          = ((MISC_PREFIX << 24) | 32);    static final int OP_SCALE              = ((MISC_PREFIX << 24) | 33);    static final int OP_RESETTRANSFORM     = ((MISC_PREFIX << 24) | 34);    static final int OP_COPYAREA1          = ((MISC_PREFIX << 24) | 35);    static final int OP_COPYAREA2          = ((MISC_PREFIX << 24) | 36);    /**     * Constructs empty command buffer with defined buffer sizes.     */    public JavaCommandBuffer() {        intParams = new int[INT_BUF_INITIAL_SIZE];        strParams = new StringBuffer(STRING_BUFFER_INITIAL_SIZE);        images = new Vector(IMAGE_BUF_INITIAL_SIZE, IMAGE_BUF_GRANULARITY);        rgbData = new Vector(IMAGE_BUF_INITIAL_SIZE, IMAGE_BUF_GRANULARITY);    }    /**     * Resets the buffer, i.e. removes all recorded commands and related data. The integer array containing     * the actual operation codes is not deleted, only the index pointer is rested, thus the memory consumption of that is not freed.     * CommandBuffer can be reseted only if it is not bound by any GraphicsContext     * @throws IllegalStateException if this CommandBuffer is bound while calling reset     */    public void reset() {        if(bound) {            throw new IllegalStateException("CommandBuffer is still bound by gc");        }        intCount = 0;        strParams.setLength(0);        Enumeration allImages = images.elements();        while(allImages.hasMoreElements()) {            Image image = (Image)allImages.nextElement();            if(image != null) {                image.freeCommandBufferCopy();            }        }        images.removeAllElements();        rgbData.removeAllElements();        containsData = false;        containsPrimitiveData = false;    }    /**     * Checks that does this buffer contain any commands     * @return true if any command has been written to buffer otherwise false     */    public boolean containsData() {        return containsData;    }    /**     * Checks that does this buffer contain any draw commands, i.e. any setters etc.     * that does to cause any pixels to be rendered are ignored     * @return true if any draw command has been written to buffer otherwise false     */    public boolean containsDrawnPrimitives() {        return containsPrimitiveData;    }    /**     * Binds this buffer     */    void bind() {        bound = true;    }    /**     * Provides the binding status of this buffer     * @return true if this buffer has been already bound otherwise false     */    boolean isBound() {        return bound;    }    /**     * Releases this buffer, i.e. it can be bound by some other GraphicsContext     */    void release() {        bound = false;    }    private void ensureIntArraySpace(final int items) {        if( intParams.length < intCount + items) {            int[] dst = new int[intParams.length + Math.max(INT_BUF_GRANULARITY, items)];            System.arraycopy(intParams, 0, dst, 0, intParams.length);            intParams = dst;        }        containsData = true;    }    private void reportNotSupported() {        throw new RuntimeException("Intenal: Operation not supported with JavaCommandBuffer");    }//    private void printBufferInfo() {//        System.out.println("CommandBuffer Info: " +this);//        System.out.println("intParamCount: " + intCount);//        System.out.println("intBuffer Size: " + intParams.length);//        System.out.println("StringBuffer Size: " + strParams.length());//    }    private void raisePrimitiveFlag() {        containsPrimitiveData = true;    }    int[] intParams() {        return intParams;    }    int intParamCount() {        return intCount;    }    Vector rgbParams() {        return rgbData;    }    Vector images() {        return images;    }    String strParams() {        return strParams.toString();    }    void drawArc (final int x, final int y, final int width, final int height, final int startAngle, final int arcAngle) {        ensureIntArraySpace(7);        intParams[intCount++] = OP_DRAWARC;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = startAngle;        intParams[intCount++] = arcAngle;        raisePrimitiveFlag();    }    void drawFocus (final int x, final int y, final int width, final int height) {        ensureIntArraySpace(5);        intParams[intCount++] = OP_DRAWFOCUS;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        raisePrimitiveFlag();    }    // Must be called from UI thread as images cannot be creates outside that    void drawImage(final Image image, final int x, final int y) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_DRAWIMAGE1;        intParams[intCount++] = x;        intParams[intCount++] = y;        // creating copy of image here uses implicit data sharing,        // thus only a shallow copy is made        images.addElement(image.getCommandBufferCopy());        raisePrimitiveFlag();    }    // must be called from UI thread as images cannot be creates outside that    void drawImage(final Image image, final int tx, final int ty, final int tw, final int th, final int sx, final int sy, final int sw, final int sh, final int manipulation) {        ensureIntArraySpace(10);        intParams[intCount++] = OP_DRAWIMAGE2;        intParams[intCount++] = tx;        intParams[intCount++] = ty;        intParams[intCount++] = tw;        intParams[intCount++] = th;        intParams[intCount++] = sx;        intParams[intCount++] = sy;        intParams[intCount++] = sw;        intParams[intCount++] = sh;        intParams[intCount++] = manipulation;        // creating copy of image here uses implicit data sharing,        // thus only a shallow copy is made        images.addElement(image.getCommandBufferCopy());        raisePrimitiveFlag();    }    void drawLine (final int x1, final int y1, final int x2, final int y2) {        ensureIntArraySpace(5);        intParams[intCount++] = OP_DRAWLINE;        intParams[intCount++] = x1;        intParams[intCount++] = y1;        intParams[intCount++] = x2;        intParams[intCount++] = y2;        raisePrimitiveFlag();    }    void drawEllipse (final int x, final int y, final int width, final int height) {        ensureIntArraySpace(5);        intParams[intCount++] = OP_DRAWELLIPSE;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        raisePrimitiveFlag();    }    void drawPoint (final int x, final int y) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_DRAWPOINT;        intParams[intCount++] = x;        intParams[intCount++] = y;        raisePrimitiveFlag();    }    void drawPolygon(final int[] pointArray) {        ensureIntArraySpace(2 + pointArray.length);        intParams[intCount++] = OP_DRAWPOLYGON;        intParams[intCount++] = pointArray.length;        for(int i = 0; i < pointArray.length; ++i) {            intParams[intCount++] = pointArray[i];        }        raisePrimitiveFlag();    }    void drawPolyline(final int[] pointArray) {        ensureIntArraySpace(2 + pointArray.length);        intParams[intCount++] = OP_DRAWPOLYLINE;        intParams[intCount++] = pointArray.length;        for(int i = 0; i < pointArray.length; ++i) {            intParams[intCount++] = pointArray[i];        }        raisePrimitiveFlag();    }    void drawRect (final int x, final int y, final int width, final int height) {        ensureIntArraySpace(5);        intParams[intCount++] = OP_DRAWRECT;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        raisePrimitiveFlag();    }    void drawRGB(final int[] rgb, final int offset, final int scanlength, final int x, final int y, final int width, final int height, final boolean processAlpha, final int manipulation) {        ensureIntArraySpace(9);        intParams[intCount++] = OP_DRAWRGB_INT;        intParams[intCount++] = offset;        intParams[intCount++] = scanlength;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = processAlpha? 1 : 0;        intParams[intCount++] = manipulation;        rgbData.addElement(rgb);        raisePrimitiveFlag();    }    void drawRGB(final byte[] rgb, final byte[] transparencyMask, final int offset, final int scanlength, final int x, final int y, final int width, final int height, final int manipulation, final int format) {        ensureIntArraySpace(9);        intParams[intCount++] = OP_DRAWRGB_BYTE;        intParams[intCount++] = offset;        intParams[intCount++] = scanlength;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = manipulation;        intParams[intCount++] = format;        rgbData.addElement(rgb);        rgbData.addElement(transparencyMask);        raisePrimitiveFlag();    }    void drawRGB(final short[] rgb, final int offset, final int scanlength, final int x, final int y, final int width, final int height, final boolean processAlpha, final int manipulation, final int format) {        ensureIntArraySpace(10);        intParams[intCount++] = OP_DRAWRGB_SHORT;        intParams[intCount++] = offset;        intParams[intCount++] = scanlength;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = processAlpha? 1 : 0;        intParams[intCount++] = manipulation;        intParams[intCount++] = format;        rgbData.addElement(rgb);        raisePrimitiveFlag();    }    void drawRoundRect (final int x, final int y, final int width, final int height, final int arcWidth, final int arcHeight) {        ensureIntArraySpace(7);        intParams[intCount++] = OP_DRAWROUNDRECT;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = arcWidth;        intParams[intCount++] = arcHeight;        raisePrimitiveFlag();    }    void drawString(final String string, final int x, final int y, final int width, final int height, final int alignments, final int flags, final boolean isTransparent) {        ensureIntArraySpace(9);        intParams[intCount++] = OP_DRAWSTRING;        intParams[intCount++] = string.length();        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = alignments;        intParams[intCount++] = flags;        intParams[intCount++] = isTransparent? 1 : 0;        strParams.append(string);        raisePrimitiveFlag();    }    void fillArc (final int x, final int y, final int width, final int height, final int startAngle, final int arcAngle) {        ensureIntArraySpace(7);        intParams[intCount++] = OP_FILLARC;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = startAngle;        intParams[intCount++] = arcAngle;        raisePrimitiveFlag();    }    void fillGradientRect(final int x, final int y, final int width, final int height, final boolean vertical, final boolean swapColors) {        ensureIntArraySpace(7);        intParams[intCount++] = OP_FILLGRADIENTRECT;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = vertical ? 1 : 0;        intParams[intCount++] = swapColors ? 1 : 0;        raisePrimitiveFlag();    }    void fillEllipse (final int x, final int y, final int width, final int height) {        ensureIntArraySpace(5);        intParams[intCount++] = OP_FILLELLIPSE;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        raisePrimitiveFlag();    }    void fillPolygon (final int[] pointArray) {        ensureIntArraySpace(2 + pointArray.length);        intParams[intCount++] = OP_FILLPOLYGON;        intParams[intCount++] = pointArray.length;        for(int i = 0; i < pointArray.length; ++i) {            intParams[intCount++] = pointArray[i];        }        raisePrimitiveFlag();    }    void fillRect (final int x, final int y, final int width, final int height) {        ensureIntArraySpace(5);        intParams[intCount++] = OP_FILLRECT;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        raisePrimitiveFlag();    }    void fillRoundRectangle (final int x, final int y, final int width, final int height, final int arcWidth, final int arcHeight) {        ensureIntArraySpace(7);        intParams[intCount++] = OP_FILLROUNDRECT;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = arcWidth;        intParams[intCount++] = arcHeight;        raisePrimitiveFlag();    }    public void setBackgroundAlpha(final int alpha) {        ensureIntArraySpace(2);        intParams[intCount++] = OP_SETBACKGROUNDALPHA;        intParams[intCount++] = alpha;    }    void setBackgroundColor(final int argb, final boolean updateAlpha) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_SETBACKGROUNDCOLOR;        intParams[intCount++] = argb;        intParams[intCount++] = updateAlpha? 1 : 0;    }    void setBlendingMode(final int mode) {        ensureIntArraySpace(2);        intParams[intCount++] = OP_SETBLENDINGMODE;        intParams[intCount++] = mode;    }    void setClip(final int x, final int y, final int width, final int height, final boolean intersects) {        ensureIntArraySpace(6);        intParams[intCount++] = OP_SETCLIP;        intParams[intCount++] = x;        intParams[intCount++] = y;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = intersects? 1 : 0;    }    void cancelClipping () {        ensureIntArraySpace(1);        intParams[intCount++] = OP_CANCELCLIPPING;    }    void setFont(final int fontHandle) {        ensureIntArraySpace(2);        intParams[intCount++] = OP_SETFONT;        intParams[intCount++] = fontHandle;    }    void setForegroundAlpha(final int alpha) {        ensureIntArraySpace(2);        intParams[intCount++] = OP_SETFOREGROUNDALPHA;        intParams[intCount++] = alpha;    }    void setForegroundColor(final int argb, final boolean updateAlpha) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_SETFOREGROUNDCOLOR;        intParams[intCount++] = argb;        intParams[intCount++] = updateAlpha? 1 : 0;    }    void setStrokeStyle(final int style) {        ensureIntArraySpace(2);        intParams[intCount++] = OP_SETSTROKESTYLE;        intParams[intCount++] = style;    }    void setStrokeWidth(final int width) {        ensureIntArraySpace(2);        intParams[intCount++] = OP_SETSTROKEWIDTH;        intParams[intCount++] = width;    }    void translate(final int x, final int y) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_TRANSLATE;        intParams[intCount++] = x;        intParams[intCount++] = y;    }    void scale(final int x, final int y) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_SCALE;        intParams[intCount++] = x;        intParams[intCount++] = y;    }    void resetTransform() {        ensureIntArraySpace(1);        intParams[intCount++] = OP_RESETTRANSFORM;    }    void copyArea(final Image image, final int x, final int y) {        ensureIntArraySpace(3);        intParams[intCount++] = OP_COPYAREA1;        intParams[intCount++] = x;        intParams[intCount++] = y;        // TODO does this need flushing on the image        images.addElement(new Image(image));        raisePrimitiveFlag();    }    void copyArea(final int srcX, final int srcY, final int width, final int height, final int destX, final int destY, final boolean paint) {        ensureIntArraySpace(8);        intParams[intCount++] = OP_COPYAREA2;        intParams[intCount++] = srcX;        intParams[intCount++] = srcY;        intParams[intCount++] = width;        intParams[intCount++] = height;        intParams[intCount++] = destX;        intParams[intCount++] = destY;        intParams[intCount++] = paint? 1 : 0;        raisePrimitiveFlag();    }    // Unsupported operations    int getAdvancedCharacterWidth(final char ch, final boolean isAdvanced) {        reportNotSupported();        return 0;    }    void getFontMetricsData(final int[] data, final int fontHandle) {        reportNotSupported();    }    int getBackgroundAlpha() {        reportNotSupported();        return 0;    }    int getBackgroundColor() {        reportNotSupported();        return 0;    }    int getBlendingMode() {        reportNotSupported();        return 0;    }    void getClip(final int[] clip) {        reportNotSupported();    }    int getForegroundAlpha() {        reportNotSupported();        return 0;    }    int getForegroundColor() {        reportNotSupported();        return 0;    }    void getTextBoundingBox(final int[] boundingBox, final String string, final int alignments, final int flags, final int rectX, final int rectY, final int rectWidth, final int rectHeight) {        reportNotSupported();    }    int getStrokeWidth() {        reportNotSupported();        return 0;    }    int getStrokeStyle() {        reportNotSupported();        return 0;    }    int getTranslateX() {        reportNotSupported();        return 0;    }    int getTranslateY() {        reportNotSupported();        return 0;    }    boolean hasClipping() {        reportNotSupported();        return false;    }    void saveSettings() {        reportNotSupported();    }    void restoreSettings() {        reportNotSupported();    }}
    22  * provided by GraphicsContext are not supported, e.g. getters, since the JavaCommandBuffer
       
    23  * does not have a real rendering target from which to query related data. To find out what is
       
    24  * supported see the methods of this class. In principal GraphicsContext supports all draw and set operations,
       
    25  * when JavaCommandBuffer is set as rendering target.
       
    26  */
       
    27 public final class JavaCommandBuffer {
       
    28 
       
    29     // All collected drawing operations and their parameters
       
    30     private int[] intParams;
       
    31     private int intCount;
       
    32     private StringBuffer strParams;
       
    33 
       
    34     // Holder for images
       
    35     private Vector images;
       
    36 
       
    37     // holder for rgbData
       
    38     private Vector rgbData;
       
    39 
       
    40     // This flag is indicates if this buffer is bound by some GraphicsContext
       
    41     private boolean bound;
       
    42 
       
    43     // This flag indicates if this buffer is empty or not
       
    44     private boolean containsData;
       
    45     
       
    46     // This flag indicates if this buffer has any draw commands in it
       
    47     private boolean containsPrimitiveData;
       
    48 
       
    49     // Memory management configuration constants
       
    50     private static final int INT_BUF_GRANULARITY         = 10;
       
    51     private static final int INT_BUF_INITIAL_SIZE        = 250;
       
    52     private static final int IMAGE_BUF_INITIAL_SIZE      = 3;
       
    53     private static final int IMAGE_BUF_GRANULARITY       = 2;
       
    54     private static final int STRING_BUFFER_INITIAL_SIZE = 10;
       
    55 
       
    56     // Prefixes for different categories of op codes, stored in MSB
       
    57     final static int DRAW_PREFIX = 0;
       
    58     final static int FILL_PREFIX = 1;
       
    59     final static int SET_PREFIX = 2;
       
    60     final static int MISC_PREFIX = 3;
       
    61 
       
    62     // Unique operation codes for all the gc operations that can be buffered.
       
    63     static final int OP_DRAWARC            = ((DRAW_PREFIX << 24) | 1);
       
    64     static final int OP_DRAWFOCUS          = ((DRAW_PREFIX << 24) | 2);
       
    65     static final int OP_DRAWIMAGE1         = ((DRAW_PREFIX << 24) | 3);
       
    66     static final int OP_DRAWIMAGE2         = ((DRAW_PREFIX << 24) | 4);
       
    67     static final int OP_DRAWLINE           = ((DRAW_PREFIX << 24) | 5);
       
    68     static final int OP_DRAWELLIPSE        = ((DRAW_PREFIX << 24) | 6);
       
    69     static final int OP_DRAWPOINT          = ((DRAW_PREFIX << 24) | 7);
       
    70     static final int OP_DRAWPOLYGON        = ((DRAW_PREFIX << 24) | 8);
       
    71     static final int OP_DRAWPOLYLINE       = ((DRAW_PREFIX << 24) | 9);
       
    72     static final int OP_DRAWRECT           = ((DRAW_PREFIX << 24) | 10);
       
    73     static final int OP_DRAWRGB_INT        = ((DRAW_PREFIX << 24) | 11);
       
    74     static final int OP_DRAWRGB_BYTE       = ((DRAW_PREFIX << 24) | 12);
       
    75     static final int OP_DRAWRGB_SHORT      = ((DRAW_PREFIX << 24) | 13);
       
    76     static final int OP_DRAWROUNDRECT      = ((DRAW_PREFIX << 24) | 14);
       
    77     static final int OP_DRAWSTRING         = ((DRAW_PREFIX << 24) | 15);
       
    78     static final int OP_FILLARC            = ((FILL_PREFIX << 24) | 16);
       
    79     static final int OP_FILLGRADIENTRECT   = ((FILL_PREFIX << 24) | 17);
       
    80     static final int OP_FILLELLIPSE        = ((FILL_PREFIX << 24) | 18);
       
    81     static final int OP_FILLPOLYGON        = ((FILL_PREFIX << 24) | 19);
       
    82     static final int OP_FILLRECT           = ((FILL_PREFIX << 24) | 20);
       
    83     static final int OP_FILLROUNDRECT      = ((FILL_PREFIX << 24) | 21);
       
    84     static final int OP_SETBACKGROUNDALPHA = ((SET_PREFIX << 24) | 22);
       
    85     static final int OP_SETBACKGROUNDCOLOR = ((SET_PREFIX << 24) | 23);
       
    86     static final int OP_SETBLENDINGMODE    = ((SET_PREFIX << 24) | 24);
       
    87     static final int OP_SETCLIP            = ((SET_PREFIX << 24) | 25);
       
    88     static final int OP_CANCELCLIPPING     = ((SET_PREFIX << 24) | 26);
       
    89     static final int OP_SETFONT            = ((SET_PREFIX << 24) | 27);
       
    90     static final int OP_SETFOREGROUNDALPHA = ((SET_PREFIX << 24) | 28);
       
    91     static final int OP_SETFOREGROUNDCOLOR = ((SET_PREFIX << 24) | 29);
       
    92     static final int OP_SETSTROKESTYLE     = ((SET_PREFIX << 24) | 30);
       
    93     static final int OP_SETSTROKEWIDTH     = ((SET_PREFIX << 24) | 31);
       
    94     static final int OP_TRANSLATE          = ((MISC_PREFIX << 24) | 32);
       
    95     static final int OP_SCALE              = ((MISC_PREFIX << 24) | 33);
       
    96     static final int OP_RESETTRANSFORM     = ((MISC_PREFIX << 24) | 34);
       
    97     static final int OP_COPYAREA1          = ((MISC_PREFIX << 24) | 35);
       
    98     static final int OP_COPYAREA2          = ((MISC_PREFIX << 24) | 36);
       
    99 
       
   100     /**
       
   101      * Constructs empty command buffer with defined buffer sizes.
       
   102      */
       
   103     public JavaCommandBuffer() {
       
   104         intParams = new int[INT_BUF_INITIAL_SIZE];
       
   105         strParams = new StringBuffer(STRING_BUFFER_INITIAL_SIZE);
       
   106         images = new Vector(IMAGE_BUF_INITIAL_SIZE, IMAGE_BUF_GRANULARITY);
       
   107         rgbData = new Vector(IMAGE_BUF_INITIAL_SIZE, IMAGE_BUF_GRANULARITY);
       
   108     }
       
   109 
       
   110     /**
       
   111      * Resets the buffer, i.e. removes all recorded commands and related data. The integer array containing
       
   112      * the actual operation codes is not deleted, only the index pointer is rested, thus the memory consumption of that is not freed.
       
   113      * CommandBuffer can be reseted only if it is not bound by any GraphicsContext
       
   114      * @throws IllegalStateException if this CommandBuffer is bound while calling reset
       
   115      */
       
   116     public void reset() {
       
   117         if(bound) {
       
   118             throw new IllegalStateException("CommandBuffer is still bound by gc");
       
   119         }
       
   120         intCount = 0;
       
   121         strParams.setLength(0);
       
   122 
       
   123         Enumeration allImages = images.elements();
       
   124         while(allImages.hasMoreElements()) {
       
   125             Image image = (Image)allImages.nextElement();
       
   126             if(image != null) {
       
   127                 image.freeCommandBufferCopy();
       
   128             }
       
   129         }
       
   130         images.removeAllElements();
       
   131         rgbData.removeAllElements();
       
   132         containsData = false;
       
   133         containsPrimitiveData = false;
       
   134     }
       
   135 
       
   136     /**
       
   137      * Checks that does this buffer contain any commands
       
   138      * @return true if any command has been written to buffer otherwise false
       
   139      */
       
   140     public boolean containsData() {
       
   141         return containsData;
       
   142     }
       
   143     
       
   144     /**
       
   145      * Checks that does this buffer contain any draw commands, i.e. any setters etc. 
       
   146      * that does to cause any pixels to be rendered are ignored 
       
   147      * @return true if any draw command has been written to buffer otherwise false
       
   148      */
       
   149     public boolean containsDrawnPrimitives() {
       
   150         return containsPrimitiveData;
       
   151     }
       
   152     
       
   153     /**
       
   154      * Binds this buffer
       
   155      */
       
   156     void bind() {
       
   157         bound = true;
       
   158     }
       
   159 
       
   160     /**
       
   161      * Provides the binding status of this buffer
       
   162      * @return true if this buffer has been already bound otherwise false
       
   163      */
       
   164     boolean isBound() {
       
   165         return bound;
       
   166     }
       
   167 
       
   168     /**
       
   169      * Releases this buffer, i.e. it can be bound by some other GraphicsContext
       
   170      */
       
   171     void release() {
       
   172         bound = false;
       
   173     }
       
   174 
       
   175     /**
       
   176      * Writes an integer to given array.
       
   177      * @param item The item to be added to the array
       
   178      * @param array The array where to append given item
       
   179      * @param elementsUsed The size of slots used in given array
       
   180      * @param granularity The granularity used if the array needs to be enlarged
       
   181      * @return Array containing the added item
       
   182      */
       
   183     private int[] writeToArray(int item, int[] array, int elementsUsed, int granularity) {
       
   184         if( array.length < elementsUsed + 1) {
       
   185             int[] src = array;
       
   186             int[] dst = new int[array.length + granularity];
       
   187             System.arraycopy(src, 0, dst, 0, src.length);
       
   188             array = dst;
       
   189         }
       
   190         array[elementsUsed] = item;
       
   191         return array;
       
   192     }
       
   193 
       
   194     private void writeInt(int param) {
       
   195         intParams = writeToArray(param, intParams, intCount++, INT_BUF_GRANULARITY);
       
   196         containsData = true;
       
   197     }
       
   198 
       
   199     private void writeImage(Image image) {
       
   200         images.addElement(image);
       
   201     }
       
   202 
       
   203     private void writeStr(String string) {
       
   204         strParams.append(string);
       
   205     }
       
   206 
       
   207     private void writeRgb(int[] rgb) {
       
   208         rgbData.addElement(rgb);
       
   209     }
       
   210     private void writeRgb(byte[] rgb) {
       
   211         rgbData.addElement(rgb);
       
   212     }
       
   213 
       
   214     private void writeRgb(short[] rgb) {
       
   215         rgbData.addElement(rgb);
       
   216     }
       
   217 
       
   218     private void reportNotSupported() {
       
   219         throw new RuntimeException("Intenal: Operation not supported with JavaCommandBuffer");
       
   220     }
       
   221 
       
   222     private void printBufferInfo() {
       
   223         System.out.println("CommandBuffer Info: " +this);
       
   224         System.out.println("intParamCount: " + intCount);
       
   225         System.out.println("intBuffer Size: " + intParams.length);
       
   226         System.out.println("StringBuffer Size: " + strParams.length());
       
   227     }
       
   228 
       
   229     private void raisePrimitiveFlag() {
       
   230         containsPrimitiveData = true;
       
   231     }
       
   232     
       
   233     int[] intParams() {
       
   234         return intParams;
       
   235     }
       
   236 
       
   237     int intParamCount() {
       
   238         return intCount;
       
   239     }
       
   240 
       
   241     Vector rgbParams() {
       
   242         return rgbData;
       
   243     }
       
   244 
       
   245     Vector images() {
       
   246         return images;
       
   247     }
       
   248 
       
   249     String strParams() {
       
   250         return strParams.toString();
       
   251     }
       
   252 
       
   253     void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle) {
       
   254         writeInt(OP_DRAWARC);
       
   255         writeInt(x);
       
   256         writeInt(y);
       
   257         writeInt(width);
       
   258         writeInt(height);
       
   259         writeInt(startAngle);
       
   260         writeInt(arcAngle);
       
   261         raisePrimitiveFlag();
       
   262     }
       
   263 
       
   264     void drawFocus (int x, int y, int width, int height) {
       
   265         writeInt(OP_DRAWFOCUS);
       
   266         writeInt(x);
       
   267         writeInt(y);
       
   268         writeInt(width);
       
   269         writeInt(height);
       
   270         raisePrimitiveFlag();
       
   271     }
       
   272 
       
   273     // must be called from UI thread as images cannot be creates outside that
       
   274     void drawImage(Image image, int x, int y) {
       
   275         writeInt(OP_DRAWIMAGE1);
       
   276         writeInt(x);
       
   277         writeInt(y);
       
   278         // creating copy of image here uses implicit data sharing,
       
   279         // thus only a shallow copy is made
       
   280         writeImage(image.getCommandBufferCopy());
       
   281         raisePrimitiveFlag();
       
   282     }
       
   283 
       
   284     // must be called from UI thread as images cannot be creates outside that
       
   285     void drawImage(Image image, int tx, int ty, int tw, int th,int sx, int sy, int sw, int sh, int manipulation) {
       
   286         writeInt(OP_DRAWIMAGE2);
       
   287         writeInt(tx);
       
   288         writeInt(ty);
       
   289         writeInt(tw);
       
   290         writeInt(th);
       
   291         writeInt(sx);
       
   292         writeInt(sy);
       
   293         writeInt(sw);
       
   294         writeInt(sh);
       
   295         writeInt(manipulation);
       
   296         // creating copy of image here uses implicit data sharing,
       
   297         // thus only a shallow copy is made
       
   298         writeImage(image.getCommandBufferCopy());
       
   299         raisePrimitiveFlag();
       
   300     }
       
   301 
       
   302     void drawLine (int x1, int y1, int x2, int y2) {
       
   303         writeInt(OP_DRAWLINE);
       
   304         writeInt(x1);
       
   305         writeInt(y1);
       
   306         writeInt(x2);
       
   307         writeInt(y2);
       
   308         raisePrimitiveFlag();
       
   309     }
       
   310 
       
   311     void drawEllipse (int x, int y, int width, int height) {
       
   312         writeInt(OP_DRAWELLIPSE);
       
   313         writeInt(x);
       
   314         writeInt(y);
       
   315         writeInt(width);
       
   316         writeInt(height);
       
   317         raisePrimitiveFlag();
       
   318     }
       
   319 
       
   320     void drawPoint (int x, int y) {
       
   321         writeInt(OP_DRAWPOINT);
       
   322         writeInt(x);
       
   323         writeInt(y);
       
   324         raisePrimitiveFlag();
       
   325     }
       
   326 
       
   327     void drawPolygon(int[] pointArray) {
       
   328         writeInt(OP_DRAWPOLYGON);
       
   329         writeInt(pointArray.length);
       
   330         for(int i = 0; i < pointArray.length; ++i) {
       
   331             writeInt(pointArray[i]);
       
   332         }
       
   333         raisePrimitiveFlag();
       
   334     }
       
   335 
       
   336     void drawPolyline(int[] pointArray) {
       
   337         writeInt(OP_DRAWPOLYLINE);
       
   338         writeInt(pointArray.length);
       
   339         for(int i = 0; i < pointArray.length; ++i) {
       
   340             writeInt(pointArray[i]);
       
   341         }
       
   342         raisePrimitiveFlag();
       
   343     }
       
   344 
       
   345     void drawRect (int x, int y, int width, int height) {
       
   346         writeInt(OP_DRAWRECT);
       
   347         writeInt(x);
       
   348         writeInt(y);
       
   349         writeInt(width);
       
   350         writeInt(height);
       
   351         raisePrimitiveFlag();
       
   352     }
       
   353 
       
   354     void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha, int manipulation) {
       
   355         writeInt(OP_DRAWRGB_INT);
       
   356         writeInt(offset);
       
   357         writeInt(scanlength);
       
   358         writeInt(x);
       
   359         writeInt(y);
       
   360         writeInt(width);
       
   361         writeInt(height);
       
   362         writeInt(processAlpha? 1 : 0);
       
   363         writeInt(manipulation);
       
   364         writeRgb(rgbData);
       
   365         raisePrimitiveFlag();
       
   366     }
       
   367 
       
   368     void drawRGB(byte[] rgbData, byte[] transparencyMask,int offset, int scanlength, int x, int y, int width, int height, int manipulation, int format) {
       
   369         writeInt(OP_DRAWRGB_BYTE);
       
   370         writeInt(offset);
       
   371         writeInt(scanlength);
       
   372         writeInt(x);
       
   373         writeInt(y);
       
   374         writeInt(width);
       
   375         writeInt(height);
       
   376         writeInt(manipulation);
       
   377         writeInt(format);
       
   378         writeRgb(rgbData);
       
   379         writeRgb(transparencyMask);
       
   380         raisePrimitiveFlag();
       
   381     }
       
   382 
       
   383     void drawRGB(short[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha, int manipulation, int format) {
       
   384         writeInt(OP_DRAWRGB_SHORT);
       
   385         writeInt(offset);
       
   386         writeInt(scanlength);
       
   387         writeInt(x);
       
   388         writeInt(y);
       
   389         writeInt(width);
       
   390         writeInt(height);
       
   391         writeInt(processAlpha? 1 : 0);
       
   392         writeInt(manipulation);
       
   393         writeInt(format);
       
   394         writeRgb(rgbData);
       
   395         raisePrimitiveFlag();
       
   396     }
       
   397 
       
   398     void drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight) {
       
   399         writeInt(OP_DRAWROUNDRECT);
       
   400         writeInt(x);
       
   401         writeInt(y);
       
   402         writeInt(width);
       
   403         writeInt(height);
       
   404         writeInt(arcWidth);
       
   405         writeInt(arcHeight);
       
   406         raisePrimitiveFlag();
       
   407     }
       
   408 
       
   409     void drawString(String string, int x, int y, int width, int height, int alignments, int flags, boolean isTransparent) {
       
   410         writeInt(OP_DRAWSTRING);
       
   411         writeStr(string);
       
   412         writeInt(string.length());
       
   413         writeInt(x);
       
   414         writeInt(y);
       
   415         writeInt(width);
       
   416         writeInt(height);
       
   417         writeInt(alignments);
       
   418         writeInt(flags);
       
   419         writeInt(isTransparent? 1 : 0);
       
   420         raisePrimitiveFlag();
       
   421     }
       
   422 
       
   423     void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle) {
       
   424         writeInt(OP_FILLARC);
       
   425         writeInt(x);
       
   426         writeInt(y);
       
   427         writeInt(width);
       
   428         writeInt(height);
       
   429         writeInt(startAngle);
       
   430         writeInt(arcAngle);
       
   431         raisePrimitiveFlag();
       
   432     }
       
   433 
       
   434     void fillGradientRect(int x, int y, int width, int height, boolean vertical, boolean swapColors) {
       
   435         writeInt(OP_FILLGRADIENTRECT);
       
   436         writeInt(x);
       
   437         writeInt(y);
       
   438         writeInt(width);
       
   439         writeInt(height);
       
   440         writeInt(vertical ? 1 : 0);
       
   441         writeInt(swapColors ? 1 : 0);
       
   442         raisePrimitiveFlag();
       
   443     }
       
   444 
       
   445     void fillEllipse (int x, int y, int width, int height) {
       
   446         writeInt(OP_FILLELLIPSE);
       
   447         writeInt(x);
       
   448         writeInt(y);
       
   449         writeInt(width);
       
   450         writeInt(height);
       
   451         raisePrimitiveFlag();
       
   452     }
       
   453 
       
   454     void fillPolygon (int[] pointArray) {
       
   455         writeInt(OP_FILLPOLYGON);
       
   456         writeInt(pointArray.length);
       
   457         for(int i = 0; i < pointArray.length; ++i) {
       
   458             writeInt(pointArray[i]);
       
   459         }
       
   460         raisePrimitiveFlag();
       
   461     }
       
   462 
       
   463     void fillRect (int x, int y, int width, int height) {
       
   464         writeInt(OP_FILLRECT);
       
   465         writeInt(x);
       
   466         writeInt(y);
       
   467         writeInt(width);
       
   468         writeInt(height);
       
   469         raisePrimitiveFlag();
       
   470     }
       
   471 
       
   472     void fillRoundRectangle (int x, int y, int width, int height, int arcWidth, int arcHeight) {
       
   473         writeInt(OP_FILLROUNDRECT);
       
   474         writeInt(x);
       
   475         writeInt(y);
       
   476         writeInt(width);
       
   477         writeInt(height);
       
   478         writeInt(arcWidth);
       
   479         writeInt(arcHeight);
       
   480         raisePrimitiveFlag();
       
   481     }
       
   482 
       
   483     public void setBackgroundAlpha(int alpha) {
       
   484         writeInt(OP_SETBACKGROUNDALPHA);
       
   485         writeInt(alpha);
       
   486     }
       
   487 
       
   488     void setBackgroundColor(int argb, boolean updateAlpha) {
       
   489         writeInt(OP_SETBACKGROUNDCOLOR);
       
   490         writeInt(argb);
       
   491         writeInt(updateAlpha? 1 : 0);
       
   492     }
       
   493 
       
   494     void setBlendingMode(int mode) {
       
   495         writeInt(OP_SETBLENDINGMODE);
       
   496         writeInt(mode);
       
   497     }
       
   498 
       
   499     void setClip(int x, int y, int width, int height, boolean intersects) {
       
   500         writeInt(OP_SETCLIP);
       
   501         writeInt(x);
       
   502         writeInt(y);
       
   503         writeInt(width);
       
   504         writeInt(height);
       
   505         writeInt(intersects? 1 : 0 );
       
   506     }
       
   507 
       
   508     void cancelClipping () {
       
   509         writeInt(OP_CANCELCLIPPING);
       
   510     }
       
   511 
       
   512     void setFont(int fontHandle) {
       
   513         writeInt(OP_SETFONT);
       
   514         writeInt(fontHandle);
       
   515     }
       
   516 
       
   517     void setForegroundAlpha(int alpha) {
       
   518         writeInt(OP_SETFOREGROUNDALPHA);
       
   519         writeInt(alpha);
       
   520     }
       
   521 
       
   522     void setForegroundColor(int argb, boolean updateAlpha) {
       
   523         writeInt(OP_SETFOREGROUNDCOLOR);
       
   524         writeInt(argb);
       
   525         writeInt(updateAlpha? 1 : 0);
       
   526     }
       
   527 
       
   528     void setStrokeStyle(int style) {
       
   529         writeInt(OP_SETSTROKESTYLE);
       
   530         writeInt(style);
       
   531     }
       
   532 
       
   533     void setStrokeWidth(int width) {
       
   534         writeInt(OP_SETSTROKEWIDTH);
       
   535         writeInt(width);
       
   536     }
       
   537 
       
   538     void translate(int x, int y) {
       
   539         writeInt(OP_TRANSLATE);
       
   540         writeInt(x);
       
   541         writeInt(y);
       
   542     }
       
   543 
       
   544     void scale(int x, int y) {
       
   545         writeInt(OP_SCALE);
       
   546         writeInt(x);
       
   547         writeInt(y);
       
   548     }
       
   549 
       
   550     void resetTransform() {
       
   551         writeInt(OP_RESETTRANSFORM);
       
   552     }
       
   553 
       
   554     void copyArea(Image image, int x, int y) {
       
   555         writeInt(OP_COPYAREA1);
       
   556         writeInt(x);
       
   557         writeInt(y);
       
   558         // TODO does this need flushing on the image
       
   559         images.addElement(new Image(image));
       
   560         raisePrimitiveFlag();
       
   561     }
       
   562 
       
   563     void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) {
       
   564         writeInt(OP_COPYAREA2);
       
   565         writeInt(srcX);
       
   566         writeInt(srcY);
       
   567         writeInt(width);
       
   568         writeInt(height);
       
   569         writeInt(destX);
       
   570         writeInt(destY);
       
   571         writeInt(paint? 1 : 0);
       
   572         raisePrimitiveFlag();
       
   573     }
       
   574 
       
   575     // Unsupported operations
       
   576     int getAdvancedCharacterWidth(char ch, boolean isAdvanced) {
       
   577         reportNotSupported();
       
   578         return 0;
       
   579     }
       
   580 
       
   581     void getFontMetricsData(int[] data, int fontHandle) {
       
   582         reportNotSupported();
       
   583     }
       
   584 
       
   585     int getBackgroundAlpha() {
       
   586         reportNotSupported();
       
   587         return 0;
       
   588     }
       
   589 
       
   590     int getBackgroundColor() {
       
   591         reportNotSupported();
       
   592         return 0;
       
   593     }
       
   594 
       
   595     int getBlendingMode() {
       
   596         reportNotSupported();
       
   597         return 0;
       
   598     }
       
   599 
       
   600     void getClip(int[] clip) {
       
   601         reportNotSupported();
       
   602     }
       
   603 
       
   604     int getForegroundAlpha() {
       
   605         reportNotSupported();
       
   606         return 0;
       
   607     }
       
   608 
       
   609     int getForegroundColor() {
       
   610         reportNotSupported();
       
   611         return 0;
       
   612     }
       
   613 
       
   614     void getTextBoundingBox(int[] boundingBox, String string, int alignments, int flags, int rectX, int rectY, int rectWidth, int rectHeight) {
       
   615         reportNotSupported();
       
   616     }
       
   617 
       
   618     int getStrokeWidth() {
       
   619         reportNotSupported();
       
   620         return 0;
       
   621     }
       
   622 
       
   623     int getStrokeStyle() {
       
   624         reportNotSupported();
       
   625         return 0;
       
   626     }
       
   627 
       
   628     int getTranslateX() {
       
   629         reportNotSupported();
       
   630         return 0;
       
   631     }
       
   632 
       
   633     int getTranslateY() {
       
   634         reportNotSupported();
       
   635         return 0;
       
   636     }
       
   637 
       
   638     boolean hasClipping() {
       
   639         reportNotSupported();
       
   640         return false;
       
   641     }
       
   642 
       
   643     void saveSettings() {
       
   644         reportNotSupported();
       
   645     }
       
   646 
       
   647     void restoreSettings() {
       
   648         reportNotSupported();
       
   649     }
       
   650 
       
   651 
       
   652 
       
   653 }