Mercurial > MadButterfly
changeset 612:b1d1b6c5af90 openvg
Implements setting pattern matrix for OpenVG
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 07 Jul 2010 18:44:17 +0800 |
parents | 38383f5f645d |
children | 6a0be737a3f3 |
files | include/mb_graph_engine_openvg.h src/graph_engine_openvg.c |
diffstat | 2 files changed, 106 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/include/mb_graph_engine_openvg.h Mon Jul 05 14:41:43 2010 +0800 +++ b/include/mb_graph_engine_openvg.h Wed Jul 07 18:44:17 2010 +0800 @@ -21,7 +21,6 @@ #define mbe_scaled_font_destroy(scaled) #define mbe_font_face_reference(face) ((mbe_font_face_t *)NULL) #define mbe_scaled_font_create(face, fnt_mtx, ctm) ((mbe_scaled_font_t *)NULL) -#define mbe_pattern_set_matrix(ptn, mtx) #define mbe_font_face_destroy(face) #define mbe_set_scaled_font(canvas, scaled) #define mbe_pattern_destroy(pattern) @@ -80,6 +79,8 @@ mbe_surface_t *tgt; EGLContext ctx; VGPath path; + + VGfloat mtx[9]; }; struct _ge_openvg_surface { @@ -92,6 +93,7 @@ struct _ge_openvg_pattern { _ge_openvg_img_t *asso_img; + VGfloat mtx[9]; VGPaint paint; }; @@ -129,6 +131,7 @@ extern EGLNativeDisplayType _ge_openvg_disp_id; extern mbe_t *_ge_openvg_current_canvas; +extern void _mbe_load_pattern_mtx(VGfloat *mtx1, VGfloat *mtx2, int mode); extern mbe_pattern_t *mbe_pattern_create_for_surface(mbe_surface_t *surface); extern mbe_pattern_t *mbe_pattern_create_radial(co_aix cx0, co_aix cy0, @@ -142,6 +145,7 @@ grad_stop_t *stops, int stop_cnt); extern mbe_pattern_t *mbe_pattern_create_image(mb_img_data_t *img); +extern void mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx); extern void mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g, co_comp_t b, co_comp_t a); /* TODO: rename n_areas to areas_cnt and make it after areas */ @@ -165,17 +169,17 @@ } while(0) /* TODO: switch VGImage between VGPaint and surface. */ #define _MK_CURRENT_PAINT(canvas) \ - if((canvas)->paint_installed) \ - vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH) + if((canvas)->paint_installed) { \ + vgSetPaint((canvas)->paint, VG_FILL_PATH|VG_STROKE_PATH); \ + } -static void -mbe_transform(mbe_t *canvas, co_aix *mtx) { - VGfloat vg_mtx[9]; - - _MK_CURRENT_CTX(canvas); - MB_MATRIX_2_OPENVG(vg_mtx, mtx); - vgLoadMatrix(vg_mtx); -} +#define mbe_transform(canvas, _mtx) \ + do { \ + MB_MATRIX_2_OPENVG((canvas)->mtx, _mtx); \ + _mbe_load_pattern_mtx(_mtx, NULL, \ + VG_MATRIX_PATH_USER_TO_SURFACE); \ + } while(0) + #define EGL_GLX 1 #ifdef EGL_GLX @@ -217,6 +221,9 @@ mbe_stroke(mbe_t *canvas) { _MK_CURRENT_CTX(canvas); _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_STROKE_PAINT_TO_USER); vgDrawPath(canvas->path, VG_STROKE_PATH); vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL); @@ -226,6 +233,9 @@ mbe_fill(mbe_t *canvas) { _MK_CURRENT_CTX(canvas); _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_FILL_PAINT_TO_USER); vgDrawPath(canvas->path, VG_FILL_PATH); vgClearPath(canvas->path, VG_PATH_CAPABILITY_ALL);
--- a/src/graph_engine_openvg.c Mon Jul 05 14:41:43 2010 +0800 +++ b/src/graph_engine_openvg.c Wed Jul 07 18:44:17 2010 +0800 @@ -13,6 +13,19 @@ (((int)(0xf * b) & 0xf) << 16) | \ ((int)(0xf * a) & 0xf)) +#define MK_ID(mtx) \ + do { \ + (mtx)[0] = 1; \ + (mtx)[1] = 0; \ + (mtx)[2] = 0; \ + (mtx)[3] = 0; \ + (mtx)[4] = 1; \ + (mtx)[5] = 0; \ + (mtx)[6] = 0; \ + (mtx)[7] = 0; \ + (mtx)[8] = 1; \ + } while(0) + /* * This implementation supports only from image surface. */ @@ -20,6 +33,7 @@ mbe_pattern_create_for_surface(mbe_surface_t *surface) { mbe_pattern_t *pattern; _ge_openvg_img_t *ge_img; + VGfloat *mtx; VGPaint paint; /* Support only from image surface */ @@ -35,9 +49,22 @@ pattern->asso_img = ge_img; pattern->paint = paint; + mtx = pattern->mtx; + MK_ID(mtx); + return pattern; } +void +_mbe_load_pattern_mtx(VGfloat *mtx1, VGfloat *mtx2, int mode) { + VGfloat affine; + + vgSeti(VG_MATRIX_MODE, mode); + vgLoadMatrix(mtx1); + if(mtx2) + vgMultMatrix(mtx2); +} + static mbe_pattern_t * _mbe_pattern_create_gradient(VGfloat *gradient, int grad_len, int grad_type, @@ -87,6 +114,8 @@ pattern->paint = paint; pattern->asso_img = NULL; + + MK_ID(pattern->mtx); return pattern; } @@ -172,6 +201,22 @@ } void +mbe_pattern_set_matrix(mbe_pattern_t *ptn, co_aix *mtx) { + co_aix rev[6]; + + compute_reverse(mtx, rev); + ptn->mtx[0] = rev[0]; + ptn->mtx[1] = rev[3]; + ptn->mtx[2] = 0; + ptn->mtx[3] = rev[1]; + ptn->mtx[4] = rev[4]; + ptn->mtx[5] = 0; + ptn->mtx[6] = rev[2]; + ptn->mtx[7] = rev[5]; + ptn->mtx[8] = 1; +} + +void mbe_set_source_rgba(mbe_t *canvas, co_comp_t r, co_comp_t g, co_comp_t b, co_comp_t a) { VGPaint paint; @@ -224,7 +269,7 @@ _openvg_find_config(mb_img_fmt_t fmt, int w, int h, EGLConfig *config) { EGLDisplay display; - EGLint attrib_list[16]; + EGLint attrib_list[32]; EGLConfig configs[1]; EGLint nconfigs; int i = 0; @@ -240,6 +285,8 @@ attrib_list[i++] = 8; attrib_list[i++] = EGL_ALPHA_SIZE; attrib_list[i++] = 8; + attrib_list[i++] = EGL_ALPHA_MASK_SIZE; + attrib_list[i++] = 8; break; case MB_IFMT_RGB24: @@ -249,16 +296,22 @@ attrib_list[i++] = 8; attrib_list[i++] = EGL_BLUE_SIZE; attrib_list[i++] = 8; + attrib_list[i++] = EGL_ALPHA_MASK_SIZE; + attrib_list[i++] = 8; break; case MB_IFMT_A8: attrib_list[i++] = EGL_ALPHA_SIZE; attrib_list[i++] = 8; + attrib_list[i++] = EGL_ALPHA_MASK_SIZE; + attrib_list[i++] = 8; break; case MB_IFMT_A1: attrib_list[i++] = EGL_ALPHA_SIZE; attrib_list[i++] = 1; + attrib_list[i++] = EGL_ALPHA_MASK_SIZE; + attrib_list[i++] = 1; break; case MB_IFMT_RGB16_565: @@ -268,6 +321,8 @@ attrib_list[i++] = 6; attrib_list[i++] = EGL_BLUE_SIZE; attrib_list[i++] = 5; + attrib_list[i++] = EGL_ALPHA_MASK_SIZE; + attrib_list[i++] = 5; break; default: @@ -471,23 +526,33 @@ free(canvas); } -/* - * This implementation support only paint with image paint. OpenVG - * does not support paint path with an alpha value. But, it supports - * to draw image with an alpha value. - */ void mbe_paint_with_alpha(mbe_t *canvas, co_comp_t alpha) { - VGImage vg_img; - _ge_openvg_img_t *ge_img; + EGLDisplay display; + VGHandle mask; + EGLint w, h; + EGLBoolean r; _MK_CURRENT_CTX(canvas); - ASSERT(canvas->src != NULL && canvas->src->asso_img != NULL); - ge_img = canvas->src->asso_img; - vg_img = ge_img->img; + display = _VG_DISPLAY(); + + r = eglQuerySurface(display, canvas->tgt, EGL_WIDTH, &w); + ASSERT(r == EGL_TRUE); + r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); + ASSERT(r == EGL_TRUE); + + /* enable and fill mask layer with alpha value */ + vgSeti(VG_MASKING, VG_TRUE); + mask = vgCreateMaskLayer(w, h); + ASSERT(mask != VG_INVALID_HANDLE); + vgFillMaskLayer(mask, 0, 0, w, h, alpha); + vgMask(mask, VG_SET_MASK, 0, 0, w, h); + vgDestroyMaskLayer(mask); + + mbe_paint(canvas); - vgDrawImage(vg_img); + vgSeti(VG_MASKING, VG_FALSE); } void @@ -499,6 +564,9 @@ _MK_CURRENT_CTX(canvas); _MK_CURRENT_PAINT(canvas); + if(canvas->src) + _mbe_load_pattern_mtx(canvas->src->mtx, NULL, + VG_MATRIX_FILL_PAINT_TO_USER); display = _VG_DISPLAY(); @@ -507,7 +575,10 @@ r = eglQuerySurface(display, canvas->tgt, EGL_HEIGHT, &h); ASSERT(r == EGL_TRUE); + /* disable scissoring and identity transform matrix */ vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); @@ -515,6 +586,8 @@ vgDrawPath(path, VG_FILL_PATH); vgDestroyPath(path); + /* re-enable scissoring and restore transform matrix */ + vgLoadMatrix(canvas->mtx); vgSeti(VG_SCISSORING, VG_TRUE); }