ImageView: implement tint attribute

This commit is contained in:
Julian Winkler 2024-12-13 21:34:35 +01:00
parent b087b82616
commit 9023e2963b
4 changed files with 44 additions and 18 deletions

View file

@ -48,7 +48,8 @@ static int java_paintable_get_intrinsic_width(GdkPaintable *gdk_paintable)
JNIEnv *env = get_jni_env();
JavaPaintable *paintable = JAVA_PAINTABLE(gdk_paintable);
jmethodID getIntrinsicWidth = _METHOD(handle_cache.drawable.class, "getIntrinsicWidth", "()I");
return (*env)->CallIntMethod(env, paintable->drawable, getIntrinsicWidth);
int width = (*env)->CallIntMethod(env, paintable->drawable, getIntrinsicWidth);
return width > 0 ? width : 0;
}
static int java_paintable_get_intrinsic_height(GdkPaintable *gdk_paintable)
@ -56,12 +57,8 @@ static int java_paintable_get_intrinsic_height(GdkPaintable *gdk_paintable)
JNIEnv *env = get_jni_env();
JavaPaintable *paintable = JAVA_PAINTABLE(gdk_paintable);
jmethodID getIntrinsicHeight = _METHOD(handle_cache.drawable.class, "getIntrinsicHeight", "()I");
return (*env)->CallIntMethod(env, paintable->drawable, getIntrinsicHeight);
}
static double java_paintable_get_intrinsic_aspect_ratio(GdkPaintable *gdk_paintable)
{
return 0;
int height = (*env)->CallIntMethod(env, paintable->drawable, getIntrinsicHeight);
return height > 0 ? height : 0;
}
static void java_paintable_init(JavaPaintable *java_paintable)
@ -73,7 +70,6 @@ static void java_paintable_paintable_init(GdkPaintableInterface *iface)
iface->snapshot = java_paintable_snapshot;
iface->get_intrinsic_height = java_paintable_get_intrinsic_height;
iface->get_intrinsic_width = java_paintable_get_intrinsic_width;
iface->get_intrinsic_aspect_ratio = java_paintable_get_intrinsic_aspect_ratio;
}
static void java_paintable_class_init(JavaPaintableClass *class)

View file

@ -163,15 +163,17 @@ public class Drawable {
setBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
}
public void setColorFilter(int color, PorterDuff.Mode mode) {}
public void setColorFilter(int color, PorterDuff.Mode mode) {
setColorFilter(new PorterDuffColorFilter(color, mode));
}
public void setColorFilter(ColorFilter filter) {}
public Drawable mutate() {
return this;
}
public int getIntrinsicWidth() {return 24;}
public int getIntrinsicHeight() {return 24;}
public int getIntrinsicWidth() {return -1;}
public int getIntrinsicHeight() {return -1;}
public void setTintList(ColorStateList tint) {}

View file

@ -12,12 +12,18 @@ import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.content.res.TypedArray;
import android.util.AttributeSet;
public class VectorDrawable extends Drawable {
private Bitmap bitmap; // prevent garbage collection
private Bitmap bitmap;
private Paint paint = new Paint();
public VectorDrawable() {
super();
@ -27,7 +33,10 @@ public class VectorDrawable extends Drawable {
final int innerDepth = parser.getDepth() + 1;
int type;
TypedArray a = r.obtainAttributes(attrs, R.styleable.VectorDrawable);
int tint = a.getColor(R.styleable.VectorDrawable_tint, 0);
if (a.hasValue(R.styleable.VectorDrawable_tint)) {
setColorFilter(a.getColor(R.styleable.VectorDrawable_tint, 0),
PorterDuff.Mode.values()[a.getInt(R.styleable.VectorDrawable_tintMode, DEFAULT_TINT_MODE.nativeInt)]);
}
float viewportWidth = a.getFloat(R.styleable.VectorDrawable_viewportWidth, 24);
float viewportHeight = a.getFloat(R.styleable.VectorDrawable_viewportHeight, 24);
float width = a.getDimension(R.styleable.VectorDrawable_width, 24);
@ -43,8 +52,8 @@ public class VectorDrawable extends Drawable {
if (type == XmlPullParser.START_TAG && parser.getName().equals("path")) {
a = r.obtainAttributes(attrs, R.styleable.VectorDrawablePath);
String pathData = a.getString(R.styleable.VectorDrawablePath_pathData);
int fillColor = tint != 0 ? tint : a.getColor(R.styleable.VectorDrawablePath_fillColor, 0);
int strokeColor = tint != 0 ? tint : a.getColor(R.styleable.VectorDrawablePath_strokeColor, 0);
int fillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor, 0);
int strokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor, 0);
float strokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth, 0);
a.recycle();
sb.append(String.format(Locale.ENGLISH, "<path fill=\"#%06x%02x\" stroke=\"#%06x%02x\" stroke-width=\"%f\" d=\"%s\"/>",
@ -55,16 +64,25 @@ public class VectorDrawable extends Drawable {
String svg = sb.toString();
byte[] bytes = svg.getBytes();
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
this.paintable = bitmap.getTexture();
}
@Override
public int getIntrinsicWidth() {
return 24; // FIXME
return bitmap.getWidth();
}
@Override
public int getIntrinsicHeight() {
return 24; // FIXME
return bitmap.getHeight();
}
@Override
public void setColorFilter(ColorFilter filter) {
paint.setColorFilter(filter);
}
@Override
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), getBounds(), paint);
}
}

View file

@ -5,8 +5,10 @@ import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
@ -16,6 +18,7 @@ public class ImageView extends View {
private Bitmap bitmap = null;
private ScaleType scaleType = ScaleType.FIT_CENTER;
private Drawable drawable = null;
private ColorFilter colorFilter = null;
public ImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@ -30,6 +33,9 @@ public class ImageView extends View {
haveCustomMeasure = false;
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ImageView, defStyleAttr, 0);
if (a.hasValue(com.android.internal.R.styleable.ImageView_tint))
colorFilter = new PorterDuffColorFilter(a.getColor(com.android.internal.R.styleable.ImageView_tint, 0),
PorterDuff.Mode.values()[a.getInt(com.android.internal.R.styleable.ImageView_tintMode, PorterDuff.Mode.SRC_IN.nativeInt)]);
setImageDrawable(a.getDrawable(com.android.internal.R.styleable.ImageView_src));
setScaleType(scaletype_from_int[a.getInt(com.android.internal.R.styleable.ImageView_scaleType, 3 /*CENTER*/)]);
a.recycle();
@ -59,6 +65,10 @@ public class ImageView extends View {
}
public void setImageDrawable(Drawable drawable) {
if (colorFilter != null) {
drawable = drawable.mutate();
drawable.setColorFilter(colorFilter);
}
this.drawable = drawable;
if (drawable != null) {
drawable.setCallback(this);