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

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.