Android Canvas drawOval流程分析

Canvas的drawOval方法,画椭圆,参数一是扫描区域,参数二为paint对象:

//frameworks/base/graphics/java/android/graphic/Canvas.java
public class Canvas extends BaseCanvas {
    public void drawOval(@NonNull RectF oval, @NonNull Paint paint) {
        super.drawOval(oval, paint);
    }
}

调用Canvas的父类BaseCanvas的drawOval方法:

//frameworks/base/graphics/java/android/graphic/BaseCanvas.java
public abstract class BaseCanvas {}
    public void drawOval(float left, float top, float right, float bottom, @NonNull Paint paint) {
        throwIfHasHwFeaturesInSwMode(paint);
        nDrawOval(mNativeCanvasWrapper, left, top, right, bottom, paint.getNativeInstance());
    }
}

drawOval

调用nDrawOval方法,nDrawOval方法是Native方法,在android_graphics_Canvas.cpp中实现,下面分别进行分析:

//framework/base/libs/hwui/jni/android_graphics_Canvas.cpp
static void drawOval(JNIEnv* env, jobject, jlong canvasHandle, jfloat left, jfloat top,
                     jfloat right, jfloat bottom, jlong paintHandle) {
    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
    get_canvas(canvasHandle)->drawOval(left, top, right, bottom, *paint);
}

调用get_canvas取得Canvas:

//framework/base/libs/hwui/jni/android_graphics_Canvas.cpp
static Canvas* get_canvas(jlong canvasHandle) {
    return reinterpret_cast<Canvas*>(canvasHandle);
}

SkiaCanvas drawOval

SkiaCanvas继承于Canvas,因此调用SkiaCanvas的drawOval方法,SkiaCanvas的drawOval方法可以用于在画布上绘制椭圆形

//frameworks/base/libs/hwui/SkiaCanvas.cpp
class SkiaCanvas : public Canvas {
SkCanvas* mCanvas; 
void SkiaCanvas::drawOval(float left, float top, float right, float bottom, const Paint& paint) {
    if (CC_UNLIKELY(paint.nothingToDraw())) return;
    SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
    applyLooper(&paint, [&](const SkPaint& p) { mCanvas->drawOval(oval, p); });
}

SkCanvas drawOval

调用mCanvas(SkCanvas)的drawOval方法:

//external/skia/include/core/SkCanvas.cpp
class SK_API SkCanvas {
void SkCanvas::drawOval(const SkRect& r, const SkPaint& paint) {
    TRACE_EVENT0("skia", TRACE_FUNC);
    // To avoid redundant logic in our culling code and various backends, we always sort rects
    // before passing them along.
    this->onDrawOval(r.makeSorted(), paint);
}
}

调用SkCanvas的onDrawOval方法:

//external/skia/include/core/SkCanvas.cpp
class SK_API SkCanvas {
void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
    SkASSERT(oval.isSorted());
    if (this->internalQuickReject(oval, paint)) {
        return;
    }


    auto layer = this->aboutToDraw(this, paint, &oval);
    if (layer) {
        this->topDevice()->drawOval(oval, layer->paint());
    }
}
}

调用SkCanvas的topDevice方法,返回SkBaseDevice对象:

//external/skia/include/core/SkCanvas.cpp
SkBaseDevice* SkCanvas::topDevice() const {
    SkASSERT(fMCRec->fDevice);
    return fMCRec->fDevice;
}
SkBitmapDevice drawOval

调用SkBaseDevice的drawOval,由SkBaseDevice的子类SkBitmapDevice实现drawOval方法:

//ext
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值