static void PointSet2D_Draw(GF_Node *node, GF_TraverseState *tr_state) { GF_Path *path; Fixed alpha, w, h; u32 i; SFColor col; DrawableContext *ctx = tr_state->ctx; M_PointSet2D *ps2D = (M_PointSet2D *)node; M_Coordinate2D *coord = (M_Coordinate2D*) ps2D->coord; M_Color *color = (M_Color *) ps2D->color; /*never outline PS2D*/ ctx->flags |= CTX_PATH_STROKE; if (!color || color->color.count<coord->point.count) { /*no texturing*/ visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); return; } get_point_size(&ctx->transform, &w, &h); path = gf_path_new(); alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255; for (i = 0; i < coord->point.count; i++) { col = color->color.vals[i]; ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); gf_path_add_rect_center(path, coord->point.vals[i].x, coord->point.vals[i].y, w, h); visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state); gf_path_reset(path); ctx->flags &= ~CTX_PATH_FILLED; } gf_path_del(path); }
GF_EXPORT GF_Path *gf_path_get_flatten(GF_Path *gp) { GF_Path *ngp; Fixed fineness; u32 i, *countour; GF_Point2D *pt; if (!gp || !gp->n_points) return NULL; if (gp->flags & GF_PATH_FLATTENED) return gf_path_clone(gp); /*avoid too high precision */ fineness = MAX(FIX_ONE - gp->fineness, FIX_ONE / 100); ngp = gf_path_new(); pt = &gp->points[0]; gf_path_add_move_to_vec(ngp, pt); countour = gp->contours; for (i=1; i<gp->n_points; ) { switch (gp->tags[i]) { case GF_PATH_CURVE_ON: case GF_PATH_CLOSE: pt = &gp->points[i]; if (*countour == i-1) { gf_path_add_move_to_vec(ngp, pt); countour++; } else { gf_path_add_line_to_vec(ngp, pt); } if (gp->tags[i]==GF_PATH_CLOSE) gf_path_close(ngp); i++; break; case GF_PATH_CURVE_CONIC: { GF_Point2D *ctl, *end, c1, c2; ctl = &gp->points[i]; end = &gp->points[i+1]; c1.x = pt->x + 2*(ctl->x - pt->x)/3; c1.y = pt->y + 2*(ctl->y - pt->y)/3; c2.x = c1.x + (end->x - pt->x) / 3; c2.y = c1.y + (end->y - pt->y) / 3; gf_subdivide_cubic(ngp, pt->x, pt->y, c1.x, c1.y, c2.x, c2.y, end->x, end->y, fineness); pt = end; if (gp->tags[i+1]==GF_PATH_CLOSE) gf_path_close(ngp); i+=2; } break; case GF_PATH_CURVE_CUBIC: gf_subdivide_cubic(ngp, pt->x, pt->y, gp->points[i].x, gp->points[i].y, gp->points[i+1].x, gp->points[i+1].y, gp->points[i+2].x, gp->points[i+2].y, fineness); pt = &gp->points[i+2]; if (gp->tags[i+2]==GF_PATH_CLOSE) gf_path_close(ngp); i+=3; break; } } if (gp->flags & GF_PATH_FILL_ZERO_NONZERO) ngp->flags |= GF_PATH_FILL_ZERO_NONZERO; ngp->flags |= (GF_PATH_BBOX_DIRTY | GF_PATH_FLATTENED); return ngp; }
void visual_2d_fill_irect(GF_VisualManager *visual, GF_IRect *rc, u32 fill, u32 strike) { GF_Path *path; GF_Path *outline; GF_PenSettings pen; GF_Raster2D *raster = visual->compositor->rasterizer; #ifdef SKIP_DRAW return; #endif if (!rc) return; if (!visual->is_attached) return; if (!fill && !strike ) return; /*no aa*/ visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1); raster->surface_set_matrix(visual->raster_surface, NULL); raster->surface_set_raster_level(visual->raster_surface, GF_RASTER_HIGH_SPEED); raster->surface_set_matrix(visual->raster_surface, NULL); path = gf_path_new(); gf_path_add_move_to(path, INT2FIX(rc->x-1), INT2FIX(rc->y+2-rc->height)); gf_path_add_line_to(path, INT2FIX(rc->x+rc->width-2), INT2FIX(rc->y+2-rc->height)); gf_path_add_line_to(path, INT2FIX(rc->x+rc->width), INT2FIX(rc->y)); gf_path_add_line_to(path, INT2FIX(rc->x), INT2FIX(rc->y)); gf_path_close(path); if (fill) { raster->surface_set_path(visual->raster_surface, path); raster->stencil_set_brush_color(visual->raster_brush, fill); raster->surface_set_clipper(visual->raster_surface, rc); raster->surface_fill(visual->raster_surface, visual->raster_brush); raster->surface_set_path(visual->raster_surface, NULL); } if (strike) { memset(&pen, 0, sizeof(GF_PenSettings)); pen.width = 2; pen.align = GF_PATH_LINE_INSIDE; pen.join = GF_LINE_JOIN_BEVEL; outline = gf_path_get_outline(path, pen); outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO; raster->surface_set_path(visual->raster_surface, outline); raster->stencil_set_brush_color(visual->raster_brush, strike); raster->surface_set_clipper(visual->raster_surface, rc); raster->surface_fill(visual->raster_surface, visual->raster_brush); raster->surface_set_path(visual->raster_surface, NULL); gf_path_del(outline); } gf_path_del(path); }
GF_FontManager *gf_font_manager_new(GF_User *user) { char *def_font = "SERIF"; u32 i, count; GF_FontManager *font_mgr; GF_FontReader *ifce; const char *opt; ifce = NULL; opt = gf_cfg_get_key(user->config, "FontEngine", "FontReader"); if (opt) { ifce = (GF_FontReader *) gf_modules_load_interface_by_name(user->modules, opt, GF_FONT_READER_INTERFACE); if (ifce && ifce->init_font_engine(ifce) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)ifce); ifce = NULL; } } if (!ifce) { count = gf_modules_get_count(user->modules); for (i=0; i<count; i++) { ifce = (GF_FontReader *) gf_modules_load_interface(user->modules, i, GF_FONT_READER_INTERFACE); if (!ifce) continue; if (ifce->init_font_engine(ifce) != GF_OK) { gf_modules_close_interface((GF_BaseInterface *)ifce); ifce = NULL; continue; } gf_cfg_set_key(user->config, "FontEngine", "FontReader", ifce->module_name); break; } } GF_SAFEALLOC(font_mgr, GF_FontManager); font_mgr->reader = ifce; font_mgr->id_buffer_size = 20; font_mgr->id_buffer = gf_malloc(sizeof(u32)*font_mgr->id_buffer_size); gf_font_manager_set_font(font_mgr, &def_font, 1, 0); font_mgr->default_font = font_mgr->font; font_mgr->line_path= gf_path_new(); gf_path_add_move_to(font_mgr->line_path, -FIX_ONE/2, FIX_ONE/2); gf_path_add_line_to(font_mgr->line_path, FIX_ONE/2, FIX_ONE/2); gf_path_add_line_to(font_mgr->line_path, FIX_ONE/2, -FIX_ONE/2); gf_path_add_line_to(font_mgr->line_path, -FIX_ONE/2, -FIX_ONE/2); gf_path_close(font_mgr->line_path); opt = gf_cfg_get_key(user->config, "FontEngine", "WaitForFontLoad"); if (!opt) gf_cfg_set_key(user->config, "FontEngine", "WaitForFontLoad", "no"); if (opt && !strcmp(opt, "yes")) font_mgr->wait_font_load = 1; return font_mgr; }
static FSItem *new_fs_item(FSStack *st, u32 line_col, u32 fill_col, Fixed width) { FSItem *item; GF_SAFEALLOC(item, FSItem); gf_list_add(st->items, item); item->fill_col = fill_col; item->width = width; item->line_col = line_col; item->path = gf_path_new(); return item; }
static void draw_clipper(VisualSurface2D *surf, struct _drawable_context *ctx) { GF_PenSettings clipset; GF_Path *clippath, *cliper; GF_Raster2D *r2d = surf->render->compositor->r2d; if (ctx->flags & CTX_IS_BACKGROUND) return; memset(&clipset, 0, sizeof(GF_PenSettings)); clipset.width = 2*FIX_ONE; clippath = gf_path_new(); gf_path_add_rect_center(clippath, ctx->bi->unclip.x + ctx->bi->unclip.width/2, ctx->bi->unclip.y - ctx->bi->unclip.height/2, ctx->bi->unclip.width, ctx->bi->unclip.height); cliper = gf_path_get_outline(clippath, clipset); gf_path_del(clippath); r2d->surface_set_matrix(surf->the_surface, NULL); r2d->surface_set_clipper(surf->the_surface, NULL); r2d->surface_set_path(surf->the_surface, cliper); r2d->stencil_set_brush_color(surf->the_pen, 0xFF000000); r2d->surface_fill(surf->the_surface, surf->the_pen); gf_path_del(cliper); }
static void draw_clipper(GF_VisualManager *visual, struct _drawable_context *ctx) { GF_PenSettings clipset; GF_Path *clippath, *cliper; GF_Raster2D *raster = visual->compositor->rasterizer; if (ctx->flags & CTX_IS_BACKGROUND) return; memset(&clipset, 0, sizeof(GF_PenSettings)); clipset.width = 2*FIX_ONE; clippath = gf_path_new(); gf_path_add_rect_center(clippath, ctx->bi->unclip.x + ctx->bi->unclip.width/2, ctx->bi->unclip.y - ctx->bi->unclip.height/2, ctx->bi->unclip.width, ctx->bi->unclip.height); cliper = gf_path_get_outline(clippath, clipset); gf_path_del(clippath); raster->surface_set_matrix(visual->raster_surface, NULL); raster->surface_set_clipper(visual->raster_surface, NULL); raster->surface_set_path(visual->raster_surface, cliper); raster->stencil_set_brush_color(visual->raster_brush, 0xFF000000); raster->surface_fill(visual->raster_surface, visual->raster_brush); gf_path_del(cliper); }
void VS2D_FillRect(VisualSurface2D *surf, DrawableContext *ctx, GF_Rect *_rc, u32 color, u32 strike_color) { GF_Path *path; GF_Rect *rc; GF_Raster2D *r2d = surf->render->compositor->r2d; #ifdef SKIP_DRAW return; #endif if (!surf->the_surface) return; if (!color && !strike_color) return; if ((ctx->flags & CTX_PATH_FILLED) && (ctx->flags & CTX_PATH_STROKE) ) { if (surf->render->compositor->draw_bvol) draw_clipper(surf, ctx); return; } /*no aa*/ VS2D_SetOptions(surf->render, surf->the_surface, 0, 1); if (_rc) { rc = _rc; r2d->surface_set_matrix(surf->the_surface, &ctx->transform); } else { rc = &ctx->bi->unclip; r2d->surface_set_matrix(surf->the_surface, NULL); } path = gf_path_new(); gf_path_add_move_to(path, rc->x, rc->y-rc->height); gf_path_add_line_to(path, rc->x+rc->width, rc->y-rc->height); gf_path_add_line_to(path, rc->x+rc->width, rc->y); gf_path_add_line_to(path, rc->x, rc->y); gf_path_close(path); if (color) { /*push path*/ r2d->surface_set_path(surf->the_surface, path); r2d->stencil_set_brush_color(surf->the_brush, color); VS2D_DoFill(surf, ctx, surf->the_brush); r2d->surface_set_path(surf->the_surface, NULL); } if (strike_color) { GF_Path *outline; GF_PenSettings pen; memset(&pen, 0, sizeof(GF_PenSettings)); pen.width = 1; pen.join = GF_LINE_JOIN_BEVEL; pen.dash = GF_DASH_STYLE_DOT; r2d->stencil_set_brush_color(surf->the_brush, strike_color); outline = gf_path_get_outline(path, pen); outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO; r2d->surface_set_path(surf->the_surface, outline); VS2D_DoFill(surf, ctx, surf->the_brush); r2d->surface_set_path(surf->the_surface, NULL); gf_path_del(outline); } gf_path_del(path); }
static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) { GF_Path *path; SFVec2f *pts; SFColor col; Fixed alpha; u32 i, count, col_ind, ind, end_at; u32 linear[2], *colors; SFVec2f start, end; u32 j, num_col; GF_STENCIL grad; GF_Raster2D *raster; DrawableContext *ctx = tr_state->ctx; M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node; M_Coordinate2D *coord = (M_Coordinate2D*) ils2D->coord; M_Color *color = (M_Color *) ils2D->color; end.x = end.y = 0; if (!coord->point.count) return; if (! ils2D->color) { /*no texturing*/ visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); return; } alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255; pts = coord->point.vals; if (!ils2D->colorPerVertex || (color->color.count<2) ) { count = 0; end_at = ils2D->coordIndex.count; if (!end_at) end_at = coord->point.count; ind = ils2D->coordIndex.count ? ils2D->coordIndex.vals[0] : 0; i=1; path = gf_path_new(); gf_path_add_move_to(path, pts[ind].x, pts[ind].y); for (; i<=end_at; i++) { if ((i==end_at) || (ils2D->coordIndex.count && ils2D->coordIndex.vals[i] == -1)) { /*draw current*/ col_ind = (ils2D->colorIndex.count && (ils2D->colorIndex.vals[count]>=0) ) ? (u32) ils2D->colorIndex.vals[count] : count; if (col_ind>=color->color.count) col_ind=color->color.count-1; col = color->color.vals[col_ind]; ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state); i++; if (i>=end_at) break; gf_path_reset(path); ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i; gf_path_add_move_to(path, pts[ind].x, pts[ind].y); if (ils2D->coordIndex.count) count++; continue; } else { ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0) ) ? (u32) ils2D->coordIndex.vals[i] : i; gf_path_add_line_to(path, pts[ind].x, pts[ind].y); } } gf_path_del(path); return; } raster = NULL; end_at = ils2D->coordIndex.count; if (!end_at) end_at = coord->point.count; count = 0; col_ind = 0; ind = 0; i=0; path = gf_path_new(); while (1) { gf_path_reset(path); ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i; start = pts[ind]; num_col = 1; i++; gf_path_add_move_to(path, start.x, start.y); if (ils2D->coordIndex.count) { while (ils2D->coordIndex.vals[i] != -1) { end = pts[ils2D->coordIndex.vals[i]]; gf_path_add_line_to(path, end.x, end.y); i++; num_col++; if (i >= ils2D->coordIndex.count) break; } } else { while (i<end_at) { end = pts[i]; gf_path_add_line_to(path, end.x, end.y); i++; num_col++; } } raster = tr_state->visual->compositor->rasterizer; /*use linear gradient*/ if (num_col==2) { Fixed pos[2]; grad = raster->stencil_new(raster, GF_STENCIL_LINEAR_GRADIENT); if (ils2D->colorIndex.count) { col = color->color.vals[ils2D->colorIndex.vals[col_ind]]; linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); col = color->color.vals[ils2D->colorIndex.vals[col_ind+1]]; linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } else if (ils2D->coordIndex.count) { col = color->color.vals[ils2D->coordIndex.vals[col_ind]]; linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); col = color->color.vals[ils2D->coordIndex.vals[col_ind+1]]; linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } else { col = color->color.vals[col_ind]; linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); col = color->color.vals[col_ind+1]; linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } pos[0] = 0; pos[1] = FIX_ONE; raster->stencil_set_linear_gradient(grad, start.x, start.y, end.x, end.y); raster->stencil_set_gradient_interpolation(grad, pos, linear, 2); } else { grad = raster->stencil_new(raster, GF_STENCIL_VERTEX_GRADIENT); if (grad) { raster->stencil_set_vertex_path(grad, path); colors = (u32*)gf_malloc(sizeof(u32) * num_col); for (j=0; j<num_col; j++) { if (ils2D->colorIndex.count>0) { col = color->color.vals[ils2D->colorIndex.vals[col_ind+j]]; } else if (ils2D->coordIndex.count) { col = color->color.vals[ils2D->coordIndex.vals[col_ind+j]]; } else { col = color->color.vals[col_ind+j]; } colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } raster->stencil_set_vertex_colors(grad, colors, num_col); gf_free(colors); } } raster->stencil_set_matrix(grad, &ctx->transform); visual_2d_draw_path(tr_state->visual, path, ctx, NULL, grad, tr_state); if (grad) raster->stencil_delete(grad); i ++; col_ind += num_col + 1; if (i >= ils2D->coordIndex.count) break; ctx->flags &= ~CTX_PATH_STROKE; } gf_path_del(path); }
void visual_2d_fill_rect(GF_VisualManager *visual, DrawableContext *ctx, GF_Rect *_rc, u32 color, u32 strike_color, GF_TraverseState *tr_state) { GF_Path *path; GF_Rect *rc; GF_Raster2D *raster = visual->compositor->rasterizer; #ifdef SKIP_DRAW return; #endif if (! visual->CheckAttached(visual) ) return; if (!color && !strike_color) return; if ((ctx->flags & CTX_PATH_FILLED) && (ctx->flags & CTX_PATH_STROKE) ) { if (visual->compositor->draw_bvol) draw_clipper(visual, ctx); return; } /*no aa*/ visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1); if (_rc) { rc = _rc; raster->surface_set_matrix(visual->raster_surface, &ctx->transform); } else { rc = &ctx->bi->unclip; raster->surface_set_matrix(visual->raster_surface, NULL); } path = gf_path_new(); gf_path_add_move_to(path, rc->x, rc->y-rc->height); gf_path_add_line_to(path, rc->x+rc->width, rc->y-rc->height); gf_path_add_line_to(path, rc->x+rc->width, rc->y); gf_path_add_line_to(path, rc->x, rc->y); gf_path_close(path); if (color) { /*push path*/ raster->surface_set_path(visual->raster_surface, path); raster->stencil_set_brush_color(visual->raster_brush, color); visual_2d_fill_path(visual, ctx, visual->raster_brush, tr_state, 0); raster->surface_set_path(visual->raster_surface, NULL); } if (strike_color) { GF_Path *outline; GF_PenSettings pen; memset(&pen, 0, sizeof(GF_PenSettings)); pen.width = 1; pen.join = GF_LINE_JOIN_BEVEL; pen.dash = GF_DASH_STYLE_DOT; raster->stencil_set_brush_color(visual->raster_brush, strike_color); outline = gf_path_get_outline(path, pen); outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO; raster->surface_set_path(visual->raster_surface, outline); visual_2d_fill_path(visual, ctx, visual->raster_brush, tr_state, 0); raster->surface_set_path(visual->raster_surface, NULL); gf_path_del(outline); } gf_path_del(path); }
static void IFS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) { u32 i, count, ci_count; u32 j, ind_col, num_col; SFVec2f center, end; SFColor col_cen; GF_STENCIL grad; u32 *colors; GF_Path *path; SFVec2f start; SFVec2f *pts; SFColor col; Fixed alpha; GF_Raster2D *raster; DrawableContext *ctx = tr_state->ctx; M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node; M_Coordinate2D *coord = (M_Coordinate2D*) ifs2D->coord; M_Color *color = (M_Color *) ifs2D->color; col.red = col.green = col.blue = 0; /*simple case, no color specified*/ if (!ifs2D->color) { visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state); visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); return; } /*if default face use first color*/ ci_count = ifs2D->coordIndex.count; pts = coord->point.vals; if (ci_count == 0) { col = (ifs2D->colorIndex.count > 0) ? color->color.vals[ifs2D->colorIndex.vals[0]] : color->color.vals[0]; alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color)) / 255; if (!alpha || !ctx->aspect.pen_props.width) { alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255; ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } else { ctx->aspect.fill_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state); visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); return; } /*we have color per faces so we need N path :(*/ if (! ifs2D->colorPerVertex) { path = gf_path_new(); count = 0; i = 0; while (1) { gf_path_reset(path); start = pts[ifs2D->coordIndex.vals[i]]; gf_path_add_move_to(path, start.x, start.y); i++; while (ifs2D->coordIndex.vals[i] != -1) { start = pts[ifs2D->coordIndex.vals[i]]; gf_path_add_line_to(path, start.x, start.y); i++; if (i >= ci_count) break; } /*close in ALL cases because even if the start/end points are the same the line join needs to be present*/ gf_path_close(path); col = (ifs2D->colorIndex.count > 0) ? color->color.vals[ifs2D->colorIndex.vals[count]] : color->color.vals[count]; alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color)) / 255; if (!alpha) { alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255; ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } else { ctx->aspect.fill_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } visual_2d_texture_path(tr_state->visual, path, ctx, tr_state); visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state); count++; i++; if (i >= ci_count) break; ctx->flags &= ~CTX_PATH_FILLED; ctx->flags &= ~CTX_PATH_STROKE; } gf_path_del(path); return; } /*final case, color per vertex means gradient fill/strike*/ raster = tr_state->visual->compositor->rasterizer; grad = raster->stencil_new(raster, GF_STENCIL_VERTEX_GRADIENT); /*not supported, fill default*/ if (!grad) { visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state); visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); return; } path = gf_path_new(); ind_col = 0; i = 0; while (1) { gf_path_reset(path); start = pts[ifs2D->coordIndex.vals[i]]; center = start; gf_path_add_move_to(path, start.x, start.y); num_col = 1; i+=1; while (ifs2D->coordIndex.vals[i] != -1) { end = pts[ifs2D->coordIndex.vals[i]]; gf_path_add_line_to(path, end.x, end.y); i++; center.x += end.x; center.y += end.y; num_col ++; if (i >= ci_count) break; } gf_path_close(path); num_col++; alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color) ) / 255; colors = (u32*)gf_malloc(sizeof(u32) * num_col); col_cen.blue = col_cen.red = col_cen.green = 0; for (j=0; j<num_col-1; j++) { if (ifs2D->colorIndex.count > ind_col + j) { col = color->color.vals[ifs2D->colorIndex.vals[ind_col + j]]; } else if (ci_count > ind_col + j) { col = color->color.vals[ifs2D->coordIndex.vals[ind_col + j]]; } colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); col_cen.blue += col.blue; col_cen.green += col.green; col_cen.red += col.red; } colors[num_col-1] = colors[0]; if (ifs2D->colorIndex.count > ind_col) { col = color->color.vals[ifs2D->colorIndex.vals[ind_col]]; } else if (ci_count > ind_col) { col = color->color.vals[ifs2D->coordIndex.vals[ind_col]]; } col_cen.blue += col.blue; col_cen.green += col.green; col_cen.red += col.red; raster->stencil_set_vertex_path(grad, path); raster->stencil_set_vertex_colors(grad, colors, num_col); gf_free(colors); col_cen.blue /= num_col; col_cen.green /= num_col; col_cen.red /= num_col; center.x /= num_col; center.y /= num_col; raster->stencil_set_vertex_center(grad, center.x, center.y, GF_COL_ARGB_FIXED(alpha, col_cen.red, col_cen.green, col_cen.blue) ); raster->stencil_set_matrix(grad, &ctx->transform); /*draw*/ visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, grad, grad, tr_state); raster->stencil_delete(grad); //goto next point i++; ind_col += num_col + 1; if (i >= ci_count) break; grad = raster->stencil_new(raster, GF_STENCIL_VERTEX_GRADIENT); ctx->flags &= ~CTX_PATH_FILLED; ctx->flags &= ~CTX_PATH_STROKE; } gf_path_del(path); }