Add support for arcs.
Change-Id: I96c057ff4eb1b464b03f132da0b85333777bee4f
This commit is contained in:
@ -525,9 +525,15 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
@Override
|
||||
public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
|
||||
Paint paint) {
|
||||
// TODO: Implement
|
||||
boolean hasModifier = setupModifiers(paint);
|
||||
nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle,
|
||||
useCenter, paint.mNativePaint);
|
||||
if (hasModifier) nResetModifiers(mRenderer);
|
||||
}
|
||||
|
||||
private native void nDrawArc(int renderer, float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, boolean useCenter, int paint);
|
||||
|
||||
@Override
|
||||
public void drawARGB(int a, int r, int g, int b) {
|
||||
drawColor((a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF));
|
||||
|
@ -332,6 +332,12 @@ static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject canvas,
|
||||
renderer->drawOval(left, top, right, bottom, paint);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject canvas,
|
||||
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
|
||||
jfloat startAngle, jfloat sweepAngle, jboolean useCenter, SkPaint* paint) {
|
||||
renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
|
||||
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
|
||||
SkRegion::Iterator it(*region);
|
||||
@ -609,6 +615,8 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nDrawRoundRect", "(IFFFFFFI)V", (void*) android_view_GLES20Canvas_drawRoundRect },
|
||||
{ "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle },
|
||||
{ "nDrawOval", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawOval },
|
||||
{ "nDrawArc", "(IFFFFFFZI)V", (void*) android_view_GLES20Canvas_drawArc },
|
||||
|
||||
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
|
||||
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
|
||||
|
||||
|
@ -164,6 +164,7 @@ public:
|
||||
CircleShapeCache circleShapeCache;
|
||||
OvalShapeCache ovalShapeCache;
|
||||
RectShapeCache rectShapeCache;
|
||||
ArcShapeCache arcShapeCache;
|
||||
PatchCache patchCache;
|
||||
TextDropShadowCache dropShadowCache;
|
||||
FboCache fboCache;
|
||||
|
@ -108,6 +108,7 @@ const char* DisplayList::OP_NAMES[] = {
|
||||
"DrawRoundRect",
|
||||
"DrawCircle",
|
||||
"DrawOval",
|
||||
"DrawArc",
|
||||
"DrawPath",
|
||||
"DrawLines",
|
||||
"DrawText",
|
||||
@ -363,6 +364,11 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
||||
renderer.drawOval(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||
}
|
||||
break;
|
||||
case DrawArc: {
|
||||
renderer.drawArc(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||
getFloat(), getFloat(), getInt() == 1, getPaint());
|
||||
}
|
||||
break;
|
||||
case DrawPath: {
|
||||
renderer.drawPath(getPath(), getPaint());
|
||||
}
|
||||
@ -675,6 +681,15 @@ void DisplayListRenderer::drawOval(float left, float top, float right, float bot
|
||||
addPaint(paint);
|
||||
}
|
||||
|
||||
void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
|
||||
addOp(DisplayList::DrawOval);
|
||||
addBounds(left, top, right, bottom);
|
||||
addPoint(startAngle, sweepAngle);
|
||||
addInt(useCenter ? 1 : 0);
|
||||
addPaint(paint);
|
||||
}
|
||||
|
||||
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
||||
addOp(DisplayList::DrawPath);
|
||||
addPath(path);
|
||||
|
@ -114,6 +114,7 @@ public:
|
||||
DrawRoundRect,
|
||||
DrawCircle,
|
||||
DrawOval,
|
||||
DrawArc,
|
||||
DrawPath,
|
||||
DrawLines,
|
||||
DrawText,
|
||||
@ -281,6 +282,8 @@ public:
|
||||
float rx, float ry, SkPaint* paint);
|
||||
void drawCircle(float x, float y, float radius, SkPaint* paint);
|
||||
void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
|
||||
void drawArc(float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
|
||||
void drawPath(SkPath* path, SkPaint* paint);
|
||||
void drawLines(float* points, int count, SkPaint* paint);
|
||||
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
|
||||
|
@ -1396,6 +1396,21 @@ void OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
|
||||
drawShape(left, top, texture, paint);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
|
||||
if (mSnapshot->isIgnored()) return;
|
||||
|
||||
if (fabs(sweepAngle) >= 360.0f) {
|
||||
drawOval(left, top, right, bottom, paint);
|
||||
return;
|
||||
}
|
||||
|
||||
glActiveTexture(gTextureUnits[0]);
|
||||
const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
|
||||
startAngle, sweepAngle, useCenter, paint);
|
||||
drawShape(left, top, texture, paint);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::drawRectAsShape(float left, float top, float right, float bottom,
|
||||
SkPaint* paint) {
|
||||
if (mSnapshot->isIgnored()) return;
|
||||
|
@ -113,6 +113,8 @@ public:
|
||||
float rx, float ry, SkPaint* paint);
|
||||
virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
|
||||
virtual void drawOval(float left, float top, float right, float bottom, SkPaint* paint);
|
||||
virtual void drawArc(float left, float top, float right, float bottom,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
|
||||
virtual void drawPath(SkPath* path, SkPaint* paint);
|
||||
virtual void drawLines(float* points, int count, SkPaint* paint);
|
||||
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
|
||||
|
@ -114,5 +114,36 @@ PathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint)
|
||||
return texture;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Arcs
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ArcShapeCache::ArcShapeCache(): ShapeCache<ArcShapeCacheEntry>(
|
||||
"arc", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
|
||||
}
|
||||
|
||||
PathTexture* ArcShapeCache::getArc(float width, float height,
|
||||
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
|
||||
ArcShapeCacheEntry entry(width, height, startAngle, sweepAngle, useCenter, paint);
|
||||
PathTexture* texture = get(entry);
|
||||
|
||||
if (!texture) {
|
||||
SkPath path;
|
||||
SkRect r;
|
||||
r.set(0.0f, 0.0f, width, height);
|
||||
if (useCenter) {
|
||||
path.moveTo(r.centerX(), r.centerY());
|
||||
}
|
||||
path.arcTo(r, startAngle, sweepAngle, !useCenter);
|
||||
if (useCenter) {
|
||||
path.close();
|
||||
}
|
||||
|
||||
texture = addTexture(entry, &path, paint);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
@ -281,6 +281,58 @@ private:
|
||||
uint32_t mHeight;
|
||||
}; // RectShapeCacheEntry
|
||||
|
||||
struct ArcShapeCacheEntry: public ShapeCacheEntry {
|
||||
ArcShapeCacheEntry(float width, float height, float startAngle, float sweepAngle,
|
||||
bool useCenter, SkPaint* paint):
|
||||
ShapeCacheEntry(ShapeCacheEntry::kShapeArc, paint) {
|
||||
mWidth = *(uint32_t*) &width;
|
||||
mHeight = *(uint32_t*) &height;
|
||||
mStartAngle = *(uint32_t*) &startAngle;
|
||||
mSweepAngle = *(uint32_t*) &sweepAngle;
|
||||
mUseCenter = useCenter ? 1 : 0;
|
||||
}
|
||||
|
||||
ArcShapeCacheEntry(): ShapeCacheEntry() {
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mStartAngle = 0;
|
||||
mSweepAngle = 0;
|
||||
mUseCenter = 0;
|
||||
}
|
||||
|
||||
ArcShapeCacheEntry(const ArcShapeCacheEntry& entry):
|
||||
ShapeCacheEntry(entry) {
|
||||
mWidth = entry.mWidth;
|
||||
mHeight = entry.mHeight;
|
||||
mStartAngle = entry.mStartAngle;
|
||||
mSweepAngle = entry.mSweepAngle;
|
||||
mUseCenter = entry.mUseCenter;
|
||||
}
|
||||
|
||||
bool lessThan(const ShapeCacheEntry& r) const {
|
||||
const ArcShapeCacheEntry& rhs = (const ArcShapeCacheEntry&) r;
|
||||
LTE_INT(mWidth) {
|
||||
LTE_INT(mHeight) {
|
||||
LTE_INT(mStartAngle) {
|
||||
LTE_INT(mSweepAngle) {
|
||||
LTE_INT(mUseCenter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint32_t mStartAngle;
|
||||
uint32_t mSweepAngle;
|
||||
uint32_t mUseCenter;
|
||||
}; // ArcShapeCacheEntry
|
||||
|
||||
/**
|
||||
* A simple LRU shape cache. The cache has a maximum size expressed in bytes.
|
||||
* Any texture added to the cache causing the cache to grow beyond the maximum
|
||||
@ -370,6 +422,14 @@ public:
|
||||
PathTexture* getRect(float width, float height, SkPaint* paint);
|
||||
}; // class RectShapeCache
|
||||
|
||||
class ArcShapeCache: public ShapeCache<ArcShapeCacheEntry> {
|
||||
public:
|
||||
ArcShapeCache();
|
||||
|
||||
PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
|
||||
bool useCenter, SkPaint* paint);
|
||||
}; // class ArcShapeCache
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Constructors/destructor
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -39,6 +39,7 @@ public class ShapesActivity extends Activity {
|
||||
private Paint mFillPaint;
|
||||
private RectF mRect;
|
||||
private RectF mOval;
|
||||
private RectF mArc;
|
||||
|
||||
ShapesView(Context c) {
|
||||
super(c);
|
||||
@ -63,6 +64,7 @@ public class ShapesActivity extends Activity {
|
||||
mFillPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
mOval = new RectF(0.0f, 0.0f, 80.0f, 45.0f);
|
||||
mArc = new RectF(0.0f, 0.0f, 100.0f, 120.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -103,7 +105,7 @@ public class ShapesActivity extends Activity {
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(650.0f, 50.0f);
|
||||
canvas.translate(625.0f, 50.0f);
|
||||
canvas.drawRect(0.0f, 0.0f, 160.0f, 90.0f, mNormalPaint);
|
||||
|
||||
canvas.translate(0.0f, 110.0f);
|
||||
@ -112,6 +114,28 @@ public class ShapesActivity extends Activity {
|
||||
canvas.translate(0.0f, 110.0f);
|
||||
canvas.drawRect(0.0f, 0.0f, 160.0f, 90.0f, mFillPaint);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(825.0f, 50.0f);
|
||||
canvas.drawArc(mArc, -30.0f, 70.0f, true, mNormalPaint);
|
||||
|
||||
canvas.translate(0.0f, 110.0f);
|
||||
canvas.drawArc(mArc, -30.0f, 70.0f, true, mStrokePaint);
|
||||
|
||||
canvas.translate(0.0f, 110.0f);
|
||||
canvas.drawArc(mArc, -30.0f, 70.0f, true, mFillPaint);
|
||||
canvas.restore();
|
||||
|
||||
canvas.save();
|
||||
canvas.translate(950.0f, 50.0f);
|
||||
canvas.drawArc(mArc, 30.0f, 100.0f, false, mNormalPaint);
|
||||
|
||||
canvas.translate(0.0f, 110.0f);
|
||||
canvas.drawArc(mArc, 30.0f, 100.0f, false, mStrokePaint);
|
||||
|
||||
canvas.translate(0.0f, 110.0f);
|
||||
canvas.drawArc(mArc, 30.0f, 100.0f, false, mFillPaint);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user