⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svg_media.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Authors: Cyril Concolato - Jean le Feuvre *				Copyright (c) 2005-200X ENST *					All rights reserved * *  This file is part of GPAC / SVG Rendering sub-project * *  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 "visualsurface2d.h"#ifndef GPAC_DISABLE_SVG#include "svg_stacks.h"#include <gpac/internal/scenegraph_dev.h>static void SVG_Draw_bitmap(RenderEffect2D *eff){	u8 alpha;	Render2D *sr;	Bool use_blit;	DrawableContext *ctx = eff->ctx;	sr = eff->surface->render;	use_blit = 1;	alpha = GF_COL_A(ctx->aspect.fill_color);	/*this is not a native texture, use graphics*/	if (!ctx->h_texture->data || ctx->transform.m[1] || ctx->transform.m[3]) {		use_blit = 0;	} else {		if (!eff->surface->SupportsFormat || !eff->surface->DrawBitmap ) use_blit = 0;		/*format not supported directly, try with brush*/		else if (!eff->surface->SupportsFormat(eff->surface, ctx->h_texture->pixelformat) ) use_blit = 0;	}	/*no HW, fall back to the graphics driver*/	if (!use_blit) {		VS2D_TexturePath(eff->surface, ctx->drawable->path, ctx);		return;	}	/*direct rendering, render without clippers */	if (eff->surface->render->top_effect->trav_flags & TF_RENDER_DIRECT) {		eff->surface->DrawBitmap(eff->surface, ctx->h_texture, &ctx->bi->clip, &ctx->bi->unclip, alpha, NULL, ctx->col_mat);	}	/*render bitmap for all dirty rects*/	else {		u32 i;		GF_IRect clip;		for (i=0; i<eff->surface->to_redraw.count; i++) {			/*there's an opaque region above, don't draw*/#ifdef TRACK_OPAQUE_REGIONS			if (eff->surface->draw_node_index < eff->surface->to_redraw.opaque_node_index[i]) continue;#endif			clip = ctx->bi->clip;			gf_irect_intersect(&clip, &eff->surface->to_redraw.list[i]);			if (clip.width && clip.height) {				eff->surface->DrawBitmap(eff->surface, ctx->h_texture, &clip, &ctx->bi->unclip, alpha, NULL, ctx->col_mat);			}		}	}}static void SVG_Build_Bitmap_Graph(SVG_image_stack *st){	GF_Rect rc, new_rc;	Fixed x, y, width, height;	u32 tag = gf_node_get_tag(st->graph->node);	switch (tag) {#ifdef GPAC_ENABLE_SVG_SA	case TAG_SVG_SA_image:		{			SVG_SA_imageElement *img = (SVG_SA_imageElement *)st->graph->node;			x = img->x.value;			y = img->y.value;			width = img->width.value;			height = img->height.value;		}		break;	case TAG_SVG_SA_video:		{			SVG_SA_videoElement *video = (SVG_SA_videoElement *)st->graph->node;			x = video->x.value;			y = video->y.value;			width = video->width.value;			height = video->height.value;		}		break;#endif#ifdef GPAC_ENABLE_SVG_SANI	case TAG_SVG_SANI_image:		{			SVG_SANI_imageElement *img = (SVG_SANI_imageElement *)st->graph->node;			x = img->x.value;			y = img->y.value;			width = img->width.value;			height = img->height.value;		}		break;	case TAG_SVG_SANI_video:		{			SVG_SANI_videoElement *video = (SVG_SANI_videoElement *)st->graph->node;			x = video->x.value;			y = video->y.value;			width = video->width.value;			height = video->height.value;		}		break;#endif	case TAG_SVG_image:	case TAG_SVG_video:		{			SVG_Element *e = (SVG_Element *)st->graph->node;			SVGAllAttributes atts;			gf_svg_flatten_attributes(e, &atts);			x = (atts.x ? atts.x->value : 0);			y = (atts.y ? atts.y->value : 0);			width = (atts.width ? atts.width->value : 0);			height = (atts.height ? atts.height->value : 0);		}		break;	default:		return;	}	if (!width) width = INT2FIX(st->txh.width);	if (!height) height = INT2FIX(st->txh.height);	gf_path_get_bounds(st->graph->path, &rc);	drawable_reset_path(st->graph);	gf_path_add_rect_center(st->graph->path, x+width/2, y+height/2, width, height);	gf_path_get_bounds(st->graph->path, &new_rc);	if (!gf_rect_equal(rc, new_rc)) st->graph->flags |= DRAWABLE_HAS_CHANGED;	gf_node_dirty_clear(st->graph->node, GF_SG_SVG_GEOMETRY_DIRTY);}#ifdef GPAC_ENABLE_SVG_SAstatic void svg_sa_render_bitmap(GF_Node *node, void *rs){	/*video stack is just an extension of image stack, type-casting is OK*/	SVG_image_stack *st = (SVG_image_stack*)gf_node_get_private(node);	RenderEffect2D *eff = (RenderEffect2D *)rs;	SVGPropertiesPointers backup_props;	u32 backup_flags;	GF_Matrix2D backup_matrix;	GF_Matrix2D *m;	DrawableContext *ctx;	if (eff->traversing_mode==TRAVERSE_DRAW) {		SVG_Draw_bitmap(eff);		return;	}	else if (eff->traversing_mode==TRAVERSE_PICK) {		eff->is_over = 1;		return;	}	svg_sa_render_base(node, eff, &backup_props, &backup_flags);	if (gf_node_dirty_get(node)) {		SVG_Build_Bitmap_Graph((SVG_image_stack*)gf_node_get_private(node));		/*if open and changed, stop and play*/		if (gf_term_check_iri_change(st->txh.compositor->term, &st->txurl, & ((SVG_SA_Element *)node)->xlink->href)) {			const char *cache_dir = gf_cfg_get_key(st->txh.compositor->user->config, "General", "CacheDirectory");			gf_svg_store_embedded_data(& ((SVG_SA_Element *)node)->xlink->href, cache_dir, "embedded_");			if (gf_term_check_iri_change(st->txh.compositor->term, &st->txurl, & ((SVG_SA_Element *)node)->xlink->href)) {				gf_term_set_mfurl_from_uri(st->txh.compositor->term, &(st->txurl), & ((SVG_SA_Element*)node)->xlink->href);				if (st->txh.is_open) gf_sr_texture_stop(&st->txh);				gf_sr_texture_play_from_to(&st->txh, &st->txurl, 0, -1, 0, 0);			}		} 		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);	} 		switch (gf_node_get_tag(node)) {#ifdef GPAC_ENABLE_SVG_SA	case TAG_SVG_SA_image:		m = &((SVG_SA_imageElement *)node)->transform.mat;		break;	case TAG_SVG_SA_video:		m = &((SVG_SA_videoElement *)node)->transform.mat;		break;#endif#ifdef GPAC_ENABLE_SVG_SANI	case TAG_SVG_SANI_image:		m = &((SVG_SA_imageElement *)node)->transform.mat;		break;	case TAG_SVG_SANI_video:		m = &((SVG_SA_videoElement *)node)->transform.mat;		break;#endif	default:		/*SVG FIXME*/		m = NULL;	}	/*FIXME: setup aspect ratio*/	if (eff->traversing_mode == TRAVERSE_GET_BOUNDS) {		svg_sa_apply_local_transformation(eff, node, &backup_matrix);		if (!svg_is_display_off(eff->svg_props)) {			gf_path_get_bounds(st->graph->path, &eff->bounds);		}		memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers));		svg_sa_restore_parent_transformation(eff, &backup_matrix);  		eff->svg_flags = backup_flags;		return;	}	if (svg_is_display_off(eff->svg_props) ||		*(eff->svg_props->visibility) == SVG_VISIBILITY_HIDDEN) {		memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers));		eff->svg_flags = backup_flags;		return;	}	svg_sa_apply_local_transformation(eff, node, &backup_matrix);	ctx = SVG_drawable_init_context(st->graph, eff);	if (!ctx || !ctx->h_texture ) return;	/*even if set this is not true*/	ctx->aspect.pen_props.width = 0;	ctx->flags |= CTX_NO_ANTIALIAS;	/*if rotation, transparent*/	ctx->flags &= ~CTX_IS_TRANSPARENT;	if (ctx->transform.m[1] || ctx->transform.m[3]) {		ctx->flags |= CTX_IS_TRANSPARENT;		ctx->flags &= ~CTX_NO_ANTIALIAS;	}	else if (ctx->h_texture->transparent) 		ctx->flags |= CTX_IS_TRANSPARENT;	else if (eff->svg_props->opacity && (eff->svg_props->opacity->type==SVG_NUMBER_VALUE) && (eff->svg_props->opacity->value!=FIX_ONE)) {		ctx->flags = CTX_IS_TRANSPARENT;		ctx->aspect.fill_color = GF_COL_ARGB(FIX2INT(0xFF * eff->svg_props->opacity->value), 0, 0, 0);	}	/*bounds are stored when building graph*/		drawable_finalize_render(ctx, eff, NULL);	svg_sa_restore_parent_transformation(eff, &backup_matrix);  	memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers));	eff->svg_flags = backup_flags;}#endifstatic void svg_play_texture(SVG_image_stack *st, SVGAllAttributes *atts){	SVGAllAttributes all_atts;	Bool lock_scene = 0;	if (st->txh.is_open) gf_sr_texture_stop(&st->txh);	if (!atts) {		gf_svg_flatten_attributes((SVG_Element*)st->txh.owner, &all_atts);		atts = &all_atts;	}	if (atts->syncBehavior) lock_scene = (*atts->syncBehavior == SMIL_SYNCBEHAVIOR_LOCKED) ? 1 : 0;	gf_sr_texture_play_from_to(&st->txh, &st->txurl, 		atts->clipBegin ? (*atts->clipBegin) : 0.0,		atts->clipEnd ? (*atts->clipEnd) : -1.0,		0, 		lock_scene);}static void svg_render_bitmap(GF_Node *node, void *rs){	/*video stack is just an extension of image stack, type-casting is OK*/	SVG_image_stack *st = (SVG_image_stack*)gf_node_get_private(node);	RenderEffect2D *eff = (RenderEffect2D *)rs;	SVGPropertiesPointers backup_props;	u32 backup_flags;	GF_Matrix2D backup_matrix;	DrawableContext *ctx;	SVGAllAttributes all_atts;	if (eff->traversing_mode==TRAVERSE_DRAW) {		SVG_Draw_bitmap(eff);		return;	}	else if (eff->traversing_mode==TRAVERSE_PICK) {		drawable_pick(eff);		return;	}	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);	svg_render_base(node, &all_atts, (RenderEffect2D *)rs, &backup_props, &backup_flags);	if (gf_node_dirty_get(node)) {		GF_FieldInfo href_info;		SVG_Build_Bitmap_Graph((SVG_image_stack*)gf_node_get_private(node));		/*if open and changed, stop and play*/		if (gf_svg_get_attribute_by_tag(node, TAG_SVG_ATT_xlink_href, 0, 0, &href_info) == GF_OK) {			if (gf_term_check_iri_change(st->txh.compositor->term, &st->txurl, href_info.far_ptr)) {				const char *cache_dir = gf_cfg_get_key(st->txh.compositor->user->config, "General", "CacheDirectory");				gf_svg_store_embedded_data(href_info.far_ptr, cache_dir, "embedded_");				if (gf_term_check_iri_change(st->txh.compositor->term, &st->txurl, href_info.far_ptr) == GF_OK) {					gf_term_set_mfurl_from_uri(st->txh.compositor->term, &(st->txurl), href_info.far_ptr);					svg_play_texture(st, &all_atts);				}			} 		}		gf_node_dirty_clear(node, GF_SG_NODE_DIRTY);	} 		/*FIXME: setup aspect ratio*/	if (eff->traversing_mode == TRAVERSE_GET_BOUNDS) {		svg_apply_local_transformation(eff, &all_atts, &backup_matrix);		if (!svg_is_display_off(eff->svg_props)) {			gf_path_get_bounds(st->graph->path, &eff->bounds);		}		svg_restore_parent_transformation(eff, &backup_matrix);		memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers));		eff->svg_flags = backup_flags;		return;	}	if (svg_is_display_off(eff->svg_props) ||		*(eff->svg_props->visibility) == SVG_VISIBILITY_HIDDEN) {		memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers));		eff->svg_flags = backup_flags;		return;	}	svg_apply_local_transformation(eff, &all_atts, &backup_matrix);	ctx = SVG_drawable_init_context(st->graph, eff);	if (!ctx || !ctx->h_texture ) return;	/*even if set this is not true*/	ctx->aspect.pen_props.width = 0;	ctx->flags |= CTX_NO_ANTIALIAS;	/*if rotation, transparent*/	ctx->flags &= ~CTX_IS_TRANSPARENT;	if (ctx->transform.m[1] || ctx->transform.m[3]) {		ctx->flags |= CTX_IS_TRANSPARENT;		ctx->flags &= ~CTX_NO_ANTIALIAS;	}	else if (ctx->h_texture->transparent) 		ctx->flags |= CTX_IS_TRANSPARENT;	else if (eff->svg_props->opacity && (eff->svg_props->opacity->type==SVG_NUMBER_VALUE) && (eff->svg_props->opacity->value!=FIX_ONE)) {		ctx->flags = CTX_IS_TRANSPARENT;		ctx->aspect.fill_color = GF_COL_ARGB(FIX2INT(0xFF * eff->svg_props->opacity->value), 0, 0, 0);	}	/*bounds are stored when building graph*/		drawable_finalize_render(ctx, eff, NULL);	svg_restore_parent_transformation(eff, &backup_matrix);	memcpy(eff->svg_props, &backup_props, sizeof(SVGPropertiesPointers));	eff->svg_flags = backup_flags;}/*********************//* SVG image element *//*********************/static void SVG_Update_image(GF_TextureHandler *txh){		MFURL *txurl = &(((SVG_image_stack *)gf_node_get_private(txh->owner))->txurl);	/*setup texture if needed*/	if (!txh->is_open && txurl->count) {		gf_sr_texture_play_from_to(txh, txurl, 0, -1, 0, 0);	}	gf_sr_texture_update_frame(txh, 0);	/*URL is present but not opened - redraw till fetch*/	if (txh->stream && !txh->hwtx) gf_sr_invalidate(txh->compositor, NULL);}static void SVG_Render_image(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		SVG_image_stack *st = (SVG_image_stack *)gf_node_get_private(node);		gf_sr_texture_destroy(&st->txh);		gf_sg_mfurl_del(st->txurl);		drawable_del(st->graph);		free(st);	} else {		switch (gf_node_get_tag(node)) {#ifdef GPAC_ENABLE_SVG_SA		case TAG_SVG_SA_image:			svg_sa_render_bitmap(node, rs);			break;#endif#ifdef GPAC_ENABLE_SVG_SANI		case TAG_SVG_SANI_image:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -