📄 layout.c
字号:
li = (LineInfo*)gf_list_get(st->lines, k+1); current_left -= gf_mulfix(l->spacing, li->width); } if (l->scrollVertical) { if (st->scroll_len < li->height) st->scroll_len = li->height; } else { st->scroll_len += li->width; } } }static void layout_setup_scroll_bounds(LayoutStack *st, M_Layout *l){ u32 minor_justify = 0; st->scroll_min = st->scroll_max = 0; if (l->horizontal) minor_justify = l->scrollVertical ? 1 : 0; else minor_justify = l->scrollVertical ? 0 : 1; /*update scroll-out max limit*/ if (l->scrollMode != -1) { /*set max limit*/ switch( get_justify(l, minor_justify)) { case L_END: if (l->scrollVertical) { if (st->scale_scroll<0) st->scroll_max = - st->scroll_len; else st->scroll_max = st->clip.height; } else { if (st->scale_scroll<0) st->scroll_max = - st->clip.width; else st->scroll_max = st->scroll_len; } break; case L_MIDDLE: if (l->scrollVertical) { if (st->scale_scroll<0) st->scroll_max = - (st->clip.height + st->scroll_len)/2; else st->scroll_max = (st->clip.height + st->scroll_len)/2; } else { if (st->scale_scroll<0) st->scroll_max = - (st->clip.width + st->scroll_len)/2; else st->scroll_max = (st->clip.width + st->scroll_len)/2; } break; default: if (l->scrollVertical) { if (st->scale_scroll<0) st->scroll_max = - st->clip.height; else st->scroll_max = st->scroll_len; } else { if (st->scale_scroll<0) st->scroll_max = - st->scroll_len; else st->scroll_max = st->clip.width; } break; } } /*scroll-in only*/ else { st->scroll_max = 0; } /*scroll-out only*/ if (l->scrollMode==1) { st->scroll_min = 0; return; } /*when vertically scrolling an horizontal layout, don't use vertical justification, only justify top/bottom lines*/ if (l->horizontal && l->scrollVertical) { if (st->scale_scroll<0) { st->scroll_min = st->scroll_len; } else { st->scroll_min = - st->clip.height; } return; } /*update scroll-in offset*/ switch( get_justify(l, minor_justify)) { case L_END: if (l->scrollVertical) { if (st->scale_scroll<0) st->scroll_min = st->clip.height; else st->scroll_min = - st->scroll_len; } else { if (st->scale_scroll<0) st->scroll_min = st->scroll_len; else st->scroll_min = -st->clip.width; } break; case L_MIDDLE: if (l->scrollVertical) { if (st->scale_scroll<0) st->scroll_min = (st->clip.height + st->scroll_len)/2; else st->scroll_min = - (st->clip.height + st->scroll_len)/2; } else { if (st->scale_scroll<0) st->scroll_min = (st->clip.width + st->scroll_len)/2; else st->scroll_min = - (st->clip.width + st->scroll_len)/2; } break; default: if (l->scrollVertical) { if (st->scale_scroll<0) st->scroll_min = st->scroll_len; else st->scroll_min = - st->clip.height; } else { if (st->scale_scroll<0) st->scroll_min = st->clip.width; else st->scroll_min = - st->scroll_len; } break; }}static void layout_scroll(LayoutStack *st, M_Layout *l){ u32 i, nb_lines; Fixed scrolled, rate, ellapsed, scroll_diff; Bool smooth, do_scroll, stop; Double time; ChildGroup2D *cg; /*not scrolling*/ if (!st->scale_scroll && !st->is_scrolling) return; time = gf_node_get_scene_time((GF_Node *)l); if (st->scale_scroll && (st->prev_rate!=st->scale_scroll)) st->start_scroll = 1; if (st->start_scroll) { st->start_scroll = 0; st->start_time = time; st->last_scroll = 0; st->is_scrolling = 1; st->prev_rate = st->scale_scroll; layout_setup_scroll_bounds(st, l); } /*handle pause/resume*/ rate = st->scale_scroll; if (!rate) { if (!st->pause_time) { st->pause_time = time; } else { time = st->pause_time; } rate = st->prev_rate; } else if (st->pause_time) { st->start_time += (time - st->pause_time); st->pause_time = 0; } smooth = l->smoothScroll; /*if the scroll is in the same direction as the layout, there is no notion of line or column to scroll so move to smooth mode*/ if (!l->horizontal && l->scrollVertical) smooth = 1; else if (l->horizontal && !l->scrollVertical) smooth = 1; /*compute advance in pixels for smooth scroll*/ ellapsed = FLT2FIX((Float) (time - st->start_time)); scrolled = gf_mulfix(ellapsed, rate); stop = 0; scroll_diff = st->scroll_max - st->scroll_min; if ((scroll_diff<0) && (scrolled<scroll_diff)) { stop = 1; scrolled = scroll_diff; } else if ((scroll_diff>0) && (scrolled>scroll_diff)) { stop = 1; scrolled = scroll_diff; } do_scroll = 1; if (!stop) { if (smooth) { do_scroll = 1; } else { scroll_diff = scrolled - st->last_scroll; do_scroll = 0; nb_lines = gf_list_count(st->lines); for (i=0; i < nb_lines; i++) { LineInfo *li = (LineInfo*)gf_list_get(st->lines, i); if (l->scrollVertical) { if (ABS(scroll_diff) >= li->height) { do_scroll = 1; break; } } else { if (fabs(scroll_diff) >= li->width) { do_scroll = 1; break; } } } } } if (do_scroll) st->last_scroll = scrolled; else scrolled = st->last_scroll; i=0; while ((cg = (ChildGroup2D *)gf_list_enum(st->groups, &i))) { if (l->scrollVertical) cg->final.y += st->scroll_min + scrolled; else cg->final.x += st->scroll_min + scrolled; } /*draw next frame*/ if (!stop) { gf_sr_invalidate(st->compositor, NULL); return; } /*done*/ if (!l->loop) return; /*restart*/ st->start_time = time; gf_sr_invalidate(st->compositor, NULL);}static void RenderLayout(GF_Node *node, void *rs, Bool is_destroy){ u32 i; GF_Matrix2D gf_mx2d_bck; ChildGroup2D *cg; GroupingNode2D *parent_bck; M_Layout *l = (M_Layout *)node; LayoutStack *st = (LayoutStack *) gf_node_get_private(node); RenderEffect2D *eff = (RenderEffect2D *)rs; if (is_destroy) { layout_reset_lines(st); DeleteGroupingNode2D((GroupingNode2D *)st); gf_list_del(st->lines); free(st); return; } if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { /*TO CHANGE IN BIFS - scroll_rate is quite unusable*/ st->scale_scroll = st->scroll_rate = l->scrollRate; if (eff->is_pixel_metrics) { if (l->scrollVertical) { st->scale_scroll *= eff->surface->render->compositor->scene_width; } else { st->scale_scroll *= eff->surface->render->compositor->scene_width; } } } /*setup effects*/ gf_mx2d_copy(gf_mx2d_bck, eff->transform); parent_bck = eff->parent; eff->parent = (GroupingNode2D *) st; gf_mx2d_init(eff->transform); /*setup bounds in local coord system, pixel metrics*/ if (!eff->is_pixel_metrics) gf_mx2d_add_scale(&eff->transform, eff->min_hsize, eff->min_hsize); st->clip = R2D_ClipperToPixelMetrics(eff, l->size); if (l->wrap) eff->text_split_mode = 1; /*note we don't clear dirty flag, this is done in traversing*/ group2d_traverse((GroupingNode2D *)st, l->children, eff); /*restore effect*/ gf_mx2d_copy(eff->transform, gf_mx2d_bck); eff->parent = parent_bck; eff->text_split_mode = 0; /*center all nodes*/ i=0; while ((cg = (ChildGroup2D *)gf_list_enum(st->groups, &i))) { cg->final.x = - cg->final.width/2; cg->final.y = cg->final.height/2; } /*apply justification*/ layout_justify(st, l); /*scroll*/ layout_scroll(st, l); /*and finish*/ i=0; while ((cg = (ChildGroup2D *)gf_list_enum(st->groups, &i))) { child2d_render_done(cg, (RenderEffect2D *)rs, &st->clip); } group2d_reset_children((GroupingNode2D*)st); group2d_force_bounds(eff->parent, &st->clip);}void R2D_InitLayout(Render2D *sr, GF_Node *node){ LayoutStack *stack; GF_SAFEALLOC(stack, LayoutStack); SetupGroupingNode2D((GroupingNode2D*)stack, sr, node); stack->lines = gf_list_new(); gf_node_set_private(node, stack); gf_node_set_callback_function(node, RenderLayout);}void R2D_LayoutModified(GF_Node *node){ LayoutStack *st = (LayoutStack *) gf_node_get_private(node); /*if modif other than scrollrate restart scroll*/ if (st->scroll_rate == ((M_Layout*)node)->scrollRate) { st->start_scroll = 1; st->is_scrolling = 0; /*draw next frame*/ gf_sr_invalidate(st->compositor, NULL); } /*modif scrollrate , update rate and invalidate scroll*/ else if (((M_Layout*)node)->scrollRate) { /*draw next frame*/ gf_sr_invalidate(st->compositor, NULL); } gf_node_dirty_set(node, 0, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -