How to edit tft library

hi, I have a sketch that uses an oled display, with its own custom library that uses port + bit banging,
I'm converting it to use a tft display with Arduino_ST7789_Fast library instead,

oled library "draw_rect" has 7 parameters

void draw_rect (uint8_t x, uint8_t y, uint8_t w, uint8_t h, 
               uint16_t edgecol, uint16_t fillcol, boolean filled) 

but Arduino_ST7789_Fast library "fillRect" has only 5

 void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);

do I just add the extra parts to "fillRect" to get the 7 parameters the sketch needs?

also, how do I convert the colour parts of the bit banging code to the tft library?

// Draw a rectangle in foreground colour optionally filled another colour
void draw_rect (uint8_t x, uint8_t y, uint8_t w, uint8_t h, 
               uint16_t edgecol, uint16_t fillcol, boolean filled) 
{  
  if(w == 0 || h == 0)
    return;

  uint8_t e_red   = (edgecol & 0xf800) >> 10;
  uint8_t e_green = (edgecol & 0x07e0) >> 5;
  uint8_t e_blue  = (edgecol & 0x001f) << 1;

  uint8_t f_red   = (fillcol & 0xf800) >> 10;
  uint8_t f_green = (fillcol & 0x07e0) >> 5;
  uint8_t f_blue  = (fillcol & 0x001f) << 1;
 
  
  PINB = 1<<cs;                           // cs low
  Send(0x26); Send(filled);               // Enable fill
  Send(0x22);                             // Draw rectangle
  Send(x); Send(y); Send(x + w - 1); Send(y + h - 1);
  Send(e_red); Send(e_green); Send(e_blue);
  Send(f_red); Send(f_green); Send(f_blue);
  PINB = 1<<cs;                           // cs high

  if(filled)                              // filled rectangles take time to draw
    //delayMicroseconds(200);               // must not issue new command too soon
    delayMicroseconds(100);               // half delay when clocking nano to 8 MHz
}
// ----------------------------------------------------------
void Arduino_ST7789::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) 
{
  if(x>=_width || y>=_height || w<=0 || h<=0) return;
  if(x+w-1>=_width)  w=_width -x;
  if(y+h-1>=_height) h=_height-y;
  setAddrWindow(x, y, x+w-1, y+h-1);

  writeMulti(color,w*h);

  CS_IDLE;
  SPI_END;
}

It looks like 'draw_rect()' is a combination of outlining a rectangle in one color and (optionally) filling the interior with a different color. If the new library has no drawRect() to draw the outline you will need to draw it with four lines: You could implement it with:

void draw_rect (uint8_t x, uint8_t y, uint8_t w, uint8_t h, 
               uint16_t edgecol, uint16_t fillcol, boolean filled)
{
  if (filled)
  {
    fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t fillcol);
  }
  // Outline the rectangle with four lines of color 'edgecol'
}
1 Like

New library has drawRect and fillRect already, so I used those, thank you!

the next part I haven't figured out is:

// Plot character in given colour
void plot_char (uint8_t x, uint8_t y, uint8_t ch, uint16_t col, uint8_t scale)
{
  uint8_t red   = (col & 0xf800) >> 10;
  uint8_t green = (col & 0x07e0) >> 5;
  uint8_t blue  = (col & 0x001f) << 1;

//  PINB = 1 << cs;                         // cs low
  for (uint8_t c = 0 ; c < 5; c++) {      // Column range
    uint8_t bits = pgm_read_byte(&font[ch - 32][c]);
    uint8_t r = 0;
    while (bits) {
      while ((bits & 1) == 0) {
        r++;
        bits = bits >> 1;
      }
      uint8_t on = (7 - r) * scale;
      while ((bits & 1) != 0) {
        r++;
        bits = bits >> 1;
      }
      uint8_t off = (7 - r) * scale + 1;
      for (int i = 0; i < scale; i++) {
        uint8_t h = x + c * scale + i;
        Send(0x21);                         // Draw line
        Send(h); Send(y + on); Send(h); Send(y + off);
        Send(red); Send(green); Send(blue);
      }
    }
  }
//  PINB = 1 << cs;                           // cs high
}

// Plot text
void plot_text(uint8_t x, uint8_t y, const char* text, uint16_t col, uint8_t scale)
{
  while (1) {
    char c = *(text++);
    if (c == 0) return;
    plot_char(x, y, c, col, scale);
    x += 6;
  }
}

I've replaced any calls from my sketch to plot_text with:

  //plot_text(2, start, text, textcol);
  tft.setCursor(2, start);
  tft.setTextColor(textcol);
  tft.setTextSize(1);
  tft.print(text);

just not sure whats happening in plot_char, even with this info from the author:

Characters and text

The character set is defined by data stored in program memory. An abbreviated version of the character map is as follows:

const uint8_t CharMap[96][6] PROGMEM = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 
{ 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 }, 
...
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }
};
The first row defines the bit patterns for ASCII character 32, space, and so on up to character 127.

The PlotChar() routine plots a specified character at the current plot position, and in the current foreground colour.

My first version of PlotChar() plotted characters by calling PlotPoint() for each pixel. However, I then tried the following alternative approach which defines an area of the display using the CASET (Column Address Set) and RASET (Row Address Set) commands, and then sends a stream of the appropriate bytes to define the character. This turned out to be over three times faster!

void PlotChar (char c) {
  int colour;
  PINB = 1<<cs;                            // cs low
  Command2(CASET, yoff+y0, yoff+y0+8*scale-1);
  Command2(RASET, xoff+x0, xoff+x0+6*scale-1);
  Command(RAMWR);
  for (int xx=0; xx<6; xx++) {
    int bits = pgm_read_byte(&CharMap[c-32][xx]);
    for (int xr=0; xr<scale; xr++) {
      for (int yy=0; yy<8; yy++) {
        if (bits>>(7-yy) & 1) colour = fore; else colour = back;
        for (int yr=0; yr<scale; yr++) {
          Data(colour>>8); Data(colour & 0xFF);
        }
      }
    }
  }
  PINB = 1<<cs;                            // cs high
  x0 = x0 + 6*scale;
}
The default value of scale is 1, but you can change it to plot larger characters. After plotting a character PlotChar() moves the plot position to the start of the next character to make it easy to plot several characters in a row without needing to call MoveTo().

Finally PlotText() allows you to plot text from a string in program memory:

void PlotText(PGM_P p) {
  while (1) {
    char c = pgm_read_byte(p++);
    if (c == 0) return;
    PlotChar(c);
  }
}
To define the text to be plotted as being in program memory use the PSTR() macro (for program string); for example:

PlotText(PSTR("Graphics Display"));