赞
踩
自定义View继承自View类,需要重写onDraw方法,通过canvas和paint进行绘制
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- canvas.drawLine();
- }
- public void drawLine(float startX, float startY, float stopX, float stopY,
- @NonNull Paint paint) {
- super.drawLine(startX, startY, stopX, stopY, paint);
- }
framework/base/graphics/java/android/graphics/BaseCanvas.java
- public void drawLine(float startX, float startY, float stopX, float stopY,
- @NonNull Paint paint) {
- throwIfHasHwFeaturesInSwMode(paint);
- nDrawLine(mNativeCanvasWrapper, startX, startY, stopX, stopY, paint.getNativeInstance());
- }
- private static native void nDrawLine(long nativeCanvas, float startX, float startY, float stopX,
- float stopY, long nativePaint);
framework/base/libs/hwui/jni/android_graphics_Canvas.cpp
- // If called from Canvas these are regular JNI
- // If called from DisplayListCanvas they are @FastNative
- static const JNINativeMethod gDrawMethods[] = {
- {"nDrawColor","(JII)V", (void*) CanvasJNI::drawColor},
- {"nDrawColor","(JJJI)V", (void*) CanvasJNI::drawColorLong},
- {"nDrawPaint","(JJ)V", (void*) CanvasJNI::drawPaint},
- {"nDrawPoint", "(JFFJ)V", (void*) CanvasJNI::drawPoint},
- {"nDrawPoints", "(J[FIIJ)V", (void*) CanvasJNI::drawPoints},
- {"nDrawLine", "(JFFFFJ)V", (void*) CanvasJNI::drawLine},
- static void drawLine(JNIEnv* env, jobject, jlong canvasHandle, jfloat startX, jfloat startY,
- jfloat stopX, jfloat stopY, jlong paintHandle) {
- Paint* paint = reinterpret_cast<Paint*>(paintHandle);
- get_canvas(canvasHandle)->drawLine(startX, startY, stopX, stopY, *paint);
- }
- static Canvas* get_canvas(jlong canvasHandle) {
- return reinterpret_cast<Canvas*>(canvasHandle);
- }
framework/base/libs/hwui/hwui/Canvas.cpp
- virtual void drawLine(float startX, float startY, float stopX, float stopY,
- const Paint& paint) = 0;
frameworks\base\libs\hwui\SkiaCanvas.cpp
- void SkiaCanvas::drawLine(float startX, float startY, float stopX, float stopY,
- const Paint& paint) {
- applyLooper(&paint,
- [&](const SkPaint& p) { mCanvas->drawLine(startX, startY, stopX, stopY, p); });
- }
- void applyLooper(const Paint* paint, Proc proc, void (*preFilter)(SkPaint&) = nullptr) {
- BlurDrawLooper* looper = paint ? paint->getLooper() : nullptr;
- Paint pnt = paint ? *paint : Paint();
- if (preFilter) {
- preFilter(pnt);
- }
- this->onFilterPaint(pnt);
- if (looper) {
- looper->apply(pnt, [&](SkPoint offset, const Paint& modifiedPaint) {
- mCanvas->save();
- mCanvas->translate(offset.fX, offset.fY);
- proc(modifiedPaint);
- mCanvas->restore();
- });
- } else {
- proc(pnt);
- }
- }

external/skia/src/core/SkCanvas.cpp
- void SkCanvas::drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint& paint) {
- SkPoint pts[2];
- pts[0].set(x0, y0);
- pts[1].set(x1, y1);
- this->drawPoints(kLines_PointMode, 2, pts, paint);
- }
- void SkCanvas::drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) {
- TRACE_EVENT0("skia", TRACE_FUNC);
- this->onDrawPoints(mode, count, pts, paint);
- }
- void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
- const SkPaint& paint) {
- if ((long)count <= 0 || paint.nothingToDraw()) {
- return;
- }
- SkASSERT(pts != nullptr);
-
- SkRect bounds;
- // Compute bounds from points (common for drawing a single line)
- if (count == 2) {
- bounds.set(pts[0], pts[1]);
- } else {
- bounds.setBounds(pts, SkToInt(count));
- }
-
- // Enforce paint style matches implicit behavior of drawPoints
- SkPaint strokePaint = paint;
- strokePaint.setStyle(SkPaint::kStroke_Style);
- if (this->internalQuickReject(bounds, strokePaint)) {
- return;
- }
-
- auto layer = this->aboutToDraw(this, strokePaint, &bounds);
- if (layer) {
- this->topDevice()->drawPoints(mode, count, pts, layer->paint());
- }
- }

external\skia\src\core\SkDevice.h
- virtual void drawPaint(const SkPaint& paint) = 0;
- virtual void drawPoints(SkCanvas::PointMode mode, size_t count,
- const SkPoint[], const SkPaint& paint) = 0;
external\skia\src\gpu\v1\Device.cpp
- void Device::drawPaint(const SkPaint& paint) {
- ASSERT_SINGLE_OWNER
- GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawPaint", fContext.get());
-
- GrPaint grPaint;
- if (!SkPaintToGrPaint(this->recordingContext(), fSurfaceDrawContext->colorInfo(), paint,
- this->asMatrixProvider(), &grPaint)) {
- return;
- }
-
- fSurfaceDrawContext->drawPaint(this->clip(), std::move(grPaint), this->localToDevice());
- }
-
- void Device::drawPoints(SkCanvas::PointMode mode,
- size_t count,
- const SkPoint pts[],
- const SkPaint& paint) {
- ASSERT_SINGLE_OWNER
- GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawPoints", fContext.get());
- SkScalar width = paint.getStrokeWidth();
- if (width < 0) {
- return;
- }
-
- GrAA aa = fSurfaceDrawContext->chooseAA(paint);
-
- if (count == 2 && mode == SkCanvas::kLines_PointMode) {
- if (paint.getPathEffect()) {
- // Probably a dashed line. Draw as a path.
- GrPaint grPaint;
- if (SkPaintToGrPaint(this->recordingContext(),
- fSurfaceDrawContext->colorInfo(),
- paint,
- this->asMatrixProvider(),
- &grPaint)) {
- SkPath path;
- path.setIsVolatile(true);
- path.moveTo(pts[0]);
- path.lineTo(pts[1]);
- fSurfaceDrawContext->drawPath(this->clip(),
- std::move(grPaint),
- aa,
- this->localToDevice(),
- path,
- GrStyle(paint, SkPaint::kStroke_Style));
- }
- return;
- }
- if (!paint.getMaskFilter() &&
- paint.getStrokeWidth() > 0 && // drawStrokedLine doesn't support hairlines.
- paint.getStrokeCap() != SkPaint::kRound_Cap) { // drawStrokedLine doesn't do round caps.
- // Simple stroked line. Bypass path rendering.
- GrPaint grPaint;
- if (SkPaintToGrPaint(this->recordingContext(),
- fSurfaceDrawContext->colorInfo(),
- paint,
- this->asMatrixProvider(),
- &grPaint)) {
- fSurfaceDrawContext->drawStrokedLine(this->clip(),
- std::move(grPaint),
- aa,
- this->localToDevice(),
- pts,
- SkStrokeRec(paint, SkPaint::kStroke_Style));
- }
- return;
- }
- }
-
- SkScalar scales[2];
- bool isHairline = (0 == width) ||
- (1 == width && this->localToDevice().getMinMaxScales(scales) &&
- SkScalarNearlyEqual(scales[0], 1.f) && SkScalarNearlyEqual(scales[1], 1.f));
- // we only handle non-coverage-aa hairlines and paints without path effects or mask filters,
- // else we let the SkDraw call our drawPath()
- if (!isHairline ||
- paint.getPathEffect() ||
- paint.getMaskFilter() ||
- fSurfaceDrawContext->chooseAAType(aa) == GrAAType::kCoverage) {
- SkRasterClip rc(this->devClipBounds());
- SkDraw draw;
- draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(this->width(), this->height()), nullptr, 0);
- draw.fMatrixProvider = this;
- draw.fRC = &rc;
- draw.drawPoints(mode, count, pts, paint, this);
- return;
- }
-
- GrPrimitiveType primitiveType = point_mode_to_primitive_type(mode);
-
- const SkMatrixProvider* matrixProvider = this;
-
- GrPaint grPaint;
- if (!SkPaintToGrPaint(this->recordingContext(), fSurfaceDrawContext->colorInfo(), paint,
- *matrixProvider, &grPaint)) {
- return;
- }
-
- static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
- sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, SkToS32(count), pts, nullptr,
- nullptr);
-
- fSurfaceDrawContext->drawVertices(this->clip(), std::move(grPaint), *matrixProvider,
- std::move(vertices), &primitiveType);
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。