skrift-color

A Skrift plugin that renders colour glyphs (colour emoji) to RGBA, in the two formats that matter in practice:

  • COLR/CPAL (v0) — layered vector glyphs (Segoe-style emoji, Twemoji-COLR builds). Each layer is an ordinary outline drawn in a flat palette colour; the plugin rasterises each layer with skrift's monochrome renderer and composites them.
  • CBDT/CBLC — embedded PNG bitmaps (e.g. Noto Color Emoji, the usual colour emoji font on Linux). The plugin extracts the glyph's PNG, decodes it (pure Ruby, via zlib), and scales it to the requested size.

Skrift::Color::Renderer#render tries COLR first, then CBDT, and returns the same RGBA Skrift::Color::Image either way (or nil to fall back to mono). It's pure Ruby with no extra dependencies, and the core skrift renderer stays monochrome — colour is entirely opt-in.

Scope

  • Supported: COLR v0 + CPAL (layered vector), and CBDT/CBLC with image format 17 + index format 1 (PNG bitmaps, as Noto Color Emoji uses).
  • Not (yet) supported: COLR v1 (gradients/transforms), sbix, OT-SVG, less common CBLC index/image formats, and ZWJ / multi-codepoint emoji sequences.

Usage

require "skrift"
require "skrift/color"

font = Skrift::Font.load("emoji.ttf")
colr = Skrift::Color::Renderer.new(font, x_scale: 64, y_scale: 64)

if (img = colr.render(0x1F600))   # nil if the codepoint has no COLR glyph
  # img is a Skrift::Color::Image: width, height, and `pixels`, a row-major
  # array of packed 0xRRGGBBAA integers (straight alpha).
  img.pixels.each_slice(img.width) { |row| ... }
else
  # fall back to skrift's normal monochrome rendering
end

Example

examples/color_preview.rb renders a colour glyph and previews it as ANSI 24-bit-colour terminal output (alpha-composited over a checkerboard) plus a saved RGBA PNG. With no arguments it uses the bundled synthetic fixture:

ruby examples/color_preview.rb                       # the fixture glyph
ruby examples/color_preview.rb Twemoji.ttf 0x1F600 96 grin.png

Tests

The specs run against a tiny synthetic COLR/CPAL font built with fontTools (committed under spec/fixtures/). Rebuild it with rake fixtures (needs python3 + fonttools).

License

ISC. See LICENSE.txt.