api-impl: implement Canvas text drawing as used by Gravity Defied

implements android.graphics.Typeface (always uses default
typeface for now), one version of Canvas.drawText, one version
of Paint.measureText, and Paint.ascend
This commit is contained in:
Mis012
2023-09-12 19:30:20 +02:00
parent f25e9b021f
commit 24353378be
10 changed files with 198 additions and 21 deletions

View File

@@ -73,6 +73,7 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
'src/api-impl-jni/database/android_database_SQLiteConnection.c',
'src/api-impl-jni/drawables/ninepatch.c',
'src/api-impl-jni/graphics/android_graphics_BitmapFactory.c',
'src/api-impl-jni/graphics/android_graphics_Typeface.c',
'src/api-impl-jni/android_content_res_AssetManager.c',
'src/api-impl-jni/audio/android_media_AudioTrack.c',
'src/api-impl-jni/audio/android_media_SoundPool.c',

View File

@@ -4,7 +4,10 @@
#include "util.h"
#include "../sk_area/include/c/sk_canvas.h"
#include "../sk_area/include/c/sk_font.h"
#include "../sk_area/include/c/sk_image.h"
#include "../sk_area/include/c/sk_typeface.h"
#include "generated_headers/android_graphics_Canvas.h"
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1save(JNIEnv *env, jclass this, jlong skia_canvas, jlong widget)
@@ -51,6 +54,18 @@ JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawRect(JNIEnv *env
sk_canvas_draw_rect(canvas, &(sk_rect_t){left, top, right, bottom}, paint);
}
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawText(JNIEnv *env, jclass this, jlong skia_canvas, jobject _text, jint start, jint end, jfloat x, jfloat y, jlong skia_font, jlong skia_paint)
{
sk_canvas_t *canvas = (sk_canvas_t *)_PTR(skia_canvas);
sk_paint_t *paint = (sk_paint_t *)_PTR(skia_paint);
sk_font_t *font = _PTR(skia_font);
const char *text = _CSTRING(_text);
/* TODO: handle start/end (here or in java) */
sk_canvas_draw_simple_text(canvas, text + start, end - start, UTF8_SK_TEXT_ENCODING, x, y, font, paint);
}
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1rotate(JNIEnv *env, jclass this, jlong skia_canvas, jlong widget, jfloat angle)
{
sk_canvas_t *canvas = (sk_canvas_t *)_PTR(skia_canvas);

View File

@@ -3,7 +3,9 @@
#include "defines.h"
#include "util.h"
#include "../sk_area/include/c/sk_font.h"
#include "../sk_area/include/c/sk_paint.h"
#include "../sk_area/include/c/sk_typeface.h"
#include "generated_headers/android_graphics_Paint.h"
JNIEXPORT jlong JNICALL Java_android_graphics_Paint_native_1constructor(JNIEnv *env, jobject this)
@@ -25,3 +27,43 @@ JNIEXPORT jint JNICALL Java_android_graphics_Paint_native_1get_1color(JNIEnv *en
return sk_paint_get_color(paint);
}
JNIEXPORT jlong JNICALL Java_android_graphics_Paint_native_1create_1font(JNIEnv *env, jclass this)
{
return _INTPTR(sk_font_new()); /* TODO: recycle this */
}
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1typeface(JNIEnv *env, jclass this, jlong skia_font, jlong skia_typeface)
{
sk_font_t *font = _PTR(skia_font);
sk_typeface_t *typeface = _PTR(skia_typeface);
sk_font_set_typeface(font, typeface);
}
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1text_1size(JNIEnv *env, jclass this, jlong skia_font, jfloat size)
{
sk_font_t *font = _PTR(skia_font);
sk_font_set_size(font, size);
}
JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1ascent(JNIEnv *env, jclass this, jlong skia_font)
{
sk_font_t *font = _PTR(skia_font);
sk_fontmetrics_t metrics;
sk_font_get_metrics(font, &metrics);
return metrics.fAscent;
}
JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1measure_1text(JNIEnv *env, jclass this, jlong skia_font, jobject _text, jint start, jint end, jlong skia_paint)
{
sk_font_t *font = _PTR(skia_font);
sk_paint_t *paint = (sk_paint_t *)_PTR(skia_paint);
const char *text = _CSTRING(_text);
return sk_font_measure_text(font, text + start, end - start, UTF8_SK_TEXT_ENCODING, NULL, paint);
}

View File

@@ -23,6 +23,14 @@ JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1save
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1restore
(JNIEnv *, jclass, jlong, jlong);
/*
* Class: android_graphics_Canvas
* Method: native_drawText
* Signature: (JLjava/lang/CharSequence;IIFFJJ)V
*/
JNIEXPORT void JNICALL Java_android_graphics_Canvas_native_1drawText
(JNIEnv *, jclass, jlong, jobject, jint, jint, jfloat, jfloat, jlong, jlong);
/*
* Class: android_graphics_Canvas
* Method: native_drawRect

View File

@@ -31,6 +31,46 @@ JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1color
JNIEXPORT jint JNICALL Java_android_graphics_Paint_native_1get_1color
(JNIEnv *, jobject, jlong);
/*
* Class: android_graphics_Paint
* Method: native_create_font
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_android_graphics_Paint_native_1create_1font
(JNIEnv *, jclass);
/*
* Class: android_graphics_Paint
* Method: native_ascent
* Signature: (J)F
*/
JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1ascent
(JNIEnv *, jclass, jlong);
/*
* Class: android_graphics_Paint
* Method: native_set_typeface
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1typeface
(JNIEnv *, jclass, jlong, jlong);
/*
* Class: android_graphics_Paint
* Method: native_set_text_size
* Signature: (JF)V
*/
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1text_1size
(JNIEnv *, jclass, jlong, jfloat);
/*
* Class: android_graphics_Paint
* Method: native_measure_text
* Signature: (JLjava/lang/CharSequence;IIJ)F
*/
JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1measure_1text
(JNIEnv *, jclass, jlong, jobject, jint, jint, jlong);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class android_graphics_Typeface */
#ifndef _Included_android_graphics_Typeface
#define _Included_android_graphics_Typeface
#ifdef __cplusplus
extern "C" {
#endif
#undef android_graphics_Typeface_NORMAL
#define android_graphics_Typeface_NORMAL 0L
#undef android_graphics_Typeface_BOLD
#define android_graphics_Typeface_BOLD 1L
#undef android_graphics_Typeface_ITALIC
#define android_graphics_Typeface_ITALIC 2L
#undef android_graphics_Typeface_BOLD_ITALIC
#define android_graphics_Typeface_BOLD_ITALIC 3L
/*
* Class: android_graphics_Typeface
* Method: native_create
* Signature: (Ljava/lang/CharSequence;I)J
*/
JNIEXPORT jlong JNICALL Java_android_graphics_Typeface_native_1create
(JNIEnv *, jclass, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,14 @@
#include <gtk/gtk.h>
#include "../defines.h"
#include "../util.h"
#include "../../sk_area/include/c/sk_typeface.h"
#include "../generated_headers/android_graphics_Typeface.h"
JNIEXPORT jlong JNICALL Java_android_graphics_Typeface_native_1create(JNIEnv *env, jclass this, jobject _family_name, jint style)
{
/* TODO: use the family name */
return _INTPTR(sk_typeface_create_default()); /* TODO: recycle this */
}

View File

@@ -95,8 +95,7 @@ public class Canvas {
* @param paint The paint used for the text (e.g. color, size, style)
*/
public void drawText(String text, float x, float y, Paint paint) {
/* native_drawText(mNativeCanvas, text, 0, text.length(), x, y, paint.mBidiFlags,
paint.mNativePaint);*/
native_drawText(skia_canvas, text, 0, text.length(), x, y, paint.skia_font, paint.skia_paint);
}
/**
@@ -377,7 +376,7 @@ public class Canvas {
}
public void setBitmap(Bitmap bitmap) {}
private static native void native_drawText(long skia_canvas, CharSequence text, int start, int end, float x, float y, long skia_font, long skia_paint);
private static native void native_drawRect(long skia_canvas, float left, float top, float right, float bottom, long skia_paint);
private static native void native_drawLine(long skia_canvas, long widget, float startX, float startY, float stopX, float stopY, long skia_paint);
private static native void native_drawBitmap(long skia_canvas, long widget, long pixbuf, float src_x, float src_y, float dest_x, float dest_y, float dest_w, float dest_h, long skia_paint);

View File

@@ -1,11 +1,9 @@
package android.graphics;
public class Paint {
public long skia_paint = 0; // should probably be private, but then we'd need to get it from C
private native long native_constructor();
private native void native_set_color(long skia_paint, int color);
private native int native_get_color(long skia_paint);
public long skia_paint = 0;
private Typeface typeface = null;
public long skia_font = 0;
public Paint() {
skia_paint = native_constructor();
@@ -32,21 +30,37 @@ public class Paint {
public void setAntiAlias(boolean aa) {}
public void setStrokeWidth(float width) {}
public void setTextSize(float textSize) {}
public void setTextSize(float size) {
if(skia_font == 0)
skia_font = native_create_font();
native_set_text_size(skia_font, size);
}
public Typeface setTypeface(Typeface typeface) {
return new Typeface();
this.typeface = typeface;
if(skia_font == 0)
skia_font = native_create_font();
native_set_typeface(skia_font, typeface.skia_typeface);
return this.typeface;
}
public void getTextBounds(String text, int start, int end, Rect bounds) {}
public void getTextBounds(char[] text, int index, int count, Rect bounds) {}
public void setFlags(int flags) {}
public void setFilterBitmap(boolean filter) {}
public void setStyle(Style style) {}
public float ascent() { return 0; }
public float ascent() {
if(skia_font == 0)
return 0;
return native_ascent(skia_font);
}
public float measureText(char[] text, int index, int count) { return 10; }
public float measureText(String text, int start, int end) { return 10; }
public float measureText(String text) { return 10; }
public float measureText(String text) {
return native_measure_text(skia_font, text, 0, text.length(), skia_paint);
}
public float measureText(CharSequence text, int start, int end) { return 10; }
public enum Style {
@@ -187,4 +201,13 @@ public class Paint {
public void setStrokeCap(Cap cap) {}
public void setStrokeJoin(Join join) {}
private native long native_constructor();
private native void native_set_color(long skia_paint, int color);
private native int native_get_color(long skia_paint);
private static native long native_create_font();
private static native float native_ascent(long skia_font);
private static native void native_set_typeface(long skia_font, long skia_typeface);
private static native void native_set_text_size(long skia_font, float size);
private static native float native_measure_text(long skia_font, CharSequence text, int start, int end, long skia_paint);
}

View File

@@ -7,25 +7,25 @@ public class Typeface {
/**
* The default NORMAL typeface object
*/
public static final Typeface DEFAULT = new Typeface();
public static final Typeface DEFAULT = create((String)null, 0);
/**
* The default BOLD typeface object. Note: this may be not actually be
* bold, depending on what fonts are installed. Call getStyle() to know
* for sure.
*/
public static final Typeface DEFAULT_BOLD = new Typeface();
public static final Typeface DEFAULT_BOLD = create((String)null, 0);
/**
* The NORMAL style of the default sans serif typeface.
*/
public static final Typeface SANS_SERIF = new Typeface();
public static final Typeface SANS_SERIF = create((String)null, 0);
/**
* The NORMAL style of the default serif typeface.
*/
public static final Typeface SERIF = new Typeface();
public static final Typeface SERIF = create((String)null, 0);
/**
* The NORMAL style of the default monospace typeface.
*/
public static final Typeface MONOSPACE = new Typeface();
public static final Typeface MONOSPACE = create((String)null, 0);
// Style
public static final int NORMAL = 0;
@@ -33,15 +33,21 @@ public class Typeface {
public static final int ITALIC = 2;
public static final int BOLD_ITALIC = 3;
public long skia_typeface = 0;
public static Typeface createFromAsset(AssetManager mgr, String path) {
return null;
return DEFAULT;
}
public static Typeface create(String familyName, int style) {
return null;
public static Typeface create(String family_name, int style) {
Typeface ret = new Typeface();
ret.skia_typeface = native_create(family_name, style);
return ret;
}
public static Typeface create(Typeface typeface, int style) {
return null;
return typeface;
}
private static native long native_create(CharSequence family_name, int style);
}