cops

package
v0.0.0-...-e2c65c2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2018 License: Apache-2.0 Imports: 0 Imported by: 0

README

cops

Cops is a Go library for rendering terminal user interfaces. Cops supports 24 bit color and pairs well with Go's color, image, and image/draw packages.

Cops models a terminal Display as an image with three layers:

  • Text *"github.com/borkshop/bork/internal/cops/textile".Textile
  • Foreground *"image".RGBA
  • Background *"image".RGBA

The display package provides a display type that models these three layers. Since the foreground and background layers are standard Go images, we can use Go's draw package and third-party image processing packages to composite color layers.

bounds := image.Rect(0, 0, 80, 23)
disp := display.New(bounds)

draw

Cops can draw displays with alpha transparency channels over lower display layers. Use the Draw method to compose displays in layers.

display.Draw(
    dst *display.Display,
    r image.Rectangle,
    src *display.Display,
    sp image.Point,
    op draw.Op, // draw.Over or draw.Src
)

Drawing will:

  • Overwrite the text layer for all non-empty text cells inside the rectangle. Fill the text with space " " to overdraw all cells.
  • Draw the foreground of the source over the foreground of the destination image. Typically, the foreground is transparent for all cells empty of text. Otherwise, this operation can have interesting results.
  • Draw the background of the source over the foreground of the destination image. This allows for translucent background colors on the source image partially obscuring the text of the destination image.
  • Draw the background of the source over the background of the destination image.

Cops defers the decision to render to 3, 4, 8, or 24 bit terminal color model to the very last phase of rendering, so application authors are free to use the gammut of any color model supported by Go, including third-party color models like HUSLuv, or pluck from the terminal 256 color palette in display.Colors.

render

The display package provides Render and RenderOver methods. The render method produces a sequence of bytes to write that will update a terminal, skipping over cells that have not changed.

Render(
    buf []byte,
    cur display.Cursor,
    dis *display.Display,
    model display.Model,
) (
    buf []byte,
    cur display.Cursor,
)

RenderOver(
    buf []byte,
    cur display.Cursor,
    over, under *display.Display,
    model display.Model,
) (
    buf []byte,
    cur display.Cursor,
)

The default display is blank and rendering it will cause no changes. Rendering a non-blank display over a blank display will effect a full display rewrite.

Render, like append, accepts and returns a slice of bytes, prefering to reuse the prior allocation, growing the allocation only when necessary.

Typical terminal applications swap a front and back display, drawing each frame over the previous.

var buf []byte
cur := display.Start
front, back := display.New2(bounds)
buf, cur = display.Render(buf, cur, front, back, display.Model24)
front, back = back, front
buf = buf[0:0]

Although the display models all colors in 32 bit RGBA, the color model samples these colors down to the terminal's supported color model.

cursor

Render accepts the current cursor state and returns the cursor state after applying the rendered bytes to the terminal. The display package provides the cursor type, which has methods for updating the cursor's position, foreground color, and background color. Each of these methods append to a buffer and return the resulting cursor state.

The initial cursor state is unknown, assuming nothing about the cursor position or coloring.

cur := display.Start

The differential update will attempt to use relative cursor position changes whenever possible, resorting to changes relative to the beginning of the same line if it loses track of its horizontal position, or relative to the home or display origin, only when the cursor position is wholely unknown.

Partial-display or log-leading renders are possible by postulating that the current cursor position at the origin and drawing around it.

cur := display.Reset

The cursor has methods to produce the commands that will show and hide the cursor, clear the display, reset its state, seek to the origin, or move to another cell's coordinates.

var buf []byte
cur := display.Start
buf, cur = cur.Hide(buf)
buf, cur = cur.Clear(buf)
buf, cur = cur.Home(buf)
os.Stdout.Write(buf)
buf = buf[0:0]

cur, buf = cur.Go(buf, image.Pt(10, 20))

buf, cur = cur.Home(buf)
buf, cur = cur.Clear(buf)
buf, cur = cur.Show(buf)
os.Stdout.Write(buf)
buf = buf[0:0]

colors

The display package provides the terminal colors, palettes, terminal rendering color models.

  • Colors is an array of 256 palette colors.
    • The first 8 are the 3-bit color palette.
    • The second 8 (8-15) are their bright versions from the 4-bit color palette.
    • The remaining colors form the 6x6x6 color cube and 24 grays scale.
  • Palette3, Palette4, and Palette8 are Go "image".Palette instances for colors expressible in those ranges.
  • Model0, Model3, Model4, Model8, and Model24 are virtual terminal color depth models with methods for rendering background and foreground colors to ANSI escape sequences, as used by "display".Render. Model0 is monochrome and does not render color. Model24 uses paletted colors only for exact matches.

textile

Displays have a text image or "textile" of strings. The textile package implements a text image, modeled after Go's "image" package.

text := textile.New(image.Rect(0, 0, 80, 23))

Just as with Go's images, the bounding box for the textile does not need to start at the origin, and subtexts share the same memory.

text.Subtext(image.Rect(1, 1, 79, 22)).Fill(".")

The default subtext is a matrix of nil strings. Nil strings are "transparent". Drawing a blank text over another textile effects no change.

Each cell of the textile may be a string of arbitrary length, so it is possible to model cells as sequences of UTF-8 including multiple code points with joiners.

The display render function is sensitive to the uncertainty whether these characters will necessarily be merged on the terminal display, invalidating the cursor's horizontal position after rendering each cell that contains more than one byte of text, then seeking to the next cell before rendering another.

text

The text package provides a convenience for rendering plain text onto a display. The Bounds(string) method returns a bounding rectangle by measuring how much space the string would need. The Write(*Display, Rectangle, string, Color) method can then write the string into a display.

front, back := display.New2(bounds)

msg := "Hello, Cops!"
msgbox := text.Bounds(msg)
center := rectangle.MiddleCenter(msgbox, bounds)
text.Write(front, center, msg, display.Colors[7])

The text package executes only the smallest subset of the terminal language, respecting "\n", "\t", and " ". Newline advances to the first column of the next line. Tab and space advance the cursor without drawing, leaving a transparent gap in the display.

Fill the bounds with " " or add a translucent or opaque background color to the display to occlude holes left by transparent space.

terminal

The terminal package is a thin wrapper around terminal control, to make terminal capability changes and restoration easy and idiomatic to Go.

term := terminal.New(os.Stdin.Fd())
defer term.Restore()
term.SetRaw()
term.SetNoEcho()

The Bounds() method returns an "image".Rectangle from the terminal size, suitable for constructing a virtual display of the same size.

bounds := term.Bounds()
front, back := display.New2(bounds)

bitmap

The bitmap package provides a memory compact image type for images with only two colors, as well as an image transformation layer that interprets another image as a bitmap of the closer match of two colors.

braille

The braille package draws bitmaps as matrices of braille dots. See cmd/braille/ for a demonstration.

Tips / Tricks

How to fill the background color for a text panel

panel := text.Display("Press any key to continue...", display.Colors[7])
draw.Draw(panel.Background, panel.Bounds(), &image.Uniform{color.NRGBA{63, 63, 63, 128}}, image.ZP, draw.Over)

The background color can be translucent. Drawing a display over another display:

  • overrides the foreground color for all cells with text, except empty and space cells.
  • draws the panel's background color over the foreground and background color of the underlying cell. This makes it possible to render translucent panels. The underlying text shows through, but faded by the overlying background color.
display.Draw(front, panel.Bounds(), panel, image.ZP, draw.Over)

Copyright 2017 Kristopher Michael Kowal and contributors. Apache 2.0 license.

Documentation

Overview

Package cops contains packages for rendering terminal user interfaces. Cops supports 24 bit color and pairs well with the "color", "image", and "image/draw" packages.

The "display" package models a display as foreground, background, and text layers. The display package provides Draw for composing display layers and Render for producing ANSI escape sequences to differentially update a terminal.

The display package also includes an ANSI cursor, colors, palettes, and rendering models for 0, 3, 4, 8, and 24 bit color.

The "textile" package implements a text layer, like Go's own "image" package.

The "text" package measures and cuts text onto a display.

The "terminal" package provides an idiomatic Go interface for terminal capabilities ("raw mode", "no echo", getting and setting size).

The "rectangle" package provides conveniences for manipulating image rectangles for display composition.

The "bitmap" package provides a compact representation of bitmap images, suitable for use as masks or sources for braille bitmap displays.

The "braille" package draws bitmap images onto displays as a matrix of braille text.

Directories

Path Synopsis
Package braille composites bitmaps as braille.
Package braille composites bitmaps as braille.
Package display models, composes, and renders virtual terminal displays using ANSI escape sequences.
Package display models, composes, and renders virtual terminal displays using ANSI escape sequences.
examples
vt
Package terminal provides an idiomatic Go interface for reading, writing, and restoring terminal capabilities.
Package terminal provides an idiomatic Go interface for reading, writing, and restoring terminal capabilities.
Package text measures and cuts raw text for terminal displays.
Package text measures and cuts raw text for terminal displays.
Package textile weaves strings into a text image.
Package textile weaves strings into a text image.
Package vtio provides a tool for drawing a ANSI stream onto a virtualized display.
Package vtio provides a tool for drawing a ANSI stream onto a virtualized display.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL