# draw_content.ludic - what is inside a box drawn: a text's lines, placed by text-align, each over its # text-shadow, and a picture # a text's lines (one, or the wrapped ones), each placed by text-align, the last cut by an ellipsis function fr_text(ui_st: mut UiState, n: UiNode) -> void { let lh = ly_line_h(n) let y = n.y + n.pt + n.bt + (lh - n.rsize * 1.25) / 2.0 let a = n.rfg_a * ui_st.fr_ga let sh = fr_text_shadow(n) if n.lines == null { var s = tf_fit(ui_st, n, n.text) if n.ellipsis { s = ly_ellipsis(ui_st, s, ui_st.tf_size, n.cw - ly_hin(n)) } fr_line(ui_st, n, sh, fr_line_x(ui_st, n, s, ui_st.tf_size), y, s, a, ui_st.tf_size) return } for i in 0 .. len(n.lines) { fr_line(ui_st, n, sh, fr_line_x(ui_st, n, n.lines[i], n.rsize), y + float(i) * lh, n.lines[i], a, n.rsize) } } # one line, over its shadow when it has one function fr_line(ui_st: UiState, n: UiNode, sh: UiNodeX, x: float, y: float, s: string, a: float, size: float) -> void { if sh != null { ui_st.ui_be.text(x + sh.tsh_x, y + sh.tsh_y, s, size, sh.tsh_c, sh.tsh_a * ui_st.fr_ga) } ui_st.ui_be.text(x, y, s, size, n.rfg, a) } # text-shadow is inherited: the nearest element that says it, or null (none) function fr_text_shadow(n: UiNode) -> UiNodeX { var at = n while at != null { if at.ex != null and at.ex.tsh_set { if at.ex.tsh_c < 0 { return null } return at.ex } at = at.parent } return null } # the opacity a native's draw is at: every group opacity around it, its own included export function ui_opacity(ui_st: UiState) -> float { return ui_st.fr_ga } # where a line starts: text-align within the room the box gives it function fr_line_x(ui_st: UiState, n: UiNode, s: string, size: float) -> float { let x = n.x + n.pl + n.bl if n.talign == UI_START { return x } let spare = n.cw - ly_hin(n) - ly_text_w(ui_st, s, size) if n.talign == UI_CENTER { return x + spare / 2.0 } return x + spare } # an : a picture file drawn as it is, as a browser draws one (unless the img sets its own # color); a cell of an atlas ("icon:tent") is a glyph, and takes the color around it as text does function fr_image(ui_st: mut UiState, n: UiNode) -> void { var c = 16777215 var a = ui_st.fr_ga if n.fg != UI_INHERIT or fr_is_cell(n.src) { c = n.rfg a = ui_st.fr_ga * n.rfg_a } var nat_w = 0.0 var nat_h = 0.0 if ui_st.ui_be.image_w != null and ui_st.ui_be.image_h != null { nat_w = ui_st.ui_be.image_w(n.src) nat_h = ui_st.ui_be.image_h(n.src) } let r = ui_object_fit_into(ui_st.fit_out, n, nat_w, nat_h) let clipped = ui_st.ui_be.clip != null and (r[2] > n.cw - ly_hin(n) or r[3] > n.ch - ly_vin(n)) if clipped { fr_clip_push(ui_st, n.x + n.pl + n.bl, n.y + n.pt + n.bt, n.cw - ly_hin(n), n.ch - ly_vin(n)) } ui_st.ui_be.image(n.src, r[0], r[1], r[2], r[3], c, a) if clipped { fr_clip_pop(ui_st) } } # prefix:name, and not a path (C:/... is a drive, not an atlas) function fr_is_cell(src: string) -> bool { for i in 0 .. len(src) { if src[i] == 47 or src[i] == 92 { return false } if src[i] == 58 { return i > 1 } } return false }