Custom draw

tuneup
This commit is contained in:
Zachary Levy
2026-04-19 21:11:26 -07:00
parent 0953462b3b
commit 90fba74243
5 changed files with 180 additions and 41 deletions

View File

@@ -352,6 +352,11 @@ prepare_text :: proc(layer: ^Layer, text: Text) {
scissor := &GLOB.scissors[layer.scissor_start + layer.scissor_len - 1]
// Snap base position to integer physical pixels to avoid atlas sub-pixel
// sampling blur (and the off-by-one bottom-row clip that comes with it).
base_x := math.round(text.position[0] * GLOB.dpi_scaling)
base_y := math.round(text.position[1] * GLOB.dpi_scaling)
for data != nil {
vertex_start := u32(len(GLOB.tmp_text_verts))
index_start := u32(len(GLOB.tmp_text_indices))
@@ -363,7 +368,7 @@ prepare_text :: proc(layer: ^Layer, text: Text) {
append(
&GLOB.tmp_text_verts,
Vertex {
position = {pos.x + text.position[0] * GLOB.dpi_scaling, -pos.y + text.position[1] * GLOB.dpi_scaling},
position = {pos.x + base_x, -pos.y + base_y},
uv = {uv.x, uv.y},
color = text.color,
},
@@ -471,6 +476,19 @@ clay_error_handler :: proc "c" (errorData: clay.ErrorData) {
log.error("Clay error:", errorData.errorType, errorData.errorText)
}
// Called for each Clay `RenderCommandType.Custom` render command that
// `prepare_clay_batch` encounters.
//
// - `layer` is the layer the command belongs to (post-z-index promotion).
// - `bounds` is already translated into the active layer's coordinate system
// and pre-DPI, matching what the built-in shape procs expect.
// - `render_data` is Clay's `CustomRenderData` for the element, exposing
// `backgroundColor`, `cornerRadius`, and the `customData` pointer the caller
// attached to `clay.CustomElementConfig.customData`.
//
// The callback must not call `new_layer` or `prepare_clay_batch`.
Custom_Draw :: #type proc(layer: ^Layer, bounds: Rectangle, render_data: clay.CustomRenderData)
ClayBatch :: struct {
bounds: Rectangle,
cmds: clay.ClayArray(clay.RenderCommand),
@@ -482,6 +500,7 @@ prepare_clay_batch :: proc(
batch: ^ClayBatch,
mouse_wheel_delta: [2]f32,
frame_time: f32 = 0,
custom_draw: Custom_Draw = nil,
) {
mouse_pos: [2]f32
mouse_flags := sdl.GetMouseState(&mouse_pos.x, &mouse_pos.y)
@@ -522,10 +541,10 @@ prepare_clay_batch :: proc(
render_data := render_command.renderData.text
txt := string(render_data.stringContents.chars[:render_data.stringContents.length])
c_text := strings.clone_to_cstring(txt, context.temp_allocator)
// Clay's render_command.id is already hashed with the same Jenkins algorithm
// as text_cache_hash, so it shares the same keyspace.
// Clay render-command IDs are derived via Clay's internal HashNumber (Jenkins-family)
// and namespaced with .Clay so they can never collide with user-provided custom text IDs.
sdl_text := cache_get_or_update(
render_command.id,
Cache_Key{render_command.id, .Clay},
c_text,
get_font(render_data.fontId, render_data.fontSize),
)
@@ -581,7 +600,9 @@ prepare_clay_batch :: proc(
} else {
rectangle_corners_lines(layer, bounds, radii, color, thickness)
}
case clay.RenderCommandType.Custom:
case clay.RenderCommandType.Custom: if custom_draw != nil {
custom_draw(layer, bounds, render_command.renderData.custom)
}
}
}
}