mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 09:18:00 +01:00
Move wrap capability to lowest level print function
This commit is contained in:
parent
9b5904e7dc
commit
e9747cf6a2
2 changed files with 92 additions and 63 deletions
|
@ -343,6 +343,76 @@ void Display::print(int x, int y, BaseFont *font, Color color, TextAlign align,
|
||||||
font->print(x_start, y_start, this, color, text, background);
|
font->print(x_start, y_start, this, color, text, background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::print(int x, int y, int width, int height, BaseFont *font, Color color, TextAlign align, const char *text,
|
||||||
|
Color background, float line_height, bool wrap) {
|
||||||
|
int x_start, y_start;
|
||||||
|
if (wrap == false) {
|
||||||
|
this->get_text_bounds(x, y, text, font, align, &x_start, &y_start, &width, &height);
|
||||||
|
font->print(x_start, y_start, this, color, text, background);
|
||||||
|
} else {
|
||||||
|
// Calculate the bounds of a single space character
|
||||||
|
int space_x1, space_y1, space_width, space_height;
|
||||||
|
this->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 x_max = x + width;
|
||||||
|
int y_max = y + height;
|
||||||
|
int word_x1, word_y1, word_width, word_height;
|
||||||
|
bool last = false;
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
// Iterate through the words and wrap them
|
||||||
|
for (const auto &w : words) {
|
||||||
|
this->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 >= x_max) {
|
||||||
|
// If the next line would overspill the height box, get ready to stop.
|
||||||
|
if (line_y + 2 * static_cast<int>(word_height * line_height) > y_max) {
|
||||||
|
last = true;
|
||||||
|
size_t length = line.length();
|
||||||
|
const std::string cont = "...";
|
||||||
|
if (length >= cont.length()) {
|
||||||
|
line.replace(length - cont.length(), cont.length(), cont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Print the current line and move to the next line
|
||||||
|
font->print(x, line_y, this, color, line.c_str(), background);
|
||||||
|
if (last) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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()) {
|
||||||
|
font->print(x, line_y, this, color, line.c_str(), background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Display::vprintf_(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,
|
void Display::vprintf_(int x, int y, BaseFont *font, Color color, Color background, TextAlign align, const char *format,
|
||||||
va_list arg) {
|
va_list arg) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
@ -483,79 +553,21 @@ void Display::printf(int x, int y, BaseFont *font, const char *format, ...) {
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::printf(int x, int y, int width, int height, BaseFont *font, float line_height, const char *format, ...) {
|
void Display::printf(int x, int y, int width, int height, BaseFont *font, Color color, Color background,
|
||||||
|
float line_height, const char *format, ...) {
|
||||||
// Text wrapping printf based on https://gist.github.com/alvesvaren/767d9585f0ecbef18ef1c7c0492c4332
|
// Text wrapping printf based on https://gist.github.com/alvesvaren/767d9585f0ecbef18ef1c7c0492c4332
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
|
|
||||||
TextAlign align = TextAlign::TOP_LEFT;
|
TextAlign align = TextAlign::TOP_LEFT;
|
||||||
|
|
||||||
// Calculate the bounds of a single space character
|
|
||||||
int space_x1, space_y1, space_width, space_height;
|
|
||||||
this->get_text_bounds(x, y, " ", font, align, &space_x1, &space_y1, &space_width, &space_height);
|
|
||||||
|
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
int ret = vsnprintf(buffer, sizeof(buffer), format, arg);
|
int ret = vsnprintf(buffer, sizeof(buffer), format, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Break text into words
|
this->print(x, y, width, height, font, color, align, buffer, background, line_height, true);
|
||||||
std::vector<std::string> words;
|
|
||||||
std::stringstream ss(buffer);
|
|
||||||
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 x_max = x + width;
|
|
||||||
int y_max = y + height;
|
|
||||||
int word_x1, word_y1, word_width, word_height;
|
|
||||||
bool last = false;
|
|
||||||
std::string line;
|
|
||||||
|
|
||||||
// Iterate through the words and wrap them
|
|
||||||
for (const auto &w : words) {
|
|
||||||
this->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 >= x_max) {
|
|
||||||
// If the next line would overspill the height box, get ready to stop.
|
|
||||||
if (line_y + 2 * static_cast<int>(word_height * line_height) > y_max) {
|
|
||||||
last = true;
|
|
||||||
size_t length = line.length();
|
|
||||||
const std::string cont = "...";
|
|
||||||
if (length >= cont.length()) {
|
|
||||||
line.replace(length - cont.length(), cont.length(), cont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Print the current line and move to the next line
|
|
||||||
this->printf(x, line_y, font, align, "%s", line.c_str());
|
|
||||||
if (last) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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()) {
|
|
||||||
this->printf(x, line_y, font, align, "%s", line.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::set_writer(display_writer_t &&writer) { this->writer_ = writer; }
|
void Display::set_writer(display_writer_t &&writer) { this->writer_ = writer; }
|
||||||
|
|
|
@ -340,6 +340,21 @@ class Display : public PollingComponent {
|
||||||
void print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text,
|
void print(int x, int y, BaseFont *font, Color color, TextAlign align, const char *text,
|
||||||
Color background = COLOR_OFF);
|
Color background = COLOR_OFF);
|
||||||
|
|
||||||
|
/** Print `text` with the anchor point at [x,y] with `font`.
|
||||||
|
*
|
||||||
|
* @param x The x coordinate of the text alignment anchor point.
|
||||||
|
* @param y The y coordinate of the text alignment anchor point.
|
||||||
|
* @param width The width of the bounding box to print text into.
|
||||||
|
* @param height The height of the bounding box to print text into.
|
||||||
|
* @param font The font to draw the text with.
|
||||||
|
* @param color The color to draw the text with.
|
||||||
|
* @param align The alignment of the text.
|
||||||
|
* @param text The text to draw.
|
||||||
|
* @param background When using multi-bit (anti-aliased) fonts, blend this background color into pixels
|
||||||
|
*/
|
||||||
|
void print(int x, int y, int width, int height, BaseFont *font, Color color, TextAlign align, const char *text,
|
||||||
|
Color background = COLOR_OFF, float line_height = 1.0, bool wrap = true);
|
||||||
|
|
||||||
/** Print `text` with the top left at [x,y] with `font`.
|
/** Print `text` with the top left at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
* @param x The x coordinate of the upper left corner.
|
* @param x The x coordinate of the upper left corner.
|
||||||
|
@ -438,12 +453,14 @@ class Display : public PollingComponent {
|
||||||
* @param width The x width of the of the box to to fill before word-wrapping.
|
* @param width The x width of the of the box to to fill before word-wrapping.
|
||||||
* @param height The y height of the of the box to to fill before truncating with a '...'.
|
* @param height The y height of the of the box to to fill before truncating with a '...'.
|
||||||
* @param font The font to draw the text with.
|
* @param font The font to draw the text with.
|
||||||
|
* @param color The color to draw the text with.
|
||||||
|
* @param background The background color to use for antialiasing.
|
||||||
* @param line_height A multiplier for the line height. Set to 1.0 for standard line spacing.
|
* @param line_height A multiplier for the line height. Set to 1.0 for standard line spacing.
|
||||||
* @param format The format to use.
|
* @param format The format to use.
|
||||||
* @param ... The arguments to use for the text formatting.
|
* @param ... The arguments to use for the text formatting.
|
||||||
*/
|
*/
|
||||||
void printf(int x, int y, int width, int height, BaseFont *font, float line_height, const char *format, ...)
|
void printf(int x, int y, int width, int height, BaseFont *font, Color color, Color background, float line_height,
|
||||||
__attribute__((format(printf, 8, 9)));
|
const char *format, ...) __attribute__((format(printf, 10, 11)));
|
||||||
|
|
||||||
/** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
|
/** Evaluate the strftime-format `format` and print the result with the anchor point at [x,y] with `font`.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue