CARPLAY版本整理
This commit is contained in:
@ -0,0 +1,5 @@
|
||||
# mutable image
|
||||
|
||||
像摄像头和视频的图像是变化的,每一帧都不同,我们把这类图片称为mutable image。
|
||||
|
||||
|
@ -0,0 +1,232 @@
|
||||
/**
|
||||
* File: mutable_image.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mutable_image
|
||||
*
|
||||
* Copyright (c) 2018 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-02-28 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "base/timer.h"
|
||||
#include "blend/image_g2d.h"
|
||||
#include "base/widget_vtable.h"
|
||||
#include "mutable_image/mutable_image.h"
|
||||
|
||||
static bitmap_format_t mutable_image_get_disire_format(widget_t* widget, canvas_t* c) {
|
||||
bitmap_format_t format = BITMAP_FMT_NONE;
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL, format);
|
||||
|
||||
if (mutable_image->fb != NULL) {
|
||||
format = (bitmap_format_t)(mutable_image->fb->format);
|
||||
} else {
|
||||
format = lcd_get_desired_bitmap_format(c->lcd);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static bitmap_t* mutable_image_prepare_image(widget_t* widget, canvas_t* c) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
bitmap_format_t format = mutable_image_get_disire_format(widget, c);
|
||||
return_value_if_fail(mutable_image != NULL && mutable_image->prepare_image != NULL, NULL);
|
||||
|
||||
if (mutable_image->create_image != NULL) {
|
||||
void* ctx = mutable_image->create_image_ctx;
|
||||
mutable_image->image = mutable_image->create_image(ctx, format, mutable_image->image);
|
||||
} else if (mutable_image->image == NULL) {
|
||||
mutable_image->image = bitmap_create_ex(widget->w, widget->h, 0, format);
|
||||
}
|
||||
|
||||
if (mutable_image->image == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mutable_image->prepare_image != NULL) {
|
||||
bitmap_t* image = mutable_image->image;
|
||||
void* ctx = mutable_image->prepare_image_ctx;
|
||||
|
||||
return_value_if_fail(mutable_image->prepare_image(ctx, image) == RET_OK, NULL);
|
||||
image->flags |= BITMAP_FLAG_CHANGED;
|
||||
}
|
||||
|
||||
return mutable_image->image;
|
||||
}
|
||||
|
||||
ret_t mutable_image_on_paint_self(widget_t* widget, canvas_t* canvas) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
bitmap_t* bitmap = mutable_image_prepare_image(widget, canvas);
|
||||
|
||||
if (bitmap == NULL) {
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
if (mutable_image->fb != NULL) {
|
||||
rect_t r = rect_init(0, 0, bitmap->w, bitmap->h);
|
||||
image_copy(mutable_image->fb, bitmap, &r, canvas->ox, canvas->oy);
|
||||
} else {
|
||||
if (image_need_transform(widget)) {
|
||||
vgcanvas_t* vg = canvas_get_vgcanvas(canvas);
|
||||
if (vg != NULL) {
|
||||
vgcanvas_save(vg);
|
||||
image_transform(widget, canvas);
|
||||
vgcanvas_draw_icon(vg, bitmap, 0, 0, bitmap->w, bitmap->h, 0, 0, widget->w, widget->h);
|
||||
vgcanvas_restore(vg);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmap->buffer != NULL) {
|
||||
rect_t dst = rect_init(0, 0, widget->w, widget->h);
|
||||
canvas_draw_image_center(canvas, bitmap, &dst);
|
||||
}
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const char* s_mutable_image_clone_properties[] = {WIDGET_PROP_SCALE_X, WIDGET_PROP_SCALE_Y,
|
||||
WIDGET_PROP_ANCHOR_X, WIDGET_PROP_ANCHOR_Y,
|
||||
WIDGET_PROP_ROTATION, NULL};
|
||||
|
||||
ret_t mutable_image_on_destroy(widget_t* widget) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(widget != NULL && mutable_image != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (mutable_image->fb != NULL) {
|
||||
bitmap_destroy(mutable_image->fb);
|
||||
mutable_image->fb = NULL;
|
||||
}
|
||||
|
||||
if (mutable_image->image != NULL) {
|
||||
bitmap_destroy(mutable_image->image);
|
||||
mutable_image->image = NULL;
|
||||
}
|
||||
|
||||
return image_base_on_destroy(widget);
|
||||
}
|
||||
|
||||
ret_t mutable_image_on_attach_parent(widget_t* widget, widget_t* parent) {
|
||||
widget_t* win = widget_get_window(parent);
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL, RET_BAD_PARAMS);
|
||||
if (widget_is_designing_window(win)) {
|
||||
widget_remove_timer(widget, mutable_image->timer_id);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
TK_DECL_VTABLE(mutable_image) = {.size = sizeof(mutable_image_t),
|
||||
.type = WIDGET_TYPE_MUTABLE_IMAGE,
|
||||
.clone_properties = s_mutable_image_clone_properties,
|
||||
.parent = TK_PARENT_VTABLE(image_base),
|
||||
.create = mutable_image_create,
|
||||
.on_destroy = mutable_image_on_destroy,
|
||||
.on_event = image_base_on_event,
|
||||
.on_paint_self = mutable_image_on_paint_self,
|
||||
.on_paint_background = widget_on_paint_null,
|
||||
.on_attach_parent = mutable_image_on_attach_parent,
|
||||
.set_prop = image_base_set_prop,
|
||||
.get_prop = image_base_get_prop};
|
||||
|
||||
static ret_t mutable_image_invalidate(const timer_info_t* info) {
|
||||
widget_t* widget = WIDGET(info->ctx);
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
|
||||
if (mutable_image->need_redraw == NULL ||
|
||||
mutable_image->need_redraw(mutable_image->need_redraw_ctx)) {
|
||||
widget_invalidate_force(WIDGET(info->ctx), NULL);
|
||||
}
|
||||
|
||||
return RET_REPEAT;
|
||||
}
|
||||
|
||||
widget_t* mutable_image_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
widget_t* widget = widget_create(parent, TK_REF_VTABLE(mutable_image), x, y, w, h);
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL, NULL);
|
||||
|
||||
mutable_image_init(widget);
|
||||
|
||||
if (parent != NULL && widget != NULL) {
|
||||
mutable_image_on_attach_parent(widget, parent);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
widget_t* mutable_image_init(widget_t* widget) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL, NULL);
|
||||
image_base_init(widget);
|
||||
mutable_image->timer_id = widget_add_timer(widget, mutable_image_invalidate, 16);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
ret_t mutable_image_set_prepare_image(widget_t* widget, mutable_image_prepare_image_t prepare_image,
|
||||
void* prepare_image_ctx) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL && prepare_image != NULL, RET_BAD_PARAMS);
|
||||
|
||||
mutable_image->prepare_image = prepare_image;
|
||||
mutable_image->prepare_image_ctx = prepare_image_ctx;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t mutable_image_set_need_redraw(widget_t* widget, mutable_image_need_redraw_t need_redraw,
|
||||
void* need_redraw_ctx) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL && need_redraw != NULL, RET_BAD_PARAMS);
|
||||
|
||||
mutable_image->need_redraw = need_redraw;
|
||||
mutable_image->need_redraw_ctx = need_redraw_ctx;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t mutable_image_set_create_image(widget_t* widget, mutable_image_create_image_t create_image,
|
||||
void* create_image_ctx) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL && create_image != NULL, RET_BAD_PARAMS);
|
||||
|
||||
mutable_image->create_image = create_image;
|
||||
mutable_image->create_image_ctx = create_image_ctx;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t mutable_image_set_framebuffer(widget_t* widget, uint32_t w, uint32_t h,
|
||||
bitmap_format_t format, uint8_t* buff) {
|
||||
mutable_image_t* mutable_image = MUTABLE_IMAGE(widget);
|
||||
return_value_if_fail(mutable_image != NULL && buff != NULL, RET_BAD_PARAMS);
|
||||
|
||||
mutable_image->fb = bitmap_create();
|
||||
return_value_if_fail(mutable_image->fb != NULL, RET_OOM);
|
||||
|
||||
bitmap_init(mutable_image->fb, w, h, format, buff);
|
||||
mutable_image->fb->should_free_handle = TRUE;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
widget_t* mutable_image_cast(widget_t* widget) {
|
||||
return_value_if_fail(WIDGET_IS_INSTANCE_OF(widget, mutable_image), NULL);
|
||||
|
||||
return widget;
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
/**
|
||||
* File: mutable_image.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mutable_image
|
||||
*
|
||||
* Copyright (c) 2018 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2019-02-28 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_MUTABLE_IMAGE_H
|
||||
#define TK_MUTABLE_IMAGE_H
|
||||
|
||||
#include "base/widget.h"
|
||||
#include "base/image_base.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
typedef bool_t (*mutable_image_need_redraw_t)(void* ctx);
|
||||
typedef ret_t (*mutable_image_prepare_image_t)(void* ctx, bitmap_t* image);
|
||||
typedef bitmap_t* (*mutable_image_create_image_t)(void* ctx, bitmap_format_t format,
|
||||
bitmap_t* old_image);
|
||||
|
||||
/**
|
||||
* @class mutable_image_t
|
||||
* @parent image_base_t
|
||||
* @annotation ["scriptable","design","widget"]
|
||||
*
|
||||
* mutable图片控件。
|
||||
*
|
||||
* 像摄像头和视频的图像是变化的,每一帧都不同,我们把这类图片称为mutable image。
|
||||
*
|
||||
* 本控件辅助实现摄像头和视频的显示功能。
|
||||
*
|
||||
* mutable\_image\_t是[image\_base\_t](image_base_t.md)的子类控件,image\_base\_t的函数均适用于mutable\_image\_t控件。
|
||||
*
|
||||
* 在xml中使用"mutable\_image"标签创建mutable图片控件。如:
|
||||
*
|
||||
* ```xml
|
||||
* <mutable_image w="100%" h="100%"/>
|
||||
* ```
|
||||
*
|
||||
* >更多用法请参考:
|
||||
* [mutable
|
||||
* image](https://github.com/zlgopen/awtk/blob/master/design/default/ui/mutable_image.xml)
|
||||
*
|
||||
* 在c代码中使用函数mutable\_image\_create创建mutable图片控件。如:
|
||||
*
|
||||
* ```c
|
||||
* widget_t* image = mutable_image_create(win, 10, 10, 200, 200);
|
||||
* mutable_image_set_prepare_image(image, get_camera_image, camera);
|
||||
* ```
|
||||
*
|
||||
* > 创建之后:
|
||||
* >
|
||||
* > 需要用mutable\_image\_set\_create\_image设置创建图片的回调函数。
|
||||
* > 需要用mutable\_image\_set\_prepare\_image设置准备图片的回调函数。
|
||||
*
|
||||
* > 完整示例请参考:[mutable image demo](
|
||||
* https://github.com/zlgopen/awtk-c-demos/blob/master/demos/mutable_image.c)
|
||||
*
|
||||
* 一般不需通过style来设置控件的显示风格,如果在特殊情况下需要,可以参考其它控件。
|
||||
*
|
||||
*/
|
||||
typedef struct _mutable_image_t {
|
||||
image_base_t image_base;
|
||||
|
||||
/*private*/
|
||||
uint32_t timer_id;
|
||||
void* prepare_image_ctx;
|
||||
mutable_image_prepare_image_t prepare_image;
|
||||
|
||||
void* need_redraw_ctx;
|
||||
mutable_image_need_redraw_t need_redraw;
|
||||
|
||||
void* create_image_ctx;
|
||||
mutable_image_create_image_t create_image;
|
||||
|
||||
bitmap_t* fb;
|
||||
bitmap_t* image;
|
||||
canvas_t* canvas;
|
||||
} mutable_image_t;
|
||||
|
||||
/**
|
||||
* @method mutable_image_create
|
||||
* 创建mutable_image对象
|
||||
* @annotation ["constructor", "scriptable"]
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* mutable_image_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method mutable_image_set_need_redraw
|
||||
* 设置need_redraw回调函数。
|
||||
*
|
||||
* 缺省每16ms刷新一次。但有时只是在变化时刷新,所以提供一个回调函数由用户决定是否需要重绘。
|
||||
*
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
* @param {mutable_image_need_redraw_t} need_redraw 检查是否需要重绘的回调函数。
|
||||
* @param {void*} need_redraw_ctx need_redraw回调函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_set_need_redraw(widget_t* widget, mutable_image_need_redraw_t need_redraw,
|
||||
void* need_redraw_ctx);
|
||||
|
||||
/**
|
||||
* @method mutable_image_set_prepare_image
|
||||
* 设置prepare_image回调函数。
|
||||
*
|
||||
* prepare_image回调函数在每次绘制之前被调用,用于准备下一帧要显示的图片。
|
||||
* 比如获取摄像头的预览图片,将其设置到image参数中。
|
||||
*
|
||||
* 注意:在回调函数中,只能修改图片的内容,不用修改图片的大小和格式,如果不匹配请先转换。
|
||||
*
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
* @param {mutable_image_prepare_image_t} prepare_image 准备图片的回调函数。
|
||||
* @param {void*} prepare_image_ctx prepare_image回调函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_set_prepare_image(widget_t* widget, mutable_image_prepare_image_t prepare_image,
|
||||
void* prepare_image_ctx);
|
||||
|
||||
/**
|
||||
* @method mutable_image_set_create_image
|
||||
* 设置create_image回调函数。
|
||||
*
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
* @param {mutable_image_create_image_t} create_image 创建图片的回调函数。
|
||||
* @param {void*} create_image_ctx create_image回调函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_set_create_image(widget_t* widget, mutable_image_create_image_t create_image,
|
||||
void* create_image_ctx);
|
||||
|
||||
/**
|
||||
* @method mutable_image_set_framebuffer
|
||||
* 设置framebuffer(当硬件支持多层合成时才用)。
|
||||
*
|
||||
* 有的硬件支持多层framebuffer,一层用于视图/摄像头,一层用于GUI,由硬件合成最终图像。
|
||||
* 此时可以设置用于摄像头的framebuffer,图像直接绘制到该framebuffer上。
|
||||
*
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
* @param {uint32_t} w framebuffer宽度。
|
||||
* @param {uint32_t} h framebuffer高度。
|
||||
* @param {bitmap_format_t} format framebuffer的格式。
|
||||
* @param {uint8_t*} buff framebuffer内存。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_set_framebuffer(widget_t* widget, uint32_t w, uint32_t h,
|
||||
bitmap_format_t format, uint8_t* buff);
|
||||
|
||||
/**
|
||||
* @method mutable_image_cast
|
||||
* 转换为mutable_image对象(供脚本语言使用)。
|
||||
*
|
||||
* @annotation ["cast"]
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
*
|
||||
* @return {widget_t*} mutable_image对象。
|
||||
*/
|
||||
widget_t* mutable_image_cast(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method mutable_image_init
|
||||
* 初始化 mutable_image (提供给继承的子类使用的)
|
||||
*
|
||||
* @annotation ["cast"]
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
*
|
||||
* @return {widget_t*} mutable_image对象。
|
||||
*/
|
||||
widget_t* mutable_image_init(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method mutable_image_on_destroy
|
||||
* 释放 mutable_image (提供给继承的子类使用的)
|
||||
*
|
||||
* @annotation ["cast"]
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
*
|
||||
* @return {widget_t*} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_on_destroy(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method mutable_image_on_paint_self
|
||||
* mutable_image 的绘制函数 (提供给继承的子类使用的)
|
||||
*
|
||||
* @annotation ["cast"]
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
* @param {canvas_t*} canvas 画布对象。
|
||||
*
|
||||
* @return {widget_t*} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_on_paint_self(widget_t* widget, canvas_t* canvas);
|
||||
|
||||
#define WIDGET_TYPE_MUTABLE_IMAGE "mutable_image"
|
||||
|
||||
#define MUTABLE_IMAGE(widget) ((mutable_image_t*)(mutable_image_cast(WIDGET(widget))))
|
||||
|
||||
/*public for subclass and runtime type check*/
|
||||
TK_EXTERN_VTABLE(mutable_image);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_MUTABLE_IMAGE_H*/
|
Reference in New Issue
Block a user