Merge "LayoutLib: replace the stack of Graphics2D with custom snapshots."

This commit is contained in:
Xavier Ducrohet
2010-12-15 13:50:37 -08:00
committed by Android (Google) Code Review
4 changed files with 405 additions and 115 deletions

View File

@@ -18,7 +18,7 @@ package android.graphics;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.layoutlib.bridge.impl.Stack;
import com.android.layoutlib.bridge.impl.GcSnapshot;
import android.graphics.Paint_Delegate.FontInfo;
import android.text.TextUtils;
@@ -26,7 +26,6 @@ import android.text.TextUtils;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
@@ -58,7 +57,7 @@ public class Canvas_Delegate {
// ---- delegate data ----
private BufferedImage mBufferedImage;
private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>();
private GcSnapshot mSnapshot = new GcSnapshot();
// ---- Public Helper methods ----
@@ -79,8 +78,8 @@ public class Canvas_Delegate {
/**
* Returns the current {@link Graphics2D} used to draw.
*/
public Graphics2D getGraphics2d() {
return mGraphicsStack.peek();
public GcSnapshot getGcSnapshot() {
return mSnapshot;
}
// ---- native methods ----
@@ -120,7 +119,7 @@ public class Canvas_Delegate {
return;
}
canvasDelegate.getGraphics2d().translate(dx, dy);
canvasDelegate.getGcSnapshot().translate(dx, dy);
}
/*package*/ static void rotate(Canvas thisCanvas, float degrees) {
@@ -131,7 +130,7 @@ public class Canvas_Delegate {
return;
}
canvasDelegate.getGraphics2d().rotate(Math.toRadians(degrees));
canvasDelegate.getGcSnapshot().rotate(Math.toRadians(degrees));
}
/*package*/ static void scale(Canvas thisCanvas, float sx, float sy) {
@@ -142,7 +141,7 @@ public class Canvas_Delegate {
return;
}
canvasDelegate.getGraphics2d().scale(sx, sy);
canvasDelegate.getGcSnapshot().scale(sx, sy);
}
/*package*/ static void skew(Canvas thisCanvas, float kx, float ky) {
@@ -154,7 +153,7 @@ public class Canvas_Delegate {
}
// get the current top graphics2D object.
Graphics2D g = canvasDelegate.getGraphics2d();
GcSnapshot g = canvasDelegate.getGcSnapshot();
// get its current matrix
AffineTransform currentTx = g.getTransform();
@@ -170,21 +169,16 @@ public class Canvas_Delegate {
}
/*package*/ static boolean clipRect(Canvas thisCanvas, RectF rect) {
return clipRect(thisCanvas,
(int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
}
/*package*/ static boolean clipRect(Canvas thisCanvas, Rect rect) {
return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
return clipRect(thisCanvas, (float) rect.left, (float) rect.top,
(float) rect.right, (float) rect.bottom);
}
/*package*/ static boolean clipRect(Canvas thisCanvas, float left, float top, float right,
float bottom) {
return clipRect(thisCanvas, (int) left, (int) top, (int) right, (int) bottom);
}
/*package*/ static boolean clipRect(Canvas thisCanvas, int left, int top, int right,
int bottom) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
if (canvasDelegate == null) {
@@ -195,7 +189,17 @@ public class Canvas_Delegate {
return canvasDelegate.clipRect(left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
}
/*package*/ static boolean clipRect(Canvas thisCanvas, int left, int top, int right,
int bottom) {
return clipRect(thisCanvas, (float) left, (float) top, (float) right, (float) bottom);
}
/*package*/ static int save(Canvas thisCanvas) {
return save(thisCanvas, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG);
}
/*package*/ static int save(Canvas thisCanvas, int saveFlags) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
if (canvasDelegate == null) {
@@ -203,21 +207,7 @@ public class Canvas_Delegate {
return 0;
}
// get the current save count
int count = canvasDelegate.mGraphicsStack.size();
// create a new graphics and add it to the stack
Graphics2D g = (Graphics2D)canvasDelegate.getGraphics2d().create();
canvasDelegate.mGraphicsStack.push(g);
// return the old save count
return count;
}
/*package*/ static int save(Canvas thisCanvas, int saveFlags) {
// FIXME implement save(flags)
return save(thisCanvas);
return canvasDelegate.save(saveFlags);
}
/*package*/ static void restore(Canvas thisCanvas) {
@@ -228,7 +218,7 @@ public class Canvas_Delegate {
return;
}
canvasDelegate.mGraphicsStack.pop();
canvasDelegate.restore();
}
/*package*/ static int getSaveCount(Canvas thisCanvas) {
@@ -239,7 +229,7 @@ public class Canvas_Delegate {
return 0;
}
return canvasDelegate.mGraphicsStack.size();
return canvasDelegate.getGcSnapshot().size();
}
/*package*/ static void restoreToCount(Canvas thisCanvas, int saveCount) {
@@ -250,9 +240,7 @@ public class Canvas_Delegate {
return;
}
while (canvasDelegate.mGraphicsStack.size() > saveCount) {
canvasDelegate.mGraphicsStack.pop();
}
canvasDelegate.restoreTo(saveCount);
}
/*package*/ static void drawPoints(Canvas thisCanvas, float[] pts, int offset, int count,
@@ -282,7 +270,7 @@ public class Canvas_Delegate {
}
// get a Graphics2D object configured with the drawing parameters.
Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
try {
for (int i = 0 ; i < count ; i += 4) {
@@ -378,10 +366,10 @@ public class Canvas_Delegate {
}
// get the current top graphics2D object.
Graphics2D g = canvasDelegate.getGraphics2d();
GcSnapshot snapshot = canvasDelegate.getGcSnapshot();
// get its current matrix
AffineTransform currentTx = g.getTransform();
AffineTransform currentTx = snapshot.getTransform();
// get the AffineTransform of the given matrix
AffineTransform matrixTx = matrixDelegate.getAffineTransform();
@@ -389,7 +377,7 @@ public class Canvas_Delegate {
currentTx.preConcatenate(matrixTx);
// give it to the graphics2D as a new matrix replacing all previous transform
g.setTransform(currentTx);
snapshot.setTransform(currentTx);
}
/*package*/ static void native_setMatrix(int nCanvas, int nMatrix) {
@@ -405,15 +393,16 @@ public class Canvas_Delegate {
}
// get the current top graphics2D object.
Graphics2D g = canvasDelegate.getGraphics2d();
GcSnapshot snapshot = canvasDelegate.getGcSnapshot();
// get the AffineTransform of the given matrix
AffineTransform matrixTx = matrixDelegate.getAffineTransform();
// give it to the graphics2D as a new matrix replacing all previous transform
g.setTransform(matrixTx);
snapshot.setTransform(matrixTx);
if (matrixDelegate.hasPerspective()) {
assert false;
Bridge.getLog().warning(null,
"android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
"supports affine transformations in the Layout Preview.");
@@ -431,9 +420,7 @@ public class Canvas_Delegate {
assert false;
}
return canvasDelegate.clipRect(
(int) left, (int) top, (int) right, (int) bottom,
regionOp);
return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
}
/*package*/ static boolean native_clipPath(int nativeCanvas,
@@ -465,7 +452,7 @@ public class Canvas_Delegate {
return false;
}
Rectangle rect = canvasDelegate.getGraphics2d().getClipBounds();
Rectangle rect = canvasDelegate.getGcSnapshot().getClip().getBounds();
if (rect != null) {
bounds.left = rect.x;
bounds.top = rect.y;
@@ -527,7 +514,7 @@ public class Canvas_Delegate {
}
// get a new graphics context.
Graphics2D graphics = (Graphics2D)canvasDelegate.getGraphics2d().create();
Graphics2D graphics = (Graphics2D)canvasDelegate.getGcSnapshot().create();
try {
// reset its transform just in case
graphics.setTransform(new AffineTransform());
@@ -568,12 +555,14 @@ public class Canvas_Delegate {
}
// get a Graphics2D object configured with the drawing parameters.
Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
// dispose Graphics2D object
g.dispose();
try {
g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
} finally {
// dispose Graphics2D object
g.dispose();
}
}
/*package*/ static void native_drawRect(int nativeCanvas, RectF rect,
@@ -600,23 +589,25 @@ public class Canvas_Delegate {
if (right > left && bottom > top) {
// get a Graphics2D object configured with the drawing parameters.
Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
int style = paintDelegate.getStyle();
try {
int style = paintDelegate.getStyle();
// draw
if (style == Paint.Style.FILL.nativeInt ||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
g.fillRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
// draw
if (style == Paint.Style.FILL.nativeInt ||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
g.fillRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
}
if (style == Paint.Style.STROKE.nativeInt ||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
g.drawRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
}
} finally {
// dispose Graphics2D object
g.dispose();
}
if (style == Paint.Style.STROKE.nativeInt ||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
g.drawRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
}
// dispose Graphics2D object
g.dispose();
}
}
@@ -638,7 +629,7 @@ public class Canvas_Delegate {
if (oval.right > oval.left && oval.bottom > oval.top) {
// get a Graphics2D object configured with the drawing parameters.
Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
int style = paintDelegate.getStyle();
@@ -692,7 +683,7 @@ public class Canvas_Delegate {
if (rect.right > rect.left && rect.bottom > rect.top) {
// get a Graphics2D object configured with the drawing parameters.
Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
int style = paintDelegate.getStyle();
@@ -833,7 +824,7 @@ public class Canvas_Delegate {
return;
}
Graphics2D g = (Graphics2D) canvasDelegate.getCustomGraphics(paintDelegate);
Graphics2D g = (Graphics2D) canvasDelegate.createCustomGraphics(paintDelegate);
try {
// Paint.TextAlign indicates how the text is positioned relative to X.
// LEFT is the default and there's nothing to do.
@@ -1018,34 +1009,53 @@ public class Canvas_Delegate {
* Disposes of the {@link Graphics2D} stack.
*/
private void dispose() {
while (mGraphicsStack.size() > 0) {
mGraphicsStack.pop().dispose();
}
mSnapshot.dispose();
}
private boolean clipRect(int left, int top, int right, int bottom, int regionOp) {
if (regionOp == Region.Op.INTERSECT.nativeInt) {
Graphics2D gc = getGraphics2d();
gc.clipRect(left, top, right - left, bottom - top);
return gc.getClip().getBounds().isEmpty() == false;
} else {
throw new UnsupportedOperationException();
}
private int save(int saveFlags) {
// get the current save count
int count = mSnapshot.size();
// create a new snapshot and add it to the stack
mSnapshot = new GcSnapshot(mSnapshot, saveFlags);
// return the old save count
return count;
}
/**
* Restores the {@link GcSnapshot} to <var>saveCount</var>
* @param saveCount the saveCount
*/
private void restoreTo(int saveCount) {
mSnapshot = mSnapshot.restoreTo(saveCount);
}
/**
* Restores the {@link GcSnapshot} to <var>saveCount</var>
* @param saveCount the saveCount
*/
private void restore() {
mSnapshot = mSnapshot.restore();
}
private boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
return mSnapshot.clipRect(left, top, right, bottom, regionOp);
}
private void setBitmap(BufferedImage image) {
mBufferedImage = image;
mGraphicsStack.push(mBufferedImage.createGraphics());
assert mSnapshot.size() == 1;
mSnapshot.setGraphics2D(mBufferedImage.createGraphics());
}
/**
* Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
* <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
*/
/*package*/ Graphics2D getCustomGraphics(Paint_Delegate paint) {
/*package*/ Graphics2D createCustomGraphics(Paint_Delegate paint) {
// make new one
Graphics2D g = getGraphics2d();
g = (Graphics2D)g.create();
Graphics2D g = getGcSnapshot().create();
// configure it
@@ -1062,6 +1072,7 @@ public class Canvas_Delegate {
Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(paint.getShader());
if (shaderDelegate != null) {
java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
assert shaderPaint != null;
if (shaderPaint != null) {
g.setPaint(shaderPaint);
useColorPaint = false;
@@ -1113,6 +1124,7 @@ public class Canvas_Delegate {
// if xfermode wasn't null, then it's something we don't support. log it.
if (xfermodeDelegate != null) {
assert false;
Bridge.getLog().warning(null,
String.format(
"Xfermode '%1$s' is not supported in the Layout Preview.",
@@ -1217,30 +1229,18 @@ public class Canvas_Delegate {
int sleft, int stop, int sright, int sbottom,
int dleft, int dtop, int dright, int dbottom) {
Graphics2D g = canvasDelegate.getGraphics2d();
Composite c = null;
if (paintDelegate != null) {
if (paintDelegate.isFilterBitmap()) {
g = (Graphics2D)g.create();
Graphics2D g = canvasDelegate.getGcSnapshot().create();
try {
if (paintDelegate != null && paintDelegate.isFilterBitmap()) {
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}
}
g.drawImage(image, dleft, dtop, dright, dbottom,
sleft, stop, sright, sbottom, null);
if (paintDelegate != null) {
if (paintDelegate.isFilterBitmap()) {
g.dispose();
}
if (c != null) {
g.setComposite(c);
}
g.drawImage(image, dleft, dtop, dright, dbottom,
sleft, stop, sright, sbottom, null);
} finally {
g.dispose();
}
}
}

View File

@@ -195,7 +195,8 @@ public final class Matrix_Delegate {
setTranslate(d.mValues, dx, dy);
}
/*package*/ static void native_setScale(int native_object, float sx, float sy, float px, float py) {
/*package*/ static void native_setScale(int native_object, float sx, float sy,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
if (d == null) {
assert false;
@@ -272,7 +273,8 @@ public final class Matrix_Delegate {
setRotate(d.mValues, sinValue, cosValue);
}
/*package*/ static void native_setSkew(int native_object, float kx, float ky, float px, float py) {
/*package*/ static void native_setSkew(int native_object, float kx, float ky,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
if (d == null) {
assert false;
@@ -364,7 +366,8 @@ public final class Matrix_Delegate {
return true;
}
/*package*/ static boolean native_preRotate(int native_object, float degrees, float px, float py) {
/*package*/ static boolean native_preRotate(int native_object, float degrees,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
if (d == null) {
assert false;
@@ -464,7 +467,8 @@ public final class Matrix_Delegate {
return true;
}
/*package*/ static boolean native_postRotate(int native_object, float degrees, float px, float py) {
/*package*/ static boolean native_postRotate(int native_object, float degrees,
float px, float py) {
Matrix_Delegate d = sManager.getDelegate(native_object);
if (d == null) {
assert false;
@@ -526,7 +530,8 @@ public final class Matrix_Delegate {
return true;
}
/*package*/ static boolean native_setRectToRect(int native_object, RectF src, RectF dst, int stf) {
/*package*/ static boolean native_setRectToRect(int native_object, RectF src,
RectF dst, int stf) {
Matrix_Delegate d = sManager.getDelegate(native_object);
if (d == null) {
assert false;

View File

@@ -160,20 +160,17 @@ public class NinePatch_Delegate {
Graphics2D graphics;
if (paint_delegate != null) {
graphics = canvas_delegate.getCustomGraphics(paint_delegate);
graphics = canvas_delegate.createCustomGraphics(paint_delegate);
} else {
graphics = canvas_delegate.getGraphics2d();
graphics = canvas_delegate.getGcSnapshot().create();
}
try {
chunkObject.draw(bitmap_delegate.getImage(), graphics,
left, top, right - left, bottom - top, destDensity, srcDensity);
} finally {
if (paint_delegate != null) {
graphics.dispose();
}
graphics.dispose();
}
}
/*package*/ static int nativeGetTransparentRegion(int bitmap, byte[] chunk, Rect location) {

View File

@@ -0,0 +1,288 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.layoutlib.bridge.impl;
import android.graphics.Canvas;
import android.graphics.Region;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
/**
* Class representing a graphics context snapshot, as well as a context stack as a linked list.
* <p>
* This is based on top of {@link Graphics2D} but can operate independently if none are available
* yet when setting transforms and clip information.
*
*/
public class GcSnapshot {
private final GcSnapshot mPrevious;
private final int mFlags;
private Graphics2D mGraphics2D = null;
/** temp transform in case transformation are set before a Graphics2D exists */
private AffineTransform mTransform = null;
/** temp clip in case clipping is set before a Graphics2D exists */
private Area mClip = null;
/**
* Creates a new {@link GcSnapshot} on top of another one.
* <p/>
* This is basically the equivalent of {@link Canvas#save(int)}
* @param previous the previous snapshot head.
* @param flags the flags regarding what should be saved.
*/
public GcSnapshot(GcSnapshot previous, int flags) {
assert previous != null;
mPrevious = previous;
mFlags = flags;
mGraphics2D = (Graphics2D) previous.mGraphics2D.create();
}
/**
* Creates the root snapshot.
* {@link #setGraphics2D(Graphics2D)} will have to be called on it when possible.
*/
public GcSnapshot() {
mPrevious = null;
mFlags = 0;
}
public void dispose() {
if (mGraphics2D != null) {
mGraphics2D.dispose();
}
if (mPrevious != null) {
mPrevious.dispose();
}
}
/**
* Restores the top {@link GcSnapshot}, and returns the next one.
*/
public GcSnapshot restore() {
return doRestore();
}
/**
* Restores the {@link GcSnapshot} to <var>saveCount</var>.
* @param saveCount the saveCount or -1 to only restore 1.
*
* @return the new head of the Gc snapshot stack.
*/
public GcSnapshot restoreTo(int saveCount) {
return doRestoreTo(size(), saveCount);
}
public int size() {
if (mPrevious != null) {
return mPrevious.size() + 1;
}
return 1;
}
/**
* Sets the Graphics2D object for this snapshot if it was created through {@link #GcSnapshot()}.
* If any transform or clip information was set before, they are put into the Graphics object.
* @param graphics2D the graphics object to set.
*/
public void setGraphics2D(Graphics2D graphics2D) {
mGraphics2D = graphics2D;
if (mTransform != null) {
mGraphics2D.setTransform(mTransform);
mTransform = null;
}
if (mClip != null) {
mGraphics2D.setClip(mClip);
mClip = null;
}
}
/**
* Creates and return a copy of the current {@link Graphics2D}.
* @return a new {@link Graphics2D}.
*/
public Graphics2D create() {
assert mGraphics2D != null;
return (Graphics2D) mGraphics2D.create();
}
public void translate(float dx, float dy) {
if (mGraphics2D != null) {
mGraphics2D.translate(dx, dy);
} else {
if (mTransform == null) {
mTransform = new AffineTransform();
}
mTransform.translate(dx, dy);
}
}
public void rotate(double radians) {
if (mGraphics2D != null) {
mGraphics2D.rotate(radians);
} else {
if (mTransform == null) {
mTransform = new AffineTransform();
}
mTransform.rotate(radians);
}
}
public void scale(float sx, float sy) {
if (mGraphics2D != null) {
mGraphics2D.scale(sx, sy);
} else {
if (mTransform == null) {
mTransform = new AffineTransform();
}
mTransform.scale(sx, sy);
}
}
public AffineTransform getTransform() {
if (mGraphics2D != null) {
return mGraphics2D.getTransform();
} else {
if (mTransform == null) {
mTransform = new AffineTransform();
}
return mTransform;
}
}
public void setTransform(AffineTransform transform) {
if (mGraphics2D != null) {
mGraphics2D.setTransform(transform);
} else {
if (mTransform == null) {
mTransform = new AffineTransform();
}
mTransform.setTransform(transform);
}
}
public boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
if (mGraphics2D != null) {
if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
Area newClip = new Area(mGraphics2D.getClip());
newClip.subtract(new Area(
new Rectangle2D.Float(left, top, right - left, bottom - top)));
mGraphics2D.setClip(newClip);
} else if (regionOp == Region.Op.INTERSECT.nativeInt) {
mGraphics2D.clipRect((int) left, (int) top,
(int) (right - left), (int) (bottom - top));
} else if (regionOp == Region.Op.UNION.nativeInt) {
Area newClip = new Area(mGraphics2D.getClip());
newClip.add(new Area(
new Rectangle2D.Float(left, top, right - left, bottom - top)));
mGraphics2D.setClip(newClip);
} else if (regionOp == Region.Op.XOR.nativeInt) {
Area newClip = new Area(mGraphics2D.getClip());
newClip.exclusiveOr(new Area(
new Rectangle2D.Float(left, top, right - left, bottom - top)));
mGraphics2D.setClip(newClip);
} else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
Area newClip = new Area(
new Rectangle2D.Float(left, top, right - left, bottom - top));
newClip.subtract(new Area(mGraphics2D.getClip()));
mGraphics2D.setClip(newClip);
} else if (regionOp == Region.Op.REPLACE.nativeInt) {
mGraphics2D.setClip((int) left, (int) top,
(int) (right - left), (int) (bottom - top));
}
return mGraphics2D.getClip().getBounds().isEmpty() == false;
} else {
if (mClip == null) {
mClip = new Area();
}
if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
//FIXME
} else if (regionOp == Region.Op.DIFFERENCE.nativeInt) {
} else if (regionOp == Region.Op.INTERSECT.nativeInt) {
} else if (regionOp == Region.Op.UNION.nativeInt) {
} else if (regionOp == Region.Op.XOR.nativeInt) {
} else if (regionOp == Region.Op.REVERSE_DIFFERENCE.nativeInt) {
} else if (regionOp == Region.Op.REPLACE.nativeInt) {
}
return mClip.getBounds().isEmpty() == false;
}
}
public Shape getClip() {
if (mGraphics2D != null) {
return mGraphics2D.getClip();
} else {
if (mClip == null) {
mClip = new Area();
}
return mClip;
}
}
private GcSnapshot doRestoreTo(int size, int saveCount) {
if (size <= saveCount) {
return this;
}
// restore the current one first.
GcSnapshot previous = doRestore();
if (size == saveCount + 1) { // this was the only one that needed restore.
return previous;
} else {
return previous.doRestoreTo(size - 1, saveCount);
}
}
private GcSnapshot doRestore() {
// if this snapshot does not save everything, then set the previous snapshot
// to this snapshot content
if (mPrevious != null) {
// didn't save the matrix? set the current matrix on the previous snapshot
if ((mFlags & Canvas.MATRIX_SAVE_FLAG) == 0) {
mPrevious.mGraphics2D.setTransform(getTransform());
}
// didn't save the clip? set the current clip on the previous snapshot
if ((mFlags & Canvas.CLIP_SAVE_FLAG) == 0) {
mPrevious.mGraphics2D.setClip(mGraphics2D.getClip());
}
}
if (mGraphics2D != null) {
mGraphics2D.dispose();
}
return mPrevious;
}
}