void drawable_finalize_render(struct _drawable_context *ctx, RenderEffect2D *eff) { Float sx, sy, pw; ctx->unclip = ctx->original; mx2d_apply_rect(&eff->transform, &ctx->unclip); /*apply pen width*/ if (ctx->aspect.has_line && ctx->aspect.pen_props.width && (ctx->aspect.pen_props.align==M4LineCentered) ) { StrikeInfo2D *si = NULL; /*if pen is scalable, the width is scaled by max(scale_x, scale_y) of the current transorm otherwise apply user/viewport transform so that original aspect is kept*/ if (ctx->aspect.pen_props.is_scalable) { sx = eff->transform.m[0]; sy = eff->transform.m[4]; } else { sx = eff->surface->top_transform.m[0]; sy = eff->surface->top_transform.m[4]; } if (sx<0) sx *= -1; if (sy<0) sy *= -1; if (sy>sx) sx = sy; ctx->aspect.line_scale = sx; /*get strike info & outline for exact bounds compute. If failure use default offset*/ si = drawctx_get_strikeinfo(ctx, ctx->node->path); if (si && si->outline) { m4_path_get_bounds(si->outline, &ctx->unclip); mx2d_apply_rect(&eff->transform, &ctx->unclip); } else { pw = ctx->aspect.pen_props.width; pw *= sx; ctx->unclip.x -= pw; ctx->unclip.y += pw; ctx->unclip.width += 2*pw; ctx->unclip.height += 2*pw; } } if (!ctx->no_antialias) { /*grow of 2 pixels (-1 and +1) to handle AA*/ pw = (eff->is_pixel_metrics) ? 1 : (2.0f/eff->surface->width); ctx->unclip.x -= pw; ctx->unclip.y += pw; ctx->unclip.width += 2*pw; ctx->unclip.height += 2*pw; } ctx->clip = m4_rect_pixelize(&ctx->unclip); ctx->unclip_pix = ctx->clip; if (eff->parent) { group2d_add_to_context_list(eff->parent, ctx); } else if (eff->trav_flags & TF_RENDER_DIRECT) { ctx->node->Draw(ctx); } }
/*default point_over routine*/ static Bool drawable_point_over(DrawableContext *ctx, Float x, Float y, Bool check_outline) { M4Matrix2D inv; StrikeInfo2D *si; if (!ctx || !ctx->node->path) return 0; assert(ctx->surface); mx2d_copy(inv, ctx->transform); mx2d_inverse(&inv); mx2d_apply_coords(&inv, &x, &y); if (m4_path_point_over(ctx->node->path, x, y)) return 1; if (!check_outline) return 0; si = drawctx_get_strikeinfo(ctx, NULL); if (si && si->outline && m4_path_point_over(si->outline, x, y)) return 1; return 0; }
void VS2D_DrawPath(VisualSurface2D *surf, GF_Path *path, DrawableContext *ctx, GF_STENCIL brush, GF_STENCIL pen) { Bool dofill, dostrike; GF_Raster2D *r2d = surf->render->compositor->r2d; #ifdef SKIP_DRAW return; #endif assert(surf->the_surface); if ((ctx->flags & CTX_PATH_FILLED) && (ctx->flags & CTX_PATH_STROKE) ) { if (surf->render->compositor->draw_bvol) draw_clipper(surf, ctx); return; } if (! (ctx->flags & CTX_IS_BACKGROUND) ) VS2D_SetOptions(surf->render, surf->the_surface, ctx->flags & CTX_IS_TEXT, 0); dofill = dostrike = 0; if (!(ctx->flags & CTX_PATH_FILLED) && GF_COL_A(ctx->aspect.fill_color) ) { dofill = 1; if (!brush) { brush = surf->the_brush; r2d->stencil_set_brush_color(brush, ctx->aspect.fill_color); } } /*compute width based on transform and top_level transform*/ if (!(ctx->flags & CTX_PATH_STROKE) && ctx->aspect.pen_props.width) { dostrike = 1; if (!pen) { pen = surf->the_pen; r2d->stencil_set_brush_color(pen, ctx->aspect.line_color); } } else if (!dofill) { return; } /*set path transform, except for background2D node which is directly build in the final coord system*/ r2d->surface_set_matrix(surf->the_surface, (ctx->flags & CTX_IS_BACKGROUND) ? NULL : &ctx->transform); /*fill path*/ if (dofill) { #if ADAPTATION_SIZE if ((ctx->bi->clip.width<ADAPTATION_SIZE) && (ctx->bi->clip.height<ADAPTATION_SIZE)) { r2d->surface_clear(surf->the_surface, &ctx->bi->clip, ctx->aspect.fill_color); } else #endif { /*push path*/ r2d->surface_set_path(surf->the_surface, path); VS2D_DoFill(surf, ctx, brush); r2d->surface_set_path(surf->the_surface, NULL); } } if (dostrike) { #if ADAPTATION_SIZE if ((ctx->bi->clip.width<ADAPTATION_SIZE) && (ctx->bi->clip.height<ADAPTATION_SIZE)) { } else #endif { StrikeInfo2D *si = drawctx_get_strikeinfo(surf->render, ctx, path); if (si && si->outline) { if (ctx->aspect.line_texture) { VS2D_TexturePathIntern(surf, si->outline, ctx->aspect.line_texture, ctx); } else { r2d->surface_set_path(surf->the_surface, si->outline); VS2D_DoFill(surf, ctx, pen); } /*that's ugly, but we cannot cache path outline for IFS2D/ILS2D*/ if (path && !(ctx->flags & CTX_IS_TEXT) && (path!=ctx->drawable->path) ) { gf_path_del(si->outline); si->outline = NULL; } } } } if (surf->render->compositor->draw_bvol) draw_clipper(surf, ctx); }