Skip to content

Instantly share code, notes, and snippets.

@alvesvaren
Created January 29, 2024 13:36
Show Gist options
  • Select an option

  • Save alvesvaren/767d9585f0ecbef18ef1c7c0492c4332 to your computer and use it in GitHub Desktop.

Select an option

Save alvesvaren/767d9585f0ecbef18ef1c7c0492c4332 to your computer and use it in GitHub Desktop.
Text wrapping for the esphome display api
#include <vector>
#include <string>
#include <sstream>
#include "esphome/components/display/display_buffer.h"
#include "text_wrap.h"
using namespace esphome;
using namespace esphome::display;
void wrap_text(DisplayBuffer* it, int x, int y, const char* text, Font* font, TextAlign align, float line_height) {
// Calculate the bounds of a single space character
int space_x1, space_y1, space_width, space_height;
it->get_text_bounds(x, y, " ", font, align, &space_x1, &space_y1, &space_width, &space_height);
// Break text into words
std::vector<std::string> words;
std::stringstream ss(text);
std::string word;
while (std::getline(ss, word, ' ')) {
words.push_back(word);
}
// Initialize variables for the wrapped text
int line_x = x;
int line_y = y;
int word_x1, word_y1, word_width, word_height;
std::string line;
// Iterate through the words and wrap them
for (const auto& w : words) {
it->get_text_bounds(line_x, line_y, w.c_str(), font, align, &word_x1, &word_y1, &word_width, &word_height);
if (line_x + word_width >= it->get_width()) {
// Print the current line and move to the next line
it->printf(x, line_y, font, align, "%s", line.c_str());
line_y += static_cast<int>(word_height * line_height);
line_x = x;
// Clear the line buffer
line.clear();
}
// Add the word to the line buffer and move the cursor
line += w;
line_x += word_width + space_width;
// If it's not the last word, add a space
if (!line.empty() && &w != &words.back()) {
line += " ";
}
}
// Print the last line
if (!line.empty()) {
it->printf(x, line_y, font, align, "%s", line.c_str());
}
}
#pragma once
#include "esphome/components/display/display_buffer.h"
void wrap_text(
esphome::display::DisplayBuffer* it, int x, int y,
const char* text, esphome::display::Font* font,
esphome::display::TextAlign align, float line_height
);
@alvesvaren
Copy link
Author

@davet2001 Sure, go for it! I just put this together pretty quickly for a project I had but it would be great to have it in esphome directly

@Omertron
Copy link

For anyone else that finds this, the line in text_wrap.h needs to change to:
const char* text, esphome::font::Font* font,

@jandechent
Copy link

jandechent commented Dec 11, 2025

  • I had to change esphome::display::DisplayBuffer to esphome::display::Display
  • I think I want to add color pass through too
  • I amended it to return the line_y as int to know where I can continue with yet another line.

@DougEdey
Copy link

I forked and added support for Color position, and returning the next line offset.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment