palcomp(1)

Name
palcomp — palette composer

Syntax
palcomp [-v] [commands...]

Description
palcomp can be used to generate palettes for terminals. The most important realization is that programs running within a terminal and which use console_codes(4) to set colors rely on the contrast of the colors produced by a color pairing to be proportional to the contrast those two codes have when using the VGA color palette. For this reason, a mainstay of this program is to operate using a colorspace with perceptual uniformity, i.e. CIELAB/LCh.

Most commands operate on a single palette, but it is possible to store multiple palettes in memory. The current working palette is called "0" (cf. loadreg/savereg). Each palette is kept in multiple colorspaces (currently sRGB and LCh), so as to avoid e.g. RGB-to-LCh-to-RGB conversion round-trips when modifying the lightness.

Options

-q  Reduce output. (Affects e.g. ct and ct256 commands.)

-v  Generate debugging output.

Commands

  b0
Set color 0 to actual black.

  bd
When the palcomp xterm command is used, also emit a colorBD parameter and use color 15.

  bg
When the palcomp xterm command is used, also emit a -bg parameter and use color 0.

  blend=pct,name
RGB-blend the current palette with another; performs `output := curpal*(100-pct) + secondpal*pct`. pct should be in the range 0..100.

  ct
Print the 16-color table.

  ct256
Print 256-color cubes and tables.

  cxl
Print a contrast analysis of the palette based on brightness differences.

  cxa
Print a contrast analysis of the palette based on Myndex Advanced Perceptual Contrast Algorithm (APCA W3). Be aware of the Helmholtz–Kohlrausch effect, where certain highly saturated colors appear brighter than their measured luminance would imply; in other words, a color pair might appear more legible than the computed contrast value indicates.

  eq[=b]
Equalize (equal-space) the lightness values of the palette's colors. The b parameter (0 <= b <= 100) specifies the mandatory lightness difference from the darkest to 2nd darkest color. In practice, b specifies the lightness value that blue is to be assigned. If b is absent, uses b=1/16.

  eval=expr
Evaluate an (almost) arbitrary expression for every palette entry. The identifiers r, g and b refer to RGB components of the palette entry. The identifiers l, c and h refer to LCh components of the palette entry. x, y and z refer to temporaries free for use. Known operators are +, -, *, /, ^ (exponentiation), , (comma operator) and =. Grouping with (...) is recognized.

As a shorthand, if expr begins with an opening parenthesis or a one-letter identifier followed by =, the expression can also be used as a command without the need to type eval=.

  eval@LIST=expr
Evaluate expression for the given colors. LIST shall be a comma-separated list of palette indices or index ranges, e.g. "0,4-7,12".

  fg
When the palcomp xterm command is used, also emit a -fg parameter and use color 7.

  hsltint=h,s,l
Map the (LCh) brightnesses onto a color line through the HSL cylinder that goes from black to the chosen color. Parameter ranges are (0 <= h < 360; 0 <= s < 1; 0 <= l <= 1). When using s<=0.5, this produces a black-to-{color} ramp; when using s==1, this produces a black-to-{color}-to-white ramp.

hsltint produces a somewhat more contrasty result than manipulating hue (h) and saturation/chromaticity (c) in LCh. Compare:

•   palcomp vgs c=100 h=120 emit

•   palcomp vgs hsltint=90,1,0.5 emit

  hsltint=#rrggbb[,l]
A different syntax for the hsltint operation. First, the RGB value for the tint color is converted to HSL. The so-computed L value can be overridden with the optional ,l suffix. Afterwards, behaves like hsltint=h,s,l.

  ild=t
Set the white point to be a series D illuminant at color temperature t. (t should be in the range 4000..25000 K). This only has an effect for the "cxa" command. (Commands like hue/lightness modification all use libbabl, which hardcodes D65.) The default white point used by palcomp is ild=6500. Note that D65 is not exactly 6500 K, due to changes of the Planck constant between when Illuminant D was first defined and 2019.

  inv16
Perform color inversion the way Norton Icon Editor did it.

  lch
Emit the LCh form of the palette to stdout (no particular formatting).

  lchtint=h,s,l

  lchtint=#rrggbb[,l]
Replace the LCh hue and saturation by the base color given in HSL or RGB. The LCh L value is retained as-is.

  loadpal=
Load RGB palette from a file. xfce4-terminal *.theme files and termux *.properties files are understood.

  loadreg=name
Set the working palette ("0") to the contents of the named palette.

  loeq[=b[,g]]
Equalize (equal-space) the lightness values of the palette's low-intensity colors plus darkgray. The b parameter (0 <= b <= g <= 100) specifies the mandatory lightness difference from the darkest to 2nd darkest color. In practice, b specifies the lightness value that blue is to be assigned. The g parameter (b <= g <= 100) specifies the lightness that the brightest color of the low-intensity section is to use (in practice, the lightness for grey). If g is absent, defaults to g=88.88; this is so that gray is still a little less intense than white. If b is absent, uses b=11.11.

  savereg=name
Save the current working palette ("0") to a new name.

  syncfromlch

  syncfromrgb
Explicitly synchronize palette representations. This can be used to experiment with value clippings (e.g. `palcomp vgs 'l=l*2' syncfromrgb 'l=l/2'`; the result of l*2 normally cannot be represented in RGB and causes clipping).

  vga
Loads the standard VGA palette.

  vgs
Loads a full-saturated VGA palette.

  win
Loads the standard Windows palette.

  xfce
Emit the palette as a line for an xfce4-terminal theme file.

  xterm
Emit the palette as xterm command line options. Use e.g. `xterm $(palcomp vga h=120 xterm)` to utilize.

Examples

Amber tint via LCh color space:

•   palcomp vgs lchtint=#ef951d fg b0 emit

Black-to-green ramp (tint via HSL color space):

•   palcomp vgs hsltint=120,1,0.5 emit

•   palcomp vgs hsltint=#00ff00 emit

Black-to-green-white ramp (tint via HSL color space):

•   palcomp vgs hsltint=120,1,1 emit

•   palcomp vgs hsltint=#00ff00,1 emit

Transmissive LCD effect, e.g. full command:

•   xterm $(palcomp vgs hsltint='#afc759' fg xterm) -bg '#102e2c'

Reflective LCD effect:

•   xterm $(palcomp vgs c=0 l=l/2 xterm) -bg '#8fa99e' -fg '#0a091b'

Caveats
Lightness in LCh space behaves a bit counterintuitive. When (saturation) c>0, then L=0 does not mean black, e.g.:
$ palcomp vgs lchtint=#0000ff stat
{-0.000000,131.208094,301.364692}
ColorPalette=#0000a9;...

As a consequence, one needs to manipulate (shift and stretch) the L channel values more after lchtint, for example by using lightness addition/multiplication manipulations:

•   palcomp vgs lchtint=#0000ff 'l=(l-42)*1.74' lch xfce

•   palcomp vgs lchtint=#0080ff 'l=(l-25)*1.49' lch xfce

Stretching the brightness this way has the side-effect that all colors get a bit darker, which may be undesirable. Instead of combining a tint with lightness manipulation, I can recommend to force color 0 to black using the b0 command.

See also
hxtools(7)