# text_fit.ludic - text-fit: shrink 12px draws a line that does not fit its box smaller, down to that # size, and cuts what still does not fit with an ellipsis; line-height (a multiple of the font size, # px or em) spaces a text's lines. Both are inherited, as font properties are. function el_text_fit(ui_st: mut UiState, n: UiNode, s: string) -> void { let parts = mm_split(ui_st, tw(ui_st, s), 32) nx(n).fit_min = 0.0 if len(parts) >= 2 and parts[0] == "shrink" { nx(n).fit_min = Math.max(el_unit(ui_st, parts[1]), 1.0) } } function el_line_h(ui_st: mut UiState, n: UiNode, s0: string) -> void { let s = tw(ui_st, s0) let x = nx(n) x.lh_kind = 0 if s == "normal" or s == "" { return } let c = s[len(s) - 1] if c >= 48 and c <= 57 or c == 46 { x.lh_kind = 1 x.lh_v = el_num(s) return } x.lh_kind = 2 x.lh_v = el_unit(ui_st, s) } # the nearest element, out from this one, that says `what` (0 text-fit, 1 line-height), or null function tf_up(n: UiNode, what: int) -> UiNodeX { var at = n while at != null { if at.ex != null and what == 0 and at.ex.fit_min > 0.0 { return at.ex } if at.ex != null and what == 1 and at.ex.lh_kind > 0 { return at.ex } at = at.parent } return null } function ly_line_h(n: UiNode) -> float { let x = tf_up(n, 1) if x == null { return n.rsize * 1.25 } if x.lh_kind == 1 { return n.rsize * x.lh_v } return x.lh_v } # one line to fit its box: at its own size if it does, else smaller down to text-fit's least, then # cut; tf_size says the size it is drawn at function tf_fit(ui_st: mut UiState, n: UiNode, s: string) -> string { ui_st.tf_size = n.rsize let x = tf_up(n, 0) let room = n.cw - ly_hin(n) if x == null or room <= 0.0 { return s } let w = ly_text_w(ui_st, s, ui_st.tf_size) if w <= room { return s } ui_st.tf_size = Math.max(x.fit_min, n.rsize * room / w) while ui_st.tf_size > x.fit_min and ly_text_w(ui_st, s, ui_st.tf_size) > room { ui_st.tf_size = Math.max(x.fit_min, ui_st.tf_size - 0.5) } return ly_ellipsis(ui_st, s, ui_st.tf_size, room) }