add support for custom Java Drawables

This is made possible, by adding a second Canvas implementation which
can be used to render directly to GdkSnapshot objects

For now the only implemented method is drawBitmap(), this is already
enough to make VectorDrawableCompat functional
This commit is contained in:
Julian Winkler
2024-03-24 21:01:47 +01:00
parent 0b78cbcc55
commit ad266c7821
15 changed files with 182 additions and 30 deletions

View File

@@ -2,6 +2,7 @@
#include <string.h>
#include "../defines.h"
#include "../util.h"
#include "NinePatchPaintable.h"
#include "../generated_headers/android_graphics_drawable_Drawable.h"
@@ -20,3 +21,49 @@ JNIEXPORT jlong JNICALL Java_android_graphics_drawable_Drawable_native_1paintabl
(*env)->ReleaseStringUTFChars(env, pathStr, path);
return _INTPTR(paintable);
}
struct _JavaPaintable {
GObject parent_instance;
jobject drawable;
};
G_DECLARE_FINAL_TYPE(JavaPaintable, java_paintable, JAVA, PAINTABLE, GObject)
static void java_paintable_snapshot(GdkPaintable *gdk_paintable, GdkSnapshot *snapshot, double width, double height)
{
JNIEnv *env = get_jni_env();
JavaPaintable *paintable = JAVA_PAINTABLE(gdk_paintable);
jclass canvas_class = (*env)->FindClass(env, "android/graphics/GskCanvas");
jmethodID canvas_constructor = _METHOD(canvas_class, "<init>", "(J)V");
jobject canvas = (*env)->NewObject(env, canvas_class, canvas_constructor, _INTPTR(snapshot));
(*env)->CallVoidMethod(env, paintable->drawable, handle_cache.drawable.setBounds, 0, 0, (int)width, (int)height);
(*env)->CallVoidMethod(env, paintable->drawable, handle_cache.drawable.draw, canvas);
if ((*env)->ExceptionCheck(env))
(*env)->ExceptionDescribe(env);
(*env)->DeleteLocalRef(env, canvas);
(*env)->DeleteLocalRef(env, canvas_class);
}
static void java_paintable_init(JavaPaintable *java_paintable)
{
}
static void java_paintable_paintable_init(GdkPaintableInterface *iface)
{
iface->snapshot = java_paintable_snapshot;
}
static void java_paintable_class_init(JavaPaintableClass *class)
{
}
G_DEFINE_TYPE_WITH_CODE(JavaPaintable, java_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(GDK_TYPE_PAINTABLE, java_paintable_paintable_init))
JNIEXPORT jlong JNICALL Java_android_graphics_drawable_Drawable_native_1constructor(JNIEnv *env, jobject this) {
JavaPaintable *paintable = NULL;
if (handle_cache.drawable.draw != _METHOD(_CLASS(this), "draw", "(Landroid/graphics/Canvas;)V")) {
paintable = g_object_new(java_paintable_get_type(), NULL);
paintable->drawable = _REF(this);
}
return _INTPTR(paintable);
}