-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a way to replace picture placeholders during drawing (#1009)
New `PictureFilterCanvas` class that allows override picture rendering during drawing Required for JetBrains/compose-multiplatform-core#1766
- Loading branch information
1 parent
cbf3345
commit c22b0fc
Showing
12 changed files
with
276 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
skiko/src/commonMain/kotlin/org/jetbrains/skia/PictureFilterCanvas.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.jetbrains.skia | ||
|
||
import org.jetbrains.skia.impl.Library.Companion.staticLoad | ||
import org.jetbrains.skia.impl.NativePointer | ||
import org.jetbrains.skia.impl.Stats | ||
import org.jetbrains.skia.impl.getPtr | ||
import org.jetbrains.skia.impl.reachabilityBarrier | ||
|
||
abstract class PictureFilterCanvas(canvas: Canvas) : | ||
Canvas(makePictureFilterCanvas(canvas), true, this) { | ||
private companion object { | ||
init { | ||
staticLoad() | ||
} | ||
} | ||
init { | ||
Stats.onNativeCall() | ||
try { | ||
doInit(_ptr) | ||
} finally { | ||
reachabilityBarrier(this) | ||
} | ||
} | ||
|
||
protected abstract fun onDrawPicture(picture: Picture, matrix: Matrix33? = null, paint: Paint? = null): Boolean | ||
|
||
fun onDrawPicture(picturePtr: NativePointer, matrixPtr: NativePointer, paintPtr: NativePointer): Boolean { | ||
val picture = Picture(picturePtr, managed = false) | ||
// TODO: Provide mapping for matrix arg | ||
val paint = if (paintPtr == NullPointer) null else Paint(paintPtr, managed = false) | ||
return onDrawPicture(picture, null, paint) | ||
} | ||
} | ||
|
||
private fun makePictureFilterCanvas(canvas: Canvas): NativePointer { | ||
Stats.onNativeCall() | ||
return try { | ||
PictureFilterCanvas_nMake(getPtr(canvas)) | ||
} finally { | ||
reachabilityBarrier(canvas) | ||
} | ||
} | ||
|
||
internal expect fun PictureFilterCanvas.doInit(ptr: NativePointer) | ||
|
||
@ExternalSymbolName("org_jetbrains_skia_PictureFilterCanvas__1nMake") | ||
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_PictureFilterCanvas__1nMake") | ||
private external fun PictureFilterCanvas_nMake(canvasPtr: NativePointer): NativePointer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include <jni.h> | ||
#include "SkNWayCanvas.h" | ||
#include "interop.hh" | ||
|
||
class SkikoPictureFilterCanvas : public SkNWayCanvas { | ||
public: | ||
SkikoPictureFilterCanvas(SkCanvas* canvas) : | ||
SkNWayCanvas(canvas->imageInfo().width(), canvas->imageInfo().height()), | ||
_jobject(nullptr) { | ||
this->addCanvas(canvas); | ||
} | ||
|
||
virtual ~SkikoPictureFilterCanvas() { | ||
skija::PictureFilterCanvas::detach(_jobject); | ||
} | ||
|
||
jobject _jobject; | ||
|
||
protected: | ||
void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) override { | ||
jboolean handled = skija::PictureFilterCanvas::onDrawPicture(_jobject, picture, matrix, paint); | ||
if (!handled) { | ||
SkCanvas::onDrawPicture(picture, matrix, paint); | ||
} | ||
} | ||
}; | ||
|
||
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_PictureFilterCanvas_1jvmKt_PictureFilterCanvas_1nInit | ||
(JNIEnv* env, jclass jclass, jobject pictureFilterCanvas, jlong canvasPtr) { | ||
SkikoPictureFilterCanvas* canvas = reinterpret_cast<SkikoPictureFilterCanvas*>(static_cast<uintptr_t>(canvasPtr)); | ||
canvas->_jobject = skija::PictureFilterCanvas::attach(env, pictureFilterCanvas); | ||
} | ||
|
||
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_PictureFilterCanvasKt_PictureFilterCanvas_1nMake | ||
(JNIEnv* env, jclass jclass, SkCanvas* canvas) { | ||
SkikoPictureFilterCanvas* filterCanvas = new SkikoPictureFilterCanvas(canvas); | ||
return reinterpret_cast<jlong>(filterCanvas); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
skiko/src/jvmMain/kotlin/org/jetbrains/skia/PictureFilterCanvas.jvm.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.jetbrains.skia | ||
|
||
import org.jetbrains.skia.impl.NativePointer | ||
|
||
internal actual fun PictureFilterCanvas.doInit(ptr: NativePointer) { | ||
PictureFilterCanvas_nInit(this, ptr) | ||
} | ||
|
||
private external fun PictureFilterCanvas_nInit(thisPtr: PictureFilterCanvas, canvasPtr: NativePointer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#include "SkNWayCanvas.h" | ||
#include "common.h" | ||
|
||
class SkikoPictureFilterCanvas : public SkNWayCanvas { | ||
public: | ||
SkikoPictureFilterCanvas(SkCanvas* canvas) : | ||
SkNWayCanvas(canvas->imageInfo().width(), canvas->imageInfo().height()), | ||
_onDrawPicture(nullptr), | ||
_onDrawPicture_picture(nullptr), | ||
_onDrawPicture_matrix(nullptr), | ||
_onDrawPicture_paint(nullptr) { | ||
this->addCanvas(canvas); | ||
} | ||
|
||
KBooleanCallback _onDrawPicture; | ||
|
||
// TODO: Support callback with parameters properly | ||
const SkPicture* _onDrawPicture_picture; | ||
const SkMatrix* _onDrawPicture_matrix; | ||
const SkPaint* _onDrawPicture_paint; | ||
|
||
protected: | ||
void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) override { | ||
_onDrawPicture_picture = picture; | ||
_onDrawPicture_matrix = matrix; | ||
_onDrawPicture_paint = paint; | ||
|
||
KBoolean handled = _onDrawPicture(); | ||
|
||
_onDrawPicture_picture = nullptr; | ||
_onDrawPicture_matrix = nullptr; | ||
_onDrawPicture_paint = nullptr; | ||
|
||
if (!handled) { | ||
SkCanvas::onDrawPicture(picture, matrix, paint); | ||
} | ||
} | ||
}; | ||
|
||
SKIKO_EXPORT KNativePointer org_jetbrains_skia_SkikoPictureFilterCanvas__1nMake | ||
(SkCanvas* canvas) { | ||
SkikoPictureFilterCanvas* filterCanvas = new SkikoPictureFilterCanvas(canvas); | ||
return reinterpret_cast<KNativePointer>(filterCanvas); | ||
} | ||
|
||
SKIKO_EXPORT void org_jetbrains_skia_SkikoPictureFilterCanvas__1nInit | ||
(KNativePointer canvasPtr, KInteropPointer onDrawPicture) { | ||
SkikoPictureFilterCanvas* canvas = reinterpret_cast<SkikoPictureFilterCanvas*>(canvasPtr); | ||
canvas->_onDrawPicture = KBooleanCallback(onDrawPicture); | ||
} | ||
|
||
SKIKO_EXPORT KNativePointer org_jetbrains_skia_SkikoPictureFilterCanvas__1nGetOnDrawPicture_picture | ||
(KNativePointer canvasPtr) { | ||
SkikoPictureFilterCanvas* canvas = reinterpret_cast<SkikoPictureFilterCanvas*>(canvasPtr); | ||
return reinterpret_cast<KNativePointer>(const_cast<SkPicture *>(canvas->_onDrawPicture_picture)); | ||
} | ||
|
||
SKIKO_EXPORT KNativePointer org_jetbrains_skia_SkikoPictureFilterCanvas__1nGetOnDrawPicture_matrix | ||
(KNativePointer canvasPtr) { | ||
SkikoPictureFilterCanvas* canvas = reinterpret_cast<SkikoPictureFilterCanvas*>(canvasPtr); | ||
return reinterpret_cast<KNativePointer>(const_cast<SkMatrix *>(canvas->_onDrawPicture_matrix)); | ||
} | ||
|
||
SKIKO_EXPORT KNativePointer org_jetbrains_skia_SkikoPictureFilterCanvas__1nGetOnDrawPicture_paint | ||
(KNativePointer canvasPtr) { | ||
SkikoPictureFilterCanvas* canvas = reinterpret_cast<SkikoPictureFilterCanvas*>(canvasPtr); | ||
return reinterpret_cast<KNativePointer>(const_cast<SkPaint *>(canvas->_onDrawPicture_paint)); | ||
} |
Oops, something went wrong.