📄 svg_base_da.c
字号:
u32 scene_width, scene_height; GF_Matrix2D mat; gf_mx2d_init(mat); scene_width = eff->surface->render->compositor->scene_width; scene_height = eff->surface->render->compositor->scene_height; if (!atts->width) { real_width = INT2FIX(scene_width); } else { switch (atts->width->type) { case SVG_NUMBER_VALUE: case SVG_NUMBER_PX: real_width = atts->width->value; break; case SVG_NUMBER_PERCENTAGE: real_width = scene_width*atts->width->value/100; break; case SVG_NUMBER_IN: real_width = dpi * atts->width->value; break; case SVG_NUMBER_CM: real_width = gf_mulfix(dpi*FLT2FIX(0.39), atts->width->value); break; case SVG_NUMBER_MM: real_width = gf_mulfix(dpi*FLT2FIX(0.039), atts->width->value); break; case SVG_NUMBER_PT: real_width = dpi/12 * atts->width->value; break; case SVG_NUMBER_PC: real_width = dpi/6 * atts->width->value; break; default: real_width = INT2FIX(scene_width); break; } } if (!atts->height) { real_height = INT2FIX(scene_height); } else { switch (atts->height->type) { case SVG_NUMBER_VALUE: case SVG_NUMBER_PX: real_height = atts->height->value; break; case SVG_NUMBER_PERCENTAGE: real_height = scene_height*atts->height->value/100; break; case SVG_NUMBER_IN: real_height = dpi * atts->height->value; break; case SVG_NUMBER_CM: real_height = gf_mulfix(dpi*FLT2FIX(0.39), atts->height->value); break; case SVG_NUMBER_MM: real_height = gf_mulfix(dpi*FLT2FIX(0.039), atts->height->value); break; case SVG_NUMBER_PT: real_height = dpi/12 * atts->height->value; break; case SVG_NUMBER_PC: real_height = dpi/6 * atts->height->value; break; default: real_height = INT2FIX(scene_height); break; } } if (atts->viewBox && atts->viewBox->width != 0 && atts->viewBox->height != 0) { Fixed scale, vp_w, vp_h; if (atts->preserveAspectRatio && atts->preserveAspectRatio->meetOrSlice==SVG_MEETORSLICE_MEET) { if (gf_divfix(real_width, atts->viewBox->width) > gf_divfix(real_height, atts->viewBox->height)) { scale = gf_divfix(real_height, atts->viewBox->height); vp_w = gf_mulfix(atts->viewBox->width, scale); vp_h = real_height; } else { scale = gf_divfix(real_width, atts->viewBox->width); vp_w = real_width; vp_h = gf_mulfix(atts->viewBox->height, scale); } } else { if (gf_divfix(real_width, atts->viewBox->width) < gf_divfix(real_height, atts->viewBox->height)) { scale = gf_divfix(real_height, atts->viewBox->height); vp_w = gf_mulfix(atts->viewBox->width, scale); vp_h = real_height; } else { scale = gf_divfix(real_width, atts->viewBox->width); vp_w = real_width; vp_h = gf_mulfix(atts->viewBox->height, scale); } } if (!atts->preserveAspectRatio || atts->preserveAspectRatio->align==SVG_PRESERVEASPECTRATIO_NONE) { mat.m[0] = gf_divfix(real_width, atts->viewBox->width); mat.m[4] = gf_divfix(real_height, atts->viewBox->height); mat.m[2] = - gf_muldiv(atts->viewBox->x, real_width, atts->viewBox->width); mat.m[5] = - gf_muldiv(atts->viewBox->y, real_height, atts->viewBox->height); } else { Fixed dx, dy; mat.m[0] = mat.m[4] = scale; mat.m[2] = - gf_mulfix(atts->viewBox->x, scale); mat.m[5] = - gf_mulfix(atts->viewBox->y, scale); dx = dy = 0; switch (atts->preserveAspectRatio->align) { case SVG_PRESERVEASPECTRATIO_XMINYMIN: break; case SVG_PRESERVEASPECTRATIO_XMIDYMIN: dx = ( real_width - vp_w) / 2; break; case SVG_PRESERVEASPECTRATIO_XMAXYMIN: dx = real_width - vp_w; break; case SVG_PRESERVEASPECTRATIO_XMINYMID: dy = ( real_height - vp_h) / 2; break; case SVG_PRESERVEASPECTRATIO_XMIDYMID: dx = ( real_width - vp_w) / 2; dy = ( real_height - vp_h) / 2; break; case SVG_PRESERVEASPECTRATIO_XMAXYMID: dx = real_width - vp_w; dy = ( real_height - vp_h) / 2; break; case SVG_PRESERVEASPECTRATIO_XMINYMAX: dy = real_height - vp_h; break; case SVG_PRESERVEASPECTRATIO_XMIDYMAX: dx = (real_width - vp_w) / 2; dy = real_height - vp_h; break; case SVG_PRESERVEASPECTRATIO_XMAXYMAX: dx = real_width - vp_w; dy = real_height - vp_h; break; } mat.m[2] += dx; mat.m[5] += dy; /*we need a clipper*/ if (atts->preserveAspectRatio->meetOrSlice==SVG_MEETORSLICE_SLICE) { GF_Rect rc; rc.width = real_width; rc.height = real_height; if (!is_root) { rc.x = 0; rc.y = real_height; gf_mx2d_apply_rect(&eff->vb_transform, &rc); } else { rc.x = dx; rc.y = dy + real_height; } eff->surface->top_clipper = gf_rect_pixelize(&rc); } } } gf_mx2d_pre_multiply(&eff->vb_transform, &mat);}static void svg_render_svg(GF_Node *node, void *rs, Bool is_destroy){ u32 viewport_color; GF_Matrix2D backup_matrix; GF_IRect top_clip; Bool is_root_svg = 0; SVGPropertiesPointers backup_props; u32 backup_flags; u32 styling_size = sizeof(SVGPropertiesPointers); RenderEffect2D *eff = (RenderEffect2D *) rs; SVGAllAttributes all_atts; if (is_destroy) { SVGPropertiesPointers *svgp = gf_node_get_private(node); gf_svg_properties_reset_pointers(svgp); free(svgp); svg_check_focus_upon_destroy(node); return; } gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!eff->svg_props) { eff->svg_props = (SVGPropertiesPointers *) gf_node_get_private(node); is_root_svg = 1; } svg_render_base(node, &all_atts, eff, &backup_props, &backup_flags); /*enable or disable navigation*/ eff->surface->render->navigation_disabled = (all_atts.zoomAndPan && *all_atts.zoomAndPan == SVG_ZOOMANDPAN_DISABLE) ? 1 : 0; if (svg_is_display_off(eff->svg_props)) { memcpy(eff->svg_props, &backup_props, styling_size); eff->svg_flags = backup_flags; return; } top_clip = eff->surface->top_clipper; gf_mx2d_copy(backup_matrix, eff->transform); gf_mx2d_init(eff->vb_transform); svg_set_viewport_transformation(eff, &all_atts, is_root_svg); gf_mx2d_pre_multiply(&eff->transform, &eff->vb_transform); if (!is_root_svg && (all_atts.x || all_atts.y)) gf_mx2d_add_translation(&eff->transform, all_atts.x->value, all_atts.y->value); /* TODO: FIX ME: this only works for single SVG element in the doc*/ if (is_root_svg && eff->svg_props->viewport_fill && eff->svg_props->viewport_fill->type != SVG_PAINT_NONE) { Fixed vp_opacity = eff->svg_props->viewport_fill_opacity ? eff->svg_props->viewport_fill_opacity->value : FIX_ONE; viewport_color = GF_COL_ARGB_FIXED(vp_opacity, eff->svg_props->viewport_fill->color.red, eff->svg_props->viewport_fill->color.green, eff->svg_props->viewport_fill->color.blue); if (eff->surface->render->compositor->back_color != viewport_color) { eff->surface->render->compositor->back_color = viewport_color; /*clear surface*/ VS2D_Clear(eff->surface, NULL, 0); gf_sr_invalidate(eff->surface->render->compositor, NULL); goto exit; } } if (eff->traversing_mode == TRAVERSE_GET_BOUNDS) { svg_get_nodes_bounds(node, ((SVG_Element *)node)->children, eff); } else { svg_render_node_list(((SVG_Element *)node)->children, eff); }exit: svg_restore_parent_transformation(eff, &backup_matrix); memcpy(eff->svg_props, &backup_props, styling_size); eff->svg_flags = backup_flags; eff->surface->top_clipper = top_clip;}void svg_init_svg(Render2D *sr, GF_Node *node){ SVGPropertiesPointers *svgp; GF_SAFEALLOC(svgp, SVGPropertiesPointers); gf_svg_properties_init_pointers(svgp); gf_node_set_private(node, svgp); gf_node_set_callback_function(node, svg_render_svg);}static void svg_render_g(GF_Node *node, void *rs, Bool is_destroy){ GF_Matrix2D backup_matrix; SVGPropertiesPointers backup_props; u32 backup_flags; u32 styling_size = sizeof(SVGPropertiesPointers); RenderEffect2D *eff = (RenderEffect2D *) rs; SVGAllAttributes all_atts; if (is_destroy) { svg_check_focus_upon_destroy(node); return; } gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); svg_render_base(node, &all_atts, eff, &backup_props, &backup_flags); if (svg_is_display_off(eff->svg_props)) { u32 prev_flags = eff->trav_flags; eff->trav_flags |= GF_SR_TRAV_SWITCHED_OFF; svg_render_node_list(((SVG_Element *)node)->children, eff); eff->trav_flags = prev_flags; memcpy(eff->svg_props, &backup_props, styling_size); eff->svg_flags = backup_flags; return; } svg_apply_local_transformation(eff, &all_atts, &backup_matrix); if (eff->traversing_mode == TRAVERSE_GET_BOUNDS) { svg_get_nodes_bounds(node, ((SVG_Element *)node)->children, eff); } else { svg_render_node_list(((SVG_Element *)node)->children, eff); drawable_check_focus_highlight(node, eff, NULL); } svg_restore_parent_transformation(eff, &backup_matrix); memcpy(eff->svg_props, &backup_props, styling_size); eff->svg_flags = backup_flags;}void svg_init_g(Render2D *sr, GF_Node *node){ gf_node_set_callback_function(node, svg_render_g);}static void svg_render_switch(GF_Node *node, void *rs, Bool is_destroy){ GF_Matrix2D backup_matrix; SVGPropertiesPointers backup_props; u32 backup_flags; u32 styling_size = sizeof(SVGPropertiesPointers); SVGAllAttributes all_atts; RenderEffect2D *eff = (RenderEffect2D *) rs; if (is_destroy) { svg_check_focus_upon_destroy(node); return; } gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); svg_render_base(node, &all_atts, eff, &backup_props, &backup_flags); if (svg_is_display_off(eff->svg_props)) { svg_restore_parent_transformation(eff, &backup_matrix); memcpy(eff->svg_props, &backup_props, styling_size); eff->svg_flags = backup_flags; return; } svg_apply_local_transformation(eff, &all_atts, &backup_matrix); if (eff->traversing_mode == TRAVERSE_GET_BOUNDS) { svg_get_nodes_bounds(node, ((SVG_Element *)node)->children, eff); } else { GF_ChildNodeItem *l = ((SVG_Element *)node)->children; while (l) { if (1 /*eval_conditional(eff->surface->render->compositor, (SVG_Element*)l->node)*/) { svg_render_node((GF_Node*)l->node, eff); break; } l = l->next; } } svg_restore_parent_transformation(eff, &backup_matrix); memcpy(eff->svg_props, &backup_props, styling_size); eff->svg_flags = backup_flags;}void svg_init_switch(Render2D *sr, GF_Node *node){ gf_node_set_callback_function(node, svg_render_switch);}static void svg_drawable_post_render(Drawable *cs, SVGPropertiesPointers *backup_props, u32 *backup_flags, RenderEffect2D *eff, Bool rectangular, Fixed path_length, SVGAllAttributes *atts){ GF_Matrix2D backup_matrix; DrawableContext *ctx; if (eff->traversing_mode == TRAVERSE_GET_BOUNDS) { if (svg_is_display_off(eff->svg_props)) gf_path_get_bounds(cs->path, &eff->bounds); goto end; } if (svg_is_display_off(eff->svg_props) || ( *(eff->svg_props->visibility) == SVG_VISIBILITY_HIDDEN) ) { goto end; } svg_apply_local_transformation(eff, atts, &backup_matrix); ctx = SVG_drawable_init_context(cs, eff); if (ctx) { if (rectangular) { if (ctx->h_texture && ctx->h_texture->transparent) {} else if (GF_COL_A(ctx->aspect.fill_color) != 0xFF) {} else if (ctx->transform.m[1] || ctx->transform.m[3]) {} else { ctx->flags &= ~CTX_IS_TRANSPARENT; } } if (path_length) ctx->aspect.pen_props.path_length = path_length; drawable_finalize_render(ctx, eff, NULL); } svg_restore_parent_transformation(eff, &backup_matrix);end: memcpy(eff->svg_props, backup_props, sizeof(SVGPropertiesPointers)); eff->svg_flags = *backup_flags;}static void svg_render_rect(GF_Node *node, void *rs, Bool is_destroy){ SVGPropertiesPointers backup_props; u32 backup_flags; Drawable *cs = (Drawable *)gf_node_get_private(node); RenderEffect2D *eff = (RenderEffect2D *)rs; SVGAllAttributes all_atts; if (is_destroy) { DestroyDrawableNode(node); return; } if (eff->traversing_mode==TRAVERSE_DRAW) { drawable_draw(eff); return; } else if (eff->traversing_mode==TRAVERSE_PICK) { drawable_pick(eff); return; } gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); svg_render_base(node, &all_atts, (RenderEffect2D *)rs, &backup_props, &backup_flags); /* 3) for a leaf node Recreates the path (i.e the shape) only if the node is dirty (has changed compared to the previous rendering phase) */ if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) { Fixed rx = (all_atts.rx ? all_atts.rx->value : 0); Fixed ry = (all_atts.ry ? all_atts.ry->value : 0); Fixed x = (all_atts.x ? all_atts.x->value : 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -