Skip to content

Commit 3c54c1b

Browse files
authored
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
1 parent 09dae79 commit 3c54c1b

File tree

5 files changed

+67
-32
lines changed

5 files changed

+67
-32
lines changed

skiko/src/commonMain/cpp/common/include/node/RenderNode.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ class RenderNode : public SkDrawable {
5555
void setRotationZ(float rotationZ);
5656
float getCameraDistance() const;
5757
void setCameraDistance(float cameraDistance);
58-
void setClipRect(const std::optional<SkRect>& clipRect);
59-
void setClipRRect(const std::optional<SkRRect>& clipRRect);
60-
void setClipPath(const std::optional<SkPath>& clipPath);
58+
void setClipRect(const std::optional<SkRect>& clipRect, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
59+
void setClipRRect(const std::optional<SkRRect>& clipRRect, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
60+
void setClipPath(const std::optional<SkPath>& clipPath, SkClipOp op = SkClipOp::kIntersect, bool doAntiAlias = false);
6161
bool getClip() const { return this->clip; }
6262
void setClip(bool clip);
6363

@@ -99,6 +99,8 @@ class RenderNode : public SkDrawable {
9999
std::optional<SkRect> clipRect;
100100
std::optional<SkRRect> clipRRect;
101101
std::optional<SkPath> clipPath;
102+
SkClipOp clipOp;
103+
bool clipAntiAlias;
102104
bool clip;
103105

104106
SkMatrix transformMatrix;

skiko/src/commonMain/cpp/common/node/RenderNode.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ RenderNode::RenderNode(const sk_sp<RenderNodeContext>& context)
7777
clipRect(),
7878
clipRRect(),
7979
clipPath(),
80+
clipOp(SkClipOp::kIntersect),
81+
clipAntiAlias(false),
8082
clip(false),
8183
transformMatrix(),
8284
transformCamera(),
@@ -166,22 +168,28 @@ void RenderNode::setCameraDistance(float cameraDistance) {
166168
this->matrixDirty = true;
167169
}
168170

169-
void RenderNode::setClipRect(const std::optional<SkRect>& clipRect) {
171+
void RenderNode::setClipRect(const std::optional<SkRect>& clipRect, SkClipOp op, bool doAntiAlias) {
170172
this->clipRect = clipRect;
171173
this->clipRRect.reset();
172174
this->clipPath.reset();
175+
this->clipOp = op;
176+
this->clipAntiAlias = doAntiAlias;
173177
}
174178

175-
void RenderNode::setClipRRect(const std::optional<SkRRect>& clipRRect) {
179+
void RenderNode::setClipRRect(const std::optional<SkRRect>& clipRRect, SkClipOp op, bool doAntiAlias) {
176180
this->clipRect.reset();
177181
this->clipRRect = clipRRect;
178182
this->clipPath.reset();
183+
this->clipOp = op;
184+
this->clipAntiAlias = doAntiAlias;
179185
}
180186

181-
void RenderNode::setClipPath(const std::optional<SkPath>& clipPath) {
187+
void RenderNode::setClipPath(const std::optional<SkPath>& clipPath, SkClipOp op, bool doAntiAlias) {
182188
this->clipRect.reset();
183189
this->clipRRect.reset();
184190
this->clipPath = clipPath;
191+
this->clipOp = op;
192+
this->clipAntiAlias = doAntiAlias;
185193
}
186194

187195
void RenderNode::setClip(bool clip) {
@@ -225,18 +233,20 @@ void RenderNode::onDraw(SkCanvas* canvas) {
225233
if (this->clip) {
226234
canvas->save();
227235
if (this->clipRect) {
228-
canvas->clipRect(*this->clipRect);
236+
canvas->clipRect(*this->clipRect, this->clipOp, this->clipAntiAlias);
229237
} else if (this->clipRRect) {
230-
canvas->clipRRect(*this->clipRRect);
238+
canvas->clipRRect(*this->clipRRect, this->clipOp, this->clipAntiAlias);
231239
} else if (this->clipPath) {
232-
canvas->clipPath(*this->clipPath);
240+
canvas->clipPath(*this->clipPath, this->clipOp, this->clipAntiAlias);
233241
} else {
234-
canvas->clipRect(SkRect::MakeWH(this->bounds.width(), this->bounds.height()));
242+
auto rect = SkRect::MakeWH(this->bounds.width(), this->bounds.height());
243+
canvas->clipRect(rect, this->clipOp, this->clipAntiAlias);
235244
}
236245
}
237246

238247
if (this->layerPaint) {
239-
canvas->saveLayer(SkRect::MakeWH(this->bounds.width(), this->bounds.height()), &*this->layerPaint);
248+
auto rect = SkRect::MakeWH(this->bounds.width(), this->bounds.height());
249+
canvas->saveLayer(rect, &*this->layerPaint);
240250
} else {
241251
canvas->save();
242252
}

skiko/src/commonMain/kotlin/org/jetbrains/skiko/node/RenderNode.kt

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,22 +241,45 @@ class RenderNode internal constructor(ptr: NativePointer, managed: Boolean = tru
241241
reachabilityBarrier(this)
242242
}
243243

244-
fun setClipRect(r: Rect) {
244+
fun setClipRect(r: Rect, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
245245
Stats.onNativeCall()
246-
RenderNode_nSetClipRect(_ptr, r.left, r.top, r.right, r.bottom)
246+
RenderNode_nSetClipRect(
247+
ptr = _ptr,
248+
left = r.left,
249+
top = r.top,
250+
right = r.right,
251+
bottom = r.bottom,
252+
mode = mode.ordinal,
253+
antiAlias = antiAlias
254+
)
247255
}
248256

249-
fun setClipRRect(r: RRect) {
257+
fun setClipRRect(r: RRect, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
250258
Stats.onNativeCall()
251259
interopScope {
252-
RenderNode_nSetClipRRect(_ptr, r.left, r.top, r.right, r.bottom, toInterop(r.radii), r.radii.size)
260+
RenderNode_nSetClipRRect(
261+
ptr = _ptr,
262+
left = r.left,
263+
top = r.top,
264+
right = r.right,
265+
bottom = r.bottom,
266+
radii = toInterop(r.radii),
267+
radiiSize = r.radii.size,
268+
mode = mode.ordinal,
269+
antiAlias = antiAlias
270+
)
253271
}
254272
}
255273

256-
fun setClipPath(p: Path?) {
274+
fun setClipPath(p: Path?, mode: ClipMode = ClipMode.INTERSECT, antiAlias: Boolean = false) {
257275
try {
258276
Stats.onNativeCall()
259-
RenderNode_nSetClipPath(_ptr, getPtr(p))
277+
RenderNode_nSetClipPath(
278+
ptr = _ptr,
279+
pathPtr = getPtr(p),
280+
mode = mode.ordinal,
281+
antiAlias = antiAlias
282+
)
260283
} finally {
261284
reachabilityBarrier(this)
262285
reachabilityBarrier(p)
@@ -435,15 +458,15 @@ private external fun RenderNode_nSetCameraDistance(ptr: NativePointer, distance:
435458

436459
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect")
437460
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect")
438-
private external fun RenderNode_nSetClipRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float)
461+
private external fun RenderNode_nSetClipRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, mode: Int, antiAlias: Boolean)
439462

440463
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect")
441464
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect")
442-
private external fun RenderNode_nSetClipRRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, radii: InteropPointer, radiiSize: Int)
465+
private external fun RenderNode_nSetClipRRect(ptr: NativePointer, left: Float, top: Float, right: Float, bottom: Float, radii: InteropPointer, radiiSize: Int, mode: Int, antiAlias: Boolean)
443466

444467
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath")
445468
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath")
446-
private external fun RenderNode_nSetClipPath(ptr: NativePointer, pathPtr: NativePointer)
469+
private external fun RenderNode_nSetClipPath(ptr: NativePointer, pathPtr: NativePointer, mode: Int, antiAlias: Boolean)
447470

448471
@ExternalSymbolName("org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip")
449472
@ModuleImport("./skiko.mjs", "org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip")

skiko/src/jvmMain/cpp/common/node/RenderNode.jvm.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,22 +197,22 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_Ren
197197
}
198198

199199
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect
200-
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
200+
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jint mode, jboolean antiAlias) {
201201
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
202-
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom));
202+
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom), static_cast<SkClipOp>(mode), antiAlias);
203203
}
204204

205205
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect
206-
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloatArray radii, jint radiiSize) {
206+
(JNIEnv *env, jclass jclass, jlong ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloatArray radii, jint radiiSize, jint mode, jboolean antiAlias) {
207207
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
208-
instance->setClipRRect(skija::RRect::toSkRRect(env, left, top, right, bottom, radii));
208+
instance->setClipRRect(skija::RRect::toSkRRect(env, left, top, right, bottom, radii), static_cast<SkClipOp>(mode), antiAlias);
209209
}
210210

211211
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath
212-
(JNIEnv *env, jclass jclass, jlong ptr, jlong pathPtr) {
212+
(JNIEnv *env, jclass jclass, jlong ptr, jlong pathPtr, jint mode, jboolean antiAlias) {
213213
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
214214
SkPath* path = reinterpret_cast<SkPath*>(static_cast<uintptr_t>(pathPtr));
215-
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt);
215+
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt, static_cast<SkClipOp>(mode), antiAlias);
216216
}
217217

218218
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip

skiko/src/nativeJsMain/cpp/node/RenderNode.native.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,22 +196,22 @@ SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetCameraDi
196196
}
197197

198198
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRect
199-
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom) {
199+
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KInt mode, KBoolean antiAlias) {
200200
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
201-
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom));
201+
instance->setClipRect(SkRect::MakeLTRB(left, top, right, bottom), static_cast<SkClipOp>(mode), antiAlias);
202202
}
203203

204204
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipRRect
205-
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KFloat* radii, KInt radiiSize) {
205+
(KNativePointer ptr, KFloat left, KFloat top, KFloat right, KFloat bottom, KFloat* radii, KInt radiiSize, KInt mode, KBoolean antiAlias) {
206206
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
207-
instance->setClipRRect(skija::RRect::toSkRRect(left, top, right, bottom, radii, radiiSize));
207+
instance->setClipRRect(skija::RRect::toSkRRect(left, top, right, bottom, radii, radiiSize), static_cast<SkClipOp>(mode), antiAlias);
208208
}
209209

210210
SKIKO_EXPORT void org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nSetClipPath
211-
(KNativePointer ptr, KNativePointer pathPtr) {
211+
(KNativePointer ptr, KNativePointer pathPtr, KInt mode, KBoolean antiAlias) {
212212
auto instance = reinterpret_cast<skiko::node::RenderNode *>(ptr);
213213
SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
214-
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt);
214+
instance->setClipPath(path ? std::optional<SkPath>{*path} : std::nullopt, static_cast<SkClipOp>(mode), antiAlias);
215215
}
216216

217217
SKIKO_EXPORT KBoolean org_jetbrains_skiko_node_RenderNodeKt_RenderNode_1nGetClip

0 commit comments

Comments
 (0)