Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3700b100 authored by Jorge Betancourt's avatar Jorge Betancourt
Browse files

add clipShader API to android.graphics.Canvas

Test: atest CtsUiRenderingTestCases:android.uirendering.cts.testclasses.ShaderClippingTests
Bug: 280116960

Change-Id: Ic78c4b2ca01e6af9e5af757aa64e15e248cadcf8
parent 70331c8b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -15667,6 +15667,7 @@ package android.graphics {
    method public boolean clipOutRect(@NonNull android.graphics.Rect);
    method public boolean clipOutRect(float, float, float, float);
    method public boolean clipOutRect(int, int, int, int);
    method @FlaggedApi("com.android.graphics.hwui.flags.clip_shader") public void clipOutShader(@NonNull android.graphics.Shader);
    method @Deprecated public boolean clipPath(@NonNull android.graphics.Path, @NonNull android.graphics.Region.Op);
    method public boolean clipPath(@NonNull android.graphics.Path);
    method @Deprecated public boolean clipRect(@NonNull android.graphics.RectF, @NonNull android.graphics.Region.Op);
@@ -15676,6 +15677,7 @@ package android.graphics {
    method @Deprecated public boolean clipRect(float, float, float, float, @NonNull android.graphics.Region.Op);
    method public boolean clipRect(float, float, float, float);
    method public boolean clipRect(int, int, int, int);
    method @FlaggedApi("com.android.graphics.hwui.flags.clip_shader") public void clipShader(@NonNull android.graphics.Shader);
    method public void concat(@Nullable android.graphics.Matrix);
    method @FlaggedApi("com.android.graphics.hwui.flags.matrix_44") public void concat44(@Nullable android.graphics.Matrix44);
    method public void disableZ();
+26 −0
Original line number Diff line number Diff line
@@ -1128,6 +1128,30 @@ public class Canvas extends BaseCanvas {
        return false;
    }

    /**
     * Intersect the current clip with the specified shader.
     * The shader will be treated as an alpha mask, taking the intersection of the two.
     *
     * @param shader The shader to intersect with the current clip
     */
    @FlaggedApi(Flags.FLAG_CLIP_SHADER)
    public void clipShader(@NonNull Shader shader) {
        nClipShader(mNativeCanvasWrapper, shader.getNativeInstance(),
                Region.Op.INTERSECT.nativeInt);
    }

    /**
     * Set the clip to the difference of the current clip and the shader.
     * The shader will be treated as an alpha mask, taking the difference of the two.
     *
     * @param shader The shader to intersect with the current clip
     */
    @FlaggedApi(Flags.FLAG_CLIP_SHADER)
    public void clipOutShader(@NonNull Shader shader) {
        nClipShader(mNativeCanvasWrapper, shader.getNativeInstance(),
                Region.Op.DIFFERENCE.nativeInt);
    }

    public @Nullable DrawFilter getDrawFilter() {
        return mDrawFilter;
    }
@@ -1472,6 +1496,8 @@ public class Canvas extends BaseCanvas {
    @CriticalNative
    private static native boolean nClipPath(long nativeCanvas, long nativePath, int regionOp);
    @CriticalNative
    private static native void nClipShader(long nativeCanvas, long nativeShader, int regionOp);
    @CriticalNative
    private static native void nSetDrawFilter(long nativeCanvas, long nativeFilter);
    @CriticalNative
    private static native void nGetMatrix(long nativeCanvas, long nativeMatrix);
+11 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ public:
            : mType(Type::RRect), mOp(op), mMatrix(m), mRRect(rrect) {}
    Clip(const SkPath& path, SkClipOp op, const SkMatrix& m)
            : mType(Type::Path), mOp(op), mMatrix(m), mPath(std::in_place, path) {}
    Clip(const sk_sp<SkShader> shader, SkClipOp op, const SkMatrix& m)
            : mType(Type::Shader), mOp(op), mMatrix(m), mShader(shader) {}

    void apply(SkCanvas* canvas) const {
        canvas->setMatrix(mMatrix);
@@ -86,6 +88,8 @@ public:
                // Ensure path clips are anti-aliased
                canvas->clipPath(mPath.value(), mOp, true);
                break;
            case Type::Shader:
                canvas->clipShader(mShader, mOp);
        }
    }

@@ -94,6 +98,7 @@ private:
        Rect,
        RRect,
        Path,
        Shader,
    };

    Type mType;
@@ -103,6 +108,7 @@ private:
    // These are logically a union (tracked separately due to non-POD path).
    std::optional<SkPath> mPath;
    SkRRect mRRect;
    sk_sp<SkShader> mShader;
};

Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
@@ -413,6 +419,11 @@ bool SkiaCanvas::clipPath(const SkPath* path, SkClipOp op) {
    return !mCanvas->isClipEmpty();
}

void SkiaCanvas::clipShader(sk_sp<SkShader> shader, SkClipOp op) {
    this->recordClip(shader, op);
    mCanvas->clipShader(shader, op);
}

bool SkiaCanvas::replaceClipRect_deprecated(float left, float top, float right, float bottom) {
    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);

+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ public:
    virtual bool quickRejectPath(const SkPath& path) const override;
    virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
    virtual bool clipPath(const SkPath* path, SkClipOp op) override;
    virtual void clipShader(sk_sp<SkShader> shader, SkClipOp op) override;
    virtual bool replaceClipRect_deprecated(float left, float top, float right,
                                            float bottom) override;
    virtual bool replaceClipPath_deprecated(const SkPath* path) override;
+1 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ public:

    virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) = 0;
    virtual bool clipPath(const SkPath* path, SkClipOp op) = 0;
    virtual void clipShader(sk_sp<SkShader> shader, SkClipOp op) = 0;
    // Resets clip to wide open, used to emulate the now-removed SkClipOp::kReplace on
    // apps with compatibility < P. Canvases for version P and later are restricted to
    // intersect and difference at the Java level, matching SkClipOp's definition.
Loading