BlockText Rendering

The text rendering classes describe how terminal text is drawn into a writable buffer. They turn BlockString content into aligned labels, wrapped paragraphs, reusable text presets and animated headlines.

Bitmap fonts plug into the same pipeline through BlockTextOptions and BlockText. For font creation and font presets, see Font.

This page focuses on placing text inside rectangles, rendering wrapped text blocks, and reusing BlockTextOptions across multiple BlockText instances. For the underlying Block, BlockString and BlockStringEditor value types, see Strings and Chars.

Details about the example output on this page

The examples below were rendered with the dedicated documentation helper doc/tools/drawing-text-reference.cpp at a fixed width of 72 terminal columns. This makes it easy to regenerate the visual output together with the code snippets.

Usage

Drawing Direct Strings and Aligned Labels

WritableBuffer provides two main entry points for text that does not need paragraph formatting:

  • drawBlockText(Position, BlockString) writes text at an exact start position.

  • drawBlockText(BlockString, Rectangle, Alignment, Color) aligns text inside a rectangle.

auto footer = BlockStringEditor{};
footer.append(
    bg::BrightBlack,
    fg::BrightYellow,
    "[Q]",
    fg::BrightWhite,
    " quit  ",
    fg::BrightCyan,
    "[R]",
    fg::BrightWhite,
    " refresh");

buffer.drawBlockText(Position{4, 4}, footer);

buffer.drawFilledFrame(
    Rectangle{42, 2, 24, 5},
    FrameStyle::LightWithRoundedCorners,
    Block{" ", Color{fg::Inherited, bg::Blue}},
    Color{fg::BrightCyan, bg::Inherited});
buffer.drawBlockText("Overview", Rectangle{42, 2, 24, 5}, Alignment::Center, Color{fg::BrightWhite, bg::Inherited});

Use the position-based overload for status lines, overlays, and other exact placements. Use the rectangle overload for titles, centered labels, and other layout-driven text.

    drawBlockText(Position, BlockString)         drawBlockText(BlockString, Rectangle, ...) 
                                                                        
  012345678901234567890123456789          ╭──────────────────────╮      
                                                                      
    [Q] quit  [R] refresh                        Overview             
                                                                      
                                          ╰──────────────────────╯      
                                                                        
   exact position, mixed colors        same API, aligned in a rectangle 
                                                                        

BlockText Alignment Inside a Rectangle

BlockText uses the same Alignment model as the geometry and bitmap helpers. This means you can place a text block inside its target rectangle without manual offset calculations.

auto title = BlockText{BlockString{"Short note"}, Rectangle{26, 2, 20, 4}, Alignment::Center};
title.setColor(Color{fg::BrightYellow, bg::Inherited});
buffer.drawBlockText(title);

The same content can be anchored to the top-left, center, or bottom-right simply by changing the alignment value.

   BlockText uses the same alignment model as other geometry-aware drawing   
                                                                        
  ┌──────────────────┐    ┌──────────────────┐    ┌──────────────────┐  
Short note        │    │    Short note    │    │                  
                  │    │                  │    │        Short note
  └──────────────────┘    └──────────────────┘    └──────────────────┘  
        TopLeft                  Center               BottomRight       
                                                                        
                                                                        

Rendering Wrapped Paragraphs

BlockText becomes especially useful when text needs wrapping, paragraph spacing, or paragraph-aware indentation.

auto help = BlockText{
    BlockString{"Navigation: Use arrow keys to move.\n\nActions: Press Enter to open."},
    Rectangle{10, 3, 52, 7},
    Alignment::TopLeft};
help.setParagraphSpacing(ParagraphSpacing::DoubleLine);
help.setWrappedLineIndent(2);
help.setColor(Color{fg::BrightWhite, bg::Inherited});

buffer.drawBlockText(help);

This keeps the content, target rectangle, and paragraph behavior in one object. For the full paragraph-formatting reference, continue with Paragraph Options.

                                                                        
      ╔════════════════════════Help Panel════════════════════════╗      
                                                          
   Navigation: Use arrow keys to move.                    
                                                          
                                                          
                                                          
   Actions: Press Enter to open.                          
                                                          
                                                          
                                                          
      ╚══════════════════════════════════════════════════════════╝      
     Text automatically wraps and keeps explicit paragraph breaks.      

Reusing BlockTextOptions and Animation

BlockTextOptions bundles color sequences, fonts, animation, and paragraph layout settings into one reusable preset.

auto options = BlockTextOptions{Alignment::Center};
options.setColorSequence(
    ColorSequence{
        Color{fg::BrightYellow, bg::Inherited},
        Color{fg::BrightRed, bg::Inherited},
        Color{fg::BrightMagenta, bg::Inherited},
        Color{fg::BrightCyan, bg::Inherited},
    });
options.setAnimation(BlockTextAnimation::ColorDiagonal);

auto left = BlockText{BlockString{"ALERT PANEL"}, Rectangle{4, 3, 28, 2}, Alignment::Center};
left.setBlockTextOptions(options);
auto right = BlockText{BlockString{"ALERT PANEL"}, Rectangle{40, 3, 28, 2}, Alignment::Center};
right.setBlockTextOptions(options);

buffer.drawBlockText(left, 1);
buffer.drawBlockText(right, 3);

This works well when several labels or headings should share one visual style. BlockTextAnimation::ColorDiagonal shifts the configured color sequence diagonally across the rendered text based on the supplied animation cycle.

                      Reuse one BlockTextOptions preset                      
  ╭──────────────────────────────╮    ╭──────────────────────────────╮  
                              │    │                              
         ALERT PANEL          │    │         ALERT PANEL          
                              │    │                              
                              │    │                              
                              │    │                              
  ╰──────────────────────────────╯    ╰──────────────────────────────╯  
             cycle = 1                           cycle = 3