Merge "LayoutLib: support for Path and BitmapShader using delegates."
This commit is contained in:
committed by
Android (Google) Code Review
commit
2363b5faac
6
tests/HwAccelerationTest/res/layout/_paths.xml
Normal file
6
tests/HwAccelerationTest/res/layout/_paths.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.android.test.hwui.PathsActivity.PathsView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.PathsActivity.PathsView>
|
||||
6
tests/HwAccelerationTest/res/layout/_shaders.xml
Normal file
6
tests/HwAccelerationTest/res/layout/_shaders.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.android.test.hwui.ShadersActivity.ShadersView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.ShadersActivity.ShadersView>
|
||||
@@ -37,7 +37,7 @@ public class PathsActivity extends Activity {
|
||||
setContentView(view);
|
||||
}
|
||||
|
||||
static class PathsView extends View {
|
||||
public static class PathsView extends View {
|
||||
private final Bitmap mBitmap1;
|
||||
private final Paint mSmallPaint;
|
||||
private final Paint mMediumPaint;
|
||||
@@ -50,7 +50,7 @@ public class PathsActivity extends Activity {
|
||||
private final float mOffset;
|
||||
private final Paint mLinePaint;
|
||||
|
||||
PathsView(Context c) {
|
||||
public PathsView(Context c) {
|
||||
super(c);
|
||||
|
||||
mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
|
||||
@@ -60,7 +60,7 @@ public class PathsActivity extends Activity {
|
||||
mSmallPaint.setColor(0xffff0000);
|
||||
mSmallPaint.setStrokeWidth(1.0f);
|
||||
mSmallPaint.setStyle(Paint.Style.STROKE);
|
||||
|
||||
|
||||
mLinePaint = new Paint();
|
||||
mLinePaint.setAntiAlias(true);
|
||||
mLinePaint.setColor(0xffff00ff);
|
||||
@@ -112,7 +112,7 @@ public class PathsActivity extends Activity {
|
||||
canvas.save();
|
||||
canvas.translate(200.0f, 60.0f);
|
||||
canvas.drawPath(mPath, mSmallPaint);
|
||||
|
||||
|
||||
canvas.translate(350.0f, 0.0f);
|
||||
canvas.drawPath(mPath, mMediumPaint);
|
||||
|
||||
@@ -121,12 +121,12 @@ public class PathsActivity extends Activity {
|
||||
canvas.drawPath(mPath, mLargePaint);
|
||||
mLargePaint.setShader(null);
|
||||
canvas.restore();
|
||||
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(200.0f, 360.0f);
|
||||
canvas.drawPath(mPath, mSmallPaint);
|
||||
canvas.drawRect(mPathBounds, mBoundsPaint);
|
||||
|
||||
|
||||
canvas.translate(350.0f, 0.0f);
|
||||
canvas.drawBitmap(mBitmap, mPathBounds.left - mOffset * 1.5f,
|
||||
mPathBounds.top - mOffset * 1.5f, null);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ShadersActivity extends Activity {
|
||||
setContentView(new ShadersView(this));
|
||||
}
|
||||
|
||||
static class ShadersView extends View {
|
||||
public static class ShadersView extends View {
|
||||
private BitmapShader mRepeatShader;
|
||||
private BitmapShader mTranslatedShader;
|
||||
private BitmapShader mScaledShader;
|
||||
@@ -53,7 +53,7 @@ public class ShadersActivity extends Activity {
|
||||
private LinearGradient mVertGradient;
|
||||
private Bitmap mTexture;
|
||||
|
||||
ShadersView(Context c) {
|
||||
public ShadersView(Context c) {
|
||||
super(c);
|
||||
|
||||
mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
|
||||
@@ -71,7 +71,7 @@ public class ShadersActivity extends Activity {
|
||||
m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f);
|
||||
m1.postRotate(45, 0, 0);
|
||||
mTranslatedShader.setLocalMatrix(m1);
|
||||
|
||||
|
||||
mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR,
|
||||
Shader.TileMode.MIRROR);
|
||||
Matrix m2 = new Matrix();
|
||||
@@ -85,10 +85,10 @@ public class ShadersActivity extends Activity {
|
||||
m3.postRotate(-90.0f);
|
||||
m3.postTranslate(0.0f, mDrawHeight);
|
||||
mHorGradient.setLocalMatrix(m3);
|
||||
|
||||
|
||||
mDiagGradient = new LinearGradient(0.0f, 0.0f, mDrawWidth / 1.5f, mDrawHeight,
|
||||
Color.BLUE, Color.MAGENTA, Shader.TileMode.CLAMP);
|
||||
|
||||
|
||||
mVertGradient = new LinearGradient(0.0f, 0.0f, 0.0f, mDrawHeight / 2.0f,
|
||||
Color.YELLOW, Color.MAGENTA, Shader.TileMode.MIRROR);
|
||||
|
||||
@@ -107,7 +107,7 @@ public class ShadersActivity extends Activity {
|
||||
|
||||
mPaint.setShader(mRepeatShader);
|
||||
canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
|
||||
|
||||
|
||||
canvas.translate(0.0f, 40.0f + mDrawHeight);
|
||||
mPaint.setShader(mTranslatedShader);
|
||||
canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
|
||||
@@ -124,7 +124,7 @@ public class ShadersActivity extends Activity {
|
||||
|
||||
mPaint.setShader(mHorGradient);
|
||||
canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
|
||||
|
||||
|
||||
canvas.translate(0.0f, 40.0f + mDrawHeight);
|
||||
mPaint.setShader(mDiagGradient);
|
||||
canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
|
||||
@@ -132,7 +132,7 @@ public class ShadersActivity extends Activity {
|
||||
canvas.translate(0.0f, 40.0f + mDrawHeight);
|
||||
mPaint.setShader(mVertGradient);
|
||||
canvas.drawRect(0.0f, 0.0f, mDrawWidth, mDrawHeight, mPaint);
|
||||
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Composite;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.AvoidXfermode
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of AvoidXfermode have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original AvoidXfermode class.
|
||||
*
|
||||
* Because this extends {@link Xfermode_Delegate}, there's no need to use a
|
||||
* {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
|
||||
* {@link Xfermode_Delegate}.
|
||||
*
|
||||
*/
|
||||
public class AvoidXfermode_Delegate extends Xfermode_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Composite getComposite() {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Avoid Xfermodes are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(int opColor, int tolerance, int nativeMode) {
|
||||
AvoidXfermode_Delegate newDelegate = new AvoidXfermode_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import android.graphics.Shader.TileMode;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.BitmapShader
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of BitmapShader have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original BitmapShader class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class BitmapShader_Delegate extends Shader_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
private java.awt.Paint mJavaPaint;
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public java.awt.Paint getJavaPaint() {
|
||||
return mJavaPaint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
// no message since isSupported returns true;
|
||||
return null;
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(int native_bitmap, int shaderTileModeX,
|
||||
int shaderTileModeY) {
|
||||
Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap);
|
||||
assert bitmap != null;
|
||||
if (bitmap == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BitmapShader_Delegate newDelegate = new BitmapShader_Delegate(
|
||||
bitmap.getImage(),
|
||||
Shader_Delegate.getTileMode(shaderTileModeX),
|
||||
Shader_Delegate.getTileMode(shaderTileModeY));
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static int nativePostCreate(int native_shader, int native_bitmap,
|
||||
int shaderTileModeX, int shaderTileModeY) {
|
||||
// pass, not needed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
|
||||
private BitmapShader_Delegate(java.awt.image.BufferedImage image,
|
||||
TileMode tileModeX, TileMode tileModeY) {
|
||||
mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
|
||||
}
|
||||
|
||||
private class BitmapShaderPaint implements java.awt.Paint {
|
||||
private final java.awt.image.BufferedImage mImage;
|
||||
private final TileMode mTileModeX;
|
||||
private final TileMode mTileModeY;
|
||||
|
||||
BitmapShaderPaint(java.awt.image.BufferedImage image,
|
||||
TileMode tileModeX, TileMode tileModeY) {
|
||||
mImage = image;
|
||||
mTileModeX = tileModeX;
|
||||
mTileModeY = tileModeY;
|
||||
}
|
||||
|
||||
public java.awt.PaintContext createContext(
|
||||
java.awt.image.ColorModel colorModel,
|
||||
java.awt.Rectangle deviceBounds,
|
||||
java.awt.geom.Rectangle2D userBounds,
|
||||
java.awt.geom.AffineTransform xform,
|
||||
java.awt.RenderingHints hints) {
|
||||
|
||||
java.awt.geom.AffineTransform canvasMatrix;
|
||||
try {
|
||||
canvasMatrix = xform.createInverse();
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in BitmapShader", e);
|
||||
canvasMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
|
||||
try {
|
||||
localMatrix = localMatrix.createInverse();
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in BitmapShader", e);
|
||||
localMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
|
||||
}
|
||||
|
||||
private class BitmapShaderContext implements java.awt.PaintContext {
|
||||
|
||||
private final java.awt.geom.AffineTransform mCanvasMatrix;
|
||||
private final java.awt.geom.AffineTransform mLocalMatrix;
|
||||
private final java.awt.image.ColorModel mColorModel;
|
||||
|
||||
public BitmapShaderContext(
|
||||
java.awt.geom.AffineTransform canvasMatrix,
|
||||
java.awt.geom.AffineTransform localMatrix,
|
||||
java.awt.image.ColorModel colorModel) {
|
||||
mCanvasMatrix = canvasMatrix;
|
||||
mLocalMatrix = localMatrix;
|
||||
mColorModel = colorModel;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
public java.awt.image.ColorModel getColorModel() {
|
||||
return mColorModel;
|
||||
}
|
||||
|
||||
public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
|
||||
java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(w, h,
|
||||
java.awt.image.BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
int[] data = new int[w*h];
|
||||
|
||||
int index = 0;
|
||||
float[] pt1 = new float[2];
|
||||
float[] pt2 = new float[2];
|
||||
for (int iy = 0 ; iy < h ; iy++) {
|
||||
for (int ix = 0 ; ix < w ; ix++) {
|
||||
// handle the canvas transform
|
||||
pt1[0] = x + ix;
|
||||
pt1[1] = y + iy;
|
||||
mCanvasMatrix.transform(pt1, 0, pt2, 0, 1);
|
||||
|
||||
// handle the local matrix.
|
||||
pt1[0] = pt2[0];
|
||||
pt1[1] = pt2[1];
|
||||
mLocalMatrix.transform(pt1, 0, pt2, 0, 1);
|
||||
|
||||
data[index++] = getColor(pt2[0], pt2[1]);
|
||||
}
|
||||
}
|
||||
|
||||
image.setRGB(0 /*startX*/, 0 /*startY*/, w, h, data, 0 /*offset*/, w /*scansize*/);
|
||||
|
||||
return image.getRaster();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a color for an arbitrary point.
|
||||
*/
|
||||
private int getColor(float fx, float fy) {
|
||||
int x = getCoordinate(Math.round(fx), mImage.getWidth(), mTileModeX);
|
||||
int y = getCoordinate(Math.round(fy), mImage.getHeight(), mTileModeY);
|
||||
|
||||
return mImage.getRGB(x, y);
|
||||
}
|
||||
|
||||
private int getCoordinate(int i, int size, TileMode mode) {
|
||||
if (i < 0) {
|
||||
switch (mode) {
|
||||
case CLAMP:
|
||||
i = 0;
|
||||
break;
|
||||
case REPEAT:
|
||||
i = size - 1 - (-i % size);
|
||||
break;
|
||||
case MIRROR:
|
||||
// this is the same as the positive side, just make the value positive
|
||||
// first.
|
||||
i = -i;
|
||||
int count = i / size;
|
||||
i = i % size;
|
||||
|
||||
if ((count % 2) == 1) {
|
||||
i = size - 1 - i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (i >= size) {
|
||||
switch (mode) {
|
||||
case CLAMP:
|
||||
i = size - 1;
|
||||
break;
|
||||
case REPEAT:
|
||||
i = i % size;
|
||||
break;
|
||||
case MIRROR:
|
||||
int count = i / size;
|
||||
i = i % size;
|
||||
|
||||
if ((count % 2) == 1) {
|
||||
i = size - 1 - i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
public int getTransparency() {
|
||||
return java.awt.Paint.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ import javax.imageio.ImageIO;
|
||||
* @see DelegateManager
|
||||
*
|
||||
*/
|
||||
public class Bitmap_Delegate {
|
||||
public final class Bitmap_Delegate {
|
||||
|
||||
// ---- delegate manager ----
|
||||
private static final DelegateManager<Bitmap_Delegate> sManager =
|
||||
|
||||
@@ -23,12 +23,14 @@ import com.android.layoutlib.bridge.impl.GcSnapshot;
|
||||
import android.graphics.Paint_Delegate.FontInfo;
|
||||
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;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
@@ -47,7 +49,7 @@ import java.util.List;
|
||||
* @see DelegateManager
|
||||
*
|
||||
*/
|
||||
public class Canvas_Delegate {
|
||||
public final class Canvas_Delegate {
|
||||
|
||||
// ---- delegate manager ----
|
||||
private static final DelegateManager<Canvas_Delegate> sManager =
|
||||
@@ -55,6 +57,10 @@ public class Canvas_Delegate {
|
||||
|
||||
// ---- delegate helper data ----
|
||||
|
||||
private interface Drawable {
|
||||
void draw(Graphics2D graphics, Paint_Delegate paint);
|
||||
}
|
||||
|
||||
// ---- delegate data ----
|
||||
private BufferedImage mBufferedImage;
|
||||
private GcSnapshot mSnapshot = new GcSnapshot();
|
||||
@@ -403,9 +409,9 @@ public class Canvas_Delegate {
|
||||
|
||||
if (matrixDelegate.hasPerspective()) {
|
||||
assert false;
|
||||
Bridge.getLog().warning(null,
|
||||
Bridge.getLog().fidelityWarning(null,
|
||||
"android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
|
||||
"supports affine transformations in the Layout Preview.");
|
||||
"supports affine transformations in the Layout Preview.", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +528,10 @@ public class Canvas_Delegate {
|
||||
// set the color
|
||||
graphics.setColor(new Color(color, true /*alpha*/));
|
||||
|
||||
setModeInGraphics(graphics, mode);
|
||||
Composite composite = PorterDuffXfermode_Delegate.getComposite(mode);
|
||||
if (composite != null) {
|
||||
graphics.setComposite(composite);
|
||||
}
|
||||
|
||||
graphics.fillRect(0, 0, canvasDelegate.mBufferedImage.getWidth(),
|
||||
canvasDelegate.mBufferedImage.getHeight());
|
||||
@@ -709,8 +718,28 @@ public class Canvas_Delegate {
|
||||
|
||||
/*package*/ static void native_drawPath(int nativeCanvas, int path,
|
||||
int paint) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
draw(nativeCanvas, paint, new Drawable() {
|
||||
public void draw(Graphics2D graphics, Paint_Delegate paint) {
|
||||
Shape shape = pathDelegate.getJavaShape();
|
||||
int style = paint.getStyle();
|
||||
|
||||
if (style == Paint.Style.FILL.nativeInt ||
|
||||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
|
||||
graphics.fill(shape);
|
||||
}
|
||||
|
||||
if (style == Paint.Style.STROKE.nativeInt ||
|
||||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
|
||||
graphics.draw(shape);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
|
||||
@@ -719,8 +748,20 @@ public class Canvas_Delegate {
|
||||
int canvasDensity,
|
||||
int screenDensity,
|
||||
int bitmapDensity) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
// get the delegate from the native int.
|
||||
Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
|
||||
if (bitmapDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedImage image = bitmapDelegate.getImage();
|
||||
float right = left + image.getWidth();
|
||||
float bottom = top + image.getHeight();
|
||||
|
||||
drawBitmap(nativeCanvas, image, nativePaintOrZero,
|
||||
0, 0, image.getWidth(), image.getHeight(),
|
||||
(int)left, (int)top, (int)right, (int)bottom);
|
||||
}
|
||||
|
||||
/*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
|
||||
@@ -998,6 +1039,34 @@ public class Canvas_Delegate {
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
|
||||
/**
|
||||
* Executes a {@link Drawable} with a given canvas and paint.
|
||||
*/
|
||||
private static void draw(int nCanvas, int nPaint, Drawable runnable) {
|
||||
// get the delegate from the native int.
|
||||
Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
|
||||
if (canvasDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
|
||||
if (paintDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
// get a Graphics2D object configured with the drawing parameters.
|
||||
Graphics2D g = canvasDelegate.createCustomGraphics(paintDelegate);
|
||||
|
||||
try {
|
||||
runnable.draw(g, paintDelegate);
|
||||
} finally {
|
||||
// dispose Graphics2D object
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private Canvas_Delegate(BufferedImage image) {
|
||||
setBitmap(image);
|
||||
}
|
||||
@@ -1069,18 +1138,23 @@ public class Canvas_Delegate {
|
||||
boolean useColorPaint = true;
|
||||
|
||||
// get the shader first, as it'll replace the color if it can be used it.
|
||||
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;
|
||||
} else {
|
||||
Bridge.getLog().warning(null,
|
||||
String.format(
|
||||
"Shader '%1$s' is not supported in the Layout Preview.",
|
||||
shaderDelegate.getClass().getCanonicalName()));
|
||||
int nativeShader = paint.getShader();
|
||||
if (nativeShader > 0) {
|
||||
Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(nativeShader);
|
||||
assert shaderDelegate != null;
|
||||
if (shaderDelegate != null) {
|
||||
if (shaderDelegate.isSupported()) {
|
||||
java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
|
||||
assert shaderPaint != null;
|
||||
if (shaderPaint != null) {
|
||||
g.setPaint(shaderPaint);
|
||||
useColorPaint = false;
|
||||
}
|
||||
} else {
|
||||
Bridge.getLog().fidelityWarning(null,
|
||||
shaderDelegate.getSupportMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1092,19 +1166,30 @@ public class Canvas_Delegate {
|
||||
if (style == Paint.Style.STROKE.nativeInt ||
|
||||
style == Paint.Style.FILL_AND_STROKE.nativeInt) {
|
||||
|
||||
PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(
|
||||
paint.getPathEffect());
|
||||
boolean customStroke = false;
|
||||
|
||||
if (effectDelegate instanceof DashPathEffect_Delegate) {
|
||||
DashPathEffect_Delegate dpe = (DashPathEffect_Delegate)effectDelegate;
|
||||
g.setStroke(new BasicStroke(
|
||||
paint.getStrokeWidth(),
|
||||
paint.getJavaCap(),
|
||||
paint.getJavaJoin(),
|
||||
paint.getStrokeMiter(),
|
||||
dpe.getIntervals(),
|
||||
dpe.getPhase()));
|
||||
} else {
|
||||
int pathEffect = paint.getPathEffect();
|
||||
if (pathEffect > 0) {
|
||||
PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(pathEffect);
|
||||
assert effectDelegate != null;
|
||||
if (effectDelegate != null) {
|
||||
if (effectDelegate.isSupported()) {
|
||||
Stroke stroke = effectDelegate.getStroke(paint);
|
||||
assert stroke != null;
|
||||
if (stroke != null) {
|
||||
g.setStroke(stroke);
|
||||
customStroke = true;
|
||||
}
|
||||
} else {
|
||||
Bridge.getLog().fidelityWarning(null,
|
||||
effectDelegate.getSupportMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if no custom stroke as been set, set the default one.
|
||||
if (customStroke == false) {
|
||||
g.setStroke(new BasicStroke(
|
||||
paint.getStrokeWidth(),
|
||||
paint.getJavaCap(),
|
||||
@@ -1113,87 +1198,28 @@ public class Canvas_Delegate {
|
||||
}
|
||||
}
|
||||
|
||||
Xfermode_Delegate xfermodeDelegate = Xfermode_Delegate.getDelegate(paint.getXfermode());
|
||||
if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
|
||||
int mode = ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
|
||||
|
||||
setModeInGraphics(g, mode);
|
||||
} else {
|
||||
// default mode is src_over
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
|
||||
|
||||
// if xfermode wasn't null, then it's something we don't support. log it.
|
||||
int xfermode = paint.getXfermode();
|
||||
if (xfermode > 0) {
|
||||
Xfermode_Delegate xfermodeDelegate = Xfermode_Delegate.getDelegate(paint.getXfermode());
|
||||
assert xfermodeDelegate != null;
|
||||
if (xfermodeDelegate != null) {
|
||||
assert false;
|
||||
Bridge.getLog().warning(null,
|
||||
String.format(
|
||||
"Xfermode '%1$s' is not supported in the Layout Preview.",
|
||||
xfermodeDelegate.getClass().getCanonicalName()));
|
||||
if (xfermodeDelegate.isSupported()) {
|
||||
Composite composite = xfermodeDelegate.getComposite();
|
||||
assert composite != null;
|
||||
if (composite != null) {
|
||||
g.setComposite(composite);
|
||||
}
|
||||
} else {
|
||||
Bridge.getLog().fidelityWarning(null,
|
||||
xfermodeDelegate.getSupportMessage(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
private static void setModeInGraphics(Graphics2D g, int mode) {
|
||||
for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
|
||||
if (m.nativeInt == mode) {
|
||||
setModeInGraphics(g, m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode) {
|
||||
switch (mode) {
|
||||
case CLEAR:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f /*alpha*/));
|
||||
break;
|
||||
case DARKEN:
|
||||
break;
|
||||
case DST:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, 1.0f /*alpha*/));
|
||||
break;
|
||||
case DST_ATOP:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1.0f /*alpha*/));
|
||||
break;
|
||||
case DST_IN:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0f /*alpha*/));
|
||||
break;
|
||||
case DST_OUT:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1.0f /*alpha*/));
|
||||
break;
|
||||
case DST_OVER:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f /*alpha*/));
|
||||
break;
|
||||
case LIGHTEN:
|
||||
break;
|
||||
case MULTIPLY:
|
||||
break;
|
||||
case SCREEN:
|
||||
break;
|
||||
case SRC:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f /*alpha*/));
|
||||
break;
|
||||
case SRC_ATOP:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f /*alpha*/));
|
||||
break;
|
||||
case SRC_IN:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f /*alpha*/));
|
||||
break;
|
||||
case SRC_OUT:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1.0f /*alpha*/));
|
||||
break;
|
||||
case SRC_OVER:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f /*alpha*/));
|
||||
break;
|
||||
case XOR:
|
||||
g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, 1.0f /*alpha*/));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void drawBitmap(
|
||||
int nativeCanvas,
|
||||
BufferedImage image,
|
||||
@@ -1228,6 +1254,7 @@ public class Canvas_Delegate {
|
||||
Paint_Delegate paintDelegate,
|
||||
int sleft, int stop, int sright, int sbottom,
|
||||
int dleft, int dtop, int dright, int dbottom) {
|
||||
//FIXME add support for canvas, screen and bitmap densities.
|
||||
|
||||
Graphics2D g = canvasDelegate.getGcSnapshot().create();
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.ComposePathEffect
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of ComposePathEffect have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original ComposePathEffect class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class ComposePathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Stroke getStroke(Paint_Delegate paint) {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Composte Path Effects are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(int outerpe, int innerpe) {
|
||||
ComposePathEffect_Delegate newDelegate = new ComposePathEffect_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Paint;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.ComposeShader
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of ComposeShader have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original ComposeShader class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class ComposeShader_Delegate extends Shader_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Paint getJavaPaint() {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Compose Shader are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate1(int native_shaderA, int native_shaderB,
|
||||
int native_mode) {
|
||||
// FIXME not supported yet.
|
||||
ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static int nativeCreate2(int native_shaderA, int native_shaderB,
|
||||
int porterDuffMode) {
|
||||
// FIXME not supported yet.
|
||||
ComposeShader_Delegate newDelegate = new ComposeShader_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static int nativePostCreate1(int native_shader, int native_skiaShaderA,
|
||||
int native_skiaShaderB, int native_mode) {
|
||||
// pass, not needed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*package*/ static int nativePostCreate2(int native_shader, int native_skiaShaderA,
|
||||
int native_skiaShaderB, int porterDuffMode) {
|
||||
// pass, not needed.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.CornerPathEffect
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of CornerPathEffect have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original CornerPathEffect class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class CornerPathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Stroke getStroke(Paint_Delegate paint) {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Corner Path Effects are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(float radius) {
|
||||
CornerPathEffect_Delegate newDelegate = new CornerPathEffect_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -18,6 +18,9 @@ package android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.DashPathEffect
|
||||
*
|
||||
@@ -32,8 +35,10 @@ import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
* {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
|
||||
* {@link PathEffect_Delegate}.
|
||||
*
|
||||
* @see PathEffect_Delegate
|
||||
*
|
||||
*/
|
||||
public class DashPathEffect_Delegate extends PathEffect_Delegate {
|
||||
public final class DashPathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
@@ -42,12 +47,26 @@ public class DashPathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
public float[] getIntervals() {
|
||||
return mIntervals;
|
||||
@Override
|
||||
public Stroke getStroke(Paint_Delegate paint) {
|
||||
return new BasicStroke(
|
||||
paint.getStrokeWidth(),
|
||||
paint.getJavaCap(),
|
||||
paint.getJavaJoin(),
|
||||
paint.getStrokeMiter(),
|
||||
mIntervals,
|
||||
mPhase);
|
||||
}
|
||||
|
||||
public float getPhase() {
|
||||
return mPhase;
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
// no message since isSupported returns true;
|
||||
return null;
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.DiscretePathEffect
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of DiscretePathEffect have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original DiscretePathEffect class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class DiscretePathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Stroke getStroke(Paint_Delegate paint) {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Discrete Path Effects are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(float length, float deviation) {
|
||||
DiscretePathEffect_Delegate newDelegate = new DiscretePathEffect_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -26,6 +26,18 @@ public abstract class Gradient_Delegate extends Shader_Delegate {
|
||||
protected final int[] mColors;
|
||||
protected final float[] mPositions;
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
// all gradient shaders are supported.
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
// all gradient shaders are supported, no need for a gradient support
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the base shader and do some basic test on the parameters.
|
||||
*
|
||||
|
||||
@@ -21,10 +21,6 @@ import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import android.graphics.Shader.TileMode;
|
||||
|
||||
import java.awt.Paint;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.NoninvertibleTransformException;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.LinearGradient
|
||||
*
|
||||
@@ -41,7 +37,7 @@ import java.awt.geom.NoninvertibleTransformException;
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class LinearGradient_Delegate extends Gradient_Delegate {
|
||||
public final class LinearGradient_Delegate extends Gradient_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
private java.awt.Paint mJavaPaint;
|
||||
@@ -49,7 +45,7 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Paint getJavaPaint() {
|
||||
public java.awt.Paint getJavaPaint() {
|
||||
return mJavaPaint;
|
||||
}
|
||||
|
||||
@@ -58,17 +54,8 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
|
||||
/*package*/ static int nativeCreate1(LinearGradient thisGradient,
|
||||
float x0, float y0, float x1, float y1,
|
||||
int colors[], float positions[], int tileMode) {
|
||||
// figure out the tile
|
||||
TileMode tile = null;
|
||||
for (TileMode tm : TileMode.values()) {
|
||||
if (tm.nativeInt == tileMode) {
|
||||
tile = tm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LinearGradient_Delegate newDelegate = new LinearGradient_Delegate(x0, y0, x1, y1,
|
||||
colors, positions, tile);
|
||||
colors, positions, Shader_Delegate.getTileMode(tileMode));
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
/*package*/ static int nativeCreate2(LinearGradient thisGradient,
|
||||
@@ -144,20 +131,20 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
|
||||
java.awt.RenderingHints hints) {
|
||||
precomputeGradientColors();
|
||||
|
||||
AffineTransform canvasMatrix;
|
||||
java.awt.geom.AffineTransform canvasMatrix;
|
||||
try {
|
||||
canvasMatrix = xform.createInverse();
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in LinearGradient", e);
|
||||
canvasMatrix = new AffineTransform();
|
||||
canvasMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
AffineTransform localMatrix = getLocalMatrix();
|
||||
java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
|
||||
try {
|
||||
localMatrix = localMatrix.createInverse();
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in LinearGradient", e);
|
||||
localMatrix = new AffineTransform();
|
||||
localMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
return new LinearGradientPaintContext(canvasMatrix, localMatrix, colorModel);
|
||||
@@ -165,12 +152,14 @@ public class LinearGradient_Delegate extends Gradient_Delegate {
|
||||
|
||||
private class LinearGradientPaintContext implements java.awt.PaintContext {
|
||||
|
||||
private final AffineTransform mCanvasMatrix;
|
||||
private final AffineTransform mLocalMatrix;
|
||||
private final java.awt.geom.AffineTransform mCanvasMatrix;
|
||||
private final java.awt.geom.AffineTransform mLocalMatrix;
|
||||
private final java.awt.image.ColorModel mColorModel;
|
||||
|
||||
public LinearGradientPaintContext(AffineTransform canvasMatrix,
|
||||
AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
|
||||
private LinearGradientPaintContext(
|
||||
java.awt.geom.AffineTransform canvasMatrix,
|
||||
java.awt.geom.AffineTransform localMatrix,
|
||||
java.awt.image.ColorModel colorModel) {
|
||||
mCanvasMatrix = canvasMatrix;
|
||||
mLocalMatrix = localMatrix;
|
||||
mColorModel = colorModel;
|
||||
|
||||
@@ -1052,6 +1052,4 @@ public final class Matrix_Delegate {
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ import java.util.Map;
|
||||
* around to map int to instance of the delegate.
|
||||
*
|
||||
*/
|
||||
public class NinePatch_Delegate {
|
||||
public final class NinePatch_Delegate {
|
||||
|
||||
/**
|
||||
* Cache map for {@link NinePatchChunk}.
|
||||
|
||||
@@ -1,611 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 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 android.graphics;
|
||||
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* The Path class encapsulates compound (multiple contour) geometric paths
|
||||
* consisting of straight line segments, quadratic curves, and cubic curves.
|
||||
* It can be drawn with canvas.drawPath(path, paint), either filled or stroked
|
||||
* (based on the paint's Style), or it can be used for clipping or to draw
|
||||
* text on a path.
|
||||
*/
|
||||
public class Path {
|
||||
|
||||
private FillType mFillType = FillType.WINDING;
|
||||
private GeneralPath mPath = new GeneralPath();
|
||||
|
||||
private float mLastX = 0;
|
||||
private float mLastY = 0;
|
||||
|
||||
//---------- Custom methods ----------
|
||||
|
||||
public Shape getAwtShape() {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
//----------
|
||||
|
||||
/**
|
||||
* Create an empty path
|
||||
*/
|
||||
public Path() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new path, copying the contents from the src path.
|
||||
*
|
||||
* @param src The path to copy from when initializing the new path
|
||||
*/
|
||||
public Path(Path src) {
|
||||
mPath.append(src.mPath, false /* connect */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any lines and curves from the path, making it empty.
|
||||
* This does NOT change the fill-type setting.
|
||||
*/
|
||||
public void reset() {
|
||||
mPath = new GeneralPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewinds the path: clears any lines and curves from the path but
|
||||
* keeps the internal data structure for faster reuse.
|
||||
*/
|
||||
public void rewind() {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/** Replace the contents of this with the contents of src.
|
||||
*/
|
||||
public void set(Path src) {
|
||||
mPath.append(src.mPath, false /* connect */);
|
||||
}
|
||||
|
||||
/** Enum for the ways a path may be filled
|
||||
*/
|
||||
public enum FillType {
|
||||
// these must match the values in SkPath.h
|
||||
WINDING (GeneralPath.WIND_NON_ZERO, false),
|
||||
EVEN_ODD (GeneralPath.WIND_EVEN_ODD, false),
|
||||
INVERSE_WINDING (GeneralPath.WIND_NON_ZERO, true),
|
||||
INVERSE_EVEN_ODD(GeneralPath.WIND_EVEN_ODD, true);
|
||||
|
||||
FillType(int rule, boolean inverse) {
|
||||
this.rule = rule;
|
||||
this.inverse = inverse;
|
||||
}
|
||||
|
||||
final int rule;
|
||||
final boolean inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path's fill type. This defines how "inside" is
|
||||
* computed. The default value is WINDING.
|
||||
*
|
||||
* @return the path's fill type
|
||||
*/
|
||||
public FillType getFillType() {
|
||||
return mFillType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path's fill type. This defines how "inside" is computed.
|
||||
*
|
||||
* @param ft The new fill type for this path
|
||||
*/
|
||||
public void setFillType(FillType ft) {
|
||||
mFillType = ft;
|
||||
mPath.setWindingRule(ft.rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filltype is one of the INVERSE variants
|
||||
*
|
||||
* @return true if the filltype is one of the INVERSE variants
|
||||
*/
|
||||
public boolean isInverseFillType() {
|
||||
return mFillType.inverse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the INVERSE state of the filltype
|
||||
*/
|
||||
public void toggleInverseFillType() {
|
||||
switch (mFillType) {
|
||||
case WINDING:
|
||||
mFillType = FillType.INVERSE_WINDING;
|
||||
break;
|
||||
case EVEN_ODD:
|
||||
mFillType = FillType.INVERSE_EVEN_ODD;
|
||||
break;
|
||||
case INVERSE_WINDING:
|
||||
mFillType = FillType.WINDING;
|
||||
break;
|
||||
case INVERSE_EVEN_ODD:
|
||||
mFillType = FillType.EVEN_ODD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the path is empty (contains no lines or curves)
|
||||
*
|
||||
* @return true if the path is empty (contains no lines or curves)
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return mPath.getCurrentPoint() == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the path specifies a rectangle. If so, and if rect is
|
||||
* not null, set rect to the bounds of the path. If the path does not
|
||||
* specify a rectangle, return false and ignore rect.
|
||||
*
|
||||
* @param rect If not null, returns the bounds of the path if it specifies
|
||||
* a rectangle
|
||||
* @return true if the path specifies a rectangle
|
||||
*/
|
||||
public boolean isRect(RectF rect) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the bounds of the path, and write the answer into bounds. If the
|
||||
* path contains 0 or 1 points, the bounds is set to (0,0,0,0)
|
||||
*
|
||||
* @param bounds Returns the computed bounds of the path
|
||||
* @param exact If true, return the exact (but slower) bounds, else return
|
||||
* just the bounds of all control points
|
||||
*/
|
||||
public void computeBounds(RectF bounds, boolean exact) {
|
||||
Rectangle2D rect = mPath.getBounds2D();
|
||||
bounds.left = (float)rect.getMinX();
|
||||
bounds.right = (float)rect.getMaxX();
|
||||
bounds.top = (float)rect.getMinY();
|
||||
bounds.bottom = (float)rect.getMaxY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hint to the path to prepare for adding more points. This can allow the
|
||||
* path to more efficiently allocate its storage.
|
||||
*
|
||||
* @param extraPtCount The number of extra points that may be added to this
|
||||
* path
|
||||
*/
|
||||
public void incReserve(int extraPtCount) {
|
||||
// pass
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the beginning of the next contour to the point (x,y).
|
||||
*
|
||||
* @param x The x-coordinate of the start of a new contour
|
||||
* @param y The y-coordinate of the start of a new contour
|
||||
*/
|
||||
public void moveTo(float x, float y) {
|
||||
mPath.moveTo(mLastX = x, mLastY = y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the beginning of the next contour relative to the last point on the
|
||||
* previous contour. If there is no previous contour, this is treated the
|
||||
* same as moveTo().
|
||||
*
|
||||
* @param dx The amount to add to the x-coordinate of the end of the
|
||||
* previous contour, to specify the start of a new contour
|
||||
* @param dy The amount to add to the y-coordinate of the end of the
|
||||
* previous contour, to specify the start of a new contour
|
||||
*/
|
||||
public void rMoveTo(float dx, float dy) {
|
||||
dx += mLastX;
|
||||
dy += mLastY;
|
||||
mPath.moveTo(mLastX = dx, mLastY = dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a line from the last point to the specified point (x,y).
|
||||
* If no moveTo() call has been made for this contour, the first point is
|
||||
* automatically set to (0,0).
|
||||
*
|
||||
* @param x The x-coordinate of the end of a line
|
||||
* @param y The y-coordinate of the end of a line
|
||||
*/
|
||||
public void lineTo(float x, float y) {
|
||||
mPath.lineTo(mLastX = x, mLastY = y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as lineTo, but the coordinates are considered relative to the last
|
||||
* point on this contour. If there is no previous point, then a moveTo(0,0)
|
||||
* is inserted automatically.
|
||||
*
|
||||
* @param dx The amount to add to the x-coordinate of the previous point on
|
||||
* this contour, to specify a line
|
||||
* @param dy The amount to add to the y-coordinate of the previous point on
|
||||
* this contour, to specify a line
|
||||
*/
|
||||
public void rLineTo(float dx, float dy) {
|
||||
if (isEmpty()) {
|
||||
mPath.moveTo(mLastX = 0, mLastY = 0);
|
||||
}
|
||||
dx += mLastX;
|
||||
dy += mLastY;
|
||||
mPath.lineTo(mLastX = dx, mLastY = dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a quadratic bezier from the last point, approaching control point
|
||||
* (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
|
||||
* this contour, the first point is automatically set to (0,0).
|
||||
*
|
||||
* @param x1 The x-coordinate of the control point on a quadratic curve
|
||||
* @param y1 The y-coordinate of the control point on a quadratic curve
|
||||
* @param x2 The x-coordinate of the end point on a quadratic curve
|
||||
* @param y2 The y-coordinate of the end point on a quadratic curve
|
||||
*/
|
||||
public void quadTo(float x1, float y1, float x2, float y2) {
|
||||
mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as quadTo, but the coordinates are considered relative to the last
|
||||
* point on this contour. If there is no previous point, then a moveTo(0,0)
|
||||
* is inserted automatically.
|
||||
*
|
||||
* @param dx1 The amount to add to the x-coordinate of the last point on
|
||||
* this contour, for the control point of a quadratic curve
|
||||
* @param dy1 The amount to add to the y-coordinate of the last point on
|
||||
* this contour, for the control point of a quadratic curve
|
||||
* @param dx2 The amount to add to the x-coordinate of the last point on
|
||||
* this contour, for the end point of a quadratic curve
|
||||
* @param dy2 The amount to add to the y-coordinate of the last point on
|
||||
* this contour, for the end point of a quadratic curve
|
||||
*/
|
||||
public void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
|
||||
if (isEmpty()) {
|
||||
mPath.moveTo(mLastX = 0, mLastY = 0);
|
||||
}
|
||||
dx1 += mLastX;
|
||||
dy1 += mLastY;
|
||||
dx2 += mLastX;
|
||||
dy2 += mLastY;
|
||||
mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cubic bezier from the last point, approaching control points
|
||||
* (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
|
||||
* made for this contour, the first point is automatically set to (0,0).
|
||||
*
|
||||
* @param x1 The x-coordinate of the 1st control point on a cubic curve
|
||||
* @param y1 The y-coordinate of the 1st control point on a cubic curve
|
||||
* @param x2 The x-coordinate of the 2nd control point on a cubic curve
|
||||
* @param y2 The y-coordinate of the 2nd control point on a cubic curve
|
||||
* @param x3 The x-coordinate of the end point on a cubic curve
|
||||
* @param y3 The y-coordinate of the end point on a cubic curve
|
||||
*/
|
||||
public void cubicTo(float x1, float y1, float x2, float y2,
|
||||
float x3, float y3) {
|
||||
mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as cubicTo, but the coordinates are considered relative to the
|
||||
* current point on this contour. If there is no previous point, then a
|
||||
* moveTo(0,0) is inserted automatically.
|
||||
*/
|
||||
public void rCubicTo(float dx1, float dy1, float dx2, float dy2,
|
||||
float dx3, float dy3) {
|
||||
if (isEmpty()) {
|
||||
mPath.moveTo(mLastX = 0, mLastY = 0);
|
||||
}
|
||||
dx1 += mLastX;
|
||||
dy1 += mLastY;
|
||||
dx2 += mLastX;
|
||||
dy2 += mLastY;
|
||||
dx3 += mLastX;
|
||||
dy3 += mLastY;
|
||||
mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the specified arc to the path as a new contour. If the start of
|
||||
* the path is different from the path's current last point, then an
|
||||
* automatic lineTo() is added to connect the current contour to the
|
||||
* start of the arc. However, if the path is empty, then we call moveTo()
|
||||
* with the first point of the arc. The sweep angle is tread mod 360.
|
||||
*
|
||||
* @param oval The bounds of oval defining shape and size of the arc
|
||||
* @param startAngle Starting angle (in degrees) where the arc begins
|
||||
* @param sweepAngle Sweep angle (in degrees) measured clockwise, treated
|
||||
* mod 360.
|
||||
* @param forceMoveTo If true, always begin a new contour with the arc
|
||||
*/
|
||||
public void arcTo(RectF oval, float startAngle, float sweepAngle,
|
||||
boolean forceMoveTo) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the specified arc to the path as a new contour. If the start of
|
||||
* the path is different from the path's current last point, then an
|
||||
* automatic lineTo() is added to connect the current contour to the
|
||||
* start of the arc. However, if the path is empty, then we call moveTo()
|
||||
* with the first point of the arc.
|
||||
*
|
||||
* @param oval The bounds of oval defining shape and size of the arc
|
||||
* @param startAngle Starting angle (in degrees) where the arc begins
|
||||
* @param sweepAngle Sweep angle (in degrees) measured clockwise
|
||||
*/
|
||||
public void arcTo(RectF oval, float startAngle, float sweepAngle) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current contour. If the current point is not equal to the
|
||||
* first point of the contour, a line segment is automatically added.
|
||||
*/
|
||||
public void close() {
|
||||
mPath.closePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how closed shapes (e.g. rects, ovals) are oriented when they
|
||||
* are added to a path.
|
||||
*/
|
||||
public enum Direction {
|
||||
/** clockwise */
|
||||
CW (0), // must match enum in SkPath.h
|
||||
/** counter-clockwise */
|
||||
CCW (1); // must match enum in SkPath.h
|
||||
|
||||
Direction(int ni) {
|
||||
nativeInt = ni;
|
||||
}
|
||||
final int nativeInt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed rectangle contour to the path
|
||||
*
|
||||
* @param rect The rectangle to add as a closed contour to the path
|
||||
* @param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
public void addRect(RectF rect, Direction dir) {
|
||||
if (rect == null) {
|
||||
throw new NullPointerException("need rect parameter");
|
||||
}
|
||||
|
||||
addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed rectangle contour to the path
|
||||
*
|
||||
* @param left The left side of a rectangle to add to the path
|
||||
* @param top The top of a rectangle to add to the path
|
||||
* @param right The right side of a rectangle to add to the path
|
||||
* @param bottom The bottom of a rectangle to add to the path
|
||||
* @param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
public void addRect(float left, float top, float right, float bottom,
|
||||
Direction dir) {
|
||||
moveTo(left, top);
|
||||
|
||||
switch (dir) {
|
||||
case CW:
|
||||
lineTo(right, top);
|
||||
lineTo(right, bottom);
|
||||
lineTo(left, bottom);
|
||||
break;
|
||||
case CCW:
|
||||
lineTo(left, bottom);
|
||||
lineTo(right, bottom);
|
||||
lineTo(right, top);
|
||||
break;
|
||||
}
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed oval contour to the path
|
||||
*
|
||||
* @param oval The bounds of the oval to add as a closed contour to the path
|
||||
* @param dir The direction to wind the oval's contour
|
||||
*/
|
||||
public void addOval(RectF oval, Direction dir) {
|
||||
if (oval == null) {
|
||||
throw new NullPointerException("need oval parameter");
|
||||
}
|
||||
|
||||
// FIXME Need to support direction
|
||||
Ellipse2D ovalShape = new Ellipse2D.Float(oval.left, oval.top, oval.width(), oval.height());
|
||||
|
||||
mPath.append(ovalShape, false /* connect */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed circle contour to the path
|
||||
*
|
||||
* @param x The x-coordinate of the center of a circle to add to the path
|
||||
* @param y The y-coordinate of the center of a circle to add to the path
|
||||
* @param radius The radius of a circle to add to the path
|
||||
* @param dir The direction to wind the circle's contour
|
||||
*/
|
||||
public void addCircle(float x, float y, float radius, Direction dir) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specified arc to the path as a new contour.
|
||||
*
|
||||
* @param oval The bounds of oval defining the shape and size of the arc
|
||||
* @param startAngle Starting angle (in degrees) where the arc begins
|
||||
* @param sweepAngle Sweep angle (in degrees) measured clockwise
|
||||
*/
|
||||
public void addArc(RectF oval, float startAngle, float sweepAngle) {
|
||||
if (oval == null) {
|
||||
throw new NullPointerException("need oval parameter");
|
||||
}
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed round-rectangle contour to the path
|
||||
*
|
||||
* @param rect The bounds of a round-rectangle to add to the path
|
||||
* @param rx The x-radius of the rounded corners on the round-rectangle
|
||||
* @param ry The y-radius of the rounded corners on the round-rectangle
|
||||
* @param dir The direction to wind the round-rectangle's contour
|
||||
*/
|
||||
public void addRoundRect(RectF rect, float rx, float ry, Direction dir) {
|
||||
if (rect == null) {
|
||||
throw new NullPointerException("need rect parameter");
|
||||
}
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed round-rectangle contour to the path. Each corner receives
|
||||
* two radius values [X, Y]. The corners are ordered top-left, top-right,
|
||||
* bottom-right, bottom-left
|
||||
*
|
||||
* @param rect The bounds of a round-rectangle to add to the path
|
||||
* @param radii Array of 8 values, 4 pairs of [X,Y] radii
|
||||
* @param dir The direction to wind the round-rectangle's contour
|
||||
*/
|
||||
public void addRoundRect(RectF rect, float[] radii, Direction dir) {
|
||||
if (rect == null) {
|
||||
throw new NullPointerException("need rect parameter");
|
||||
}
|
||||
if (radii.length < 8) {
|
||||
throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values");
|
||||
}
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a copy of src to the path, offset by (dx,dy)
|
||||
*
|
||||
* @param src The path to add as a new contour
|
||||
* @param dx The amount to translate the path in X as it is added
|
||||
*/
|
||||
public void addPath(Path src, float dx, float dy) {
|
||||
PathIterator iterator = src.mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
|
||||
mPath.append(iterator, false /* connect */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a copy of src to the path
|
||||
*
|
||||
* @param src The path that is appended to the current path
|
||||
*/
|
||||
public void addPath(Path src) {
|
||||
addPath(src, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a copy of src to the path, transformed by matrix
|
||||
*
|
||||
* @param src The path to add as a new contour
|
||||
*/
|
||||
public void addPath(Path src, Matrix matrix) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset the path by (dx,dy), returning true on success
|
||||
*
|
||||
* @param dx The amount in the X direction to offset the entire path
|
||||
* @param dy The amount in the Y direction to offset the entire path
|
||||
* @param dst The translated path is written here. If this is null, then
|
||||
* the original path is modified.
|
||||
*/
|
||||
public void offset(float dx, float dy, Path dst) {
|
||||
GeneralPath newPath = new GeneralPath();
|
||||
|
||||
PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
|
||||
|
||||
newPath.append(iterator, false /* connect */);
|
||||
|
||||
if (dst != null) {
|
||||
dst.mPath = newPath;
|
||||
} else {
|
||||
mPath = newPath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset the path by (dx,dy), returning true on success
|
||||
*
|
||||
* @param dx The amount in the X direction to offset the entire path
|
||||
* @param dy The amount in the Y direction to offset the entire path
|
||||
*/
|
||||
public void offset(float dx, float dy) {
|
||||
offset(dx, dy, null /* dst */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last point of the path.
|
||||
*
|
||||
* @param dx The new X coordinate for the last point
|
||||
* @param dy The new Y coordinate for the last point
|
||||
*/
|
||||
public void setLastPoint(float dx, float dy) {
|
||||
mLastX = dx;
|
||||
mLastY = dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the points in this path by matrix, and write the answer
|
||||
* into dst. If dst is null, then the the original path is modified.
|
||||
*
|
||||
* @param matrix The matrix to apply to the path
|
||||
* @param dst The transformed path is written here. If dst is null,
|
||||
* then the the original path is modified
|
||||
*/
|
||||
public void transform(Matrix matrix, Path dst) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the points in this path by matrix.
|
||||
*
|
||||
* @param matrix The matrix to apply to the path
|
||||
*/
|
||||
public void transform(Matrix matrix) {
|
||||
transform(matrix, null /* dst */);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.PathDashPathEffect
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of PathDashPathEffect have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original PathDashPathEffect class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class PathDashPathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Stroke getStroke(Paint_Delegate paint) {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Path Dash Path Effects are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(int native_path, float advance, float phase,
|
||||
int native_style) {
|
||||
PathDashPathEffect_Delegate newDelegate = new PathDashPathEffect_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -18,6 +18,8 @@ package android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.PathEffect
|
||||
*
|
||||
@@ -33,7 +35,7 @@ import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
* @see DelegateManager
|
||||
*
|
||||
*/
|
||||
public class PathEffect_Delegate {
|
||||
public abstract class PathEffect_Delegate {
|
||||
|
||||
// ---- delegate manager ----
|
||||
protected static final DelegateManager<PathEffect_Delegate> sManager =
|
||||
@@ -49,6 +51,11 @@ public class PathEffect_Delegate {
|
||||
return sManager.getDelegate(nativeShader);
|
||||
}
|
||||
|
||||
public abstract Stroke getStroke(Paint_Delegate paint);
|
||||
public abstract boolean isSupported();
|
||||
public abstract String getSupportMessage();
|
||||
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static void nativeDestructor(int native_patheffect) {
|
||||
|
||||
748
tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
Normal file
748
tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
Normal file
@@ -0,0 +1,748 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import android.graphics.Path.Direction;
|
||||
import android.graphics.Path.FillType;
|
||||
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.Path
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of Path have been replaced
|
||||
* by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original Path class.
|
||||
*
|
||||
* @see DelegateManager
|
||||
*
|
||||
*/
|
||||
public final class Path_Delegate {
|
||||
|
||||
// ---- delegate manager ----
|
||||
private static final DelegateManager<Path_Delegate> sManager =
|
||||
new DelegateManager<Path_Delegate>();
|
||||
|
||||
// ---- delegate data ----
|
||||
private FillType mFillType = FillType.WINDING;
|
||||
private GeneralPath mPath = new GeneralPath();
|
||||
|
||||
private float mLastX = 0;
|
||||
private float mLastY = 0;
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
public static Path_Delegate getDelegate(int nPath) {
|
||||
return sManager.getDelegate(nPath);
|
||||
}
|
||||
|
||||
public Shape getJavaShape() {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int init1() {
|
||||
// create the delegate
|
||||
Path_Delegate newDelegate = new Path_Delegate();
|
||||
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static int init2(int nPath) {
|
||||
// create the delegate
|
||||
Path_Delegate newDelegate = new Path_Delegate();
|
||||
|
||||
// get the delegate to copy
|
||||
if (nPath > 0) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
newDelegate.set(pathDelegate);
|
||||
}
|
||||
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static void native_reset(int nPath) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.mPath.reset();
|
||||
}
|
||||
|
||||
/*package*/ static void native_rewind(int nPath) {
|
||||
// call out to reset since there's nothing to optimize in
|
||||
// terms of data structs.
|
||||
native_reset(nPath);
|
||||
}
|
||||
|
||||
/*package*/ static void native_set(int native_dst, int native_src) {
|
||||
Path_Delegate pathDstDelegate = sManager.getDelegate(native_dst);
|
||||
if (pathDstDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
Path_Delegate pathSrcDelegate = sManager.getDelegate(native_src);
|
||||
if (pathSrcDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDstDelegate.set(pathSrcDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static int native_getFillType(int nPath) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pathDelegate.mFillType.nativeInt;
|
||||
}
|
||||
|
||||
/*package*/ static void native_setFillType(int nPath, int ft) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.mFillType = Path.sFillTypeArray[ft];
|
||||
}
|
||||
|
||||
/*package*/ static boolean native_isEmpty(int nPath) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return pathDelegate.isEmpty();
|
||||
}
|
||||
|
||||
/*package*/ static boolean native_isRect(int nPath, RectF rect) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// create an Area that can test if the path is a rect
|
||||
Area area = new Area(pathDelegate.mPath);
|
||||
if (area.isRectangular()) {
|
||||
if (rect != null) {
|
||||
pathDelegate.fillBounds(rect);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*package*/ static void native_computeBounds(int nPath, RectF bounds) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.fillBounds(bounds);
|
||||
}
|
||||
|
||||
/*package*/ static void native_incReserve(int nPath, int extraPtCount) {
|
||||
// since we use a java2D path, there's no way to pre-allocate new points,
|
||||
// so we do nothing.
|
||||
}
|
||||
|
||||
/*package*/ static void native_moveTo(int nPath, float x, float y) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.moveTo(x, y);
|
||||
}
|
||||
|
||||
/*package*/ static void native_rMoveTo(int nPath, float dx, float dy) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.rMoveTo(dx, dy);
|
||||
}
|
||||
|
||||
/*package*/ static void native_lineTo(int nPath, float x, float y) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.lineTo(x, y);
|
||||
}
|
||||
|
||||
/*package*/ static void native_rLineTo(int nPath, float dx, float dy) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.rLineTo(dx, dy);
|
||||
}
|
||||
|
||||
/*package*/ static void native_quadTo(int nPath, float x1, float y1, float x2, float y2) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.quadTo(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/*package*/ static void native_rQuadTo(int nPath, float dx1, float dy1,
|
||||
float dx2, float dy2) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.rQuadTo(dx1, dy1, dx2, dy2);
|
||||
}
|
||||
|
||||
/*package*/ static void native_cubicTo(int nPath, float x1, float y1,
|
||||
float x2, float y2, float x3, float y3) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.cubicTo(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
/*package*/ static void native_rCubicTo(int nPath, float x1, float y1,
|
||||
float x2, float y2, float x3, float y3) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.rCubicTo(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
/*package*/ static void native_arcTo(int nPath, RectF oval,
|
||||
float startAngle, float sweepAngle, boolean forceMoveTo) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
|
||||
}
|
||||
|
||||
/*package*/ static void native_close(int nPath) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.close();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addRect(int nPath, RectF rect, int dir) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.addRect(rect.left, rect.top, rect.right, rect.bottom, dir);
|
||||
}
|
||||
|
||||
/*package*/ static void native_addRect(int nPath, float left, float top,
|
||||
float right, float bottom, int dir) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.addRect(left, top, right, bottom, dir);
|
||||
}
|
||||
|
||||
/*package*/ static void native_addOval(int nPath, RectF oval, int dir) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addCircle(int nPath, float x, float y,
|
||||
float radius, int dir) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addArc(int nPath, RectF oval,
|
||||
float startAngle, float sweepAngle) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addRoundRect(int nPath, RectF rect,
|
||||
float rx, float ry, int dir) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addRoundRect(int nPath, RectF r,
|
||||
float[] radii, int dir) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addPath(int nPath, int src, float dx,
|
||||
float dy) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addPath(int nPath, int src) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_addPath(int nPath, int src, int matrix) {
|
||||
// FIXME
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/*package*/ static void native_offset(int nPath, float dx, float dy,
|
||||
int dst_path) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
Path_Delegate dstDelegate = null;
|
||||
if (dst_path > 0) {
|
||||
dstDelegate = sManager.getDelegate(dst_path);
|
||||
if (dstDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pathDelegate.offset(dx, dy, dstDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static void native_offset(int nPath, float dx, float dy) {
|
||||
native_offset(nPath, dx, dy, 0);
|
||||
}
|
||||
|
||||
/*package*/ static void native_setLastPoint(int nPath, float dx, float dy) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
pathDelegate.mLastX = dx;
|
||||
pathDelegate.mLastY = dy;
|
||||
}
|
||||
|
||||
/*package*/ static void native_transform(int nPath, int matrix,
|
||||
int dst_path) {
|
||||
Path_Delegate pathDelegate = sManager.getDelegate(nPath);
|
||||
if (pathDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
|
||||
if (matrixDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
|
||||
Path_Delegate dstDelegate = null;
|
||||
if (dst_path > 0) {
|
||||
dstDelegate = sManager.getDelegate(dst_path);
|
||||
if (dstDelegate == null) {
|
||||
assert false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pathDelegate.transform(matrixDelegate, dstDelegate);
|
||||
}
|
||||
|
||||
/*package*/ static void native_transform(int nPath, int matrix) {
|
||||
native_transform(nPath, matrix, 0);
|
||||
}
|
||||
|
||||
/*package*/ static void finalizer(int nPath) {
|
||||
sManager.removeDelegate(nPath);
|
||||
}
|
||||
|
||||
|
||||
// ---- Private helper methods ----
|
||||
|
||||
private void set(Path_Delegate delegate) {
|
||||
mPath.reset();
|
||||
setFillType(delegate.mFillType);
|
||||
mPath.append(delegate.mPath, false /*connect*/);
|
||||
}
|
||||
|
||||
private void setFillType(FillType fillType) {
|
||||
mFillType = fillType;
|
||||
mPath.setWindingRule(getWindingRule(fillType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java2D winding rules matching a given Android {@link FillType}.
|
||||
* @param type the android fill type
|
||||
* @return the matching java2d winding rule.
|
||||
*/
|
||||
private static int getWindingRule(FillType type) {
|
||||
switch (type) {
|
||||
case WINDING:
|
||||
case INVERSE_WINDING:
|
||||
return GeneralPath.WIND_NON_ZERO;
|
||||
case EVEN_ODD:
|
||||
case INVERSE_EVEN_ODD:
|
||||
return GeneralPath.WIND_EVEN_ODD;
|
||||
}
|
||||
|
||||
assert false;
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
private static Direction getDirection(int direction) {
|
||||
for (Direction d : Direction.values()) {
|
||||
if (direction == d.nativeInt) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the path is empty.
|
||||
* @return true if the path is empty.
|
||||
*/
|
||||
private boolean isEmpty() {
|
||||
return mPath.getCurrentPoint() == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the given {@link RectF} with the path bounds.
|
||||
* @param bounds the RectF to be filled.
|
||||
*/
|
||||
private void fillBounds(RectF bounds) {
|
||||
Rectangle2D rect = mPath.getBounds2D();
|
||||
bounds.left = (float)rect.getMinX();
|
||||
bounds.right = (float)rect.getMaxX();
|
||||
bounds.top = (float)rect.getMinY();
|
||||
bounds.bottom = (float)rect.getMaxY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the beginning of the next contour to the point (x,y).
|
||||
*
|
||||
* @param x The x-coordinate of the start of a new contour
|
||||
* @param y The y-coordinate of the start of a new contour
|
||||
*/
|
||||
private void moveTo(float x, float y) {
|
||||
mPath.moveTo(mLastX = x, mLastY = y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the beginning of the next contour relative to the last point on the
|
||||
* previous contour. If there is no previous contour, this is treated the
|
||||
* same as moveTo().
|
||||
*
|
||||
* @param dx The amount to add to the x-coordinate of the end of the
|
||||
* previous contour, to specify the start of a new contour
|
||||
* @param dy The amount to add to the y-coordinate of the end of the
|
||||
* previous contour, to specify the start of a new contour
|
||||
*/
|
||||
private void rMoveTo(float dx, float dy) {
|
||||
dx += mLastX;
|
||||
dy += mLastY;
|
||||
mPath.moveTo(mLastX = dx, mLastY = dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a line from the last point to the specified point (x,y).
|
||||
* If no moveTo() call has been made for this contour, the first point is
|
||||
* automatically set to (0,0).
|
||||
*
|
||||
* @param x The x-coordinate of the end of a line
|
||||
* @param y The y-coordinate of the end of a line
|
||||
*/
|
||||
private void lineTo(float x, float y) {
|
||||
mPath.lineTo(mLastX = x, mLastY = y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as lineTo, but the coordinates are considered relative to the last
|
||||
* point on this contour. If there is no previous point, then a moveTo(0,0)
|
||||
* is inserted automatically.
|
||||
*
|
||||
* @param dx The amount to add to the x-coordinate of the previous point on
|
||||
* this contour, to specify a line
|
||||
* @param dy The amount to add to the y-coordinate of the previous point on
|
||||
* this contour, to specify a line
|
||||
*/
|
||||
private void rLineTo(float dx, float dy) {
|
||||
if (isEmpty()) {
|
||||
mPath.moveTo(mLastX = 0, mLastY = 0);
|
||||
}
|
||||
dx += mLastX;
|
||||
dy += mLastY;
|
||||
mPath.lineTo(mLastX = dx, mLastY = dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a quadratic bezier from the last point, approaching control point
|
||||
* (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
|
||||
* this contour, the first point is automatically set to (0,0).
|
||||
*
|
||||
* @param x1 The x-coordinate of the control point on a quadratic curve
|
||||
* @param y1 The y-coordinate of the control point on a quadratic curve
|
||||
* @param x2 The x-coordinate of the end point on a quadratic curve
|
||||
* @param y2 The y-coordinate of the end point on a quadratic curve
|
||||
*/
|
||||
private void quadTo(float x1, float y1, float x2, float y2) {
|
||||
mPath.quadTo(x1, y1, mLastX = x2, mLastY = y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as quadTo, but the coordinates are considered relative to the last
|
||||
* point on this contour. If there is no previous point, then a moveTo(0,0)
|
||||
* is inserted automatically.
|
||||
*
|
||||
* @param dx1 The amount to add to the x-coordinate of the last point on
|
||||
* this contour, for the control point of a quadratic curve
|
||||
* @param dy1 The amount to add to the y-coordinate of the last point on
|
||||
* this contour, for the control point of a quadratic curve
|
||||
* @param dx2 The amount to add to the x-coordinate of the last point on
|
||||
* this contour, for the end point of a quadratic curve
|
||||
* @param dy2 The amount to add to the y-coordinate of the last point on
|
||||
* this contour, for the end point of a quadratic curve
|
||||
*/
|
||||
private void rQuadTo(float dx1, float dy1, float dx2, float dy2) {
|
||||
if (isEmpty()) {
|
||||
mPath.moveTo(mLastX = 0, mLastY = 0);
|
||||
}
|
||||
dx1 += mLastX;
|
||||
dy1 += mLastY;
|
||||
dx2 += mLastX;
|
||||
dy2 += mLastY;
|
||||
mPath.quadTo(dx1, dy1, mLastX = dx2, mLastY = dy2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cubic bezier from the last point, approaching control points
|
||||
* (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
|
||||
* made for this contour, the first point is automatically set to (0,0).
|
||||
*
|
||||
* @param x1 The x-coordinate of the 1st control point on a cubic curve
|
||||
* @param y1 The y-coordinate of the 1st control point on a cubic curve
|
||||
* @param x2 The x-coordinate of the 2nd control point on a cubic curve
|
||||
* @param y2 The y-coordinate of the 2nd control point on a cubic curve
|
||||
* @param x3 The x-coordinate of the end point on a cubic curve
|
||||
* @param y3 The y-coordinate of the end point on a cubic curve
|
||||
*/
|
||||
private void cubicTo(float x1, float y1, float x2, float y2,
|
||||
float x3, float y3) {
|
||||
mPath.curveTo(x1, y1, x2, y2, mLastX = x3, mLastY = y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as cubicTo, but the coordinates are considered relative to the
|
||||
* current point on this contour. If there is no previous point, then a
|
||||
* moveTo(0,0) is inserted automatically.
|
||||
*/
|
||||
private void rCubicTo(float dx1, float dy1, float dx2, float dy2,
|
||||
float dx3, float dy3) {
|
||||
if (isEmpty()) {
|
||||
mPath.moveTo(mLastX = 0, mLastY = 0);
|
||||
}
|
||||
dx1 += mLastX;
|
||||
dy1 += mLastY;
|
||||
dx2 += mLastX;
|
||||
dy2 += mLastY;
|
||||
dx3 += mLastX;
|
||||
dy3 += mLastY;
|
||||
mPath.curveTo(dx1, dy1, dx2, dy2, mLastX = dx3, mLastY = dy3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the specified arc to the path as a new contour. If the start of
|
||||
* the path is different from the path's current last point, then an
|
||||
* automatic lineTo() is added to connect the current contour to the
|
||||
* start of the arc. However, if the path is empty, then we call moveTo()
|
||||
* with the first point of the arc. The sweep angle is tread mod 360.
|
||||
*
|
||||
* @param oval The bounds of oval defining shape and size of the arc
|
||||
* @param startAngle Starting angle (in degrees) where the arc begins
|
||||
* @param sweepAngle Sweep angle (in degrees) measured clockwise, treated
|
||||
* mod 360.
|
||||
* @param forceMoveTo If true, always begin a new contour with the arc
|
||||
*/
|
||||
private void arcTo(RectF oval, float startAngle, float sweepAngle,
|
||||
boolean forceMoveTo) {
|
||||
Arc2D arc = new Arc2D.Float(oval.left, oval.top, oval.width(), oval.height(), startAngle,
|
||||
sweepAngle, Arc2D.OPEN);
|
||||
mPath.append(arc, true /*connect*/);
|
||||
|
||||
resetLastPointFromPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current contour. If the current point is not equal to the
|
||||
* first point of the contour, a line segment is automatically added.
|
||||
*/
|
||||
private void close() {
|
||||
mPath.closePath();
|
||||
}
|
||||
|
||||
private void resetLastPointFromPath() {
|
||||
Point2D last = mPath.getCurrentPoint();
|
||||
mLastX = (float) last.getX();
|
||||
mLastY = (float) last.getY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a closed rectangle contour to the path
|
||||
*
|
||||
* @param left The left side of a rectangle to add to the path
|
||||
* @param top The top of a rectangle to add to the path
|
||||
* @param right The right side of a rectangle to add to the path
|
||||
* @param bottom The bottom of a rectangle to add to the path
|
||||
* @param dir The direction to wind the rectangle's contour
|
||||
*/
|
||||
private void addRect(float left, float top, float right, float bottom,
|
||||
int dir) {
|
||||
moveTo(left, top);
|
||||
|
||||
Direction direction = getDirection(dir);
|
||||
|
||||
switch (direction) {
|
||||
case CW:
|
||||
lineTo(right, top);
|
||||
lineTo(right, bottom);
|
||||
lineTo(left, bottom);
|
||||
break;
|
||||
case CCW:
|
||||
lineTo(left, bottom);
|
||||
lineTo(right, bottom);
|
||||
lineTo(right, top);
|
||||
break;
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
resetLastPointFromPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset the path by (dx,dy), returning true on success
|
||||
*
|
||||
* @param dx The amount in the X direction to offset the entire path
|
||||
* @param dy The amount in the Y direction to offset the entire path
|
||||
* @param dst The translated path is written here. If this is null, then
|
||||
* the original path is modified.
|
||||
*/
|
||||
public void offset(float dx, float dy, Path_Delegate dst) {
|
||||
GeneralPath newPath = new GeneralPath();
|
||||
|
||||
PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy));
|
||||
|
||||
newPath.append(iterator, false /*connect*/);
|
||||
|
||||
if (dst != null) {
|
||||
dst.mPath = newPath;
|
||||
} else {
|
||||
mPath = newPath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the points in this path by matrix, and write the answer
|
||||
* into dst. If dst is null, then the the original path is modified.
|
||||
*
|
||||
* @param matrix The matrix to apply to the path
|
||||
* @param dst The transformed path is written here. If dst is null,
|
||||
* then the the original path is modified
|
||||
*/
|
||||
public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
|
||||
if (matrix.hasPerspective()) {
|
||||
assert false;
|
||||
Bridge.getLog().fidelityWarning(null,
|
||||
"android.graphics.Path#transform() only " +
|
||||
"supports affine transformations in the Layout Preview.", null);
|
||||
}
|
||||
|
||||
GeneralPath newPath = new GeneralPath();
|
||||
|
||||
PathIterator iterator = mPath.getPathIterator(matrix.getAffineTransform());
|
||||
|
||||
newPath.append(iterator, false /*connect*/);
|
||||
|
||||
if (dst != null) {
|
||||
dst.mPath = newPath;
|
||||
} else {
|
||||
mPath = newPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Composite;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.PixelXorXfermode
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of PixelXorXfermode have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original PixelXorXfermode class.
|
||||
*
|
||||
* Because this extends {@link Xfermode_Delegate}, there's no need to use a
|
||||
* {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
|
||||
* {@link Xfermode_Delegate}.
|
||||
*
|
||||
* @see Xfermode_Delegate
|
||||
*/
|
||||
public class PixelXorXfermode_Delegate extends Xfermode_Delegate {
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Composite getComposite() {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Pixel XOR Xfermodes are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(int opColor) {
|
||||
PixelXorXfermode_Delegate newDelegate = new PixelXorXfermode_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
package android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Composite;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.PorterDuffXfermode
|
||||
*
|
||||
@@ -41,8 +45,64 @@ public class PorterDuffXfermode_Delegate extends Xfermode_Delegate {
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
public int getMode() {
|
||||
return mMode;
|
||||
@Override
|
||||
public Composite getComposite() {
|
||||
return getComposite(mMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
// no message since isSupported returns true;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Composite getComposite(int mode) {
|
||||
PorterDuff.Mode m = getMode(mode);
|
||||
switch (m) {
|
||||
case CLEAR:
|
||||
return AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f /*alpha*/);
|
||||
case DARKEN:
|
||||
break;
|
||||
case DST:
|
||||
return AlphaComposite.getInstance(AlphaComposite.DST, 1.0f /*alpha*/);
|
||||
case DST_ATOP:
|
||||
return AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1.0f /*alpha*/);
|
||||
case DST_IN:
|
||||
return AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0f /*alpha*/);
|
||||
case DST_OUT:
|
||||
return AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1.0f /*alpha*/);
|
||||
case DST_OVER:
|
||||
return AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f /*alpha*/);
|
||||
case LIGHTEN:
|
||||
break;
|
||||
case MULTIPLY:
|
||||
break;
|
||||
case SCREEN:
|
||||
break;
|
||||
case SRC:
|
||||
return AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f /*alpha*/);
|
||||
case SRC_ATOP:
|
||||
return AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f /*alpha*/);
|
||||
case SRC_IN:
|
||||
return AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f /*alpha*/);
|
||||
case SRC_OUT:
|
||||
return AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1.0f /*alpha*/);
|
||||
case SRC_OVER:
|
||||
return AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f /*alpha*/);
|
||||
case XOR:
|
||||
return AlphaComposite.getInstance(AlphaComposite.XOR, 1.0f /*alpha*/);
|
||||
}
|
||||
|
||||
Bridge.getLog().fidelityWarning(null,
|
||||
String.format("Unsupported PorterDuff Mode: %s", m.name()),
|
||||
null);
|
||||
|
||||
return AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
@@ -58,4 +118,15 @@ public class PorterDuffXfermode_Delegate extends Xfermode_Delegate {
|
||||
mMode = mode;
|
||||
}
|
||||
|
||||
private static PorterDuff.Mode getMode(int mode) {
|
||||
for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
|
||||
if (m.nativeInt == mode) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
Bridge.getLog().error(null, String.format("Unknown PorterDuff.Mode: %d", mode));
|
||||
assert false;
|
||||
return PorterDuff.Mode.SRC_OVER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,6 @@ import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import android.graphics.Shader.TileMode;
|
||||
|
||||
import java.awt.Paint;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.NoninvertibleTransformException;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.RadialGradient
|
||||
*
|
||||
@@ -49,7 +45,7 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Paint getJavaPaint() {
|
||||
public java.awt.Paint getJavaPaint() {
|
||||
return mJavaPaint;
|
||||
}
|
||||
|
||||
@@ -57,17 +53,8 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
|
||||
|
||||
/*package*/ static int nativeCreate1(float x, float y, float radius,
|
||||
int colors[], float positions[], int tileMode) {
|
||||
// figure out the tile
|
||||
TileMode tile = null;
|
||||
for (TileMode tm : TileMode.values()) {
|
||||
if (tm.nativeInt == tileMode) {
|
||||
tile = tm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RadialGradient_Delegate newDelegate = new RadialGradient_Delegate(x, y, radius,
|
||||
colors, positions, tile);
|
||||
colors, positions, Shader_Delegate.getTileMode(tileMode));
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
@@ -133,20 +120,20 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
|
||||
java.awt.RenderingHints hints) {
|
||||
precomputeGradientColors();
|
||||
|
||||
AffineTransform canvasMatrix;
|
||||
java.awt.geom.AffineTransform canvasMatrix;
|
||||
try {
|
||||
canvasMatrix = xform.createInverse();
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in RadialGradient", e);
|
||||
canvasMatrix = new AffineTransform();
|
||||
canvasMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
AffineTransform localMatrix = getLocalMatrix();
|
||||
java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
|
||||
try {
|
||||
localMatrix = localMatrix.createInverse();
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in RadialGradient", e);
|
||||
localMatrix = new AffineTransform();
|
||||
localMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
return new RadialGradientPaintContext(canvasMatrix, localMatrix, colorModel);
|
||||
@@ -154,12 +141,14 @@ public class RadialGradient_Delegate extends Gradient_Delegate {
|
||||
|
||||
private class RadialGradientPaintContext implements java.awt.PaintContext {
|
||||
|
||||
private final AffineTransform mCanvasMatrix;
|
||||
private final AffineTransform mLocalMatrix;
|
||||
private final java.awt.geom.AffineTransform mCanvasMatrix;
|
||||
private final java.awt.geom.AffineTransform mLocalMatrix;
|
||||
private final java.awt.image.ColorModel mColorModel;
|
||||
|
||||
public RadialGradientPaintContext(AffineTransform canvasMatrix,
|
||||
AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
|
||||
public RadialGradientPaintContext(
|
||||
java.awt.geom.AffineTransform canvasMatrix,
|
||||
java.awt.geom.AffineTransform localMatrix,
|
||||
java.awt.image.ColorModel colorModel) {
|
||||
mCanvasMatrix = canvasMatrix;
|
||||
mLocalMatrix = localMatrix;
|
||||
mColorModel = colorModel;
|
||||
|
||||
@@ -18,7 +18,7 @@ package android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.geom.AffineTransform;
|
||||
import android.graphics.Shader.TileMode;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.Shader
|
||||
@@ -52,7 +52,25 @@ public abstract class Shader_Delegate {
|
||||
return sManager.getDelegate(nativeShader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link TileMode} matching the given int.
|
||||
* @param tileMode the tile mode int value
|
||||
* @return the TileMode enum.
|
||||
*/
|
||||
public static TileMode getTileMode(int tileMode) {
|
||||
for (TileMode tm : TileMode.values()) {
|
||||
if (tm.nativeInt == tileMode) {
|
||||
return tm;
|
||||
}
|
||||
}
|
||||
|
||||
assert false;
|
||||
return TileMode.CLAMP;
|
||||
}
|
||||
|
||||
public abstract java.awt.Paint getJavaPaint();
|
||||
public abstract boolean isSupported();
|
||||
public abstract String getSupportMessage();
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
@@ -111,19 +129,19 @@ public abstract class Shader_Delegate {
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
|
||||
protected AffineTransform getLocalMatrix() {
|
||||
protected java.awt.geom.AffineTransform getLocalMatrix() {
|
||||
Matrix_Delegate localMatrixDelegate = null;
|
||||
if (mLocalMatrix > 0) {
|
||||
localMatrixDelegate = Matrix_Delegate.getDelegate(mLocalMatrix);
|
||||
if (localMatrixDelegate == null) {
|
||||
assert false;
|
||||
return new AffineTransform();
|
||||
return new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
return localMatrixDelegate.getAffineTransform();
|
||||
}
|
||||
|
||||
return new AffineTransform();
|
||||
return new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Stroke;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.SumPathEffect
|
||||
*
|
||||
* Through the layoutlib_create tool, the original native methods of SumPathEffect have been
|
||||
* replaced by calls to methods of the same name in this delegate class.
|
||||
*
|
||||
* This class behaves like the original native implementation, but in Java, keeping previously
|
||||
* native data into its own objects and mapping them to int that are sent back and forth between
|
||||
* it and the original SumPathEffect class.
|
||||
*
|
||||
* Because this extends {@link Shader_Delegate}, there's no need to use a {@link DelegateManager},
|
||||
* as all the Shader classes will be added to the manager owned by {@link Shader_Delegate}.
|
||||
*
|
||||
* @see Shader_Delegate
|
||||
*
|
||||
*/
|
||||
public class SumPathEffect_Delegate extends PathEffect_Delegate {
|
||||
|
||||
// ---- delegate data ----
|
||||
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Stroke getStroke(Paint_Delegate paint) {
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupportMessage() {
|
||||
return "Sum Path Effects are not supported in Layout Preview mode.";
|
||||
}
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static int nativeCreate(int first, int second) {
|
||||
SumPathEffect_Delegate newDelegate = new SumPathEffect_Delegate();
|
||||
return sManager.addDelegate(newDelegate);
|
||||
}
|
||||
|
||||
// ---- Private delegate/helper methods ----
|
||||
}
|
||||
@@ -19,10 +19,6 @@ package android.graphics;
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Paint;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.NoninvertibleTransformException;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.SweepGradient
|
||||
*
|
||||
@@ -47,7 +43,7 @@ public class SweepGradient_Delegate extends Gradient_Delegate {
|
||||
// ---- Public Helper methods ----
|
||||
|
||||
@Override
|
||||
public Paint getJavaPaint() {
|
||||
public java.awt.Paint getJavaPaint() {
|
||||
return mJavaPaint;
|
||||
}
|
||||
|
||||
@@ -116,20 +112,20 @@ public class SweepGradient_Delegate extends Gradient_Delegate {
|
||||
java.awt.RenderingHints hints) {
|
||||
precomputeGradientColors();
|
||||
|
||||
AffineTransform canvasMatrix;
|
||||
java.awt.geom.AffineTransform canvasMatrix;
|
||||
try {
|
||||
canvasMatrix = xform.createInverse();
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in SweepGradient", e);
|
||||
canvasMatrix = new AffineTransform();
|
||||
canvasMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
AffineTransform localMatrix = getLocalMatrix();
|
||||
java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
|
||||
try {
|
||||
localMatrix = localMatrix.createInverse();
|
||||
} catch (NoninvertibleTransformException e) {
|
||||
} catch (java.awt.geom.NoninvertibleTransformException e) {
|
||||
Bridge.getLog().error(null, "Unable to inverse matrix in SweepGradient", e);
|
||||
localMatrix = new AffineTransform();
|
||||
localMatrix = new java.awt.geom.AffineTransform();
|
||||
}
|
||||
|
||||
return new SweepGradientPaintContext(canvasMatrix, localMatrix, colorModel);
|
||||
@@ -137,12 +133,14 @@ public class SweepGradient_Delegate extends Gradient_Delegate {
|
||||
|
||||
private class SweepGradientPaintContext implements java.awt.PaintContext {
|
||||
|
||||
private final AffineTransform mCanvasMatrix;
|
||||
private final AffineTransform mLocalMatrix;
|
||||
private final java.awt.geom.AffineTransform mCanvasMatrix;
|
||||
private final java.awt.geom.AffineTransform mLocalMatrix;
|
||||
private final java.awt.image.ColorModel mColorModel;
|
||||
|
||||
public SweepGradientPaintContext(AffineTransform canvasMatrix,
|
||||
AffineTransform localMatrix, java.awt.image.ColorModel colorModel) {
|
||||
public SweepGradientPaintContext(
|
||||
java.awt.geom.AffineTransform canvasMatrix,
|
||||
java.awt.geom.AffineTransform localMatrix,
|
||||
java.awt.image.ColorModel colorModel) {
|
||||
mCanvasMatrix = canvasMatrix;
|
||||
mLocalMatrix = localMatrix;
|
||||
mColorModel = colorModel;
|
||||
|
||||
@@ -18,6 +18,8 @@ package android.graphics;
|
||||
|
||||
import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
|
||||
import java.awt.Composite;
|
||||
|
||||
/**
|
||||
* Delegate implementing the native methods of android.graphics.Xfermode
|
||||
*
|
||||
@@ -33,7 +35,7 @@ import com.android.layoutlib.bridge.impl.DelegateManager;
|
||||
* @see DelegateManager
|
||||
*
|
||||
*/
|
||||
public class Xfermode_Delegate {
|
||||
public abstract class Xfermode_Delegate {
|
||||
|
||||
// ---- delegate manager ----
|
||||
protected static final DelegateManager<Xfermode_Delegate> sManager =
|
||||
@@ -49,6 +51,11 @@ public class Xfermode_Delegate {
|
||||
return sManager.getDelegate(native_instance);
|
||||
}
|
||||
|
||||
public abstract Composite getComposite();
|
||||
public abstract boolean isSupported();
|
||||
public abstract String getSupportMessage();
|
||||
|
||||
|
||||
// ---- native methods ----
|
||||
|
||||
/*package*/ static void finalizer(int native_instance) {
|
||||
|
||||
@@ -106,17 +106,27 @@ public final class CreateInfo implements ICreateInfo {
|
||||
*/
|
||||
private final static String[] DELEGATE_CLASS_NATIVES = new String[] {
|
||||
"android.animation.PropertyValuesHolder",
|
||||
"android.graphics.AvoidXfermode",
|
||||
"android.graphics.Bitmap",
|
||||
"android.graphics.BitmapShader",
|
||||
"android.graphics.Canvas",
|
||||
"android.graphics.ComposePathEffect",
|
||||
"android.graphics.ComposeShader",
|
||||
"android.graphics.CornerPathEffect",
|
||||
"android.graphics.DashPathEffect",
|
||||
"android.graphics.DiscretePathEffect",
|
||||
"android.graphics.LinearGradient",
|
||||
"android.graphics.Matrix",
|
||||
"android.graphics.NinePatch",
|
||||
"android.graphics.Paint",
|
||||
"android.graphics.Path",
|
||||
"android.graphics.PathDashPathEffect",
|
||||
"android.graphics.PathEffect",
|
||||
"android.graphics.PixelXorXfermode",
|
||||
"android.graphics.PorterDuffXfermode",
|
||||
"android.graphics.RadialGradient",
|
||||
"android.graphics.Shader",
|
||||
"android.graphics.SumPathEffect",
|
||||
"android.graphics.SweepGradient",
|
||||
"android.graphics.Typeface",
|
||||
"android.graphics.Xfermode",
|
||||
@@ -140,7 +150,6 @@ public final class CreateInfo implements ICreateInfo {
|
||||
private final static String[] RENAMED_CLASSES =
|
||||
new String[] {
|
||||
"android.graphics.BitmapFactory", "android.graphics._Original_BitmapFactory",
|
||||
"android.graphics.Path", "android.graphics._Original_Path",
|
||||
"android.os.ServiceManager", "android.os._Original_ServiceManager",
|
||||
"android.view.SurfaceView", "android.view._Original_SurfaceView",
|
||||
"android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
|
||||
|
||||
Reference in New Issue
Block a user