Font

The font classes allow you to render large, bitmap-based text directly in the terminal. You typically use fonts for titles, banners, or other decorative elements that should visually stand out in your interface.

A Font defines how characters are mapped to bitmap glyphs. These glyphs are then rendered onto the terminal buffer, giving you full control over how text appears beyond standard character rendering.

Details about the example output on this page

The examples below were rendered using the dedicated documentation helper doc/tools/font-reference.cpp at a fixed width of 72 terminal columns. This allows you to regenerate the visual output alongside the code snippets.

Usage

Rendering a Bitmap Font Title

Font integrates directly with Text. Assign a font to a Text instance and render it like any other text block.

auto title = Text{String{"COLOR TERM"}, Rectangle{0, 0, 60, 6}, Alignment::Center};
title.setFont(Font::defaultAscii());
title.setColorSequence(ColorSequence{
    Color{fg::BrightBlue, bg::Black},
    Color{fg::BrightCyan, bg::Black},
    Color{fg::BrightMagenta, bg::Black},
    Color{fg::BrightYellow, bg::Black},
});
title.setAnimation(TextAnimation::ColorDiagonal);

buffer.drawText(title, animationCycle);

The built-in defaultAscii() font renders large ASCII characters using a bitmap representation. Because fonts integrate seamlessly with Text, all existing features—such as alignment, color sequences, and animations—work without additional configuration.

This means you can treat bitmap text just like regular text while achieving a much stronger visual impact.

                    defaultAscii() for large titles                     
 Bitmap fonts still use Text alignment, color sequences, and animation. 
                                                                        
                                                         
                                                          
                                                        
                                                     
             animated headline in a regular Text rectangle              
                                                                        

Creating a Font from Row Masks

For small custom alphabets, the most direct approach is to create a Font with a fixed bitmap height and add only the glyphs you need using FontGlyph.

Each row in the bitmap is defined as a bitmask, where set bits represent filled pixels. This gives you precise control over the glyph shape while keeping the definition compact and efficient.

auto font = std::make_shared<Font>(5);
font->addGlyph("A", FontGlyph{std::vector<uint64_t>{
    0b01110U,
    0b10001U,
    0b11111U,
    0b10001U,
    0b10001U}});
font->addGlyph("M", FontGlyph{std::vector<uint64_t>{
    0b10001U,
    0b11011U,
    0b10101U,
    0b10001U,
    0b10001U}});
font->addGlyph("O", FontGlyph{std::vector<uint64_t>{
    0b01110U,
    0b10001U,
    0b10001U,
    0b10001U,
    0b01110U}});
font->addGlyph("T", FontGlyph{std::vector<uint64_t>{
    0b11111U,
    0b00100U,
    0b00100U,
    0b00100U,
    0b00100U}});

auto text = Text{String{"ATOM"}, Rectangle{0, 0, 72, 3}, Alignment::Center};
text.setFont(font);
text.setColor(Color{fg::BrightGreen, bg::Black});
buffer.drawText(text);

This approach works well for logos, badges, and domain-specific mini alphabets. A five-row bitmap font is rendered as three terminal rows because the renderer automatically packs the bitmap into Unicode block characters.

                       Custom font from row masks                       
   Add just the glyphs you need for logos, badges, or tiny alphabets.   
                                                                        
                              ▞▀▖▀▛▘▞▀▖▙▗▌                              
                              ▛▀▌ ▌ ▌ ▌▌▘▌                              
                              ▘ ▘ ▘ ▝▀ ▘ ▘                              
                  5 bitmap rows become 3 terminal rows                  
                                                                        

Embedding a Reusable Font Preset

If you want a custom font to live directly in your source tree, you can define glyphs as small pixel patterns and store them in a Font::GlyphMap.

This keeps glyph definitions readable and easy to maintain.

auto makeGlyph(std::initializer_list<std::string_view> rows) -> FontGlyph {
    auto bitmap = Bitmap::fromPattern(rows);
    auto glyph = FontGlyph{bitmap.size()};
    glyph.draw(Position{0, 0}, bitmap);
    return glyph;
}

auto makeClockFont() -> FontPtr {
    auto glyphs = Font::GlyphMap{};
    glyphs.emplace("1", makeGlyph({
        "..#..",
        ".##..",
        "..#..",
        "..#..",
        "..#..",
        "..#..",
        ".###."}));
    // ...
    return std::make_shared<Font>(7, std::move(glyphs));
}

auto clock = Text{String{"12:30"}, Rectangle{12, 3, 48, 4}, Alignment::Center};
clock.setFont(makeClockFont());
clock.setColor(Color{fg::BrightYellow, bg::Inherited});
buffer.drawText(clock);

This approach is ideal when you only need a limited alphabet, such as digits, status labels, or brand-specific glyphs. Characters that are not defined in the font are simply skipped during rendering.

                                                                        
          ╔═══════════════Embedded font preset═══════════════╗          
                                                  
                  ▗▌ ▟▜▖▖▀▜▖▟▜▖                   
                   ▌  ▟▘ ▗▟▘█▐▌                   
                   ▌ ▟▘ ▘ ▐▌█▐▌                   
                  ▝▀ ▀▀▘ ▀▀ ▝▀                    
    Build one GlyphMap and reuse the FontPtr.     
          ╚══════════════════════════════════════════════════╝          
                                                                        

Reusing Font Settings with TextOptions

Fonts are part of TextOptions. This allows you to bundle a font together with colors, animation, alignment, and paragraph settings, and then reuse that configuration across multiple Text instances.

auto options = TextOptions{Alignment::Center};
options.setFont(makeRowMaskFont());
options.setColorSequence(ColorSequence{
    Color{fg::BrightYellow, bg::Inherited},
    Color{fg::BrightRed, bg::Inherited},
    Color{fg::BrightMagenta, bg::Inherited},
});
options.setAnimation(TextAnimation::ColorDiagonal);

auto left = Text{String{"ATOM"}, Rectangle{4, 3, 28, 3}, Alignment::Center};
left.setTextOptions(options);
auto right = Text{String{"TOMATO"}, Rectangle{40, 3, 28, 3}, Alignment::Center};
right.setTextOptions(options);

buffer.drawText(left, 1);
buffer.drawText(right, 6);

This is especially useful if your application uses a consistent headline style across multiple views.

                      Reuse one TextOptions preset                      
  ╭──────────────────────────────╮    ╭──────────────────────────────╮  
                              │    │                              
                  │    │            
                     │    │                  
                       │    │                    
                              │    │                              
  ╰──────────────────────────────╯    ╰──────────────────────────────╯  
                 one font preset, multiple text blocks                  

Interface

class Font

A bitmap font used to render stylized terminal text.

Public Types

using GlyphMap = std::unordered_map<std::string, FontGlyph>

Mapping from UTF-8 character strings to glyph bitmaps.

Public Functions

Font() = default

Create an empty font with height 0.

explicit Font(int height) noexcept

Create an empty font with the given glyph height.

Parameters:

height – The glyph height in bitmap rows.

Font(int height, GlyphMap glyphs) noexcept

Create a font with the given glyph height and glyph map.

Parameters:
  • height – The glyph height in bitmap rows.

  • glyphs – The initial glyph map.

void addGlyph(std::string name, FontGlyph glyph)

Add or replace one glyph in this font.

Parameters:
  • name – The UTF-8 encoded character represented by the glyph.

  • glyph – The bitmap glyph.

void setHeight(int height) noexcept

Set the configured font height in bitmap rows.

Parameters:

height – The new glyph height.

int height() const noexcept

Get the configured font height in bitmap rows.

const GlyphMap &glyphs() const noexcept

Access the configured glyph map.

const FontGlyph *glyph(std::string_view name) const

Find one glyph by its UTF-8 character string.

Parameters:

name – The UTF-8 encoded character to look up.

Returns:

A pointer to the glyph, or nullptr if no glyph exists for name.

Public Static Functions

static FontPtr defaultAscii()

Create a new font instance with the built-in ASCII-centric default glyph set.

Returns:

A new shared font instance containing the default Latin letters, punctuation, and spacing glyphs.

using erbsland::cterm::FontPtr = std::shared_ptr<Font>

Shared pointer to a terminal font.

class FontGlyph : public erbsland::cterm::Bitmap

A bitmap glyph that can be used by a terminal text font.

Public Functions

FontGlyph() = default

Create an empty glyph.

inline explicit FontGlyph(const Size size) noexcept

Create an empty glyph with the given size.

Parameters:

size – The glyph dimensions.

template<typename T>
inline explicit FontGlyph(const std::vector<T> &data)

Create a glyph from numeric row masks.

Parameters:

data – One 64-bit mask per bitmap row.

Public Static Attributes

static constexpr auto cMaxGlyphWidth = 64

Maximum supported glyph width when importing numeric row masks.