improve vgcanvas on picasso

This commit is contained in:
xianjimli 2018-04-25 15:14:30 +08:00
parent 11788a5113
commit a9ed485499
13 changed files with 24403 additions and 49 deletions

View File

@ -2940,6 +2940,7 @@ PEXPORT void PICAPI ps_quad_curve_to(ps_context* ctx, const ps_point* cp, const
*/
PEXPORT void PICAPI ps_arc(ps_context* ctx, const ps_point* cp, float radius,
float sangle, float eangle, ps_bool clockwise);
PEXPORT void PICAPI ps_arc_to(ps_context* ctx, float r, const ps_point* tp, const ps_point* ep);
/**
* \fn void ps_tangent_arc(ps_context* ctx, const ps_rect* rect, float sangle, float sweep)

View File

@ -18,6 +18,31 @@
namespace picasso {
/**
* Jim: picasso原始实现中
* path时
*/
static inline void ps_add_path(ps_context* ctx, vertex_source& vs) {
conv_transform cvs(vs, ctx->state->world_matrix);
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(cvs, 0);
else
ctx->path.join_path(cvs, 0);
}
static inline void ps_last_point(ps_context* ctx, ps_point* pt) {
ps_point p = {0, 0};
p.x = ctx->path.last_x();
p.y = ctx->path.last_y();
ps_viewport_to_world(ctx, &p);
*pt = p;
return;
}
static inline void _clip_path(context_state* state, const graphic_path& p, filling_rule r)
{
if (!state->clip.path.total_vertices()) {
@ -346,11 +371,18 @@ void PICAPI ps_stroke(ps_context* ctx)
return;
}
ps_matrix m;
ps_get_matrix(ctx, &m);
ps_identity(ctx);
ctx->canvas->p->render_shadow(ctx->state, ctx->path, false, true);
ctx->canvas->p->render_stroke(ctx->state, ctx->raster, ctx->path);
ctx->canvas->p->render_blur(ctx->state);
ctx->path.free_all();
ctx->raster.reset();
ps_set_matrix(ctx, &m);
global_status = STATUS_SUCCEED;
}
@ -366,11 +398,18 @@ void PICAPI ps_fill(ps_context* ctx)
return;
}
ps_matrix m;
ps_get_matrix(ctx, &m);
ps_identity(ctx);
ctx->canvas->p->render_shadow(ctx->state, ctx->path, true, false);
ctx->canvas->p->render_fill(ctx->state, ctx->raster, ctx->path);
ctx->canvas->p->render_blur(ctx->state);
ctx->path.free_all();
ctx->raster.reset();
ps_set_matrix(ctx, &m);
global_status = STATUS_SUCCEED;
}
@ -804,6 +843,8 @@ void PICAPI ps_new_sub_path(ps_context* ctx)
void PICAPI ps_rectangle(ps_context* ctx, const ps_rect* pr)
{
ps_rect r;
ps_point pt = {pr->x, pr->y};
if (!picasso::is_valid_system_device()) {
global_status = STATUS_DEVICE_ERROR;
return;
@ -814,6 +855,13 @@ void PICAPI ps_rectangle(ps_context* ctx, const ps_rect* pr)
return;
}
ps_world_to_viewport(ctx, &pt);
r.x = pt.x;
r.y = pt.y;
r.w = pr->w;
r.h = pr->h;
pr = &r;
ctx->path.set_shape(picasso::graphic_path::shape_rectangle); //It is because boder edge.
ctx->path.move_to(FLT_TO_SCALAR(floor(pr->x)), FLT_TO_SCALAR(floor(pr->y)));
ctx->path.hline_rel(FLT_TO_SCALAR(floor(pr->w)));
@ -843,10 +891,7 @@ void PICAPI ps_rounded_rect(ps_context* ctx, const ps_rect* r, float ltx, float
rr.radius(FLT_TO_SCALAR(ltx), FLT_TO_SCALAR(lty), FLT_TO_SCALAR(rtx), FLT_TO_SCALAR(rty),
FLT_TO_SCALAR(rbx), FLT_TO_SCALAR(rby), FLT_TO_SCALAR(lbx), FLT_TO_SCALAR(lby));
rr.normalize_radius();
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(rr, 0);
else
ctx->path.join_path(rr, 0);
ps_add_path(ctx, rr);
global_status = STATUS_SUCCEED;
}
@ -864,10 +909,7 @@ void PICAPI ps_ellipse(ps_context* ctx, const ps_rect* r)
picasso::ellipse e(FLT_TO_SCALAR(floor(r->x)+r->w/2), FLT_TO_SCALAR(floor(r->y)+r->h/2),
FLT_TO_SCALAR(r->w/2), FLT_TO_SCALAR(r->h/2));
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(e, 0);
else
ctx->path.join_path(e, 0);
ps_add_path(ctx, e);
global_status = STATUS_SUCCEED;
}
@ -900,6 +942,10 @@ void PICAPI ps_move_to(ps_context* ctx, const ps_point* pt)
return;
}
ps_point p = {pt->x, pt->y};
ps_world_to_viewport(ctx, &p);
pt = &p;
ctx->path.move_to(FLT_TO_SCALAR(floor(pt->x)), FLT_TO_SCALAR(floor(pt->y)));
global_status = STATUS_SUCCEED;
}
@ -916,6 +962,10 @@ void PICAPI ps_line_to(ps_context* ctx, const ps_point* pt)
return;
}
ps_point p = {pt->x, pt->y};
ps_world_to_viewport(ctx, &p);
pt = &p;
ctx->path.line_to(FLT_TO_SCALAR(floor(pt->x)), FLT_TO_SCALAR(floor(pt->y)));
global_status = STATUS_SUCCEED;
}
@ -933,14 +983,13 @@ void PICAPI ps_bezier_curve_to(ps_context* ctx, const ps_point* fcp,
return;
}
picasso::curve4 c(FLT_TO_SCALAR(floor(ctx->path.last_x())), FLT_TO_SCALAR(floor(ctx->path.last_y())),
ps_point lp;
ps_last_point(ctx, &lp);
picasso::curve4 c(FLT_TO_SCALAR(floor(lp.x)), FLT_TO_SCALAR(floor(lp.y)),
FLT_TO_SCALAR(floor(fcp->x)), FLT_TO_SCALAR(floor(fcp->y)), FLT_TO_SCALAR(floor(scp->x)),
FLT_TO_SCALAR(floor(scp->y)), FLT_TO_SCALAR(floor(ep->x)), FLT_TO_SCALAR(floor(ep->y)));
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(c, 0);
else
ctx->path.join_path(c, 0);
ps_add_path(ctx, c);
global_status = STATUS_SUCCEED;
}
@ -956,14 +1005,33 @@ void PICAPI ps_quad_curve_to(ps_context* ctx, const ps_point* cp, const ps_point
return;
}
picasso::curve3 c(FLT_TO_SCALAR(floor(ctx->path.last_x())), FLT_TO_SCALAR(floor(ctx->path.last_y())),
ps_point lp;
ps_last_point(ctx, &lp);
picasso::curve3 c(FLT_TO_SCALAR(floor(lp.x)), FLT_TO_SCALAR(floor(lp.y)),
FLT_TO_SCALAR(floor(cp->x)), FLT_TO_SCALAR(floor(cp->y)),
FLT_TO_SCALAR(floor(ep->x)), FLT_TO_SCALAR(floor(ep->y)));
ps_add_path(ctx, c);
global_status = STATUS_SUCCEED;
}
void PICAPI ps_arc_to(ps_context* ctx, float r, const ps_point* tp, const ps_point* ep) {
ps_path* path = ps_path_create();
ps_point startp = {tp->x, tp->y};
ps_world_to_viewport(ctx, &startp);
ps_point endp = {ep->x, ep->y};
ps_world_to_viewport(ctx, &endp);
ps_path_tangent_arc_to(path, r, &startp, &endp);
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(c, 0);
ctx->path.concat_path(path->path, 0);
else
ctx->path.join_path(c, 0);
ctx->path.join_path(path->path, 0);
ps_path_unref(path);
global_status = STATUS_SUCCEED;
}
@ -983,10 +1051,7 @@ void PICAPI ps_arc(ps_context* ctx, const ps_point* cp, float r,
picasso::arc a(FLT_TO_SCALAR(floor(cp->x)), FLT_TO_SCALAR(floor(cp->y)),
FLT_TO_SCALAR(r), FLT_TO_SCALAR(r), FLT_TO_SCALAR(sa), FLT_TO_SCALAR(ea), (clockwise ? true : false));
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(a, 0);
else
ctx->path.join_path(a, 0);
ps_add_path(ctx, a);
global_status = STATUS_SUCCEED;
}
@ -1010,10 +1075,7 @@ void PICAPI ps_tangent_arc(ps_context* ctx, const ps_rect* r, float sa, float sw
picasso::bezier_arc ba(Floor(cx), Floor(cy), xr, yr, FLT_TO_SCALAR(sa), FLT_TO_SCALAR(sw));
picasso::conv_curve cr(ba);
if (picasso::_is_closed_path(ctx->path))
ctx->path.concat_path(cr, 0);
else
ctx->path.join_path(cr, 0);
ps_add_path(ctx, cr);
global_status = STATUS_SUCCEED;
}

24174
3rd/picasso/tags Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,8 +10,8 @@ GTEST_ROOT = os.path.join(LFTK_ROOT, '3rd/gtest/googletest')
BIN_DIR=os.path.join(LFTK_ROOT, 'bin')
LIB_DIR=os.path.join(LFTK_ROOT, 'lib')
LCD='NANOVG'
LCD='SDL'
LCD='NANOVG'
VGCANVAS='AGG'
VGCANVAS='PICASSO'
@ -23,6 +23,11 @@ if LCD == 'NANOVG':
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_NANOVG -DWITH_GL3'
else:
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_STB_IMAGE -DWITH_STB_FONT -DSDL2'
if VGCANVAS == 'AGG':
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_AGG'
elif VGCANVAS == 'PICASSO':
COMMON_CCFLAGS = COMMON_CCFLAGS + ' -DWITH_PICASSO'
os.environ['LCD'] = LCD
os.environ['VGCANVAS'] =VGCANVAS

View File

@ -302,16 +302,54 @@ static void draw_basic_shapes(vgcanvas_t* vg, bool_t stroke) {
static void stroke_lines(vgcanvas_t* vg) {
vgcanvas_save(vg);
vgcanvas_move_to(vg, 0, 0);
vgcanvas_line_to(vg, 40, 40);
vgcanvas_translate(vg, 40, 0);
vgcanvas_quad_to(vg, 40, 40, 40, 0);
vgcanvas_move_to(vg, 0, 0);
vgcanvas_quad_to(vg, 40, 0, 40, 40);
vgcanvas_translate(vg, 40, 0);
vgcanvas_move_to(vg, 0, 0);
vgcanvas_bezier_to(vg, 20, 0, 20, 40, 40, 40);
vgcanvas_translate(vg, 40, 0);
vgcanvas_stroke(vg);
vgcanvas_set_line_width(vg, 2);
vgcanvas_arc(vg, 20, 20, 15, 0, 3.14, FALSE);
vgcanvas_arc(vg, 20, 20, 15, 0, 3.14/2, TRUE);
vgcanvas_stroke(vg);
vgcanvas_stroke(vg);
vgcanvas_restore(vg);
}
static void draw_image(vgcanvas_t* vg) {
bitmap_t img;
vgcanvas_translate(vg, 10, 0);
image_manager_load(default_im(), "earth", &img);
vgcanvas_draw_image(vg, &img, 5, 5, img.w-10, img.h-10, 0, 0, img.w * 2, img.h * 2);
vgcanvas_translate(vg, 100, 0);
vgcanvas_draw_image(vg, &img, 0, 0, img.w, img.h, 0, 0, img.w, img.h);
image_manager_load(default_im(), "bricks", &img);
vgcanvas_translate(vg, 50, 0);
vgcanvas_translate(vg, img.w >> 1, img.h >> 1);
vgcanvas_rotate(vg, 3.14/4);
vgcanvas_translate(vg, -img.w >> 1, -img.h >> 1);
vgcanvas_scale(vg, 1.5, 1.5);
vgcanvas_draw_image(vg, &img, 0, 0, img.w, img.h, 0, 0, img.w, img.h);
return;
}
static ret_t on_paint_vg(void* ctx, event_t* e) {
paint_event_t* evt = (paint_event_t*)e;
canvas_t* c = evt->c;
@ -325,7 +363,9 @@ static ret_t on_paint_vg(void* ctx, event_t* e) {
vgcanvas_translate(vg, 0, 50);
draw_basic_shapes(vg, TRUE);
vgcanvas_translate(vg, 0, 50);
//stroke_lines(vg);
stroke_lines(vg);
vgcanvas_translate(vg, 0, 50);
draw_image(vg);
return RET_OK;
}

View File

@ -157,4 +157,4 @@ const unsigned char image_slider_drag[] = {
0x51,0x51,0x51,0xc0,0x51,0x51,0x51,0xff,0x51,0x51,0x51,0xff,0x51,0x51,0x51,0xff,0x51,0x51,0x51,0xff,
0x51,0x51,0x51,0xd0,0x50,0x50,0x50,0xa0,0x50,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};/*3176*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x7f,0x00,0x00,};/*3176*/

View File

@ -116,4 +116,4 @@ const unsigned char image_unchecked[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0x7f,0x00,0x00,};/*2344*/
0x00,0x00,0x00,0x00,};/*2344*/

View File

@ -10,4 +10,4 @@ const unsigned char ui_window2[] = {
0x6f,0x70,0x00,0x74,0x65,0x78,0x74,0x00,0x54,0x6f,0x70,0x00,0x00,0x00,0x01,0x00,0x0a,0x00,0x03,0x02,
0x01,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x6e,0x61,
0x6d,0x65,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x74,0x65,0x78,0x74,0x00,0x43,0x6c,0x6f,0x73,0x65,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,};/*227*/
0x00,0x00,0x00,0x6c,0x66,0x74,0x6b,};/*227*/

View File

@ -39,6 +39,25 @@ static ret_t image_stb_destroy(bitmap_t* image) {
return RET_OK;
}
static ret_t image_to_abgr32(bitmap_t* image) {
int i = 0;
uint8_t* p = image->data;
int n = image->w * image->h;
for(i = 0; i < n; i++) {
uint8_t t = p[0];
p[0] = p[3];
p[3] = t;
t = p[1];
p[1] = p[2];
p[2] = t;
p+=4;
}
return RET_OK;
}
static ret_t image_loader_stb_load(image_loader_t* l, const uint8_t* buff, uint32_t buff_size,
bitmap_t* image) {
int i = 0;
@ -73,17 +92,26 @@ static ret_t image_loader_stb_load(image_loader_t* l, const uint8_t* buff, uint3
data4 += 4;
data += 3;
}
#ifdef WITH_PICASSO
image_to_abgr32(image);
#endif
} else {
image->data = data;
image->destroy = image_stb_destroy;
for (i = 0; i < w * h; i += n) {
if (data[3] != 0xff) {
#ifdef WITH_PICASSO
image_to_abgr32(image);
#endif
return RET_OK;
}
data += 4;
}
image->flags |= BITMAP_FLAG_OPAQUE;
#ifdef WITH_PICASSO
image_to_abgr32(image);
#endif
}
return RET_OK;

View File

@ -75,7 +75,7 @@ static ret_t lcd_mem_draw_points(lcd_t* lcd, point_t* points, uint32_t nr) {
if (color.rgba.a == 0xff) {
p[0] = pixel;
} else if (color.rgba.a) {
p[0] = blend_pixel(p[i], color);
p[0] = blend_pixel(p[0], color);
}
}

View File

@ -159,6 +159,7 @@ lcd_t* lcd_sdl2_init(SDL_Renderer* render) {
lcd.lcd_mem = (lcd_mem_t*)lcd_mem_create(w, h, FALSE);
lcd.texture =
SDL_CreateTexture(render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, w, h);
//SDL_CreateTexture(render, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, w, h);
// SDL_CreateTexture(render, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, w, h);
return base;

View File

@ -23,8 +23,13 @@
#include "base/mem.h"
#include "base/utf8.h"
#include "base/vgcanvas.h"
#include "picasso_objects.h"
#include "base/resource_manager.h"
#define MAX_IMAGE_NR 256
#define format COLOR_FORMAT_ABGR
//#define format COLOR_FORMAT_RGBA
typedef struct _vgcanvas_picasso_t {
vgcanvas_t base;
@ -35,6 +40,7 @@ typedef struct _vgcanvas_picasso_t {
ps_path* path;
ps_context* vg;
ps_canvas* canvas;
ps_image* images[MAX_IMAGE_NR];
} vgcanvas_picasso_t;
static ps_point ps_point_init(float_t x, float_t y) {
@ -53,6 +59,29 @@ static ps_color ps_color_init(color_t color) {
return c;
}
static ps_image* vgcanvas_picasso_ensure_image(vgcanvas_picasso_t* canvas, bitmap_t* img) {
int32_t i = 0;
ps_image* pimg = NULL;
for (i = 0; i < MAX_IMAGE_NR; i++) {
ps_image* iter = canvas->images[i];
if (iter && iter->buffer.buffer() == (img->data)) {
return iter;
}
}
pimg = ps_image_create_with_data((ps_byte*)img->data, format, img->w, img->h, img->w * 4);
pimg->buffer.set_transparent(!(img->flags & BITMAP_FLAG_OPAQUE));
for (i = 0; i < MAX_IMAGE_NR; i++) {
if (canvas->images[i] == NULL) {
canvas->images[i] = pimg;
return pimg;
}
}
return NULL;
}
ret_t vgcanvas_picasso_begin_frame(vgcanvas_t* vgcanvas, rect_t* dirty_rect) {
ps_color color = {0, 0, 0, 0};
vgcanvas_picasso_t* picasso = (vgcanvas_picasso_t*)vgcanvas;
@ -161,12 +190,13 @@ static ret_t vgcanvas_picasso_arc_to(vgcanvas_t* vgcanvas, float_t x1, float_t y
ps_point p2 = ps_point_init(x2, y2);
ps_context* vg = ((vgcanvas_picasso_t*)vgcanvas)->vg;
/*TODO:
* ps_arc_to(vg, r, &p1, &p2);
*/
(void)p1;
(void)p2;
(void)vg;
/*TODO*/
return RET_OK;
}
@ -383,19 +413,28 @@ static uint32_t vgcanvas_picasso_measure_text(vgcanvas_t* vgcanvas, const char*
static ret_t vgcanvas_picasso_draw_image(vgcanvas_t* vgcanvas, bitmap_t* img, float_t sx, float_t sy,
float_t sw, float_t sh, float_t dx, float_t dy, float_t dw,
float_t dh) {
float_t x = 0;
float_t y = 0;
float_t w = 0;
float_t h = 0;
float_t scale_x = dw/sw;
float_t scale_y = dh/sh;
ps_context* vg = ((vgcanvas_picasso_t*)vgcanvas)->vg;
ps_image* pimg = vgcanvas_picasso_ensure_image((vgcanvas_picasso_t*)vgcanvas, img);
(void)vg;
(void)sx;
(void)sy;
(void)sw;
(void)sh;
(void)dx;
(void)dy;
(void)dw;
(void)dh;
(void)img;
/*TODO*/
vgcanvas_clip_rect(vgcanvas, dx, dy, dw, dh);
ps_set_source_image(vg, pimg);
ps_set_filter(vg, FILTER_NEAREST);
vgcanvas_begin_path(vgcanvas);
x = dx - scale_x * sx;
y = dy - scale_y * sy;
w = img->w * scale_x;
h = img->h * scale_y;
vgcanvas_rect(vgcanvas, x, y, w, h);
vgcanvas_fill(vgcanvas);
return RET_OK;
}
@ -586,7 +625,7 @@ vgcanvas_t* vgcanvas_create(uint32_t w, uint32_t h, void* buff) {
picasso->base.vt = &vt;
ps_initialize();
picasso->canvas = ps_canvas_create_with_data((ps_byte*)buff, COLOR_FORMAT_ABGR, w, h, w*4);
picasso->canvas = ps_canvas_create_with_data((ps_byte*)buff, format, w, h, w*4);
picasso->vg = ps_context_create(picasso->canvas, 0);
return &(picasso->base);

View File

@ -1,5 +1,7 @@
#!/bin/bash
scons
BIN_DIR=./bin
RAW_DIR=demos/res/raw
SRC_DIR=demos/res/src
@ -15,12 +17,13 @@ $BIN_DIR/resgen $RAW_DIR/fonts/font.ttf $SRC_DIR/fonts/default_ttf.data
$BIN_DIR/resgen $RAW_DIR/fonts/action_protocol.ttf $SRC_DIR/fonts/ap.data
$BIN_DIR/fontgen $RAW_DIR/fonts/font.ttf $RAW_DIR/fonts/text.txt $SRC_DIR/fonts/default.data 20
for f in $RAW_DIR/images/*.png;
for f in $RAW_DIR/images/*.*;
do
F1=${f/raw/src};
F2=${F1/\.png/.data};
F3=${F2/\.jpg/.data};
echo $BIN_DIR/imagegen $f $F3
$BIN_DIR/imagegen $f $F3
done
@ -29,6 +32,7 @@ do
F1=${f/raw/src};
F2=${F1/\.xml/.data};
echo $BIN_DIR/xml_to_ui $f $F2
$BIN_DIR/xml_to_ui $f $F2
done
@ -50,4 +54,4 @@ function gen_res_c() {
gen_res_c > demos/resource.c
scons