GxEPD2_PP : Text is cutted and not printing as expected

I have been playing around with the fantastic lib GxEPD2_PP build by @ZinggJM :hugs:

Want to build a display that shows some citations. I had it working at some point and it looked like this:


But then I messed it all up..

Don't know what I did wrong.. But I have now moved it all out of web IDE and using the vscode particle workbench instead - so I can use git and be able to revert back (next time I mess up).

I would be very thankful if anybody can point out to me what I'm doing wrong.

I haven't refactored the code to be clean, yet - but it looks like this now:

/*

  • Project eCitations
  • Description:
  • Author: Lasse Norfeldt
  • Date: 2019
    */

#include <Adafruit_GFX_RK.h>
#include <GxEPD2_PP.h>

// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI: Waveshare e-paper displays with SPI - Displays - Arduino Forum
// Good Dispay ePaper for Arduino: Good Display ePaper for Arduino - Displays - Arduino Forum

// mapping suggestion from Waveshare SPI e-Paper to Particle Photon
// A5 MOSI
// A4 MISO
// A3 SCK
// A2 SS
// BUSY -> D4, RST -> A0, DC -> A1, CS -> A2, CLK -> A3, DIN -> A5, GND -> GND, 3.3V -> 3.3V
// NOTE: it looks like MISO can't be used as general input pin for BUSY.

// base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code
// enable or disable GxEPD2_GFX base class
#define ENABLE_GxEPD2_GFX 0

#include <Adafruit_GFX.h>
#include <Arduino.h>
#include <FreeSerifBoldItalic18pt7b.h>
#include <FreeSerifItalic18pt7b.h>

#include <GxEPD2_3C.h>
#include <GxEPD2_BW.h>

GxEPD2_3C<GxEPD2_750c, GxEPD2_750c::HEIGHT / 4>
display(GxEPD2_750c(/CS=A2/ SS, /DC=/A1, /RST=/A0, /BUSY=/D4));

void setup() {
// Debugging Serial
Serial.begin(115200);
Serial.println();
Serial.println("Starting eCitations");

display.init(115200);

delay(3000);

showCitation("**Jeg** elsker Josefine;Jeg **elsker** Isabella;Jeg elsker **Tyson**");

}

void loop() {
}

int countLines(String str) {
int i = str.indexOf(";");
if (i > 0) {
return countLines(str.substring(i + 1, str.length())) + 1;
} else {
return 1;
}
}

void showCitation(String citation) {
// Initial settings
display.setFullWindow();
display.fillScreen(GxEPD_WHITE);
display.setRotation(0);

// Start sending the print
display.firstPage();
do {
    // Get display width and height
    int dw = display.width();
    int dh = display.height();

    // Draw a red border
    int padding = 5;
    int stroke = 4;
    for (int p = padding; p < (padding + stroke + 1); p++) {
        display.drawRect(p, p, dw - 2 * p, dh - 2 * p, GxEPD_RED);
    }

    // Figure out how many lines there are
    int nLines = countLines(citation);
    Serial.println();
    Serial.print("nLines: ");
    Serial.println(nLines);

    // Loop through each line
    if (citation != "") {
        do {
            // Slice out a sentence to print
            int i_delimiter = citation.indexOf(";");
            String sentence = citation.substring(0, i_delimiter);
            citation = citation.replace(i_delimiter > 0 ? sentence + ";" : sentence, "");

            Serial.println();
            Serial.print("sentence: ");
            Serial.println(sentence);
            Serial.print("citation: ");
            Serial.println(citation);

            // Figuring out where to start placing the cursor
            String rawStr = String(sentence);
            String pureStr = String(sentence.replace("*", ""));
            int16_t t1bx, t1by;
            uint16_t t1bw, t1bh;
            display.getTextBounds(pureStr, 0, 0, &t1bx, &t1by, &t1bw, &t1bh);  // Don't take into account the different font width
            uint16_t x = (int)(dw - t1bw) / 2;
            uint16_t y = (int)((dh - 35 * nLines) / 2 + ((nLines - 1) * 40) + 20);
            display.setCursor(x, y);

            // Serial debugger
            Serial.print("x: ");
            Serial.println(x);
            Serial.print("y: ");
            Serial.println(y);

            // Fragment the sentence into blocks
            int strong;
            int space;
            if (rawStr.indexOf("**") == 0) {
                strong = 1;
                rawStr = rawStr.substring(2, rawStr.length());  // Dirty hacks
                x -= 5;
            } else {
                strong = 0;
            }
            rawStr = rawStr + "**";

            do {
                // Set font style and color
                if (strong == 1) {
                    display.setTextColor(GxEPD_RED);
                    display.setFont(&FreeSerifBoldItalic18pt7b);
                    strong--;
                    space = 2;
                } else {
                    display.setTextColor(GxEPD_BLACK);
                    display.setFont(&FreeSerifItalic18pt7b);
                    strong++;
                    space = 5;
                };

                // Find "**"
                int i_stars = rawStr.indexOf("**");

                // Print until "**"
                String prtStr = rawStr.substring(0, i_stars);
                display.print(prtStr);

                // Move cursor
                int16_t t2bx, t2by;
                uint16_t t2bw, t2bh;
                display.getTextBounds(prtStr, 0, 0, &t2bx, &t2by, &t2bw, &t2bh);
                x = x + t2bw + space;
                display.setCursor(x, y);

                // Remove until "**"
                rawStr = rawStr.substring(i_stars + 2, rawStr.length());

            } while (rawStr.indexOf("**") > 0);  // End of sentence block/fragments

        } while (citation.indexOf(";") > 0);  // End of sentence
    }                                         // End of IF

} while (display.nextPage());  // End of printing

Serial.println("Citation printed");

}

Here is a gist of the code:

Hi @Norfeldt

I read through your code and it doesn’t look like you ever use the returned value t2bh or anything else to increment the y value for the cursor position, say at the of one of the while loops. That didn’t seem correct to me if you wanted your display to have three lines of text.

thank you @bko for taking the time to look at my code. I appreciate it.

When I do particle serial monitor I get the following

Starting eCitations

nLines: 3

sentence: **Jeg** elsker Josefine
citation: Jeg elsker** Isabella;Jeg elsker **Tyson**
x: 263
y: 239

sentence: Jeg elsker** Isabella
citation: Jeg elsker **Tyson**
x: 197
y: 239
_PowerOn : 71646

nLines: 1

sentence: Jeg elsker **Tyson**
citation: 
x: 203
y: 194

nLines: 1

nLines: 1
_Update_Full : 31638663
_PowerOff : 39363
Citation printed

The y i moving (239, 239, 194) - but not correctly I agree

It looks like your code depends on nLines changing every time. I would try putting an extra ';' at end of your char array:

  showCitation("Jeg **elsker** Josefine;Jeg **elsker** Isabella;");

@bko I tried to do as you suggested

showCitation("Jeg **elsker** Josefine;Jeg **elsker** Isabella;");

Now it does not print anything (other than the red border). The serial indicates that y is the same for each:

Serial monitor opened successfully:

Starting eCitations

nLines: 4

sentence: **Jeg** elsker Josefine
citation: Jeg elsker** Isabella;Jeg elsker **Tyson**;
x: 263
y: 262

sentence: Jeg elsker** Isabella
citation: Jeg elsker **Tyson**;
x: 197
y: 262

sentence: Jeg elsker **Tyson**
citation: 
x: 203
y: 262
_PowerOn : 71649

nLines: 1

nLines: 1

nLines: 1
_Update_Full : 31650689
_PowerOff : 39361
Citation printed

I therefore moved the nLines into the loop and commented out a big section

#include <Adafruit_GFX_RK.h>
#include <GxEPD2_PP.h>
//...
#define ENABLE_GxEPD2_GFX 0

#include <Adafruit_GFX.h>
#include <Arduino.h>
#include <FreeSerifBoldItalic18pt7b.h>
#include <FreeSerifItalic18pt7b.h>

#include <GxEPD2_3C.h>
#include <GxEPD2_BW.h>

GxEPD2_3C<GxEPD2_750c, GxEPD2_750c::HEIGHT / 4> display(
    GxEPD2_750c(/*CS=A2*/ SS, /*DC=*/A1, /*RST=*/A0, /*BUSY=*/D4));

void setup() {
    // Debugging Serial
    Serial.begin(115200);
    Serial.println();
    Serial.println("Starting eCitations");

    display.init(115200);

    delay(3000);

    showCitation("**Jeg** elsker Josefine;Jeg elsker** Isabella;Jeg elsker **Tyson**");
}

void loop() {}

int countLines(String str) {
    int i = str.indexOf(";");
    if (i > 0) {
        return countLines(str.substring(i + 1, str.length())) + 1;
    } else {
        return 1;
    }
}

void showCitation(String citation) {
    // Initial settings
    display.setFullWindow();
    display.fillScreen(GxEPD_WHITE);
    display.setRotation(0);

    // Start sending the print
    display.firstPage();
    do {
        // Get display width and height
        int dw = display.width();
        int dh = display.height();

        // Draw a red border
        int padding = 5;
        int stroke = 4;
        for (int p = padding; p < (padding + stroke + 1); p++) {
            display.drawRect(p, p, dw - 2 * p, dh - 2 * p, GxEPD_RED);
        }

        // Loop through each line
        if (citation != "") {
            do {
                // Figure out how many lines there are
                int nLines = countLines(citation);
                Serial.println();
                Serial.print("nLines: ");
                Serial.println(nLines);

                // Slice out a sentence to print
                int i_delimiter = citation.indexOf(";");
                String sentence = citation.substring(0, i_delimiter);
                citation = citation.replace(i_delimiter > 0 ? sentence + ";" : sentence, "");

                Serial.println();
                Serial.print("sentence: ");
                Serial.println(sentence);
                Serial.print("citation: ");
                Serial.println(citation);

                // Figuring out where to start placing the cursor
                String rawStr = String(sentence);
                String pureStr = String(sentence.replace("*", ""));
                int16_t t1bx, t1by;
                uint16_t t1bw, t1bh;
                display.getTextBounds(
                    pureStr, 0, 0, &t1bx, &t1by, &t1bw,
                    &t1bh);  // Don't take into account the different font width
                uint16_t x = (int)(dw - t1bw) / 2;
                uint16_t y = (int)((dh - 35 * nLines) / 2 + ((nLines - 1) * 40) + 20);
                display.setCursor(x, y);

                // Serial debugger
                Serial.print("x: ");
                Serial.println(x);
                Serial.print("y: ");
                Serial.println(y);

                display.setTextColor(GxEPD_RED);                // ADDED
                display.setFont(&FreeSerifBoldItalic18pt7b);   // ADDED
                display.print(pureStr);                                       // ADDED

                // // Fragment the sentence into blocks
                // .... ALL COMMENTED OUT
                // } while (rawStr.indexOf("**") > 0);  // End of sentence block/fragments

            } while (citation.indexOf(";") > 0);  // End of sentence
        }                                         // End of IF

    } while (display.nextPage());  // End of printing

    Serial.println("Citation printed");
}

This does not work (only prints the red border - no text printed) - neither with ; or without it in the showCitation call.

The serial says the following:

Serial monitor opened successfully:

Starting eCitations

nLines: 4

sentence: **Jeg** elsker Josefine
citation: Jeg elsker** Isabella;Jeg elsker **Tyson**;
x: 263
y: 262

nLines: 3

sentence: Jeg elsker** Isabella
citation: Jeg elsker **Tyson**;
x: 263
y: 239

nLines: 2

sentence: Jeg elsker **Tyson**
citation: 
x: 272
y: 217
_PowerOn : 71651
_Update_Full : 31650578
_PowerOff : 39363
Citation printed

Well, that second serial output is very promising–it looks like the three strings are going to three different y coordinates, so I think you are close.

Why did you add the display.nextPage() call at the end of printing? I an not sure but I think that might be a problem.

Agree that the nLine fix is a step closer. But just weird that nothing is printed at all.

The use while (display.nextPage()); comes from the lib example. Think that it is something that is used to deliver small chunks of data to the display.

Looking at the helloWorld() in the code example:

void helloWorld()
{
  //Serial.println("helloWorld");
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  int16_t tbx, tby; uint16_t tbw, tbh;
  display.getTextBounds(HelloWorld, 0, 0, &tbx, &tby, &tbw, &tbh);
  uint16_t x = (display.width() - tbw) / 2;
  uint16_t y = (display.height() + tbh) / 2; // y is base line!
  display.setFullWindow();
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    display.setCursor(x, y);
    display.print(HelloWorld);
  }
  while (display.nextPage());
  //Serial.println("helloWorld done");
}
 // here we use paged drawing, even if the processor has enough RAM for full buffer
  // so this can be used with any supported processor board.
  // the cost in code overhead and execution time penalty is marginal
  // tell the graphics class to use paged drawing mode
  display.firstPage();
  do
  {
    // this part of code is executed multiple times, as many as needed,
    // in case of full buffer it is executed once
    // IMPORTANT: each iteration needs to draw the same, to avoid strange effects
    // use a copy of values that might change, don't read e.g. from analog or pins in the loop!
    display.fillScreen(GxEPD_WHITE); // set the background to white (fill the buffer with value for white)
    display.setCursor(x, y); // set the postition to start printing text
    display.print(text); // print some text
    // end of part executed multiple times
  }
  // tell the graphics class to transfer the buffer content (page) to the controller buffer
  // the graphics class will command the controller to refresh to the screen when the last page has been transferred
  // returns true if more pages need be drawn and transferred
  // returns false if the last page has been transferred and the screen refreshed for panels without fast partial update
  // returns false for panels with fast partial update when the controller buffer has been written once more, to make the differential buffers equal
  // (for full buffered with fast partial update the (full) buffer is just transferred again, and false returned)
  while (display.nextPage());

@bko You pointed me in the correct direction! It’s because I keep changning citation in the while loop.

This prints all 3 lines (but still needs some fiddling).

/*
 * Project eCitations
 * Description:
 * Author: Lasse Norfeldt
 * Date: 2019
 */

#include <Adafruit_GFX_RK.h>
#include <GxEPD2_PP.h>

// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI:
// http://forum.arduino.cc/index.php?topic=487007.0 Good Dispay ePaper for
// Arduino: https://forum.arduino.cc/index.php?topic=436411.0

// mapping suggestion from Waveshare SPI e-Paper to Particle Photon
// A5 MOSI
// A4 MISO
// A3 SCK
// A2 SS
// BUSY -> D4, RST -> A0, DC -> A1, CS -> A2, CLK -> A3, DIN -> A5, GND ->
// GND, 3.3V -> 3.3V NOTE: it looks like MISO can't be used as general input pin
// for BUSY.

// base class GxEPD2_GFX can be used to pass references or pointers to the
// display instance as parameter, uses ~1.2k more code enable or disable
// GxEPD2_GFX base class
#define ENABLE_GxEPD2_GFX 0

#include <Adafruit_GFX.h>
#include <Arduino.h>
#include <FreeSerifBoldItalic18pt7b.h>
#include <FreeSerifItalic18pt7b.h>

#include <GxEPD2_3C.h>
#include <GxEPD2_BW.h>

GxEPD2_3C<GxEPD2_750c, GxEPD2_750c::HEIGHT / 4> display(
    GxEPD2_750c(/*CS=A2*/ SS, /*DC=*/A1, /*RST=*/A0, /*BUSY=*/D4));

void setup() {
    // Debugging Serial
    Serial.begin(115200);
    Serial.println();
    Serial.println("Starting eCitations");

    display.init(115200);

    delay(3000);

    showCitation("**Jeg** elsker Josefine;Jeg elsker** Isabella;Jeg elsker **Tyson**;");
}

void loop() {}

int countLines(String str) {
    int i = str.indexOf(";");
    if (i > 0) {
        return countLines(str.substring(i + 1, str.length())) + 1;
    } else {
        return 1;
    }
}

void showCitation(String citation) {
    // Initial settings
    display.setFullWindow();
    display.fillScreen(GxEPD_WHITE);
    display.setRotation(0);

    // Get display width and height
    int dw = display.width();
    int dh = display.height();

    // Start sending the print
    display.firstPage();
    do {
        // Draw a red border
        int padding = 5;
        int stroke = 4;
        for (int p = padding; p < (padding + stroke + 1); p++) {
            display.drawRect(p, p, dw - 2 * p, dh - 2 * p, GxEPD_RED);
        }

        String citationCopy = String(citation);
        // Loop through each line
        if (citation != "") {
            do {
                // Figure out how many lines there are
                int nLines = countLines(citation);
                Serial.println();
                Serial.print("nLines: ");
                Serial.println(nLines);

                // Slice out a sentence to print
                int i_delimiter = citation.indexOf(";");
                String sentence = citation.substring(0, i_delimiter);
                citation = citation.replace(i_delimiter > 0 ? sentence + ";" : sentence, "");

                Serial.println();
                Serial.print("sentence: ");
                Serial.println(sentence);
                Serial.print("citation: ");
                Serial.println(citation);

                // Figuring out where to start placing the cursor
                String rawStr = String(sentence);
                String pureStr = String(sentence.replace("*", ""));
                int16_t t1bx, t1by;
                uint16_t t1bw, t1bh;
                display.getTextBounds(
                    pureStr, 0, 0, &t1bx, &t1by, &t1bw,
                    &t1bh);  // Don't take into account the different font width
                uint16_t x = (int)(dw - t1bw) / 2;
                uint16_t y = (int)((dh - 35 * nLines) / 2 + ((nLines - 1) * 40) + 20);
                display.setCursor(x, y);

                // Serial debugger
                Serial.print("pureStr: ");
                Serial.println(pureStr);
                Serial.print("x: ");
                Serial.println(x);
                Serial.print("y: ");
                Serial.println(y);

                // DEBUG SECTION
                display.setTextColor(GxEPD_RED);
                display.setFont(&FreeSerifBoldItalic18pt7b);
                display.print(pureStr);

                // // Fragment the sentence into blocks
                // int strong;
                // int space;
                // if (rawStr.indexOf("**") == 0) {
                //     strong = 1;
                //     rawStr = rawStr.substring(2, rawStr.length());  // Dirty hacks
                //     x -= 5;
                // } else {
                //     strong = 0;
                // }
                // rawStr = rawStr + "**";

                // do {
                //     // Set font style and color
                //     if (strong == 1) {
                //         display.setTextColor(GxEPD_RED);
                //         display.setFont(&FreeSerifBoldItalic18pt7b);
                //         strong--;
                //         space = 2;
                //     } else {
                //         display.setTextColor(GxEPD_BLACK);
                //         display.setFont(&FreeSerifItalic18pt7b);
                //         strong++;
                //         space = 5;
                //     };

                //     // Find "**"
                //     int i_stars = rawStr.indexOf("**");

                //     // Print until "**"
                //     String prtStr = rawStr.substring(0, i_stars);
                //     display.print(prtStr);

                //     // Move cursor
                //     int16_t t2bx, t2by;
                //     uint16_t t2bw, t2bh;
                //     display.getTextBounds(prtStr, 0, 0, &t2bx, &t2by, &t2bw, &t2bh);
                //     x = x + t2bw + space;
                //     display.setCursor(x, y);

                //     // Remove until "**"
                //     rawStr = rawStr.substring(i_stars + 2, rawStr.length());

                // } while (rawStr.indexOf("**") > 0);  // End of sentence block/fragments

            } while (citation.indexOf(";") > 0);  // End of sentence
        }                                         // End of IF
        citation = citationCopy;
    } while (display.nextPage());  // End of printing

    Serial.println("Citation printed");
}
1 Like

Here is the working version (still needs refatoring)

/*
 * Project eCitations
 * Description:
 * Author: Lasse Norfeldt
 * Date: 2019
 */

#include <Adafruit_GFX_RK.h>
#include <GxEPD2_PP.h>

// Supporting Arduino Forum Topics:
// Waveshare e-paper displays with SPI:
// http://forum.arduino.cc/index.php?topic=487007.0 Good Dispay ePaper for
// Arduino: https://forum.arduino.cc/index.php?topic=436411.0

// mapping suggestion from Waveshare SPI e-Paper to Particle Photon
// A5 MOSI
// A4 MISO
// A3 SCK
// A2 SS
// BUSY -> D4, RST -> A0, DC -> A1, CS -> A2, CLK -> A3, DIN -> A5, GND ->
// GND, 3.3V -> 3.3V NOTE: it looks like MISO can't be used as general input pin
// for BUSY.

// base class GxEPD2_GFX can be used to pass references or pointers to the
// display instance as parameter, uses ~1.2k more code enable or disable
// GxEPD2_GFX base class
#define ENABLE_GxEPD2_GFX 0

#include <Adafruit_GFX.h>
#include <Arduino.h>
#include <FreeSerifBoldItalic18pt7b.h>
#include <FreeSerifItalic18pt7b.h>

#include <GxEPD2_3C.h>
#include <GxEPD2_BW.h>

GxEPD2_3C<GxEPD2_750c, GxEPD2_750c::HEIGHT / 4> display(
    GxEPD2_750c(/*CS=A2*/ SS, /*DC=*/A1, /*RST=*/A0, /*BUSY=*/D4));

void setup() {
    // Debugging Serial
    Serial.begin(115200);
    Serial.println();
    Serial.println("Starting eCitations");

    display.init(115200);

    delay(3000);

    showCitation("**Jeg** elsker Josefine;Jeg **elsker** Isabella;Jeg elsker **Tyson**;");
}

void loop() {}

int countLines(String str) {
    int i = str.indexOf(";");
    if (i > 0) {
        return countLines(str.substring(i + 1, str.length())) + 1;
    } else {
        return 0;
    }
}

void showCitation(String citation) {
    // Initial settings
    display.setFullWindow();
    display.fillScreen(GxEPD_WHITE);
    display.setRotation(0);

    // Get display width and height
    int dw = display.width();
    int dh = display.height();

    Serial.print("dw: ");
    Serial.println(dw);
    Serial.print("dh: ");
    Serial.println(dh);

    // Start sending the print
    display.firstPage();
    do {
        // Draw a red border
        int padding = 5;
        int stroke = 4;
        for (int p = padding; p < (padding + stroke + 1); p++) {
            display.drawRect(p, p, dw - 2 * p, dh - 2 * p, GxEPD_RED);
        }

        // Loop through each line
        String citationCopy = String(citation);  // Make a copy because it will be shorten and needs to be restored at the end
        if (citation != "") {
            do {
                // Figure out how many lines there are
                int nLine = countLines(citation);
                Serial.println();
                Serial.print("nLine: ");
                Serial.println(nLine);

                // Slice out a sentence to print
                int i_delimiter = citation.indexOf(";");
                String sentence = citation.substring(0, i_delimiter);
                citation = citation.replace(i_delimiter > 0 ? sentence + ";" : sentence, "");

                Serial.println();
                Serial.print("sentence: ");
                Serial.println(sentence);
                Serial.print("citation: ");
                Serial.println(citation);

                // Figuring out where to start placing the cursor
                String rawStr = String(sentence);
                String pureStr = String(sentence.replace("*", ""));
                int16_t t1bx, t1by;
                uint16_t t1bw, t1bh;
                display.getTextBounds(
                    pureStr, 0, 0, &t1bx, &t1by,
                    &t1bw, &t1bh);  // Don't take into account the different font width
                uint16_t x = (int)((dw - t1bw) / 2);
                uint16_t y = (int)((dh / 2) - ((nLine - 1) * 38) + countLines(citationCopy) / 2 * 38);
                display.setCursor(x, y);

                // Serial debugger
                Serial.print("pureStr: ");
                Serial.println(pureStr);
                Serial.print("x: ");
                Serial.println(x);
                Serial.print("t1bw: ");
                Serial.println(t1bw);
                Serial.print("y: ");
                Serial.println(y);

                // Fragment the sentence into blocks
                int strong;
                int space;
                if (rawStr.indexOf("**") == 0) {
                    strong = 1;
                    rawStr = rawStr.substring(2, rawStr.length());  // Dirty hacks
                    x -= 5;
                } else {
                    strong = 0;
                }
                rawStr = rawStr + "**";

                do {
                    // Set font style and color
                    if (strong == 1) {
                        display.setTextColor(GxEPD_RED);
                        display.setFont(&FreeSerifBoldItalic18pt7b);
                        strong--;
                        space = 2;
                    } else {
                        display.setTextColor(GxEPD_BLACK);
                        display.setFont(&FreeSerifItalic18pt7b);
                        strong++;
                        space = 5;
                    };

                    // Find "**"
                    int i_stars = rawStr.indexOf("**");

                    // Print until "**"
                    String prtStr = rawStr.substring(0, i_stars);
                    display.print(prtStr);

                    // Move cursor
                    int16_t t2bx, t2by;
                    uint16_t t2bw, t2bh;
                    display.getTextBounds(prtStr, 0, 0, &t2bx, &t2by, &t2bw, &t2bh);
                    x = x + t2bw + space;
                    display.setCursor(x, y);

                    // Remove until "**"
                    rawStr = rawStr.substring(i_stars + 2, rawStr.length());

                } while (rawStr.indexOf("**") > 0);  // End of sentence block/fragments

            } while (citation.indexOf(";") > 0);  // End of sentence
        }                                         // End of IF
        citation = citationCopy;
    } while (display.nextPage());  // End of printing

    Serial.println("Citation printed");
}
1 Like