///|
/// Render text at pixel coordinates using a TextRenderer.
/// Converts pixel-space vertices to NDC for the builtin shader.
pub fn render_text(
text_renderer : @text.TextRenderer,
text : String,
size_px : Double,
x : Double,
y : Double,
dst : @gfx.ImageHandle,
shader : @gfx.ShaderHandle,
color_hex : Int,
screen_w : Double,
screen_h : Double,
) -> Array[@gfx.DrawTrianglesCommand] {
let blend = @gfx.BlendMode::from_int(1)
let r = (color_hex >> 16) & 0xFF
let g = (color_hex >> 8) & 0xFF
let b = color_hex & 0xFF
let uniform = [r, g, b, 255]
let cmds = text_renderer.render_text(
text, size_px, x, y, dst, shader, blend, uniform,
)
// Convert pixel-space vertices to NDC (stride 4: x, y, u, v)
let result : Array[@gfx.DrawTrianglesCommand] = []
for cmd in cmds {
let vdata = cmd.vertex_data
let ndc_vdata : Array[Double] = Array::make(vdata.length(), 0.0)
for i = 0; i < vdata.length(); i = i + 4 {
ndc_vdata[i] = vdata[i] / screen_w * 2.0 - 1.0 // x → NDC
ndc_vdata[i + 1] = -(vdata[i + 1] / screen_h * 2.0 - 1.0) // y → NDC (flip)
ndc_vdata[i + 2] = vdata[i + 2] // u
ndc_vdata[i + 3] = vdata[i + 3] // v
}
result.push(
@gfx.new_draw_triangles_command(
cmd.dst,
cmd.shader,
cmd.dst_regions,
cmd.index_offset,
cmd.pipeline_id,
cmd.uniform_hash,
blend,
ndc_vdata,
cmd.indices,
cmd.src_image_ids,
cmd.uniform_dwords,
),
)
}
result
}
///|
/// Measure text dimensions without rendering.
pub fn measure_text(
text_renderer : @text.TextRenderer,
text : String,
size_px : Double,
) -> @font.TextMetrics {
text_renderer.measure(text, size_px)
}