Unverified Commit 8be256ce authored by Aleksandr Veselov's avatar Aleksandr Veselov Committed by GitHub

Implement PaintFilterCanvas for native (#377)

parent 5d25c129
package org.jetbrains.skia
import org.jetbrains.skia.impl.*
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
/**
* A utility proxy base class for implementing draw/paint filters.
*/
abstract class PaintFilterCanvas(canvas: Canvas, unrollDrawable: Boolean) :
abstract class PaintFilterCanvas(private val canvas: Canvas, unrollDrawable: Boolean) :
Canvas(PaintFilterCanvas_nMake(getPtr(canvas), unrollDrawable), true, canvas) {
companion object {
init {
......@@ -37,15 +34,21 @@ abstract class PaintFilterCanvas(canvas: Canvas, unrollDrawable: Boolean) :
*/
init {
Stats.onNativeCall()
_nAttachToJava(_ptr)
doInit(_ptr)
Stats.onNativeCall()
reachabilityBarrier(canvas)
}
}
internal expect fun PaintFilterCanvas.doInit(ptr: NativePointer)
@ExternalSymbolName("org_jetbrains_skia_PaintFilterCanvas__1nMake")
private external fun PaintFilterCanvas_nMake(canvasPtr: NativePointer, unrollDrawable: Boolean): NativePointer
@ExternalSymbolName("org_jetbrains_skia_PaintFilterCanvas__1nAttachToJava")
external fun _nAttachToJava(canvasPtr: NativePointer)
// Native/JS only
@ExternalSymbolName("org_jetbrains_skia_PaintFilterCanvas__1nInit")
internal external fun PaintFilterCanvas_nInit(ptr: NativePointer, onFilter: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_PaintFilterCanvas__1nGetOnFilterPaint")
internal external fun PaintFilterCanvas_nGetOnFilterPaint(ptr: NativePointer): NativePointer
package org.jetbrains.skia
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class PaintFilterCanvasTest {
@Test
fun canFilter() {
val surface = Surface.makeRasterN32Premul(16, 16)
val canvas = surface.canvas
var called = false
val canvasFilterRed = object : PaintFilterCanvas(canvas, true) {
override fun onFilter(paint: Paint): Boolean {
called = true
return paint.color == Color.RED
}
}
canvasFilterRed.drawRect(
Rect(0f, 0f, 8f, 8f),
Paint().apply { color = Color.RED }
)
canvasFilterRed.drawRect(
Rect(0f, 0f, 8f, 8f),
Paint().apply { color = Color.BLUE }
) // Must not be drawn
val pixels = Bitmap.makeFromImage(surface.makeImageSnapshot())
assertTrue(called)
assertEquals(Color.RED, pixels.getColor(2, 2))
}
}
\ No newline at end of file
......@@ -32,11 +32,11 @@ protected:
}
private:
float unrollDrawable;
bool unrollDrawable;
};
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_PaintFilterCanvasKt__1nAttachToJava
(JNIEnv* env, jobject jobj, jlong canvasPtr, jboolean unrollDrawable) {
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_PaintFilterCanvas_1jvmKt_PaintFilterCanvas_1nInit
(JNIEnv* env, jclass jclass, jobject jobj, jlong canvasPtr) {
SkijaPaintFilterCanvas* canvas = reinterpret_cast<SkijaPaintFilterCanvas*>(static_cast<uintptr_t>(canvasPtr));
canvas->jobj = skija::PaintFilterCanvas::attach(env, jobj);
}
......
package org.jetbrains.skia
import org.jetbrains.skia.impl.NativePointer
internal actual fun PaintFilterCanvas.doInit(ptr: NativePointer) {
PaintFilterCanvas_nInit(this, ptr)
}
private external fun PaintFilterCanvas_nInit(thisPtr: PaintFilterCanvas, canvasPtr: NativePointer)
......@@ -7,33 +7,58 @@
#include "SkPaintFilterCanvas.h"
#include "common.h"
class SkijaPaintFilterCanvas : public SkPaintFilterCanvas {
public:
SkijaPaintFilterCanvas(
SkCanvas* canvas,
bool unrollDrawable
) : SkPaintFilterCanvas(canvas), unrollDrawable(unrollDrawable), _onFilter(nullptr), _onFilterPaint(nullptr) {}
SKIKO_EXPORT void org_jetbrains_skia_PaintFilterCanvas__1nAttachToJava
(KNativePointer canvasPtr, KBoolean unrollDrawable) {
TODO("implement org_jetbrains_skia_PaintFilterCanvas__1nAttachToJava");
}
#if 0
SKIKO_EXPORT void org_jetbrains_skia_PaintFilterCanvas__1nAttachToJava
(KNativePointer canvasPtr, KBoolean unrollDrawable) {
SkijaPaintFilterCanvas* canvas = reinterpret_cast<SkijaPaintFilterCanvas*>((canvasPtr));
canvas->jobj = skija::PaintFilterCanvas::attach(env, jobj);
}
#endif
SkPaint* onFilterPaint() const {
return _onFilterPaint;
}
void init(KInteropPointer onFilter) {
_onFilter = KBooleanCallback(onFilter);
}
protected:
bool onFilter(SkPaint& paint) const override {
_onFilterPaint = &paint;
KBoolean result = _onFilter();
_onFilterPaint = nullptr;
return static_cast<bool>(result);
}
void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
if (unrollDrawable) {
drawable->draw(this, matrix);
} else {
SkPaintFilterCanvas::onDrawDrawable(drawable, matrix);
}
}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_PaintFilterCanvas__1nMake
(KNativePointer canvasPtr, KBoolean unrollDrawable) {
TODO("implement org_jetbrains_skia_PaintFilterCanvas__1nMake");
private:
KBooleanCallback _onFilter;
mutable SkPaint* _onFilterPaint;
bool unrollDrawable;
};
SKIKO_EXPORT void org_jetbrains_skia_PaintFilterCanvas__1nInit
(KNativePointer canvasPtr, KInteropPointer onFilter) {
SkijaPaintFilterCanvas* canvas = reinterpret_cast<SkijaPaintFilterCanvas*>((canvasPtr));
canvas->init(onFilter);
}
#if 0
SKIKO_EXPORT KNativePointer org_jetbrains_skia_PaintFilterCanvas__1nMake
(KNativePointer canvasPtr, KBoolean unrollDrawable) {
SkCanvas* canvas = reinterpret_cast<SkCanvas*>((canvasPtr));
SkijaPaintFilterCanvas* filterCanvas = new SkijaPaintFilterCanvas(canvas, unrollDrawable);
return reinterpret_cast<KNativePointer>(filterCanvas);
}
#endif
SKIKO_EXPORT KNativePointer org_jetbrains_skia_PaintFilterCanvas__1nGetOnFilterPaint
(KNativePointer canvasPtr) {
SkijaPaintFilterCanvas* canvas = reinterpret_cast<SkijaPaintFilterCanvas*>((canvasPtr));
return reinterpret_cast<KNativePointer>(canvas->onFilterPaint());
}
package org.jetbrains.skia
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.interopScope
internal actual fun PaintFilterCanvas.doInit(ptr: NativePointer) {
interopScope {
val onFilter = virtualBoolean {
val paint = Paint(PaintFilterCanvas_nGetOnFilterPaint(ptr), false)
onFilter(paint)
}
PaintFilterCanvas_nInit(ptr, onFilter)
}
}
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