1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: CanvasUtils.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 import com
.sun
.star
.uno
.UnoRuntime
;
35 import com
.sun
.star
.rendering
.*;
36 import com
.sun
.star
.geometry
.*;
40 import java
.awt
.geom
.*;
42 public class CanvasUtils
48 public static java
.awt
.geom
.AffineTransform
makeTransform( AffineMatrix2D ooTransform
)
50 return new AffineTransform( ooTransform
.m00
,
58 public static AffineMatrix2D
makeAffineMatrix2D( java
.awt
.geom
.AffineTransform transform
)
60 double[] matrix
= new double[6];
61 transform
.getMatrix( matrix
);
63 return new AffineMatrix2D( matrix
[0], matrix
[2], matrix
[4],
64 matrix
[1], matrix
[3], matrix
[5] );
67 public static void initGraphics( Graphics2D graphics
)
69 if( graphics
!= null )
71 java
.awt
.RenderingHints hints
= new java
.awt
.RenderingHints(null);
76 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_FRACTIONALMETRICS
,
77 java
.awt
.RenderingHints
.VALUE_FRACTIONALMETRICS_ON
) );
78 // hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_ALPHA_INTERPOLATION,
79 // java.awt.RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY) );
80 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_ALPHA_INTERPOLATION
,
81 java
.awt
.RenderingHints
.VALUE_ALPHA_INTERPOLATION_SPEED
) );
82 // hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_INTERPOLATION,
83 // java.awt.RenderingHints.VALUE_INTERPOLATION_BICUBIC) );
84 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_INTERPOLATION
,
85 java
.awt
.RenderingHints
.VALUE_INTERPOLATION_BILINEAR
) );
86 // hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_RENDERING,
87 // java.awt.RenderingHints.VALUE_RENDER_QUALITY) );
88 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_RENDERING
,
89 java
.awt
.RenderingHints
.VALUE_RENDER_SPEED
) );
90 // hints.add( new java.awt.RenderingHints( java.awt.RenderingHints.KEY_STROKE_CONTROL,
91 // java.awt.RenderingHints.VALUE_STROKE_NORMALIZE) );
92 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_STROKE_CONTROL
,
93 java
.awt
.RenderingHints
.VALUE_STROKE_DEFAULT
) );
94 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_ANTIALIASING
,
95 java
.awt
.RenderingHints
.VALUE_ANTIALIAS_ON
) );
99 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_ALPHA_INTERPOLATION
,
100 java
.awt
.RenderingHints
.VALUE_ALPHA_INTERPOLATION_SPEED
) );
101 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_INTERPOLATION
,
102 java
.awt
.RenderingHints
.VALUE_INTERPOLATION_BILINEAR
) );
103 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_RENDERING
,
104 java
.awt
.RenderingHints
.VALUE_RENDER_SPEED
) );
105 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_STROKE_CONTROL
,
106 java
.awt
.RenderingHints
.VALUE_STROKE_DEFAULT
) );
107 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_ANTIALIASING
,
108 java
.awt
.RenderingHints
.VALUE_ANTIALIAS_OFF
) );
111 // the least common denominator standard
112 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_FRACTIONALMETRICS
,
113 java
.awt
.RenderingHints
.VALUE_FRACTIONALMETRICS_ON
) );
114 hints
.add( new java
.awt
.RenderingHints( java
.awt
.RenderingHints
.KEY_TEXT_ANTIALIASING
,
115 java
.awt
.RenderingHints
.VALUE_TEXT_ANTIALIAS_ON
) );
117 graphics
.setRenderingHints( hints
);
121 //----------------------------------------------------------------------------------
123 public static java
.awt
.geom
.GeneralPath
makeGenPathFromBezierPoints( RealBezierSegment2D
[][] points
)
125 java
.awt
.geom
.GeneralPath path
= new java
.awt
.geom
.GeneralPath();
127 // extract every polygon into GeneralPath object
128 for( int i
=0; i
<points
.length
; ++i
)
130 if( points
[i
].length
> 0 )
131 path
.moveTo((float) points
[i
][0].Px
, (float) points
[i
][0].Py
);
133 for( int j
=1; j
<points
[i
].length
; ++j
)
135 CanvasUtils
.printLog( "makeGenPathFromBezierPoints: point added." );
136 path
.curveTo((float)(points
[i
][j
-1].C1x
), (float)(points
[i
][j
-1].C1y
),
137 (float)(points
[i
][j
-1].C2x
), (float)(points
[i
][j
-1].C2y
),
138 (float) points
[i
][j
].Px
, (float) points
[i
][j
].Py
);
147 public static java
.awt
.geom
.GeneralPath
makeGenPathFromBezierPoly( com
.sun
.star
.rendering
.XBezierPolyPolygon2D poly
)
151 com
.sun
.star
.geometry
.RealBezierSegment2D
[][] points
= poly
.getBezierSegments(0,-1,0,-1);
153 return makeGenPathFromBezierPoints( points
);
155 catch( com
.sun
.star
.lang
.IndexOutOfBoundsException e
)
159 return new java
.awt
.geom
.GeneralPath();
162 public static java
.awt
.geom
.GeneralPath
makeGenPathFromLinePoints( RealPoint2D
[][] points
)
164 java
.awt
.geom
.GeneralPath path
= new java
.awt
.geom
.GeneralPath();
166 // extract every polygon into GeneralPath object
167 for( int i
=0; i
<points
.length
; ++i
)
169 if( points
[i
].length
> 0 )
170 path
.moveTo((float) points
[i
][0].X
, (float) points
[i
][0].Y
);
172 for( int j
=1; j
<points
[i
].length
; ++j
)
174 CanvasUtils
.printLog( "makeGenPathFromLinePoints: point (" +
175 points
[i
][j
].X
+ "," + points
[i
][j
].Y
+ ") added." );
176 path
.lineTo((float) points
[i
][j
].X
, (float) points
[i
][j
].Y
);
185 public static java
.awt
.geom
.GeneralPath
makeGenPathFromLinePoly( com
.sun
.star
.rendering
.XLinePolyPolygon2D poly
)
189 com
.sun
.star
.geometry
.RealPoint2D
[][] points
= poly
.getPoints(0,-1,0,-1);
191 return makeGenPathFromLinePoints( points
);
193 catch( com
.sun
.star
.lang
.IndexOutOfBoundsException e
)
197 return new java
.awt
.geom
.GeneralPath();
200 public static java
.awt
.geom
.GeneralPath
makeGeneralPath( com
.sun
.star
.rendering
.XPolyPolygon2D poly
)
202 if( poly
instanceof BezierPolyPolygon
)
204 CanvasUtils
.printLog( "makeGeneralPath: bezier impl used." );
205 return ((BezierPolyPolygon
)poly
).getJavaPath();
208 if( poly
instanceof LinePolyPolygon
)
210 CanvasUtils
.printLog( "makeGeneralPath: line impl used." );
211 return ((LinePolyPolygon
)poly
).getJavaPath();
214 XBezierPolyPolygon2D bezierPoly
= (XBezierPolyPolygon2D
) UnoRuntime
.queryInterface(XBezierPolyPolygon2D
.class, poly
);
216 if( bezierPoly
!= null )
218 // extract polygon data. Prefer bezier interface, because
219 // that's the more high-level data.
220 return makeGenPathFromBezierPoly( bezierPoly
);
223 XLinePolyPolygon2D linePoly
= (XLinePolyPolygon2D
) UnoRuntime
.queryInterface(XLinePolyPolygon2D
.class, poly
);
225 if( linePoly
!= null )
227 // extract polygon data. Fallback to line polygon, if no
228 // curves are available.
229 return makeGenPathFromLinePoly( linePoly
);
232 // Only opaque general interface. No chance to get to the
233 // data. Empty path, then
234 CanvasUtils
.printLog( "makeGeneralPath: Cannot access polygon data, given interface has class" + poly
.getClass().getName() );
235 return new GeneralPath();
238 public static java
.awt
.image
.BufferedImage
getBufferedImage( com
.sun
.star
.rendering
.XBitmap bitmap
)
240 if( bitmap
instanceof CanvasBitmap
)
242 CanvasUtils
.printLog( "getBufferedImage: CanvasBitmap impl used." );
243 return ((CanvasBitmap
)bitmap
).getBufferedImage();
246 XIntegerBitmap integerBitmap
= (XIntegerBitmap
) UnoRuntime
.queryInterface(XIntegerBitmap
.class, bitmap
);
248 if( integerBitmap
!= null )
250 // extract bitmap data. TODO.
254 // check other types. TODO.
258 public static byte [] int2byte( int [] input
)
260 byte [] output
= new byte[4*input
.length
];
263 for( i
=0, j
=0; i
<input
.length
; ++i
)
265 output
[j
] = (byte)(input
[i
] & 255);
266 output
[j
+1] = (byte)((input
[i
]/256) & 255);
267 output
[j
+2] = (byte)((input
[i
]/256/256) & 255);
268 output
[j
+3] = (byte)((input
[i
]/256/256/256) & 255);
275 public static int [] byte2int( byte [] input
)
277 int [] output
= new int[(input
.length
+3)/4];
280 for( i
=0,j
=0; j
<output
.length
; ++j
)
282 output
[j
] = input
[i
] + (input
[i
+1] + (input
[i
+2] + input
[i
+3]*256)*256)*256;
289 public static int javaRuleFromCompositeOp( byte compositeOp
)
291 // TODO: Finish mapping of Canvas and Java compositing magics
292 int rule
= java
.awt
.AlphaComposite
.SRC_OVER
;
293 switch( compositeOp
)
295 case com
.sun
.star
.rendering
.CompositeOperation
.CLEAR
:
296 CanvasUtils
.printLog( "javaRuleFromCompositeOp: clear selected" );
297 rule
= java
.awt
.AlphaComposite
.CLEAR
;
300 case com
.sun
.star
.rendering
.CompositeOperation
.SOURCE
:
301 CanvasUtils
.printLog( "javaRuleFromCompositeOp: src selected" );
302 rule
= java
.awt
.AlphaComposite
.SRC
;
305 case com
.sun
.star
.rendering
.CompositeOperation
.DESTINATION
:
306 CanvasUtils
.printLog( "javaRuleFromCompositeOp: dst selected" );
307 rule
= java
.awt
.AlphaComposite
.DST
;
310 case com
.sun
.star
.rendering
.CompositeOperation
.OVER
:
311 CanvasUtils
.printLog( "javaRuleFromCompositeOp: over selected" );
312 rule
= java
.awt
.AlphaComposite
.SRC_OVER
;
315 case com
.sun
.star
.rendering
.CompositeOperation
.UNDER
:
316 CanvasUtils
.printLog( "javaRuleFromCompositeOp: under selected" );
317 rule
= java
.awt
.AlphaComposite
.DST_OVER
;
320 case com
.sun
.star
.rendering
.CompositeOperation
.INSIDE
:
321 CanvasUtils
.printLog( "javaRuleFromCompositeOp: inside selected" );
322 rule
= java
.awt
.AlphaComposite
.CLEAR
;
325 case com
.sun
.star
.rendering
.CompositeOperation
.INSIDE_REVERSE
:
326 CanvasUtils
.printLog( "javaRuleFromCompositeOp: inReverse selected" );
327 rule
= java
.awt
.AlphaComposite
.CLEAR
;
330 case com
.sun
.star
.rendering
.CompositeOperation
.OUTSIDE
:
331 CanvasUtils
.printLog( "javaRuleFromCompositeOp: outside selected" );
332 rule
= java
.awt
.AlphaComposite
.CLEAR
;
335 case com
.sun
.star
.rendering
.CompositeOperation
.OUTSIDE_REVERSE
:
336 CanvasUtils
.printLog( "javaRuleFromCompositeOp: outReverse selected" );
337 rule
= java
.awt
.AlphaComposite
.CLEAR
;
340 case com
.sun
.star
.rendering
.CompositeOperation
.XOR
:
341 CanvasUtils
.printLog( "javaRuleFromCompositeOp: xor selected" );
342 rule
= java
.awt
.AlphaComposite
.CLEAR
;
345 case com
.sun
.star
.rendering
.CompositeOperation
.ADD
:
346 CanvasUtils
.printLog( "javaRuleFromCompositeOp: add selected" );
347 rule
= java
.awt
.AlphaComposite
.CLEAR
;
350 case com
.sun
.star
.rendering
.CompositeOperation
.SATURATE
:
351 CanvasUtils
.printLog( "javaRuleFromCompositeOp: saturate selected" );
352 rule
= java
.awt
.AlphaComposite
.CLEAR
;
356 CanvasUtils
.printLog( "javaRuleFromCompositeOp: Unexpected compositing rule" );
363 public static java
.awt
.AlphaComposite
makeAlphaComposite( byte compositeOp
)
365 return java
.awt
.AlphaComposite
.getInstance( javaRuleFromCompositeOp( compositeOp
) );
368 public static java
.awt
.AlphaComposite
makeAlphaCompositeAlpha( byte compositeOp
, double alpha
)
370 return java
.awt
.AlphaComposite
.getInstance( javaRuleFromCompositeOp( compositeOp
), (float)alpha
);
373 // when given to setupGraphicsState, makes that method to also
374 // setup the Paint with the color specified in the render state.
375 public static final byte alsoSetupPaint
=0;
377 // when given to setupGraphicsState, makes that method to _not_
378 // setup the Paint with the color specified in the render state.
379 public static final byte dontSetupPaint
=1;
381 public static java
.awt
.geom
.AffineTransform
ViewConcatRenderTransform( ViewState viewState
,
382 RenderState renderState
)
384 // calculate overall affine transform
385 AffineTransform transform
= makeTransform( viewState
.AffineTransform
);
386 transform
.concatenate( makeTransform( renderState
.AffineTransform
) );
388 printTransform( transform
, "ViewConcatRenderTransform" );
393 public static void setupGraphicsState( java
.awt
.Graphics2D graphics
,
395 RenderState renderState
,
396 byte paintTouchMode
)
398 // calculate overall affine transform
399 graphics
.setTransform( ViewConcatRenderTransform(viewState
, renderState
) );
401 // setup overall clip polyPolygon
402 if( viewState
.Clip
!= null )
404 Area clipArea
= new Area( makeGeneralPath( viewState
.Clip
) );
406 if( renderState
.Clip
!= null )
407 clipArea
.intersect( new Area( makeGeneralPath( renderState
.Clip
) ) );
409 graphics
.setClip( clipArea
);
411 else if( renderState
.Clip
!= null )
413 Area clipArea
= new Area( makeGeneralPath( renderState
.Clip
) );
414 graphics
.setClip( clipArea
);
418 // TODO: HACK! Use true visible area here!
419 graphics
.setClip( new java
.awt
.Rectangle(-1000000,-1000000,2000000,2000000) );
422 // setup current output color
423 // TODO: Complete color handling here
424 if( paintTouchMode
== alsoSetupPaint
)
426 switch( renderState
.DeviceColor
.length
)
429 CanvasUtils
.printLog( "setupGraphicsState: Color(" +
430 renderState
.DeviceColor
[0] + "," +
431 renderState
.DeviceColor
[1] + "," +
432 renderState
.DeviceColor
[2] + ") set." );
433 graphics
.setColor( new Color( (float)renderState
.DeviceColor
[0],
434 (float)renderState
.DeviceColor
[1],
435 (float)renderState
.DeviceColor
[2] ) );
439 CanvasUtils
.printLog( "setupGraphicsState: Color(" +
440 renderState
.DeviceColor
[0] + "," +
441 renderState
.DeviceColor
[1] + "," +
442 renderState
.DeviceColor
[2] + "," +
443 renderState
.DeviceColor
[3] + ") set." );
444 graphics
.setColor( new Color( (float)renderState
.DeviceColor
[0],
445 (float)renderState
.DeviceColor
[1],
446 (float)renderState
.DeviceColor
[2],
447 (float)renderState
.DeviceColor
[3] ) );
451 CanvasUtils
.printLog( "setupGraphicsState: unexpected number of " +
452 renderState
.DeviceColor
.length
+ " color components!" );
457 // setup current composite mode
458 graphics
.setComposite( makeAlphaComposite( renderState
.CompositeOperation
) );
461 public static void applyStrokeAttributes( java
.awt
.Graphics2D graphics
,
462 StrokeAttributes attributes
)
464 int cap
= java
.awt
.BasicStroke
.CAP_BUTT
;
466 if( attributes
.StartCapType
!= attributes
.EndCapType
)
467 CanvasUtils
.printLog( "applyStrokeAttributes: different start and end caps are not yet supported!" );
469 if( attributes
.LineArray
.length
!= 0 )
470 CanvasUtils
.printLog( "applyStrokeAttributes: multi-strokes are not yet supported!" );
472 if( attributes
.StartCapType
== PathCapType
.BUTT
)
473 cap
= java
.awt
.BasicStroke
.CAP_BUTT
;
474 else if( attributes
.StartCapType
== PathCapType
.ROUND
)
475 cap
= java
.awt
.BasicStroke
.CAP_ROUND
;
476 else if( attributes
.StartCapType
== PathCapType
.SQUARE
)
477 cap
= java
.awt
.BasicStroke
.CAP_SQUARE
;
479 int join
= java
.awt
.BasicStroke
.JOIN_MITER
;
481 if( attributes
.JoinType
== PathJoinType
.MITER
)
482 cap
= java
.awt
.BasicStroke
.JOIN_MITER
;
483 else if( attributes
.JoinType
== PathJoinType
.ROUND
)
484 cap
= java
.awt
.BasicStroke
.JOIN_ROUND
;
485 else if( attributes
.JoinType
== PathJoinType
.BEVEL
)
486 cap
= java
.awt
.BasicStroke
.JOIN_BEVEL
;
488 CanvasUtils
.printLog( "applyStrokeAttributes: current join type not yet supported!" );
490 float [] dashArray
= null;
492 if( attributes
.DashArray
.length
!= 0 )
494 dashArray
= new float [attributes
.DashArray
.length
];
496 for( int i
=0; i
<attributes
.DashArray
.length
; ++i
)
497 dashArray
[i
] = (float)attributes
.DashArray
[i
];
500 graphics
.setStroke( new java
.awt
.BasicStroke( (float)attributes
.StrokeWidth
,
503 (float)attributes
.MiterLimit
,
508 public static void setupGraphicsFont( java
.awt
.Graphics2D graphics
,
510 RenderState renderState
,
511 com
.sun
.star
.rendering
.XCanvasFont xFont
)
513 if( xFont
instanceof CanvasFont
)
515 CanvasUtils
.printLog( "setupGraphicsFont: font impl used." );
516 graphics
.setFont( ((CanvasFont
)xFont
).getFont() );
520 CanvasUtils
.printLog( "setupGraphicsFont: creating Java font anew." );
521 CanvasFont canvasFont
;
522 canvasFont
= new CanvasFont( xFont
.getFontRequest(), null );
523 graphics
.setFont( canvasFont
.getFont() );
527 static java
.awt
.geom
.Rectangle2D
.Double
calcTransformedRectBounds( java
.awt
.geom
.Rectangle2D
.Double aRect
,
528 AffineTransform aTransform
)
530 // transform rect by given transformation
531 java
.awt
.geom
.Point2D
.Double aPointTopLeft
= new java
.awt
.geom
.Point2D
.Double(aRect
.x
, aRect
.y
);
532 aTransform
.transform(aPointTopLeft
, aPointTopLeft
);
534 java
.awt
.geom
.Point2D
.Double aPointTopRight
= new java
.awt
.geom
.Point2D
.Double(aRect
.x
+ aRect
.width
,
536 aTransform
.transform(aPointTopRight
, aPointTopRight
);
538 java
.awt
.geom
.Point2D
.Double aPointBottomLeft
= new java
.awt
.geom
.Point2D
.Double(aRect
.x
,
539 aRect
.y
+ aRect
.height
);
540 aTransform
.transform(aPointBottomLeft
, aPointBottomLeft
);
542 java
.awt
.geom
.Point2D
.Double aPointBottomRight
= new java
.awt
.geom
.Point2D
.Double(aRect
.x
+ aRect
.width
,
543 aRect
.y
+ aRect
.height
);
544 aTransform
.transform(aPointBottomRight
, aPointBottomRight
);
546 // calc bounding rect of those four points
547 java
.awt
.geom
.Point2D
.Double aResTopLeft
= new java
.awt
.geom
.Point2D
.Double( Math
.min(aPointTopLeft
.x
,
548 Math
.min(aPointTopRight
.x
,
549 Math
.min(aPointBottomLeft
.x
,aPointBottomRight
.x
))),
550 Math
.min(aPointTopLeft
.y
,
551 Math
.min(aPointTopRight
.y
,
552 Math
.min(aPointBottomLeft
.y
,aPointBottomRight
.y
))) );
554 java
.awt
.geom
.Point2D
.Double aResBottomRight
= new java
.awt
.geom
.Point2D
.Double( Math
.max(aPointTopLeft
.x
,
555 Math
.max(aPointTopRight
.x
,
556 Math
.max(aPointBottomLeft
.x
,aPointBottomRight
.x
))),
557 Math
.max(aPointTopLeft
.y
,
558 Math
.max(aPointTopRight
.y
,
559 Math
.max(aPointBottomLeft
.y
,aPointBottomRight
.y
))) );
560 return new java
.awt
.geom
.Rectangle2D
.Double( aResTopLeft
.x
, aResTopLeft
.y
,
561 aResBottomRight
.x
- aResTopLeft
.x
,
562 aResBottomRight
.y
- aResTopLeft
.y
);
565 // Create a corrected view transformation out of the give one,
566 // which ensures that the rectangle given by (0,0) and
567 // attributes.untransformedSize is mapped with its left,top corner
568 // to (0,0) again. This is required to properly render sprite
569 // animations to buffer bitmaps.
570 public static ViewState
createAnimationViewState( ViewState inputViewState
,
571 AnimationAttributes attributes
)
573 // TODO: Properly respect clip here. Might have to be transformed, too.
575 AffineTransform aViewTransform
= makeTransform( inputViewState
.AffineTransform
);
577 // transform Rect(0,0,attributes.untransformedSize) by
579 java
.awt
.geom
.Rectangle2D
.Double aTransformedRect
=
580 calcTransformedRectBounds( new java
.awt
.geom
.Rectangle2D
.Double(0.0, 0.0,
581 attributes
.UntransformedSize
.Width
,
582 attributes
.UntransformedSize
.Height
),
585 printTransform( aViewTransform
, "createAnimationViewState" );
587 CanvasUtils
.printLog( "createAnimationViewState: transformed origin is: (" + aTransformedRect
.x
+ ", " + aTransformedRect
.y
+ ")" );
589 // now move resulting left,top point of bounds to (0,0)
590 AffineTransform animationViewTransform
= new AffineTransform();
591 animationViewTransform
.translate( -aTransformedRect
.x
, -aTransformedRect
.y
);
592 animationViewTransform
.concatenate( aViewTransform
);
594 printTransform( animationViewTransform
, "createAnimationViewState" );
596 return new ViewState( makeAffineMatrix2D( animationViewTransform
), inputViewState
.Clip
);
599 public static void postRenderImageTreatment( Image buffer
)
601 // TODO: This is specific to Sun's JREs 1.4 and upwards. Make this more portable
602 buffer
.flush(); // as long as we force images to VRAM,
603 // we need to flush them afterwards, to
604 // avoid eating up all VRAM.
607 public static void printTransform( AffineTransform transform
,
608 String stringPrefix
)
610 CanvasUtils
.printLog( stringPrefix
+ ": Transform is" );
611 double [] matrix
= new double[6];
612 transform
.getMatrix(matrix
);
615 System
.err
.print( matrix
[i
] + ", " );
616 CanvasUtils
.printLog( "" );
619 public static void preCondition( boolean bCondition
,
623 printLog("Precondition violated: " + methodName
);
626 public static void printLog( String s
)
628 System
.err
.println( s
);