Exemplo n.º 1
0
/*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);
	}
}
Exemplo n.º 2
0
void VS2D_TexturePathText(VisualSurface2D *surf, DrawableContext *txt_ctx, GF_Path *path, GF_Rect *object_bounds, GF_HWTEXTURE hwtx, GF_Rect *gf_sr_texture_bounds)
{
	Fixed sS, sT;
	GF_Matrix2D gf_mx2d_txt;
	GF_Rect rc, orig_rc;
	u8 alpha, r, g, b;
	GF_ColorMatrix cmat;
	GF_Raster2D *r2d = surf->render->compositor->r2d;

	VS2D_SetOptions(surf->render, surf->the_surface, 0, 1);

	/*get original bounds*/
	orig_rc = *object_bounds;
	rc = *gf_sr_texture_bounds;

	/*get scaling ratio so that active texture view is stretched to original bounds (std 2D shape texture mapping in MPEG4)*/
	sS = gf_divfix(orig_rc.width, rc.width);
	sT = gf_divfix(orig_rc.height, rc.height);
	
	gf_mx2d_init(gf_mx2d_txt);
	gf_mx2d_add_scale(&gf_mx2d_txt, sS, sT);

	/*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*/	
	gf_mx2d_add_matrix(&gf_mx2d_txt, &txt_ctx->transform);

	/*set path transform, except for background2D node which is directly build in the final coord system*/
	r2d->stencil_set_matrix(hwtx, &gf_mx2d_txt);

	alpha = GF_COL_A(txt_ctx->aspect.fill_color);
	r = GF_COL_R(txt_ctx->aspect.fill_color);
	g = GF_COL_G(txt_ctx->aspect.fill_color);
	b = GF_COL_B(txt_ctx->aspect.fill_color);

	/*if col do a cxmatrix*/
	if (!r && !g && !b) {
		r2d->stencil_set_texture_alpha(hwtx, alpha);
	} else {
		r2d->stencil_set_texture_alpha(hwtx, 0xFF);
		memset(cmat.m, 0, sizeof(Fixed) * 20);
		cmat.m[4] = INT2FIX(r)/255;
		cmat.m[9] = INT2FIX(g)/255;
		cmat.m[14] = INT2FIX(b)/255;
		cmat.m[18] = INT2FIX(alpha)/255;
		cmat.identity = 0;
		r2d->stencil_set_color_matrix(hwtx, &cmat);
	}

	r2d->surface_set_matrix(surf->the_surface, &txt_ctx->transform);

	/*push path*/
	r2d->surface_set_path(surf->the_surface, path);

	VS2D_DoFill(surf, txt_ctx, hwtx);
	r2d->surface_set_path(surf->the_surface, NULL);
	txt_ctx->flags |= CTX_PATH_FILLED;
}
Exemplo n.º 3
0
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);
	}
}
Exemplo n.º 4
0
GF_Err evg_surface_fill(GF_SURFACE _this, GF_STENCIL stencil)
{
	GF_Rect rc;
	GF_Matrix2D mat, st_mat;
	Bool restore_filter;
	EVGSurface *surf = (EVGSurface *)_this;
	EVGStencil *sten = (EVGStencil *)stencil;
	if (!surf || !stencil) return GF_BAD_PARAM;
	if (!surf->ftoutline.n_points) return GF_OK;
	surf->sten = sten;

	/*setup ft raster calllbacks*/
	if (!setup_grey_callback(surf)) return GF_OK;

/*	surf->ftparams.gray_spans = gray_spans_stub; */

	get_surface_world_matrix(surf, &mat);

	restore_filter = 0;
	/*get path frame for texture convertion */
	if (sten->type != GF_STENCIL_SOLID) {
		rc = surf->path_bounds;
		gf_mx2d_apply_rect(&mat, &rc);
		rc.x = rc.y = 0;
		/*assign target frame and matrix*/
		sten->frame = rc;
		gf_mx2d_copy(sten->pmat, surf->mat);
		gf_mx2d_inverse(&sten->pmat);

		gf_mx2d_copy(st_mat, sten->smat);
		gf_mx2d_init(sten->smat);
		switch (sten->type) {
		case GF_STENCIL_TEXTURE:
			if (! ((EVG_Texture *)sten)->pixels) return GF_BAD_PARAM;

			if (((EVG_Texture *)sten)->mod & GF_TEXTURE_FLIP) {
				if (!surf->center_coords) gf_mx2d_add_scale(&sten->smat, FIX_ONE, -FIX_ONE);
			} else {
				if (surf->center_coords) gf_mx2d_add_scale(&sten->smat, FIX_ONE, -FIX_ONE);
			}
			evg_set_texture_active(sten);
			gf_mx2d_add_matrix(&sten->smat, &st_mat);
			gf_mx2d_add_matrix(&sten->smat, &mat);
			gf_mx2d_inverse(&sten->smat);
			evg_bmp_init(sten);
			if (((EVG_Texture *)sten)->filter == GF_TEXTURE_FILTER_DEFAULT) {
				restore_filter = 1;
				((EVG_Texture *)sten)->filter = surf->texture_filter;
			}

			break;
		case GF_STENCIL_LINEAR_GRADIENT:
		{
			EVG_LinearGradient *lin = (EVG_LinearGradient *)sten;
			gf_mx2d_add_matrix(&sten->smat, &st_mat);
			gf_mx2d_add_matrix(&sten->smat, &mat);
			gf_mx2d_inverse(&sten->smat);
			/*and finalize matrix in gradient coord system*/
			gf_mx2d_add_matrix(&sten->smat, &lin->vecmat);
			gf_mx2d_add_scale(&sten->smat, INT2FIX(1<<EVGGRADIENTBITS), INT2FIX(1<<EVGGRADIENTBITS));

		}
			break;
		case GF_STENCIL_RADIAL_GRADIENT:
		{
			EVG_RadialGradient *rad = (EVG_RadialGradient*)sten;
			gf_mx2d_copy(sten->smat, st_mat);
			gf_mx2d_add_matrix(&sten->smat, &mat);
			gf_mx2d_inverse(&sten->smat);
			gf_mx2d_add_translation(&sten->smat, -rad->center.x, -rad->center.y);
			gf_mx2d_add_scale(&sten->smat, gf_invfix(rad->radius.x), gf_invfix(rad->radius.y));

			rad->d_f.x = gf_divfix(rad->focus.x - rad->center.x, rad->radius.x);
			rad->d_f.y = gf_divfix(rad->focus.y - rad->center.y, rad->radius.y);
			/*init*/
			evg_radial_init(rad);
		}
			break;
		}
	}

	if (surf->useClipper) {
		surf->ftparams.clip_xMin = surf->clipper.x;
		surf->ftparams.clip_yMin = surf->clipper.y;
		surf->ftparams.clip_xMax = (surf->clipper.x + surf->clipper.width);
		surf->ftparams.clip_yMax = (surf->clipper.y + surf->clipper.height);
	} else {
		surf->ftparams.clip_xMin = 0;
		surf->ftparams.clip_yMin = 0;
		surf->ftparams.clip_xMax = (surf->width);
		surf->ftparams.clip_yMax = (surf->height);
	}

	/*and call the raster*/
	evg_raster_render(surf->raster, &surf->ftparams);

	/*restore stencil matrix*/
	if (sten->type != GF_STENCIL_SOLID) {
		gf_mx2d_copy(sten->smat, st_mat);
		if (restore_filter) ((EVG_Texture *)sten)->filter = GF_TEXTURE_FILTER_DEFAULT;
	}
	surf->sten = 0L;
	return GF_OK;
}
Exemplo n.º 5
0
void gf_sc_get_nodes_bounds(GF_Node *self, GF_ChildNodeItem *children, GF_TraverseState *tr_state, s32 *child_idx)
{
	u32 i;
	SFVec2f size;
	GF_Rect rc;
	GF_Matrix2D cur_mx;

	if (tr_state->abort_bounds_traverse) {
		if (self == tr_state->for_node) {
			gf_mx2d_pre_multiply(&tr_state->mx_at_node, &tr_state->transform);
		}
		tr_state->abort_bounds_traverse=0;
		gf_sc_get_nodes_bounds(self, children, tr_state, child_idx);
		tr_state->abort_bounds_traverse=1;
		return;
	}
	if (!children) return;

	size.x = size.y = -FIX_ONE;
#ifndef GPAC_DISABLE_VRML
	switch (gf_node_get_tag(self)) {
	case TAG_MPEG4_Layer2D: size = ((M_Layer2D *)self)->size; break;
	case TAG_MPEG4_Layer3D: size = ((M_Layer3D *)self)->size; break;
	case TAG_MPEG4_Form: size = ((M_Form *)self)->size; break;
	}
#endif
	if ((size.x>=0) && (size.y>=0)) {
		tr_state->bounds = gf_rect_center(size.x, size.y);
		return;
	}

	gf_mx2d_copy(cur_mx, tr_state->transform);
	rc = gf_rect_center(0,0);

	i = 0;
	while (children) {
		if (child_idx && (i != (u32) *child_idx)) {
			children = children->next;
			continue;
		}
		gf_mx2d_init(tr_state->transform);
		tr_state->bounds = gf_rect_center(0,0);

		/*we hit the target node*/
		if (children->node == tr_state->for_node) 
			tr_state->abort_bounds_traverse = 1;

		gf_node_traverse(children->node, tr_state);

		if (tr_state->abort_bounds_traverse) {
			gf_mx2d_add_matrix(&tr_state->mx_at_node, &cur_mx);
			return;
		}

		gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds);
		gf_rect_union(&rc, &tr_state->bounds);
		children = children->next;
		if (child_idx) 
			break;
	}

#ifndef GPAC_DISABLE_SVG
	if (gf_node_get_tag(self)==TAG_SVG_use) {
		GF_FieldInfo info;
		if (gf_node_get_attribute_by_tag(self, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) {
			GF_Node *iri = ((XMLRI*)info.far_ptr)->target;
			if (iri) {
				gf_mx2d_init(tr_state->transform);
				tr_state->bounds = gf_rect_center(0,0);

				/*we hit the target node*/
				if (iri == tr_state->for_node) 
					tr_state->abort_bounds_traverse = 1;

				gf_node_traverse(iri, tr_state);

				if (tr_state->abort_bounds_traverse) {
					gf_mx2d_pre_multiply(&tr_state->mx_at_node, &cur_mx);
					return;
				}

				gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds);
				gf_rect_union(&rc, &tr_state->bounds);
			}
		}
	}
#endif
	
	gf_mx2d_copy(tr_state->transform, cur_mx);
	if (self != tr_state->for_node) {
		gf_mx2d_apply_rect(&tr_state->transform, &rc);
	}
	tr_state->bounds = rc;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
static void svg_recompute_viewport_transformation(GF_Node *node, SVGsvgStack *stack, GF_TraverseState *tr_state, SVGAllAttributes *atts) 
{
	GF_Matrix2D mx;
	SVG_ViewBox ext_vb, *vb;
	SVG_PreserveAspectRatio par;
	Fixed scale, vp_w, vp_h;
	Fixed parent_width, parent_height, doc_width, doc_height;

	/*canvas size negociation has already been done when attaching the scene to the compositor*/
	if (atts->width && (atts->width->type==SVG_NUMBER_PERCENTAGE) ) { 
		parent_width = gf_mulfix(tr_state->vp_size.x, atts->width->value/100);
		doc_width = 0;
	} else if (!stack->root_svg) {
		doc_width = parent_width = atts->width ? atts->width->value : 0;
	} else {
		parent_width = tr_state->vp_size.x;
		doc_width = atts->width ? atts->width->value : 0;
	}

	if (atts->height && (atts->height->type==SVG_NUMBER_PERCENTAGE) ) { 
		parent_height = gf_mulfix(tr_state->vp_size.y, atts->height->value/100);
		doc_height = 0;
	} else if (!stack->root_svg) {
		doc_height = parent_height = atts->height ? atts->height->value : 0;
	} else {
		parent_height = tr_state->vp_size.y;
		doc_height = atts->height ? atts->height->value : 0;
	}

	stack->vp = stack->parent_vp = tr_state->vp_size;

	vb = atts->viewBox;

	gf_mx2d_init(mx);

	if (stack->root_svg) {
		const char *frag_uri = gf_scene_get_fragment_uri(node);
		if (frag_uri) {
			/*SVGView*/
			if (!strncmp(frag_uri, "svgView", 7)) {
				if (!strncmp(frag_uri, "svgView(viewBox(", 16)) {
					Float x, y, w, h;
					sscanf(frag_uri, "svgView(viewBox(%f,%f,%f,%f))", &x, &y, &w, &h);
					ext_vb.x = FLT2FIX(x);
					ext_vb.y = FLT2FIX(y);
					ext_vb.width = FLT2FIX(w);
					ext_vb.height = FLT2FIX(h);
					ext_vb.is_set = 1;
					vb = &ext_vb;
				}
				else if (!strncmp(frag_uri, "svgView(transform(", 18)) {
					Bool ret = gf_svg_parse_transformlist(&mx, (char *) frag_uri+18);
                    if (!ret) {
                        GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error parsing SVG View transform component: %s\n", frag_uri+18));
                    }
				}
			}
			/*fragID*/
			else {
				GF_Node *target = gf_sg_find_node_by_name(gf_node_get_graph(node), (char *) frag_uri);
				if (target) {
					GF_Matrix2D mx;
					GF_TraverseState bounds_state;
					memset(&bounds_state, 0, sizeof(bounds_state));
					bounds_state.traversing_mode = TRAVERSE_GET_BOUNDS;
					bounds_state.visual = tr_state->visual;
					bounds_state.for_node = target;
					bounds_state.svg_props = tr_state->svg_props;
					gf_mx2d_init(bounds_state.transform);
					gf_mx2d_init(bounds_state.mx_at_node);
					gf_mx_init(tr_state->visual->compositor->hit_world_to_local);
					gf_sc_get_nodes_bounds(node, ((GF_ParentNode *)node)->children, &bounds_state, NULL);
					gf_mx2d_from_mx(&mx, &tr_state->visual->compositor->hit_world_to_local);
					gf_mx2d_apply_rect(&mx, &bounds_state.bounds);
					ext_vb.x = bounds_state.bounds.x;
					ext_vb.y = bounds_state.bounds.y-bounds_state.bounds.height;
					ext_vb.width = bounds_state.bounds.width;
					ext_vb.height = bounds_state.bounds.height;
					ext_vb.is_set = 1;
					vb = &ext_vb;
				}
			}
		}
	}
	gf_mx2d_init(stack->viewbox_mx);

	if (!vb) {
		if (!doc_width || !doc_height) {
			gf_mx2d_copy(stack->viewbox_mx, mx);
			return;
		}
		/*width/height were specified in the doc, use them to compute a dummy viewbox*/
		ext_vb.x = 0;
		ext_vb.y = 0;
		ext_vb.width = doc_width;
		ext_vb.height = doc_height;
		ext_vb.is_set = 1;
		vb = &ext_vb;
	}
	if ((vb->width<=0) || (vb->height<=0) ) {
		gf_mx2d_copy(stack->viewbox_mx, mx);
		return;
	}
	stack->vp.x = vb->width;
	stack->vp.y = vb->height;

	/*setup default*/
	par.defer = 0;
	par.meetOrSlice = SVG_MEETORSLICE_MEET;
	par.align = SVG_PRESERVEASPECTRATIO_XMIDYMID;

	/*use parent (animation, image) viewport settings*/
	if (tr_state->parent_anim_atts) {
		if (tr_state->parent_anim_atts->preserveAspectRatio) {
			if (tr_state->parent_anim_atts->preserveAspectRatio->defer) {
				if (atts->preserveAspectRatio) 
					par = *atts->preserveAspectRatio;
			} else {
				par = *tr_state->parent_anim_atts->preserveAspectRatio;
			}
		}
	}
	/*use current viewport settings*/
	else if (atts->preserveAspectRatio) {
		par = *atts->preserveAspectRatio;
	}

	if (par.meetOrSlice==SVG_MEETORSLICE_MEET) {
		if (gf_divfix(parent_width, vb->width) > gf_divfix(parent_height, vb->height)) {
			scale = gf_divfix(parent_height, vb->height);
			vp_w = gf_mulfix(vb->width, scale);
			vp_h = parent_height;
		} else {
			scale = gf_divfix(parent_width, vb->width);
			vp_w = parent_width;
			vp_h = gf_mulfix(vb->height, scale);
		}
	} else {
		if (gf_divfix(parent_width, vb->width) < gf_divfix(parent_height, vb->height)) {
			scale = gf_divfix(parent_height, vb->height);
			vp_w = gf_mulfix(vb->width, scale);
			vp_h = parent_height;
		} else {
			scale = gf_divfix(parent_width, vb->width);
			vp_w = parent_width;
			vp_h = gf_mulfix(vb->height, scale);
		}
	}

	if (par.align==SVG_PRESERVEASPECTRATIO_NONE) {
		stack->viewbox_mx.m[0] = gf_divfix(parent_width, vb->width);
		stack->viewbox_mx.m[4] = gf_divfix(parent_height, vb->height);
		stack->viewbox_mx.m[2] = - gf_muldiv(vb->x, parent_width, vb->width); 
		stack->viewbox_mx.m[5] = - gf_muldiv(vb->y, parent_height, vb->height); 
	} else {
		Fixed dx, dy;
		stack->viewbox_mx.m[0] = stack->viewbox_mx.m[4] = scale;
		stack->viewbox_mx.m[2] = - gf_mulfix(vb->x, scale); 
		stack->viewbox_mx.m[5] = - gf_mulfix(vb->y, scale); 

		dx = dy = 0;
		switch (par.align) {
		case SVG_PRESERVEASPECTRATIO_XMINYMIN:
			break;
		case SVG_PRESERVEASPECTRATIO_XMIDYMIN:
			dx = ( parent_width - vp_w) / 2; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMAXYMIN:
			dx = parent_width - vp_w; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMINYMID:
			dy = ( parent_height - vp_h) / 2; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMIDYMID:
			dx = ( parent_width  - vp_w) / 2; 
			dy = ( parent_height - vp_h) / 2; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMAXYMID:
			dx = parent_width  - vp_w; 
			dy = ( parent_height - vp_h) / 2; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMINYMAX:
			dy = parent_height - vp_h; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMIDYMAX:
			dx = (parent_width - vp_w) / 2; 
			dy = parent_height - vp_h; 
			break;
		case SVG_PRESERVEASPECTRATIO_XMAXYMAX:
			dx = parent_width  - vp_w; 
			dy = parent_height - vp_h; 
			break;
		}
		gf_mx2d_add_translation(&stack->viewbox_mx, dx, dy);
		stack->dx = dx;
		stack->dy = dy;
		stack->vpw = vp_w;
		stack->vph = vp_h;

		/*we need a clipper*/
		if (stack->root_svg && !tr_state->parent_anim_atts && (par.meetOrSlice==SVG_MEETORSLICE_SLICE)) {
			GF_Rect rc;
			rc.width = parent_width;
			rc.height = parent_height;
			if (!stack->root_svg) {
				rc.x = 0;
				rc.y = parent_height;
				gf_mx2d_apply_rect(&stack->viewbox_mx, &rc);
			} else {
				rc.x = dx;
				rc.y = dy + parent_height;
			}
//			tr_state->visual->top_clipper = gf_rect_pixelize(&rc);
		}
	}
	gf_mx2d_add_matrix(&stack->viewbox_mx, &mx);
}
Exemplo n.º 8
0
void visual_2d_texture_path_extended(GF_VisualManager *visual, GF_Path *path, GF_TextureHandler *txh, struct _drawable_context *ctx, GF_Rect *orig_bounds, GF_Matrix2D *ext_mx, GF_TraverseState *tr_state)
{
	Fixed sS, sT;
	u32 tx_tile;
	GF_STENCIL tx_raster;
	GF_Matrix2D mx_texture;
	GF_Rect orig_rc;
	GF_Raster2D *raster;

	if (! visual->CheckAttached(visual) ) return;

	raster = visual->compositor->rasterizer;

	if (!txh) txh = ctx->aspect.fill_texture;
	if (!txh) return;
	if (!txh->tx_io) {
		gf_node_dirty_set(txh->owner, 0, 1);

		txh->needs_refresh=1;
		return;
	}


	/*this is gradient draw*/
	if (txh->compute_gradient_matrix) {
		visual_2d_draw_gradient(visual, path, txh, ctx, tr_state, ext_mx, orig_bounds);
		return;
	}


#ifndef GPAC_DISABLE_3D
	if (visual->compositor->hybrid_opengl) {
		visual_2d_texture_path_opengl_auto(visual, path, txh, ctx, orig_bounds, ext_mx, tr_state);
		return;
	}
#endif

	if (txh->flags & GF_SR_TEXTURE_PRIVATE_MEDIA) {
		GF_Window src, dst;
		visual_2d_fill_path(visual, ctx, NULL, tr_state, 0);

		/*if texture not ready, update the size before computing output rectangles */
		if (!txh->width || !txh->height) {
			gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat, &txh->is_flipped);
			/*in case the node is an MPEG-4 bitmap, force stack rebuild at next frame */
			gf_node_dirty_set(ctx->drawable->node, GF_SG_NODE_DIRTY, 1);
		}

		if (compositor_texture_rectangles(visual, txh, &ctx->bi->clip, &ctx->bi->unclip, &src, &dst, NULL, NULL)) {
			if (txh->stream && gf_mo_set_position(txh->stream, &src, &dst)) {
				gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat, &txh->is_flipped);
				/*force dirty flag to get called again*/
				gf_node_dirty_set(ctx->drawable->node, GF_SG_NODE_DIRTY, 1);
				gf_sc_next_frame_state(visual->compositor, GF_SC_DRAW_FRAME);
			}
		}



		return;
	}

	if (!gf_sc_texture_push_image(txh, 0, 1)) return;
	tx_raster = gf_sc_texture_get_stencil(txh);

	/*setup quality even for background (since quality concerns images)*/
	visual_2d_set_options(visual->compositor, visual->raster_surface, ctx->flags & CTX_IS_TEXT, ctx->flags & CTX_NO_ANTIALIAS);

	/*get original bounds*/
	if (orig_bounds) {
		orig_rc = *orig_bounds;
	} else {
		gf_path_get_bounds(path, &orig_rc);
	}

	/*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(mx_texture);
	gf_mx2d_add_scale(&mx_texture, sS, sT);

#ifndef GPAC_DISABLE_VRML
	/*apply texture transform*/
	if (ctx->flags & CTX_HAS_APPEARANCE) {
		GF_Matrix2D tex_trans;
		visual_2d_get_texture_transform(ctx->appear, txh, &tex_trans, (txh == ctx->aspect.fill_texture) ? 0 : 1, txh->width * sS, txh->height * sT);
		gf_mx2d_add_matrix(&mx_texture, &tex_trans);
	}
#endif

	/*move to bottom-left corner of bounds */
	gf_mx2d_add_translation(&mx_texture, (orig_rc.x), (orig_rc.y - orig_rc.height));

	if (ext_mx) gf_mx2d_add_matrix(&mx_texture, ext_mx);

	/*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(&mx_texture, &ctx->transform);

	/*set path transform*/
	raster->stencil_set_matrix(tx_raster, &mx_texture);


	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;
	if (ctx->flags & CTX_FLIPED_COORDS)
		tx_tile |= GF_TEXTURE_FLIP;
	raster->stencil_set_tiling(tx_raster, (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*/
		raster->stencil_set_alpha(tx_raster, a );
		raster->stencil_set_color_matrix(tx_raster, ctx->col_mat);

		raster->surface_set_matrix(visual->raster_surface, &ctx->transform);
	} else {
		raster->surface_set_matrix(visual->raster_surface, NULL);
	}
	txh->flags |= GF_SR_TEXTURE_USED;

	/*push path & draw*/
	raster->surface_set_path(visual->raster_surface, path);
	visual_2d_fill_path(visual, ctx, tx_raster, tr_state, 0);
	raster->surface_set_path(visual->raster_surface, NULL);



	ctx->flags |= CTX_PATH_FILLED;
}
Exemplo n.º 9
0
void visual_2d_texture_path_text(GF_VisualManager *visual, DrawableContext *txt_ctx, GF_Path *path, GF_Rect *object_bounds, GF_TextureHandler *txh, GF_TraverseState *tr_state)
{
	GF_STENCIL stencil;
	Fixed sS, sT;
	GF_Matrix2D gf_mx2d_txt;
	GF_Rect orig_rc;
	u8 alpha, r, g, b;
	GF_ColorMatrix cmat;
	GF_Raster2D *raster;

	if (! visual->CheckAttached(visual) ) return;

	raster = visual->compositor->rasterizer;

	stencil = gf_sc_texture_get_stencil(txh);
	if (!stencil) return;

	visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1);

	/*get original bounds*/
	orig_rc = *object_bounds;

	/*get scaling ratio so that active texture view is stretched to original bounds (std 2D shape texture mapping in MPEG4)*/
	sS = gf_divfix(orig_rc.width, INT2FIX(txh->width));
	sT = gf_divfix(orig_rc.height, INT2FIX(txh->height));

	gf_mx2d_init(gf_mx2d_txt);
	gf_mx2d_add_scale(&gf_mx2d_txt, sS, sT);

	/*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*/
	gf_mx2d_add_matrix(&gf_mx2d_txt, &txt_ctx->transform);

	/*set path transform, except for background2D node which is directly build in the final coord system*/
	raster->stencil_set_matrix(stencil, &gf_mx2d_txt);

	alpha = GF_COL_A(txt_ctx->aspect.fill_color);
	r = GF_COL_R(txt_ctx->aspect.fill_color);
	g = GF_COL_G(txt_ctx->aspect.fill_color);
	b = GF_COL_B(txt_ctx->aspect.fill_color);

	/*if col do a cxmatrix*/
	if (!r && !g && !b) {
		raster->stencil_set_alpha(stencil, alpha);
	} else {
		raster->stencil_set_alpha(stencil, 0xFF);
		memset(cmat.m, 0, sizeof(Fixed) * 20);
		cmat.m[4] = INT2FIX(r)/255;
		cmat.m[9] = INT2FIX(g)/255;
		cmat.m[14] = INT2FIX(b)/255;
		cmat.m[18] = INT2FIX(alpha)/255;
		cmat.identity = 0;
		raster->stencil_set_color_matrix(stencil, &cmat);
	}

	raster->surface_set_matrix(visual->raster_surface, &txt_ctx->transform);
	txh->flags |= GF_SR_TEXTURE_USED;

	/*push path*/
	raster->surface_set_path(visual->raster_surface, path);

	visual_2d_fill_path(visual, txt_ctx, stencil, tr_state, 0);
	raster->surface_set_path(visual->raster_surface, NULL);
	txt_ctx->flags |= CTX_PATH_FILLED;
}