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:
void setRotationZ(float rotationZ);
float getCameraDistance() const;
void setCameraDistance(float cameraDistance);
void setClipRect(const std::optional<SkRect>& clipRect);
void setClipRRect(const std::optional<SkRRect>& clipRRect);
void setClipPath(const std::optional<SkPath>& clipPath);
void setClipRect(const std::optional<SkRect>& clipRect, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
void setClipRRect(const std::optional<SkRRect>& clipRRect, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
void setClipPath(const std::optional<SkPath>& clipPath, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
bool getClip() const { return this->clip; }
void setClip(bool clip);
......@@ -99,6 +99,8 @@ private:
std::optional<SkRect> clipRect;
std::optional<SkRRect> clipRRect;
std::optional<SkPath> clipPath;
SkClipOp clipOp;
bool clipAntiAlias;
bool clip;
SkMatrix transformMatrix;
......
......@@ -77,6 +77,8 @@ RenderNode::RenderNode(const sk_sp<RenderNodeContext>& context)
clipRect(),
clipRRect(),
clipPath(),
clipOp(SkClipOp::kIntersect),
clipAntiAlias(false),
clip(false),
transformMatrix(),
transformCamera(),
......@@ -166,22 +168,28 @@ void RenderNode::setCameraDistance(float cameraDistance) {
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->clipRRect.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->clipRRect = clipRRect;
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->clipRRect.reset();
this->clipPath = clipPath;
this->clipOp = op;
this->clipAntiAlias = doAntiAlias;
}
void RenderNode::setClip(bool clip) {
......@@ -225,18 +233,20 @@ void RenderNode::onDraw(SkCanvas* canvas) {
if (this->clip) {
canvas->save();
if (this->clipRect) {
canvas->clipRect(*this->clipRect);
canvas->clipRect(*this->clipRect, this->clipOp, this->clipAntiAlias);
} else if (this->clipRRect) {
canvas->clipRRect(*this->clipRRect);
canvas->clipRRect(*this->clipRRect, this->clipOp, this->clipAntiAlias);
} else if (this->clipPath) {
canvas->clipPath(*this->clipPath);
canvas->clipPath(*this->clipPath, this->clipOp, this->clipAntiAlias);
} 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) {
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 {
canvas->save();
}
......
......@@ -241,22 +241,45 @@ class RenderNode internal constructor(ptr: NativePointer, managed: Boolean = tru
reachabilityBarrier(this)
}
fun setClipRect(r: Rect) {
Stats.onNativeCall()
RenderNode_nSetClipRect(_ptr, r.left, r.top, r.right, r.bottom)
fun setClipRect(r: Rect, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
Stats.onNativeCall()
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()
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 {
Stats.onNativeCall()
RenderNode_nSetClipPath(_ptr, getPtr(p))
RenderNode_nSetClipPath(
ptr = _ptr,
pathPtr = getPtr(p),
mode = mode.ordinal,
antiAlias = antiAlias
)
} finally {
reachabilityBarrier(this)
reachabilityBarrier(p)
......@@ -435,15 +458,15 @@ private external fun RenderNode_nSetCameraDistance(ptr: NativePointer, distance:
@ExternalSymbolName("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")
@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")
@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")
@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
}
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);
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
(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);
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
(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);
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
......
......@@ -196,22 +196,22 @@ SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDi
}
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);
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
(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);
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
(KNativePointer ptr, KNativePointer pathPtr) {
(KNativePointer ptr, KNativePointer pathPtr, KInt mode, KBoolean antiAlias) {
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
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
......
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