P5 Drawing Library
P5 is a drawing library inspired by Processing and p5.js. It wraps DVI::Graphics and provides an easy-to-use API for fill and stroke colors, coordinate transforms, blend modes, text drawing, and more.
Table of Contents
- Basic Usage
- Screen Control
- Colors and Styles
- Blend Modes
- Drawing Shapes
- Drawing Curves
- Drawing Text
- Images and Pixels
- Coordinate Transforms
Basic Usage
Create an instance with P5.new, draw shapes and text, then call commit to display on screen.
require "p5"
p5 = P5.new
p5.background(0x00) # Fill the screen with black
p5.fill(p5.color(200, 0, 0)) # Set fill color to red
p5.stroke(0xFF) # Set stroke color to white
p5.circle(160, 120, 50) # Draw a circle
p5.text_font(DVI::Graphics::FONT_MPLUS_12)
p5.text("Hello!", 10, 10) # Draw text
p5.commit # Display on screen
Initial State
An instance created with P5.new is initialized with the following state.
| Property | Initial Value |
|---|---|
| Fill color | 0xFF (white), enabled |
| Stroke color | 0xFF (white), enabled |
| Stroke weight | 1 pixel |
| Font | DVI::Graphics::FONT_8X8 |
| Text color | 0xFF (white) |
| Text alignment | Horizontal :left, vertical :top |
| Line spacing | 0 (no extra) |
| Coordinate transform | None (identity matrix) |
Resolution Switching
In Harucom’s graphics mode, you can switch between two resolutions: 640x480px (default) and 320x240px.
Use DVI::Graphics.set_resolution to switch, and width and height will change accordingly.
DVI::Graphics.set_resolution(320, 240) # Switch to 320x240
p5 = P5.new
p5.width #=> 320
p5.height #=> 240
# Switch back to 640x480
DVI::Graphics.set_resolution(640, 480)
Screen Control
P5.new
p5 = P5.new
Creates a new P5 instance and switches to graphics mode.
P5#width
p5.width #=> 640 or 320
Returns the width of the framebuffer in pixels.
P5#height
p5.height #=> 480 or 240
Returns the height of the framebuffer in pixels.
P5#background(color)
p5.background(0x00) # Fill with black
# or
p5.background(p5.color(0, 0, 0)) # Fill with black
Fills the entire screen with the specified RGB332 color.
P5#commit
p5.commit
Waits for VBlank (vertical blanking interval), then copies the back buffer to the front buffer for display. Call this after all drawing for one frame is complete.
Colors and Styles
Colors are specified in RGB332 format (1 byte). The color method converts standard RGB values (0-255)
to this format.
P5#fill(color)
p5.fill(0xE0) # Fill with red
# or
p5.fill(p5.color(255, 0, 0))
Sets the fill color for subsequent shapes and enables filling.
P5#no_fill
p5.no_fill
Disables filling for subsequent shapes.
P5#stroke(color)
p5.stroke(0xFF) # White outline
Sets the stroke (outline) color for subsequent shapes and enables stroke drawing.
P5#no_stroke
p5.no_stroke
Disables stroke (outline) drawing for subsequent shapes.
P5#stroke_weight(w)
p5.stroke_weight(3) # 3-pixel wide lines
Sets the stroke thickness in pixels. Affects line, triangle outlines, etc.
P5#color(r, g, b)
red = p5.color(255, 0, 0) #=> RGB332 red
green = p5.color(0, 255, 0) #=> RGB332 green
Converts RGB values (0-255 each) to an RGB332 color value (1 byte).
Blend Modes
P5#blend_mode(mode)
p5.blend_mode(P5::ADD)
Changes the pixel compositing method. Available modes:
| Constant | Behavior |
|---|---|
P5::REPLACE |
Overwrite (default) |
P5::ADD |
Per-channel addition (saturating) |
P5::SUBTRACT |
Per-channel subtraction (saturating) |
P5::MULTIPLY |
Per-channel multiply |
P5::SCREEN |
Per-channel screen compositing |
P5#alpha(value)
p5.alpha(128) # Semi-transparent
Enables alpha blending and sets the opacity (0-255). 0 is fully transparent, 255 is fully opaque.
Drawing Shapes
Shapes are filled with the current fill color (fill) and outlined with the stroke color (stroke).
They are affected by coordinate transforms (translate, rotate, scale).
P5#point(x, y)
p5.point(100, 50)
Draws a single pixel at (x, y). Uses the stroke color.
P5#line(x0, y0, x1, y1)
p5.line(0, 0, 100, 100)
Draws a line from (x0, y0) to (x1, y1). Stroke color and weight are applied.
P5#rect(x, y, w, h)
p5.rect(10, 10, 100, 50)
Draws a rectangle with (x, y) as the top-left corner, width w, and height h. When rotation is applied, it is internally drawn as two triangles.
P5#circle(cx, cy, r)
p5.circle(160, 120, 50)
Draws a circle centered at (cx, cy) with radius r.
If scale applies different horizontal and vertical factors, it is drawn as an ellipse.
P5#ellipse(cx, cy, rx, ry)
p5.ellipse(160, 120, 80, 40)
Draws an ellipse centered at (cx, cy) with horizontal radius rx and vertical radius ry.
P5#triangle(x0, y0, x1, y1, x2, y2)
p5.triangle(100, 10, 50, 90, 150, 90)
Draws a triangle connecting three vertices.
P5#arc(cx, cy, r, start_angle, stop_angle)
p5.arc(160, 120, 50, 0, Math::PI / 2)
Draws a pie slice (arc sector) centered at (cx, cy) with radius r. Angles are specified in radians (0 is right, PI/2 is down).
Drawing Curves
P5#bezier(x1, y1, x2, y2, x3, y3, x4, y4)
p5.bezier(10, 10, 40, 80, 120, 80, 150, 10)
Draws a cubic Bezier curve from (x1, y1) to (x4, y4). (x2, y2) and (x3, y3) are the control points. Approximated with 20 line segments.
P5#curve(x1, y1, x2, y2, x3, y3, x4, y4)
p5.curve(0, 0, 50, 50, 100, 20, 150, 80)
Draws a Catmull-Rom spline curve. The curve is drawn between (x2, y2) and (x3, y3), with (x1, y1) and (x4, y4) used as guides that determine the curve’s shape. Approximated with 20 line segments.
Drawing Text
P5#text_font(font, wide_font = nil)
p5.text_font(DVI::Graphics::FONT_MPLUS_12)
p5.text_font(DVI::Graphics::FONT_MPLUS_12, DVI::Graphics::FONT_MPLUS_J12)
Sets the font used for text drawing. If a wide font is specified as the second argument, full-width characters (such as Japanese) can be displayed through Unicode-to-JIS conversion.
P5#text_color(color)
p5.text_color(0xE0) # Red text
Sets the text color.
P5#text_align(horizontal, vertical = :top)
p5.text_align(:center, :center)
Sets the text alignment.
- Horizontal:
:left,:center,:right - Vertical:
:top,:center,:bottom
P5#text_leading(pixels)
p5.text_leading(4)
Sets the additional line spacing in pixels. Added to the font’s glyph height.
P5#text_width(str)
w = p5.text_width("Hello")
Returns the width in pixels that the string would occupy when drawn with the current font.
P5#text(str, x, y)
p5.text("Hello, world!", 10, 10)
Draws a UTF-8 string at position (x, y).
The drawing position is adjusted according to the alignment set by text_align.
Among coordinate transforms, translation is applied to the text position.
Images and Pixels
P5#image(data, x, y, w, h)
p5.image(pixel_data, 10, 10, 32, 32)
Draws RGB332 image data (byte array) at position (x, y). w and h are the image width and height.
P5#image_masked(data, mask, x, y, w, h)
p5.image_masked(pixel_data, mask_data, 10, 10, 32, 32)
Draws an image with a transparency mask. The mask is 1bpp (1 bit per pixel) transparency data.
P5#get_pixel(x, y)
c = p5.get_pixel(100, 50)
Returns the RGB332 color value of the pixel at (x, y).
P5#set_pixel(x, y, color)
p5.set_pixel(100, 50, 0xE0)
Sets the pixel at (x, y) to the specified RGB332 color.
Coordinate Transforms
Coordinate transforms let you change the position, angle, and size of drawn shapes.
Transforms are managed internally as an affine transformation matrix, and each call to
translate, rotate, or scale is multiplied into the current matrix.
P5#translate(tx, ty)
p5.translate(100, 50)
Translates the coordinate system by (tx, ty).
P5#rotate(angle)
p5.rotate(Math::PI / 4) # Rotate 45 degrees
Rotates the coordinate system by angle (in radians).
P5#scale(sx, sy = sx)
p5.scale(2) # Scale 2x in both directions
p5.scale(2, 0.5) # Scale 2x horizontal, 0.5x vertical
Scales the coordinate system. If only one argument is given, both axes use the same factor.
P5#push_matrix
p5.push_matrix
Saves the current transformation matrix onto the stack.
Call pop_matrix later to restore this state.
P5#pop_matrix
p5.pop_matrix
Restores the transformation matrix previously saved by push_matrix.
P5#reset_matrix
p5.reset_matrix
Resets the transformation matrix to its initial state (identity matrix). All transforms are cleared.