diff options
Diffstat (limited to 'canvas/source/java/CanvasUtils.java')
-rw-r--r-- | canvas/source/java/CanvasUtils.java | 670 |
1 files changed, 670 insertions, 0 deletions
diff --git a/canvas/source/java/CanvasUtils.java b/canvas/source/java/CanvasUtils.java new file mode 100644 index 000000000000..0df1f69768ca --- /dev/null +++ b/canvas/source/java/CanvasUtils.java @@ -0,0 +1,670 @@ +/************************************************************************* + * + * $RCSfile: CanvasUtils.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 CanvasUtils +{ + // + // Canvas utilities + // ================ + // + public static java.awt.geom.AffineTransform makeTransform( AffineMatrix2D ooTransform ) + { + return new AffineTransform( ooTransform.m00, + ooTransform.m10, + ooTransform.m01, + ooTransform.m11, + ooTransform.m02, + ooTransform.m12 ); + } + + public static AffineMatrix2D makeAffineMatrix2D( java.awt.geom.AffineTransform transform ) + { + double[] matrix = new double[6]; + transform.getMatrix( matrix ); + + return new AffineMatrix2D( matrix[0], matrix[2], matrix[4], + matrix[1], matrix[3], matrix[5] ); + } + + public static void initGraphics( Graphics2D graphics ) + { + if( graphics != null ) + { + java.awt.RenderingHints hints = new java.awt.RenderingHints(null); + boolean hq = true; + + if( hq ) + { + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_FRACTIONALMETRICS, + java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON ) ); +// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, +// java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, + java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED) ); +// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION, +// java.awt.RenderingHints.VALUE_INTERPOLATION_BICUBIC) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION, + java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR) ); +// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING, +// java.awt.RenderingHints.VALUE_RENDER_QUALITY) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING, + java.awt.RenderingHints.VALUE_RENDER_SPEED) ); +// hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL, +// java.awt.RenderingHints.VALUE_STROKE_NORMALIZE) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL, + java.awt.RenderingHints.VALUE_STROKE_DEFAULT) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ANTIALIASING, + java.awt.RenderingHints.VALUE_ANTIALIAS_ON) ); + } + else + { + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION, + java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION, + java.awt.RenderingHints.VALUE_INTERPOLATION_BILINEAR) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING, + java.awt.RenderingHints.VALUE_RENDER_SPEED) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL, + java.awt.RenderingHints.VALUE_STROKE_DEFAULT) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ANTIALIASING, + java.awt.RenderingHints.VALUE_ANTIALIAS_OFF) ); + } + + // the least common denominator standard + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_FRACTIONALMETRICS, + java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON) ); + hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_TEXT_ANTIALIASING, + java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON) ); + + graphics.setRenderingHints( hints ); + } + } + + //---------------------------------------------------------------------------------- + + public static java.awt.geom.GeneralPath makeGenPathFromBezierPoints( RealBezierSegment2D [][] points ) + { + java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath(); + + // extract every polygon into GeneralPath object + for( int i=0; i<points.length; ++i ) + { + if( points[i].length > 0 ) + path.moveTo((float) points[i][0].Px, (float) points[i][0].Py); + + for( int j=1; j<points[i].length; ++j ) + { + CanvasUtils.printLog( "makeGenPathFromBezierPoints: point added." ); + path.curveTo((float)(points[i][j-1].C1x), (float)(points[i][j-1].C1y), + (float)(points[i][j-1].C2x), (float)(points[i][j-1].C2y), + (float) points[i][j].Px, (float) points[i][j].Py ); + } + + // TODO: closePath? + } + + return path; + } + + public static java.awt.geom.GeneralPath makeGenPathFromBezierPoly( drafts.com.sun.star.rendering.XBezierPolyPolygon2D poly ) + { + try + { + drafts.com.sun.star.geometry.RealBezierSegment2D [][] points = poly.getPoints(0,-1,0,-1); + + return makeGenPathFromBezierPoints( points ); + } + catch( com.sun.star.lang.IndexOutOfBoundsException e ) + { + } + + return new java.awt.geom.GeneralPath(); + } + + public static java.awt.geom.GeneralPath makeGenPathFromLinePoints( RealPoint2D [][] points ) + { + java.awt.geom.GeneralPath path = new java.awt.geom.GeneralPath(); + + // extract every polygon into GeneralPath object + for( int i=0; i<points.length; ++i ) + { + if( points[i].length > 0 ) + path.moveTo((float) points[i][0].X, (float) points[i][0].Y); + + for( int j=1; j<points[i].length; ++j ) + { + CanvasUtils.printLog( "makeGenPathFromLinePoints: point (" + + points[i][j].X + "," + points[i][j].Y + ") added." ); + path.lineTo((float) points[i][j].X, (float) points[i][j].Y ); + } + + // TODO: closePath? + } + + return path; + } + + public static java.awt.geom.GeneralPath makeGenPathFromLinePoly( drafts.com.sun.star.rendering.XLinePolyPolygon2D poly ) + { + try + { + drafts.com.sun.star.geometry.RealPoint2D [][] points = poly.getPoints(0,-1,0,-1); + + return makeGenPathFromLinePoints( points ); + } + catch( com.sun.star.lang.IndexOutOfBoundsException e ) + { + } + + return new java.awt.geom.GeneralPath(); + } + + public static java.awt.geom.GeneralPath makeGeneralPath( drafts.com.sun.star.rendering.XPolyPolygon2D poly ) + { + if( poly instanceof BezierPolyPolygon ) + { + CanvasUtils.printLog( "makeGeneralPath: bezier impl used." ); + return ((BezierPolyPolygon)poly).getJavaPath(); + } + + if( poly instanceof LinePolyPolygon ) + { + CanvasUtils.printLog( "makeGeneralPath: line impl used." ); + return ((LinePolyPolygon)poly).getJavaPath(); + } + + XBezierPolyPolygon2D bezierPoly = (XBezierPolyPolygon2D) UnoRuntime.queryInterface(XBezierPolyPolygon2D.class, poly); + + if( bezierPoly != null ) + { + // extract polygon data. Prefer bezier interface, because + // that's the more high-level data. + return makeGenPathFromBezierPoly( bezierPoly ); + } + + XLinePolyPolygon2D linePoly = (XLinePolyPolygon2D) UnoRuntime.queryInterface(XLinePolyPolygon2D.class, poly); + + if( linePoly != null ) + { + // extract polygon data. Fallback to line polygon, if no + // curves are available. + return makeGenPathFromLinePoly( linePoly ); + } + + // Only opaque general interface. No chance to get to the + // data. Empty path, then + CanvasUtils.printLog( "makeGeneralPath: Cannot access polygon data, given interface has class" + poly.getClass().getName() ); + return new GeneralPath(); + } + + public static java.awt.image.BufferedImage getBufferedImage( drafts.com.sun.star.rendering.XBitmap bitmap ) + { + if( bitmap instanceof CanvasBitmap ) + { + CanvasUtils.printLog( "getBufferedImage: CanvasBitmap impl used." ); + return ((CanvasBitmap)bitmap).getBufferedImage(); + } + + XIntegerBitmap integerBitmap = (XIntegerBitmap) UnoRuntime.queryInterface(XIntegerBitmap.class, bitmap); + + if( integerBitmap != null ) + { + // extract bitmap data. TODO. + return null; + } + + // check other types. TODO. + return null; + } + + public static byte [] int2byte( int [] input ) + { + byte [] output = new byte[4*input.length]; + + int i, j; + for( i=0, j=0; i<input.length; ++i ) + { + output[j] = (byte)(input[i] & 255); + output[j+1] = (byte)((input[i]/256) & 255); + output[j+2] = (byte)((input[i]/256/256) & 255); + output[j+3] = (byte)((input[i]/256/256/256) & 255); + j += 4; + } + + return output; + } + + public static int [] byte2int( byte [] input ) + { + int [] output = new int[(input.length+3)/4]; + + int i, j; + for( i=0,j=0; j<output.length; ++j ) + { + output[j] = input[i] + (input[i+1] + (input[i+2] + input[i+3]*256)*256)*256; + i += 4; + } + + return output; + } + + public static int javaRuleFromCompositeOp( byte compositeOp ) + { + // TODO: Finish mapping of Canvas and Java compositing magics + int rule = java.awt.AlphaComposite.SRC_OVER; + switch( compositeOp ) + { + case drafts.com.sun.star.rendering.CompositeOperation.CLEAR: + CanvasUtils.printLog( "javaRuleFromCompositeOp: clear selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.SOURCE: + CanvasUtils.printLog( "javaRuleFromCompositeOp: src selected" ); + rule = java.awt.AlphaComposite.SRC; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.DESTINATION: + CanvasUtils.printLog( "javaRuleFromCompositeOp: dst selected" ); + rule = java.awt.AlphaComposite.DST; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.OVER: + CanvasUtils.printLog( "javaRuleFromCompositeOp: over selected" ); + rule = java.awt.AlphaComposite.SRC_OVER; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.UNDER: + CanvasUtils.printLog( "javaRuleFromCompositeOp: under selected" ); + rule = java.awt.AlphaComposite.DST_OVER; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.INSIDE: + CanvasUtils.printLog( "javaRuleFromCompositeOp: inside selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.INSIDE_REVERSE: + CanvasUtils.printLog( "javaRuleFromCompositeOp: inReverse selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.OUTSIDE: + CanvasUtils.printLog( "javaRuleFromCompositeOp: outside selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.OUTSIDE_REVERSE: + CanvasUtils.printLog( "javaRuleFromCompositeOp: outReverse selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.XOR: + CanvasUtils.printLog( "javaRuleFromCompositeOp: xor selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.ADD: + CanvasUtils.printLog( "javaRuleFromCompositeOp: add selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + case drafts.com.sun.star.rendering.CompositeOperation.SATURATE: + CanvasUtils.printLog( "javaRuleFromCompositeOp: saturate selected" ); + rule = java.awt.AlphaComposite.CLEAR; + break; + + default: + CanvasUtils.printLog( "javaRuleFromCompositeOp: Unexpected compositing rule" ); + break; + } + + return rule; + } + + public static java.awt.AlphaComposite makeAlphaComposite( byte compositeOp ) + { + return java.awt.AlphaComposite.getInstance( javaRuleFromCompositeOp( compositeOp ) ); + } + + public static java.awt.AlphaComposite makeAlphaCompositeAlpha( byte compositeOp, double alpha ) + { + return java.awt.AlphaComposite.getInstance( javaRuleFromCompositeOp( compositeOp ), (float)alpha ); + } + + // when given to setupGraphicsState, makes that method to also + // setup the Paint with the color specified in the render state. + public static final byte alsoSetupPaint=0; + + // when given to setupGraphicsState, makes that method to _not_ + // setup the Paint with the color specified in the render state. + public static final byte dontSetupPaint=1; + + public static java.awt.geom.AffineTransform ViewConcatRenderTransform( ViewState viewState, + RenderState renderState ) + { + // calculate overall affine transform + AffineTransform transform = makeTransform( viewState.AffineTransform ); + transform.concatenate( makeTransform( renderState.AffineTransform ) ); + + printTransform( transform, "ViewConcatRenderTransform" ); + + return transform; + } + + public static void setupGraphicsState( java.awt.Graphics2D graphics, + ViewState viewState, + RenderState renderState, + byte paintTouchMode ) + { + // calculate overall affine transform + graphics.setTransform( ViewConcatRenderTransform(viewState, renderState ) ); + + // setup overall clip polyPolygon + if( viewState.Clip != null ) + { + Area clipArea = new Area( makeGeneralPath( viewState.Clip ) ); + + if( renderState.Clip != null ) + clipArea.intersect( new Area( makeGeneralPath( renderState.Clip ) ) ); + + graphics.setClip( clipArea ); + } + else if( renderState.Clip != null ) + { + Area clipArea = new Area( makeGeneralPath( renderState.Clip ) ); + graphics.setClip( clipArea ); + } + else + { + // TODO: HACK! Use true visible area here! + graphics.setClip( new java.awt.Rectangle(-1000000,-1000000,2000000,2000000) ); + } + + // setup current output color + // TODO: Complete color handling here + if( paintTouchMode == alsoSetupPaint ) + { + switch( renderState.DeviceColor.length ) + { + case 3: + CanvasUtils.printLog( "setupGraphicsState: Color(" + + renderState.DeviceColor[0] + "," + + renderState.DeviceColor[1] + "," + + renderState.DeviceColor[2] + ") set." ); + graphics.setColor( new Color( (float)renderState.DeviceColor[0], + (float)renderState.DeviceColor[1], + (float)renderState.DeviceColor[2] ) ); + break; + + case 4: + CanvasUtils.printLog( "setupGraphicsState: Color(" + + renderState.DeviceColor[0] + "," + + renderState.DeviceColor[1] + "," + + renderState.DeviceColor[2] + "," + + renderState.DeviceColor[3] + ") set." ); + graphics.setColor( new Color( (float)renderState.DeviceColor[0], + (float)renderState.DeviceColor[1], + (float)renderState.DeviceColor[2], + (float)renderState.DeviceColor[3] ) ); + break; + + default: + CanvasUtils.printLog( "setupGraphicsState: unexpected number of " + + renderState.DeviceColor.length + " color components!" ); + break; + } + } + + // setup current composite mode + graphics.setComposite( makeAlphaComposite( renderState.CompositeOperation ) ); + } + + public static void applyStrokeAttributes( java.awt.Graphics2D graphics, + StrokeAttributes attributes ) + { + int cap = java.awt.BasicStroke.CAP_BUTT; + + if( attributes.StartCapType != attributes.EndCapType ) + CanvasUtils.printLog( "applyStrokeAttributes: different start and end caps are not yet supported!" ); + + if( attributes.LineArray.length != 0 ) + CanvasUtils.printLog( "applyStrokeAttributes: multi-strokes are not yet supported!" ); + + if( attributes.StartCapType == PathCapType.BUTT ) + cap = java.awt.BasicStroke.CAP_BUTT; + else if( attributes.StartCapType == PathCapType.ROUND ) + cap = java.awt.BasicStroke.CAP_ROUND; + else if( attributes.StartCapType == PathCapType.SQUARE ) + cap = java.awt.BasicStroke.CAP_SQUARE; + + int join = java.awt.BasicStroke.JOIN_MITER; + + if( attributes.JoinType == PathJoinType.MITER ) + cap = java.awt.BasicStroke.JOIN_MITER; + else if( attributes.JoinType == PathJoinType.ROUND ) + cap = java.awt.BasicStroke.JOIN_ROUND; + else if( attributes.JoinType == PathJoinType.BEVEL ) + cap = java.awt.BasicStroke.JOIN_BEVEL; + else + CanvasUtils.printLog( "applyStrokeAttributes: current join type not yet supported!" ); + + float [] dashArray = null; + + if( attributes.DashArray.length != 0 ) + { + dashArray = new float [attributes.DashArray.length]; + + for( int i=0; i<attributes.DashArray.length; ++i ) + dashArray[i] = (float)attributes.DashArray[i]; + } + + graphics.setStroke( new java.awt.BasicStroke( (float)attributes.StrokeWidth, + cap, + join, + (float)attributes.MiterLimit, + dashArray, + 0) ); + } + + public static void setupGraphicsFont( java.awt.Graphics2D graphics, + ViewState viewState, + RenderState renderState, + drafts.com.sun.star.rendering.XCanvasFont xFont ) + { + if( xFont instanceof CanvasFont ) + { + CanvasUtils.printLog( "setupGraphicsFont: font impl used." ); + graphics.setFont( ((CanvasFont)xFont).getFont() ); + } + else + { + CanvasUtils.printLog( "setupGraphicsFont: creating Java font anew." ); + CanvasFont canvasFont; + canvasFont = new CanvasFont( xFont.getFontRequest(), null ); + graphics.setFont( canvasFont.getFont() ); + } + } + + static java.awt.geom.Rectangle2D.Double calcTransformedRectBounds( java.awt.geom.Rectangle2D.Double aRect, + AffineTransform aTransform ) + { + // transform rect by given transformation + java.awt.geom.Point2D.Double aPointTopLeft = new java.awt.geom.Point2D.Double(aRect.x, aRect.y); + aTransform.transform(aPointTopLeft, aPointTopLeft); + + java.awt.geom.Point2D.Double aPointTopRight = new java.awt.geom.Point2D.Double(aRect.x + aRect.width, + aRect.y); + aTransform.transform(aPointTopRight, aPointTopRight); + + java.awt.geom.Point2D.Double aPointBottomLeft = new java.awt.geom.Point2D.Double(aRect.x, + aRect.y + aRect.height); + aTransform.transform(aPointBottomLeft, aPointBottomLeft); + + java.awt.geom.Point2D.Double aPointBottomRight = new java.awt.geom.Point2D.Double(aRect.x + aRect.width, + aRect.y + aRect.height); + aTransform.transform(aPointBottomRight, aPointBottomRight); + + // calc bounding rect of those four points + java.awt.geom.Point2D.Double aResTopLeft = new java.awt.geom.Point2D.Double( Math.min(aPointTopLeft.x, + Math.min(aPointTopRight.x, + Math.min(aPointBottomLeft.x,aPointBottomRight.x))), + Math.min(aPointTopLeft.y, + Math.min(aPointTopRight.y, + Math.min(aPointBottomLeft.y,aPointBottomRight.y))) ); + + java.awt.geom.Point2D.Double aResBottomRight = new java.awt.geom.Point2D.Double( Math.max(aPointTopLeft.x, + Math.max(aPointTopRight.x, + Math.max(aPointBottomLeft.x,aPointBottomRight.x))), + Math.max(aPointTopLeft.y, + Math.max(aPointTopRight.y, + Math.max(aPointBottomLeft.y,aPointBottomRight.y))) ); + return new java.awt.geom.Rectangle2D.Double( aResTopLeft.x, aResTopLeft.y, + aResBottomRight.x - aResTopLeft.x, + aResBottomRight.y - aResTopLeft.y ); + } + + // Create a corrected view transformation out of the give one, + // which ensures that the rectangle given by (0,0) and + // attributes.untransformedSize is mapped with its left,top corner + // to (0,0) again. This is required to properly render sprite + // animations to buffer bitmaps. + public static ViewState createAnimationViewState( ViewState inputViewState, + AnimationAttributes attributes ) + { + // TODO: Properly respect clip here. Might have to be transformed, too. + + AffineTransform aViewTransform = makeTransform( inputViewState.AffineTransform ); + + // transform Rect(0,0,attributes.untransformedSize) by + // viewTransform + java.awt.geom.Rectangle2D.Double aTransformedRect = + calcTransformedRectBounds( new java.awt.geom.Rectangle2D.Double(0.0, 0.0, + attributes.UntransformedSize.Width, + attributes.UntransformedSize.Height), + aViewTransform ); + + printTransform( aViewTransform, "createAnimationViewState" ); + + CanvasUtils.printLog( "createAnimationViewState: transformed origin is: (" + aTransformedRect.x + ", " + aTransformedRect.y + ")" ); + + // now move resulting left,top point of bounds to (0,0) + AffineTransform animationViewTransform = new AffineTransform(); + animationViewTransform.translate( -aTransformedRect.x, -aTransformedRect.y ); + animationViewTransform.concatenate( aViewTransform ); + + printTransform( animationViewTransform, "createAnimationViewState" ); + + return new ViewState( makeAffineMatrix2D( animationViewTransform ), inputViewState.Clip ); + } + + public static void postRenderImageTreatment( Image buffer ) + { + // TODO: This is specific to Sun's JREs 1.4 and upwards. Make this more portable + buffer.flush(); // as long as we force images to VRAM, + // we need to flush them afterwards, to + // avoid eating up all VRAM. + } + + public static void printTransform( AffineTransform transform, + String stringPrefix ) + { + CanvasUtils.printLog( stringPrefix + ": Transform is" ); + double [] matrix = new double[6]; + transform.getMatrix(matrix); + int i; + for( i=0; i<6; ++i ) + System.err.print( matrix[i] + ", " ); + CanvasUtils.printLog( "" ); + } + + public static void preCondition( boolean bCondition, + String methodName ) + { + if( !bCondition ) + printLog("Precondition violated: " + methodName); + } + + public static void printLog( String s ) + { + System.err.println( s ); + } +} |