📄 layout.c
字号:
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; ChildGroup *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 = (ChildGroup *)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; ChildGroup *cg; Bool mode_bckup, had_clip; GroupingNode *parent_bck; GF_Rect clip, prev_clipper; M_Layout *l = (M_Layout *)node; LayoutStack *st = (LayoutStack *) gf_node_get_private(node); RenderEffect3D *eff = (RenderEffect3D *)rs; if (is_destroy) { layout_reset_lines(st); DeleteGroupingNode((GroupingNode *)st); gf_list_del(st->lines); free(st); return; } /*note we don't clear dirty flag, this is done in traversing*/ 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; /*move to pixel metrics*/ if (R3D_GetSurfaceSizeInfo(eff, &st->clip.width, &st->clip.height)) { st->scale_scroll = gf_mulfix(st->scale_scroll, l->scrollVertical ? st->clip.height : st->clip.width); } /*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); gf_bbox_from_rect(&st->bbox, &st->clip); } /*setup clipping*/ if (eff->traversing_mode==TRAVERSE_SORT) clip = R3D_UpdateClipper(eff, st->clip, &had_clip, &prev_clipper, 0); /*don't waste time traversing is pick ray not in clipper*/ if ((eff->traversing_mode==TRAVERSE_PICK) && !R3D_PickInClipper(eff, &st->clip)) goto layout_exit; /*setup effects*/ parent_bck = eff->parent; mode_bckup = eff->traversing_mode; eff->traversing_mode = TRAVERSE_GET_BOUNDS; eff->parent = (GroupingNode *) st; if (l->wrap) eff->text_split_mode = 1; grouping_traverse((GroupingNode *)st, eff, NULL); /*restore effect*/ eff->parent = parent_bck; eff->traversing_mode = mode_bckup; if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) { eff->bbox = st->bbox; goto layout_exit; } /*center all nodes*/ i=0; while ((cg = (ChildGroup *)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); i=0; while ((cg = (ChildGroup *)gf_list_enum(st->groups, &i))) { child_render_done(cg, eff); } if (eff->traversing_mode==TRAVERSE_SORT) { if (had_clip) eff->clipper = prev_clipper; eff->has_clip = had_clip; }layout_exit: group_reset_children((GroupingNode*)st); if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) gf_bbox_from_rect(&eff->bbox, &st->clip); eff->text_split_mode = 0;}void R3D_InitLayout(Render3D *sr, GF_Node *node){ LayoutStack *stack; GF_SAFEALLOC(stack, LayoutStack); SetupGroupingNode((GroupingNode*)stack, sr->compositor, node, & ((M_Layout *)node)->children); stack->lines = gf_list_new(); gf_node_set_private(node, stack); gf_node_set_callback_function(node, RenderLayout);}void R3D_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; /*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); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -