P5 is a drawing library inspired by Processing and p5.js. It wraps DVI::Graphics with a stateful API for fill/stroke colors, coordinate transforms, blend modes, and text layout.
Module: P5
- P5.new
- P5#width
- P5#height
- P5#background
- P5#commit
- P5#fill
- P5#no_fill
- P5#stroke
- P5#no_stroke
- P5#stroke_weight
- P5#blend_mode
- P5#alpha
- P5#text_font
- P5#text_color
- P5#text_align
- P5#text_leading
- P5#text_width
- P5#point
- P5#line
- P5#rect
- P5#circle
- P5#ellipse
- P5#triangle
- P5#arc
- P5#bezier
- P5#curve
- P5#text
- P5#translate
- P5#rotate
- P5#scale
- P5#push_matrix
- P5#pop_matrix
- P5#reset_matrix
- P5#color
- P5#image
P5 provides a high-level drawing API on top of DVI::Graphics. Creating a
P5 instance switches the display to graphics mode and initializes drawing
state (fill white, stroke white, 8x8 font, identity transform).
require "p5"
p5 = P5.new
p5.background(0x00)
p5.fill(p5.color(200, 0, 0))
p5.stroke(0xFF)
p5.circle(160, 120, 50)
p5.text_font(DVI::Graphics::FONT_MPLUS_12)
p5.text("Hello!", 10, 10)
p5.commitCreates a new P5 instance and switches to graphics mode.
Returns the current framebuffer width in pixels (640 or 320).
Returns the current framebuffer height in pixels (480 or 240).
Fills the entire framebuffer with the given RGB332 color.
Waits for VBlank and copies the back buffer to the front buffer for display. Call this once per frame after all drawing is complete.
Sets the fill color for subsequent shape drawing and enables fill.
Disables fill for subsequent shape drawing.
Sets the stroke (outline) color for subsequent shape drawing and enables stroke.
Disables stroke for subsequent shape drawing.
Sets the stroke thickness in pixels. Affects line, triangle outlines,
and thick lines. Negative values are clamped to 0.
Sets the pixel compositing mode. Available modes:
| Constant | Effect |
|---|---|
P5::REPLACE |
Overwrite (default) |
P5::ADD |
Saturating add per channel |
P5::SUBTRACT |
Saturating subtract per channel |
P5::MULTIPLY |
Multiply per channel |
P5::SCREEN |
Screen blend per channel |
Sets alpha blend mode with the given opacity (0-255, clamped). Switches to alpha blending automatically.
Sets the font for text rendering. Pass a second font for CJK (wide) character support via Unicode-to-JIS lookup.
Sets the color for text rendering.
Sets text alignment. Horizontal: :left, :center, :right. Vertical:
:top, :center, :bottom.
Sets extra line spacing in pixels (added to font glyph height).
Returns the pixel width of a string rendered with the current font.
Draws a single pixel at (x, y) using the stroke color.
Draws a line from (x0, y0) to (x1, y1) using the stroke color.
Draws a rectangle at (x, y) with size (w, h). Fills with fill color, outlines with stroke color. Under rotation, decomposed into two triangles.
Draws a circle centered at (cx, cy) with radius r. Under non-uniform scale, rendered as an ellipse.
Draws an ellipse centered at (cx, cy) with radii (rx, ry).
Draws a triangle with the given vertices.
Draws a pie-slice arc centered at (cx, cy) with radius r. Angles are in radians (0 = right, PI/2 = down). Rendered as a triangle fan in C using hardware sinf/cosf.
Draws a cubic bezier curve from (x1, y1) to (x4, y4) with control points (x2, y2) and (x3, y3). Rendered as 20 line segments.
Draws a Catmull-Rom spline through (x2, y2) to (x3, y3), shaped by (x1, y1) and (x4, y4). Rendered as 20 line segments.
Draws a UTF-8 string at (x, y). Position is adjusted by text_align.
Coordinate transforms apply to the position (translation only for text).
Translates the coordinate system by (tx, ty).
Rotates the coordinate system by angle (in radians).
Scales the coordinate system. Pass one argument for uniform scale.
Saves the current transform matrix to the stack. The stack is capped at
P5::MATRIX_STACK_MAX (32) entries and raises if exceeded, to catch
unbalanced push/pop loops before they exhaust memory.
Restores the transform matrix from the stack.
Resets the transform matrix to identity.
Converts RGB values (0-255) to an RGB332 color byte.
Blits an RGB332 image (byte string) at position (x, y).
P5 holds all drawing state as Ruby instance variables. The C layer
(DVI::Graphics) is stateless: every drawing function receives the
framebuffer pointer, width, height, and color as arguments. The only C-side
state is the blend mode (global, set via dvi_graphics_set_blend_mode).
Transforms are implemented entirely in Ruby using a 2x3 affine matrix.
Drawing functions check translate_only? for a fast path (integer addition
only) and fall back to full matrix multiplication for rotation and scale.
For rotated rectangles, the four corners are transformed and rendered as
two fill_triangle calls plus four line segments. For scaled circles, the
matrix scale factors are extracted and the circle is rendered as an
ellipse via fill_ellipse.
At 640x480, the back buffer is in PSRAM (307 KB). At 320x240, the back
buffer uses the second half of the SRAM framebuffer (76.8 KB), providing
fast SRAM-to-SRAM copies. commit waits for VBlank, then copies the back
buffer to the front buffer.
Drawing functions dispatch to REPLACE-only or blend-aware paths. The
REPLACE path uses fill_span (inlined to memset) and plot_pixel (direct
store). The blend path uses blend_span with per-mode optimized loops
that pre-extract constant source channels outside the pixel loop.
| File | Description |
|---|---|
| rootfs/lib/p5.rb | P5 Ruby class |
| dvi_graphics_draw.c | Shape primitives (rect, circle, ellipse, triangle, arc, line) |
| dvi_graphics_text.c | Text rendering and measurement |
| dvi_graphics_draw.h | C drawing API declarations |
| dvi.c | Ruby bindings for DVI::Graphics |
- Processing: Creative coding environment (original inspiration)
- p5.js: JavaScript port of Processing