implement some Canvas methods needed for composeUI

This commit is contained in:
Julian Winkler
2024-11-30 17:58:31 +01:00
committed by Mis012
parent cb7805bb45
commit d0952101a6
17 changed files with 143 additions and 18 deletions

View File

@@ -80,7 +80,17 @@ JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1stroke_1width(JN
sk_paint_set_stroke_width(_PTR(skia_paint), width); sk_paint_set_stroke_width(_PTR(skia_paint), width);
} }
JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1get_1stroke_1width(JNIEnv *env, jclass this, jlong skia_paint)
{
return sk_paint_get_stroke_width(_PTR(skia_paint));
}
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1style(JNIEnv *env, jclass this, jlong skia_paint, jint style) JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1style(JNIEnv *env, jclass this, jlong skia_paint, jint style)
{ {
sk_paint_set_style(_PTR(skia_paint), (sk_paint_style_t)style); sk_paint_set_style(_PTR(skia_paint), (sk_paint_style_t)style);
} }
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1blendmode(JNIEnv *env, jclass this, jlong skia_paint, jint blendmode)
{
sk_paint_set_blendmode(_PTR(skia_paint), (sk_blendmode_t)blendmode);
}

View File

@@ -81,6 +81,14 @@ JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawLine
JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawText JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawText
(JNIEnv *, jobject, jlong, jstring, jfloat, jfloat, jlong); (JNIEnv *, jobject, jlong, jstring, jfloat, jfloat, jlong);
/*
* Class: android_graphics_GskCanvas
* Method: native_drawRoundRect
* Signature: (JFFFFFFIF)V
*/
JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawRoundRect
(JNIEnv *, jobject, jlong, jfloat, jfloat, jfloat, jfloat, jfloat, jfloat, jint, jfloat);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -113,6 +113,14 @@ JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1measure_1text
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1stroke_1width JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1stroke_1width
(JNIEnv *, jclass, jlong, jfloat); (JNIEnv *, jclass, jlong, jfloat);
/*
* Class: android_graphics_Paint
* Method: native_get_stroke_width
* Signature: (J)F
*/
JNIEXPORT jfloat JNICALL Java_android_graphics_Paint_native_1get_1stroke_1width
(JNIEnv *, jclass, jlong);
/* /*
* Class: android_graphics_Paint * Class: android_graphics_Paint
* Method: native_set_style * Method: native_set_style
@@ -121,6 +129,14 @@ JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1stroke_1width
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1style JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1style
(JNIEnv *, jclass, jlong, jint); (JNIEnv *, jclass, jlong, jint);
/*
* Class: android_graphics_Paint
* Method: native_set_blendmode
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_android_graphics_Paint_native_1set_1blendmode
(JNIEnv *, jclass, jlong, jint);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -223,6 +223,14 @@ JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1removeView
JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChildren JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChildren
(JNIEnv *, jobject, jlong, jlong); (JNIEnv *, jobject, jlong, jlong);
/*
* Class: android_view_ViewGroup
* Method: native_drawChild
* Signature: (JJJ)V
*/
JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChild
(JNIEnv *, jobject, jlong, jlong, jlong);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -119,3 +119,21 @@ JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawText(JNIEnv *
gtk_snapshot_translate(snapshot, &GRAPHENE_POINT_INIT(-x, -y)); gtk_snapshot_translate(snapshot, &GRAPHENE_POINT_INIT(-x, -y));
g_object_unref(layout); g_object_unref(layout);
} }
JNIEXPORT void JNICALL Java_android_graphics_GskCanvas_native_1drawRoundRect(JNIEnv *env, jclass this_class, jlong snapshot_ptr, jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat rx, jfloat ry, jint color, jfloat width)
{
GdkSnapshot *snapshot = (GdkSnapshot *)_PTR(snapshot_ptr);
GdkRGBA gdk_color[4];
for (int i = 0; i < 4; i++) {
gdk_color[i].red = (float)((color >> 16) & 0xff) / 0xff;
gdk_color[i].green = (float)((color >> 8) & 0xff) / 0xff;
gdk_color[i].blue = (float)((color >> 0) & 0xff) / 0xff;
gdk_color[i].alpha = (float)((color >> 24) & 0xff) / 0xff;
}
GskRoundedRect round_rect = {
.bounds = GRAPHENE_RECT_INIT(left, top, right - left, bottom - top),
.corner = {{rx, ry}, {rx, ry}, {rx, ry}, {rx, ry}},
};
const float widths[4] = {width, width, width, width};
gtk_snapshot_append_border(snapshot, &round_rect, widths, gdk_color);
}

View File

@@ -246,3 +246,10 @@ JNIEXPORT jboolean JNICALL Java_android_graphics_Matrix_native_1preRotate__JFFF(
graphene_matrix_translate(matrix, &GRAPHENE_POINT3D_INIT(px, py, 0)); graphene_matrix_translate(matrix, &GRAPHENE_POINT3D_INIT(px, py, 0));
return true; return true;
} }
JNIEXPORT jboolean JNICALL Java_android_graphics_Matrix_native_1equals(JNIEnv *env, jclass class, jlong matrix1_ptr, jlong matrix2_ptr)
{
graphene_matrix_t *matrix1 = (graphene_matrix_t *)_PTR(matrix1_ptr);
graphene_matrix_t *matrix2 = (graphene_matrix_t *)_PTR(matrix2_ptr);
return graphene_matrix_equal(matrix1, matrix2);
}

View File

@@ -54,3 +54,12 @@ JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChildren(JNIEnv *
GdkSnapshot *snapshot = GDK_SNAPSHOT(_PTR(snapshot_ptr)); GdkSnapshot *snapshot = GDK_SNAPSHOT(_PTR(snapshot_ptr));
gtk_widget_snapshot_child(&wrapper->parent_instance, wrapper->child, snapshot); gtk_widget_snapshot_child(&wrapper->parent_instance, wrapper->child, snapshot);
} }
JNIEXPORT void JNICALL Java_android_view_ViewGroup_native_1drawChild(JNIEnv *env, jobject this, jlong widget_ptr, jlong child_ptr, jlong snapshot_ptr)
{
GtkWidget *widget = GTK_WIDGET(_PTR(widget_ptr));
GtkWidget *child = gtk_widget_get_parent(GTK_WIDGET(_PTR(child_ptr)));
GdkSnapshot *snapshot = GDK_SNAPSHOT(_PTR(snapshot_ptr));
gtk_widget_queue_draw(child); // FIXME: why didn't compose UI invalidate the child?
gtk_widget_snapshot_child(widget, child, snapshot);
}

View File

@@ -488,7 +488,7 @@ public class Canvas {
public boolean getClipBounds(Rect outRect) { public boolean getClipBounds(Rect outRect) {
outRect.set(0, 0, 100, 100); outRect.set(0, 0, 100, 100);
return false; return true;
} }
private static native long native_canvas_from_bitmap(long pixbuf); private static native long native_canvas_from_bitmap(long pixbuf);

View File

@@ -89,6 +89,11 @@ public class GskCanvas extends Canvas {
drawBitmap(bitmap, src, new Rect((int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom), paint); drawBitmap(bitmap, src, new Rect((int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom), paint);
} }
@Override
public void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) {
native_drawRoundRect(snapshot, left, top, right, bottom, rx, ry, paint.getColor(), paint.getStrokeWidth());
}
protected native void native_drawBitmap(long snapshot, long texture, int x, int y, int width, int height, int color); protected native void native_drawBitmap(long snapshot, long texture, int x, int y, int width, int height, int color);
protected native void native_drawRect(long snapshot, float left, float top, float right, float bottom, int color); protected native void native_drawRect(long snapshot, float left, float top, float right, float bottom, int color);
protected native void native_drawPath(long snapshot, long path, long paint); protected native void native_drawPath(long snapshot, long path, long paint);
@@ -98,4 +103,5 @@ public class GskCanvas extends Canvas {
protected native void native_restore(long snapshot); protected native void native_restore(long snapshot);
protected native void native_drawLine(long snapshot, float startX, float startY, float stopX, float stopY, long paint); protected native void native_drawLine(long snapshot, float startX, float startY, float stopX, float stopY, long paint);
protected native void native_drawText(long snapshot, String text, float x, float y, long paint); protected native void native_drawText(long snapshot, String text, float x, float y, long paint);
protected native void native_drawRoundRect(long snapshot, float left, float top, float right, float bottom, float rx, float ry, int color, float strokeWidth);
} }

View File

@@ -1,5 +1,7 @@
package android.graphics; package android.graphics;
import java.util.Locale;
public class Paint { public class Paint {
public static final int ANTI_ALIAS_FLAG = (1 << 0); public static final int ANTI_ALIAS_FLAG = (1 << 0);
public static final int FILTER_BITMAP_FLAG = (1 << 1); public static final int FILTER_BITMAP_FLAG = (1 << 1);
@@ -185,7 +187,9 @@ public class Paint {
public /*native*/ int getAlpha() { return 0; } public /*native*/ int getAlpha() { return 0; }
public /*native*/ void setAlpha(int a) {} public /*native*/ void setAlpha(int a) {}
public /*native*/ float getStrokeWidth() { return 0; } public float getStrokeWidth() {
return native_get_stroke_width(skia_paint);
}
public /*native*/ float getStrokeMiter() { return 0; } public /*native*/ float getStrokeMiter() { return 0; }
public /*native*/ void setStrokeMiter(float miter) {} public /*native*/ void setStrokeMiter(float miter) {}
@@ -202,7 +206,12 @@ public class Paint {
public void setShadowLayer(float radius, float dx, float dy, int color) {} public void setShadowLayer(float radius, float dx, float dy, int color) {}
public Xfermode setXfermode(Xfermode xfermode) { return xfermode; } public Xfermode setXfermode(Xfermode xfermode) {
if (xfermode instanceof PorterDuffXfermode) {
native_set_blendmode(skia_paint, ((PorterDuffXfermode)xfermode).mode.nativeInt);
}
return xfermode;
}
public void setLetterSpacing(float spacing) {} public void setLetterSpacing(float spacing) {}
@@ -290,6 +299,10 @@ public class Paint {
public Join getStrokeJoin() { return Join.MITER; } public Join getStrokeJoin() { return Join.MITER; }
public Locale getTextLocale() { return Locale.getDefault(); }
public float getLetterSpacing() { return 1.0f; }
private native long native_constructor(); private native long native_constructor();
private native void native_set_antialias(long skia_paint, boolean aa); private native void native_set_antialias(long skia_paint, boolean aa);
private native void native_set_color(long skia_paint, int color); private native void native_set_color(long skia_paint, int color);
@@ -300,5 +313,7 @@ public class Paint {
private static native void native_set_text_size(long skia_font, float size); 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); private static native float native_measure_text(long skia_font, CharSequence text, int start, int end, long skia_paint);
private static native void native_set_stroke_width(long skia_font, float width); private static native void native_set_stroke_width(long skia_font, float width);
private static native float native_get_stroke_width(long skia_font);
private static native void native_set_style(long skia_paint, int style); private static native void native_set_style(long skia_paint, int style);
private static native void native_set_blendmode(long skia_paint, int mode);
} }

View File

@@ -1,5 +1,10 @@
package android.graphics; package android.graphics;
public class PorterDuffXfermode extends Xfermode { public class PorterDuffXfermode extends Xfermode {
public PorterDuffXfermode(PorterDuff.Mode mode) {}
PorterDuff.Mode mode;
public PorterDuffXfermode(PorterDuff.Mode mode) {
this.mode = mode;
}
} }

View File

@@ -2,6 +2,10 @@ package android.text;
public class BoringLayout extends Layout { public class BoringLayout extends Layout {
public BoringLayout (CharSequence source, TextPaint paint, int outerwidth, Layout.Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad) {
super(source, paint, outerwidth, align, spacingMult, spacingAdd);
}
public static class Metrics {}; public static class Metrics {};
public static Metrics isBoring(CharSequence source, TextPaint paint, Metrics metrics) { public static Metrics isBoring(CharSequence source, TextPaint paint, Metrics metrics) {

View File

@@ -12,6 +12,14 @@ public class Layout {
ALIGN_RIGHT, ALIGN_RIGHT,
} }
private CharSequence text;
private TextPaint paint;
protected Layout(CharSequence text, TextPaint paint, int width, Layout.Alignment align, float spacingMult, float spacingAdd) {
this.text = text;
this.paint = paint;
}
public int getLineCount() {return 1;} public int getLineCount() {return 1;}
public float getLineWidth(int line) {return 10;} public float getLineWidth(int line) {return 10;}
@@ -20,18 +28,20 @@ public class Layout {
public int getEllipsisCount(int line) {return 0;} public int getEllipsisCount(int line) {return 0;}
public CharSequence getText() {return "FIXME Layout.getText";} public CharSequence getText() {return text;}
public int getWidth() {return 10;} public int getWidth() {return 10;}
public int getHeight() {return 10;} public int getHeight() {return 10;}
public void draw(Canvas canvas) {} public void draw(Canvas canvas) {
canvas.drawText(text.toString(), 0, 0, paint);
}
public int getParagraphDirection(int line) {return 0;} public int getParagraphDirection(int line) {return 0;}
public static float getDesiredWidth(CharSequence source, int start, int end, TextPaint paint) { public static float getDesiredWidth(CharSequence source, int start, int end, TextPaint paint) {
return 10; return 400;
} }
public int getLineEnd(int line) {return 100;} public int getLineEnd(int line) {return 100;}
@@ -59,4 +69,10 @@ public class Layout {
public int getLineForVertical(int y) {return 0;} public int getLineForVertical(int y) {return 0;}
public int getOffsetForHorizontal(int line, float x) {return 0;} public int getOffsetForHorizontal(int line, float x) {return 0;}
public float getPrimaryHorizontal(int line) {return 0;}
public int getLineForOffset(int offset) {return 0;}
public int getLineTop(int line) {return 0;}
} }

View File

@@ -1,22 +1,14 @@
package android.text; package android.text;
import android.graphics.Canvas;
public class StaticLayout extends Layout { public class StaticLayout extends Layout {
private CharSequence text;
public StaticLayout(CharSequence source, int bufstart, int bufend, public StaticLayout(CharSequence source, int bufstart, int bufend,
TextPaint paint, int outerwidth, TextPaint paint, int outerwidth,
Alignment align, TextDirectionHeuristic textDir, Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd, float spacingmult, float spacingadd,
boolean includepad, boolean includepad,
TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) { TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
this.text = source; super(source, paint, outerwidth, align, spacingmult, spacingadd);
}
public CharSequence getText() {
return text;
} }
public int getWidth() { public int getWidth() {
@@ -29,5 +21,4 @@ public class StaticLayout extends Layout {
public float getLineLeft(int line) {return 0;} public float getLineLeft(int line) {return 0;}
public void draw(Canvas canvas) {}
} }

View File

@@ -15,4 +15,11 @@ public class TextDirectionHeuristics {
return true; return true;
} }
}; };
public static final TextDirectionHeuristic FIRSTSTRONG_LTR = new TextDirectionHeuristic() {
@Override
public boolean isRtl(CharSequence text, int start, int end) {
return false;
}
};
} }

View File

@@ -5,6 +5,7 @@ import android.animation.LayoutTransition;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.GskCanvas;
import android.util.AttributeSet; import android.util.AttributeSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@@ -147,6 +148,7 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
protected native void native_removeView(long widget, long child); protected native void native_removeView(long widget, long child);
@Override @Override
protected native void native_drawChildren(long widget, long snapshot); protected native void native_drawChildren(long widget, long snapshot);
protected native void native_drawChild(long widget, long child, long snapshot);
@Override @Override
protected void native_drawContent(long widget, long snapshot) {} protected void native_drawContent(long widget, long snapshot) {}
@@ -392,6 +394,8 @@ public class ViewGroup extends View implements ViewParent, ViewManager {
} }
public boolean drawChild(Canvas canvas, View child, long drawingTime) { public boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (canvas instanceof GskCanvas)
native_drawChild(widget, child.widget, ((GskCanvas)canvas).snapshot);
return false; return false;
} }

View File

@@ -5,6 +5,7 @@ import android.content.res.ColorStateList;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.BoringLayout;
import android.text.Editable; import android.text.Editable;
import android.text.InputFilter; import android.text.InputFilter;
import android.text.Layout; import android.text.Layout;
@@ -281,7 +282,7 @@ public class TextView extends View {
} }
public Layout getLayout() { public Layout getLayout() {
return new Layout(); return new BoringLayout(getText(), getPaint(), getWidth(), Layout.Alignment.ALIGN_NORMAL, 1, 0, new BoringLayout.Metrics(), false);
} }
public int getCurrentTextColor() {return 0;} public int getCurrentTextColor() {return 0;}