-
-
Save alvesvaren/767d9585f0ecbef18ef1c7c0492c4332 to your computer and use it in GitHub Desktop.
#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 | |
); |
Thanks for this, it was very helpful. I had an urgent priority to add dad jokes to my e-paper display, least I die of boredom.
Note, I had to add #include esphome/components/font/font.h
to text_wrap.cpp
because it would error out on lack of reference to Font
. I also needed to change Font*
font to esphome::display::BaseFont* font
on the wrap_text function for the same reason.
Perhaps you have a reference to Font
somewhere else in your ESPHome config?
Anyway, it works like a charm! Thanks again.
This is great @alvesvaren. I have built on what you wrote, to make a printf format compatible version, that also allows you to specify a box anywhere on the screen (not just wrapping at the screen edge). Would you be willing for this to be added to the official esphome distribution?
If so, I am happy to create the pull request.
@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
Put the files in the esphome folder of your home assistant configuration.
Usage in yaml: