Rainbow Ripple, how do you ripple?

by David Jones

Rainbow Ripple Matrix Mono is my first experiment with making a COLRv0 font. The font combines COLR technology with selectable colourways and smart rules to create a harmonised colour change across the text. I call this the Ripple System.

The graphic form of the font is from the Epson FX-80 dot matrix printer.

Here’s an example of the font in a box that you should be able to edit:

Rainbow Ripple Matrix Mono

Get Ready to put some Rainbow Ripple in your typography!

The experimental nature of this font (and mostly the tools used to make it) meant that for about 1 year it had a bug where it didn’t display on macOS Firefox Desktop browser, but did everywhere else; macOS Firefox Desktop is, of course, my main browser. That bug should be fixed (short version: do not lie about your glyph bounding boxes), but do let me know if there are problems.

The font is in a preview and testing stage and there are a couple of other issues to fix as well: the left side-bearing and the somewhat limited character repertoire.

All the glyphs are made from dots that lie on a particular grid; this is in some ways similar to pixel fonts.

Coloured dots

In this font each dot is coloured and the colours are chosen to give a rainbow colouring that ripples across the letters. Each dot has a single flat colour and they are chosen from a small palette; this suits the OpenType COLRv0 format very well.

COLRv0 was designed to be simple to implement with the existing font rendering systems: Build up a a colour glyph by rendering a sequence of layers with each layer rendered in a single colour. That is more or less how the COLR (version 0) table works: a colour glyph has an entry in the COLR table and consists of a number of layers; each layer has a single colour and a shape. The shape of a layer is defined by reference to another glyph in the font file.

A relatively simple rendering system can be made by taking each layer in turn and rendering the layer glyph in its colour into a buffer and repeating until all the layers are rendered.

I’ll illustrate that with R from this font. It breaks down into these pieces:

Pieces of R

There may be empty layers, depending on the letter shape and the repeating tile shape. In this case there is 1 that is empty. In the current implementation empty layers are still defined 'ecause technically it’s easier to keep them than remove them (the extra space that these empty layers take up in the font file is dominated by the UTF-16 encoding of the glyph name). Even /space is broken down into several layer glyphs, all of which are empty. Hmm.

Let’s ripple

Ready for Rainbow Ripple? Try Ripple Today!

If you look at the R in this example you can see that the separate occurences of R have the same shape, but different colour. Different colourways, to borrow a term from the textile industry. At least, they will have different colourways if they appear at different positions along the line. On a narrow mobile device you may be unlucky and have all the Rs start at the beginning of a line. In that case either edit the text, rotate your phone to landscape, or pretend that i was talking about the ps in «Ripple» instead.

I could have made one colourway per glyph and it would have made a nice COLRv0 font. But i was hooked and had to carry on.

Within each glyph the colours appear in sequence from left to right in a cyclic ripple that is the same across all glyphs. These rainbow examples use a palette of 7 colours, approximating a rainbow (that repeats). The colours themselves i re-used from Kate’s 12-bit rainbow palette.

That's neat. But note that the same rainbow cycle ripples across the letters consistently. The gaps between letters can make it hard to follow, because the palette still cycles but you can’t see it in the gap. It’s a little bit clearer using a mixture of H and N:

HNHHNNHNHNHHNNHNHNHHNNHNHNHHNNHNHNHHNNHNHNHHNNHN NHNNHHNHNHNNHHNHNHNNHHNHNHNNHHNHNHNNHHNHNHNNHHNH

Each colour glyph has one layer for each colour that appears in the glyph and the COLR table defines the colour and the shape. On a technical level, each colourway of each glyph is a new colour glyph that has a separate entry in the COLR table.

Fortunately, the layer glyphs that define shape can be re-used (for R we can see those in the breakdown above). All the colourways of R have the same number of layers and the same shapes, they are just coloured differently.

The glyphs that we start with in the text are uncoloured: a plain R, a plain a, and so on; i call these primary glyphs. They are directly mapped from unicode values (cmap table) and represent the uncoloured glyph shape.

For each primary glyph we have 7 colour glyphs, one for each colourway; and for each colourway we have 5 layer glyphs that define the geometry for a single colour (some of which may be empty, some of which may use the same colour as another layer, again for technical convenience). As i said, i re-use the layer glyphs for all the colourways of a primary. But that’s still 12 more glyphs for each primary, so a ×13 expansion.

The numbers can be fiddled a bit. The number of colourways depends on the palette and the shape of the repeating tile. The number of layer glyph shapes depends on the shape of the repeating tile.

In both cases the current Ripple System implementation has a saving of between 50 to 88% because the tile repeat "divides into" the width of all the glyphs (this is a mono font, so they are all the same). This saves in the number of colourways required. A more general set of widths for the glyph in the font would result in more colourways and another expansion in glyph numbers.

The magic of colour

Having 7 different colourways for each glyph doesn’t by itself do anything. In so far as fonts are magic (and they are), that magic has been created with...

OpenType Layout feature code.

Typically OpenType Layout feature code is used for things like contextual selection of alternate glyphs: for example when /f is followed by /b in korfball a feature code could be implemented to replaced /f with an f that does not collide with the /b, /f.calt say. Or we could replace /f/b with a ligature /f_b. The OpenType Layout features are also used much more extensively in so-called complex scripts (Arabic, Devanagari and so on).

The same feature code that gives a font contextual alternatives can be used to select colour glyphs.

NNNNNNNNN

Consider this row of N glyphs. Each particular N starts and ends with a certain colour, and, by extending the ripple to the next glyph, determines the colourway of the next glyph.

I happen to know that the first glyph in this sequence is called u004E.p0; u004E stands for unicode 004E which is LATIN CAPITAL LETTER N, and in Rainbow Ripple .p0 means use colourway 0. There is an OpenType feature rule of the form:

sub u004E.p0 u004E' by u004E.p12;

The prime (it’s an ASCII apostrophe really) in u004E' means that this rule is a contextual rule, and that u004E is the input (the rule is applied when the input matches). A contextual rule may use context before (and after, but in this case, just before) the input to decide what to do with the input. The input is marked with a prime in the rule. So u004E when preceded by u004E.p0 is substitued with u004E.p12 (the preceding context is unchanged). This is exactly the situation that the second N finds itself in. It is preceeded by u004E.p0 so the second N will get substituted by u004E.p12.

There are rules for every possible combination of primary glyph preceded by each colour glyph. In actual practice groups are used to keep the number of rules to a manageable level. In the feature file as defined, most of the rules are remarkably simple:

sub @next.p12 @primary' by @init.p12;

The @ syntax refers to a named group. @primary contains all the primary glyphs in sequence; @init.p12 contains the same glyphs in the same sequence, but in their p12 colourway. The @next.p12 group is all the glyphs whose colourway determines that the next glyph should be colourway p12. For this rainbow ripple pattern, only 7 rules are needed. The appropriate definition of the groups is A Small Matter of Programming.

In this way every single possible colour glyph will determine which colourway to use for the following primary.

At the beginning of a line (or paragraph, or whatever segment of text the font engine chooses), we need to prime the colour pump. Picking a colour glyph for the first glyph will cause all of the following glyphs to be coloured, but without that, nothing will change.

I have a set of rules used only at the start of line.

I have all sort of ideas here for magically and seemingly randomly choosing the starting colourway based on following context, but the prototype Ripple System did the simplest thing that could possibly work and picked the first colourway. That was not only sufficient, but for certain patterns gave a quite pleasing coherence of colour pattern across a whole page.

Those rules look like:

sub u004E' by u004E.p0;

This too is a contextual rule, note the prime in u004E, but without any context used. This is for technical reasons to do with lookup rule priority: in the middle of a line, it is important that the earlier rules are used, and that this rule is only applied at the beginning of a line.

Endless forms, most colourful

Of course all of the above is done with coding. In fact this font has never been touched with a “normal” font editor like FontForge or Glyphs. The font is the product of my own scripts in Python and font processing tools (mostly in Go), with the exception of makeotf used to compile the feature rules. Even the SVG for the dot was written by hand in a text editor.

The Ripple System scripts are sufficiently flexible that i can try many variations of tile shape and palette. I show a few here.

Rainbow Ripple Matrix Mono 102

Rainbow Ripple Matrix Mono 104

Rainbow Ripple Matrix Mono 106

Rainbow Ripple Matrix Mono 194

Rainbow Ripple Matrix Mono 196

Rainbow Ripple Matrix Mono 302

Rainbow Ripple Matrix Mono 412

Rainbow Ripple Matrix Mono 492

I even made a cool Univers/Bitstream style numbering system to save me making names for what turns out to be a near infinite number of variations.

Put a rainbow in your life now!

END