Media
vgui
Widgets and scenes drawn offscreen into an image, with no window.
Released v1.0.0 · 2026-09-28use "stdlib/gui.ven"
A retained mode 2D scene and widget layer, built entirely on top of the standard library's own software rasterizer: canvases, filled rectangles, lines and writing the result out as an image. It is an offscreen layer with no operating system window of its own, meant for composing a scene in memory rather than showing one live.
print Widget("rect", 0, 0, 20, 10, "", (0, 0, 0), (200, 30, 30), [])
Reference (15 functions)
API reference
char_cell_width()
Gives back the fixed "character cell" width, in pixels, used to size a label's text.
char_cell_width()char_cell_height()
Gives back the fixed "character cell" height, in pixels, used to size a label's text.
char_cell_height()widget_rect(x, y, width, height, bg_color)
Builds a "rect" Widget: a plain filled rectangle with no text and no children.
widget_rect(0, 0, 20, 10, (200, 30, 30))widget_label(x, y, text, fg_color)
Builds a "label" Widget, sized from texts length via the character-cell constants.
widget_label(5, 5, "Hi", (0, 0, 0))widget_button(x, y, width, height, text, bg_color, fg_color)
Builds a "button" Widget: a filled rectangle in bg_color with an outline in fg_color.
widget_button(0, 0, 40, 12, "OK", (10, 10, 200), (255, 255, 255))widget_panel(x, y, width, height, bg_color)
Builds a "panel" Widget: the only widget kind that can hold children.
widget_panel(0, 0, 100, 100, (240, 240, 240))panel_add_child(panel, child)
panel_add_child(widget_panel(0, 0, 100, 100, (240, 240, 240)), widget_rect(0, 0, 20, 10, (200, 30, 30)))Layout pass
layout_vstack(panel, padding, spacing)
Stacks panels direct children top to bottom, mutating each child's x/y in place.
layout_vstack(panel_add_child(widget_panel(0, 0, 100, 100, (240, 240, 240)), widget_rect(0, 0, 20, 10, (200, 30, 30))), 4, 2)layout_hstack(panel, padding, spacing)
Stacks panels direct children left to right, mutating each child's x/y in place.
layout_hstack(panel_add_child(widget_panel(0, 0, 100, 100, (240, 240, 240)), widget_rect(0, 0, 10, 10, (1, 1, 1))), 3, 5)Render pass
draw_rect_outline(canvas, x0, y0, x1, y1, r, g, b)
draw_rect_outline(canvas_new(10, 10), 0, 0, 9, 9, 255, 255, 255)render_widget(canvas, widget)
Rasterizes one widget, and its whole subtree if it is a panel, onto canvas.
render_widget(canvas_new(20, 20), widget_rect(0, 0, 10, 10, (200, 30, 30)))Unsafe-boundary hardening
max_canvas_pixels()
render_scene/render_scene_to_ppm are this module's real trust boundary: canvas_width/canvas_height are caller-supplied Integers with no other validation anywhere in this module or in raster.vens own canvas_new (which just loops width * height times appending a pixel, whatever that product is).
max_canvas_pixels()validate_canvas_dimensions(canvas_width, canvas_height)
Raises unless canvas_width/canvas_height are positive and within max_canvas_pixels.
validate_canvas_dimensions(100, 100)render_scene(root, canvas_width, canvas_height, bg_color)
Builds a fresh Canvas, fills it with bg_color, and renders roots whole subtree onto it.
render_scene(widget_rect(0, 0, 20, 10, (200, 30, 30)), 100, 100, (255, 255, 255))render_scene_to_ppm(root, canvas_width, canvas_height, bg_color, path)
render_scene_to_ppm(widget_rect(0, 0, 20, 10, (200, 30, 30)), 100, 100, (255, 255, 255), "scene.ppm")