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; } }
void V4SceneManager::CreateIDandAddToPool(GF_Node *node) { // gets a node ID u32 id = gf_sg_get_next_available_node_id(GetSceneGraph()); char d[10]; // supposes no more than 1 000 000 000 objects // queries the pool to know which number to use for the name itoa(pools.GetCount(gf_node_get_tag(node)), d, 10); char c[50]; strcpy(c, gf_node_get_class_name(node)); strncat(c, "_", 1); strncat(c, d, 10); gf_node_set_id(node, id, c); // assigns NodeID and name pools.Add(node); // adds to the node pool }
static void svg2bifs_node_end(void *sax_cbck, const char *name, const char *name_space) { SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck; GF_Node *parent; SVGPropertiesPointers *backup_props = gf_node_get_private(converter->svg_parent); memcpy(&converter->svg_props, backup_props, sizeof(SVGPropertiesPointers)); // gf_free(backup_props); gf_node_set_private(converter->svg_parent, NULL); if (!(gf_node_get_tag(converter->svg_parent) == TAG_SVG_animateTransform)) converter->bifs_parent = gf_node_get_parent(converter->bifs_parent, 0); parent = gf_node_get_parent(converter->svg_parent, 0); gf_node_unregister(converter->svg_parent, parent); if (!parent) gf_sg_set_root_node(converter->svg_sg, NULL); converter->svg_parent = parent; converter->bifs_text_node = NULL; fprintf(stdout, "END:\t%s\t%s\n", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none"); }
static void StatNode(GF_SceneStatistics *stat, GF_Node *n, Bool isUsed, Bool isDelete, GF_Node *prev) { u32 i; GF_NodeStats *ptr = NULL; if (!stat) return; if (n->sgprivate->tag == TAG_ProtoNode) { #ifndef GPAC_DISABLE_VRML GF_ProtoInstance *pr = (GF_ProtoInstance *)n; i=0; while ((ptr = (GF_NodeStats *)gf_list_enum(stat->proto_stats, &i))) { if (pr->proto_interface->ID == ptr->tag) break; ptr = NULL; } if (!ptr) { GF_SAFEALLOC(ptr, GF_NodeStats); ptr->tag = pr->proto_interface->ID; ptr->name = gf_sg_proto_get_class_name(pr->proto_interface); gf_list_add(stat->proto_stats, ptr); } #endif } else { i=0; while ((ptr = (GF_NodeStats *)gf_list_enum(stat->node_stats, &i))) { if (n->sgprivate->tag == ptr->tag) break; ptr = NULL; } if (!ptr) { GF_SAFEALLOC(ptr, GF_NodeStats); ptr->tag = n->sgprivate->tag; ptr->name = gf_node_get_class_name(n); gf_list_add(stat->node_stats, ptr); } } if (isDelete) ptr->nb_del += n->sgprivate->num_instances; else if (isUsed) ptr->nb_used += 1; /*this is because the node passes twice in the stat, once on DumpNode and once in replaceALL*/ else ptr->nb_created += prev ? (prev->sgprivate->num_instances - 1) : 1; }
Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) { u32 k, i, count, num_nodes, num_changed; GF_IRect refreshRect; Bool redraw_all; Bool hyb_force_redraw=GF_FALSE; #ifndef GPAC_DISABLE_VRML M_Background2D *bck = NULL; DrawableContext *bck_ctx = NULL; #endif DrawableContext *ctx; struct _drawable_store *it, *prev; DrawableContext *first_opaque = NULL; Bool has_clear = 0; Bool has_changed = 0; Bool redraw_all_on_background_change = GF_TRUE; /*in direct mode the visual is always redrawn*/ if (tr_state->immediate_draw) { /*flush pending contexts due to overlays*/ visual_2d_flush_overlay_areas(visual, tr_state); visual_2d_release_raster(visual); visual_clean_contexts(visual); visual->num_nodes_prev_frame = visual->num_nodes_current_frame; return 1; } num_changed = 0; /*if the aspect ratio has changed redraw everything*/ redraw_all = tr_state->invalidate_all; #ifndef GPAC_DISABLE_3D if (visual->compositor->hybrid_opengl && !visual->offscreen) redraw_all_on_background_change = GF_FALSE; #endif /*check for background changes for transparent nodes*/ #ifndef GPAC_DISABLE_VRML bck = (M_Background2D*)gf_list_get(visual->back_stack, 0); if (bck) { if (!bck->isBound) { if (visual->last_had_back) { if (redraw_all_on_background_change) redraw_all = 1; else hyb_force_redraw = 1; } visual->last_had_back = 0; } else { bck_ctx = b2d_get_context(bck, visual->back_stack); if (!visual->last_had_back || (bck_ctx->flags & CTX_REDRAW_MASK) ) { if (redraw_all_on_background_change) redraw_all = 1; else hyb_force_redraw = 1; } visual->last_had_back = (bck_ctx->aspect.fill_texture && !bck_ctx->aspect.fill_texture->transparent) ? 2 : 1; } } else #endif if (visual->last_had_back) { visual->last_had_back = 0; if (redraw_all_on_background_change) redraw_all = 1; else hyb_force_redraw = 1; } num_nodes = 0; ctx = visual->context; while (ctx && ctx->drawable) { num_nodes++; drawctx_update_info(ctx, visual); if (!redraw_all) { u32 res; assert( gf_irect_inside(&visual->top_clipper, &ctx->bi->clip) ); res = register_context_rect(&visual->to_redraw, ctx, num_nodes, &first_opaque); if (res) { num_changed ++; if (res==2) hyb_force_redraw=GF_TRUE; } } ctx = ctx->next; } /*garbage collection*/ /*clear all remaining bounds since last frames (the ones that moved or that are not drawn this frame)*/ prev = NULL; it = visual->prev_nodes; while (it) { while (drawable_get_previous_bound(it->drawable, &refreshRect, visual)) { if (!redraw_all) { //assert( gf_irect_inside(&visual->top_clipper, &refreshRect) ); gf_irect_intersect(&refreshRect, &visual->top_clipper); register_dirty_rect(&visual->to_redraw, &refreshRect); has_clear=1; } } /*if node is marked as undrawn, remove from visual*/ if (!(it->drawable->flags & DRAWABLE_DRAWN_ON_VISUAL)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Node %s no longer on visual - unregistering it\n", gf_node_get_class_name(it->drawable->node))); /*remove all bounds info related to this visual and unreg node */ drawable_reset_bounds(it->drawable, visual); it->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_VISUAL; if (it->drawable->flags & DRAWABLE_IS_OVERLAY) { visual->compositor->video_out->Blit(visual->compositor->video_out, NULL, NULL, NULL, 1); } if (prev) prev->next = it->next; else visual->prev_nodes = it->next; if (!it->next) visual->last_prev_entry = prev; gf_free(it); it = prev ? prev->next : visual->prev_nodes; } else { prev = it; it = it->next; } } if (redraw_all) { ra_clear(&visual->to_redraw); ra_add(&visual->to_redraw, &visual->surf_rect); #ifdef TRACK_OPAQUE_REGIONS visual->to_redraw.list[0].opaque_node_index=0; #endif } else { ra_refresh(&visual->to_redraw); if (visual->compositor->debug_defer) { visual->ClearSurface(visual, &visual->top_clipper, 0); } } /*nothing to redraw*/ if (!hyb_force_redraw && ra_is_empty(&visual->to_redraw) ) { #ifndef GPAC_DISABLE_3D //force canvas draw visual->nb_objects_on_canvas_since_last_ogl_flush = 1; #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] No changes found since last frame - skipping redraw\n")); goto exit; } has_changed = 1; tr_state->traversing_mode = TRAVERSE_DRAW_2D; if (first_opaque && (visual->to_redraw.count==1) && gf_rect_equal(first_opaque->bi->clip, visual->to_redraw.list[0].rect)) { visual->has_modif=0; goto skip_background; } /*redraw everything*/ #ifndef GPAC_DISABLE_VRML if (bck_ctx) { drawable_check_bounds(bck_ctx, visual); tr_state->ctx = bck_ctx; visual->draw_node_index = 0; /*force clearing entire zone, not just viewport, when using color. If texture, we MUST use the VP clipper in order to compute offsets when blitting bitmaps*/ if (bck_ctx->aspect.fill_texture && bck_ctx->aspect.fill_texture->stream) { bck_ctx->bi->clip = visual->top_clipper; } else { bck_ctx->bi->clip = visual->surf_rect; } bck_ctx->bi->unclip = gf_rect_ft(&bck_ctx->bi->clip); bck_ctx->next = visual->context; bck_ctx->flags |= CTX_BACKROUND_NOT_LAYER; gf_node_traverse(bck_ctx->drawable->node, tr_state); bck_ctx->flags &= ~CTX_BACKROUND_NOT_LAYER; } else #endif /*GPAC_DISABLE_VRML*/ { count = visual->to_redraw.count; for (k=0; k<count; k++) { GF_IRect rc; /*opaque area, skip*/ #ifdef TRACK_OPAQUE_REGIONS if (visual->to_redraw.list[k].opaque_node_index > 0) continue; #endif rc = visual->to_redraw.list[k].rect; visual->ClearSurface(visual, &rc, 0); } #ifndef GPAC_DISABLE_3D if (!count && hyb_force_redraw) { compositor_2d_hybgl_clear_surface_ex(tr_state->visual, NULL, 0, GF_FALSE); } #endif } if (!redraw_all && !has_clear) visual->has_modif=0; skip_background: #ifndef GPAC_DISABLE_LOG if (gf_log_tool_level_on(GF_LOG_COMPOSE, GF_LOG_INFO)) { GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Visual2D] Redraw %d / %d nodes (all: %s - %d dirty rects\n)", num_changed, num_nodes, redraw_all ? "yes" : "no", visual->to_redraw.count)); if (visual->to_redraw.count>1) GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("\n")); for (i=0; i<visual->to_redraw.count; i++) { GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("\tDirtyRect #%d: %d:%d@%dx%d\n", i+1, visual->to_redraw.list[i].rect.x, visual->to_redraw.list[i].rect.y, visual->to_redraw.list[i].rect.width, visual->to_redraw.list[i].rect.height)); assert(visual->to_redraw.list[i].rect.width); } } #endif visual->draw_node_index = 0; ctx = visual->context; while (ctx && ctx->drawable) { visual->draw_node_index ++; tr_state->ctx = ctx; /*if overlay we cannot remove the context and cannot draw directly*/ if (! visual_2d_overlaps_overlay(tr_state->visual, ctx, tr_state)) { if (ctx->drawable->flags & DRAWABLE_USE_TRAVERSE_DRAW) { gf_node_traverse(ctx->drawable->node, tr_state); } else { drawable_draw(ctx->drawable, tr_state); } } ctx = ctx->next; } /*flush pending contexts due to overlays*/ visual_2d_flush_overlay_areas(visual, tr_state); #ifndef GPAC_DISABLE_VRML if (bck_ctx) bck_ctx->next = NULL; #endif if (visual->direct_flush) { GF_DirtyRectangles dr; u32 i; dr.count = visual->to_redraw.count; dr.list = gf_malloc(sizeof(GF_IRect)*dr.count); for (i=0; i<dr.count; i++) { dr.list[i] = visual->to_redraw.list[i].rect; } visual->compositor->video_out->FlushRectangles(visual->compositor->video_out, &dr); visual->compositor->skip_flush=1; gf_free(dr.list); } exit: /*clear dirty rects*/ ra_clear(&visual->to_redraw); visual_2d_release_raster(visual); visual_clean_contexts(visual); visual->num_nodes_prev_frame = visual->num_nodes_current_frame; return has_changed; }
GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) { GF_Err e; u32 rem, count; struct _drawable_store *it, *prev; #ifndef GPAC_DISABLE_VRML DrawableContext *ctx; M_Background2D *bck; #endif u32 draw_mode; /*reset display list*/ visual->cur_context = visual->context; if (visual->context) visual->context->drawable = NULL; visual->has_modif = 0; visual->has_overlays = 0; visual_2d_setup_projection(visual, tr_state); if (!visual->top_clipper.width || !visual->top_clipper.height) return GF_OK; tr_state->traversing_mode = TRAVERSE_SORT; visual->num_nodes_current_frame = 0; /*setup raster surface, brush and pen */ e = visual_2d_init_raster(visual); if (e) return e; draw_mode = 0; if (tr_state->immediate_draw) draw_mode = 1; /*if we're requested to invalidate everything, switch to direct drawing but don't reset bounds*/ else if (tr_state->invalidate_all) { tr_state->immediate_draw = 1; draw_mode = 2; } tr_state->invalidate_all = 0; /*reset prev nodes if any (previous traverse was indirect)*/ rem = count = 0; prev = NULL; it = visual->prev_nodes; while (it) { /*node was not drawn on this visual*/ if (!drawable_flush_bounds(it->drawable, visual, draw_mode)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Unregistering previously drawn node %s from visual\n", gf_node_get_class_name(it->drawable->node))); /*remove all bounds info related to this visual and unreg node */ drawable_reset_bounds(it->drawable, visual); if (prev) prev->next = it->next; else visual->prev_nodes = it->next; if (!it->next) visual->last_prev_entry = prev; rem++; gf_free(it); it = prev ? prev->next : visual->prev_nodes; } else { /*mark drawable as already registered with visual*/ it->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL; prev = it; it = it->next; count++; } } GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Top visual initialized - %d nodes registered and %d removed - using %s rendering\n", count, rem, draw_mode ? "direct" : "dirty-rect")); if (!draw_mode) return GF_OK; #ifndef GPAC_DISABLE_VRML /*direct mode, draw background*/ bck = (M_Background2D*) gf_list_get(visual->back_stack, 0); if (bck && bck->isBound) { ctx = b2d_get_context(bck, visual->back_stack); if (ctx) { /*force clearing entire zone, not just viewport, when using color. If texture, we MUST use the VP clipper in order to compute offsets when blitting bitmaps*/ if (ctx->aspect.fill_texture &&ctx->aspect.fill_texture->stream) { ctx->bi->clip = visual->top_clipper; } else { ctx->bi->clip = visual->surf_rect; } ctx->bi->unclip = gf_rect_ft(&ctx->bi->clip); tr_state->traversing_mode = TRAVERSE_BINDABLE; ctx->flags |= CTX_BACKROUND_NOT_LAYER; gf_node_traverse((GF_Node *) bck, tr_state); tr_state->traversing_mode = TRAVERSE_SORT; ctx->flags &= ~CTX_BACKROUND_NOT_LAYER; } else { visual->ClearSurface(visual, NULL, 0); } } else #endif { visual->ClearSurface(visual, NULL, 0); } return GF_OK; }
GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node) { u32 NDTBits, node_type, node_tag, BVersion, node_id; const char *node_name; Bool flag, reset_qp14; GF_Node *new_node; GF_Err e; assert(codec->info); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) )); /*NULL node is a USE of maxID*/ if (!node) { GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL); GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL"); return GF_OK; } flag = BE_NodeIsUSE(codec, node); GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node)); if (flag) { gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits); new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) ); if (!new_node) return codec->LastError = GF_SG_UNKNOWN_NODE; /*restore QP14 length*/ switch (gf_node_get_tag(new_node)) { case TAG_MPEG4_Coordinate: { u32 nbCoord = ((M_Coordinate *)new_node)->point.count; gf_bifs_enc_qp14_enter(codec, GF_TRUE); gf_bifs_enc_qp14_set_length(codec, nbCoord); gf_bifs_enc_qp14_enter(codec, GF_FALSE); } break; case TAG_MPEG4_Coordinate2D: { u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count; gf_bifs_enc_qp14_enter(codec, GF_TRUE); gf_bifs_enc_qp14_set_length(codec, nbCoord); gf_bifs_enc_qp14_enter(codec, GF_FALSE); } break; } return GF_OK; } BVersion = GF_BIFS_V1; node_tag = node->sgprivate->tag; while (1) { node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion); NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion); if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1; GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL); if (node_type) break; BVersion += 1; if (BVersion > GF_BIFS_NUM_VERSION) { if (parent_node) { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s as a child of %s\n", gf_node_get_class_name(node), gf_node_get_class_name(parent_node) )); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) )); } return codec->LastError = GF_BIFS_UNKNOWN_VERSION; } } if (BVersion==2 && node_type==1) { GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface; GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL); } /*special handling of 3D mesh*/ /*DEF'd node*/ node_name = gf_node_get_name_and_id(node, &node_id); GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL); if (node_id) { GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL); if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name ); } /*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/ /*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/ reset_qp14 = !codec->coord_stored; /*QP14 case*/ switch (node_tag) { case TAG_MPEG4_Coordinate: case TAG_MPEG4_Coordinate2D: gf_bifs_enc_qp14_enter(codec, GF_TRUE); } e = EncNodeFields(codec, bs, node); if (e) return e; if (codec->coord_stored && reset_qp14) gf_bifs_enc_qp14_reset(codec); switch (node_tag) { case TAG_MPEG4_Coordinate: case TAG_MPEG4_Coordinate2D: gf_bifs_enc_qp14_enter(codec, GF_FALSE); break; } return GF_OK; }
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes) { u32 i; SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck; SVGPropertiesPointers *backup_props; char *id_string = NULL; u32 tag; SVG_Element *elt; SVG_DeferedAnimation *anim = NULL; tag = gf_xml_get_element_tag(name, 0); elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag); if (!gf_sg_get_root_node(converter->svg_sg)) { gf_node_register((GF_Node *)elt, NULL); gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt); } else { gf_node_register((GF_Node *)elt, converter->svg_parent); //gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt); } // fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt)); // if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent)); if (gf_svg_is_animation_tag(tag)) { GF_SAFEALLOC(anim, SVG_DeferedAnimation); /*default anim target is parent node*/ anim->animation_elt = elt; if (converter->svg_parent) { anim->target = anim->anim_parent = (SVG_Element*) converter->svg_parent; } } for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!stricmp(att->name, "style")) { gf_svg_parse_style((GF_Node *)elt, att->value); } else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) { gf_svg_parse_element_id((GF_Node *)elt, att->value, 0); id_string = att->value; } else if (anim && !stricmp(att->name, "to")) { anim->to = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "from")) { anim->from = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "by")) { anim->by = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "values")) { anim->values = gf_strdup(att->value); } else if (anim && (tag == TAG_SVG_animateTransform) && !stricmp(att->name, "type")) { anim->type = gf_strdup(att->value); } else { GF_FieldInfo info; if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) { gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0); } else { fprintf(stdout, "Skipping attribute %s\n", att->name); } } } if (anim) { svg_parse_animation(converter->svg_sg, anim); } memset(&converter->all_atts, 0, sizeof(SVGAllAttributes)); gf_svg_flatten_attributes(elt, &converter->all_atts); backup_props = gf_malloc(sizeof(SVGPropertiesPointers)); memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers)); gf_node_set_private((GF_Node *)elt, backup_props); gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props); fprintf(stdout, "START\t%s\t%s\t%s", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none", name); converter->svg_parent = (GF_Node *)elt; if (!gf_sg_get_root_node(converter->bifs_sg)) { if (tag == TAG_SVG_svg) { GF_Node *node, *child; converter->bifs_sg->usePixelMetrics = 1; if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) { converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value); } else { converter->bifs_sg->width = 320; } if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) { converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value); } else { converter->bifs_sg->height = 200; } node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup); gf_node_register(node, NULL); gf_sg_set_root_node(converter->bifs_sg, node); child = gf_node_new(converter->bifs_sg, TAG_MPEG4_QuantizationParameter); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_QuantizationParameter *qp = (M_QuantizationParameter *)child; qp->useEfficientCoding = 1; } /* SVG to BIFS coordinate transformation */ child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Viewport *vp = (M_Viewport*)child; if (converter->all_atts.viewBox) { vp->size.x = converter->all_atts.viewBox->width; vp->size.y = converter->all_atts.viewBox->height; vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2; vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2); } else { vp->size.x = INT2FIX(converter->bifs_sg->width); vp->size.y = INT2FIX(converter->bifs_sg->height); vp->position.x = INT2FIX(converter->bifs_sg->width)/2; vp->position.y = -INT2FIX(converter->bifs_sg->height)/2; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Background2D *b = (M_Background2D *)child; b->backColor.red = FIX_ONE; b->backColor.green = FIX_ONE; b->backColor.blue = FIX_ONE; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; { M_Transform2D *tr = (M_Transform2D *)node; tr->scale.y = -FIX_ONE; } converter->bifs_parent = node; } } else { GF_Node *node, *child; node = converter->bifs_parent; switch(tag) { case TAG_SVG_g: { if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; } else { M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group); gf_node_register((GF_Node *)g, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g); node = (GF_Node *)g; converter->bifs_parent = node; } } break; case TAG_SVG_rect: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } if (converter->all_atts.x || converter->all_atts.y) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } { M_Transform2D *tr = (M_Transform2D *)node; if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0); if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0); } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle); gf_node_register(shape->geometry, (GF_Node *)shape); { M_Rectangle *rect = (M_Rectangle *)shape->geometry; if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value; if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value; } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_path: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } if (converter->all_atts.x || converter->all_atts.y) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } { M_Transform2D *tr = (M_Transform2D *)node; if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value; if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D); gf_node_register(shape->geometry, (GF_Node *)shape); if (converter->all_atts.d) { M_Coordinate2D *c2d; M_XCurve2D *xc = (M_XCurve2D *)shape->geometry; u32 i, j, c, k; xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)xc->point; gf_node_register(xc->point, (GF_Node *)xc); gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points); gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points); c = 0; k = 0; j = 0; c2d->point.vals[k] = converter->all_atts.d->points[0]; k++; xc->type.vals[0] = 0; for (i = 1; i < converter->all_atts.d->n_points; ) { switch(converter->all_atts.d->tags[i]) { case GF_PATH_CURVE_ON: c2d->point.vals[k] = converter->all_atts.d->points[i]; k++; if (i-1 == converter->all_atts.d->contours[c]) { xc->type.vals[j] = 0; c++; } else { xc->type.vals[j] = 1; } i++; break; case GF_PATH_CURVE_CUBIC: c2d->point.vals[k] = converter->all_atts.d->points[i]; c2d->point.vals[k+1] = converter->all_atts.d->points[i+1]; c2d->point.vals[k+2] = converter->all_atts.d->points[i+2]; k+=3; xc->type.vals[j] = 2; if (converter->all_atts.d->tags[i+2]==GF_PATH_CLOSE) { j++; xc->type.vals[j] = 6; } i+=3; break; case GF_PATH_CLOSE: xc->type.vals[j] = 6; i++; break; case GF_PATH_CURVE_CONIC: c2d->point.vals[k] = converter->all_atts.d->points[i]; c2d->point.vals[k+1] = converter->all_atts.d->points[i+1]; k+=2; xc->type.vals[j] = 7; if (converter->all_atts.d->tags[i+1]==GF_PATH_CLOSE) { j++; xc->type.vals[j] = 6; } i+=2; break; } j++; } xc->type.count = j; c2d->point.count = k; } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_polyline: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D); gf_node_register(shape->geometry, (GF_Node *)shape); if (converter->all_atts.points) { M_Coordinate2D *c2d; M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry; u32 i; ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)ifs->coord; gf_node_register(ifs->coord, (GF_Node *)ifs); gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points)); for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) { SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i); c2d->point.vals[i].x = p->x; c2d->point.vals[i].y = p->y; } } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_text: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Transform2D *tr = (M_Transform2D *)child; if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value; if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value; tr->scale.y = -FIX_ONE; } node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_FontStyle *fs; M_Text *text; M_Shape *shape = (M_Shape *)node; text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text); shape->geometry = (GF_Node *)text; converter->bifs_text_node = shape->geometry; gf_node_register(shape->geometry, (GF_Node *)shape); fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle); gf_node_register((GF_Node *)fs, (GF_Node*)text); text->fontStyle = (GF_Node *)fs; gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1); fs->family.vals[0] = gf_strdup(converter->svg_props.font_family->value); fs->size = converter->svg_props.font_size->value; shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_ellipse: case TAG_SVG_circle: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform_matrix(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->force_transform) { node = add_transform2d(converter, node); if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } if (converter->all_atts.cx || converter->all_atts.cy) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Transform2D *tr = (M_Transform2D *)child; if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value; if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value; } node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; if (tag == TAG_SVG_ellipse) { M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse); shape->geometry = (GF_Node *)e; e->radius.x = converter->all_atts.rx->value; e->radius.y = converter->all_atts.ry->value; } else { M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle); shape->geometry = (GF_Node *)c; c->radius = converter->all_atts.r->value; } gf_node_register(shape->geometry, (GF_Node *)shape); shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_defs: { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; { M_Switch *sw = (M_Switch *)node; sw->whichChoice = -1; } converter->bifs_parent = node; } break; case TAG_SVG_solidColor: { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; converter->bifs_parent = node; } break; case TAG_SVG_animateTransform: { GF_Node *child_ts; if (!gf_node_get_id(node)) { gf_node_set_id(node, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } child_ts = gf_node_new(converter->bifs_sg, TAG_MPEG4_TimeSensor); if (!gf_node_get_id(child_ts)) { gf_node_set_id(child_ts, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child_ts, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child_ts); { M_TimeSensor *ts = (M_TimeSensor *)child_ts; if (converter->all_atts.dur) { ts->cycleInterval = converter->all_atts.dur->clock_value; } if (converter->all_atts.repeatCount && converter->all_atts.repeatCount->type == SMIL_REPEATCOUNT_INDEFINITE) { ts->loop = 1; } } if (converter->all_atts.transform_type) { GF_FieldInfo fromField, toField; switch (*converter->all_atts.transform_type) { case SVG_TRANSFORM_ROTATE: child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D); if (!gf_node_get_id(child)) { gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child); gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField); gf_node_get_field_by_name(child, "set_fraction", &toField); gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex); gf_node_get_field_by_name(child, "value_changed", &fromField); gf_node_get_field_by_name(node, "rotationAngle", &toField); gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex); { M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child; if (converter->all_atts.keyTimes) { SFFloat *g; u32 count, i; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g); *g = *f; } } if (converter->all_atts.values) { SFVec2f *g; u32 count, i; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point_Angle *p; p = gf_list_get(converter->all_atts.values->values, i); gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g); g->x = p->x; g->y = p->y; } } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_ScalarInterpolator); if (!gf_node_get_id(child)) { gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child); gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField); gf_node_get_field_by_name(child, "set_fraction", &toField); gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex); gf_node_get_field_by_name(child, "value_changed", &fromField); gf_node_get_field_by_name(node, "center", &toField); gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex); { M_ScalarInterpolator *si = (M_ScalarInterpolator *)child; if (converter->all_atts.keyTimes) { SFFloat *g; u32 count, i; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); gf_sg_vrml_mf_append(&si->key, GF_SG_VRML_MFFLOAT, &g); *g = *f; } } if (converter->all_atts.values) { SFFloat *g; u32 count, i; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point_Angle *p; p = gf_list_get(converter->all_atts.values->values, i); gf_sg_vrml_mf_append(&si->keyValue, GF_SG_VRML_MFFLOAT, &g); *g = p->angle; } } } break; case SVG_TRANSFORM_SCALE: case SVG_TRANSFORM_TRANSLATE: child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D); if (!gf_node_get_id(child)) { gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL); } gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode *)node)->children, child); gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField); gf_node_get_field_by_name(child, "set_fraction", &toField); gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex); gf_node_get_field_by_name(child, "value_changed", &fromField); if (*converter->all_atts.transform_type == SVG_TRANSFORM_SCALE) gf_node_get_field_by_name(node, "scale", &toField); else gf_node_get_field_by_name(node, "translation", &toField); gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex); { M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child; if (converter->all_atts.keyTimes) { SFFloat *g; u32 count, i; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g); *g = *f; } } if (converter->all_atts.values) { SFVec2f *g; u32 count, i; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point *p; p = gf_list_get(converter->all_atts.values->values, i); gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g); g->x = p->x; g->y = p->y; } } } break; default: fprintf(stdout, "Warning: transformation type not supported \n"); } } //converter->bifs_parent = node; } break; default: { fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt)); child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); //gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; converter->bifs_parent = node; } break; } if (id_string) gf_node_set_id(converter->bifs_parent, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);//gf_node_get_name((GF_Node *)elt)); } fprintf(stdout, "\t%s\n", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none"); }
static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_STENCIL stencil, GF_TraverseState *tr_state, Bool is_erase) { Bool has_modif = GF_FALSE; GF_IRect clip; GF_Raster2D *raster = visual->compositor->rasterizer; /*background & direct drawing : use ctx clip*/ if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) { if (ctx->bi->clip.width && ctx->bi->clip.height) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (direct draw)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node) )); if (stencil) { raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip); raster->surface_fill(visual->raster_surface, stencil); } else { raster->surface_clear(visual->raster_surface, &ctx->bi->clip, 0); } has_modif = GF_TRUE; } } /*indirect drawing, draw path in all dirty areas*/ else { u32 i; for (i=0; i<visual->to_redraw.count; i++) { /*there's an opaque region above, don't draw*/ #ifdef TRACK_OPAQUE_REGIONS if (!is_erase && (visual->draw_node_index<visual->to_redraw.list[i].opaque_node_index)) continue; #endif clip = ctx->bi->clip; gf_irect_intersect(&clip, &visual->to_redraw.list[i].rect); if (clip.width && clip.height) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node), i)); if (stencil) { raster->surface_set_clipper(visual->raster_surface, &clip); raster->surface_fill(visual->raster_surface, stencil); } else { raster->surface_clear(visual->raster_surface, &clip, 0); } has_modif = 1; } } } #ifndef GPAC_DISABLE_3D if (!is_erase) visual->nb_objects_on_canvas_since_last_ogl_flush++; #endif if (has_modif) { visual->has_modif = 1; #ifndef GPAC_DISABLE_3D if (!visual->offscreen && visual->compositor->hybrid_opengl && !is_erase) ra_union_rect(&visual->hybgl_drawn, &ctx->bi->clip); #endif } }
void gf_sc_on_node_init(GF_Compositor *compositor, GF_Node *node) { switch (gf_node_get_tag(node)) { #ifndef GPAC_DISABLE_VRML case TAG_MPEG4_AnimationStream: compositor_init_animationstream(compositor, node); break; case TAG_MPEG4_AudioBuffer: compositor_init_audiobuffer(compositor, node); break; case TAG_MPEG4_AudioSource: compositor_init_audiosource(compositor, node); break; case TAG_MPEG4_AudioClip: #ifndef GPAC_DISABLE_X3D case TAG_X3D_AudioClip: #endif compositor_init_audioclip(compositor, node); break; case TAG_MPEG4_TimeSensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_TimeSensor: #endif compositor_init_timesensor(compositor, node); break; case TAG_MPEG4_ImageTexture: #ifndef GPAC_DISABLE_X3D case TAG_X3D_ImageTexture: #endif case TAG_MPEG4_CacheTexture: compositor_init_imagetexture(compositor, node); break; case TAG_MPEG4_PixelTexture: #ifndef GPAC_DISABLE_X3D case TAG_X3D_PixelTexture: #endif compositor_init_pixeltexture(compositor, node); break; case TAG_MPEG4_MovieTexture: #ifndef GPAC_DISABLE_X3D case TAG_X3D_MovieTexture: #endif compositor_init_movietexture(compositor, node); break; case TAG_MPEG4_Background2D: compositor_init_background2d(compositor, node); break; case TAG_MPEG4_Bitmap: compositor_init_bitmap(compositor, node); break; case TAG_MPEG4_ColorTransform: compositor_init_colortransform(compositor, node); break; case TAG_MPEG4_Circle: compositor_init_circle(compositor, node); break; case TAG_MPEG4_Curve2D: compositor_init_curve2d(compositor, node); break; case TAG_MPEG4_XCurve2D: compositor_init_curve2d(compositor, node); break; case TAG_MPEG4_Ellipse: compositor_init_ellipse(compositor, node); break; case TAG_MPEG4_OrderedGroup: compositor_init_orderedgroup(compositor, node); break; case TAG_MPEG4_PointSet2D: compositor_init_pointset2d(compositor, node); break; case TAG_MPEG4_Transform2D: compositor_init_transform2d(compositor, node); break; case TAG_MPEG4_TransformMatrix2D: compositor_init_transformmatrix2d(compositor, node); break; case TAG_MPEG4_LineProperties: compositor_init_lineprops(compositor, node); break; case TAG_MPEG4_XLineProperties: compositor_init_lineprops(compositor, node); break; case TAG_MPEG4_Viewport: compositor_init_viewport(compositor, node); break; case TAG_MPEG4_IndexedLineSet2D: compositor_init_indexed_line_set2d(compositor, node); break; case TAG_MPEG4_IndexedFaceSet2D: compositor_init_indexed_face_set2d(compositor, node); break; case TAG_MPEG4_Sound2D: compositor_init_sound2d(compositor, node); break; case TAG_MPEG4_LinearGradient: compositor_init_linear_gradient(compositor, node); break; case TAG_MPEG4_RadialGradient: compositor_init_radial_gradient(compositor, node); break; case TAG_MPEG4_CompositeTexture2D: compositor_init_compositetexture2d(compositor, node); break; case TAG_MPEG4_MatteTexture: compositor_init_mattetexture(compositor, node); break; case TAG_MPEG4_Form: compositor_init_form(compositor, node); break; case TAG_MPEG4_Layer2D: compositor_init_layer2d(compositor, node); break; case TAG_MPEG4_Layout: compositor_init_layout(compositor, node); break; case TAG_MPEG4_PathLayout: compositor_init_path_layout(compositor, node); break; /*sensors*/ case TAG_MPEG4_Anchor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Anchor: #endif compositor_init_anchor(compositor, node); break; case TAG_MPEG4_DiscSensor: compositor_init_disc_sensor(compositor, node); break; case TAG_MPEG4_PlaneSensor2D: compositor_init_plane_sensor2d(compositor, node); break; case TAG_MPEG4_ProximitySensor2D: compositor_init_proximity_sensor2d(compositor, node); break; case TAG_MPEG4_TouchSensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_TouchSensor: #endif compositor_init_touch_sensor(compositor, node); break; case TAG_MPEG4_Group: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Group: #endif compositor_init_group(compositor, node); break; case TAG_MPEG4_Rectangle: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Rectangle2D: #endif compositor_init_rectangle(compositor, node); break; case TAG_MPEG4_Shape: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Shape: #endif compositor_init_shape(compositor, node); break; case TAG_MPEG4_Switch: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Switch: #endif compositor_init_switch(compositor, node); break; case TAG_MPEG4_Text: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Text: #endif compositor_init_text(compositor, node); break; #ifndef GPAC_DISABLE_3D case TAG_MPEG4_Background: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Background: #endif compositor_init_background(compositor, node); break; case TAG_MPEG4_CylinderSensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_CylinderSensor: #endif compositor_init_cylinder_sensor(compositor, node); break; case TAG_MPEG4_PlaneSensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_PlaneSensor: #endif compositor_init_plane_sensor(compositor, node); break; case TAG_MPEG4_ProximitySensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_ProximitySensor: #endif compositor_init_proximity_sensor(compositor, node); break; case TAG_MPEG4_SphereSensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_SphereSensor: #endif compositor_init_sphere_sensor(compositor, node); break; case TAG_MPEG4_VisibilitySensor: #ifndef GPAC_DISABLE_X3D case TAG_X3D_VisibilitySensor: #endif compositor_init_visibility_sensor(compositor, node); break; case TAG_MPEG4_Box: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Box: #endif compositor_init_box(compositor, node); break; case TAG_MPEG4_Cone: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Cone: #endif compositor_init_cone(compositor, node); break; case TAG_MPEG4_Cylinder: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Cylinder: #endif compositor_init_cylinder(compositor, node); break; case TAG_MPEG4_ElevationGrid: #ifndef GPAC_DISABLE_X3D case TAG_X3D_ElevationGrid: #endif compositor_init_elevation_grid(compositor, node); break; case TAG_MPEG4_Extrusion: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Extrusion: #endif compositor_init_extrusion(compositor, node); break; case TAG_MPEG4_IndexedFaceSet: #ifndef GPAC_DISABLE_X3D case TAG_X3D_IndexedFaceSet: #endif compositor_init_ifs(compositor, node); break; case TAG_MPEG4_IndexedLineSet: #ifndef GPAC_DISABLE_X3D case TAG_X3D_IndexedLineSet: #endif compositor_init_ils(compositor, node); break; case TAG_MPEG4_PointSet: #ifndef GPAC_DISABLE_X3D case TAG_X3D_PointSet: #endif compositor_init_point_set(compositor, node); break; case TAG_MPEG4_Sphere: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Sphere: #endif compositor_init_sphere(compositor, node); break; case TAG_MPEG4_Billboard: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Billboard: #endif compositor_init_billboard(compositor, node); break; case TAG_MPEG4_Collision: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Collision: #endif compositor_init_collision(compositor, node); break; case TAG_MPEG4_LOD: #ifndef GPAC_DISABLE_X3D case TAG_X3D_LOD: #endif compositor_init_lod(compositor, node); break; case TAG_MPEG4_Transform: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Transform: #endif compositor_init_transform(compositor, node); break; case TAG_MPEG4_Sound: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Sound: #endif compositor_init_sound(compositor, node); break; case TAG_MPEG4_Viewpoint: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Viewpoint: #endif compositor_init_viewpoint(compositor, node); break; case TAG_MPEG4_NavigationInfo: #ifndef GPAC_DISABLE_X3D case TAG_X3D_NavigationInfo: #endif compositor_init_navigation_info(compositor, node); break; case TAG_MPEG4_Fog: #ifndef GPAC_DISABLE_X3D case TAG_X3D_Fog: #endif compositor_init_fog(compositor, node); break; case TAG_MPEG4_DirectionalLight: #ifndef GPAC_DISABLE_X3D case TAG_X3D_DirectionalLight: #endif compositor_init_directional_light(compositor, node); break; case TAG_MPEG4_PointLight: #ifndef GPAC_DISABLE_X3D case TAG_X3D_PointLight: #endif compositor_init_point_light(compositor, node); break; case TAG_MPEG4_SpotLight: #ifndef GPAC_DISABLE_X3D case TAG_X3D_SpotLight: #endif compositor_init_spot_light(compositor, node); break; case TAG_MPEG4_NonLinearDeformer: compositor_init_non_linear_deformer(compositor, node); break; case TAG_MPEG4_Layer3D: compositor_init_layer3d(compositor, node); break; case TAG_MPEG4_CompositeTexture3D: compositor_init_compositetexture3d(compositor, node); break; case TAG_MPEG4_EnvironmentTest: compositor_init_envtest(compositor, node); break; #endif /*X3D nodes*/ #ifndef GPAC_DISABLE_X3D case TAG_X3D_StaticGroup: compositor_init_static_group(compositor, node); break; case TAG_X3D_Disk2D: compositor_init_disk2d(compositor, node); break; case TAG_X3D_Arc2D: case TAG_X3D_ArcClose2D: compositor_init_arc2d(compositor, node); break; case TAG_X3D_Polyline2D: compositor_init_polyline2d(compositor, node); break; case TAG_X3D_TriangleSet2D: compositor_init_triangle_set2d(compositor, node); break; #ifndef GPAC_DISABLE_3D case TAG_X3D_Polypoint2D: compositor_init_polypoint2d(compositor, node); break; case TAG_X3D_LineSet: compositor_init_lineset(compositor, node); break; case TAG_X3D_TriangleSet: compositor_init_triangle_set(compositor, node); break; case TAG_X3D_TriangleStripSet: compositor_init_triangle_strip_set(compositor, node); break; case TAG_X3D_TriangleFanSet: compositor_init_triangle_fan_set(compositor, node); break; case TAG_X3D_IndexedTriangleFanSet: compositor_init_indexed_triangle_fan_set(compositor, node); break; case TAG_X3D_IndexedTriangleStripSet: compositor_init_indexed_triangle_strip_set(compositor, node); break; case TAG_X3D_IndexedTriangleSet: compositor_init_indexed_triangle_set(compositor, node); break; #endif #endif /*GPAC_DISABLE_X3D*/ case TAG_ProtoNode: compositor_init_hardcoded_proto(compositor, node); break; case TAG_MPEG4_SBVCAnimation: compositor_init_afx_node(compositor, node, & ((M_SBVCAnimation *)node)->url); break; case TAG_MPEG4_BitWrapper: compositor_init_afx_node(compositor, node, & ((M_BitWrapper *)node)->url); break; #endif /*GPAC_DISABLE_VRML*/ #ifndef GPAC_DISABLE_SVG /* SVG Part */ case TAG_SVG_svg: compositor_init_svg_svg(compositor, node); break; case TAG_SVG_g: compositor_init_svg_g(compositor, node); break; case TAG_SVG_switch: compositor_init_svg_switch(compositor, node); break; case TAG_SVG_rect: compositor_init_svg_rect(compositor, node); break; case TAG_SVG_path: compositor_init_svg_path(compositor, node); break; case TAG_SVG_circle: compositor_init_svg_circle(compositor, node); break; case TAG_SVG_ellipse: compositor_init_svg_ellipse(compositor, node); break; case TAG_SVG_line: compositor_init_svg_line(compositor, node); break; case TAG_SVG_polyline: compositor_init_svg_polyline(compositor, node); break; case TAG_SVG_polygon: compositor_init_svg_polygon(compositor, node); break; case TAG_SVG_a: compositor_init_svg_a(compositor, node); break; case TAG_SVG_linearGradient: compositor_init_svg_linearGradient(compositor, node); break; case TAG_SVG_radialGradient: compositor_init_svg_radialGradient(compositor, node); break; case TAG_SVG_solidColor: compositor_init_svg_solidColor(compositor, node); break; case TAG_SVG_stop: compositor_init_svg_stop(compositor, node); break; case TAG_SVG_text: compositor_init_svg_text(compositor, node); break; case TAG_SVG_tspan: compositor_init_svg_tspan(compositor, node); break; case TAG_SVG_textArea: compositor_init_svg_textarea(compositor, node); break; case TAG_SVG_tbreak: compositor_init_svg_tbreak(compositor, node); break; case TAG_SVG_image: compositor_init_svg_image(compositor, node); break; case TAG_SVG_video: compositor_init_svg_video(compositor, node); break; case TAG_SVG_audio: compositor_init_svg_audio(compositor, node, 0); break; /*SVG font support - note that we initialize the font when parsing the font-face element, not the font element*/ case TAG_SVG_font_face: compositor_init_svg_font(compositor, node); break; case TAG_SVG_missing_glyph: case TAG_SVG_glyph: compositor_init_svg_glyph(compositor, node); break; case TAG_SVG_font_face_uri: compositor_init_svg_font_face_uri(compositor, node); break; case TAG_SVG_use: compositor_init_svg_use(compositor, node); break; case TAG_SVG_animation: compositor_init_svg_animation(compositor, node); break; case TAG_SVG_foreignObject: compositor_init_svg_foreign_object(compositor, node); break; case TAG_SVG_filter: compositor_init_svg_filter(compositor, node); break; case TAG_LSR_updates: compositor_init_svg_updates(compositor, node); break; #endif default: GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] node %s will not be rendered\n", gf_node_get_class_name(node))); break; } }
void compositor_init_afx_node(GF_Compositor *compositor, GF_Node *node, MFURL *url) { GF_MediaObject *mo = gf_mo_register(node, url, 0, 0); if (!mo) { GF_LOG(GF_LOG_WARNING, GF_LOG_COMPOSE, ("[Compositor] AFX Decoder not found for node %s - node may not be completely/correctly rendered\n", gf_node_get_class_name(node))); } #ifndef GPAC_DISABLE_VRML if (gf_node_get_tag(node)==TAG_MPEG4_BitWrapper) { compositor_init_bitwrapper(compositor, node); } #endif }
static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy) { GF_List *oldb, *oldv; GF_Node *viewport; GF_Node *back; Bool prev_layer; GF_Matrix2D backup; SFVec2f prev_vp; #ifndef GPAC_DISABLE_3D GF_Matrix mx3d; GF_List *oldf, *oldn; GF_List *node_list_backup; GF_Rect prev_clipper; Bool had_clip; #endif M_Layer2D *l = (M_Layer2D *)node; Layer2DStack *st = (Layer2DStack *) gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { gf_list_del(st->backs); gf_list_del(st->views); group_2d_destroy(node, (GroupingNode2D*)st); gf_free(st); return; } /*layers can only be used in a 2D context*/ #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d && tr_state->camera->is_3D) return; #endif /*layer2D maintains its own stacks*/ oldb = tr_state->backgrounds; oldv = tr_state->viewpoints; tr_state->backgrounds = st->backs; tr_state->viewpoints = st->views; prev_layer = tr_state->is_layer; tr_state->is_layer = 1; #ifndef GPAC_DISABLE_3D oldf = tr_state->fogs; oldn = tr_state->navigations; tr_state->fogs = tr_state->navigations = NULL; #endif l2d_CheckBindables(node, tr_state, st->first); back = (GF_Node*)gf_list_get(st->backs, 0); viewport = (GF_Node*)gf_list_get(st->views, 0); if ((tr_state->traversing_mode == TRAVERSE_SORT) || (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS)) { /*override group bounds*/ visual_get_size_info(tr_state, &st->clip.width, &st->clip.height); /*setup bounds in local coord system*/ if (l->size.x>=0) st->clip.width = l->size.x; if (l->size.y>=0) st->clip.height = l->size.y; st->clip = gf_rect_center(st->clip.width, st->clip.height); st->bounds = st->clip; } prev_vp = tr_state->vp_size; tr_state->vp_size.x = st->clip.width; tr_state->vp_size.y = st->clip.height; switch (tr_state->traversing_mode) { case TRAVERSE_SORT: #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { tr_state->layer_clipper = compositor_2d_update_clipper(tr_state, st->clip, &had_clip, &prev_clipper, 1); visual_3d_matrix_push(tr_state->visual); gf_mx_copy(mx3d, tr_state->model_matrix); /*setup clipping*/ visual_3d_set_clipper_2d(tr_state->visual, tr_state->layer_clipper); /*apply background BEFORE viewport*/ if (back) { tr_state->traversing_mode = TRAVERSE_BINDABLE; gf_bbox_from_rect(&tr_state->bbox, &st->clip); gf_node_traverse(back, tr_state); } /*sort all children without transform, and use current transform when flushing contexts*/ gf_mx_init(tr_state->model_matrix); /*apply viewport*/ if (viewport) { tr_state->traversing_mode = TRAVERSE_BINDABLE; tr_state->bounds = st->clip; gf_node_traverse(viewport, tr_state); visual_3d_matrix_add(tr_state->visual, tr_state->model_matrix.m); } node_list_backup = tr_state->visual->alpha_nodes_to_draw; tr_state->visual->alpha_nodes_to_draw = gf_list_new(); tr_state->traversing_mode = TRAVERSE_SORT; /*reset cull flag*/ tr_state->cull_flag = 0; group_2d_traverse(node, (GroupingNode2D *)st, tr_state); visual_3d_flush_contexts(tr_state->visual, tr_state); tr_state->traversing_mode = TRAVERSE_SORT; assert(!gf_list_count(tr_state->visual->alpha_nodes_to_draw)); gf_list_del(tr_state->visual->alpha_nodes_to_draw); tr_state->visual->alpha_nodes_to_draw = node_list_backup; visual_3d_matrix_pop(tr_state->visual); gf_mx_copy(tr_state->model_matrix, mx3d); visual_3d_reset_clipper_2d(tr_state->visual); tr_state->has_layer_clip = had_clip; if (had_clip) { tr_state->layer_clipper = prev_clipper; visual_3d_set_clipper_2d(tr_state->visual, tr_state->layer_clipper); } } else #endif { GF_IRect prev_clip; GF_Rect rc; gf_mx2d_copy(backup, tr_state->transform); prev_clip = tr_state->visual->top_clipper; rc = st->clip; /*get clipper in world coordinate*/ gf_mx2d_apply_rect(&tr_state->transform, &rc); if (viewport) { tr_state->traversing_mode = TRAVERSE_BINDABLE; tr_state->bounds = st->clip; gf_node_traverse(viewport, tr_state); #if VIEWPORT_CLIPS /*move viewport box in world coordinate*/ gf_mx2d_apply_rect(&backup, &tr_state->bounds); /*and intersect with layer clipper*/ rect_intersect(&rc, &tr_state->bounds); #endif } tr_state->visual->top_clipper = gf_rect_pixelize(&rc); gf_irect_intersect(&tr_state->visual->top_clipper, &prev_clip); tr_state->traversing_mode = TRAVERSE_SORT; if (tr_state->visual->top_clipper.width && tr_state->visual->top_clipper.height) { if (back && Bindable_GetIsBound(back) ) { DrawableContext *ctx; ctx = b2d_get_context((M_Background2D*) back, st->backs); gf_mx2d_init(ctx->transform); ctx->bi->clip = tr_state->visual->top_clipper; ctx->bi->unclip = rc; if (tr_state->immediate_draw) { tr_state->ctx = ctx; tr_state->traversing_mode = TRAVERSE_DRAW_2D; gf_node_traverse(back, tr_state); tr_state->traversing_mode = TRAVERSE_SORT; tr_state->ctx = NULL; } else { DrawableContext *back_ctx = visual_2d_get_drawable_context(tr_state->visual); gf_node_traverse(back, tr_state); back_ctx->flags = ctx->flags; back_ctx->flags &= ~CTX_IS_TRANSPARENT; back_ctx->flags |= CTX_IS_BACKGROUND; back_ctx->aspect = ctx->aspect; back_ctx->drawable = ctx->drawable; drawable_check_bounds(back_ctx, tr_state->visual); back_ctx->bi->clip = ctx->bi->clip; back_ctx->bi->unclip = ctx->bi->unclip; } /*keep track of node drawn*/ if (!(ctx->drawable->flags & DRAWABLE_REGISTERED_WITH_VISUAL) ) { struct _drawable_store *it; GF_SAFEALLOC(it, struct _drawable_store); it->drawable = ctx->drawable; if (tr_state->visual->last_prev_entry) { tr_state->visual->last_prev_entry->next = it; tr_state->visual->last_prev_entry = it; } else { tr_state->visual->prev_nodes = tr_state->visual->last_prev_entry = it; } GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer2D] Registering new drawn node %s on visual\n", gf_node_get_class_name(it->drawable->node))); ctx->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL; } } group_2d_traverse(node, (GroupingNode2D *)st, tr_state); } tr_state->visual->top_clipper = prev_clip; gf_mx2d_copy(tr_state->transform, backup); } break; /*check picking - we must fall in our 2D clipper*/ case TRAVERSE_PICK: if (gf_sc_pick_in_clipper(tr_state, &st->clip)) { #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { /*apply viewport*/ if (viewport) { gf_mx_copy(mx3d, tr_state->model_matrix); tr_state->traversing_mode = TRAVERSE_BINDABLE; tr_state->bounds = st->clip; gf_node_traverse(viewport, tr_state); tr_state->traversing_mode = TRAVERSE_PICK; group_2d_traverse(node, (GroupingNode2D *)st, tr_state); gf_mx_copy(tr_state->model_matrix, mx3d); } else { group_2d_traverse(node, (GroupingNode2D *)st, tr_state); } } else #endif { if (viewport) { gf_mx2d_copy(backup, tr_state->transform); tr_state->traversing_mode = TRAVERSE_BINDABLE; tr_state->bounds = st->clip; gf_node_traverse(viewport, tr_state); tr_state->traversing_mode = TRAVERSE_PICK; group_2d_traverse(node, (GroupingNode2D *)st, tr_state); gf_mx2d_copy(tr_state->transform, backup); } else { group_2d_traverse(node, (GroupingNode2D *)st, tr_state); } } } break; case TRAVERSE_GET_BOUNDS: if (tr_state->for_node) { group_2d_traverse(node, (GroupingNode2D *)st, tr_state); } else { tr_state->bounds = st->clip; #ifndef GPAC_DISABLE_3D gf_bbox_from_rect(&tr_state->bbox, &st->clip); #endif } break; case TRAVERSE_DRAW_2D: group_2d_traverse(node, (GroupingNode2D *)st, tr_state); break; #ifndef GPAC_DISABLE_3D /*drawing a layer means drawing all sub-elements as a whole (no depth sorting with parents)*/ case TRAVERSE_DRAW_3D: assert(0); break; #endif } /*restore traversing state*/ tr_state->vp_size = prev_vp; tr_state->backgrounds = oldb; tr_state->viewpoints = oldv; tr_state->is_layer = prev_layer; #ifndef GPAC_DISABLE_3D tr_state->fogs = oldf; tr_state->navigations = oldn; #endif /*in case we missed bindables*/ if (st->first) { st->first = 0; gf_sc_invalidate(tr_state->visual->compositor, NULL); } }
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes) { u32 i; SVG_SANI_BIFS_Converter *converter = (SVG_SANI_BIFS_Converter *)sax_cbck; SVGPropertiesPointers *backup_props; char *id_string = NULL; u32 tag = gf_svg_get_element_tag(name); SVG_Element *elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag); if (!gf_sg_get_root_node(converter->svg_sg)) { gf_node_register((GF_Node *)elt, NULL); gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt); } else { gf_node_register((GF_Node *)elt, converter->svg_parent); //gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt); } converter->svg_parent = (GF_Node *)elt; // fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt)); // if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent)); for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!stricmp(att->name, "style")) { gf_svg_parse_style((GF_Node *)elt, att->value); } else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) { gf_svg_parse_element_id((GF_Node *)elt, att->value, 0); id_string = att->value; } else { GF_FieldInfo info; if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) { gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0); } else { fprintf(stdout, "Skipping attribute %s\n", att->name); } } } memset(&converter->all_atts, 0, sizeof(SVGAllAttributes)); gf_svg_flatten_attributes(elt, &converter->all_atts); backup_props = gf_malloc(sizeof(SVGPropertiesPointers)); memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers)); gf_node_set_private((GF_Node *)elt, backup_props); gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props); if (!gf_sg_get_root_node(converter->bifs_sg)) { if (tag == TAG_SVG_svg) { GF_Node *node, *child; converter->bifs_sg->usePixelMetrics = 1; if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) { converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value); } else { converter->bifs_sg->width = 320; } if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) { converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value); } else { converter->bifs_sg->height = 200; } node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup); gf_node_register(node, NULL); gf_sg_set_root_node(converter->bifs_sg, node); /* SVG to BIFS coordinate transformation */ child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); if (converter->all_atts.viewBox) { M_Viewport *vp = (M_Viewport*)child; vp->size.x = converter->all_atts.viewBox->width; vp->size.y = converter->all_atts.viewBox->height; vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2; vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2); } else { M_Viewport *vp = (M_Viewport*)child; vp->size.x = INT2FIX(converter->bifs_sg->width); vp->size.y = INT2FIX(converter->bifs_sg->height); vp->position.x = INT2FIX(converter->bifs_sg->width)/2; vp->position.y = -INT2FIX(converter->bifs_sg->height)/2; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Background2D *b = (M_Background2D *)child; b->backColor.red = FIX_ONE; b->backColor.green = FIX_ONE; b->backColor.blue = FIX_ONE; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; { M_Transform2D *tr = (M_Transform2D *)node; tr->scale.y = -FIX_ONE; } converter->bifs_parent = node; } } else { GF_Node *node, *child; node = converter->bifs_parent; switch(tag) { case TAG_SVG_g: { if (converter->all_atts.transform) { node = add_transform(converter, node); converter->bifs_parent = node; } else { M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group); gf_node_register((GF_Node *)g, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g); node = (GF_Node *)g; converter->bifs_parent = node; } } break; case TAG_SVG_rect: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->all_atts.x || converter->all_atts.y) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } { M_Transform2D *tr = (M_Transform2D *)node; if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0); if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0); } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle); gf_node_register(shape->geometry, (GF_Node *)shape); { M_Rectangle *rect = (M_Rectangle *)shape->geometry; if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value; if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value; } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_path: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->all_atts.x || converter->all_atts.y) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } { M_Transform2D *tr = (M_Transform2D *)node; if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value; if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D); gf_node_register(shape->geometry, (GF_Node *)shape); if (converter->all_atts.d) { M_Coordinate2D *c2d; M_XCurve2D *xc = (M_XCurve2D *)shape->geometry; u32 i, j, c; xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)xc->point; gf_node_register(xc->point, (GF_Node *)xc); gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points); j= 0; for (i = 0; i < converter->all_atts.d->n_points; i++) { if (converter->all_atts.d->tags[i] != GF_PATH_CLOSE || i == converter->all_atts.d->n_points-1) { c2d->point.vals[j] = converter->all_atts.d->points[i]; j++; } } c2d->point.count = j; gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points); c = 0; j = 0; xc->type.vals[0] = 0; for (i = 1; i < converter->all_atts.d->n_points; i++) { switch(converter->all_atts.d->tags[i]) { case GF_PATH_CURVE_ON: if (c < converter->all_atts.d->n_contours && i-1 == converter->all_atts.d->contours[c]) { xc->type.vals[j] = 0; c++; } else { xc->type.vals[j] = 1; } break; case GF_PATH_CURVE_CUBIC: xc->type.vals[j] = 2; i+=2; break; case GF_PATH_CLOSE: xc->type.vals[j] = 6; break; case GF_PATH_CURVE_CONIC: xc->type.vals[j] = 7; i++; break; } j++; } xc->type.count = j; } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_polyline: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform(converter, node); converter->bifs_parent = node; is_parent_set = 1; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D); gf_node_register(shape->geometry, (GF_Node *)shape); if (converter->all_atts.points) { M_Coordinate2D *c2d; M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry; u32 i; ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)ifs->coord; gf_node_register(ifs->coord, (GF_Node *)ifs); gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points)); for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) { SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i); c2d->point.vals[i].x = p->x; c2d->point.vals[i].y = p->y; } } shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_text: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform(converter, node); converter->bifs_parent = node; is_parent_set = 1; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Transform2D *tr = (M_Transform2D *)child; if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value; if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value; tr->scale.y = -FIX_ONE; } node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_FontStyle *fs; M_Text *text; M_Shape *shape = (M_Shape *)node; text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text); shape->geometry = (GF_Node *)text; converter->bifs_text_node = shape->geometry; gf_node_register(shape->geometry, (GF_Node *)shape); fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle); gf_node_register((GF_Node *)fs, (GF_Node*)text); text->fontStyle = (GF_Node *)fs; gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1); fs->family.vals[0] = strdup(converter->svg_props.font_family->value); fs->size = converter->svg_props.font_size->value; shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_ellipse: case TAG_SVG_circle: { Bool is_parent_set = 0; if (converter->all_atts.transform) { node = add_transform(converter, node); converter->bifs_parent = node; is_parent_set = 1; } if (converter->all_atts.cx || converter->all_atts.cy) { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); { M_Transform2D *tr = (M_Transform2D *)child; if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value; if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value; } node = child; child = NULL; if (!is_parent_set) { converter->bifs_parent = node; is_parent_set = 1; } } child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; if (!is_parent_set) converter->bifs_parent = node; { M_Shape *shape = (M_Shape *)node; if (tag == TAG_SVG_ellipse) { M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse); shape->geometry = (GF_Node *)e; e->radius.x = converter->all_atts.rx->value; e->radius.y = converter->all_atts.ry->value; } else { M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle); shape->geometry = (GF_Node *)c; c->radius = converter->all_atts.r->value; } gf_node_register(shape->geometry, (GF_Node *)shape); shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); gf_node_register(shape->appearance, (GF_Node *)shape); } } break; case TAG_SVG_defs: { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; { M_Switch *sw = (M_Switch *)node; sw->whichChoice = -1; } converter->bifs_parent = node; } break; case TAG_SVG_solidColor: { child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; converter->bifs_parent = node; } break; default: { fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt)); child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D); gf_node_register(child, node); gf_node_list_add_child(&((GF_ParentNode*)node)->children, child); node = child; child = NULL; converter->bifs_parent = node; } break; } if (id_string) gf_node_set_id(converter->bifs_parent, gf_node_get_id((GF_Node *)elt), gf_node_get_name((GF_Node *)elt)); } }
void V4StudioTree::AddNodesToItem(wxTreeItemId parentItemId, GF_Node * node, s32 fieldIndex, s32 position) { GF_FieldInfo field; u32 count, i, j; char *name; if (!node) return; // displays the name and the defname it exists u32 s = strlen(gf_node_get_class_name(node)); if (gf_node_get_name(node)) { s += strlen(gf_node_get_name(node)); name = new char[s+4]; strcpy(name, gf_node_get_class_name(node)); strcat(name, " - "); strcat(name, gf_node_get_name(node)); } else { name = new char[s+1]; strcpy(name, gf_node_get_class_name(node)); } GF_Node * parent = NULL; V4StudioTreeItemData *parentItemData = (V4StudioTreeItemData *)GetItemData(parentItemId); if (parentItemData != NULL) parent = parentItemData->GetNode(); V4StudioTreeItemData * currentItemData = new V4StudioTreeItemData(node, parent, fieldIndex, position); wxTreeItemId nodeItemId; if (position == -1) nodeItemId = AppendItem(parentItemId, wxString(name), -1, -1, currentItemData); else nodeItemId = InsertItem(parentItemId, position, wxString(name), -1, -1, currentItemData); delete [] name; name = NULL; count = gf_node_get_field_count(node); for (i=0;i<count; i++) { gf_node_get_field(node, i, &field); if (field.eventType == GF_SG_EVENT_IN || field.eventType == GF_SG_EVENT_OUT) continue; switch (field.fieldType) { case GF_SG_VRML_SFNODE: if (* (GF_Node **) field.far_ptr) { AddNodesToItem(nodeItemId, * (GF_Node **) field.far_ptr, i, -1); } break; case GF_SG_VRML_MFNODE: { GF_List *nodes = (* (GF_List **) field.far_ptr); // list of children u32 nbNodes = gf_list_count(nodes); u8 skipped = 0; // counts nodes not added for (j=0; j< nbNodes; j++) { // gets a pointer to the current child GF_Node *child = (GF_Node *)gf_list_get(nodes, j); // prevents the dictionnary from being added to the graph const char * c = gf_node_get_name(child); if ( (c != NULL) && !strcmp(c,DICTNAME) ) { skipped++; continue; } // recursively adds children AddNodesToItem(nodeItemId, child, i, j-skipped); } } break; default: break; } } Expand(nodeItemId); }
Bool visual_2d_draw_frame(GF_VisualManager *visual, GF_Node *root, GF_TraverseState *tr_state, Bool is_root_visual) { GF_SceneGraph *sg; GF_Matrix2D backup; u32 i; Bool res; GF_Err e; #ifndef GPAC_DISABLE_LOG u32 itime, time = gf_sys_clock(); #endif gf_mx2d_copy(backup, tr_state->transform); visual->bounds_tracker_modif_flag = DRAWABLE_HAS_CHANGED; e = visual_2d_init_draw(visual, tr_state); if (e) { gf_mx2d_copy(tr_state->transform, backup); GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Visual2D] Cannot init draw phase: %s\n", gf_error_to_string(e))); return 0; } #ifndef GPAC_DISABLE_LOG itime = gf_sys_clock(); visual->compositor->traverse_setup_time = itime - time; time = itime; #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Traversing scene subtree (root node %s)\n", root ? gf_node_get_class_name(root) : "none")); if (is_root_visual) { gf_node_traverse(root, tr_state); i=0; while ((sg = (GF_SceneGraph*)gf_list_enum(visual->compositor->extra_scenes, &i))) { gf_sc_traverse_subscene(visual->compositor, root, sg, tr_state); } } else { gf_node_traverse(root, tr_state); } #ifndef GPAC_DISABLE_LOG itime = gf_sys_clock(); visual->compositor->traverse_and_direct_draw_time = itime - time; time = itime; #endif gf_mx2d_copy(tr_state->transform, backup); res = visual_2d_terminate_draw(visual, tr_state); #ifndef GPAC_DISABLE_LOG if (!tr_state->immediate_draw) { visual->compositor->indirect_draw_time = gf_sys_clock() - time; } #endif return res; }
void svg_drawable_3d_pick(Drawable *drawable, GF_TraverseState *tr_state, DrawAspect2D *asp) { SFVec3f local_pt, world_pt, vdiff; SFVec3f hit_normal; SFVec2f text_coords; u32 i, count; Fixed sqdist; Bool node_is_over; GF_Compositor *compositor; GF_Matrix mx; GF_Ray r; compositor = tr_state->visual->compositor; node_is_over = 0; r = tr_state->ray; gf_mx_copy(mx, tr_state->model_matrix); gf_mx_inverse(&mx); gf_mx_apply_ray(&mx, &r); /*if we already have a hit point don't check anything below...*/ if (compositor->hit_square_dist && !compositor->grabbed_sensor && !tr_state->layer3d) { GF_Plane p; GF_BBox box; SFVec3f hit = compositor->hit_world_point; gf_mx_apply_vec(&mx, &hit); p.normal = r.dir; p.d = -1 * gf_vec_dot(p.normal, hit); gf_bbox_from_rect(&box, &drawable->path->bbox); if (gf_bbox_plane_relation(&box, &p) == GF_BBOX_FRONT) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] bounding box of node %s (DEF %s) below current hit point - skipping\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node))); return; } } node_is_over = 0; if (compositor_get_2d_plane_intersection(&r, &local_pt)) { node_is_over = svg_drawable_is_over(drawable, local_pt.x, local_pt.y, asp, tr_state, NULL); } if (!node_is_over) return; hit_normal.x = hit_normal.y = 0; hit_normal.z = FIX_ONE; text_coords.x = gf_divfix(local_pt.x, drawable->path->bbox.width) + FIX_ONE/2; text_coords.y = gf_divfix(local_pt.y, drawable->path->bbox.height) + FIX_ONE/2; /*check distance from user and keep the closest hitpoint*/ world_pt = local_pt; gf_mx_apply_vec(&tr_state->model_matrix, &world_pt); for (i=0; i<tr_state->num_clip_planes; i++) { if (gf_plane_get_distance(&tr_state->clip_planes[i], &world_pt) < 0) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is not in clipper half space\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node))); return; } } gf_vec_diff(vdiff, world_pt, tr_state->ray.orig); sqdist = gf_vec_lensq(vdiff); if (compositor->hit_square_dist && (compositor->hit_square_dist+FIX_EPSILON<sqdist)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is farther (%g) than current pick (%g)\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node), FIX2FLT(sqdist), FIX2FLT(compositor->hit_square_dist))); return; } compositor->hit_square_dist = sqdist; /*also stack any VRML sensors present at the current level. If the event is not catched by a listener in the SVG tree, the event will be forwarded to the VRML tree*/ gf_list_reset(compositor->sensors); count = gf_list_count(tr_state->vrml_sensors); for (i=0; i<count; i++) { gf_list_add(compositor->sensors, gf_list_get(tr_state->vrml_sensors, i)); } gf_mx_copy(compositor->hit_world_to_local, tr_state->model_matrix); gf_mx_copy(compositor->hit_local_to_world, mx); compositor->hit_local_point = local_pt; compositor->hit_world_point = world_pt; compositor->hit_world_ray = tr_state->ray; compositor->hit_normal = hit_normal; compositor->hit_texcoords = text_coords; svg_clone_use_stack(compositor, tr_state); /*not use in SVG patterns*/ compositor->hit_appear = NULL; compositor->hit_node = drawable->node; compositor->hit_text = NULL; compositor->hit_use_dom_events = 1; GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is under mouse - hit %g %g %g\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node), FIX2FLT(world_pt.x), FIX2FLT(world_pt.y), FIX2FLT(world_pt.z))); }
static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_STENCIL stencil, GF_TraverseState *tr_state) { GF_IRect clip; GF_Raster2D *raster = visual->compositor->rasterizer; /*background & direct drawing : use ctx clip*/ if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) { if (ctx->bi->clip.width && ctx->bi->clip.height) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (direct draw)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node) )); if (stencil) { raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip); raster->surface_fill(visual->raster_surface, stencil); } else { raster->surface_clear(visual->raster_surface, &ctx->bi->clip, 0); } visual->has_modif = 1; } } /*indirect drawing, draw path in all dirty areas*/ else { u32 i; for (i=0; i<visual->to_redraw.count; i++) { /*there's an opaque region above, don't draw*/ #ifdef TRACK_OPAQUE_REGIONS if (visual->draw_node_index<visual->to_redraw.opaque_node_index[i]) continue; #endif clip = ctx->bi->clip; gf_irect_intersect(&clip, &visual->to_redraw.list[i]); if (clip.width && clip.height) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node), i)); if (stencil) { raster->surface_set_clipper(visual->raster_surface, &clip); raster->surface_fill(visual->raster_surface, stencil); } else { raster->surface_clear(visual->raster_surface, &clip, 0); } visual->has_modif = 1; } } } }