📄 grouping_stacks.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / 2D rendering module * * GPAC is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * GPAC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */#include "stacks2d.h"#include "visualsurface2d.h"/*for anchor processing, which needs to be filtered at the inline scene level*/#include <gpac/internal/terminal_dev.h>typedef struct{ s32 last_switch;} SwitchStack;static void RenderSwitch(GF_Node *node, void *rs, Bool is_destroy){ GF_ChildNodeItem *l; u32 i, count; Bool prev_switch; GF_ChildNodeItem *children; s32 whichChoice; GF_Node *child; SwitchStack *st = (SwitchStack *)gf_node_get_private(node); RenderEffect2D *eff; eff = (RenderEffect2D *)rs; if (is_destroy) { free(st); return; } if (gf_node_get_name(node)) { node = node; } /*WARNING: X3D/MPEG4 NOT COMPATIBLE*/ if (gf_node_get_tag(node)==TAG_MPEG4_Switch) { children = ((M_Switch *)node)->choice; whichChoice = ((M_Switch *)node)->whichChoice; } else { children = ((X_Switch *)node)->children; whichChoice = ((X_Switch *)node)->whichChoice; } count = gf_node_list_get_count(children); prev_switch = eff->trav_flags; /*check changes in choice field*/ if ((gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) || (st->last_switch != whichChoice) ) { eff->trav_flags |= GF_SR_TRAV_SWITCHED_OFF; i=0; l = children; while (l) {// if ((s32) i!=whichChoice) gf_node_render(l->node, eff); if ((s32) i == st->last_switch) gf_node_render(l->node, eff); l = l->next; i++; } eff->trav_flags &= ~GF_SR_TRAV_SWITCHED_OFF; st->last_switch = whichChoice; } gf_node_dirty_clear(node, 0); /*no need to check for sensors since a sensor is active for the whole parent group, that is for switch itself CSQ: switch cannot be used to switch sensors, too bad...*/ eff->trav_flags = prev_switch; if (whichChoice>=0) { child = (GF_Node*)gf_node_list_get_child(children, whichChoice); gf_node_render(child, eff); }}void R2D_InitSwitch(Render2D *sr, GF_Node *node){ SwitchStack *st = (SwitchStack *)malloc(sizeof(SwitchStack)); st->last_switch = -1; gf_node_set_private(node, st); gf_node_set_callback_function(node, RenderSwitch);}/*transform2D*/static void RenderTransform2D(GF_Node *node, void *rs, Bool is_destroy){ GF_Matrix2D bckup; M_Transform2D *tr = (M_Transform2D *)node; Transform2DStack *ptr = (Transform2DStack *)gf_node_get_private(node); RenderEffect2D *eff; if (is_destroy) { DeleteGroupingNode2D((GroupingNode2D *)ptr); free(ptr); return; } eff = (RenderEffect2D *) rs; if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { gf_mx2d_init(ptr->mat); ptr->is_identity = 1; if ((tr->scale.x != FIX_ONE) || (tr->scale.y != FIX_ONE)) { gf_mx2d_add_scale_at(&ptr->mat, tr->scale.x, tr->scale.y, 0, 0, tr->scaleOrientation); ptr->is_identity = 0; } if (tr->rotationAngle) { gf_mx2d_add_rotation(&ptr->mat, tr->center.x, tr->center.y, tr->rotationAngle); ptr->is_identity = 0; } if (tr->translation.x || tr->translation.y) { ptr->is_identity = 0; gf_mx2d_add_translation(&ptr->mat, tr->translation.x, tr->translation.y); } } /*note we don't clear dirty flag, this is done in traversing*/ if (ptr->is_identity) { group2d_traverse((GroupingNode2D *)ptr, tr->children, eff); } else { gf_mx2d_copy(bckup, eff->transform); gf_mx2d_copy(eff->transform, ptr->mat); gf_mx2d_add_matrix(&eff->transform, &bckup); group2d_traverse((GroupingNode2D *)ptr, tr->children, eff); gf_mx2d_copy(eff->transform, bckup); }}void R2D_InitTransform2D(Render2D *sr, GF_Node *node){ Transform2DStack *stack = (Transform2DStack *)malloc(sizeof(Transform2DStack)); SetupGroupingNode2D((GroupingNode2D *)stack, sr, node); gf_mx2d_init(stack->mat); stack->is_identity = 1; gf_node_set_private(node, stack); gf_node_set_callback_function(node, RenderTransform2D);}void TM2D_GetMatrix(GF_Node *n, GF_Matrix2D *mat){ M_TransformMatrix2D *tr = (M_TransformMatrix2D*)n; gf_mx2d_init(*mat); mat->m[0] = tr->mxx; mat->m[1] = tr->mxy; mat->m[2] = tr->tx; mat->m[3] = tr->myx; mat->m[4] = tr->myy; mat->m[5] = tr->ty;}/*TransformMatrix2D*/static void RenderTransformMatrix2D(GF_Node *node, void *rs, Bool is_destroy){ GF_Matrix2D bckup; M_TransformMatrix2D *tr = (M_TransformMatrix2D*)node; Transform2DStack *ptr = (Transform2DStack *) gf_node_get_private(node); RenderEffect2D *eff = (RenderEffect2D *)rs; if (is_destroy) { DeleteGroupingNode2D((GroupingNode2D *)ptr); free(ptr); return; } if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { TM2D_GetMatrix(node, &ptr->mat); if ((tr->mxx==FIX_ONE) && (tr->mxy==0) && (tr->tx==0) && (tr->myx==0) && (tr->myy==FIX_ONE) && (tr->ty==0) ) ptr->is_identity = 1; else ptr->is_identity = 0; } /*note we don't clear dirty flag, this is done in traversing*/ if (ptr->is_identity) { group2d_traverse((GroupingNode2D *)ptr, tr->children, eff); } else { gf_mx2d_copy(bckup, eff->transform); gf_mx2d_copy(eff->transform, ptr->mat); gf_mx2d_add_matrix(&eff->transform, &bckup); group2d_traverse((GroupingNode2D *)ptr, tr->children, eff); gf_mx2d_copy(eff->transform, bckup); }}void R2D_InitTransformMatrix2D(Render2D *sr, GF_Node *node){ Transform2DStack *stack = (Transform2DStack *)malloc(sizeof(Transform2DStack)); SetupGroupingNode2D((GroupingNode2D *)stack, sr, node); gf_mx2d_init(stack->mat); gf_node_set_private(node, stack); gf_node_set_callback_function(node, RenderTransformMatrix2D);}typedef struct{ GF_Node *owner; GF_Renderer *compositor; GROUPINGNODESTACK2D GF_ColorMatrix cmat;} ColorTransformStack;/*ColorTransform*/static void RenderColorTransform(GF_Node *node, void *rs, Bool is_destroy){ Bool c_changed; M_ColorTransform *tr = (M_ColorTransform *)node; ColorTransformStack *ptr = (ColorTransformStack *)gf_node_get_private(node); RenderEffect2D *eff; eff = (RenderEffect2D *) rs; if (is_destroy) { DeleteGroupingNode2D((GroupingNode2D *)ptr); free(ptr); return; } c_changed = 0; if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { gf_cmx_set(&ptr->cmat, tr->mrr , tr->mrg, tr->mrb, tr->mra, tr->tr, tr->mgr , tr->mgg, tr->mgb, tr->mga, tr->tg, tr->mbr, tr->mbg, tr->mbb, tr->mba, tr->tb, tr->mar, tr->mag, tr->mab, tr->maa, tr->ta); c_changed = 1; } /*note we don't clear dirty flag, this is done in traversing*/ if (ptr->cmat.identity) { group2d_traverse((GroupingNode2D *) ptr, tr->children, eff); } else { GF_ColorMatrix gf_cmx_bck; Bool prev_inv = eff->invalidate_all; /*if modified redraw all nodes*/ if (c_changed) eff->invalidate_all = 1; gf_cmx_copy(&gf_cmx_bck, &eff->color_mat); gf_cmx_multiply(&eff->color_mat, &ptr->cmat); group2d_traverse((GroupingNode2D *) ptr, tr->children, eff); /*restore effects*/ gf_cmx_copy(&eff->color_mat, &gf_cmx_bck); eff->invalidate_all = prev_inv; }}void R2D_InitColorTransform(Render2D *sr, GF_Node *node){ ColorTransformStack *stack = (ColorTransformStack *)malloc(sizeof(ColorTransformStack)); SetupGroupingNode2D((GroupingNode2D *)stack, sr, node); gf_cmx_init(&stack->cmat); gf_node_set_private(node, stack); gf_node_set_callback_function(node, RenderColorTransform);}static void RenderGroup(GF_Node *node, void *rs, Bool is_destroy){ GroupingNode2D *group = (GroupingNode2D *) gf_node_get_private(node); if (is_destroy) { DeleteGroupingNode2D(group); free(group); return; } group2d_traverse(group, ((M_Group *)node)->children, (RenderEffect2D*)rs);}void R2D_InitGroup(Render2D *sr, GF_Node *node){ GroupingNode2D *stack = (GroupingNode2D *)malloc(sizeof(GroupingNode2D)); SetupGroupingNode2D(stack, sr, node); gf_node_set_private(node, stack); gf_node_set_callback_function(node, RenderGroup);}typedef struct{ GF_Node *owner; GF_Renderer *compositor; GROUPINGNODESTACK2D Bool enabled, is_over; SensorHandler hdl;} AnchorStack;static void RenderAnchor(GF_Node *node, void *rs, Bool is_destroy){ AnchorStack *st = (AnchorStack *) gf_node_get_private(node); M_Anchor *an = (M_Anchor *) node; RenderEffect2D *eff = (RenderEffect2D *)rs; if (is_destroy) { R2D_UnregisterSensor(st->compositor, &st->hdl); if (st->compositor->interaction_sensors) st->compositor->interaction_sensors--; DeleteGroupingNode2D((GroupingNode2D *)st); free(st); return; } /*update enabled state*/ if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { st->enabled = 0; if (an->url.count && an->url.vals[0].url && strlen(an->url.vals[0].url) ) st->enabled = 1; } /*note we don't clear dirty flag, this is done in traversing*/ group2d_traverse((GroupingNode2D*)st, an->children, eff);}static Bool anchor_is_enabled(SensorHandler *sh){ AnchorStack *st = (AnchorStack *) gf_node_get_private(sh->owner); return st->enabled;}static Bool OnAnchor(SensorHandler *sh, GF_Event *evt, DrawableContext *ctx, GF_Matrix2D *sensor_matrix){ u32 i; GF_Event event; AnchorStack *st = (AnchorStack *) gf_node_get_private(sh->owner); M_Anchor *an = (M_Anchor *) sh->owner; if (ctx==NULL) { event.type = GF_EVENT_NAVIGATE_INFO; event.navigate.to_url = ""; st->compositor->user->EventProc(st->compositor->user->opaque, &event); st->is_over = 0; return 0; } if (evt->type == GF_EVENT_MOUSEMOVE) { if (!st->is_over && st->compositor->user->EventProc) { event.type = GF_EVENT_NAVIGATE_INFO; event.navigate.to_url = an->description.buffer; if (!event.navigate.to_url || !strlen(event.navigate.to_url)) event.navigate.to_url = an->url.vals[0].url; st->compositor->user->EventProc(st->compositor->user->opaque, &event); } st->is_over = 1; return 0; } if ((evt->type != GF_EVENT_MOUSEUP) || (evt->mouse.button != GF_MOUSE_LEFT)) return 0; event.type = GF_EVENT_NAVIGATE; event.navigate.param_count = an->parameter.count; event.navigate.parameters = (const char **) an->parameter.vals;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -