Created
January 29, 2024 13:36
-
-
Save alvesvaren/767d9585f0ecbef18ef1c7c0492c4332 to your computer and use it in GitHub Desktop.
Text wrapping for the esphome display api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Put the files in the esphome folder of your home assistant configuration.
Usage in yaml: