📄 texture_stacks.c
字号:
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_PickSensitiveNode(st->surf, x, y);}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 GradientGetMatrix(GF_Node *transform, GF_Matrix2D *mat){ gf_mx2d_init(*mat); if (transform) { switch (gf_node_get_tag(transform) ) { case TAG_MPEG4_Transform2D: { M_Transform2D *tr = (M_Transform2D *)transform; gf_mx2d_add_scale_at(mat, 0, 0, tr->scale.x, tr->scale.y, tr->scaleOrientation); gf_mx2d_add_rotation(mat, tr->center.x, tr->center.y, tr->rotationAngle); gf_mx2d_add_translation(mat, tr->translation.x, tr->translation.y); } break; case TAG_MPEG4_TransformMatrix2D: TM2D_GetMatrix(transform, mat); break; default: break; } }}typedef struct{ GF_TextureHandler txh;} GradientStack;/* linear gradient*/static void DestroyLinearGradient(GF_Node *node, void *rs, Bool is_destroy){ if (is_destroy) { GradientStack *st = (GradientStack *) gf_node_get_private(node); gf_sr_texture_destroy(&st->txh); free(st); }}static void UpdateLinearGradient(GF_TextureHandler *txh){ u32 i, *cols; Fixed a; Bool const_a; M_LinearGradient *lg = (M_LinearGradient *) txh->owner; GradientStack *st = (GradientStack *) gf_node_get_private(txh->owner); if (!txh->hwtx) txh->hwtx = txh->compositor->r2d->stencil_new(txh->compositor->r2d, GF_STENCIL_LINEAR_GRADIENT); if (!gf_node_dirty_get(txh->owner)) return; gf_node_dirty_clear(txh->owner, 0); txh->needs_refresh = 1; st->txh.transparent = 0; const_a = (lg->opacity.count == 1) ? 1 : 0; cols = (u32*)malloc(sizeof(u32) * lg->key.count); for (i=0; i<lg->key.count; i++) { a = (const_a ? lg->opacity.vals[0] : lg->opacity.vals[i]); cols[i] = GF_COL_ARGB_FIXED(a, lg->keyValue.vals[i].red, lg->keyValue.vals[i].green, lg->keyValue.vals[i].blue); if (a != FIX_ONE) txh->transparent = 1; } txh->compositor->r2d->stencil_set_gradient_interpolation(txh->hwtx, lg->key.vals, cols, lg->key.count); free(cols); txh->compositor->r2d->stencil_set_gradient_mode(txh->hwtx, (GF_GradientMode) lg->spreadMethod);}static void LG_ComputeMatrix(GF_TextureHandler *txh, GF_Rect *bounds, GF_Matrix2D *mat){ SFVec2f start, end; M_LinearGradient *lg = (M_LinearGradient *) txh->owner; if (lg->key.count<2) return; if (lg->key.count != lg->keyValue.count) return; start = lg->startPoint; end = lg->endPoint; /*create gradient brush if needed*/ if (!txh->hwtx) return; GradientGetMatrix((GF_Node *) lg->transform, mat); /*move line to object space*/ start.x = gf_mulfix(start.x, bounds->width); end.x = gf_mulfix(end.x, bounds->width); start.y = gf_mulfix(start.y, bounds->height); end.y = gf_mulfix(end.y, bounds->height); /*move transform to object space*/ mat->m[2] = gf_mulfix(mat->m[2], bounds->width); mat->m[5] = gf_mulfix(mat->m[5], bounds->height); mat->m[1] = gf_muldiv(mat->m[1], bounds->width, bounds->height); mat->m[3] = gf_muldiv(mat->m[3], bounds->height, bounds->width); /*translate to the center of the bounds*/ gf_mx2d_add_translation(mat, bounds->x, bounds->y - bounds->height); txh->compositor->r2d->stencil_set_linear_gradient(txh->hwtx, start.x, start.y, end.x, end.y);}void R2D_InitLinearGradient(Render2D *sr, GF_Node *node){ GradientStack *st; GF_SAFEALLOC(st, GradientStack); gf_sr_texture_setup(&st->txh, sr->compositor, node); st->txh.update_texture_fcnt = UpdateLinearGradient; st->txh.compute_gradient_matrix = LG_ComputeMatrix; gf_node_set_private(node, st); gf_node_set_callback_function(node, DestroyLinearGradient);}GF_TextureHandler *r2d_lg_get_texture(GF_Node *node){ GradientStack *st = (GradientStack*) gf_node_get_private(node); return &st->txh;}/* radial gradient*/static void DestroyRadialGradient(GF_Node *node, void *rs, Bool is_destroy){ if (is_destroy) { GradientStack *st = (GradientStack *) gf_node_get_private(node); gf_sr_texture_destroy(&st->txh); free(st); }}static void UpdateRadialGradient(GF_TextureHandler *txh){ u32 i; M_RadialGradient *rg = (M_RadialGradient*) txh->owner; GradientStack *st = (GradientStack *) gf_node_get_private(txh->owner); if (!txh->hwtx) txh->hwtx = txh->compositor->r2d->stencil_new(txh->compositor->r2d, GF_STENCIL_RADIAL_GRADIENT); if (!gf_node_dirty_get(txh->owner)) return; gf_node_dirty_clear(txh->owner, 0); txh->needs_refresh = 1; st->txh.transparent = 0; for (i=0; i<rg->opacity.count; i++) { if (rg->opacity.vals[i] != FIX_ONE) { st->txh.transparent = 1; break; } }}static void RG_ComputeMatrix(GF_TextureHandler *txh, GF_Rect *bounds, GF_Matrix2D *mat){ SFVec2f center, focal; u32 i, *cols; Fixed a; Bool const_a; M_RadialGradient *rg = (M_RadialGradient *) txh->owner; if (rg->key.count<2) return; if (rg->key.count != rg->keyValue.count) return; /*create gradient brush if needed*/ if (!txh->hwtx) return; GradientGetMatrix((GF_Node *) rg->transform, mat); center = rg->center; focal = rg->focalPoint; /*move circle to object space*/ center.x = gf_mulfix(center.x, bounds->width); center.y = gf_mulfix(center.y, bounds->height); focal.x = gf_mulfix(focal.x, bounds->width); focal.y = gf_mulfix(focal.y, bounds->height); /*move transform to object space*/ mat->m[2] = gf_mulfix(mat->m[2], bounds->width); mat->m[5] = gf_mulfix(mat->m[5], bounds->height); mat->m[1] = gf_muldiv(mat->m[1], bounds->width, bounds->height); mat->m[3] = gf_muldiv(mat->m[3], bounds->height, bounds->width); txh->compositor->r2d->stencil_set_radial_gradient(txh->hwtx, center.x, center.y, focal.x, focal.y, gf_mulfix(rg->radius, bounds->width), gf_mulfix(rg->radius, bounds->height)); const_a = (rg->opacity.count == 1) ? 1 : 0; cols = (u32*)malloc(sizeof(u32) * rg->key.count); for (i=0; i<rg->key.count; i++) { a = (const_a ? rg->opacity.vals[0] : rg->opacity.vals[i]); cols[i] = GF_COL_ARGB_FIXED(a, rg->keyValue.vals[i].red, rg->keyValue.vals[i].green, rg->keyValue.vals[i].blue); } txh->compositor->r2d->stencil_set_gradient_interpolation(txh->hwtx, rg->key.vals, cols, rg->key.count); free(cols); txh->compositor->r2d->stencil_set_gradient_mode(txh->hwtx, (GF_GradientMode) rg->spreadMethod); gf_mx2d_add_translation(mat, bounds->x, bounds->y - bounds->height);}void R2D_InitRadialGradient(Render2D *sr, GF_Node *node){ GradientStack *st; GF_SAFEALLOC(st, GradientStack); gf_sr_texture_setup(&st->txh, sr->compositor, node); st->txh.update_texture_fcnt = UpdateRadialGradient; st->txh.compute_gradient_matrix = RG_ComputeMatrix; gf_node_set_private(node, st); gf_node_set_callback_function(node, DestroyRadialGradient);}GF_TextureHandler *r2d_rg_get_texture(GF_Node *node){ GradientStack *st = (GradientStack*) gf_node_get_private(node); return &st->txh;}void R2D_InitMatteTexture(Render2D *sr, GF_Node *node){}GF_TextureHandler *r2d_matte_get_texture(GF_Node *node){ return NULL;}void R2D_MatteTextureModified(GF_Node *node){}GF_TextureHandler *R2D_GetTextureHandler(GF_Node *n){ if (!n) return NULL; switch (gf_node_get_tag(n)) { case TAG_MPEG4_CompositeTexture2D: return ct2D_get_texture(n); case TAG_MPEG4_MatteTexture: return r2d_matte_get_texture(n); case TAG_MPEG4_LinearGradient: return r2d_lg_get_texture(n); case TAG_MPEG4_RadialGradient: return r2d_rg_get_texture(n); default: return gf_sr_texture_get_handler(n); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -