implement drawing into Bitmaps with Canvas, make BitmapDrawable use use paintable, misc Bitmap improvements

This commit is contained in:
Mis012
2024-03-16 15:00:22 +01:00
parent fa1aa36f6b
commit 2e864adc0f
10 changed files with 201 additions and 85 deletions

View File

@@ -8,16 +8,8 @@
#include "generated_headers/android_graphics_Bitmap.h"
/*
* We use a GdkPixbuf as the backing for a bitmap.
* We additionally create a view into it as a skia image,
* so we can pass it to skia functions.
*/
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1bitmap_1from_1path(JNIEnv *env, jobject this, jobject path)
void attach_sk_image(GdkPixbuf *pixbuf)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(_CSTRING(path), NULL);
android_log_printf(ANDROID_LOG_VERBOSE, "["__FILE__"]", ">>> made pixbuf from path: >%s<, >%p<\n", _CSTRING(path), pixbuf);
sk_imageinfo_t info = {
.width = gdk_pixbuf_get_width(pixbuf),
.height = gdk_pixbuf_get_height(pixbuf),
@@ -34,10 +26,32 @@ JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1bitmap_1from_1path(
sk_image_t *image = sk_image_new_raster_data(&info, pixels, rowstride);
g_object_set_data(G_OBJECT(pixbuf), "sk_image", image);
}
/*
* We use a GdkPixbuf as the backing for a bitmap.
* We additionally create a view into it as a skia image,
* so we can pass it to skia functions.
*/
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1bitmap_1from_1path(JNIEnv *env, jobject this, jobject path)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(_CSTRING(path), NULL);
android_log_printf(ANDROID_LOG_VERBOSE, "["__FILE__"]", ">>> made pixbuf from path: >%s<, >%p<\n", _CSTRING(path), pixbuf);
attach_sk_image(pixbuf);
g_object_ref(pixbuf);
return _INTPTR(pixbuf);
}
/* new empty bitmap */
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1create(JNIEnv *env, jclass this, jint width, jint height)
{
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, width, height);
attach_sk_image(pixbuf);
return _INTPTR(pixbuf);
}
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getWidth(JNIEnv *env, jobject this)
{
@@ -59,7 +73,8 @@ JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getHeight(JNIEnv *env, jobje
return gdk_pixbuf_get_height(pixbuf);
}
JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels(JNIEnv *env, jclass, jlong bitmapHandle, jintArray pixelArray, jint offset, jint stride, jint x, jint y, jint width, jint height, jboolean premultiplied) {
JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels(JNIEnv *env, jclass, jlong bitmapHandle, jintArray pixelArray, jint offset, jint stride, jint x, jint y, jint width, jint height, jboolean premultiplied)
{
int i,j;
GdkPixbuf *pixbuf = _PTR(bitmapHandle);
g_assert(gdk_pixbuf_get_n_channels(pixbuf) == 4);
@@ -79,26 +94,41 @@ JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels(JNIEnv *env,
(*env)->ReleaseIntArrayElements(env, pixelArray, dst, 0);
}
JNIEXPORT jboolean JNICALL Java_android_graphics_Bitmap_nativeRecycle(JNIEnv *env, jclass, jlong bitmapHandle) {
JNIEXPORT jboolean JNICALL Java_android_graphics_Bitmap_nativeRecycle(JNIEnv *env, jclass, jlong bitmapHandle)
{
GdkPixbuf *pixbuf = _PTR(bitmapHandle);
sk_image_t *image = g_object_get_data(G_OBJECT(pixbuf), "sk_image");
if(!image) {
fprintf(stderr, "pixbuf doesn't have a skia image associated: %p\n", pixbuf);
g_object_unref(pixbuf);
return true;
}
sk_image_unref(image);
if(image)
sk_image_unref(image);
else
fprintf(stderr, "nativeRecycle: pixbuf doesn't have a skia image associated: %p\n", pixbuf);
g_object_unref(pixbuf);
return true;
}
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1copy(JNIEnv *env, jclass, jlong src_ptr) {
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1copy(JNIEnv *env, jclass, jlong src_ptr)
{
GdkPixbuf *src = _PTR(src_ptr);
GdkPixbuf *copy = gdk_pixbuf_copy(src);
sk_image_t *image = g_object_get_data(G_OBJECT(src), "sk_image");
printf("native_copy: dbg: %p\n", image);
if(image)
g_object_set_data(G_OBJECT(copy), "sk_image", sk_image_make_raster_image(image)); // probably?
else
fprintf(stderr, "native_copy: pixbuf doesn't have a skia image associated: %p\n", src);
return _INTPTR(copy);
}
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_nativeRowBytes(JNIEnv *env, jclass, jlong pixbuf_ptr) {
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1subpixbuf(JNIEnv *env, jclass, jlong _pixbuf, jint x, jint y, jint width, jint height)
{
GdkPixbuf *pixbuf = _PTR(_pixbuf);
GdkPixbuf *subpixbuf = gdk_pixbuf_new_subpixbuf(pixbuf, x, y, width, height);
attach_sk_image(subpixbuf);
return _INTPTR(subpixbuf);
}
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_nativeRowBytes(JNIEnv *env, jclass, jlong pixbuf_ptr)
{
GdkPixbuf *pixbuf = _PTR(pixbuf_ptr);
return gdk_pixbuf_get_rowstride(pixbuf);

View File

@@ -10,6 +10,26 @@
#include "generated_headers/android_graphics_Canvas.h"
JNIEXPORT jlong JNICALL Java_android_graphics_Canvas_native_1canvas_1from_1bitmap(JNIEnv *env, jclass this, jlong _pixbuf)
{
GdkPixbuf *pixbuf = (GdkPixbuf *)_PTR(_pixbuf);
/* - copied from bitmap (TODO: refactor) - */
sk_imageinfo_t info = {
.width = gdk_pixbuf_get_width(pixbuf),
.height = gdk_pixbuf_get_height(pixbuf),
.colorType = RGBA_8888_SK_COLORTYPE, // is this correct?
.alphaType = PREMUL_SK_ALPHATYPE,
};
void *pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
// size_t pixbuf_size = rowstride * (info.height - 1)
// + /* last row: */ info.width * ((gdk_pixbuf_get_n_channels(pixbuf) * gdk_pixbuf_get_bits_per_sample(pixbuf) + 7) / 8);
/* --------------------------------------- */
return _INTPTR(sk_canvas_new_from_raster(&info, pixbuf_pixels, /*pixbuf_size*/rowstride, NULL));
}
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1save(JNIEnv *env, jclass this, jlong skia_canvas, jlong widget)
{
sk_canvas_t *canvas = (sk_canvas_t *)_PTR(skia_canvas);
@@ -32,7 +52,10 @@ JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawLine(JNIEnv *env
sk_canvas_draw_line(canvas, start_x, start_y, stop_x, stop_y, paint);
}
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawBitmap(JNIEnv *env , jclass this_class, jlong skia_canvas, jlong widget, jlong _pixbuf, jfloat src_x, jfloat src_y, jfloat dest_x , jfloat dest_y, jfloat dest_w , jfloat dest_h, jlong skia_paint)
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawBitmap(JNIEnv *env , jclass this_class, jlong skia_canvas, jlong widget, jlong _pixbuf,
jfloat src_left, jfloat src_top, jfloat src_right, jfloat src_bottom,
jfloat dst_left, jfloat dst_top, jfloat dst_right, jfloat dst_bottom,
jlong skia_paint)
{
sk_canvas_t *canvas = (sk_canvas_t *)_PTR(skia_canvas);
GdkPixbuf *pixbuf = (GdkPixbuf *)_PTR(_pixbuf);
@@ -40,10 +63,11 @@ JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawBitmap(JNIEnv *e
sk_image_t *image = g_object_get_data(G_OBJECT(pixbuf), "sk_image");
if(!image) {
fprintf(stderr, "pixbuf doesn't have a skia image associated: %p\n", pixbuf);
fprintf(stderr, "drawBitmap: pixbuf doesn't have a skia image associated: %p\n", pixbuf);
return;
}
sk_canvas_draw_image(canvas, image, dest_x, dest_y, paint);
sk_canvas_draw_image_rect(canvas, image, &(sk_rect_t){src_left, src_top, src_right, src_bottom},
&(sk_rect_t){dst_left, dst_top, dst_right, dst_bottom}, paint);
}
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawRect(JNIEnv *env, jclass this, jlong skia_canvas, jfloat left, jfloat top, jfloat right, jfloat bottom, jlong skia_paint)

View File

@@ -11,6 +11,22 @@ extern "C" {
#define android_graphics_Bitmap_DENSITY_NONE 0L
#undef android_graphics_Bitmap_WORKING_COMPRESS_STORAGE
#define android_graphics_Bitmap_WORKING_COMPRESS_STORAGE 4096L
/*
* Class: android_graphics_Bitmap
* Method: getWidth
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getWidth
(JNIEnv *, jobject);
/*
* Class: android_graphics_Bitmap
* Method: getHeight
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getHeight
(JNIEnv *, jobject);
/*
* Class: android_graphics_Bitmap
* Method: native_bitmap_from_path
@@ -29,19 +45,19 @@ JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1copy
/*
* Class: android_graphics_Bitmap
* Method: getWidth
* Signature: ()I
* Method: native_subpixbuf
* Signature: (JIIII)J
*/
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getWidth
(JNIEnv *, jobject);
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1subpixbuf
(JNIEnv *, jclass, jlong, jint, jint, jint, jint);
/*
* Class: android_graphics_Bitmap
* Method: getHeight
* Signature: ()I
* Method: native_create
* Signature: (II)J
*/
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getHeight
(JNIEnv *, jobject);
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1create
(JNIEnv *, jclass, jint, jint);
/*
* Class: android_graphics_Bitmap

View File

@@ -7,6 +7,14 @@
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: android_graphics_Canvas
* Method: native_canvas_from_bitmap
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_android_graphics_Canvas_native_1canvas_1from_1bitmap
(JNIEnv *, jclass, jlong);
/*
* Class: android_graphics_Canvas
* Method: native_save
@@ -50,10 +58,10 @@ JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawLine
/*
* Class: android_graphics_Canvas
* Method: native_drawBitmap
* Signature: (JJJFFFFFFJ)V
* Signature: (JJJFFFFFFFFJ)V
*/
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawBitmap
(JNIEnv *, jclass, jlong, jlong, jlong, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jlong);
(JNIEnv *, jclass, jlong, jlong, jlong, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jlong);
/*
* Class: android_graphics_Canvas

View File

@@ -0,0 +1,21 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class android_graphics_drawable_BitmapDrawable */
#ifndef _Included_android_graphics_drawable_BitmapDrawable
#define _Included_android_graphics_drawable_BitmapDrawable
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: android_graphics_drawable_BitmapDrawable
* Method: native_paintable_from_pixbuf
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_android_graphics_drawable_BitmapDrawable_native_1paintable_1from_1pixbuf
(JNIEnv *, jclass, jlong);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,11 @@
#include <gtk/gtk.h>
#include "../defines.h"
#include "../util.h"
JNIEXPORT jlong JNICALL Java_android_graphics_drawable_BitmapDrawable_native_1paintable_1from_1pixbuf(JNIEnv *env, jclass this, jlong _pixbuf)
{
GdkPixbuf *pixbuf = (GdkPixbuf *)_PTR(_pixbuf);
return _INTPTR(gdk_texture_new_for_pixbuf(pixbuf));
}