user41951: First of all I want to be clear, I'm not very skilled in programming methods, all the C I learned was for various Arduino projects.
That being said, I just finished a project that reads some data from ELM327 via a HC-05 Bluetooth module and prints it to a 3.5 inch screen. All is working as intended, but apparently I have capped my Arduino UNO's memory because the sketch utilizes 99% of it. At the moment this is not very troublesome, but if sometime in the future I want to add more data to be read, I won't be able to do it.
With this in mind, I was looking for some advice on how I could rewrite my code in order to occupy less memory. I tried some stuff, but had little effect. As I said, I'm not familiar with advanced programming techniques.
LE: So I used all of your advice, I got rid of all the fonts, modified the MCUFRIEND library to only work with my display and got rid of some repeating code, and now the sketch got 35% smaller. Thanks to all.

Sketch uses 21216 bytes (65%) of program storage space. Maximum is 32256 bytes.
  Global variables use 642 bytes (31%) of dynamic memory, leaving 1406 bytes for local variables. Maximum is 2048 bytes.

Here's the (old) code:
#include <SoftwareSerial.h> 
#include <Adafruit_GFX.h> 
#include <MCUFRIEND_kbv.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold24pt7b.h>

SoftwareSerial BTSerial(10, 11);
MCUFRIEND_kbv tft;

#define BLACK   0x0000
#define WHITE   0xFFFF
#define GREY    0x8410

byte inData;
char inChar;
String constructor="";
String deconstructor="";
int A;
int B;
bool busy = false;

void setup()
{
    Retry:
    Serial.begin(9600);
    BTSerial.begin(38400);
    delay(1000);

    BTSerial.println("0100");
    while(BTSerial.available()>0)
    {
      inData=0;
      inChar=0;
      inData = BTSerial.read();
      inChar=char(inData);
      constructor = constructor + inChar;
      delay(20);
   }
    if (constructor.length()>0)
    {
      Serial.println("Conectat");
    }
    else { 
      goto Retry;
      Serial.println("retry");
    }
    delay(5000);
    ReadData();
    basicConditions();

    tft.reset();
    uint16_t identifier = tft.readID();
    if (identifier == 0xEFEF) identifier = 0x9486;
    tft.begin(identifier);

    tft.fillScreen(BLACK);
    tft.setRotation(1);
    tft.setTextColor(WHITE);

    tft.fillRect(10, 40, 70, 40, GREY);
    tft.fillRect(10, 140, 70, 40, GREY);
    tft.fillRect(10, 240, 70, 40, GREY);
    tft.fillRect(140, 70, 200, 100, GREY);
    tft.fillRect(150, 220, 180, 60, GREY);
    tft.fillRect(370, 40, 70, 40, GREY);
    tft.fillRect(370, 140, 70, 40, GREY);
    tft.fillRect(370, 240, 70, 40, GREY);

    tft.setCursor(170,10);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("Dacia 4X4");

    tft.setCursor(30,35);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Cuplu");
    tft.setCursor(80,70);
    tft.setFont(&FreeMonoBold18pt7b);
    tft.print("%");

    tft.setCursor(15,120);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Presiune"); 
    tft.setCursor(15,135);   
    tft.print("motorina");
    tft.setCursor(82,170);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("bar");

    tft.setCursor(15,220);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Presiune"); 
    tft.setCursor(20,235);   
    tft.print("admisie");  
    tft.setCursor(82,270);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("bar");  

    tft.setCursor(395,20);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Temp."); 
    tft.setCursor(382,35);   
    tft.print("Antigel");
    tft.setCursor(450,70);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("C"); 

    tft.setCursor(395,120);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("Temp."); 
    tft.setCursor(382,135);   
    tft.print("Admisie");
    tft.setCursor(450,170);
    tft.setFont(&FreeMonoBold12pt7b);
    tft.print("C"); 

    tft.setFont(&FreeMonoBold9pt7b);
    tft.setCursor(370,235);   
    tft.print("Debit Aer");
    tft.setCursor(445,270);
    tft.setFont(&FreeMonoBold9pt7b);
    tft.print("g/s");     

    tft.setFont(&FreeMonoBold12pt7b);
    tft.setCursor(150, 62);   
    tft.print("Turatie (RPM)");

    tft.setFont(&FreeMonoBold12pt7b);
    tft.setCursor(152, 212);   
    tft.print("Viteza (KM/H)");



}

void loop()
{
  cuplu();
  PresMot();
  PresAdm();
  TempAntig();
  TempAdm();
  MAF();
  RPM();
  viteza();
}
void basicConditions(){
    if(constructor.indexOf(">")>0)  {
    busy=false;
    constructor="";
  }
}
void ReadData()
{   
  if (BTSerial.available()>0)
    busy = true;
  while(busy = true && constructor.indexOf(">")<0)
  {
    if (BTSerial.available()>0){
    inData=0;
    inChar=0;
    inData = BTSerial.read();
    inChar=char(inData);
    constructor = constructor + inChar;
    //Serial.println(constructor);
    //Serial.println(busy);
  }
  }
  //Serial.println("done");

  if (constructor.indexOf(">")>0){
    deconstructor=constructor.substring(11,13);
    A = strtol(deconstructor.c_str(),NULL,16);
    if (constructor.length()>15) {
        deconstructor = constructor.substring(14,16);
            B = strtol(deconstructor.c_str(),NULL,16);
    }
    else B = 0;
  }
}
void cuplu() {
  if (busy == false){
    BTSerial.println("01041");
      ReadData();
    tft.setTextSize(1);
    tft.setFont(&FreeMonoBold18pt7b);
    tft.setCursor(10, 70);
    tft.fillRect(10, 40, 70, 40, GREY); 
    tft.print(A/2.55, 0);   
  }
  basicConditions();
}
void PresMot() {
  if (busy == false){
      BTSerial.println("010A1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.setCursor(10, 170);
    tft.fillRect(10, 140, 70, 40, GREY); 
    tft.print((3*A)/100.0, 1);
  }
  basicConditions();
}
void PresAdm() {
  if (busy == false){
      BTSerial.println("010B1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.setCursor(10, 270);
    tft.fillRect(10, 240, 70, 40, GREY); 
    tft.print((A/100.0), 1);
  }
  basicConditions();
}
void TempAntig() {
    if (busy == false){
      BTSerial.println("01051");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.fillRect(370, 40, 70, 40, GREY);
    tft.setCursor(370, 70);
    tft.print(A-40);
    }
  basicConditions();
}
void TempAdm() {
    if (busy == false){
      BTSerial.println("010F1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.fillRect(370, 140, 70, 40, GREY);
    tft.setCursor(370, 170);
    tft.print(A-40);
    }
  basicConditions();
}
void MAF() {
  if (busy == false){
      BTSerial.println("01101");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&FreeMonoBold18pt7b);
      tft.fillRect(370, 240, 70, 40, GREY);
    tft.setCursor(370, 270);
    tft.print(((256*A)+B)/4.0, 0);  
  }
  basicConditions();
}
void RPM() {
  if (busy == false){
      BTSerial.println("010C1");
      ReadData();
      tft.setFont(&FreeMonoBold18pt7b);
    tft.setTextSize(2);
    tft.fillRect(140, 70, 200, 100, GREY);
    tft.setCursor(150, 140); 
    tft.print(A/4.0, 0);
  }
  basicConditions();
}
void viteza() {
  if (busy == false){
      BTSerial.println("010D1");
      ReadData();
      tft.setFont(&FreeMonoBold18pt7b);
    tft.setTextSize(2); 
      tft.fillRect(150, 220, 180, 60, GREY);
    tft.setCursor(180, 270); 
    tft.print(A);
  }
  basicConditions();
}


user313: Strings get allocated, reallocated, and deallocated as you use them, which can leave the heap - the bottom end of RAM memory - fragmented and the fragments essentially unusable. The memory report from the compiler can't show this; it happens at runtime.
If instead, you pre-allocate character arrays of a sufficient size for the eventual maximum text you want to put in them, they will stay in one place, neither growing nor shrinking, but also won't create those unused but unusable "holes" in the RAM.
Update:
Instead of:
String xyz;
xyz = "Hello";
xyz = xyz + ',';
xyz = xyz + "World!\n";

, you'd write:
#define XYZ_MAX  25    // or whatever size you need

char xyz[XYZ_MAX+1];
strcpy(xyz, "Hello";      // overwrites whatever is there
strcat(xyz, ", World!\n"; // appends whatever is there

You can further optimize RAM by directing the compiler to store the string literal ("Hello", etc.) in Flash. That's another topic, but here is a link to an article about it in the Arduino Playground, to get you started.

user7508: I assume you mean that are running short of flash memory, rather than
RAM. I base this assumption on the fact that you say that it's 99%
full, and that this “is not very troublesome”. Filling 99% of the RAM
with statically allocated data would certainly be troublesome. But
please note that it as always better to make your question clear and
explicit, rather than expect the respondents to make guesses.
Now, look at your font files. Each one of them ends with a comment
similar to this:
// Approx. 1672 bytes

Just adding those numbers we get:
FreeMonoBold9pt7b   1672 bytes
FreeMonoBold12pt7b  2402 bytes
FreeMonoBold18pt7b  4485 bytes
FreeMonoBold24pt7b  7469 bytes
------------------------------
TOTAL              16028 bytes

That's about 49% of your Arduino's flash. So that's the first place you
should be looking to if you want to save flash. Do you really need
these four different font sizes? And more specifically, do you really
need the (very flash hungry) largest sizes? Getting rid of some of them
is the easiest way to save flash.
If you really want to keep them all, your next option is to trim the
fonts in order to have only the characters you are actually using. This
can be a lot of work, but it should be a very effective way of
significantly reducing their flash footprint.
If you decide to take this path, the first step is to take note of what
characters you need at each font size. From a cursory look at your
source, it seems to me that the 18 pt font is only used for
printing “%”, “.”, the ten digits, and possibly “-”. That's a lot less
than the full ASCII repertoire the font supports. And I can't see where
you are using the 24 pt font. Look into an ASCII table and take
note of the smallest continuous range that contains all the characters
you use at one font size. Then trim the Glyphs array of the font to
keep only that range, and fix the first and last fields of the
GFXfont struct accordingly.
Next step is what will take most of the work. For each character you
actually need, take note of the bitmapOffset field of its glyph and
the next one. This way you know the range of offsets that are used by
that character. Then remove from the font's Bitmaps array all the
bytes that are at offsets you don't need. While doing this, you will be
changing the offsets of the bytes you keep, so you should update the
bitmapOffset fields on the Glyphs array accordingly.
Yes, that's quite some work, but you should end up with custom fonts
that are a lot lighter than the original ones, and yet capable of
displaying everything you are displaying now. Maybe you could write a
program to automate all this. Maybe someone already did that and you can
find it through a Web search...

user27653: The documentation for the MCUFRIEND_kbv project has a file describing how to use.
This document has the statement:
Most of these controllers are #define SUPPORT_xxxx by default.
You can save Flash memory on a Uno by commenting out the macro(s) in MCUFRIEND_kbv.cpp

So you open MCUFRIEND_kbv.cpp and comment out support for the controllers you aren't using.
You can also reduce the number of different fonts you use to save Flash space.

41951: <p>First of all I want to be clear, I'm not very skilled in programming methods, all the C I learned was for various Arduino projects.</p>

<p>That being said, I just finished a project that reads some data from ELM327 via a HC-05 Bluetooth module and prints it to a 3.5 inch screen. All is working as intended, but apparently I have capped my Arduino UNO's memory because the sketch utilizes 99% of it. At the moment this is not very troublesome, but if sometime in the future I want to add more data to be read, I won't be able to do it.</p>

<p>With this in mind, I was looking for some advice on how I could rewrite my code in order to occupy less memory. I tried some stuff, but had little effect. As I said, I'm not familiar with advanced programming techniques.</p>

<p>LE: So I used all of your advice, I got rid of all the fonts, modified the MCUFRIEND library to only work with my display and got rid of some repeating code, and now the sketch got 35% smaller. Thanks to all.</p>

<blockquote>
  <p>Sketch uses 21216 bytes (65%) of program storage space. Maximum is 32256 bytes.
  Global variables use 642 bytes (31%) of dynamic memory, leaving 1406 bytes for local variables. Maximum is 2048 bytes.</p>
</blockquote>

<p>Here's the (old) code:</p>

<pre><code>#include &lt;SoftwareSerial.h&gt; 
#include &lt;Adafruit_GFX.h&gt; 
#include &lt;MCUFRIEND_kbv.h&gt;
#include &lt;Fonts/FreeMonoBold9pt7b.h&gt;
#include &lt;Fonts/FreeMonoBold12pt7b.h&gt;
#include &lt;Fonts/FreeMonoBold18pt7b.h&gt;
#include &lt;Fonts/FreeMonoBold24pt7b.h&gt;

SoftwareSerial BTSerial(10, 11);
MCUFRIEND_kbv tft;

#define BLACK   0x0000
#define WHITE   0xFFFF
#define GREY    0x8410

byte inData;
char inChar;
String constructor="";
String deconstructor="";
int A;
int B;
bool busy = false;

void setup()
{
    Retry:
    Serial.begin(9600);
    BTSerial.begin(38400);
    delay(1000);

    BTSerial.println("0100");
    while(BTSerial.available()&gt;0)
    {
      inData=0;
      inChar=0;
      inData = BTSerial.read();
      inChar=char(inData);
      constructor = constructor + inChar;
      delay(20);
   }
    if (constructor.length()&gt;0)
    {
      Serial.println("Conectat");
    }
    else { 
      goto Retry;
      Serial.println("retry");
    }
    delay(5000);
    ReadData();
    basicConditions();

    tft.reset();
    uint16_t identifier = tft.readID();
    if (identifier == 0xEFEF) identifier = 0x9486;
    tft.begin(identifier);

    tft.fillScreen(BLACK);
    tft.setRotation(1);
    tft.setTextColor(WHITE);

    tft.fillRect(10, 40, 70, 40, GREY);
    tft.fillRect(10, 140, 70, 40, GREY);
    tft.fillRect(10, 240, 70, 40, GREY);
    tft.fillRect(140, 70, 200, 100, GREY);
    tft.fillRect(150, 220, 180, 60, GREY);
    tft.fillRect(370, 40, 70, 40, GREY);
    tft.fillRect(370, 140, 70, 40, GREY);
    tft.fillRect(370, 240, 70, 40, GREY);

    tft.setCursor(170,10);
    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.print("Dacia 4X4");

    tft.setCursor(30,35);
    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.print("Cuplu");
    tft.setCursor(80,70);
    tft.setFont(&amp;FreeMonoBold18pt7b);
    tft.print("%");

    tft.setCursor(15,120);
    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.print("Presiune"); 
    tft.setCursor(15,135);   
    tft.print("motorina");
    tft.setCursor(82,170);
    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.print("bar");

    tft.setCursor(15,220);
    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.print("Presiune"); 
    tft.setCursor(20,235);   
    tft.print("admisie");  
    tft.setCursor(82,270);
    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.print("bar");  

    tft.setCursor(395,20);
    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.print("Temp."); 
    tft.setCursor(382,35);   
    tft.print("Antigel");
    tft.setCursor(450,70);
    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.print("C"); 

    tft.setCursor(395,120);
    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.print("Temp."); 
    tft.setCursor(382,135);   
    tft.print("Admisie");
    tft.setCursor(450,170);
    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.print("C"); 

    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.setCursor(370,235);   
    tft.print("Debit Aer");
    tft.setCursor(445,270);
    tft.setFont(&amp;FreeMonoBold9pt7b);
    tft.print("g/s");     

    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.setCursor(150, 62);   
    tft.print("Turatie (RPM)");

    tft.setFont(&amp;FreeMonoBold12pt7b);
    tft.setCursor(152, 212);   
    tft.print("Viteza (KM/H)");



}

void loop()
{
  cuplu();
  PresMot();
  PresAdm();
  TempAntig();
  TempAdm();
  MAF();
  RPM();
  viteza();
}
void basicConditions(){
    if(constructor.indexOf("&gt;")&gt;0)  {
    busy=false;
    constructor="";
  }
}
void ReadData()
{   
  if (BTSerial.available()&gt;0)
    busy = true;
  while(busy = true &amp;&amp; constructor.indexOf("&gt;")&lt;0)
  {
    if (BTSerial.available()&gt;0){
    inData=0;
    inChar=0;
    inData = BTSerial.read();
    inChar=char(inData);
    constructor = constructor + inChar;
    //Serial.println(constructor);
    //Serial.println(busy);
  }
  }
  //Serial.println("done");

  if (constructor.indexOf("&gt;")&gt;0){
    deconstructor=constructor.substring(11,13);
    A = strtol(deconstructor.c_str(),NULL,16);
    if (constructor.length()&gt;15) {
        deconstructor = constructor.substring(14,16);
            B = strtol(deconstructor.c_str(),NULL,16);
    }
    else B = 0;
  }
}
void cuplu() {
  if (busy == false){
    BTSerial.println("01041");
      ReadData();
    tft.setTextSize(1);
    tft.setFont(&amp;FreeMonoBold18pt7b);
    tft.setCursor(10, 70);
    tft.fillRect(10, 40, 70, 40, GREY); 
    tft.print(A/2.55, 0);   
  }
  basicConditions();
}
void PresMot() {
  if (busy == false){
      BTSerial.println("010A1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&amp;FreeMonoBold18pt7b);
      tft.setCursor(10, 170);
    tft.fillRect(10, 140, 70, 40, GREY); 
    tft.print((3*A)/100.0, 1);
  }
  basicConditions();
}
void PresAdm() {
  if (busy == false){
      BTSerial.println("010B1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&amp;FreeMonoBold18pt7b);
      tft.setCursor(10, 270);
    tft.fillRect(10, 240, 70, 40, GREY); 
    tft.print((A/100.0), 1);
  }
  basicConditions();
}
void TempAntig() {
    if (busy == false){
      BTSerial.println("01051");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&amp;FreeMonoBold18pt7b);
      tft.fillRect(370, 40, 70, 40, GREY);
    tft.setCursor(370, 70);
    tft.print(A-40);
    }
  basicConditions();
}
void TempAdm() {
    if (busy == false){
      BTSerial.println("010F1");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&amp;FreeMonoBold18pt7b);
      tft.fillRect(370, 140, 70, 40, GREY);
    tft.setCursor(370, 170);
    tft.print(A-40);
    }
  basicConditions();
}
void MAF() {
  if (busy == false){
      BTSerial.println("01101");
      ReadData();
      tft.setTextSize(1);
      tft.setFont(&amp;FreeMonoBold18pt7b);
      tft.fillRect(370, 240, 70, 40, GREY);
    tft.setCursor(370, 270);
    tft.print(((256*A)+B)/4.0, 0);  
  }
  basicConditions();
}
void RPM() {
  if (busy == false){
      BTSerial.println("010C1");
      ReadData();
      tft.setFont(&amp;FreeMonoBold18pt7b);
    tft.setTextSize(2);
    tft.fillRect(140, 70, 200, 100, GREY);
    tft.setCursor(150, 140); 
    tft.print(A/4.0, 0);
  }
  basicConditions();
}
void viteza() {
  if (busy == false){
      BTSerial.println("010D1");
      ReadData();
      tft.setFont(&amp;FreeMonoBold18pt7b);
    tft.setTextSize(2); 
      tft.fillRect(150, 220, 180, 60, GREY);
    tft.setCursor(180, 270); 
    tft.print(A);
  }
  basicConditions();
}
</code></pre>
 313: <p>Strings get allocated, reallocated, and deallocated as you use them, which can leave the heap - the bottom end of RAM memory - fragmented and the fragments essentially unusable. The memory report from the compiler can't show this; it happens at runtime.</p>

<p>If instead, you pre-allocate character arrays of a sufficient size for the eventual maximum text you want to put in them, they will stay in one place, neither growing nor shrinking, but also won't create those unused but unusable "holes" in the RAM.</p>

<p>Update:</p>

<p>Instead of:</p>

<pre><code>String xyz;
xyz = "Hello";
xyz = xyz + ',';
xyz = xyz + "World!\n";
</code></pre>

<p>, you'd write:</p>

<pre><code>#define XYZ_MAX  25    // or whatever size you need

char xyz[XYZ_MAX+1];
strcpy(xyz, "Hello";      // overwrites whatever is there
strcat(xyz, ", World!\n"; // appends whatever is there
</code></pre>

<p>You can further optimize RAM by directing the compiler to store the string literal (<code>"Hello"</code>, etc.) in Flash. That's another topic, but here is a l<a href="https://playground.arduino.cc/Main/PROGMEM" rel="nofollow noreferrer">ink to an article</a> about it in the Arduino Playground, to get you started.</p>
 7508: <p>I assume you mean that are running short of <em>flash</em> memory, rather than
<em>RAM</em>. I base this assumption on the fact that you say that it's 99%
full, and that this “is not very troublesome”. Filling 99% of the RAM
with statically allocated data would certainly be troublesome. But
please note that it as always better to make your question clear and
explicit, rather than expect the respondents to make guesses.</p>

<p>Now, look at your font files. Each one of them ends with a comment
similar to this:</p>

<pre><code>// Approx. 1672 bytes
</code></pre>

<p>Just adding those numbers we get:</p>

<pre><code>FreeMonoBold9pt7b   1672 bytes
FreeMonoBold12pt7b  2402 bytes
FreeMonoBold18pt7b  4485 bytes
FreeMonoBold24pt7b  7469 bytes
------------------------------
TOTAL              16028 bytes
</code></pre>

<p>That's about 49% of your Arduino's flash. So that's the first place you
should be looking to if you want to save flash. Do you <em>really</em> need
these four different font sizes? And more specifically, do you <em>really</em>
need the (very flash hungry) largest sizes? Getting rid of some of them
is the easiest way to save flash.</p>

<p>If you really want to keep them all, your next option is to trim the
fonts in order to have only the characters you are actually using. This
can be a lot of work, but it should be a very effective way of
significantly reducing their flash footprint.</p>

<p>If you decide to take this path, the first step is to take note of what
characters you need at each font size. From a cursory look at your
source, it seems to me that the 18&nbsp;pt font is only used for
printing “%”, “.”, the ten digits, and possibly “-”. That's a lot less
than the full ASCII repertoire the font supports. And I can't see where
you are using the 24&nbsp;pt font. Look into an ASCII table and take
note of the smallest continuous range that contains all the characters
you use at one font size. Then trim the <code>Glyphs</code> array of the font to
keep only that range, and fix the <code>first</code> and <code>last</code> fields of the
<code>GFXfont</code> struct accordingly.</p>

<p>Next step is what will take most of the work. For each character you
actually need, take note of the <code>bitmapOffset</code> field of its glyph <em>and
the next one</em>. This way you know the range of offsets that are used by
that character. Then remove from the font's <code>Bitmaps</code> array all the
bytes that are at offsets you don't need. While doing this, you will be
changing the offsets of the bytes you keep, so you should update the
<code>bitmapOffset</code> fields on the <code>Glyphs</code> array accordingly.</p>

<p>Yes, that's quite some work, but you should end up with custom fonts
that are a lot lighter than the original ones, and yet capable of
displaying everything you are displaying now. Maybe you could write a
program to automate all this. Maybe someone already did that and you can
find it through a Web search...</p>
 27653: <p>The documentation for the <a href="https://github.com/prenticedavid/MCUFRIEND_kbv" rel="nofollow noreferrer">MCUFRIEND_kbv project</a> has a file <a href="https://github.com/prenticedavid/MCUFRIEND_kbv/blob/master/extras/mcufriend_how_to.txt" rel="nofollow noreferrer">describing how to use</a>.</p>

<p>This document has the statement:</p>

<pre><code>Most of these controllers are #define SUPPORT_xxxx by default.
You can save Flash memory on a Uno by commenting out the macro(s) in MCUFRIEND_kbv.cpp
</code></pre>

<p>So you open MCUFRIEND_kbv.cpp and comment out support for the controllers you <strong>aren't</strong> using.</p>

<p>You can also reduce the number of different fonts you use to save Flash space.</p>
