Unverified Commit 3c54c1b7 authored by Ivan Matkov's avatar Ivan Matkov Committed by GitHub

Add clip mode and anti-alias options to RenderNode (#1018)

Required to fix https://youtrack.jetbrains.com/issue/CMP-7508

Test: covered by existing tests
parent 09dae793
...@@ -55,9 +55,9 @@ public: ...@@ -55,9 +55,9 @@ public:
void setRotationZ(float rotationZ); void setRotationZ(float rotationZ);
float getCameraDistance() const; float getCameraDistance() const;
void setCameraDistance(float cameraDistance); void setCameraDistance(float cameraDistance);
void setClipRect(const std::optional<SkRect>& clipRect); void setClipRect(const std::optional<SkRect>& clipRect, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
void setClipRRect(const std::optional<SkRRect>& clipRRect); void setClipRRect(const std::optional<SkRRect>& clipRRect, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
void setClipPath(const std::optional<SkPath>& clipPath); void setClipPath(const std::optional<SkPath>& clipPath, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
bool getClip() const { return this->clip; } bool getClip() const { return this->clip; }
void setClip(bool clip); void setClip(bool clip);
...@@ -99,6 +99,8 @@ private: ...@@ -99,6 +99,8 @@ private:
std::optional<SkRect> clipRect; std::optional<SkRect> clipRect;
std::optional<SkRRect> clipRRect; std::optional<SkRRect> clipRRect;
std::optional<SkPath> clipPath; std::optional<SkPath> clipPath;
SkClipOp clipOp;
bool clipAntiAlias;
bool clip; bool clip;
SkMatrix transformMatrix; SkMatrix transformMatrix;
......
...@@ -77,6 +77,8 @@ RenderNode::RenderNode(const sk_sp<RenderNodeContext>& context) ...@@ -77,6 +77,8 @@ RenderNode::RenderNode(const sk_sp<RenderNodeContext>& context)
clipRect(), clipRect(),
clipRRect(), clipRRect(),
clipPath(), clipPath(),
clipOp(SkClipOp::kIntersect),
clipAntiAlias(false),
clip(false), clip(false),
transformMatrix(), transformMatrix(),
transformCamera(), transformCamera(),
...@@ -166,22 +168,28 @@ void RenderNode::setCameraDistance(float cameraDistance) { ...@@ -166,22 +168,28 @@ void RenderNode::setCameraDistance(float cameraDistance) {
this->matrixDirty = true; this->matrixDirty = true;
} }
void RenderNode::setClipRect(const std::optional<SkRect>& clipRect) { void RenderNode::setClipRect(const std::optional<SkRect>& clipRect, SkClipOp op, bool doAntiAlias) {
this->clipRect = clipRect; this->clipRect = clipRect;
this->clipRRect.reset(); this->clipRRect.reset();
this->clipPath.reset(); this->clipPath.reset();
this->clipOp = op;
this->clipAntiAlias = doAntiAlias;
} }
void RenderNode::setClipRRect(const std::optional<SkRRect>& clipRRect) { void RenderNode::setClipRRect(const std::optional<SkRRect>& clipRRect, SkClipOp op, bool doAntiAlias) {
this->clipRect.reset(); this->clipRect.reset();
this->clipRRect = clipRRect; this->clipRRect = clipRRect;
this->clipPath.reset(); this->clipPath.reset();
this->clipOp = op;
this->clipAntiAlias = doAntiAlias;
} }
void RenderNode::setClipPath(const std::optional<SkPath>& clipPath) { void RenderNode::setClipPath(const std::optional<SkPath>& clipPath, SkClipOp op, bool doAntiAlias) {
this->clipRect.reset(); this->clipRect.reset();
this->clipRRect.reset(); this->clipRRect.reset();
this->clipPath = clipPath; this->clipPath = clipPath;
this->clipOp = op;
this->clipAntiAlias = doAntiAlias;
} }
void RenderNode::setClip(bool clip) { void RenderNode::setClip(bool clip) {
...@@ -225,18 +233,20 @@ void RenderNode::onDraw(SkCanvas* canvas) { ...@@ -225,18 +233,20 @@ void RenderNode::onDraw(SkCanvas* canvas) {
if (this->clip) { if (this->clip) {
canvas->save(); canvas->save();
if (this->clipRect) { if (this->clipRect) {
canvas->clipRect(*this->clipRect); canvas->clipRect(*this->clipRect, this->clipOp, this->clipAntiAlias);
} else if (this->clipRRect) { } else if (this->clipRRect) {
canvas->clipRRect(*this->clipRRect); canvas->clipRRect(*this->clipRRect, this->clipOp, this->clipAntiAlias);
} else if (this->clipPath) { } else if (this->clipPath) {
canvas->clipPath(*this->clipPath); canvas->clipPath(*this->clipPath, this->clipOp, this->clipAntiAlias);
} else { } else {
canvas->clipRect(SkRect::MakeWH(this->bounds.width(), this->bounds.height())); auto rect = SkRect::MakeWH(this->bounds.width(), this->bounds.height());
canvas->clipRect(rect, this->clipOp, this->clipAntiAlias);
} }
} }
if (this->layerPaint) { if (this->layerPaint) {
canvas->saveLayer(SkRect::MakeWH(this->bounds.width(), this->bounds.height()), &*this->layerPaint); auto rect = SkRect::MakeWH(this->bounds.width(), this->bounds.height());
canvas->saveLayer(rect, &*this->layerPaint);
} else { } else {
canvas->save(); canvas->save();
} }
......
...@@ -241,22 +241,45 @@ class RenderNode internal constructor(ptr: NativePointer, managed: Boolean = tru ...@@ -241,22 +241,45 @@ class RenderNode internal constructor(ptr: NativePointer, managed: Boolean = tru
reachabilityBarrier(this) reachabilityBarrier(this)
} }
fun setClipRect(r: Rect) { fun setClipRect(r: Rect, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
Stats.onNativeCall() Stats.onNativeCall()
RenderNode_nSetClipRect(_ptr, r.left, r.top, r.right, r.bottom) RenderNode_nSetClipRect(
ptr = _ptr,
left = r.left,
top = r.top,
right = r.right,
bottom = r.bottom,
mode = mode.ordinal,
antiAlias = antiAlias
)
} }
fun setClipRRect(r: RRect) { fun setClipRRect(r: RRect, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
Stats.onNativeCall() Stats.onNativeCall()
interopScope { interopScope {
RenderNode_nSetClipRRect(_ptr, r.left, r.top, r.right, r.bottom, toInterop(r.radii), r.radii.size) RenderNode_nSetClipRRect(
ptr = _ptr,
left = r.left,
top = r.top,
right = r.right,
bottom = r.bottom,
radii = toInterop(r.radii),
radiiSize = r.radii.size,
mode = mode.ordinal,
antiAlias = antiAlias
)
} }
} }
fun setClipPath(p: Path?) { fun setClipPath(p: Path?, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
try { try {
Stats.onNativeCall() Stats.onNativeCall()
RenderNode_nSetClipPath(_ptr, getPtr(p)) RenderNode_nSetClipPath(
ptr = _ptr,
pathPtr = getPtr(p),
mode = mode.ordinal,
antiAlias = antiAlias
)
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(p) reachabilityBarrier(p)
...@@ -435,15 +458,15 @@ private external fun RenderNode_nSetCameraDistance(ptr: NativePointer, distance: ...@@ -435,15 +458,15 @@ private external fun RenderNode_nSetCameraDistance(ptr: NativePointer, distance:
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect") @ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect") @ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect")
private external fun RenderNode_nSetClipRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float) private external fun RenderNode_nSetClipRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, mode: Int, antiAlias: Boolean)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect") @ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect") @ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect")
private external fun RenderNode_nSetClipRRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, radii: InteropPointer, radiiSize: Int) private external fun RenderNode_nSetClipRRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, radii: InteropPointer, radiiSize: Int, mode: Int, antiAlias: Boolean)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath") @ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath") @ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath")
private external fun RenderNode_nSetClipPath(ptr: NativePointer, pathPtr: NativePointer) private external fun RenderNode_nSetClipPath(ptr: NativePointer, pathPtr: NativePointer, mode: Int, antiAlias: Boolean)
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip") @ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip")
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip") @ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip")
......
...@@ -197,22 +197,22 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_Ren ...@@ -197,22 +197,22 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_Ren
} }
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom) { (JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jint mode, jboolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr); auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom)); instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom), static_cast<SkClipOp>(mode), antiAlias);
} }
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloatArray radii, jint radiiSize) { (JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloatArray radii, jint radiiSize, jint mode, jboolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr); auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRRect(skija::RRect::toSkRRect(env, left, top, right, bottom, radii)); instance->setClipRRect(skija::RRect::toSkRRect(env, left, top, right, bottom, radii), static_cast<SkClipOp>(mode), antiAlias);
} }
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath
(JNIEnv *env, jclass jclass, jlong ptr, jlong pathPtr) { (JNIEnv *env, jclass jclass, jlong ptr, jlong pathPtr, jint mode, jboolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr); auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkPath* path = reinterpret_cast<SkPath*>(static_cast<uintptr_t>(pathPtr)); SkPath* path = reinterpret_cast<SkPath*>(static_cast<uintptr_t>(pathPtr));
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt); instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt, static_cast<SkClipOp>(mode), antiAlias);
} }
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip
......
...@@ -196,22 +196,22 @@ SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDi ...@@ -196,22 +196,22 @@ SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDi
} }
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom) { (KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KInt mode, KBoolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr); auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom)); instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom), static_cast<SkClipOp>(mode), antiAlias);
} }
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KFloat* radii, KInt radiiSize) { (KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KFloat* radii, KInt radiiSize, KInt mode, KBoolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr); auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
instance->setClipRRect(skija::RRect::toSkRRect(left, top, right, bottom, radii, radiiSize)); instance->setClipRRect(skija::RRect::toSkRRect(left, top, right, bottom, radii, radiiSize), static_cast<SkClipOp>(mode), antiAlias);
} }
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath
(KNativePointer ptr, KNativePointer pathPtr) { (KNativePointer ptr, KNativePointer pathPtr, KInt mode, KBoolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr); auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
SkPath* path = reinterpret_cast<SkPath*>(pathPtr); SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt); instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt, static_cast<SkClipOp>(mode), antiAlias);
} }
SKIKO_EXPORT KBoolean org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip SKIKO_EXPORT KBoolean org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment