diff -r e8e63152f320 -r 2a9601315dfc javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/org/eclipse/swt/internal/qt/graphics/JavaCommandBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/org/eclipse/swt/internal/qt/graphics/JavaCommandBuffer.java Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,613 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + *******************************************************************************/ +package org.eclipse.swt.internal.qt.graphics; + +import java.util.Vector; +import java.util.Enumeration; + +/** + * 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. + */ +public final class JavaCommandBuffer { + + // All collected drawing operations and their parameters + private int[] intParams; + private int intCount; + private StringBuffer strParams; + + // Holder for images + private Vector images; + + // holder for rgbData + private Vector rgbData; + + // This flag is indicates if this buffer is bound by some GraphicsContext + private boolean bound; + + // This flag indicates if this buffer is empty or not + private boolean containsData; + + // 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; + + // 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; + + // 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.isDisposed()) { + image.dispose(); + } + } + images.removeAllElements(); + rgbData.removeAllElements(); + containsData = false; + } + + /** + * Binds this buffer + */ + void bind() { + bound = true; + } + + /** + * Checks that does this buffer contain any commands + * @return + */ + boolean containsData() { + return containsData; + } + + /** + * 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; + } + + /** + * Writes an integer to given array. + * @param item The item to be added to the array + * @param array The array where to append given item + * @param elementsUsed The size of slots used in given array + * @param granularity The granularity used if the array needs to be enlarged + * @return Array containing the added item + */ + private int[] writeToArray(int item, int[] array, int elementsUsed, int granularity) { + if( array.length < elementsUsed + 1) { + int[] src = array; + int[] dst = new int[array.length + granularity]; + System.arraycopy(src, 0, dst, 0, src.length); + array = dst; + } + array[elementsUsed] = item; + return array; + } + + private void writeInt(int param) { + intParams = writeToArray(param, intParams, intCount++, INT_BUF_GRANULARITY); + containsData = true; + } + + private void writeImage(Image image) { + images.addElement(image); + } + + private void writeStr(String string) { + strParams.append(string); + } + + private void writeRgb(int[] rgb) { + rgbData.addElement(rgb); + } + private void writeRgb(byte[] rgb) { + rgbData.addElement(rgb); + } + + private void writeRgb(short[] rgb) { + rgbData.addElement(rgb); + } + + 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()); + } + + int[] intParams() { + return intParams; + } + + int intParamCount() { + return intCount; + } + + Vector rgbParams() { + return rgbData; + } + + Vector images() { + return images; + } + + String strParams() { + return strParams.toString(); + } + + void drawArc (int x, int y, int width, int height, int startAngle, int arcAngle) { + writeInt(OP_DRAWARC); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(startAngle); + writeInt(arcAngle); + } + + void drawFocus (int x, int y, int width, int height) { + writeInt(OP_DRAWFOCUS); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + } + + // must be called from UI thread as images cannot be creates outside that + void drawImage(Image image, int x, int y) { + writeInt(OP_DRAWIMAGE1); + writeInt(x); + writeInt(y); + // creating copy of image here uses implicit data sharing, + // thus only a shallow copy is made + writeImage(new Image(image)); + } + + // must be called from UI thread as images cannot be creates outside that + void drawImage(Image image, int tx, int ty, int tw, int th,int sx, int sy, int sw, int sh, int manipulation) { + writeInt(OP_DRAWIMAGE2); + writeInt(tx); + writeInt(ty); + writeInt(tw); + writeInt(th); + writeInt(sx); + writeInt(sy); + writeInt(sw); + writeInt(sh); + writeInt(manipulation); + // creating copy of image here uses implicit data sharing, + // thus only a shallow copy is made + writeImage(new Image(image)); + } + + void drawLine (int x1, int y1, int x2, int y2) { + writeInt(OP_DRAWLINE); + writeInt(x1); + writeInt(y1); + writeInt(x2); + writeInt(y2); + } + + void drawEllipse (int x, int y, int width, int height) { + writeInt(OP_DRAWELLIPSE); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + } + + void drawPoint (int x, int y) { + writeInt(OP_DRAWPOINT); + writeInt(x); + writeInt(y); + } + + void drawPolygon(int[] pointArray) { + writeInt(OP_DRAWPOLYGON); + writeInt(pointArray.length); + for(int i = 0; i < pointArray.length; ++i) { + writeInt(pointArray[i]); + } + } + + void drawPolyline(int[] pointArray) { + writeInt(OP_DRAWPOLYLINE); + writeInt(pointArray.length); + for(int i = 0; i < pointArray.length; ++i) { + writeInt(pointArray[i]); + } + } + + void drawRect (int x, int y, int width, int height) { + writeInt(OP_DRAWRECT); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + } + + void drawRGB(int[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha, int manipulation) { + writeInt(OP_DRAWRGB_INT); + writeInt(offset); + writeInt(scanlength); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(processAlpha? 1 : 0); + writeInt(manipulation); + writeRgb(rgbData); + } + + void drawRGB(byte[] rgbData, byte[] transparencyMask,int offset, int scanlength, int x, int y, int width, int height, int manipulation, int format) { + writeInt(OP_DRAWRGB_BYTE); + writeInt(offset); + writeInt(scanlength); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(manipulation); + writeInt(format); + writeRgb(rgbData); + writeRgb(transparencyMask); + } + + void drawRGB(short[] rgbData, int offset, int scanlength, int x, int y, int width, int height, boolean processAlpha, int manipulation, int format) { + writeInt(OP_DRAWRGB_SHORT); + writeInt(offset); + writeInt(scanlength); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(processAlpha? 1 : 0); + writeInt(manipulation); + writeInt(format); + writeRgb(rgbData); + } + + void drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight) { + writeInt(OP_DRAWROUNDRECT); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(arcWidth); + writeInt(arcHeight); + } + + void drawString(String string, int x, int y, int width, int height, int alignments, int flags, boolean isTransparent) { + writeInt(OP_DRAWSTRING); + writeStr(string); + writeInt(string.length()); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(alignments); + writeInt(flags); + writeInt(isTransparent? 1 : 0); + } + + void fillArc (int x, int y, int width, int height, int startAngle, int arcAngle) { + writeInt(OP_FILLARC); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(startAngle); + writeInt(arcAngle); + } + + void fillGradientRect(int x, int y, int width, int height, boolean vertical, boolean swapColors) { + writeInt(OP_FILLGRADIENTRECT); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(vertical ? 1 : 0); + writeInt(swapColors ? 1 : 0); + } + + void fillEllipse (int x, int y, int width, int height) { + writeInt(OP_FILLELLIPSE); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + } + + void fillPolygon (int[] pointArray) { + writeInt(OP_FILLPOLYGON); + writeInt(pointArray.length); + for(int i = 0; i < pointArray.length; ++i) { + writeInt(pointArray[i]); + } + } + + void fillRect (int x, int y, int width, int height) { + writeInt(OP_FILLRECT); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + } + + void fillRoundRectangle (int x, int y, int width, int height, int arcWidth, int arcHeight) { + writeInt(OP_FILLROUNDRECT); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(arcWidth); + writeInt(arcHeight); + } + + public void setBackgroundAlpha(int alpha) { + writeInt(OP_SETBACKGROUNDALPHA); + writeInt(alpha); + } + + void setBackgroundColor(int argb, boolean updateAlpha) { + writeInt(OP_SETBACKGROUNDCOLOR); + writeInt(argb); + writeInt(updateAlpha? 1 : 0); + } + + void setBlendingMode(int mode) { + writeInt(OP_SETBLENDINGMODE); + writeInt(mode); + } + + void setClip(int x, int y, int width, int height, boolean intersects) { + writeInt(OP_SETCLIP); + writeInt(x); + writeInt(y); + writeInt(width); + writeInt(height); + writeInt(intersects? 1 : 0 ); + } + + void cancelClipping () { + writeInt(OP_CANCELCLIPPING); + } + + void setFont(int fontHandle) { + writeInt(OP_SETFONT); + writeInt(fontHandle); + } + + void setForegroundAlpha(int alpha) { + writeInt(OP_SETFOREGROUNDALPHA); + writeInt(alpha); + } + + void setForegroundColor(int argb, boolean updateAlpha) { + writeInt(OP_SETFOREGROUNDCOLOR); + writeInt(argb); + writeInt(updateAlpha? 1 : 0); + } + + void setStrokeStyle(int style) { + writeInt(OP_SETSTROKESTYLE); + writeInt(style); + } + + void setStrokeWidth(int width) { + writeInt(OP_SETSTROKEWIDTH); + writeInt(width); + } + + void translate(int x, int y) { + writeInt(OP_TRANSLATE); + writeInt(x); + writeInt(y); + } + + void scale(int x, int y) { + writeInt(OP_SCALE); + writeInt(x); + writeInt(y); + } + + void resetTransform() { + writeInt(OP_RESETTRANSFORM); + } + + void copyArea(Image image, int x, int y) { + writeInt(OP_COPYAREA1); + writeInt(x); + writeInt(y); + // TODO does this need flushing on the image + images.addElement(new Image(image)); + } + + void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) { + writeInt(OP_COPYAREA2); + writeInt(srcX); + writeInt(srcY); + writeInt(width); + writeInt(height); + writeInt(destX); + writeInt(destY); + writeInt(paint? 1 : 0); + } + + // Unsupported operations + int getAdvancedCharacterWidth(char ch, boolean isAdvanced) { + reportNotSupported(); + return 0; + } + + void getFontMetricsData(int[] data, int fontHandle) { + reportNotSupported(); + } + + int getBackgroundAlpha() { + reportNotSupported(); + return 0; + } + + int getBackgroundColor() { + reportNotSupported(); + return 0; + } + + int getBlendingMode() { + reportNotSupported(); + return 0; + } + + void getClip(int[] clip) { + reportNotSupported(); + } + + int getForegroundAlpha() { + reportNotSupported(); + return 0; + } + + int getForegroundColor() { + reportNotSupported(); + return 0; + } + + void getTextBoundingBox(int[] boundingBox, String string, int alignments, int flags, int rectX, int rectY, int rectWidth, 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(); + } + + + +}