📄 drawable.c
字号:
}void R2D_LinePropsRemoved(Render2D *sr, GF_Node *n){ StrikeInfo2D *si, *cur, *prev; u32 i = 0; while ((si = (StrikeInfo2D*)gf_list_enum(sr->strike_bank, &i))) { if (si->lineProps == n) { /*remove from node*/ if (si->node) { Drawable *st = (Drawable *) gf_node_get_private(si->node); /*yerk this is ugly, but text is not a regular drawable and adding a fct just to get the drawable would be just pain*/ if (gf_node_get_tag(si->node)==TAG_MPEG4_Text) st = ((TextStack2D*)st)->graph; assert(st && st->outline); cur = st->outline; prev = NULL; while (cur) { if (cur!=si) { prev = cur; cur = cur->next; continue; } if (prev) prev->next = cur->next; else st->outline = cur->next; break; } } i--; gf_list_rem(sr->strike_bank, i); delete_strikeinfo2d(si); } }}static void DestroyLineProps(GF_Node *n, void *rs, Bool is_destroy){ if (is_destroy) { LinePropStack *st = (LinePropStack *)gf_node_get_private(n); R2D_LinePropsRemoved(st->sr, n); free(st); }}void R2D_InitLineProps(Render2D *sr, GF_Node *node){ LinePropStack *st = (LinePropStack *)malloc(sizeof(LinePropStack)); st->sr = sr; st->last_mod_time = 1; gf_node_set_private(node, st); gf_node_set_callback_function(node, DestroyLineProps);}u32 R2D_LP_GetLastUpdateTime(GF_Node *node){ LinePropStack *st = (LinePropStack *)gf_node_get_private(node); if (!st) return 0; if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { st->last_mod_time ++; gf_node_dirty_clear(node, 0); } return st->last_mod_time;}#ifndef GPAC_DISABLE_SVG#if 0static GF_Node *svg_get_texture_target(GF_Node *node, DOM_String uri){ GF_Node *target = NULL; if (uri[0]=='#') target = gf_sg_find_node_by_name(gf_node_get_graph(node), uri+1); return target;}#endifstatic void setup_svg_drawable_context(DrawableContext *ctx, struct _visual_surface_2D *surf, SVGPropertiesPointers *props){ Fixed clamped_solid_opacity = FIX_ONE; Fixed clamped_fill_opacity = (props->fill_opacity->value < 0 ? 0 : (props->fill_opacity->value > FIX_ONE ? FIX_ONE : props->fill_opacity->value)); Fixed clamped_stroke_opacity = (props->stroke_opacity->value < 0 ? 0 : (props->stroke_opacity->value > FIX_ONE ? FIX_ONE : props->stroke_opacity->value)); ctx->aspect.fill_color = 0; if (props->fill->type==SVG_PAINT_URI) { if (props->fill->iri.type != XMLRI_ELEMENTID) { /* trying to resolve the IRI to the Paint Server */ XMLRI *iri = &props->fill->iri; GF_SceneGraph *sg = gf_node_get_graph(ctx->drawable->node); GF_Node *n = gf_sg_find_node_by_name(sg, &(iri->string[1])); if (n) { iri->type = XMLRI_ELEMENTID; iri->target = n; gf_svg_register_iri(sg, iri); free(iri->string); iri->string = NULL; } } /* If paint server not found, paint is equivalent to none */ if (props->fill->iri.type == XMLRI_ELEMENTID) { switch (gf_node_get_tag((GF_Node *)props->fill->iri.target)) { case TAG_SVG_solidColor: { SVGAllAttributes all_atts; gf_svg_flatten_attributes((SVG_Element*)props->fill->iri.target, &all_atts); if (all_atts.solid_color) { if (all_atts.solid_opacity) { Fixed val = all_atts.solid_opacity->value; clamped_solid_opacity = MIN(FIX_ONE, MAX(0, val) ); } ctx->aspect.fill_color = GF_COL_ARGB_FIXED(clamped_solid_opacity, all_atts.solid_color->color.red, all_atts.solid_color->color.green, all_atts.solid_color->color.blue); } } break; case TAG_SVG_linearGradient: case TAG_SVG_radialGradient: ctx->h_texture = svg_gradient_get_texture((GF_Node *)props->fill->iri.target); break;#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_solidColor: { SVG_SA_solidColorElement *solidColorElt = (SVG_SA_solidColorElement *)props->fill->iri.target; clamped_solid_opacity = (solidColorElt->properties->solid_opacity.value < 0 ? 0 : (solidColorElt->properties->solid_opacity.value > FIX_ONE ? FIX_ONE : solidColorElt->properties->solid_opacity.value)); ctx->aspect.fill_color = GF_COL_ARGB_FIXED(clamped_solid_opacity, solidColorElt->properties->solid_color.color.red, solidColorElt->properties->solid_color.color.green, solidColorElt->properties->solid_color.color.blue); } break; case TAG_SVG_SA_linearGradient: case TAG_SVG_SA_radialGradient: ctx->h_texture = svg_sa_gradient_get_texture((GF_Node *)props->fill->iri.target); break;#endif /*FIXME*/ default: break; } } } else if (props->fill->type == SVG_PAINT_COLOR) { if (props->fill->color.type == SVG_COLOR_CURRENTCOLOR) { ctx->aspect.fill_color = GF_COL_ARGB_FIXED(clamped_fill_opacity, props->color->color.red, props->color->color.green, props->color->color.blue); } else if (props->fill->color.type == SVG_COLOR_RGBCOLOR) { ctx->aspect.fill_color = GF_COL_ARGB_FIXED(clamped_fill_opacity, props->fill->color.red, props->fill->color.green, props->fill->color.blue); } else if (props->fill->color.type >= SVG_COLOR_ACTIVE_BORDER) { ctx->aspect.fill_color = surf->render->compositor->sys_colors[props->fill->color.type - 3]; ctx->aspect.fill_color |= ((u32) (clamped_fill_opacity*255) ) << 24; } } if (*props->fill_rule == SVG_FILLRULE_NONZERO) { ctx->drawable->path->flags |= GF_PATH_FILL_ZERO_NONZERO; } else { ctx->drawable->path->flags &= ~GF_PATH_FILL_ZERO_NONZERO; } ctx->aspect.line_color = 0; ctx->aspect.pen_props.width = (props->stroke->type != SVG_PAINT_NONE) ? props->stroke_width->value : 0; if (props->stroke->type==SVG_PAINT_URI) { if (props->stroke->iri.type != XMLRI_ELEMENTID) { /* trying to resolve the IRI to the Paint Server */ XMLRI *iri = &props->stroke->iri; GF_SceneGraph *sg = gf_node_get_graph(ctx->drawable->node); GF_Node *n = gf_sg_find_node_by_name(sg, &(iri->string[1])); if (n) { iri->type = XMLRI_ELEMENTID; iri->target = n; gf_svg_register_iri(sg, iri); free(iri->string); iri->string = NULL; } } /* Paint server not found, stroke is equivalent to none */ if (props->stroke->iri.type == XMLRI_ELEMENTID) { switch (gf_node_get_tag((GF_Node *)props->stroke->iri.target)) { case TAG_SVG_solidColor: { SVGAllAttributes all_atts; gf_svg_flatten_attributes((SVG_Element*)props->stroke->iri.target, &all_atts); if (all_atts.solid_color) { if (all_atts.solid_opacity) { Fixed val = all_atts.solid_opacity->value; clamped_solid_opacity = MIN(FIX_ONE, MAX(0, val) ); } ctx->aspect.line_color = GF_COL_ARGB_FIXED(clamped_solid_opacity, all_atts.solid_color->color.red, all_atts.solid_color->color.green, all_atts.solid_color->color.blue); } } break;#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_solidColor: { SVG_SA_solidColorElement *solidColorElt = (SVG_SA_solidColorElement *)props->stroke->iri.target; clamped_solid_opacity = (solidColorElt->properties->solid_opacity.value < 0 ? 0 : (solidColorElt->properties->solid_opacity.value > FIX_ONE ? FIX_ONE : solidColorElt->properties->solid_opacity.value)); ctx->aspect.line_color = GF_COL_ARGB_FIXED(clamped_solid_opacity, solidColorElt->properties->solid_color.color.red, solidColorElt->properties->solid_color.color.green, solidColorElt->properties->solid_color.color.blue); } break; case TAG_SVG_SA_linearGradient: case TAG_SVG_SA_radialGradient: ctx->aspect.line_texture = svg_sa_gradient_get_texture((GF_Node*)props->stroke->iri.target); break;#endif default: break; } } } else if (props->stroke->type == SVG_PAINT_COLOR) { if (props->stroke->color.type == SVG_COLOR_CURRENTCOLOR) { ctx->aspect.line_color = GF_COL_ARGB_FIXED(clamped_stroke_opacity, props->color->color.red, props->color->color.green, props->color->color.blue); } else if (props->stroke->color.type == SVG_COLOR_RGBCOLOR) { ctx->aspect.line_color = GF_COL_ARGB_FIXED(clamped_stroke_opacity, props->stroke->color.red, props->stroke->color.green, props->stroke->color.blue); } else if (props->stroke->color.type >= SVG_COLOR_ACTIVE_BORDER) { ctx->aspect.line_color = surf->render->compositor->sys_colors[SVG_COLOR_ACTIVE_BORDER - 3]; ctx->aspect.line_color |= ((u32) (clamped_stroke_opacity*255)) << 24; } } if (props->stroke_dasharray->type != SVG_STROKEDASHARRAY_NONE) { ctx->aspect.pen_props.dash = GF_DASH_STYLE_CUSTOM_ABS; ctx->aspect.pen_props.dash_offset = props->stroke_dashoffset->value; ctx->aspect.pen_props.dash_set = (GF_DashSettings *) &(props->stroke_dasharray->array); } ctx->aspect.line_scale = (props->vector_effect && (*props->vector_effect == SVG_VECTOREFFECT_NONSCALINGSTROKE)) ? 0 : FIX_ONE; ctx->aspect.pen_props.cap = (u8) *props->stroke_linecap; ctx->aspect.pen_props.join = (u8) *props->stroke_linejoin; ctx->aspect.pen_props.miterLimit = props->stroke_miterlimit->value;}DrawableContext *SVG_drawable_init_context(Drawable *drawable, RenderEffect2D *eff){ DrawableContext *ctx; Bool skipFill = 0; assert(eff->surface); /*switched-off geometry nodes are not rendered*/ if (eff->trav_flags & GF_SR_TRAV_SWITCHED_OFF) return NULL; //Get a empty context from the current surface ctx = VS2D_GetDrawableContext(eff->surface); gf_mx2d_copy(ctx->transform, eff->transform); ctx->drawable = drawable; ctx->appear = eff->parent_use; if (eff->invalidate_all || gf_svg_has_appearance_flag_dirty(eff->svg_flags)) ctx->flags |= CTX_APP_DIRTY; if (eff->svg_flags & (GF_SG_SVG_STROKEDASHARRAY_DIRTY | GF_SG_SVG_STROKEDASHOFFSET_DIRTY | GF_SG_SVG_STROKELINECAP_DIRTY | GF_SG_SVG_STROKELINEJOIN_DIRTY | GF_SG_SVG_STROKEMITERLIMIT_DIRTY | GF_SG_SVG_STROKEWIDTH_DIRTY | GF_SG_SVG_VECTOREFFECT_DIRTY )) ctx->flags |= CTX_SVG_OUTLINE_GEOMETRY_DIRTY; ctx->h_texture = NULL; /*FIXME - only needed for texture*/ if (!eff->color_mat.identity) { GF_SAFEALLOC(ctx->col_mat, GF_ColorMatrix); gf_cmx_copy(ctx->col_mat, &eff->color_mat); } switch (gf_node_get_tag(ctx->drawable->node) ) {#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_image: case TAG_SVG_SA_video:#endif case TAG_SVG_image: case TAG_SVG_video: { SVG_image_stack *st = (SVG_image_stack*) gf_node_get_private(ctx->drawable->node); ctx->h_texture = &(st->txh); } break; case TAG_SVG_line: case TAG_SVG_polyline: break; default: break; } setup_svg_drawable_context(ctx, eff->surface, eff->svg_props); /*Update texture info - draw even if texture not created (this may happen if the media is removed)*/ if (ctx->h_texture && ctx->h_texture->needs_refresh) ctx->flags |= CTX_TEXTURE_DIRTY; if (check_transparent_skip(ctx, skipFill)) { switch (*eff->svg_props->pointer_events) { case SVG_POINTEREVENTS_NONE: VS2D_RemoveLastContext(eff->surface); return NULL; case SVG_POINTEREVENTS_FILL: case SVG_POINTEREVENTS_VISIBLEFILL: ctx->flags |= CTX_SVG_PICK_PATH; break; case SVG_POINTEREVENTS_STROKE: case SVG_POINTEREVENTS_VISIBLESTROKE: ctx->flags |= CTX_SVG_PICK_OUTLINE; break; case SVG_POINTEREVENTS_BOUNDINGBOX: ctx->flags |= CTX_SVG_PICK_BOUNDS; break; default: ctx->flags |= CTX_SVG_PICK_PATH | CTX_SVG_PICK_OUTLINE; break; } } //ctx->flags |= CTX_HAS_LISTENERS; return ctx;}#ifdef GPAC_ENABLE_SVG_SANIstatic void setup_svg_sani_drawable_context(DrawableContext *ctx, struct _visual_surface_2D *surf){ SVG_SANI_pathElement *path = (SVG_SANI_pathElement *)ctx->drawable->node; Fixed clamped_solid_opacity = FIX_ONE; Fixed clamped_fill_opacity = (path->fill_opacity.value < 0 ? 0 : (path->fill_opacity.value > FIX_ONE ? FIX_ONE : path->fill_opacity.value)); Fixed clamped_stroke_opacity = (path->stroke_opacity.value < 0 ? 0 : (path->stroke_opacity.value > FIX_ONE ? FIX_ONE : path->stroke_opacity.value)); ctx->aspect.fill_color = 0; if (path->fill.type==SVG_PAINT_URI) { if (path->fill.iri.type != XMLRI_ELEMENTID) { /* trying to resolve the IRI to the Paint Server */ XMLRI *iri = &path->fill.iri; GF_SceneGraph *sg = gf_node_get_graph(ctx->drawable->node); GF_Node *n = gf_sg_find_node_by_name(sg, &(iri->string[1])); if (n) { iri->type = XMLRI_ELEMENTID; iri->target = (SVG_SA_Element *) n; gf_svg_register_iri(sg, iri); free(iri->string); iri->string = NULL; } } /* Paint server not found, paint is equivalent to none */ if (path->fill.iri.type == XMLRI_ELEMENTID) { switch (gf_node_get_tag((GF_Node *)path->fill.iri.target)) { case TAG_SVG_SA_solidColor: { SVG_SA_solidColorElement *solidColorElt = (SVG_SA_solidColorElement *)path->fill.iri.target; clamped_solid_opacity = (solidColorElt->properties->solid_opacity.value < 0 ? 0 : (solidColorElt->properties->solid_opacity.value > FIX_ONE ? FIX_ONE : solidColorElt->properties->solid_opacity.value)); ctx->aspect.fill_color = GF_COL_ARGB_FIXED(clamped_solid_opacity, solidColorElt->properties->solid_color.color.red, solidColorElt->properties->solid_color.color.green, solidColorElt->properties->solid_color.color.blue); } break; case TAG_SVG_SA_linearGradient: case TAG_SVG_SA_radialGradient: ctx->h_texture = svg_sa_gradient_get_texture((GF_Node *)path->fill.iri.target); break; default: break; } } } else if (path->fill.color.type == SVG_COLOR_RGBCOLOR) { ctx->aspect.fill_color = GF_COL_ARGB_FIXED(clamped_fill_opacity, path->fill.color.red, path->fill.color.green, path->fill.color.blue); } else if (path->fill.color.type >= SVG_COLOR_ACTIVE_BORDER) { ctx->aspect.fill_color = surf->render->compositor->sys_colors[path->fill.color.type - 3]; ctx->aspect.fill_color |= ((u32) (clamped_fill_opacity*255) ) << 24; } ctx->aspect.pen_props.width = (path->stroke.type != SVG_PAINT_NONE) ? path->stroke_width.value : 0; if (path->stroke.type==SVG_PAINT_URI) { if (path->stroke.iri.type != XMLRI_ELEMENTID) { /* trying to resolve the IRI to the Paint Server */ XMLRI *iri = &path->stroke.iri; GF_SceneGraph *sg = gf_node_get_graph(ctx->drawable->node); GF_Node *n = gf_sg_find_node_by_name(sg, &(iri->string[1])); if (n) { iri->type = XMLRI_ELEMENTID; iri->target = (SVG_SA_Element *) n; gf_svg_register_iri(sg, iri); free(iri->string); iri->string = NULL; } } if (path->stroke.iri.type != XMLRI_ELEMENTID) { /* Paint server not found, stroke is equivalent to none */ ctx->aspect.pen_props.width = 0; } else { switch (gf_node_get_tag((GF_Node *)path->stroke.iri.target)) { case TAG_SVG_SA_solidColor: { SVG_SA_solidColorElement *solidColorElt = (SVG_SA_solidColorElement *)path->stroke.iri.target; clamped_solid_opacity = (solidColorElt->properties->solid_opacity.value < 0 ? 0 : (solidColorElt->properties->solid_opacity.value > FIX_ONE ? FIX_ONE : solidColorElt->properties->solid_opacity.value)); ctx->aspect.line_color = GF_COL_ARGB_FIXED(clamped_solid_opacity, solidColorElt->properties->solid_color.color.red, solidColorElt->properties->solid_color.color.green, solidColorElt->properties->solid_color.color.blue); } break; case TAG_SVG_SA_linearGradient: case TAG_SVG_SA_radialGradient: ctx->aspect.line_texture = svg_sa_gradient_get_texture((GF_Node*)path->stroke.iri.target); break; default: ctx->aspect.pen_props.width = 0; } } } else if (path->stroke.color.type == SVG_COLOR_RGBCOLOR) { ctx->aspect.line_color = GF_COL_ARGB_FIXED(clamped_stroke_opacity, path->stroke.color.red, path->stroke.color.green, path->stroke.color.blue); } else if (path->stroke.color.type >= SVG_COLOR_ACTIVE_BORDER) { ctx->aspect.line_color = surf->render->compositor->sys_colors[SVG_COLOR_ACTIVE_BORDER - 3]; ctx->aspect.line_color |= ((u32) (clamped_stroke_opacity*255)) << 24; } if (path->stroke_dasharray.type != SVG_STROKEDASHARRAY_NONE) { ctx->aspect.pen_props.dash = GF_DASH_STYLE_CUSTOM_ABS; ctx->aspect.pen_props.dash_offset = path->stroke_dashoffset.value; ctx->aspect.pen_props.dash_set = (GF_DashSettings *) &(path->stroke_dasharray.array); } ctx->aspect.line_scale = (path->vector_effect == SVG_VECTOREFFECT_NONSCALINGSTROKE) ? 0 : FIX_ONE; ctx->aspect.pen_props.cap = path->stroke_linecap; ctx->aspect.pen_props.join = path->stroke_linejoin; ctx->aspect.pen_props.miterLimit = path->stroke_miterlimit.value;}DrawableContext *svg_sani_drawable_init_context(Drawable *drawable, RenderEffect2D *eff){ DrawableContext *ctx; Bool skipFill = 0; assert(eff->surface); /*switched-off geometry nodes are not rendered*/ if (eff->trav_flags & GF_SR_TRAV_SWITCHED_OFF) return NULL; //Get a empty context from the current surface ctx = VS2D_GetDrawableContext(eff->surface); gf_mx2d_copy(ctx->transform, eff->transform); ctx->drawable = drawable; ctx->appear = eff->parent_use; if (eff->invalidate_all || gf_svg_has_appearance_flag_dirty(eff->svg_flags)) ctx->flags |= CTX_APP_DIRTY; ctx->h_texture = NULL; setup_svg_sani_drawable_context(ctx, eff->surface); /*Update texture info - draw even if texture not created (this may happen if the media is removed)*/ if (ctx->h_texture && ctx->h_texture->needs_refresh) ctx->flags |= CTX_TEXTURE_DIRTY; if (check_transparent_skip(ctx, skipFill)) { VS2D_RemoveLastContext(eff->surface); return NULL; } //ctx->flags |= CTX_HAS_LISTENERS; return ctx;}#endif#endif //SVG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -