Skip to content

Commit cb3ae23

Browse files
committed
Add drawTextBox function
1 parent fa5e3ba commit cb3ae23

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed

src/include/Graphics.cpp

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,4 +271,105 @@ int16_t Graphics::width()
271271
int16_t Graphics::height()
272272
{
273273
return _height;
274-
};
274+
};
275+
276+
277+
/**
278+
* @brief Draws a text box with optional border and word-wrapped content
279+
*
280+
* @param int16_t x0
281+
* Top-left x-coordinate of the text box
282+
* @param int16_t y0
283+
* Top-left y-coordinate of the text box
284+
* @param int16_t x1
285+
* Bottom-right x-coordinate of the text box
286+
* @param int16_t y1
287+
* Bottom-right y-coordinate of the text box
288+
* @param const char* text
289+
* The null-terminated string to be rendered inside the box
290+
* @param uint16_t textSizeMultiplier
291+
* Size multiplier for the text
292+
* @param const GFXfont* font
293+
* Pointer to the font to use for rendering the text
294+
* @param uint16_t verticalSpacing
295+
* Vertical spacing (in pixels) between lines of text; if 0 or NULL, defaults to text height + padding
296+
* @param bool showBorder
297+
* Whether to draw a border around the text box
298+
* @param uint16_t fontSize
299+
* Font size in points (pt)
300+
*
301+
* @details This function renders a block of text inside the defined rectangular area.
302+
* It automatically wraps words to the next line if they exceed the available width.
303+
* If the text does not fit entirely, an ellipsis ("...") is added to the final visible line.
304+
* Text is padded with spaces to keep a consistent line length.
305+
*/
306+
void Graphics::drawTextBox(int16_t x0,int16_t y0,int16_t x1,int16_t y1, const char* text,uint16_t textSizeMultiplier, const GFXfont *font, uint16_t verticalSpacing, bool showBorder, uint16_t fontSize )
307+
{
308+
int16_t currentX = x0;
309+
int16_t currentY = y0;
310+
311+
int16_t textLenght=strlen(text);
312+
int offset=0;
313+
fontSize=(fontSize*3)/4; //1pt = 4/3 px
314+
int numOfCharactersPerLine=(x1-x0)/(textSizeMultiplier*fontSize);
315+
int16_t currentLineLenght=numOfCharactersPerLine;
316+
this->setTextSize(textSizeMultiplier);
317+
this->setFont(font);
318+
if(showBorder)
319+
{
320+
this->drawRect(x0,y0,(x1-x0),(y1-y0),1);
321+
}
322+
if(verticalSpacing==NULL)
323+
{
324+
verticalSpacing=textSizeMultiplier*fontSize+6;
325+
}
326+
for (int i = y0; i < (y1 - verticalSpacing); i += verticalSpacing)
327+
{
328+
currentY = i;
329+
this->setCursor(currentX, currentY);
330+
331+
int remainingLength = textLenght - offset;
332+
int lineLength = (remainingLength < currentLineLenght) ? remainingLength : currentLineLenght;
333+
334+
// Temporary buffer to hold potential line
335+
char* buffer = (char*)malloc((lineLength + 1) * sizeof(char));
336+
memcpy(buffer, text + offset, lineLength);
337+
buffer[lineLength] = '\0';
338+
339+
// Find the last space in buffer to wrap at word boundary
340+
int lastSpaceIndex = -1;
341+
for (int j = 0; j < lineLength; ++j) {
342+
if (buffer[j] == ' ') lastSpaceIndex = j;
343+
}
344+
345+
// If a word gets cut, wrap to the next line
346+
if ((offset + lineLength < textLenght) && (text[offset + lineLength] != ' ') && (lastSpaceIndex != -1) && ((i + verticalSpacing) < (y1 - verticalSpacing))) {
347+
lineLength = lastSpaceIndex + 1; // Include the space
348+
}
349+
350+
// Allocate space for actual line with null-terminator
351+
char* textPart = (char*)malloc((currentLineLenght + 1) * sizeof(char));
352+
memset(textPart, ' ', currentLineLenght); // Fill with spaces
353+
memcpy(textPart, text + offset, lineLength); // Copy valid part
354+
textPart[currentLineLenght] = '\0';
355+
356+
// Ellipsis on final visible line
357+
if ((i + verticalSpacing) >= (y1 - verticalSpacing) && (offset + lineLength < textLenght)) {
358+
359+
360+
textPart[currentLineLenght - 1] = '.';
361+
textPart[currentLineLenght - 2] = '.';
362+
textPart[currentLineLenght - 3] = '.';
363+
}
364+
365+
this->print(textPart);
366+
367+
offset += lineLength;
368+
free(buffer);
369+
free(textPart);
370+
371+
if (offset >= textLenght) return;
372+
}
373+
374+
375+
}

src/include/Graphics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Graphics : public Shapes, public Image
5555
uint8_t getRotation();
5656

5757
void drawPixel(int16_t x, int16_t y, uint16_t color) override;
58+
void drawTextBox(int16_t x0,int16_t y0,int16_t x1,int16_t x2, const char* text,uint16_t textSize=1, const GFXfont *font=NULL, uint16_t vericalSpacing=NULL, bool showBorder=false, uint16_t fontSize=8 );
5859

5960
#if !defined(ARDUINO_INKPLATECOLOR) && !defined(ARDUINO_INKPLATE2) && !defined(ARDUINO_INKPLATE4) && \
6061
!defined(ARDUINO_INKPLATE7)
@@ -99,6 +100,7 @@ class Graphics : public Shapes, public Image
99100
void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) override;
100101
void endWrite(void) override;
101102

103+
102104
uint8_t _displayMode = 0;
103105

104106
protected:

0 commit comments

Comments
 (0)