/*
* Created by LuaView.
* Copyright (c) 2017, Alibaba Group. All rights reserved.
*
* This source code is licensed under the MIT.
* For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
*/
package com.taobao.luaview.userdata.ui;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import com.taobao.luaview.global.LuaResourceFinder;
import com.taobao.luaview.userdata.base.BaseLuaTable;
import com.taobao.luaview.userdata.constants.UDTextAlign;
import com.taobao.luaview.util.ColorUtil;
import com.taobao.luaview.util.DimenUtil;
import com.taobao.luaview.util.LuaUtil;
import com.taobao.luaview.view.LVViewGroup;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Canvas,View.onDraw返回的数据
*
* @author song
*/
public class UDCanvas extends BaseLuaTable {
private static final Map<String, Integer> sPaintAttrIndex;
private static final int PAINT_COLOR = 1;
private static final int PAINT_ALPHA = 2;
private static final int PAINT_STROKE_WIDTH = 3;
private static final int PAINT_TEXT_SIZE = 4;
private static final int PAINT_UNDERLINE = 5;
private static final int PAINT_STRIKE_THROUGH = 6;
private static final int PAINT_BOLD = 7;
private static final int PAINT_LETTER_SPACING = 8;
private static final int PAINT_TYPEFACE = 9;
private static final int PAINT_TEXT_SCALE_X = 10;
private static final int PAINT_TEXT_SKEW_X = 11;
private static final int PAINT_LINEAR_TEXT = 12;
private static final int PAINT_TEXT_ALIGN = 13;
private static final int PAINT_STYLE = 14;
private static final int PAINT_FILTER_BITMAP = 15;
private static final int PAINT_STYLE_FILL = 16;
private static final int PAINT_STYLE_STROKE = 17;
private static final int PAINT_STYLE_BOTH = 18;
private WeakReference<Canvas> mCanvas;
private Paint mPaint;
private RectF mRectF = new RectF();
static {
//attrs
sPaintAttrIndex = new HashMap<String, Integer>();
sPaintAttrIndex.put("color", PAINT_COLOR);
sPaintAttrIndex.put("alpha", PAINT_ALPHA);
sPaintAttrIndex.put("strokewidth", PAINT_STROKE_WIDTH);
sPaintAttrIndex.put("textsize", PAINT_TEXT_SIZE);
sPaintAttrIndex.put("underline", PAINT_UNDERLINE);
sPaintAttrIndex.put("strikethrough", PAINT_STRIKE_THROUGH);
sPaintAttrIndex.put("bold", PAINT_BOLD);//bold
sPaintAttrIndex.put("textbold", PAINT_BOLD);//bold
sPaintAttrIndex.put("letterspacing", PAINT_LETTER_SPACING);
sPaintAttrIndex.put("typeface", PAINT_TYPEFACE);//font
sPaintAttrIndex.put("font", PAINT_TYPEFACE);//font
sPaintAttrIndex.put("textscalex", PAINT_TEXT_SCALE_X);
sPaintAttrIndex.put("textskewx", PAINT_TEXT_SKEW_X);
sPaintAttrIndex.put("lineartext", PAINT_LINEAR_TEXT);
sPaintAttrIndex.put("textalign", PAINT_TEXT_ALIGN);
sPaintAttrIndex.put("style", PAINT_STYLE);
sPaintAttrIndex.put("filterbitmap", PAINT_FILTER_BITMAP);
//style
sPaintAttrIndex.put("fill", PAINT_STYLE_FILL);
sPaintAttrIndex.put("stroke", PAINT_STYLE_STROKE);
sPaintAttrIndex.put("strokefill", PAINT_STYLE_BOTH);
sPaintAttrIndex.put("fillstroke", PAINT_STYLE_BOTH);
sPaintAttrIndex.put("both", PAINT_STYLE_BOTH);
}
public UDCanvas(LVViewGroup target, Canvas canvas, Globals globals, LuaValue metatable, Varargs varargs) {
super(globals, metatable, varargs);
init(target, canvas);
}
private void init(LVViewGroup target, Canvas canvas) {
setCanvas(canvas);
//其他 5
set("nativeObj", new nativeObj());//获取canvas对象
set("size", new size());//获取canvas的宽高, size(), return 100, 100
set("save", new save());//保持当前canvas状态, save()
set("restore", new restore());//恢复canvas状态, restore()
set("clipRect", new clipRect());//clip rect, clipRect(left, top, right, bottom)
//paint 8
set("color", new color());//color(0xff0000)
set("textSize", new textSize());//textSize(20)
set("alpha", new alpha());//alpha(0.5)
set("strokeWidth", new strokeWidth());//画笔宽度 strokeWidth(2)
set("style", new style());//style("fill", "stroke", "fillStroke")
set("font", new font());//font("name")
set("bold", new textBold());//bold(true)
set("resetPaint", new resetPaint());//resetPaint()
//变换操作 4
set("translate", new translate());//translate(dx, dy), translate(-10, 10)
set("scale", new scale());//scale(2, 2) or scale(2, 2, 坐标x, 坐标y)
set("rotate", new rotate());//rotate(30) or rotate(30, 0, 0)
set("skew", new skew());//skew(x, y)
//绘制操作 9
set("drawLine", new drawLine());//drawLine(x1, y1, x2, y2)
set("drawPoint", new drawPoint());//drawPoint(x, y)
set("drawRect", new drawRect());//drawRect(x1, y1, x2, y2)
set("drawRoundRect", new drawRoundRect());//drawRoundRect(x1, y1, x2, y2, rx, ry)
set("drawCircle", new drawCircle());//drawCircle(x, y, r)
set("drawText", new drawText());//drawText("text", x, y)
set("drawOval", new drawOval());//drawOval(x1, y1, x2, y2)
set("drawArc", new drawArc());//drawArc(x1, y1, x2, y2, 开始角度, 结束角度, 是否以中心为点)
set("drawImage", new drawImage());//drawBitmap("name", x, y) or drawBitmap("name, x1, y1, x2, y2) or drawBitmap(Image(), ...)
}
public void setTarget(LVViewGroup mTarget) {
//TODO
}
public void setCanvas(Canvas mCanvas) {
this.mCanvas = new WeakReference<Canvas>(mCanvas);
}
public Canvas getCanvas() {
return mCanvas != null ? mCanvas.get() : null;
}
private Paint getDefaultPaint(LuaValue config) {
if (mPaint == null) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
//config
if (config instanceof LuaTable) {
mPaint.reset();
final LuaValue[] keys = ((LuaTable) config).keys();
if (keys != null && keys.length > 0) {
String key;
LuaValue value;
for (int i = 0; i < keys.length; i++) {
if (LuaUtil.isString(keys[i])) {
key = keys[i].optjstring(null);
if (!TextUtils.isEmpty(key)) {
key = key.toLowerCase();
value = config.get(keys[i]);
if (LuaUtil.isValid(value)) {
Integer pos = sPaintAttrIndex.get(key);
if (pos == null) {
continue;
}
switch (pos) {
case PAINT_COLOR:
mPaint.setColor(ColorUtil.parse(value));
break;
case PAINT_ALPHA:
mPaint.setAlpha(LuaUtil.toAlphaInt(value));
break;
case PAINT_STROKE_WIDTH:
mPaint.setStrokeWidth(DimenUtil.dpiToPxF((float) value.optdouble(0)));
break;
case PAINT_TEXT_SIZE:
mPaint.setTextSize(DimenUtil.spToPx((float) value.optdouble(12.0f)));
break;
case PAINT_UNDERLINE:
mPaint.setUnderlineText(value.optboolean(false));
break;
case PAINT_STRIKE_THROUGH:
mPaint.setStrikeThruText(value.optboolean(false));
break;
case PAINT_BOLD:
mPaint.setFakeBoldText(value.optboolean(false));
break;
case PAINT_LETTER_SPACING:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mPaint.setLetterSpacing(DimenUtil.dpiToPxF((float) value.optdouble(0)));
}
break;
case PAINT_TYPEFACE: {
String typeface = value.optjstring(null);
if (!TextUtils.isEmpty(typeface)) {
mPaint.setTypeface(getLuaResourceFinder().findTypeface(typeface));
}
break;
}
case PAINT_TEXT_SCALE_X:
mPaint.setTextScaleX((float) value.optdouble(1));
break;
case PAINT_TEXT_SKEW_X:
mPaint.setTextSkewX((float) value.optdouble(0));
break;
case PAINT_LINEAR_TEXT:
mPaint.setLinearText(value.optboolean(false));
break;
case PAINT_TEXT_ALIGN: {
setPaintTextAlign(value);
break;
}
case PAINT_STYLE: {
setPaintStyle(value);
break;
}
case PAINT_FILTER_BITMAP:
mPaint.setFilterBitmap(value.optboolean(false));
break;
}
}
}
}
}
}
//anti alias
mPaint.setAntiAlias(true);
}
return mPaint;
}
/**
* set Paint text Align
*
* @param value
*/
private void setPaintTextAlign(LuaValue value) {
Paint paint = getDefaultPaint(null);
if (paint != null) {
final int align = value.optint(1);
switch (align) {
case 0:
case UDTextAlign.LEFT:
paint.setTextAlign(Paint.Align.LEFT);
break;
case 2:
case UDTextAlign.RIGHT:
paint.setTextAlign(Paint.Align.RIGHT);
break;
case 1:
case UDTextAlign.CENTER:
default:
paint.setTextAlign(Paint.Align.CENTER);
break;
}
}
}
/**
* set Paint Style
*
* @param value
*/
private void setPaintStyle(LuaValue value) {
Paint paint = getDefaultPaint(null);
if (paint != null) {
if (LuaUtil.isNumber(value)) {
final int style = value.optint(1);
switch (style) {
case 1:
paint.setStyle(Paint.Style.STROKE);
break;
case 2:
paint.setStyle(Paint.Style.FILL_AND_STROKE);
break;
case 0:
default:
paint.setStyle(Paint.Style.FILL);
break;
}
} else if (LuaUtil.isString(value)) {
final String style = value.optjstring(null);
final Integer styleInt = sPaintAttrIndex.get(style != null ? style.toLowerCase() : null);
if (styleInt != null) {
switch (styleInt) {
case PAINT_STYLE_BOTH:
paint.setStyle(Paint.Style.FILL_AND_STROKE);
break;
case PAINT_STYLE_FILL:
paint.setStyle(Paint.Style.FILL);
break;
case PAINT_STYLE_STROKE:
paint.setStyle(Paint.Style.STROKE);
break;
}
}
}
}
}
//-----------------------------------------------funs-------------------------------------------
/**
* return native Object
*/
class nativeObj extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
return CoerceJavaToLua.coerce(getCanvas());
}
}
/**
* save
*/
class save extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
Canvas canvas = getCanvas();
if (canvas != null) {
canvas.save();
}
return UDCanvas.this;
}
}
/**
* restore
*/
class restore extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
Canvas canvas = getCanvas();
if (canvas != null) {
if (args.narg() >= 2) {
final int count = LuaUtil.getInt(args, 2);
canvas.restoreToCount(count);
} else {
canvas.restore();
}
}
return UDCanvas.this;
}
}
/**
* size
*/
class size extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final float width = DimenUtil.pxToDpi(canvas.getWidth());
final float height = DimenUtil.pxToDpi(canvas.getHeight());
return varargsOf(valueOf(width), valueOf(height));
} else {
return varargsOf(valueOf(0), valueOf(0));
}
}
}
/**
* reset paint
*/
class resetPaint extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
getDefaultPaint(null).reset();
getDefaultPaint(null).setAntiAlias(true);
return UDCanvas.this;
}
}
//-----------------------------------------属性 opts--------------------------------------------
/**
* set color
*/
class color extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
getDefaultPaint(null).setColor(ColorUtil.parse(LuaUtil.getValue(args, 2)));
}
return UDCanvas.this;
}
}
/**
* text size
*/
class textSize extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
getDefaultPaint(null).setTextSize(DimenUtil.spToPx((float) args.optdouble(2, 12.0f)));
}
return UDCanvas.this;
}
}
/**
* alpha
*/
class alpha extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
getDefaultPaint(null).setAlpha(LuaUtil.getAlphaInt(args, 2));
}
return UDCanvas.this;
}
}
/**
* strokeWidth
*/
class strokeWidth extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
getDefaultPaint(null).setStrokeWidth(DimenUtil.dpiToPxF((float) args.optdouble(2, 0)));
}
return UDCanvas.this;
}
}
/**
* style
*/
class style extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
setPaintStyle(args.arg(2));
}
return UDCanvas.this;
}
}
/**
* font
*/
class font extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
final String typeface = args.optjstring(2, null);
if (!TextUtils.isEmpty(typeface)) {
getDefaultPaint(null).setTypeface(getLuaResourceFinder().findTypeface(typeface));
}
}
return UDCanvas.this;
}
}
/**
* text bold
*/
class textBold extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() >= 2) {
getDefaultPaint(null).setFakeBoldText(args.optboolean(2, false));
}
return UDCanvas.this;
}
}
//-----------------------------------------变换 opts--------------------------------------------
/**
* translate
*/
class translate extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
final Canvas canvas = getCanvas();
if (canvas != null) {
if (args.narg() >= 3) {
final float dx = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 2));
final float dy = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 3));
canvas.translate(dx, dy);
}
}
return UDCanvas.this;
}
}
/**
* scale
*/
class scale extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
final Canvas canvas = getCanvas();
if (canvas != null) {
if (args.narg() >= 5) {
final float sx = LuaUtil.getFloat(args, 2);
final float sy = LuaUtil.getFloat(args, 3);
final float px = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 4));
final float py = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 5));
canvas.scale(sx, sy, px, py);
} else if (args.narg() >= 2) {//支持一个参数
final float sx = LuaUtil.getFloat(args, 2);
final float sy = LuaUtil.getFloat(args, 3, 2);
canvas.scale(sx, sy);
}
}
return UDCanvas.this;
}
}
/**
* rotate
*/
class rotate extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
final Canvas canvas = getCanvas();
if (canvas != null) {
if (args.narg() >= 4) {
final float degree = LuaUtil.getFloat(args, 2);
final float x = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 3));
final float y = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 4));
canvas.rotate(degree, x, y);
} else if (args.narg() >= 2) {
final float degree = LuaUtil.getFloat(args, 2);
canvas.rotate(degree);
}
}
return UDCanvas.this;
}
}
/**
* skew
*/
class skew extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
final Canvas canvas = getCanvas();
if (canvas != null) {
if (args.narg() >= 3) {
final float sx = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 2));
final float sy = DimenUtil.dpiToPx(LuaUtil.getFloat(args, 3));
canvas.skew(sx, sy);
}
}
return UDCanvas.this;
}
}
/**
* clip rect
*/
class clipRect extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
clipRects(varargs);
} else {
clipRect(varargs);
}
}
return UDCanvas.this;
}
private void clipRect(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 5) {
final float x1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float dx = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final float dy = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 5));
canvas.clipRect(x1, y1, x1 + dx, y1 + dy);
}
}
private void clipRects(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
float x1, y1, dx, dy;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 4) {
x1 = DimenUtil.dpiToPx(value.get(1));
y1 = DimenUtil.dpiToPx(value.get(2));
dx = DimenUtil.dpiToPx(value.get(3));
dy = DimenUtil.dpiToPx(value.get(4));
canvas.clipRect(x1, y1, x1 + dx, y1 + dy);
}
}
}
}
}
}
}
//-----------------------------------------draw opts--------------------------------------------
/**
* draw Line
*/
class drawLine extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawLines(varargs);
} else {
drawLine(varargs);
}
}
return UDCanvas.this;
}
private void drawLine(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 5) {
final float x1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float x2 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final float y2 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 5));
final LuaValue config = LuaUtil.isTable(value.arg(6)) ? LuaUtil.getTable(value, 6) : null;
canvas.drawLine(x1, y1, x2, y2, getDefaultPaint(config));
}
}
private void drawLines(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
final float pts[] = new float[keys.length * 4];
LuaValue value = null;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 4) {
for (int j = 0; j < 4; j++) {
pts[i * 4 + j] = DimenUtil.dpiToPx(value.get(j + 1));
}
}
}
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
canvas.drawLines(pts, getDefaultPaint(config));
}
}
}
}
}
/**
* draw rects
*/
class drawRect extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawRects(varargs);
} else {
drawRect(varargs);
}
}
return UDCanvas.this;
}
private void drawRect(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 5) {
final float x1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float dx = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final float dy = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 5));
final LuaValue config = LuaUtil.isTable(value.arg(6)) ? LuaUtil.getTable(value, 6) : null;
canvas.drawRect(x1, y1, x1 + dx, y1 + dy, getDefaultPaint(config));
}
}
private void drawRects(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
float x1, y1, dx, dy;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 4) {
x1 = DimenUtil.dpiToPx(value.get(1));
y1 = DimenUtil.dpiToPx(value.get(2));
dx = DimenUtil.dpiToPx(value.get(3));
dy = DimenUtil.dpiToPx(value.get(4));
canvas.drawRect(x1, y1, x1 + dx, y1 + dy, getDefaultPaint(LuaUtil.isTable(value.get(5)) ? value.get(5) : config));
}
}
}
}
}
}
}
/**
* draw rects
*/
class drawRoundRect extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawRoundRects(varargs);
} else {
drawRoundRect(varargs);
}
}
return UDCanvas.this;
}
private void drawRoundRect(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 7) {
final float x1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float dx = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final float dy = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 5));
final float x3 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 6));
final float y3 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 7));
final LuaValue config = LuaUtil.isTable(value.arg(8)) ? LuaUtil.getTable(value, 8) : null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawRoundRect(x1, y1, x1 + dx, y1 + dy, x3, y3, getDefaultPaint(config));
} else {
drawRoundRectPlain(x1, y1, x1 + dx, y1 + dy, x3, y3, getDefaultPaint(config), canvas);
}
}
}
private void drawRoundRects(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
float x1, y1, dx, dy, x3, y3;
Paint paint = null;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 6) {
x1 = DimenUtil.dpiToPx(value.get(1));
y1 = DimenUtil.dpiToPx(value.get(2));
dx = DimenUtil.dpiToPx(value.get(3));
dy = DimenUtil.dpiToPx(value.get(4));
x3 = DimenUtil.dpiToPx(value.get(5));
y3 = DimenUtil.dpiToPx(value.get(6));
paint = getDefaultPaint(LuaUtil.isTable(value.get(7)) ? value.get(7) : config);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawRoundRect(x1, y1, x1 + dx, y1 + dy, x3, y3, paint);
} else {
drawRoundRectPlain(x1, y1, x1 + dx, y1 + dy, x3, y3, paint, canvas);
}
}
}
}
}
}
}
//api 21 以下的绘制
public void drawRoundRectPlain(float left, float top, float right, float bottom, float rx, float ry, Paint paint, Canvas canvas) {
Path path = new Path();
if (rx < 0) {
rx = 0;
}
if (ry < 0) {
ry = 0;
}
float width = right - left;
float height = bottom - top;
if (rx > width / 2) {
rx = width / 2;
}
if (ry > height / 2) {
ry = height / 2;
}
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
path.rLineTo(-widthMinusCorners, 0);
path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
path.rLineTo(0, heightMinusCorners);
path.rQuadTo(0, ry, rx, ry);//bottom-left corner
path.rLineTo(widthMinusCorners, 0);
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
canvas.drawPath(path, paint);
}
}
/**
* draw arc
*/
class drawArc extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawArcs(varargs);
} else {
drawArc(varargs);
}
}
return UDCanvas.this;
}
private void drawArc(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 8) {
final float x1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float dx = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final float dy = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 5));
final float x3 = LuaUtil.getFloat(value, 6);
final float y3 = LuaUtil.getFloat(value, 7);
final boolean use = LuaUtil.getBoolean(value, false, 8);
final LuaValue config = LuaUtil.isTable(value.arg(9)) ? LuaUtil.getTable(value, 9) : null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc(x1, y1, x1 + dx, y1 + dy, x3, y3, use, getDefaultPaint(config));
} else {
final RectF rectF = mRectF;
rectF.left = x1;
rectF.top = y1;
rectF.right = x1 + dx;
rectF.bottom = y1 + dy;
canvas.drawArc(rectF, x3, y3, use, getDefaultPaint(config));
}
}
}
private void drawArcs(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
float x1, y1, dx, dy, x3, y3;
boolean use = false;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 7) {
x1 = DimenUtil.dpiToPx(value.get(1));
y1 = DimenUtil.dpiToPx(value.get(2));
dx = DimenUtil.dpiToPx(value.get(3));
dy = DimenUtil.dpiToPx(value.get(4));
x3 = (float) value.get(5).optdouble(0);
y3 = (float) value.get(6).optdouble(0);
use = value.get(7).optboolean(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawArc(x1, y1, x1 + dx, y1 + dy, x3, y3, use,
getDefaultPaint(LuaUtil.isTable(value.get(8)) ? value.get(8) : config));
} else {
final RectF rectF = mRectF;
rectF.left = x1;
rectF.top = y1;
rectF.right = x1 + dx;
rectF.bottom = y1 + dy;
canvas.drawArc(rectF, x3, y3, use, getDefaultPaint(config));
}
}
}
}
}
}
}
}
/**
* draw a point in canvas
*/
class drawPoint extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawPoints(varargs);
} else {
drawPoint(varargs);
}
}
return UDCanvas.this;
}
private void drawPoint(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 3) {
final float x = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final LuaValue config = LuaUtil.isTable(value.arg(4)) ? LuaUtil.getTable(value, 4) : null;
canvas.drawPoint(x, y, getDefaultPaint(config));
}
}
private void drawPoints(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
final float pts[] = new float[keys.length * 2];
LuaValue value = null;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 2) {
for (int j = 0; j < 2; j++) {
pts[i * 2 + j] = DimenUtil.dpiToPx(value.get(j + 1));
}
}
}
canvas.drawPoints(pts, getDefaultPaint(config));
}
}
}
}
}
/**
* draw a circle in canvas
*/
class drawCircle extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawCircles(varargs);
} else {
drawCircle(varargs);
}
}
return UDCanvas.this;
}
private void drawCircle(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 4) {
final float x = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float r = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final LuaValue config = LuaUtil.isTable(value.arg(5)) ? LuaUtil.getTable(value, 5) : null;
canvas.drawCircle(x, y, r, getDefaultPaint(config));
}
}
private void drawCircles(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 3) {
canvas.drawCircle(DimenUtil.dpiToPx(value.get(1)),
DimenUtil.dpiToPx(value.get(2)),
DimenUtil.dpiToPx(value.get(3)),
getDefaultPaint(LuaUtil.isTable(value.get(4)) ? value.get(4) : config));
}
}
}
}
}
}
}
/**
* draw a text in canvas
*/
class drawText extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawTexts(varargs);
} else {
drawText(varargs);
}
}
return UDCanvas.this;
}
private void drawText(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 4) {
final CharSequence text = LuaUtil.getText(value, 2);
if (!TextUtils.isEmpty(text)) {
final float x = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float y = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final LuaValue config = LuaUtil.isTable(value.arg(5)) ? LuaUtil.getTable(value, 5) : null;
canvas.drawText(text, 0, text.length(), x, y, getDefaultPaint(config));
}
}
}
private void drawTexts(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
CharSequence text = null;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 3) {
text = LuaUtil.toText(value.get(1));
if (!TextUtils.isEmpty(text)) {
canvas.drawText(text, 0, text.length(),
DimenUtil.dpiToPx(value.get(2)),
DimenUtil.dpiToPx(value.get(3)),
getDefaultPaint(LuaUtil.isTable(value.get(4)) ? value.get(4) : config));
}
}
}
}
}
}
}
}
/**
* draw a oval in canvas
*/
class drawOval extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
if (varargs.istable(2)) {
drawOvals(varargs);
} else {
drawOval(varargs);
}
}
return UDCanvas.this;
}
private void drawOval(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 5) {
final float x1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 2));
final float y1 = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 3));
final float dx = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 4));
final float dy = DimenUtil.dpiToPx(LuaUtil.getFloat(value, 5));
final LuaValue config = LuaUtil.isTable(value.arg(6)) ? LuaUtil.getTable(value, 6) : null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawOval(x1, y1, x1 + dx, y1 + dy, getDefaultPaint(config));
} else {
final RectF rectF = mRectF;
rectF.left = x1;
rectF.top = y1;
rectF.right = x1 + dx;
rectF.bottom = y1 + dy;
canvas.drawOval(rectF, getDefaultPaint(config));
}
}
}
private void drawOvals(Varargs varargs) {
final Canvas canvas = getCanvas();
if (canvas != null) {
final LuaTable table = LuaUtil.getTable(varargs, 2);
final LuaValue config = LuaUtil.isTable(varargs.arg(3)) ? LuaUtil.getTable(varargs, 3) : null;
if (table != null) {
final LuaValue[] keys = table.keys();
if (keys.length > 0) {
LuaValue value = null;
float x1, y1, dx, dy;
for (int i = 0; i < keys.length; i++) {
value = table.get(keys[i]);
if (value instanceof LuaTable && value.length() >= 4) {
x1 = DimenUtil.dpiToPx(value.get(1));
y1 = DimenUtil.dpiToPx(value.get(2));
dx = DimenUtil.dpiToPx(value.get(3));
dy = DimenUtil.dpiToPx(value.get(4));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
canvas.drawOval(x1, y1, x1 + dx, y1 + dy, getDefaultPaint(LuaUtil.isTable(value.get(5)) ? value.get(5) : config));
} else {
final RectF rectF = mRectF;
rectF.left = x1;
rectF.top = y1;
rectF.right = x1 + dx;
rectF.bottom = y1 + dy;
canvas.drawOval(rectF, getDefaultPaint(config));
}
}
}
}
}
}
}
}
/**
* draw color
*/
class drawColor extends VarArgFunction {
@Override
public Varargs invoke(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() > 1) {
final Integer color = ColorUtil.parse(LuaUtil.getInt(value, 2));
final Integer alpha = LuaUtil.getAlphaInt(value, 3);
if (color != null) {
if (alpha != null) {
final int r = Color.red(color);
final int g = Color.green(color);
final int b = Color.green(color);
canvas.drawARGB(alpha, r, g, b);
} else {
canvas.drawColor(color);
}
}
}
return UDCanvas.this;
}
}
/**
* draw a bitmap
*/
class drawImage extends VarArgFunction {
@Override
public Varargs invoke(Varargs varargs) {
if (varargs != null && varargs.narg() > 1) {
drawImage(varargs);
}
return UDCanvas.this;
}
private void drawImage(Varargs value) {
final Canvas canvas = getCanvas();
if (canvas != null && value != null && value.narg() >= 4) {
final LuaValue param = LuaUtil.getValue(value, 2);
Drawable drawable = null;
if (LuaUtil.isString(param)) {
final String uri = param.optjstring(null);
final LuaResourceFinder finder = getLuaResourceFinder();
if (!TextUtils.isEmpty(uri) && finder != null) {
drawable = finder.findDrawable(uri);
}
} else if (param instanceof UDImageView) {
View view = ((UDImageView) param).getView();
if (view instanceof ImageView) {
drawable = ((ImageView) view).getDrawable();
}
}
Bitmap bitmap = null;
if (drawable != null) {
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
} else {//TODO glide GlideImageDrawable,通过反射
try {
Method method = drawable.getClass().getMethod("getBitmap");
if (method != null) {
bitmap = (Bitmap) method.invoke(drawable);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (bitmap != null) {
final float x = DimenUtil.dpiToPx(LuaUtil.getValue(value, 3));
final float y = DimenUtil.dpiToPx(LuaUtil.getValue(value, 4));
LuaValue config = null;
if (value.narg() >= 6) {
final float dx = DimenUtil.dpiToPx(LuaUtil.getValue(value, 5));
final float dy = DimenUtil.dpiToPx(LuaUtil.getValue(value, 6));
config = LuaUtil.isTable(value.arg(7)) ? LuaUtil.getTable(value, 7) : null;
canvas.drawBitmap(bitmap, null, new RectF(x, y, x + dx, y + dy), getDefaultPaint(config));
} else {
config = LuaUtil.isTable(value.arg(5)) ? LuaUtil.getTable(value, 5) : null;
canvas.drawBitmap(bitmap, x, y, getDefaultPaint(config));
}
}
}
}
}
}