GF_Node *CT2D_PickNode(GF_TextureHandler *txh, DrawableContext *ctx, Fixed x, Fixed y) { GF_Rect orig; GF_Matrix2D mat, tx_trans; Fixed width, height; Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner); assert(st->surf); orig = ctx->bi->unclip; gf_mx2d_copy(mat, ctx->transform); gf_mx2d_inverse(&mat); gf_mx2d_apply_rect(&mat, &orig); gf_mx2d_init(mat); gf_mx2d_add_scale(&mat, orig.width / st->width, orig.height / st->height); get_gf_sr_texture_transform(ctx->appear, &st->txh, &tx_trans, (ctx->h_texture==&st->txh) ? 0 : 1, INT2FIX(orig.width), INT2FIX(orig.height)); gf_mx2d_add_matrix(&mat, &tx_trans); gf_mx2d_add_translation(&mat, (orig.x), (orig.y - orig.height)); gf_mx2d_add_matrix(&mat, &ctx->transform); gf_mx2d_inverse(&mat); gf_mx2d_apply_coords(&mat, &x, &y); width = INT2FIX(st->width); height = INT2FIX(st->height); while (x>width) x -= width; while (x < 0) x += width; while (y>height) y -= height; while (y < 0) y += height; x -= width / 2; y -= height / 2; return VS2D_PickNode(st->surf, x, y); }
static void VS2D_DrawGradient(VisualSurface2D *surf, GF_Path *path, GF_TextureHandler *txh, struct _drawable_context *ctx) { GF_Rect rc; GF_Matrix2D g_mat, txt_mat; GF_Raster2D *r2d = surf->render->compositor->r2d; if (!txh) txh = ctx->h_texture; gf_path_get_bounds(path, &rc); if (!rc.width || !rc.height || !txh->hwtx) return; txh->compute_gradient_matrix(txh, &rc, &g_mat); if (ctx->flags & CTX_HAS_APPEARANCE) { get_gf_sr_texture_transform(ctx->appear, txh, &txt_mat, (txh == ctx->h_texture) ? 0 : 1, INT2FIX(txh->width), INT2FIX(txh->height)); gf_mx2d_add_matrix(&g_mat, &txt_mat); } gf_mx2d_add_matrix(&g_mat, &ctx->transform); r2d->stencil_set_matrix(txh->hwtx, &g_mat); r2d->stencil_set_color_matrix(txh->hwtx, ctx->col_mat); r2d->surface_set_matrix(surf->the_surface, &ctx->transform); r2d->surface_set_path(surf->the_surface, path); VS2D_DoFill(surf, ctx, txh->hwtx); r2d->surface_set_path(surf->the_surface, NULL); ctx->flags |= CTX_PATH_FILLED; }
void VS2D_TexturePathIntern(VisualSurface2D *surf, GF_Path *path, GF_TextureHandler *txh, struct _drawable_context *ctx) { Fixed sS, sT; u32 tx_tile; GF_Matrix2D gf_mx2d_txt, gf_sr_texture_transform; GF_Rect rc, orig_rc; GF_Raster2D *r2d = surf->render->compositor->r2d; if (!txh) txh = ctx->h_texture; if (!txh || !txh->hwtx) return; /*this is gradient draw*/ if (txh->compute_gradient_matrix) { VS2D_DrawGradient(surf, path, txh, ctx); return; } /*setup quality even for background (since quality concerns images)*/ VS2D_SetOptions(surf->render, surf->the_surface, ctx->flags & CTX_IS_TEXT, ctx->flags & CTX_NO_ANTIALIAS); /*get original bounds*/ gf_path_get_bounds(path, &orig_rc); /*get active texture window in pixels*/ rc.width = INT2FIX(txh->width); rc.height = INT2FIX(txh->height); /*get scaling ratio so that active texture view is stretched to original bounds (std 2D shape texture mapping in MPEG4)*/ sS = orig_rc.width / txh->width; sT = orig_rc.height / txh->height; gf_mx2d_init(gf_mx2d_txt); gf_mx2d_add_scale(&gf_mx2d_txt, sS, sT); /*apply texture transform*/ get_gf_sr_texture_transform(ctx->appear, txh, &gf_sr_texture_transform, (txh == ctx->h_texture) ? 0 : 1, txh->width * sS, txh->height * sT); gf_mx2d_add_matrix(&gf_mx2d_txt, &gf_sr_texture_transform); /*move to bottom-left corner of bounds */ gf_mx2d_add_translation(&gf_mx2d_txt, (orig_rc.x), (orig_rc.y - orig_rc.height)); /*move to final coordinate system (except background which is built directly in final coord system)*/ if (!(ctx->flags & CTX_IS_BACKGROUND) ) gf_mx2d_add_matrix(&gf_mx2d_txt, &ctx->transform); /*set path transform, except for background2D node which is directly build in the final coord system*/ r2d->stencil_set_matrix(txh->hwtx, &gf_mx2d_txt); tx_tile = 0; if (txh->flags & GF_SR_TEXTURE_REPEAT_S) tx_tile |= GF_TEXTURE_REPEAT_S; if (txh->flags & GF_SR_TEXTURE_REPEAT_T) tx_tile |= GF_TEXTURE_REPEAT_T; r2d->stencil_set_tiling(txh->hwtx, (GF_TextureTiling) tx_tile); if (!(ctx->flags & CTX_IS_BACKGROUND) ) { u8 a = GF_COL_A(ctx->aspect.fill_color); if (!a) a = GF_COL_A(ctx->aspect.line_color); /*texture alpha scale is the original material transparency, NOT the one after color transform*/ r2d->stencil_set_texture_alpha(txh->hwtx, a ); r2d->stencil_set_color_matrix(txh->hwtx, ctx->col_mat); r2d->surface_set_matrix(surf->the_surface, &ctx->transform); } else { r2d->surface_set_matrix(surf->the_surface, NULL); } /*push path & draw*/ r2d->surface_set_path(surf->the_surface, path); VS2D_DoFill(surf, ctx, txh->hwtx); r2d->surface_set_path(surf->the_surface, NULL); ctx->flags |= CTX_PATH_FILLED; }