Beispiel #1
0
static void TraverseStyleGroup(GF_Node *node, void *rs, Bool is_destroy)
{
	Bool set = 0;
	StyleGroupStack *stack = (StyleGroupStack *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *) rs;

	if (is_destroy) {
		gf_free(stack);
		return;
	}

	if (tr_state->traversing_mode==TRAVERSE_SORT) {
		if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {

			gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
			/*flag is not set for PROTO*/
			gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0);
		}
	}
	StyleGroup_GetNode(node, &stack->sg);

	if (!tr_state->override_appearance) {
		set = 1;
		tr_state->override_appearance = stack->sg.appearance;
	}
	group_2d_traverse((GF_Node *)&stack->sg, (GroupingNode2D*)stack, tr_state);

	if (set) {
		tr_state->override_appearance = NULL;
	}
}
Beispiel #2
0
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);

}
Beispiel #3
0
void drawable_3d_base_traverse(GF_Node *n, void *rs, Bool is_destroy, void (*build_shape)(GF_Node*,Drawable3D *,GF_TraverseState *) )
{
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	Drawable3D *stack = (Drawable3D*)gf_node_get_private(n);

	if (is_destroy) {
		drawable_3d_del(n);
		return;
	}
	if (gf_node_dirty_get(n)) {
		mesh_reset(stack->mesh);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Rebuilding mesh %s\n", gf_node_get_class_name(n)));
		build_shape(n, stack, tr_state);
		gf_node_dirty_clear(n, 0);
	}
	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_3D:
		visual_3d_draw(tr_state, stack->mesh);
		drawable3d_check_focus_highlight(n, tr_state, &stack->mesh->bounds);
		break;
	case TRAVERSE_GET_BOUNDS:
		tr_state->bbox = stack->mesh->bounds;
		break;
	case TRAVERSE_PICK:
		visual_3d_vrml_drawable_pick(n, tr_state, stack->mesh, NULL);
		return;
	}
}
Beispiel #4
0
/*TransformMatrix2D*/
static void TraverseTransformMatrix2D(GF_Node *node, void *rs, Bool is_destroy)
{
	Transform2DStack *ptr = (Transform2DStack *) gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		gf_sc_check_focus_upon_destroy(node);
		group_2d_destroy(node, (GroupingNode2D*)ptr);
		gf_free(ptr);
		return;
	}

	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {
		M_TransformMatrix2D *tr = (M_TransformMatrix2D*)node;
		tr_mx2d_get_matrix(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;

		ptr->is_null = ( (!ptr->mat.m[0] && !ptr->mat.m[1]) || (!ptr->mat.m[3] && !ptr->mat.m[4]) ) ? 1 : 0;
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
	}
	traverse_transform(node, ptr, tr_state);
}
Beispiel #5
0
static void svg_animation_smil_update(GF_Node *node, SVGlinkStack *stack, Fixed normalized_scene_time)
{
	if (stack->init_vis_state == 3) {
		stack->init_vis_state = 4;
		gf_mo_resume(stack->resource);
	} else if (stack->needs_play || (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY )) {
		SVGAllAttributes all_atts;
		Double clipBegin, clipEnd;
		GF_MediaObject *new_res;
		gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
		clipBegin = all_atts.clipBegin ? *all_atts.clipBegin : 0;
		clipEnd = all_atts.clipEnd ? *all_atts.clipEnd : -1;

		if (stack->needs_play) {
			gf_mo_play(stack->resource, clipBegin, clipEnd, 0);
			stack->needs_play = 0;
		} else {            
            Bool primary = all_atts.gpac_useAsPrimary ? *all_atts.gpac_useAsPrimary : 1;
            new_res = gf_mo_load_xlink_resource(node, primary, clipBegin, clipEnd);
			if (new_res != stack->resource) {
				if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
				if (all_atts.xlink_href) all_atts.xlink_href->target = NULL;
				stack->resource = new_res;
				stack->fragment_id = NULL;
				stack->inline_sg = NULL;
			}
			gf_node_dirty_clear(node, 0);
		}
	}
}
Beispiel #6
0
static void build_indexed_triangle_fan_set(GF_Node *node, Drawable3D *stack, GF_TraverseState *tr_state)
{
	MFInt32 fanList;
	u32 i, nb_fans;
	X_IndexedTriangleFanSet *itfs = (X_IndexedTriangleFanSet *)node;
	gf_node_dirty_clear(node, 0);
	if (!itfs->coord) return;

	fanList.count = 0;
	fanList.vals = NULL;
	nb_fans = 0;
	for (i=0; i<itfs->index.count; i++) {
		if (itfs->index.vals[i]==-1) {
			if (nb_fans>=3) {
				u32 *out_nb;
				gf_sg_vrml_mf_append(&fanList, GF_SG_VRML_MFINT32, (void **) &out_nb);
				*out_nb = nb_fans;
			}
			nb_fans = 0;
		} else {
			nb_fans++;
		}
	}
	if (nb_fans>=3) {
		u32 *out_nb;
		gf_sg_vrml_mf_append(&fanList, GF_SG_VRML_MFINT32, (void **) &out_nb);
		*out_nb = nb_fans;
	}
	BuildTriangleFanSet(stack->mesh, itfs->coord, itfs->color, itfs->texCoord, itfs->normal, &fanList, &itfs->index, itfs->normalPerVertex, itfs->ccw, itfs->solid);
	gf_sg_vrml_mf_reset(&fanList, GF_SG_VRML_MFINT32);
}
Beispiel #7
0
void compositor_extrude_text(GF_Node *node, GF_TraverseState *tr_state, GF_Mesh *mesh, MFVec3f *thespine, Fixed creaseAngle, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool txAlongSpine)
{
	u32 i, count;
	Fixed min_cx, min_cy, width_cx, width_cy;
	TextStack *st = (TextStack *) gf_node_get_private(node);

	/*rebuild text node*/
	if (gf_node_dirty_get(node)) {
		ParentNode2D *parent = tr_state->parent;
		tr_state->parent = NULL;
		text_clean_paths(tr_state->visual->compositor, st);
		drawable_reset_path(st->graph);
		gf_node_dirty_clear(node, 0);
		build_text(st, (M_Text *)node, tr_state);
		tr_state->parent = parent;
	}

	min_cx = st->bounds.x;
	min_cy = st->bounds.y - st->bounds.height;
	width_cx = st->bounds.width;
	width_cy = st->bounds.height;

	mesh_reset(mesh);
	count = gf_list_count(st->spans);
	for (i=0; i<count; i++) {
		GF_TextSpan *span = (GF_TextSpan *)gf_list_get(st->spans, i);
		GF_Path *span_path = gf_font_span_create_path(span);
		mesh_extrude_path_ext(mesh, span_path, thespine, creaseAngle, min_cx, min_cy, width_cx, width_cy, begin_cap, end_cap, spine_ori, spine_scale, txAlongSpine);
		gf_path_del(span_path);
	}
	mesh_update_bounds(mesh);
	gf_mesh_build_aabbtree(mesh);
}
Beispiel #8
0
static void TraverseDepthViewPoint(GF_Node *node, void *rs, Bool is_destroy)
{
    if (!is_destroy && gf_node_dirty_get(node)) {
        GF_TraverseState *tr_state = (GF_TraverseState *) rs;
        GF_FieldInfo field;
        gf_node_dirty_clear(node, 0);

        tr_state->visual->depth_vp_position = 0;
        tr_state->visual->depth_vp_range = 0;
#ifndef GPAC_DISABLE_3D
        if (!tr_state->camera) return;
        tr_state->camera->flags |= CAM_IS_DIRTY;
#endif

        if (gf_node_get_field(node, 0, &field) != GF_OK) return;
        if (field.fieldType != GF_SG_VRML_SFBOOL) return;

        if ( *(SFBool *) field.far_ptr) {
            if (gf_node_get_field(node, 1, &field) != GF_OK) return;
            if (field.fieldType != GF_SG_VRML_SFFLOAT) return;
            tr_state->visual->depth_vp_position = *(SFFloat *) field.far_ptr;
            if (gf_node_get_field(node, 2, &field) != GF_OK) return;
            if (field.fieldType != GF_SG_VRML_SFFLOAT) return;
            tr_state->visual->depth_vp_range = *(SFFloat *) field.far_ptr;
        }
#ifndef GPAC_DISABLE_3D
        if (tr_state->layer3d) gf_node_dirty_set(tr_state->layer3d, GF_SG_NODE_DIRTY, 0);
#endif
        gf_sc_invalidate(tr_state->visual->compositor, NULL);
    }
}
Beispiel #9
0
static void svg_sani_render_path(GF_Node *node, void *rs, Bool is_destroy)
{
	SVG_SANI_pathElement *path = (SVG_SANI_pathElement *)node;
	Drawable *cs = (Drawable *)gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		svg_sani_destroy_path(node);
		return;
	}
	if (eff->traversing_mode==TRAVERSE_DRAW) {
		drawable_draw(eff);
		return;
	}
	else if (eff->traversing_mode==TRAVERSE_PICK) {
		drawable_pick(eff);
		return;
	}

	svg_sani_render_base(node, eff);

	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
#if USE_GF_PATH
		cs->path = &path->d;
#else
		drawable_reset_path(cs);
		gf_svg_path_build(cs->path, path->d.commands, path->d.points);
#endif
		if (path->fill_rule==GF_PATH_FILL_ZERO_NONZERO) cs->path->flags |= GF_PATH_FILL_ZERO_NONZERO;

		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		cs->flags |= DRAWABLE_HAS_CHANGED;
	}
	svg_sani_DrawablePostRender(cs, (SVG_SANI_TransformableElement *)path, eff, 0, (path->pathLength.type==SVG_NUMBER_VALUE) ? path->pathLength.value : 0);
}
Beispiel #10
0
static void svg_sani_render_line(GF_Node *node, void *rs, Bool is_destroy)
{
	SVG_SANI_lineElement *line = (SVG_SANI_lineElement *)node;
	Drawable *cs = (Drawable *)gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DestroyDrawableNode(node);
		return;
	}
	if (eff->traversing_mode==TRAVERSE_DRAW) {
		drawable_draw(eff);
		return;
	}
	else if (eff->traversing_mode==TRAVERSE_PICK) {
		drawable_pick(eff);
		return;
	}

	svg_sani_render_base(node, (RenderEffect2D *)rs);

	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
		drawable_reset_path(cs);
		gf_path_add_move_to(cs->path, line->x1.value, line->y1.value);
		gf_path_add_line_to(cs->path, line->x2.value, line->y2.value);
		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		cs->flags |= DRAWABLE_HAS_CHANGED;
	}
	svg_sani_DrawablePostRender(cs, (SVG_SANI_TransformableElement *)line, (RenderEffect2D *)rs, 0, 0);
}
Beispiel #11
0
static void svg_traverse_updates(GF_Node *node, void *rs, Bool is_destroy)
{
	/*video stack is just an extension of image stack, type-casting is OK*/
	SVG_updates_stack *stack = (SVG_updates_stack*)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	SVGAllAttributes all_atts;
	SVGPropertiesPointers backup_props;
	u32 backup_flags, dirty_flags;

	if (is_destroy) {
		if (stack->resource) {
			if (stack->is_open) {
				gf_mo_set_flag(stack->resource, GF_MO_DISPLAY_REMOVE, GF_TRUE);
				gf_mo_stop(stack->resource);
			}
			gf_mo_unregister(node, stack->resource);
		}
		gf_free(stack);
		return;
	} 

	if (tr_state->traversing_mode!=TRAVERSE_SORT) return;

	/*flatten attributes and apply animations + inheritance*/
	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
	if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags))
		return;

	dirty_flags = gf_node_dirty_get(node);
	if (dirty_flags) {
		stack->clipBegin = all_atts.clipBegin ? *all_atts.clipBegin : 0;
		stack->clipEnd = all_atts.clipEnd ? *all_atts.clipEnd : -1;
		if (dirty_flags & GF_SG_SVG_XLINK_HREF_DIRTY) {
			GF_MediaObject *new_res;
			MFURL url;
			Bool lock_timeline=GF_FALSE;
			url.vals = NULL;
			url.count = 0;

			if (all_atts.syncBehavior) lock_timeline = (*all_atts.syncBehavior == SMIL_SYNCBEHAVIOR_LOCKED) ? GF_TRUE : GF_FALSE;

			gf_term_get_mfurl_from_xlink(node, &url);

			new_res = gf_mo_register(node, &url, lock_timeline, GF_FALSE);
			gf_sg_mfurl_del(url);
			
			if (stack->resource!=new_res) {
				if (stack->resource) {
					gf_mo_stop(stack->resource);
					gf_mo_unregister(node, stack->resource);
				}
				stack->resource = new_res;
				if (stack->resource && stack->is_open) gf_mo_play(stack->resource, stack->clipBegin, stack->clipEnd, GF_FALSE);
			}
		}
		gf_node_dirty_clear(node, 0);
	}
	memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
	tr_state->svg_flags = backup_flags;
}
Beispiel #12
0
static void TraverseTransform2D(GF_Node *node, void *rs, Bool is_destroy)
{
	M_Transform2D *tr = (M_Transform2D *)node;
	Transform2DStack *ptr = (Transform2DStack *)gf_node_get_private(node);
	GF_TraverseState *tr_state;
	
	if (is_destroy) {
		gf_sc_check_focus_upon_destroy(node);
		group_2d_destroy(node, (GroupingNode2D*)ptr);
		gf_free(ptr);
		return;
	}

	tr_state = (GF_TraverseState *) 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);
		}
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
		ptr->is_null = (!tr->scale.x || !tr->scale.y) ? 1 : 0;
	}
	traverse_transform(node, ptr, tr_state);
}
Beispiel #13
0
static void TraverseDepthGroup(GF_Node *node, void *rs, Bool is_destroy)
{
#ifdef GF_SR_USE_DEPTH
	Fixed depth_gain, depth_offset;
#endif

	DepthGroupStack *stack = (DepthGroupStack *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *) rs;

	if (is_destroy) {
		gf_free(stack);
		return;
	}

	if (tr_state->traversing_mode==TRAVERSE_SORT) {
		if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {

			gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
			/*flag is not set for PROTO*/
			gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0);
		}
	}
	DepthGroup_GetNode(node, &stack->dg);


#ifdef GF_SR_USE_DEPTH
	depth_gain = tr_state->depth_gain;
	depth_offset = tr_state->depth_offset;

	// new offset is multiplied by parent gain and added to parent offset
	tr_state->depth_offset = gf_mulfix(stack->dg.depth_offset, tr_state->depth_gain) + tr_state->depth_offset;

	// gain is multiplied by parent gain
	tr_state->depth_gain = gf_mulfix(tr_state->depth_gain, stack->dg.depth_gain);
#endif

#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d) {
		GF_Matrix mx_bckup, mx;

		gf_mx_copy(mx_bckup, tr_state->model_matrix);
		gf_mx_init(mx);
		mx.m[14] = gf_mulfix(stack->dg.depth_offset, tr_state->visual->compositor->depth_gl_scale);
		gf_mx_add_matrix(&tr_state->model_matrix, &mx);
		group_2d_traverse((GF_Node *)&stack->dg, (GroupingNode2D*)stack, tr_state);
		gf_mx_copy(tr_state->model_matrix, mx_bckup);

	} else
#endif
	{

		group_2d_traverse((GF_Node *)&stack->dg, (GroupingNode2D*)stack, tr_state);
	}

#ifdef GF_SR_USE_DEPTH
	tr_state->depth_gain = depth_gain;
	tr_state->depth_offset = depth_offset;
#endif
}
Beispiel #14
0
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);
	}
}
Beispiel #15
0
static void TraverseOrderedGroup(GF_Node *node, void *rs, Bool is_destroy)
{
	u32 i, count;
	struct og_pos *priorities;
	Bool invalidate_backup;
	OrderedGroupStack *stack = (OrderedGroupStack *) gf_node_get_private(node);
	M_OrderedGroup *og = (M_OrderedGroup *) node;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		gf_sc_check_focus_upon_destroy(node);
		group_2d_destroy(node, (GroupingNode2D*)stack);
		if (stack->positions) gf_free(stack->positions);
		gf_free(stack);
		return;
	}

	if (!og->order.count || (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) ) {
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
		group_2d_traverse(node, (GroupingNode2D*)stack, tr_state);
		return;
	}

	invalidate_backup = tr_state->invalidate_all;
	/*check whether the OrderedGroup node has changed*/
	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {
		if (stack->positions) gf_free(stack->positions);
		count = gf_node_list_get_count(og->children);
		priorities = (struct og_pos*)gf_malloc(sizeof(struct og_pos)*count);
		for (i=0; i<count; i++) {
			priorities[i].position = i;
			priorities[i].priority = (i<og->order.count) ? og->order.vals[i] : 0;
		}
		qsort(priorities, count, sizeof(struct og_pos), compare_priority);

		stack->positions = (u32*)gf_malloc(sizeof(u32) * count);
		for (i=0; i<count; i++) stack->positions[i] = priorities[i].position;
		gf_free(priorities);
		
		tr_state->invalidate_all = 1;
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
	}
	group_2d_traverse_with_order(node, (GroupingNode2D*)stack, tr_state, stack->positions);
	tr_state->invalidate_all = invalidate_backup;
}
Beispiel #16
0
static void ellipse_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		drawable_reset_path(stack);
		gf_path_add_ellipse(stack->path, 0, 0, ((M_Ellipse *) node)->radius.x*2, ((M_Ellipse *) node)->radius.y*2);
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Beispiel #17
0
static void circle_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		Fixed a = ((M_Circle *) node)->radius * 2;
		drawable_reset_path(stack);
		gf_path_add_ellipse(stack->path, 0, 0, a, a);
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Beispiel #18
0
static void rectangle_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	/*if modified update node - we don't update for other traversing mode in order not to mess up the dirty
	rect tracking (otherwise we would miss geometry changes with same bounds)*/
	if (gf_node_dirty_get(node)) {
		drawable_reset_path(stack);
		gf_path_add_rect_center(stack->path, 0, 0, ((M_Rectangle *) node)->size.x, ((M_Rectangle *) node)->size.y);
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Beispiel #19
0
static void disk2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		Fixed a = ((X_Disk2D *) node)->outerRadius * 2;
		drawable_reset_path(stack);
		gf_path_add_ellipse(stack->path, 0, 0, a, a);
		a = ((X_Disk2D *) node)->innerRadius * 2;
		if (a) gf_path_add_ellipse(stack->path, 0, 0, a, a);
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Beispiel #20
0
/*ColorTransform*/
static void TraverseColorTransform(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);
	GF_TraverseState *tr_state = (GF_TraverseState *) rs;
	Bool prev_inv;

	if (is_destroy) {
		gf_sc_check_focus_upon_destroy(node);
		group_2d_destroy(node, (GroupingNode2D*)ptr);
		gf_free(ptr);
		return;
	}
	if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) {
		group_2d_traverse(node, (GroupingNode2D *) ptr, tr_state);
		return;
	}

	prev_inv = tr_state->invalidate_all;
	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;
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
	}

	if ((tr_state->traversing_mode==TRAVERSE_SORT) 
		&& !tr->maa && !tr->mar && !tr->mag && !tr->mab && !tr->ta)
		return; 

	/*if modified redraw all nodes*/
	if (c_changed) tr_state->invalidate_all = 1;

	/*note we don't clear dirty flag, this is done in traversing*/
	if (ptr->cmat.identity) {
		group_2d_traverse(node, (GroupingNode2D *) ptr, tr_state);
	} else {
		GF_ColorMatrix gf_cmx_bck;
		gf_cmx_copy(&gf_cmx_bck, &tr_state->color_mat);
		gf_cmx_multiply(&tr_state->color_mat, &ptr->cmat);


		group_2d_traverse(node, (GroupingNode2D *) ptr, tr_state);
		/*restore traversing state*/
		gf_cmx_copy(&tr_state->color_mat, &gf_cmx_bck);
	}
	tr_state->invalidate_all = prev_inv;
}
Beispiel #21
0
static void arc2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		drawable_reset_path(stack);
		if (gf_node_get_tag(node)==TAG_X3D_Arc2D) {
			X_Arc2D *a = (X_Arc2D *) node;
			gf_path_add_arc(stack->path, a->radius, a->startAngle, a->endAngle, 0);
		} else {
			X_ArcClose2D *a = (X_ArcClose2D *) node;
			gf_path_add_arc(stack->path, a->radius, a->startAngle, a->endAngle, !stricmp(a->closureType.buffer, "PIE") ? 2 : 1);
		}
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Beispiel #22
0
static void text_check_changes(GF_Node *node, TextStack *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node) || tr_state->visual->compositor->reset_fonts) {
		text_clean_paths(tr_state->visual->compositor, stack);
		build_text(stack, (M_Text*)node, tr_state);
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack->graph, tr_state);
	}
	
	if (tr_state->visual->compositor->edited_text && (tr_state->visual->compositor->focus_node==node)) {
		drawable_mark_modified(stack->graph, tr_state);	
		tr_state->visual->has_text_edit = 1;
		if (!stack->bounds.width) stack->bounds.width = INT2FIX(1)/100;
		if (!stack->bounds.height) stack->bounds.height = INT2FIX(1)/100;
	}
}
Beispiel #23
0
static void polyline2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		u32 i;
		X_Polyline2D *a = (X_Polyline2D *) node;
		drawable_reset_path(stack);
		for (i=0; i<a->lineSegments.count; i++) {
			if (i) {
				gf_path_add_line_to(stack->path, a->lineSegments.vals[i].x, a->lineSegments.vals[i].y);
			} else {
				gf_path_add_move_to(stack->path, a->lineSegments.vals[i].x, a->lineSegments.vals[i].y);
			}
		}
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
Beispiel #24
0
static void triangleset2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	if (gf_node_dirty_get(node)) {
		u32 i, count;
		X_TriangleSet2D *p = (X_TriangleSet2D *)node;
		drawable_reset_path(stack);
		count = p->vertices.count;
		while (count%3) count--;
		for (i=0; i<count; i+=3) {
			gf_path_add_move_to(stack->path, p->vertices.vals[i].x, p->vertices.vals[i].y);
			gf_path_add_line_to(stack->path, p->vertices.vals[i+1].x, p->vertices.vals[i+1].y);
			gf_path_add_line_to(stack->path, p->vertices.vals[i+2].x, p->vertices.vals[i+2].y);
			gf_path_close(stack->path);
		}
		gf_node_dirty_clear(node, 0);
		drawable_mark_modified(stack, tr_state);
	}
}
static void ifs2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	u32 i;
	SFVec2f *pts;
	u32 ci_count, c_count;
	Bool started;
	M_IndexedFaceSet2D *ifs2D;
	M_Coordinate2D *coord;

	if (! gf_node_dirty_get(node)) return;

	ifs2D = (M_IndexedFaceSet2D *)node;
	coord = (M_Coordinate2D *)ifs2D->coord;
	drawable_reset_path(stack);
	gf_node_dirty_clear(node, 0);
	drawable_mark_modified(stack, tr_state);


	c_count = coord->point.count;
	ci_count = ifs2D->coordIndex.count;
	pts = coord->point.vals;

	if (ci_count > 0) {
		started = 0;
		for (i=0; i < ci_count; i++) {
			if (ifs2D->coordIndex.vals[i] == -1) {
				gf_path_close(stack->path);
				started = 0;
			} else if (!started) {
				started = 1;
				gf_path_add_move_to_vec(stack->path, &pts[ifs2D->coordIndex.vals[i]]);
			} else {
				gf_path_add_line_to_vec(stack->path, &pts[ifs2D->coordIndex.vals[i]]);
			}
		}
		if (started) gf_path_close(stack->path);
	} else if (c_count) {
		gf_path_add_move_to_vec(stack->path, &pts[0]);
		for (i=1; i < c_count; i++) {
			gf_path_add_line_to_vec(stack->path, &pts[i]);
		}
		gf_path_close(stack->path);
	}
}
Beispiel #26
0
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;
		}
	}
}
Beispiel #27
0
static void svg_sani_render_polygon(GF_Node *node, void *rs, Bool is_destroy)
{
	SVG_SANI_polygonElement *polygon = (SVG_SANI_polygonElement *)node;
	Drawable *cs = (Drawable *)gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DestroyDrawableNode(node);
		return;
	}
	if (eff->traversing_mode==TRAVERSE_DRAW) {
		drawable_draw(eff);
		return;
	}
	else if (eff->traversing_mode==TRAVERSE_PICK) {
		drawable_pick(eff);
		return;
	}

	svg_sani_render_base(node, (RenderEffect2D *)rs);

	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
		u32 i;
		u32 nbPoints = gf_list_count(polygon->points);
		drawable_reset_path(cs);
		if (nbPoints) {
			SVG_Point *p = (SVG_Point *)gf_list_get(polygon->points, 0);
			gf_path_add_move_to(cs->path, p->x, p->y);
			for (i = 1; i < nbPoints; i++) {
				p = (SVG_Point *)gf_list_get(polygon->points, i);
				gf_path_add_line_to(cs->path, p->x, p->y);
			}
			gf_path_close(cs->path);
		} else {
			gf_path_add_move_to(cs->path, 0, 0);
		}
		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		cs->flags |= DRAWABLE_HAS_CHANGED;
	}
	svg_sani_DrawablePostRender(cs, (SVG_SANI_TransformableElement *)polygon, (RenderEffect2D *)rs, 0, 0);
}
Beispiel #28
0
static void pointset2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	u32 i;
	Fixed w, h;
	M_Coordinate2D *coord;

	if (!gf_node_dirty_get(node)) return;
	coord = (M_Coordinate2D *) ((M_PointSet2D *)node)->coord;

	drawable_reset_path(stack);

	get_point_size(&tr_state->transform, &w, &h);
	/*for PS2D don't add to avoid too  much antialiasing, just try to fill the given pixel*/
	for (i=0; i < coord->point.count; i++)
		gf_path_add_rect(stack->path, coord->point.vals[i].x, coord->point.vals[i].y, w, h);

	stack->path->flags |= GF_PATH_FILL_ZERO_NONZERO;

	gf_node_dirty_clear(node, 0);
	drawable_mark_modified(stack, tr_state);
}
Beispiel #29
0
static void ils2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
{
	u32 i;
	Bool started;
	SFVec2f *pts;
	M_IndexedLineSet2D *ils2D;
	M_Coordinate2D *coord;

	if (! gf_node_dirty_get(node)) return;

	drawable_reset_path(stack);
	gf_node_dirty_clear(node, 0);
	drawable_mark_modified(stack, tr_state);

	ils2D = (M_IndexedLineSet2D *)node;
	coord = (M_Coordinate2D *)ils2D->coord;

	pts = coord->point.vals;
	if (ils2D->coordIndex.count > 0) {
		started = 0;
		for (i=0; i < ils2D->coordIndex.count; i++) {
			/*NO close on ILS2D*/
			if (ils2D->coordIndex.vals[i] == -1) {
				started = 0;
			} else if (!started) {
				started = 1;
				gf_path_add_move_to(stack->path, pts[ils2D->coordIndex.vals[i]].x, pts[ils2D->coordIndex.vals[i]].y);
			} else {
				gf_path_add_line_to(stack->path, pts[ils2D->coordIndex.vals[i]].x, pts[ils2D->coordIndex.vals[i]].y);
			}
		}
	} else if (coord->point.count) {
		gf_path_add_move_to(stack->path, pts[0].x, pts[0].y);
		for (i=1; i < coord->point.count; i++) {
			gf_path_add_line_to(stack->path, pts[i].x, pts[i].y);
		}
	}
	stack->path->flags |= GF_PATH_FILL_ZERO_NONZERO;
}
Beispiel #30
0
static void TraverseAnchor(GF_Node *node, void *rs, Bool is_destroy)
{
	AnchorStack *st = (AnchorStack *) gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		mpeg4_sensor_deleted(node, &st->hdl);
		gf_sc_check_focus_upon_destroy(node);
		if (st->sensors) gf_list_del(st->sensors);
		gf_free(st);
		return;
	}

	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {
		MFURL *url = NULL;
		switch (gf_node_get_tag(node)) {
		case TAG_MPEG4_Anchor:
			url = & ((M_Anchor *)node)->url;
			break;
#ifndef GPAC_DISABLE_X3D
		case TAG_X3D_Anchor:
			url = & ((X_Anchor *)node)->url;
			break;
#endif
		}
		st->enabled = 0;
		if (url && url->count && url->vals[0].url && strlen(url->vals[0].url) )
			st->enabled = 1;

		if (!tr_state->visual->compositor->user->EventProc) {
			st->enabled = 0;
		}
		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);
	}

	group_2d_traverse(node, (GroupingNode2D*)st, tr_state);
}