mirror of
https://github.com/Bodmer/TFT_eSPI.git
synced 2024-09-21 10:27:11 +00:00
Add smooth (antialiased) fonts
This commit is contained in:
parent
02a902f617
commit
8752236ac2
76
Extensions/Button.cpp
Normal file
76
Extensions/Button.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/***************************************************************************************
|
||||
** Code for the GFX button UI element
|
||||
** Grabbed from Adafruit_GFX library and enhanced to handle any label font
|
||||
***************************************************************************************/
|
||||
TFT_eSPI_Button::TFT_eSPI_Button(void) {
|
||||
_gfx = 0;
|
||||
}
|
||||
|
||||
// Classic initButton() function: pass center & size
|
||||
void TFT_eSPI_Button::initButton(
|
||||
TFT_eSPI *gfx, int16_t x, int16_t y, uint16_t w, uint16_t h,
|
||||
uint16_t outline, uint16_t fill, uint16_t textcolor,
|
||||
char *label, uint8_t textsize)
|
||||
{
|
||||
// Tweak arguments and pass to the newer initButtonUL() function...
|
||||
initButtonUL(gfx, x - (w / 2), y - (h / 2), w, h, outline, fill,
|
||||
textcolor, label, textsize);
|
||||
}
|
||||
|
||||
// Newer function instead accepts upper-left corner & size
|
||||
void TFT_eSPI_Button::initButtonUL(
|
||||
TFT_eSPI *gfx, int16_t x1, int16_t y1, uint16_t w, uint16_t h,
|
||||
uint16_t outline, uint16_t fill, uint16_t textcolor,
|
||||
char *label, uint8_t textsize)
|
||||
{
|
||||
_x1 = x1;
|
||||
_y1 = y1;
|
||||
_w = w;
|
||||
_h = h;
|
||||
_outlinecolor = outline;
|
||||
_fillcolor = fill;
|
||||
_textcolor = textcolor;
|
||||
_textsize = textsize;
|
||||
_gfx = gfx;
|
||||
strncpy(_label, label, 9);
|
||||
}
|
||||
|
||||
void TFT_eSPI_Button::drawButton(boolean inverted) {
|
||||
uint16_t fill, outline, text;
|
||||
|
||||
if(!inverted) {
|
||||
fill = _fillcolor;
|
||||
outline = _outlinecolor;
|
||||
text = _textcolor;
|
||||
} else {
|
||||
fill = _textcolor;
|
||||
outline = _outlinecolor;
|
||||
text = _fillcolor;
|
||||
}
|
||||
|
||||
uint8_t r = min(_w, _h) / 4; // Corner radius
|
||||
_gfx->fillRoundRect(_x1, _y1, _w, _h, r, fill);
|
||||
_gfx->drawRoundRect(_x1, _y1, _w, _h, r, outline);
|
||||
|
||||
_gfx->setTextColor(text);
|
||||
_gfx->setTextSize(_textsize);
|
||||
|
||||
uint8_t tempdatum = _gfx->getTextDatum();
|
||||
_gfx->setTextDatum(MC_DATUM);
|
||||
_gfx->drawString(_label, _x1 + (_w/2), _y1 + (_h/2));
|
||||
_gfx->setTextDatum(tempdatum);
|
||||
}
|
||||
|
||||
boolean TFT_eSPI_Button::contains(int16_t x, int16_t y) {
|
||||
return ((x >= _x1) && (x < (_x1 + _w)) &&
|
||||
(y >= _y1) && (y < (_y1 + _h)));
|
||||
}
|
||||
|
||||
void TFT_eSPI_Button::press(boolean p) {
|
||||
laststate = currstate;
|
||||
currstate = p;
|
||||
}
|
||||
|
||||
boolean TFT_eSPI_Button::isPressed() { return currstate; }
|
||||
boolean TFT_eSPI_Button::justPressed() { return (currstate && !laststate); }
|
||||
boolean TFT_eSPI_Button::justReleased() { return (!currstate && laststate); }
|
38
Extensions/Button.h
Normal file
38
Extensions/Button.h
Normal file
@ -0,0 +1,38 @@
|
||||
/***************************************************************************************
|
||||
// The following button class has been ported over from the Adafruit_GFX library so
|
||||
// should be compatible.
|
||||
// A slightly different implementation in this TFT_eSPI library allows the button
|
||||
// legends to be in any font
|
||||
***************************************************************************************/
|
||||
|
||||
class TFT_eSPI_Button {
|
||||
|
||||
public:
|
||||
TFT_eSPI_Button(void);
|
||||
// "Classic" initButton() uses center & size
|
||||
void initButton(TFT_eSPI *gfx, int16_t x, int16_t y,
|
||||
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
|
||||
uint16_t textcolor, char *label, uint8_t textsize);
|
||||
|
||||
// New/alt initButton() uses upper-left corner & size
|
||||
void initButtonUL(TFT_eSPI *gfx, int16_t x1, int16_t y1,
|
||||
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
|
||||
uint16_t textcolor, char *label, uint8_t textsize);
|
||||
void drawButton(boolean inverted = false);
|
||||
boolean contains(int16_t x, int16_t y);
|
||||
|
||||
void press(boolean p);
|
||||
boolean isPressed();
|
||||
boolean justPressed();
|
||||
boolean justReleased();
|
||||
|
||||
private:
|
||||
TFT_eSPI *_gfx;
|
||||
int16_t _x1, _y1; // Coordinates of top-left corner
|
||||
uint16_t _w, _h;
|
||||
uint8_t _textsize;
|
||||
uint16_t _outlinecolor, _fillcolor, _textcolor;
|
||||
char _label[10];
|
||||
|
||||
boolean currstate, laststate;
|
||||
};
|
511
Extensions/Smooth_font.cpp
Normal file
511
Extensions/Smooth_font.cpp
Normal file
@ -0,0 +1,511 @@
|
||||
// Coded by Bodmer 10/2/18, see license in root directory.
|
||||
// This is part of the TFT_eSPI class and is associated with anti-aliased font functions
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// New anti-aliased (smoothed) font functions added below
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: loadFont
|
||||
** Description: loads parameters from a new font vlw file stored in SPIFFS
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSPI::loadFont(String fontName)
|
||||
{
|
||||
/*
|
||||
The vlw font format does not appear to be documented anywhere, so some reverse
|
||||
engineering has been applied!
|
||||
|
||||
Header of vlw file comprises 6 uint32_t parameters (24 bytes total):
|
||||
1. The gCount (number of character glyphs)
|
||||
2. A version number (0xB = 11 for the one I am using)
|
||||
3. The font size (in points, not pixels)
|
||||
4. Deprecated mboxY parameter (typically set to 0)
|
||||
5. Ascent in pixels from baseline to top of "d"
|
||||
6. Descent in pixels from baseline to bottom of "p"
|
||||
|
||||
Next are gCount sets of values for each glyph, each set comprises 7 int32t parameters (28 bytes):
|
||||
1. Glyph Unicode stored as a 32 bit value
|
||||
2. Height of bitmap bounding box
|
||||
3. Width of bitmap bounding box
|
||||
4. gxAdvance for cursor (setWidth in Processing)
|
||||
5. dY = distance from cursor baseline to top of glyph bitmap (signed value +ve = up)
|
||||
6. dX = distance from cursor to left side of glyph bitmap (signed value -ve = left)
|
||||
7. padding value, typically 0
|
||||
|
||||
The bitmaps start next at 24 + (28 * gCount) bytes from the start of the file.
|
||||
Each pixel is 1 byte, an 8 bit Alpha value which represents the transparency from
|
||||
0xFF foreground colour, 0x00 background. The sketch uses a linear interpolation
|
||||
between the foreground and background RGB component colours. e.g.
|
||||
pixelRed = ((fgRed * alpha) + (bgRed * (255 - alpha))/255
|
||||
To gain a performance advantage fixed point arithmetic is used with rounding and
|
||||
division by 256 (shift right 8 bits is faster).
|
||||
|
||||
After the bitmaps is:
|
||||
1 byte for font name string length (excludes null)
|
||||
a zero terminated character string giving the font name
|
||||
1 byte for Postscript name string length
|
||||
a zero/one terminated character string giving the font name
|
||||
last byte is 0 for non-anti-aliased and 1 for anti-aliased (smoothed)
|
||||
|
||||
Then the font name seen by Java when it's created
|
||||
Then the postscript name of the font
|
||||
Then a boolean to tell if smoothing is on or not.
|
||||
|
||||
Glyph bitmap example is:
|
||||
// Cursor coordinate positions for this and next character are marked by 'C'
|
||||
// C<------- gxAdvance ------->C gxAdvance is how far to move cursor for next glyph cursor position
|
||||
// | |
|
||||
// | | ascent is top of "d", descent is bottom of "p"
|
||||
// +-- gdX --+ ascent
|
||||
// | +-- gWidth--+ | gdX is offset to left edge of glyph bitmap
|
||||
// | + x@.........@x + | gdX may be negative e.g. italic "y" tail extending to left of
|
||||
// | | @@.........@@ | | cursor position, plot top left corner of bitmap at (cursorX + gdX)
|
||||
// | | @@.........@@ gdY | gWidth and gHeight are glyph bitmap dimensions
|
||||
// | | .@@@.....@@@@ | |
|
||||
// | gHeight ....@@@@@..@@ + + <-- baseline
|
||||
// | | ...........@@ |
|
||||
// | | ...........@@ | gdY is the offset to the top edge of the bitmap
|
||||
// | | .@@.......@@. descent plot top edge of bitmap at (cursorY + yAdvance - gdY)
|
||||
// | + x..@@@@@@@..x | x marks the corner pixels of the bitmap
|
||||
// | |
|
||||
// +---------------------------+ yAdvance is y delta for the next line, font size or (ascent + descent)
|
||||
// some fonts can overlay in y direction so may need a user adjust value
|
||||
|
||||
*/
|
||||
|
||||
_gFontFilename = "/" + fontName + ".vlw";
|
||||
|
||||
fontFile = SPIFFS.open( _gFontFilename, "r");
|
||||
|
||||
if(!fontFile) return;
|
||||
|
||||
//unloadFont();
|
||||
|
||||
fontFile.seek(0, fs::SeekSet);
|
||||
|
||||
gFont.gCount = (uint16_t)readInt32(); // glyph count in file
|
||||
readInt32(); // vlw encoder version - discard
|
||||
gFont.yAdvance = (uint16_t)readInt32(); // Font size in points, not pixels
|
||||
readInt32(); // discard
|
||||
gFont.ascent = (uint16_t)readInt32(); // top of "d"
|
||||
gFont.descent = (uint16_t)readInt32(); // bottom of "p"
|
||||
|
||||
// These next gFont values will be updated when the Metrics are fetched
|
||||
gFont.maxAscent = gFont.ascent; // Determined from metrics
|
||||
gFont.maxDescent = gFont.descent; // Determined from metrics
|
||||
gFont.yAdvance = gFont.ascent + gFont.descent;
|
||||
gFont.spaceWidth = gFont.yAdvance / 4; // Guess at space width
|
||||
|
||||
fontLoaded = true;
|
||||
|
||||
// Fetch the metrics for each glyph
|
||||
loadMetrics(gFont.gCount);
|
||||
|
||||
//fontFile.close();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: loadMetrics
|
||||
** Description: Get the metrics for each glyph and store in RAM
|
||||
*************************************************************************************x*/
|
||||
//#define SHOW_ASCENT_DESCENT
|
||||
void TFT_eSPI::loadMetrics(uint16_t gCount)
|
||||
{
|
||||
uint32_t headerPtr = 24;
|
||||
uint32_t bitmapPtr = 24 + gCount * 28;
|
||||
|
||||
gUnicode = (uint16_t*)malloc( gCount * 2); // Unicode 16 bit Basic Multilingual Plane (0-FFFF)
|
||||
gHeight = (uint8_t*)malloc( gCount ); // Height of glyph
|
||||
gWidth = (uint8_t*)malloc( gCount ); // Width of glyph
|
||||
gxAdvance = (uint8_t*)malloc( gCount ); // xAdvance - to move x cursor
|
||||
gdY = (int8_t*)malloc( gCount ); // offset from bitmap top edge from lowest point in any character
|
||||
gdX = (int8_t*)malloc( gCount ); // offset for bitmap left edge relative to cursor X
|
||||
gBitmap = (uint32_t*)malloc( gCount * 4); // seek pointer to glyph bitmap in SPIFFS file
|
||||
|
||||
#ifdef SHOW_ASCENT_DESCENT
|
||||
Serial.print("ascent = "); Serial.println(gFont.ascent);
|
||||
Serial.print("descent = "); Serial.println(gFont.descent);
|
||||
#endif
|
||||
|
||||
uint16_t gNum = 0;
|
||||
fontFile.seek(headerPtr, fs::SeekSet);
|
||||
while (gNum < gCount)
|
||||
{
|
||||
gUnicode[gNum] = (uint16_t)readInt32(); // Unicode code point value
|
||||
gHeight[gNum] = (uint8_t)readInt32(); // Height of glyph
|
||||
gWidth[gNum] = (uint8_t)readInt32(); // Width of glyph
|
||||
gxAdvance[gNum] = (uint8_t)readInt32(); // xAdvance - to move x cursor
|
||||
gdY[gNum] = (int8_t)readInt32(); // y delta from baseline
|
||||
gdX[gNum] = (int8_t)readInt32(); // x delta from cursor
|
||||
readInt32(); // ignored
|
||||
|
||||
// Different glyph sets have different ascent values not always based on "d", so get maximum glyph ascent
|
||||
if (gdY[gNum] > gFont.maxAscent)
|
||||
{
|
||||
// Avoid UTF coding values and characters that tend to give duff values
|
||||
if (((gUnicode[gNum] > 0x20) && (gUnicode[gNum] < 0xA0) && (gUnicode[gNum] != 0x7F)) || (gUnicode[gNum] > 0xFF))
|
||||
{
|
||||
gFont.maxAscent = gdY[gNum];
|
||||
#ifdef SHOW_ASCENT_DESCENT
|
||||
Serial.print("Unicode = 0x"); Serial.print(gUnicode[gNum], HEX); Serial.print(", maxAscent = "); Serial.println(gFont.maxAscent);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Different glyph sets have different descent values not always based on "p", so get maximum glyph descent
|
||||
if (((int16_t)gHeight[gNum] - (int16_t)gdY[gNum]) > gFont.maxDescent)
|
||||
{
|
||||
// Avoid UTF coding values and characters that tend to give duff values
|
||||
if (((gUnicode[gNum] > 0x20) && (gUnicode[gNum] < 0xA0) && (gUnicode[gNum] != 0x7F)) || (gUnicode[gNum] > 0xFF))
|
||||
{
|
||||
gFont.maxDescent = gHeight[gNum] - gdY[gNum];
|
||||
#ifdef SHOW_ASCENT_DESCENT
|
||||
Serial.print("Unicode = 0x"); Serial.print(gUnicode[gNum], HEX); Serial.print(", maxDescent = "); Serial.println(gHeight[gNum] - gdY[gNum]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
gBitmap[gNum] = bitmapPtr;
|
||||
|
||||
headerPtr += 28;
|
||||
|
||||
bitmapPtr += gWidth[gNum] * gHeight[gNum];
|
||||
|
||||
gNum++;
|
||||
yield();
|
||||
}
|
||||
|
||||
gFont.yAdvance = gFont.maxAscent + gFont.maxDescent;
|
||||
|
||||
gFont.spaceWidth = (gFont.ascent + gFont.descent) * 2/7; // Guess at space width
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: deleteMetrics
|
||||
** Description: Delete the old glyph metrics and free up the memory
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSPI::unloadFont( void )
|
||||
{
|
||||
if (gUnicode)
|
||||
{
|
||||
free(gUnicode);
|
||||
gUnicode = NULL;
|
||||
}
|
||||
|
||||
if (gHeight)
|
||||
{
|
||||
free(gHeight);
|
||||
gHeight = NULL;
|
||||
}
|
||||
|
||||
if (gWidth)
|
||||
{
|
||||
free(gWidth);
|
||||
gWidth = NULL;
|
||||
}
|
||||
|
||||
if (gxAdvance)
|
||||
{
|
||||
free(gxAdvance);
|
||||
gxAdvance = NULL;
|
||||
}
|
||||
|
||||
if (gdY)
|
||||
{
|
||||
free(gdY);
|
||||
gdY = NULL;
|
||||
}
|
||||
|
||||
if (gdX)
|
||||
{
|
||||
free(gdX);
|
||||
gdX = NULL;
|
||||
}
|
||||
|
||||
if (gBitmap)
|
||||
{
|
||||
free(gBitmap);
|
||||
gBitmap = NULL;
|
||||
}
|
||||
fontFile.close();
|
||||
fontLoaded = false;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: decodeUTF8
|
||||
** Description: Line buffer UTF-8 decoder with fall-back to extended ASCII
|
||||
*************************************************************************************x*/
|
||||
#define DECODE_UTF8
|
||||
uint16_t TFT_eSPI::decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
|
||||
{
|
||||
byte c = buf[(*index)++];
|
||||
//Serial.print("Byte from string = 0x"); Serial.println(c, HEX);
|
||||
|
||||
#ifdef DECODE_UTF8
|
||||
// 7 bit Unicode
|
||||
if ((c & 0x80) == 0x00) return c;
|
||||
|
||||
// 11 bit Unicode
|
||||
if (((c & 0xE0) == 0xC0) && (remaining > 1))
|
||||
return ((c & 0x1F)<<6) | (buf[(*index)++]&0x3F);
|
||||
|
||||
// 16 bit Unicode
|
||||
if (((c & 0xF0) == 0xE0) && (remaining > 2))
|
||||
return ((c & 0x0F)<<12) | ((buf[(*index)++]&0x3F)<<6) | ((buf[(*index)++]&0x3F));
|
||||
|
||||
// 21 bit Unicode not supported so fall-back to extended ASCII
|
||||
// if ((c & 0xF8) == 0xF0) return c;
|
||||
#endif
|
||||
|
||||
return c; // fall-back to extended ASCII
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: decodeUTF8
|
||||
** Description: Serial UTF-8 decoder with fall-back to extended ASCII
|
||||
*************************************************************************************x*/
|
||||
uint16_t TFT_eSPI::decodeUTF8(uint8_t c)
|
||||
{
|
||||
|
||||
#ifdef DECODE_UTF8
|
||||
if (decoderState == 0)
|
||||
{
|
||||
// 7 bit Unicode
|
||||
if ((c & 0x80) == 0x00) return (uint16_t)c;
|
||||
|
||||
// 11 bit Unicode
|
||||
if ((c & 0xE0) == 0xC0)
|
||||
{
|
||||
decoderBuffer = ((c & 0x1F)<<6);
|
||||
decoderState = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 16 bit Unicode
|
||||
if ((c & 0xF0) == 0xE0)
|
||||
{
|
||||
decoderBuffer = ((c & 0x0F)<<12);
|
||||
decoderState = 2;
|
||||
return 0;
|
||||
}
|
||||
// 21 bit Unicode not supported so fall-back to extended ASCII
|
||||
if ((c & 0xF8) == 0xF0) return (uint16_t)c;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decoderState == 2)
|
||||
{
|
||||
decoderBuffer |= ((c & 0x3F)<<6);
|
||||
decoderState--;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
decoderBuffer |= (c & 0x3F);
|
||||
decoderState = 0;
|
||||
return decoderBuffer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return (uint16_t)c; // fall-back to extended ASCII
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: alphaBlend
|
||||
** Description: Blend foreground and background and return new colour
|
||||
*************************************************************************************x*/
|
||||
uint16_t TFT_eSPI::alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc)
|
||||
{
|
||||
// For speed use fixed point maths and rounding to permit a power of 2 division
|
||||
uint16_t fgR = ((fgc >> 10) & 0x3E) + 1;
|
||||
uint16_t fgG = ((fgc >> 4) & 0x7E) + 1;
|
||||
uint16_t fgB = ((fgc << 1) & 0x3E) + 1;
|
||||
|
||||
uint16_t bgR = ((bgc >> 10) & 0x3E) + 1;
|
||||
uint16_t bgG = ((bgc >> 4) & 0x7E) + 1;
|
||||
uint16_t bgB = ((bgc << 1) & 0x3E) + 1;
|
||||
|
||||
// Shift right 1 to drop rounding bit and shift right 8 to divide by 256
|
||||
uint16_t r = (((fgR * alpha) + (bgR * (255 - alpha))) >> 9);
|
||||
uint16_t g = (((fgG * alpha) + (bgG * (255 - alpha))) >> 9);
|
||||
uint16_t b = (((fgB * alpha) + (bgB * (255 - alpha))) >> 9);
|
||||
|
||||
// Combine RGB565 colours into 16 bits
|
||||
return (r << 11) | (g << 5) | (b << 0);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: readInt32
|
||||
** Description: Get a 32 bit integer from the font file
|
||||
*************************************************************************************x*/
|
||||
uint32_t TFT_eSPI::readInt32(void)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
val |= fontFile.read() << 24;
|
||||
val |= fontFile.read() << 16;
|
||||
val |= fontFile.read() << 8;
|
||||
val |= fontFile.read();
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getUnicodeIndex
|
||||
** Description: Get the font file index of a Unicode character
|
||||
*************************************************************************************x*/
|
||||
bool TFT_eSPI::getUnicodeIndex(uint16_t unicode, uint16_t *index)
|
||||
{
|
||||
for (uint16_t i = 0; i < gFont.gCount; i++)
|
||||
{
|
||||
if (gUnicode[i] == unicode)
|
||||
{
|
||||
*index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: drawGlyph
|
||||
** Description: Write a character to the TFT cursor position
|
||||
*************************************************************************************x*/
|
||||
// Expects file to be open
|
||||
void TFT_eSPI::drawGlyph(uint16_t code)
|
||||
{
|
||||
if (code < 0x21)
|
||||
{
|
||||
if (code == 0x20) {
|
||||
cursor_x += gFont.spaceWidth;
|
||||
return;
|
||||
}
|
||||
|
||||
if (code == '\n') {
|
||||
cursor_x = 0;
|
||||
cursor_y += gFont.yAdvance;
|
||||
if (cursor_y >= _height) cursor_y = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t gNum = 0;
|
||||
bool found = getUnicodeIndex(code, &gNum);
|
||||
|
||||
uint16_t fg = textcolor;
|
||||
uint16_t bg = textbgcolor;
|
||||
|
||||
if (found)
|
||||
{
|
||||
|
||||
if (textwrapX && (cursor_x + gWidth[gNum] + gdX[gNum] > _width))
|
||||
{
|
||||
cursor_y += gFont.yAdvance;
|
||||
cursor_x = 0;
|
||||
}
|
||||
if (textwrapY && ((cursor_y + gFont.yAdvance) >= _height)) cursor_y = 0;
|
||||
if (cursor_x == 0) cursor_x -= gdX[gNum];
|
||||
|
||||
fontFile.seek(gBitmap[gNum], fs::SeekSet); // This is taking >30ms for a significant position shift
|
||||
|
||||
uint8_t pbuffer[gWidth[gNum]];
|
||||
|
||||
uint16_t xs = 0;
|
||||
uint16_t dl = 0;
|
||||
|
||||
for (int y = 0; y < gHeight[gNum]; y++)
|
||||
{
|
||||
fontFile.read(pbuffer, gWidth[gNum]); //<//
|
||||
for (int x = 0; x < gWidth[gNum]; x++)
|
||||
{
|
||||
uint8_t pixel = pbuffer[x]; //<//
|
||||
if (pixel)
|
||||
{
|
||||
if (pixel != 0xFF)
|
||||
{
|
||||
if (dl) { drawFastHLine( xs, y + cursor_y + gFont.maxAscent - gdY[gNum], dl, fg); dl = 0; }
|
||||
drawPixel(x + cursor_x + gdX[gNum], y + cursor_y + gFont.maxAscent - gdY[gNum], alphaBlend(pixel, fg, bg));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dl==0) xs = x + cursor_x + gdX[gNum];
|
||||
dl++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dl) { drawFastHLine( xs, y + cursor_y + gFont.maxAscent - gdY[gNum], dl, fg); dl = 0; }
|
||||
}
|
||||
}
|
||||
if (dl) { drawFastHLine( xs, y + cursor_y + gFont.maxAscent - gdY[gNum], dl, fg); dl = 0; }
|
||||
}
|
||||
|
||||
|
||||
cursor_x += gxAdvance[gNum];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a Unicode in font so draw a rectangle and move on cursor
|
||||
drawRect(cursor_x, cursor_y + gFont.maxAscent - gFont.ascent, gFont.spaceWidth, gFont.ascent, fg);
|
||||
cursor_x += gFont.spaceWidth + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: showFont
|
||||
** Description: Page through all characters in font, td ms between screens
|
||||
*************************************************************************************x*/
|
||||
void TFT_eSPI::showFont(uint32_t td)
|
||||
{
|
||||
if(!fontLoaded) return;
|
||||
// fontFile = SPIFFS.open( _gFontFilename, "r" );
|
||||
|
||||
if(!fontFile)
|
||||
{
|
||||
fontLoaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int16_t cursorX = width(); // Force start of new page to initialise cursor
|
||||
int16_t cursorY = height();// for the first character
|
||||
uint32_t timeDelay = 0; // No delay before first page
|
||||
|
||||
fillScreen(textbgcolor);
|
||||
|
||||
for (uint16_t i = 0; i < gFont.gCount; i++)
|
||||
{
|
||||
// Check if this will need a new screen
|
||||
if (cursorX + gdX[i] + gWidth[i] >= width()) {
|
||||
cursorX = -gdX[i];
|
||||
|
||||
cursorY += gFont.yAdvance;
|
||||
if (cursorY + gFont.maxAscent + gFont.descent >= height()) {
|
||||
cursorX = -gdX[i];
|
||||
cursorY = 0;
|
||||
delay(timeDelay);
|
||||
timeDelay = td;
|
||||
fillScreen(textbgcolor);
|
||||
}
|
||||
}
|
||||
|
||||
setCursor(cursorX, cursorY);
|
||||
drawGlyph(gUnicode[i]);
|
||||
cursorX += gxAdvance[i];
|
||||
//cursorX += printToSprite( cursorX, cursorY, i );
|
||||
yield();
|
||||
}
|
||||
|
||||
delay(timeDelay);
|
||||
fillScreen(textbgcolor);
|
||||
//fontFile.close();
|
||||
|
||||
}
|
54
Extensions/Smooth_font.h
Normal file
54
Extensions/Smooth_font.h
Normal file
@ -0,0 +1,54 @@
|
||||
// Coded by Bodmer 10/2/18, see license in root directory.
|
||||
// This is part of the TFT_eSPI class and is associated with anti-aliased font functions
|
||||
|
||||
public:
|
||||
|
||||
// These are for the new antialiased fonts
|
||||
void loadFont(String fontName);
|
||||
void unloadFont( void );
|
||||
bool getUnicodeIndex(uint16_t unicode, uint16_t *index);
|
||||
|
||||
uint16_t decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining);
|
||||
uint16_t decodeUTF8(uint8_t c);
|
||||
|
||||
uint16_t alphaBlend(uint8_t alpha, uint16_t fgc, uint16_t bgc);
|
||||
|
||||
void drawGlyph(uint16_t code);
|
||||
void showFont(uint32_t td);
|
||||
|
||||
fs::File fontFile;
|
||||
|
||||
// This is for the whole font
|
||||
typedef struct
|
||||
{
|
||||
uint16_t gCount; // Total number of characters
|
||||
uint16_t yAdvance; // Line advance
|
||||
uint16_t spaceWidth; // Width of a space character
|
||||
int16_t ascent; // Height of top of 'd' above baseline, other characters may be taller
|
||||
int16_t descent; // Offset to bottom of 'p', other characters may have a larger descent
|
||||
uint16_t maxAscent; // Maximum ascent found in font
|
||||
uint16_t maxDescent; // Maximum descent found in font
|
||||
} fontMetrics;
|
||||
|
||||
fontMetrics gFont = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
// These are for the metrics for each individual glyph (so we don't need to seek this in file and waste time)
|
||||
uint16_t* gUnicode = NULL; //UTF-16 code, the codes are searched so do not need to be sequential
|
||||
uint8_t* gHeight = NULL; //cheight
|
||||
uint8_t* gWidth = NULL; //cwidth
|
||||
uint8_t* gxAdvance = NULL; //setWidth
|
||||
int8_t* gdY = NULL; //topExtent
|
||||
int8_t* gdX = NULL; //leftExtent
|
||||
uint32_t* gBitmap = NULL; //file pointer to greyscale bitmap
|
||||
|
||||
String _gFontFilename;
|
||||
|
||||
uint8_t decoderState = 0; // UTF8 decoder state
|
||||
uint16_t decoderBuffer; // Unicode code-point buffer
|
||||
|
||||
bool fontLoaded = false; // Flags when a anti-aliased font is loaded
|
||||
|
||||
private:
|
||||
|
||||
void loadMetrics(uint16_t gCount);
|
||||
uint32_t readInt32(void);
|
1409
Extensions/Sprite.cpp
Normal file
1409
Extensions/Sprite.cpp
Normal file
File diff suppressed because it is too large
Load Diff
111
Extensions/Sprite.h
Normal file
111
Extensions/Sprite.h
Normal file
@ -0,0 +1,111 @@
|
||||
/***************************************************************************************
|
||||
// The following class creates Sprites in RAM, graphics can then be drawn in the Sprite
|
||||
// and rendered quickly onto the TFT screen. The class inherits the graphics functions
|
||||
// from the TFT_eSPI class. Some functions are overridden by this class so that the
|
||||
// graphics are written to the Sprite rather than the TFT.
|
||||
***************************************************************************************/
|
||||
|
||||
class TFT_eSprite : public TFT_eSPI {
|
||||
|
||||
public:
|
||||
|
||||
TFT_eSprite(TFT_eSPI *tft);
|
||||
|
||||
// Create a sprite of width x height pixels, return a pointer to the RAM area
|
||||
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
|
||||
// RAM required is 1 byte per pixel for 8 bit colour depth, 2 bytes for 16 bit
|
||||
void* createSprite(int16_t width, int16_t height);
|
||||
|
||||
// Delete the sprite to free up the RAM
|
||||
void deleteSprite(void);
|
||||
|
||||
// Set the colour depth to 8 or 16 bits. Can be used to change depth an existing
|
||||
// sprite, but clears it to black, returns a new pointer if sprite is re-created.
|
||||
void* setColorDepth(int8_t b);
|
||||
|
||||
void drawPixel(uint32_t x, uint32_t y, uint32_t color);
|
||||
|
||||
void drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size),
|
||||
|
||||
fillSprite(uint32_t color),
|
||||
|
||||
// Define a window to push 16 bit colour pixels into is a raster order
|
||||
// Colours are converted to 8 bit if depth is set to 8
|
||||
setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1),
|
||||
pushColor(uint32_t color),
|
||||
pushColor(uint32_t color, uint16_t len),
|
||||
// Push a pixel preformatted as a 8 or 16 bit colour (avoids conversion overhead)
|
||||
writeColor(uint16_t color),
|
||||
|
||||
// Set the scroll zone, top left corner at x,y with defined width and height
|
||||
// The colour (optional, black is default) is used to fill the gap after the scroll
|
||||
setScrollRect(int32_t x, int32_t y, uint32_t w, uint32_t h, uint16_t color = TFT_BLACK),
|
||||
// Scroll the defined zone dx,dy pixels. Negative values left,up, positive right,down
|
||||
// dy is optional (default is then no up/down scroll).
|
||||
// The sprite coordinate frame does not move because pixels are moved
|
||||
scroll(int16_t dx, int16_t dy = 0),
|
||||
|
||||
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
|
||||
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
|
||||
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
|
||||
|
||||
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
|
||||
|
||||
// Set the sprite text cursor position for print class (does not change the TFT screen cursor)
|
||||
setCursor(int16_t x, int16_t y);
|
||||
|
||||
// Read the colour of a pixel at x,y and return value in 565 format
|
||||
uint16_t readPixel(int32_t x0, int32_t y0);
|
||||
|
||||
// Write an image (colour bitmap) to the sprite
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint16_t *data);
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data);
|
||||
|
||||
// Swap the byte order for pushImage() - corrects different image endianness
|
||||
void setSwapBytes(bool swap);
|
||||
bool getSwapBytes(void);
|
||||
|
||||
// Push the sprite to the TFT screen, this fn calls pushImage() in the TFT class.
|
||||
// Optionally a "transparent" colour can be defined, pixels of that colour will not be rendered
|
||||
void pushSprite(int32_t x, int32_t y);
|
||||
void pushSprite(int32_t x, int32_t y, uint16_t transparent);
|
||||
|
||||
int16_t drawChar(unsigned int uniCode, int x, int y, int font),
|
||||
drawChar(unsigned int uniCode, int x, int y);
|
||||
|
||||
// Return the width and height of the sprite
|
||||
int16_t width(void),
|
||||
height(void);
|
||||
|
||||
// Used by print class to print text to cursor position
|
||||
size_t write(uint8_t);
|
||||
|
||||
// Functions associated with anti-aliased fonts
|
||||
void drawGlyph(uint16_t code);
|
||||
void printToSprite(String string);
|
||||
void printToSprite(char *cbuffer, int len);
|
||||
int16_t printToSprite(int16_t x, int16_t y, uint16_t index);
|
||||
|
||||
private:
|
||||
|
||||
TFT_eSPI *_tft;
|
||||
|
||||
protected:
|
||||
|
||||
uint16_t *_img; // pointer to 16 bit sprite
|
||||
uint8_t *_img8; // pointer to 8 bit sprite
|
||||
bool _created, _bpp16; // created and bits per pixel depth flags
|
||||
|
||||
bool _gFont = false;
|
||||
|
||||
int32_t _icursor_x, _icursor_y;
|
||||
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
|
||||
int32_t _sx, _sy; // x,y for scroll zone
|
||||
uint32_t _sw, _sh; // w,h for scroll zone
|
||||
uint32_t _scolor; // gap fill colour for scroll zone
|
||||
|
||||
boolean _iswapBytes; // Swap the byte order for Sprite pushImage()
|
||||
|
||||
int32_t _iwidth, _iheight; // Sprite image width and height
|
||||
|
||||
};
|
319
Extensions/Touch.cpp
Normal file
319
Extensions/Touch.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
// The following touch screen support code by maxpautsch was merged 1/10/17
|
||||
// https://github.com/maxpautsch
|
||||
// Define TOUCH_CS is the user setup file to enable this code
|
||||
// A demo is provided in examples Generic folder
|
||||
// Additions by Bodmer to double sample and use Z value to improve detection reliability
|
||||
// See license in root directory.
|
||||
|
||||
#ifdef TOUCH_CS // If a pin has been allocated to the Touch screen load functions
|
||||
/***************************************************************************************
|
||||
** Function name: getTouchRaw
|
||||
** Description: read raw touch position. Return false if not pressed.
|
||||
***************************************************************************************/
|
||||
uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
|
||||
uint16_t tmp;
|
||||
CS_H;
|
||||
|
||||
spi_begin_touch();
|
||||
|
||||
T_CS_L;
|
||||
|
||||
// Start bit + YP sample request for x position
|
||||
tmp = SPI.transfer(0xd0);
|
||||
tmp = SPI.transfer(0);
|
||||
tmp = tmp <<5;
|
||||
tmp |= 0x1f & (SPI.transfer(0)>>3);
|
||||
|
||||
*x = tmp;
|
||||
|
||||
// Start bit + XP sample request for y position
|
||||
SPI.transfer(0x90);
|
||||
tmp = SPI.transfer(0);
|
||||
tmp = tmp <<5;
|
||||
tmp |= 0x1f & (SPI.transfer(0)>>3);
|
||||
|
||||
*y = tmp;
|
||||
|
||||
T_CS_H;
|
||||
|
||||
spi_end_touch();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getTouchRawZ
|
||||
** Description: read raw pressure on touchpad and return Z value.
|
||||
***************************************************************************************/
|
||||
uint16_t TFT_eSPI::getTouchRawZ(void){
|
||||
CS_H;
|
||||
|
||||
spi_begin_touch();
|
||||
|
||||
T_CS_L;
|
||||
|
||||
// Z sample request
|
||||
uint16_t tz = 0xFFF;
|
||||
SPI.transfer(0xb1);
|
||||
tz += SPI.transfer16(0xc1) >> 3;
|
||||
tz -= SPI.transfer16(0x91) >> 3;
|
||||
|
||||
T_CS_H;
|
||||
|
||||
spi_end_touch();
|
||||
|
||||
return tz;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: validTouch
|
||||
** Description: read validated position. Return false if not pressed.
|
||||
***************************************************************************************/
|
||||
#define _RAWERR 10 // Deadband in position samples
|
||||
uint8_t TFT_eSPI::validTouch(uint16_t *x, uint16_t *y, uint16_t threshold){
|
||||
uint16_t x_tmp, y_tmp, x_tmp2, y_tmp2;
|
||||
|
||||
// Wait until pressure stops increasing
|
||||
uint16_t z1 = 1;
|
||||
uint16_t z2 = 0;
|
||||
while (z1 > z2)
|
||||
{
|
||||
z2 = z1;
|
||||
z1 = getTouchRawZ();
|
||||
delay(1);
|
||||
}
|
||||
|
||||
// Serial.print("Z = ");Serial.println(z1);
|
||||
|
||||
if (z1 <= threshold) return false;
|
||||
|
||||
getTouchRaw(&x_tmp,&y_tmp);
|
||||
|
||||
// Serial.print("Sample 1 x,y = "); Serial.print(x_tmp);Serial.print(",");Serial.print(y_tmp);
|
||||
// Serial.print(", Z = ");Serial.println(z1);
|
||||
|
||||
delay(1); // Small delay to the next sample
|
||||
if (getTouchRawZ() <= threshold) return false;
|
||||
|
||||
delay(2); // Small delay to the next sample
|
||||
getTouchRaw(&x_tmp2,&y_tmp2);
|
||||
|
||||
// Serial.print("Sample 2 x,y = "); Serial.print(x_tmp2);Serial.print(",");Serial.println(y_tmp2);
|
||||
// Serial.print("Sample difference = ");Serial.print(abs(x_tmp - x_tmp2));Serial.print(",");Serial.println(abs(y_tmp - y_tmp2));
|
||||
|
||||
if (abs(x_tmp - x_tmp2) > _RAWERR) return false;
|
||||
if (abs(y_tmp - y_tmp2) > _RAWERR) return false;
|
||||
|
||||
*x = x_tmp;
|
||||
*y = y_tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: getTouch
|
||||
** Description: read callibrated position. Return false if not pressed.
|
||||
***************************************************************************************/
|
||||
#define Z_THRESHOLD 350 // Touch pressure threshold for validating touches
|
||||
uint8_t TFT_eSPI::getTouch(uint16_t *x, uint16_t *y, uint16_t threshold){
|
||||
uint16_t x_tmp, y_tmp, xx, yy;
|
||||
|
||||
if (threshold<20) threshold = 20;
|
||||
if (_pressTime > millis()) threshold=20;
|
||||
|
||||
uint8_t n = 5;
|
||||
uint8_t valid = 0;
|
||||
while (n--)
|
||||
{
|
||||
if (validTouch(&x_tmp, &y_tmp, threshold)) valid++;;
|
||||
}
|
||||
|
||||
if (valid<1) { _pressTime = 0; return false; }
|
||||
|
||||
_pressTime = millis() + 50;
|
||||
|
||||
if(!touchCalibration_rotate){
|
||||
xx=(x_tmp-touchCalibration_x0)*_width/touchCalibration_x1;
|
||||
yy=(y_tmp-touchCalibration_y0)*_height/touchCalibration_y1;
|
||||
if(touchCalibration_invert_x)
|
||||
xx = _width - xx;
|
||||
if(touchCalibration_invert_y)
|
||||
yy = _height - yy;
|
||||
} else {
|
||||
yy=(x_tmp-touchCalibration_x0)*_height/touchCalibration_x1;
|
||||
xx=(y_tmp-touchCalibration_y0)*_width/touchCalibration_y1;
|
||||
if(touchCalibration_invert_x)
|
||||
xx = _width - xx;
|
||||
if(touchCalibration_invert_y)
|
||||
yy = _height - yy;
|
||||
}
|
||||
|
||||
if (xx >= _width || yy >= _height) return valid;
|
||||
|
||||
_pressX = xx;
|
||||
_pressY = yy;
|
||||
*x = _pressX;
|
||||
*y = _pressY;
|
||||
return valid;
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: calibrateTouch
|
||||
** Description: generates calibration parameters for touchscreen.
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::calibrateTouch(uint16_t *parameters, uint32_t color_fg, uint32_t color_bg, uint8_t size){
|
||||
int16_t values[] = {0,0,0,0,0,0,0,0};
|
||||
uint16_t x_tmp, y_tmp;
|
||||
|
||||
|
||||
|
||||
for(uint8_t i = 0; i<4; i++){
|
||||
fillRect(0, 0, size+1, size+1, color_bg);
|
||||
fillRect(0, _height-size-1, size+1, size+1, color_bg);
|
||||
fillRect(_width-size-1, 0, size+1, size+1, color_bg);
|
||||
fillRect(_width-size-1, _height-size-1, size+1, size+1, color_bg);
|
||||
|
||||
if (i == 5) break; // used to clear the arrows
|
||||
|
||||
switch (i) {
|
||||
case 0: // up left
|
||||
drawLine(0, 0, 0, size, color_fg);
|
||||
drawLine(0, 0, size, 0, color_fg);
|
||||
drawLine(0, 0, size , size, color_fg);
|
||||
break;
|
||||
case 1: // bot left
|
||||
drawLine(0, _height-size-1, 0, _height-1, color_fg);
|
||||
drawLine(0, _height-1, size, _height-1, color_fg);
|
||||
drawLine(size, _height-size-1, 0, _height-1 , color_fg);
|
||||
break;
|
||||
case 2: // up right
|
||||
drawLine(_width-size-1, 0, _width-1, 0, color_fg);
|
||||
drawLine(_width-size-1, size, _width-1, 0, color_fg);
|
||||
drawLine(_width-1, size, _width-1, 0, color_fg);
|
||||
break;
|
||||
case 3: // bot right
|
||||
drawLine(_width-size-1, _height-size-1, _width-1, _height-1, color_fg);
|
||||
drawLine(_width-1, _height-1-size, _width-1, _height-1, color_fg);
|
||||
drawLine(_width-1-size, _height-1, _width-1, _height-1, color_fg);
|
||||
break;
|
||||
}
|
||||
|
||||
// user has to get the chance to release
|
||||
if(i>0) delay(1000);
|
||||
|
||||
for(uint8_t j= 0; j<8; j++){
|
||||
// Use a lower detect threshold as corners tend to be less sensitive
|
||||
while(!validTouch(&x_tmp, &y_tmp, Z_THRESHOLD/4));
|
||||
values[i*2 ] += x_tmp;
|
||||
values[i*2+1] += y_tmp;
|
||||
}
|
||||
values[i*2 ] /= 8;
|
||||
values[i*2+1] /= 8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// check orientation
|
||||
// from case 0 to case 1, the y value changed.
|
||||
// If the measured delta of the touch x axis is bigger than the delta of the y axis, the touch and TFT axes are switched.
|
||||
touchCalibration_rotate = false;
|
||||
if(abs(values[0]-values[2]) > abs(values[1]-values[3])){
|
||||
touchCalibration_rotate = true;
|
||||
touchCalibration_x0 = (values[0] + values[4])/2; // calc min x
|
||||
touchCalibration_x1 = (values[2] + values[6])/2; // calc max x
|
||||
touchCalibration_y0 = (values[1] + values[3])/2; // calc min y
|
||||
touchCalibration_y1 = (values[5] + values[7])/2; // calc max y
|
||||
} else {
|
||||
touchCalibration_x0 = (values[0] + values[2])/2; // calc min x
|
||||
touchCalibration_x1 = (values[4] + values[6])/2; // calc max x
|
||||
touchCalibration_y0 = (values[1] + values[5])/2; // calc min y
|
||||
touchCalibration_y1 = (values[3] + values[7])/2; // calc max y
|
||||
}
|
||||
|
||||
// in addition, the touch screen axis could be in the opposit direction of the TFT axis
|
||||
touchCalibration_invert_x = false;
|
||||
if(touchCalibration_x0 > touchCalibration_x1){
|
||||
values[0]=touchCalibration_x0;
|
||||
touchCalibration_x0 = touchCalibration_x1;
|
||||
touchCalibration_x1 = values[0];
|
||||
touchCalibration_invert_x = true;
|
||||
}
|
||||
touchCalibration_invert_y = false;
|
||||
if(touchCalibration_y0 > touchCalibration_y1){
|
||||
values[0]=touchCalibration_y0;
|
||||
touchCalibration_y0 = touchCalibration_y1;
|
||||
touchCalibration_y1 = values[0];
|
||||
touchCalibration_invert_y = true;
|
||||
}
|
||||
|
||||
// pre calculate
|
||||
touchCalibration_x1 -= touchCalibration_x0;
|
||||
touchCalibration_y1 -= touchCalibration_y0;
|
||||
|
||||
if(touchCalibration_x0 == 0) touchCalibration_x0 = 1;
|
||||
if(touchCalibration_x1 == 0) touchCalibration_x1 = 1;
|
||||
if(touchCalibration_y0 == 0) touchCalibration_y0 = 1;
|
||||
if(touchCalibration_y1 == 0) touchCalibration_y1 = 1;
|
||||
|
||||
// export parameters, if pointer valid
|
||||
if(parameters != NULL){
|
||||
parameters[0] = touchCalibration_x0;
|
||||
parameters[1] = touchCalibration_x1;
|
||||
parameters[2] = touchCalibration_y0;
|
||||
parameters[3] = touchCalibration_y1;
|
||||
parameters[4] = touchCalibration_rotate | (touchCalibration_invert_x <<1) | (touchCalibration_invert_y <<2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: setTouch
|
||||
** Description: imports calibration parameters for touchscreen.
|
||||
***************************************************************************************/
|
||||
void TFT_eSPI::setTouch(uint16_t *parameters){
|
||||
touchCalibration_x0 = parameters[0];
|
||||
touchCalibration_x1 = parameters[1];
|
||||
touchCalibration_y0 = parameters[2];
|
||||
touchCalibration_y1 = parameters[3];
|
||||
|
||||
if(touchCalibration_x0 == 0) touchCalibration_x0 = 1;
|
||||
if(touchCalibration_x1 == 0) touchCalibration_x1 = 1;
|
||||
if(touchCalibration_y0 == 0) touchCalibration_y0 = 1;
|
||||
if(touchCalibration_y1 == 0) touchCalibration_y1 = 1;
|
||||
|
||||
touchCalibration_rotate = parameters[4] & 0x01;
|
||||
touchCalibration_invert_x = parameters[4] & 0x02;
|
||||
touchCalibration_invert_y = parameters[4] & 0x04;
|
||||
}
|
||||
|
||||
|
||||
#else // TOUCH CS is not defined so generate dummy functions that do nothing
|
||||
|
||||
/***************************************************************************************
|
||||
** Function name: Dummy functions for case where chip select pin is undefined
|
||||
** Description:
|
||||
***************************************************************************************/
|
||||
|
||||
uint8_t TFT_eSPI::getTouchRaw(uint16_t *x, uint16_t *y){
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t TFT_eSPI::getTouchRawZ(void){
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t TFT_eSPI::validTouch(uint16_t *x, uint16_t *y, uint16_t threshold){
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t TFT_eSPI::getTouch(uint16_t *x, uint16_t *y, uint16_t threshold){
|
||||
return true;
|
||||
}
|
||||
|
||||
void TFT_eSPI::calibrateTouch(uint16_t *parameters, uint32_t color_bg, uint32_t color_fg, uint8_t size){
|
||||
}
|
||||
|
||||
void TFT_eSPI::setTouch(uint16_t *parameters){
|
||||
}
|
||||
|
||||
#endif // TOUCH_CS
|
24
Extensions/Touch.h
Normal file
24
Extensions/Touch.h
Normal file
@ -0,0 +1,24 @@
|
||||
// Coded by Bodmer 10/2/18, see license in root directory.
|
||||
// This is part of the TFT_eSPI class and is associated with the Touch Screen handlers
|
||||
|
||||
public:
|
||||
|
||||
uint8_t getTouchRaw(uint16_t *x, uint16_t *y);
|
||||
uint16_t getTouchRawZ(void);
|
||||
uint8_t getTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
|
||||
|
||||
void calibrateTouch(uint16_t *data, uint32_t color_fg, uint32_t color_bg, uint8_t size);
|
||||
void setTouch(uint16_t *data);
|
||||
|
||||
private:
|
||||
|
||||
inline void spi_begin_touch() __attribute__((always_inline));
|
||||
inline void spi_end_touch() __attribute__((always_inline));
|
||||
|
||||
// These are associated with the Touch Screen handlers
|
||||
uint8_t validTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
|
||||
// Initialise with example calibration values so processor does not crash if setTouch() not called in setup()
|
||||
uint16_t touchCalibration_x0 = 300, touchCalibration_x1 = 3600, touchCalibration_y0 = 300, touchCalibration_y1 = 3600;
|
||||
uint8_t touchCalibration_rotate = 1, touchCalibration_invert_x = 2, touchCalibration_invert_y = 0;
|
||||
uint32_t _pressTime;
|
||||
uint16_t _pressX, _pressY;
|
@ -12,7 +12,7 @@
|
||||
PROGMEM const unsigned char widtbl_f7s[96] = // character width table
|
||||
{
|
||||
12, 12, 12, 12, 12, 12, 12, 12, // char 32 - 39
|
||||
12, 12, 12, 12, 12, 17, 12, 12, // char 40 - 47
|
||||
12, 12, 12, 12, 12, 32, 12, 12, // char 40 - 47
|
||||
32, 32, 32, 32, 32, 32, 32, 32, // char 48 - 55
|
||||
32, 32, 12, 12, 12, 12, 12, 12, // char 56 - 63
|
||||
12, 12, 12, 12, 12, 12, 12, 12, // char 64 - 71
|
||||
@ -32,10 +32,12 @@ PROGMEM const unsigned char chr_f7s_20[] =
|
||||
0x7F, 0x7F, 0x7F, 0x7F, 0x3F
|
||||
};
|
||||
|
||||
// Make - sign look like a segment
|
||||
PROGMEM const unsigned char chr_f7s_2D[] =
|
||||
{
|
||||
0x7F, 0x7F, 0x45, 0x8A, 0x05, 0x8A, 0x05, 0x8A,
|
||||
0x05, 0x8A, 0x7F, 0x7F, 0x7F, 0x2B
|
||||
0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x27, 0x8E, 0x0E,
|
||||
0x92, 0x0A, 0x96, 0x09, 0x94, 0x0C, 0x90, 0x7F,
|
||||
0x7F, 0x7F, 0x7F, 0x7F, 0x47
|
||||
};
|
||||
|
||||
PROGMEM const unsigned char chr_f7s_2E[] =
|
||||
|
@ -1,5 +1,7 @@
|
||||
# TFT_eSPI
|
||||
|
||||
>>> This branch includes new antialiased font capability, this is a work-in-progress <<<
|
||||
|
||||
An Arduino IDE compatible graphics and fonts library for ESP8266 and ESP32 processors with a driver for ILI9341, ILI9163, ST7735 and S6D02A1 based TFT displays that support SPI.
|
||||
|
||||
The library also supports TFT displays designed for the Raspberry Pi that are based on a ILI9486 driver chip with a 480 x 320 pixel screen. This display must be of the Waveshare design and use a 16 bit serial interface based on the 74HC04, 74HC4040 and 2 x 74HC4094 logic chips. A modification to these displays is possible (see mod image in Tools folder) to make many graphics functions much faster (e.g. 23ms to clear the screen, 1.2ms to draw a 72 pixel high numeral).
|
||||
@ -32,7 +34,7 @@ Configuration of the library font selections, pins used to interface with the TF
|
||||
|
||||
I have made some changes that will be uploaded soon that improves sprite and image rendering performance by up to 3x faster on the ESP8266. These updates are currently being tested/debugged.
|
||||
|
||||
**2. Anti-aliased fonts - see Smooth_font branch for beta version**
|
||||
**2. Anti-aliased fonts**
|
||||
|
||||
I have been experimenting with anti-aliased font files in "vlw" format generated by the free [Processing IDE](https://processing.org/). This IDE can be used to generate font files from your computer's font set and include **any** Unicode characters. This means Greek, Japanese and any other UTF-16 glyphs can be used.
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
#ifdef CGRAM_OFFSET
|
||||
colstart = 0;
|
||||
rowstart = 0;
|
||||
@ -16,8 +16,8 @@
|
||||
break;
|
||||
case 1:
|
||||
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
#ifdef CGRAM_OFFSET
|
||||
colstart = 0;
|
||||
rowstart = 0;
|
||||
@ -25,8 +25,8 @@
|
||||
break;
|
||||
case 2:
|
||||
writedata(TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
#ifdef CGRAM_OFFSET
|
||||
colstart = 0;
|
||||
rowstart = 32;
|
||||
@ -34,8 +34,8 @@
|
||||
break;
|
||||
case 3:
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
#ifdef CGRAM_OFFSET
|
||||
colstart = 32;
|
||||
rowstart = 0;
|
||||
|
@ -11,8 +11,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MX | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 1:
|
||||
#ifdef M5STACK
|
||||
@ -20,8 +20,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MV | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 2:
|
||||
#ifdef M5STACK
|
||||
@ -29,8 +29,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MY | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 3:
|
||||
#ifdef M5STACK
|
||||
@ -38,8 +38,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
// These next rotations are for bottom up BMP drawing
|
||||
case 4:
|
||||
@ -48,8 +48,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 5:
|
||||
#ifdef M5STACK
|
||||
@ -57,8 +57,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 6:
|
||||
#ifdef M5STACK
|
||||
@ -66,8 +66,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 7:
|
||||
#ifdef M5STACK
|
||||
@ -75,8 +75,8 @@
|
||||
#else
|
||||
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
|
||||
#endif
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -5,43 +5,43 @@
|
||||
switch (rotation) {
|
||||
case 0: // Portrait
|
||||
writedata(TFT_MAD_BGR | TFT_MAD_MX);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 1: // Landscape (Portrait + 90)
|
||||
writedata(TFT_MAD_BGR | TFT_MAD_MV);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 2: // Inverter portrait
|
||||
writedata( TFT_MAD_BGR | TFT_MAD_MY);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 3: // Inverted landscape
|
||||
writedata(TFT_MAD_BGR | TFT_MAD_MV | TFT_MAD_MX | TFT_MAD_MY);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 4: // Portrait
|
||||
writedata(TFT_MAD_BGR | TFT_MAD_MX | TFT_MAD_MY);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 5: // Landscape (Portrait + 90)
|
||||
writedata(TFT_MAD_BGR | TFT_MAD_MV | TFT_MAD_MX);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 6: // Inverter portrait
|
||||
writedata( TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 7: // Inverted landscape
|
||||
writedata(TFT_MAD_BGR | TFT_MAD_MV | TFT_MAD_MY);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -7,22 +7,22 @@
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 1:
|
||||
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_BGR);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 2:
|
||||
writedata(TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 3:
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
}
|
||||
|
@ -23,8 +23,8 @@
|
||||
} else {
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_BGR);
|
||||
}
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 1:
|
||||
if (tabcolor == INITR_BLACKTAB) {
|
||||
@ -44,8 +44,8 @@
|
||||
} else {
|
||||
writedata(TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_BGR);
|
||||
}
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 2:
|
||||
if (tabcolor == INITR_BLACKTAB) {
|
||||
@ -65,8 +65,8 @@
|
||||
} else {
|
||||
writedata(TFT_MAD_BGR);
|
||||
}
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 3:
|
||||
if (tabcolor == INITR_BLACKTAB) {
|
||||
@ -86,30 +86,30 @@
|
||||
} else {
|
||||
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_BGR);
|
||||
}
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
|
||||
// These next rotations are for bottum up BMP drawing
|
||||
/* case 4:
|
||||
writedata(ST7735_TFT_MAD_MX | ST7735_TFT_MAD_MY | ST7735_TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 5:
|
||||
writedata(ST7735_TFT_MAD_MV | ST7735_TFT_MAD_MX | ST7735_TFT_MAD_BGR);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
case 6:
|
||||
writedata(ST7735_TFT_MAD_BGR);
|
||||
_width = _width_orig;
|
||||
_height = _height_orig;
|
||||
_width = _init_width;
|
||||
_height = _init_height;
|
||||
break;
|
||||
case 7:
|
||||
writedata(ST7735_TFT_MAD_MY | ST7735_TFT_MAD_MV | ST7735_TFT_MAD_BGR);
|
||||
_width = _height_orig;
|
||||
_height = _width_orig;
|
||||
_width = _init_height;
|
||||
_height = _init_width;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
1816
TFT_eSPI.cpp
1816
TFT_eSPI.cpp
File diff suppressed because it is too large
Load Diff
226
TFT_eSPI.h
226
TFT_eSPI.h
@ -1,9 +1,9 @@
|
||||
/***************************************************
|
||||
Arduino TFT graphics library targetted at ESP8266
|
||||
Arduino TFT graphics library targeted at ESP8266
|
||||
and ESP32 based boards.
|
||||
|
||||
This is a standalone library that contains the
|
||||
hardware driver, the graphics funtions and the
|
||||
hardware driver, the graphics functions and the
|
||||
proportional fonts.
|
||||
|
||||
The larger fonts are Run Length Encoded to reduce
|
||||
@ -74,6 +74,17 @@
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
#ifdef SMOOTH_FONT
|
||||
// Call up the SPIFFS FLASH filing system for the anti-aliased fonts
|
||||
#define FS_NO_GLOBALS
|
||||
#include <FS.h>
|
||||
|
||||
#ifdef ESP32
|
||||
#include "SPIFFS.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (ESP8266) && defined (D0_USED_FOR_DC)
|
||||
#define DC_C digitalWrite(TFT_DC, LOW)
|
||||
#define DC_D digitalWrite(TFT_DC, HIGH)
|
||||
@ -255,7 +266,11 @@
|
||||
template <typename T> static inline void
|
||||
swap_coord(T& a, T& b) { T t = a; a = b; b = t; }
|
||||
|
||||
// This is a structure to conveniently hold infomation on the default fonts
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
// This is a structure to conveniently hold information on the default fonts
|
||||
// Stores pointer to font character image address table, width table and height
|
||||
|
||||
// Create a null set in case some fonts not used (to prevent crash)
|
||||
@ -318,7 +333,6 @@ const PROGMEM fontinfo fontdata [] = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Class functions and variables
|
||||
class TFT_eSPI : public Print {
|
||||
|
||||
@ -343,9 +357,8 @@ class TFT_eSPI : public Print {
|
||||
void setWindow(int16_t x0, int16_t y0, int16_t x1, int16_t y1),
|
||||
pushColor(uint16_t color),
|
||||
pushColor(uint16_t color, uint16_t len),
|
||||
//pushColors(uint16_t *data, uint8_t len),
|
||||
pushColors(uint8_t *data, uint32_t len),
|
||||
pushColors(uint16_t *data, uint32_t len, bool swap = true), // With byte swap option
|
||||
pushColors(uint8_t *data, uint32_t len),
|
||||
|
||||
fillScreen(uint32_t color);
|
||||
|
||||
@ -375,7 +388,7 @@ class TFT_eSPI : public Print {
|
||||
setTextColor(uint16_t fgcolor, uint16_t bgcolor),
|
||||
setTextSize(uint8_t size),
|
||||
|
||||
setTextWrap(boolean wrap),
|
||||
setTextWrap(boolean wrapX, boolean wrapY = false),
|
||||
setTextDatum(uint8_t datum),
|
||||
setTextPadding(uint16_t x_width),
|
||||
|
||||
@ -427,13 +440,14 @@ class TFT_eSPI : public Print {
|
||||
|
||||
uint8_t getRotation(void),
|
||||
getTextDatum(void),
|
||||
color332(uint16_t color565); // Convert 16 bit colour to 8 bits
|
||||
color16to8(uint16_t color565); // Convert 16 bit colour to 8 bits
|
||||
|
||||
int16_t getCursorX(void),
|
||||
getCursorY(void);
|
||||
|
||||
uint16_t fontsLoaded(void),
|
||||
color565(uint8_t r, uint8_t g, uint8_t b);
|
||||
color565(uint8_t r, uint8_t g, uint8_t b),
|
||||
color8to16(uint8_t color332); // Convert 8 bit colour to 16 bits
|
||||
|
||||
int16_t drawNumber(long long_num,int poX, int poY, int font),
|
||||
drawNumber(long long_num,int poX, int poY),
|
||||
@ -462,49 +476,39 @@ class TFT_eSPI : public Print {
|
||||
|
||||
void setAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye);
|
||||
|
||||
// These are associated with the Touch Screen handlers
|
||||
uint8_t getTouchRaw(uint16_t *x, uint16_t *y);
|
||||
uint16_t getTouchRawZ(void);
|
||||
uint8_t getTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
|
||||
|
||||
void calibrateTouch(uint16_t *data, uint32_t color_fg, uint32_t color_bg, uint8_t size);
|
||||
void setTouch(uint16_t *data);
|
||||
|
||||
size_t write(uint8_t);
|
||||
|
||||
int32_t cursor_x, cursor_y;
|
||||
uint32_t textcolor, textbgcolor;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
inline void spi_begin() __attribute__((always_inline));
|
||||
inline void spi_end() __attribute__((always_inline));
|
||||
inline void spi_begin_touch() __attribute__((always_inline));
|
||||
inline void spi_end_touch() __attribute__((always_inline));
|
||||
|
||||
void readAddrWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye);
|
||||
|
||||
uint8_t tabcolor,
|
||||
colstart = 0, rowstart = 0; // some ST7735 displays need this changed
|
||||
|
||||
volatile uint32_t *dcport, *csport;//, *mosiport, *clkport, *rsport;
|
||||
volatile uint32_t *dcport, *csport;
|
||||
|
||||
uint32_t cspinmask, dcpinmask, wrpinmask;//, mosipinmask, clkpinmask;
|
||||
uint32_t cspinmask, dcpinmask, wrpinmask;
|
||||
|
||||
uint32_t lastColor = 0xFFFF;
|
||||
|
||||
// These are associated with the Touch Screen handlers
|
||||
uint8_t validTouch(uint16_t *x, uint16_t *y, uint16_t threshold = 600);
|
||||
// Initialise with example calibration values so processor does not crash if setTouch() not called in setup()
|
||||
uint16_t touchCalibration_x0 = 300, touchCalibration_x1 = 3600, touchCalibration_y0 = 300, touchCalibration_y1 = 3600;
|
||||
uint8_t touchCalibration_rotate = 1, touchCalibration_invert_x = 2, touchCalibration_invert_y = 0;
|
||||
uint32_t _pressTime;
|
||||
uint16_t _pressX, _pressY;
|
||||
|
||||
protected:
|
||||
|
||||
int32_t cursor_x, cursor_y, win_xe, win_ye, padX;
|
||||
int32_t win_xe, win_ye, padX;
|
||||
|
||||
uint32_t _width_orig, _height_orig; // Display w/h as input, used by setRotation()
|
||||
uint32_t _init_width, _init_height; // Display w/h as input, used by setRotation()
|
||||
uint32_t _width, _height; // Display w/h as modified by current rotation
|
||||
uint32_t textcolor, textbgcolor, fontsloaded, addr_row, addr_col;
|
||||
uint32_t addr_row, addr_col;
|
||||
|
||||
uint32_t fontsloaded;
|
||||
|
||||
uint8_t glyph_ab, // glyph height above baseline
|
||||
glyph_bb, // glyph height below baseline
|
||||
@ -513,164 +517,32 @@ class TFT_eSPI : public Print {
|
||||
textdatum, // Text reference datum
|
||||
rotation; // Display rotation (0-3)
|
||||
|
||||
bool textwrap; // If set, 'wrap' text at right edge of display
|
||||
bool textwrapX, textwrapY; // If set, 'wrap' text at right and optionally bottom edge of display
|
||||
bool _swapBytes; // Swap the byte order for TFT pushImage()
|
||||
bool locked, inTransaction; // Transaction and mutex lock flags for ESP32
|
||||
bool _booted;
|
||||
|
||||
int32_t _lastColor;
|
||||
|
||||
#ifdef LOAD_GFXFF
|
||||
GFXfont
|
||||
*gfxFont;
|
||||
GFXfont *gfxFont;
|
||||
#endif
|
||||
|
||||
};
|
||||
// Load the Touch extension
|
||||
#ifdef TOUCH_CS
|
||||
#include "Extensions/Touch.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************************
|
||||
// The following button class has been ported over from the Adafruit_GFX library so
|
||||
// should be compatible.
|
||||
// A slightly different implementation in this TFT_eSPI library allows the button
|
||||
// legends to be in any font
|
||||
***************************************************************************************/
|
||||
// Load the Anti-aliased font extension
|
||||
#ifdef SMOOTH_FONT
|
||||
#include "Extensions/Smooth_font.h"
|
||||
#endif
|
||||
|
||||
class TFT_eSPI_Button {
|
||||
|
||||
public:
|
||||
TFT_eSPI_Button(void);
|
||||
// "Classic" initButton() uses center & size
|
||||
void initButton(TFT_eSPI *gfx, int16_t x, int16_t y,
|
||||
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
|
||||
uint16_t textcolor, char *label, uint8_t textsize);
|
||||
|
||||
// New/alt initButton() uses upper-left corner & size
|
||||
void initButtonUL(TFT_eSPI *gfx, int16_t x1, int16_t y1,
|
||||
uint16_t w, uint16_t h, uint16_t outline, uint16_t fill,
|
||||
uint16_t textcolor, char *label, uint8_t textsize);
|
||||
void drawButton(boolean inverted = false);
|
||||
boolean contains(int16_t x, int16_t y);
|
||||
|
||||
void press(boolean p);
|
||||
boolean isPressed();
|
||||
boolean justPressed();
|
||||
boolean justReleased();
|
||||
|
||||
private:
|
||||
TFT_eSPI *_gfx;
|
||||
int16_t _x1, _y1; // Coordinates of top-left corner
|
||||
uint16_t _w, _h;
|
||||
uint8_t _textsize;
|
||||
uint16_t _outlinecolor, _fillcolor, _textcolor;
|
||||
char _label[10];
|
||||
|
||||
boolean currstate, laststate;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
// The following class creates Sprites in RAM, graphics can then be drawn in the Sprite
|
||||
// and rendered quickly onto the TFT screen. The class inherits the graphics functions
|
||||
// from the TFT_eSPI class. Some functions are overridden by this class so that the
|
||||
// graphics are written to the Sprite rather than the TFT.
|
||||
***************************************************************************************/
|
||||
|
||||
class TFT_eSprite : public TFT_eSPI {
|
||||
|
||||
public:
|
||||
|
||||
TFT_eSprite(TFT_eSPI *tft);
|
||||
|
||||
// Create a sprite of width x height pixels, return a pointer to the RAM area
|
||||
// Sketch can cast returned value to (uint16_t*) for 16 bit depth if needed
|
||||
// RAM required is 1 byte per pixel for 8 bit colour depth, 2 bytes for 16 bit
|
||||
uint8_t* createSprite(int16_t width, int16_t height);
|
||||
|
||||
// Delete the sprite to free up the RAM
|
||||
void deleteSprite(void);
|
||||
|
||||
// Set the colour depth to 8 or 16 bits. Can be used to change depth an existing
|
||||
// sprite, but clears it to black, returns a new pointer if sprite is re-created.
|
||||
uint8_t* setColorDepth(int8_t b);
|
||||
|
||||
void drawPixel(uint32_t x, uint32_t y, uint32_t color);
|
||||
|
||||
void drawChar(int32_t x, int32_t y, unsigned char c, uint32_t color, uint32_t bg, uint8_t size),
|
||||
|
||||
fillSprite(uint32_t color),
|
||||
|
||||
// Define a window to push 16 bit colour pixels into is a raster order
|
||||
// Colours are converted to 8 bit if depth is set to 8
|
||||
setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1),
|
||||
pushColor(uint32_t color),
|
||||
pushColor(uint32_t color, uint16_t len),
|
||||
// Push a pixel preformatted as a 8 or 16 bit colour (avoids conversion overhead)
|
||||
writeColor(uint16_t color),
|
||||
|
||||
// Set the scroll zone, top left corner at x,y with defined width and height
|
||||
// The colour (optional, black is default) is used to fill the gap after the scroll
|
||||
setScrollRect(int32_t x, int32_t y, uint32_t w, uint32_t h, uint16_t color = TFT_BLACK),
|
||||
// Scroll the defined zone dx,dy pixels. Negative values left,up, positive right,down
|
||||
// dy is optional (default is then no up/down scroll).
|
||||
// The sprite coordinate frame does not move because pixels are moved
|
||||
scroll(int16_t dx, int16_t dy = 0),
|
||||
|
||||
drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color),
|
||||
drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color),
|
||||
drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color),
|
||||
|
||||
fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color),
|
||||
|
||||
// Set the sprite text cursor position for print class (does not change the TFT screen cursor)
|
||||
setCursor(int16_t x, int16_t y);
|
||||
|
||||
// Read the colour of a pixel at x,y and return value in 565 format
|
||||
uint16_t readPixel(int32_t x0, int32_t y0);
|
||||
|
||||
// Write an image (colour bitmap) to the sprite
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, uint16_t *data);
|
||||
void pushImage(int32_t x0, int32_t y0, uint32_t w, uint32_t h, const uint16_t *data);
|
||||
|
||||
// Swap the byte order for pushImage() - corrects different image endianness
|
||||
void setSwapBytes(bool swap);
|
||||
bool getSwapBytes(void);
|
||||
|
||||
// Push the sprite to the TFT screen, this fn calls pushImage() in the TFT class.
|
||||
// Optionally a "transparent" colour can be defined, pixels of that colour will not be rendered
|
||||
void pushSprite(int32_t x, int32_t y);
|
||||
void pushSprite(int32_t x, int32_t y, uint16_t transparent);
|
||||
|
||||
int16_t drawChar(unsigned int uniCode, int x, int y, int font),
|
||||
drawChar(unsigned int uniCode, int x, int y);
|
||||
|
||||
// Return the width and height of the sprite
|
||||
int16_t width(void),
|
||||
height(void);
|
||||
|
||||
// Used by print class to print text to cursor position
|
||||
size_t write(uint8_t);
|
||||
|
||||
private:
|
||||
|
||||
TFT_eSPI *_tft;
|
||||
|
||||
protected:
|
||||
|
||||
uint16_t *_img; // pointer to 16 bit sprite
|
||||
uint8_t *_img8; // pointer to 8 bit sprite
|
||||
bool _created, _bpp16; // created and bits per pixel depth flags
|
||||
|
||||
int32_t _icursor_x, _icursor_y;
|
||||
int32_t _xs, _ys, _xe, _ye, _xptr, _yptr; // for setWindow
|
||||
int32_t _sx, _sy; // x,y for scroll zone
|
||||
uint32_t _sw, _sh; // w,h for scroll zone
|
||||
uint32_t _scolor; // gap fill colour for scroll zone
|
||||
|
||||
boolean _iswapBytes; // Swap the byte order for Sprite pushImage()
|
||||
|
||||
int32_t _iwidth, _iheight; // Sprite image width and height
|
||||
|
||||
};
|
||||
}; // End of class TFT_eSPI
|
||||
|
||||
// Load the Button Class
|
||||
#include "Extensions/Button.h"
|
||||
|
||||
// Load the Sprite Class
|
||||
#include "Extensions/Sprite.h"
|
||||
|
||||
#endif
|
||||
|
483
Tools/Create_Smooth_Font/Create_font_5/Create_font_5.pde
Normal file
483
Tools/Create_Smooth_Font/Create_font_5/Create_font_5.pde
Normal file
@ -0,0 +1,483 @@
|
||||
// Select the character range in the user configure section starting at line 100
|
||||
|
||||
/*
|
||||
Software License Agreement (FreeBSD License)
|
||||
|
||||
Copyright (c) 2018 Bodmer (https://github.com/Bodmer)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// This is a processing sketch to create font files for the TFT_eSPI library:
|
||||
|
||||
// https://github.com/Bodmer/TFT_eSPI
|
||||
|
||||
// Coded by Bodmer January 2018
|
||||
|
||||
// See comments below in code for specifying the font parameters
|
||||
// (point size, unicode blocks to include etc). Ranges of characers or
|
||||
// specific individual unicodes can be included in the created font file/
|
||||
|
||||
// Created fonts are saved in the sketches "FontFiles" folder. Press Ctrl+K to
|
||||
// see that folder.
|
||||
|
||||
// 16 bit unicodes in the range 0x0000 - 0xFFFF are supported.
|
||||
|
||||
// The sketch will convert True Type (a .ttf or .otf file) file stored in the
|
||||
// sketches "Data" folder as well as your computers system fonts.
|
||||
|
||||
// To maximise rendering performance only include the characters you will use.
|
||||
// Characters at the start of the file will render faster than those at the end.
|
||||
|
||||
// Once created the files must be loaded into the ESP32 or ESP8266 SPIFFS memory
|
||||
// using the Arduino IDE plugin detailed here:
|
||||
// https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||
// https://github.com/me-no-dev/arduino-esp32fs-plugin
|
||||
|
||||
// The sketch list all the available PC fonts to the console, you may need to increase
|
||||
// console line count (in preferences.txt) to stop some fonts scrolling out of view.
|
||||
// See link in File>Preferences to locate "preferences.txt" file. You must close
|
||||
// Processing then edit the file lines. If Processing is not closed first then the
|
||||
// edits will be overwritten by defaults! Edit "preferences.txt" as follows for
|
||||
// 1000 lines, then save, then run Processing again:
|
||||
|
||||
/*
|
||||
console.length=1000 // Line 4 in file
|
||||
console.scrollback.lines=1000 // Line 7 in file
|
||||
*/
|
||||
|
||||
// Useful links:
|
||||
/*
|
||||
|
||||
https://en.wikipedia.org/wiki/Unicode_font
|
||||
|
||||
https://www.gnu.org/software/freefont/
|
||||
https://www.gnu.org/software/freefont/sources/
|
||||
https://www.gnu.org/software/freefont/ranges/
|
||||
http://savannah.gnu.org/projects/freefont/
|
||||
|
||||
http://www.google.com/get/noto/
|
||||
|
||||
https://github.com/Bodmer/TFT_eSPI
|
||||
https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||
https://github.com/me-no-dev/arduino-esp32fs-plugin
|
||||
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
import java.awt.Desktop;
|
||||
|
||||
// >>>>>>>>>> USER CONFIGURED PARAMETERS START HERE <<<<<<<<<<
|
||||
|
||||
|
||||
// Use font name for ttf files placed in the "Data" folder or the font number seen in IDE Console for system fonts
|
||||
// the font numbers are listed when the sketch is run.
|
||||
// | 1 2 | Maximum filename size for SPIFFS is 32 including leading /
|
||||
// 1234567890123456789012345 and added point size and .vlw extension, so max is 25
|
||||
String fontName = "Final-Frontier"; //Manually crop the filename length later after creation if needed
|
||||
|
||||
String fontType = ".ttf"; //SPIFFS does not accept underscore in filename!
|
||||
//String fontType = ".otf";
|
||||
|
||||
// Use font number instead of name, -1 means use name above, or a value >=0 means use system font number from list.
|
||||
int fontNumber = -1; // << Use [Number] in brackets from the fonts listed in console window
|
||||
|
||||
// Define the font size in points for the created font file
|
||||
int fontSize = 28;
|
||||
|
||||
// Font size to use in the Processing sketch display window that pops up (can be different to above)
|
||||
int displayFontSize = 28;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Next we specify which unicode blocks from the the Basic Multilingual Plane (BMP) are included in the final font file. //
|
||||
// Note: The ttf/otf font file MAY NOT contain all possible Unicode characters, refer to the fonts online documentation. //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static final int[] unicodeBlocks = {
|
||||
// The list below has been created from the table here: https://en.wikipedia.org/wiki/Unicode_block
|
||||
// Remove // at start of lines below to include that unicode block, different code ranges can also be specified by
|
||||
// editting the start and end of range values. Multiple lines from the list below can be included, limited only by
|
||||
// the final font file size!
|
||||
|
||||
// Block range, //Block name, Code points, Assigned characters, Scripts
|
||||
// First, last, //Range is inclusive of first and last codes
|
||||
0x0021, 0x007E, //Basic Latin, 128, 128, Latin (52 characters), Common (76 characters)
|
||||
//0x0080, 0x00FF, //Latin-1 Supplement, 128, 128, Latin (64 characters), Common (64 characters)
|
||||
//0x0100, 0x017F, //Latin Extended-A, 128, 128, Latin
|
||||
//0x0180, 0x024F, //Latin Extended-B, 208, 208, Latin
|
||||
//0x0250, 0x02AF, //IPA Extensions, 96, 96, Latin
|
||||
//0x02B0, 0x02FF, //Spacing Modifier Letters, 80, 80, Bopomofo (2 characters), Latin (14 characters), Common (64 characters)
|
||||
//0x0300, 0x036F, //Combining Diacritical Marks, 112, 112, Inherited
|
||||
//0x0370, 0x03FF, //Greek and Coptic, 144, 135, Coptic (14 characters), Greek (117 characters), Common (4 characters)
|
||||
//0x0400, 0x04FF, //Cyrillic, 256, 256, Cyrillic (254 characters), Inherited (2 characters)
|
||||
//0x0500, 0x052F, //Cyrillic Supplement, 48, 48, Cyrillic
|
||||
//0x0530, 0x058F, //Armenian, 96, 89, Armenian (88 characters), Common (1 character)
|
||||
//0x0590, 0x05FF, //Hebrew, 112, 87, Hebrew
|
||||
//0x0600, 0x06FF, //Arabic, 256, 255, Arabic (237 characters), Common (6 characters), Inherited (12 characters)
|
||||
//0x0700, 0x074F, //Syriac, 80, 77, Syriac
|
||||
//0x0750, 0x077F, //Arabic Supplement, 48, 48, Arabic
|
||||
//0x0780, 0x07BF, //Thaana, 64, 50, Thaana
|
||||
//0x07C0, 0x07FF, //NKo, 64, 59, Nko
|
||||
//0x0800, 0x083F, //Samaritan, 64, 61, Samaritan
|
||||
//0x0840, 0x085F, //Mandaic, 32, 29, Mandaic
|
||||
//0x0860, 0x086F, //Syriac Supplement, 16, 11, Syriac
|
||||
//0x08A0, 0x08FF, //Arabic Extended-A, 96, 73, Arabic (72 characters), Common (1 character)
|
||||
//0x0900, 0x097F, //Devanagari, 128, 128, Devanagari (124 characters), Common (2 characters), Inherited (2 characters)
|
||||
//0x0980, 0x09FF, //Bengali, 128, 95, Bengali
|
||||
//0x0A00, 0x0A7F, //Gurmukhi, 128, 79, Gurmukhi
|
||||
//0x0A80, 0x0AFF, //Gujarati, 128, 91, Gujarati
|
||||
//0x0B00, 0x0B7F, //Oriya, 128, 90, Oriya
|
||||
//0x0B80, 0x0BFF, //Tamil, 128, 72, Tamil
|
||||
//0x0C00, 0x0C7F, //Telugu, 128, 96, Telugu
|
||||
//0x0C80, 0x0CFF, //Kannada, 128, 88, Kannada
|
||||
//0x0D00, 0x0D7F, //Malayalam, 128, 117, Malayalam
|
||||
//0x0D80, 0x0DFF, //Sinhala, 128, 90, Sinhala
|
||||
//0x0E00, 0x0E7F, //Thai, 128, 87, Thai (86 characters), Common (1 character)
|
||||
//0x0E80, 0x0EFF, //Lao, 128, 67, Lao
|
||||
//0x0F00, 0x0FFF, //Tibetan, 256, 211, Tibetan (207 characters), Common (4 characters)
|
||||
//0x1000, 0x109F, //Myanmar, 160, 160, Myanmar
|
||||
//0x10A0, 0x10FF, //Georgian, 96, 88, Georgian (87 characters), Common (1 character)
|
||||
//0x1100, 0x11FF, //Hangul Jamo, 256, 256, Hangul
|
||||
//0x1200, 0x137F, //Ethiopic, 384, 358, Ethiopic
|
||||
//0x1380, 0x139F, //Ethiopic Supplement, 32, 26, Ethiopic
|
||||
//0x13A0, 0x13FF, //Cherokee, 96, 92, Cherokee
|
||||
//0x1400, 0x167F, //Unified Canadian Aboriginal Syllabics, 640, 640, Canadian Aboriginal
|
||||
//0x1680, 0x169F, //Ogham, 32, 29, Ogham
|
||||
//0x16A0, 0x16FF, //Runic, 96, 89, Runic (86 characters), Common (3 characters)
|
||||
//0x1700, 0x171F, //Tagalog, 32, 20, Tagalog
|
||||
//0x1720, 0x173F, //Hanunoo, 32, 23, Hanunoo (21 characters), Common (2 characters)
|
||||
//0x1740, 0x175F, //Buhid, 32, 20, Buhid
|
||||
//0x1760, 0x177F, //Tagbanwa, 32, 18, Tagbanwa
|
||||
//0x1780, 0x17FF, //Khmer, 128, 114, Khmer
|
||||
//0x1800, 0x18AF, //Mongolian, 176, 156, Mongolian (153 characters), Common (3 characters)
|
||||
//0x18B0, 0x18FF, //Unified Canadian Aboriginal Syllabics Extended, 80, 70, Canadian Aboriginal
|
||||
//0x1900, 0x194F, //Limbu, 80, 68, Limbu
|
||||
//0x1950, 0x197F, //Tai Le, 48, 35, Tai Le
|
||||
//0x1980, 0x19DF, //New Tai Lue, 96, 83, New Tai Lue
|
||||
//0x19E0, 0x19FF, //Khmer Symbols, 32, 32, Khmer
|
||||
//0x1A00, 0x1A1F, //Buginese, 32, 30, Buginese
|
||||
//0x1A20, 0x1AAF, //Tai Tham, 144, 127, Tai Tham
|
||||
//0x1AB0, 0x1AFF, //Combining Diacritical Marks Extended, 80, 15, Inherited
|
||||
//0x1B00, 0x1B7F, //Balinese, 128, 121, Balinese
|
||||
//0x1B80, 0x1BBF, //Sundanese, 64, 64, Sundanese
|
||||
//0x1BC0, 0x1BFF, //Batak, 64, 56, Batak
|
||||
//0x1C00, 0x1C4F, //Lepcha, 80, 74, Lepcha
|
||||
//0x1C50, 0x1C7F, //Ol Chiki, 48, 48, Ol Chiki
|
||||
//0x1C80, 0x1C8F, //Cyrillic Extended-C, 16, 9, Cyrillic
|
||||
//0x1CC0, 0x1CCF, //Sundanese Supplement, 16, 8, Sundanese
|
||||
//0x1CD0, 0x1CFF, //Vedic Extensions, 48, 42, Common (15 characters), Inherited (27 characters)
|
||||
//0x1D00, 0x1D7F, //Phonetic Extensions, 128, 128, Cyrillic (2 characters), Greek (15 characters), Latin (111 characters)
|
||||
//0x1D80, 0x1DBF, //Phonetic Extensions Supplement, 64, 64, Greek (1 character), Latin (63 characters)
|
||||
//0x1DC0, 0x1DFF, //Combining Diacritical Marks Supplement, 64, 63, Inherited
|
||||
//0x1E00, 0x1EFF, //Latin Extended Additional, 256, 256, Latin
|
||||
//0x1F00, 0x1FFF, //Greek Extended, 256, 233, Greek
|
||||
//0x2000, 0x206F, //General Punctuation, 112, 111, Common (109 characters), Inherited (2 characters)
|
||||
//0x2070, 0x209F, //Superscripts and Subscripts, 48, 42, Latin (15 characters), Common (27 characters)
|
||||
//0x20A0, 0x20CF, //Currency Symbols, 48, 32, Common
|
||||
//0x20D0, 0x20FF, //Combining Diacritical Marks for Symbols, 48, 33, Inherited
|
||||
//0x2100, 0x214F, //Letterlike Symbols, 80, 80, Greek (1 character), Latin (4 characters), Common (75 characters)
|
||||
//0x2150, 0x218F, //Number Forms, 64, 60, Latin (41 characters), Common (19 characters)
|
||||
//0x2190, 0x21FF, //Arrows, 112, 112, Common
|
||||
//0x2200, 0x22FF, //Mathematical Operators, 256, 256, Common
|
||||
//0x2300, 0x23FF, //Miscellaneous Technical, 256, 256, Common
|
||||
//0x2400, 0x243F, //Control Pictures, 64, 39, Common
|
||||
//0x2440, 0x245F, //Optical Character Recognition, 32, 11, Common
|
||||
//0x2460, 0x24FF, //Enclosed Alphanumerics, 160, 160, Common
|
||||
//0x2500, 0x257F, //Box Drawing, 128, 128, Common
|
||||
//0x2580, 0x259F, //Block Elements, 32, 32, Common
|
||||
//0x25A0, 0x25FF, //Geometric Shapes, 96, 96, Common
|
||||
//0x2600, 0x26FF, //Miscellaneous Symbols, 256, 256, Common
|
||||
//0x2700, 0x27BF, //Dingbats, 192, 192, Common
|
||||
//0x27C0, 0x27EF, //Miscellaneous Mathematical Symbols-A, 48, 48, Common
|
||||
//0x27F0, 0x27FF, //Supplemental Arrows-A, 16, 16, Common
|
||||
//0x2800, 0x28FF, //Braille Patterns, 256, 256, Braille
|
||||
//0x2900, 0x297F, //Supplemental Arrows-B, 128, 128, Common
|
||||
//0x2980, 0x29FF, //Miscellaneous Mathematical Symbols-B, 128, 128, Common
|
||||
//0x2A00, 0x2AFF, //Supplemental Mathematical Operators, 256, 256, Common
|
||||
//0x2B00, 0x2BFF, //Miscellaneous Symbols and Arrows, 256, 207, Common
|
||||
//0x2C00, 0x2C5F, //Glagolitic, 96, 94, Glagolitic
|
||||
//0x2C60, 0x2C7F, //Latin Extended-C, 32, 32, Latin
|
||||
//0x2C80, 0x2CFF, //Coptic, 128, 123, Coptic
|
||||
//0x2D00, 0x2D2F, //Georgian Supplement, 48, 40, Georgian
|
||||
//0x2D30, 0x2D7F, //Tifinagh, 80, 59, Tifinagh
|
||||
//0x2D80, 0x2DDF, //Ethiopic Extended, 96, 79, Ethiopic
|
||||
//0x2DE0, 0x2DFF, //Cyrillic Extended-A, 32, 32, Cyrillic
|
||||
//0x2E00, 0x2E7F, //Supplemental Punctuation, 128, 74, Common
|
||||
//0x2E80, 0x2EFF, //CJK Radicals Supplement, 128, 115, Han
|
||||
//0x2F00, 0x2FDF, //Kangxi Radicals, 224, 214, Han
|
||||
//0x2FF0, 0x2FFF, //Ideographic Description Characters, 16, 12, Common
|
||||
//0x3000, 0x303F, //CJK Symbols and Punctuation, 64, 64, Han (15 characters), Hangul (2 characters), Common (43 characters), Inherited (4 characters)
|
||||
//0x3040, 0x309F, //Hiragana, 96, 93, Hiragana (89 characters), Common (2 characters), Inherited (2 characters)
|
||||
//0x30A0, 0x30FF, //Katakana, 96, 96, Katakana (93 characters), Common (3 characters)
|
||||
//0x3100, 0x312F, //Bopomofo, 48, 42, Bopomofo
|
||||
//0x3130, 0x318F, //Hangul Compatibility Jamo, 96, 94, Hangul
|
||||
//0x3190, 0x319F, //Kanbun, 16, 16, Common
|
||||
//0x31A0, 0x31BF, //Bopomofo Extended, 32, 27, Bopomofo
|
||||
//0x31C0, 0x31EF, //CJK Strokes, 48, 36, Common
|
||||
//0x31F0, 0x31FF, //Katakana Phonetic Extensions, 16, 16, Katakana
|
||||
//0x3200, 0x32FF, //Enclosed CJK Letters and Months, 256, 254, Hangul (62 characters), Katakana (47 characters), Common (145 characters)
|
||||
//0x3300, 0x33FF, //CJK Compatibility, 256, 256, Katakana (88 characters), Common (168 characters)
|
||||
//0x3400, 0x4DBF, //CJK Unified Ideographs Extension A, 6,592, 6,582, Han
|
||||
//0x4DC0, 0x4DFF, //Yijing Hexagram Symbols, 64, 64, Common
|
||||
//0x4E00, 0x9FFF, //CJK Unified Ideographs, 20,992, 20,971, Han
|
||||
//0xA000, 0xA48F, //Yi Syllables, 1,168, 1,165, Yi
|
||||
//0xA490, 0xA4CF, //Yi Radicals, 64, 55, Yi
|
||||
//0xA4D0, 0xA4FF, //Lisu, 48, 48, Lisu
|
||||
//0xA500, 0xA63F, //Vai, 320, 300, Vai
|
||||
//0xA640, 0xA69F, //Cyrillic Extended-B, 96, 96, Cyrillic
|
||||
//0xA6A0, 0xA6FF, //Bamum, 96, 88, Bamum
|
||||
//0xA700, 0xA71F, //Modifier Tone Letters, 32, 32, Common
|
||||
//0xA720, 0xA7FF, //Latin Extended-D, 224, 160, Latin (155 characters), Common (5 characters)
|
||||
//0xA800, 0xA82F, //Syloti Nagri, 48, 44, Syloti Nagri
|
||||
//0xA830, 0xA83F, //Common Indic Number Forms, 16, 10, Common
|
||||
//0xA840, 0xA87F, //Phags-pa, 64, 56, Phags Pa
|
||||
//0xA880, 0xA8DF, //Saurashtra, 96, 82, Saurashtra
|
||||
//0xA8E0, 0xA8FF, //Devanagari Extended, 32, 30, Devanagari
|
||||
//0xA900, 0xA92F, //Kayah Li, 48, 48, Kayah Li (47 characters), Common (1 character)
|
||||
//0xA930, 0xA95F, //Rejang, 48, 37, Rejang
|
||||
//0xA960, 0xA97F, //Hangul Jamo Extended-A, 32, 29, Hangul
|
||||
//0xA980, 0xA9DF, //Javanese, 96, 91, Javanese (90 characters), Common (1 character)
|
||||
//0xA9E0, 0xA9FF, //Myanmar Extended-B, 32, 31, Myanmar
|
||||
//0xAA00, 0xAA5F, //Cham, 96, 83, Cham
|
||||
//0xAA60, 0xAA7F, //Myanmar Extended-A, 32, 32, Myanmar
|
||||
//0xAA80, 0xAADF, //Tai Viet, 96, 72, Tai Viet
|
||||
//0xAAE0, 0xAAFF, //Meetei Mayek Extensions, 32, 23, Meetei Mayek
|
||||
//0xAB00, 0xAB2F, //Ethiopic Extended-A, 48, 32, Ethiopic
|
||||
//0xAB30, 0xAB6F, //Latin Extended-E, 64, 54, Latin (52 characters), Greek (1 character), Common (1 character)
|
||||
//0xAB70, 0xABBF, //Cherokee Supplement, 80, 80, Cherokee
|
||||
//0xABC0, 0xABFF, //Meetei Mayek, 64, 56, Meetei Mayek
|
||||
//0xAC00, 0xD7AF, //Hangul Syllables, 11,184, 11,172, Hangul
|
||||
//0xD7B0, 0xD7FF, //Hangul Jamo Extended-B, 80, 72, Hangul
|
||||
//0xD800, 0xDB7F, //High Surrogates, 896, 0, Unknown
|
||||
//0xDB80, 0xDBFF, //High Private Use Surrogates, 128, 0, Unknown
|
||||
//0xDC00, 0xDFFF, //Low Surrogates, 1,024, 0, Unknown
|
||||
//0xE000, 0xF8FF, //Private Use Area, 6,400, 6,400, Unknown
|
||||
//0xF900, 0xFAFF, //CJK Compatibility Ideographs, 512, 472, Han
|
||||
//0xFB00, 0xFB4F, //Alphabetic Presentation Forms, 80, 58, Armenian (5 characters), Hebrew (46 characters), Latin (7 characters)
|
||||
//0xFB50, 0xFDFF, //Arabic Presentation Forms-A, 688, 611, Arabic (609 characters), Common (2 characters)
|
||||
//0xFE00, 0xFE0F, //Variation Selectors, 16, 16, Inherited
|
||||
//0xFE10, 0xFE1F, //Vertical Forms, 16, 10, Common
|
||||
//0xFE20, 0xFE2F, //Combining Half Marks, 16, 16, Cyrillic (2 characters), Inherited (14 characters)
|
||||
//0xFE30, 0xFE4F, //CJK Compatibility Forms, 32, 32, Common
|
||||
//0xFE50, 0xFE6F, //Small Form Variants, 32, 26, Common
|
||||
//0xFE70, 0xFEFF, //Arabic Presentation Forms-B, 144, 141, Arabic (140 characters), Common (1 character)
|
||||
//0xFF00, 0xFFEF, //Halfwidth and Fullwidth Forms, 240, 225, Hangul (52 characters), Katakana (55 characters), Latin (52 characters), Common (66 characters)
|
||||
//0xFFF0, 0xFFFF, //Specials, 16, 5, Common
|
||||
|
||||
//0x0030, 0x0039, //Example custom range (numbers 0-9)
|
||||
//0x0041, 0x005A, //Example custom range (Upper case A-Z)
|
||||
//0x0061, 0x007A, //Example custom range (Lower case a-z)
|
||||
};
|
||||
|
||||
// Here we specify specific individual Unicodes to be included (appended at end of selected range)
|
||||
static final int[] specificUnicodes = {
|
||||
|
||||
// Commonly used codes, add or remove // in next line
|
||||
// 0x00A3, 0x00B0, 0x00B5, 0x03A9, 0x20AC, // £ ° µ Ω €
|
||||
|
||||
// Numbers and characters for showing time, change next line to //* to use
|
||||
/*
|
||||
0x002B, 0x002D, 0x002E, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, // - + . 0 1 2 3 4
|
||||
0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x0061, 0x006D, // 5 6 7 8 9 : a m
|
||||
0x0070, // p
|
||||
//*/
|
||||
|
||||
// More characters, change next line to //* to use
|
||||
/*
|
||||
0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0x010C, 0x010D,
|
||||
0x010E, 0x010F, 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B,
|
||||
|
||||
0x0131, 0x0139, 0x013A, 0x013D, 0x013E, 0x0141, 0x0142, 0x0143,
|
||||
0x0144, 0x0147, 0x0148, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154,
|
||||
0x0155, 0x0158, 0x0159, 0x015A, 0x015B, 0x015E, 0x015F, 0x0160,
|
||||
0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x016E, 0x016F, 0x0170,
|
||||
0x0171, 0x0178, 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E,
|
||||
0x0192,
|
||||
|
||||
0x02C6, 0x02C7, 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD,
|
||||
0x03A9, 0x03C0, 0x2013, 0x2014, 0x2018, 0x2019, 0x201A, 0x201C,
|
||||
0x201D, 0x201E, 0x2020, 0x2021, 0x2022, 0x2026, 0x2030, 0x2039,
|
||||
0x203A, 0x2044, 0x20AC,
|
||||
|
||||
0x2122, 0x2202, 0x2206, 0x220F,
|
||||
|
||||
0x2211, 0x221A, 0x221E, 0x222B, 0x2248, 0x2260, 0x2264, 0x2265,
|
||||
0x25CA,
|
||||
|
||||
0xF8FF, 0xFB01, 0xFB02,
|
||||
//*/
|
||||
};
|
||||
|
||||
|
||||
// >>>>>>>>>> USER CONFIGURED PARAMETERS END HERE <<<<<<<<<<
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Variable to hold the inclusive Unicode range (16 bit values only for this sketch)
|
||||
int firstUnicode = 0;
|
||||
int lastUnicode = 0;
|
||||
|
||||
PFont myFont;
|
||||
|
||||
void setup() {
|
||||
|
||||
size(1000, 800);
|
||||
|
||||
// Print the available fonts to the console as a list:
|
||||
String[] fontList = PFont.list();
|
||||
printArray(fontList);
|
||||
|
||||
// Set the fontName from the array number or the defined fontName
|
||||
if (fontNumber >= 0)
|
||||
{
|
||||
fontName = fontList[fontNumber];
|
||||
fontType = "";
|
||||
}
|
||||
|
||||
char[] charset;
|
||||
int index = 0, count = 0;
|
||||
|
||||
int blockCount = unicodeBlocks.length;
|
||||
|
||||
for (int i = 0; i < blockCount; i+=2) {
|
||||
firstUnicode = unicodeBlocks[i];
|
||||
lastUnicode = unicodeBlocks[i+1];
|
||||
if (lastUnicode < firstUnicode) {
|
||||
delay(100);
|
||||
System.err.println("ERROR: Bad Unicode range secified, last < first!");
|
||||
System.err.print("first in range = 0x" + hex(firstUnicode, 4));
|
||||
System.err.println(", last in range = 0x" + hex(lastUnicode, 4));
|
||||
while (true);
|
||||
}
|
||||
// calculate the number of characters
|
||||
count += (lastUnicode - firstUnicode + 1);
|
||||
}
|
||||
|
||||
count += specificUnicodes.length;
|
||||
|
||||
println();
|
||||
println("=====================");
|
||||
println("Creating font file...");
|
||||
println("Unicode blocks included = " + (blockCount/2));
|
||||
println("Specific unicodes included = " + specificUnicodes.length);
|
||||
println("Total number of characters = " + count);
|
||||
|
||||
if (count == 0) {
|
||||
delay(100);
|
||||
System.err.println("ERROR: No Unicode range or specific codes have been defined!");
|
||||
while (true);
|
||||
}
|
||||
|
||||
// allocate memory
|
||||
charset = new char[count];
|
||||
|
||||
for (int i = 0; i < blockCount; i+=2) {
|
||||
firstUnicode = unicodeBlocks[i];
|
||||
lastUnicode = unicodeBlocks[i+1];
|
||||
|
||||
// loading the range specified
|
||||
for (int code = firstUnicode; code <= lastUnicode; code++) {
|
||||
charset[index] = Character.toChars(code)[0];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// loading the range specified
|
||||
for (int i = 0; i < specificUnicodes.length; i++) {
|
||||
charset[index] = Character.toChars(specificUnicodes[i])[0];
|
||||
index++;
|
||||
}
|
||||
// Create the font in memory
|
||||
myFont = createFont(fontName+fontType, 32, true, charset);
|
||||
|
||||
// Print a few characters to the sketch window
|
||||
fill(0, 0, 0);
|
||||
textFont(myFont);
|
||||
|
||||
// Set the left and top margin
|
||||
int margin = displayFontSize;
|
||||
translate(margin/2, margin);
|
||||
|
||||
int gapx = displayFontSize*10/8;
|
||||
int gapy = displayFontSize*10/8;
|
||||
index = 0;
|
||||
fill(0);
|
||||
|
||||
textSize(displayFontSize);
|
||||
|
||||
for (int y = 0; y < height-gapy; y += gapy) {
|
||||
int x = 0;
|
||||
while (x < width) {
|
||||
|
||||
int unicode = charset[index];
|
||||
float cwidth = textWidth((char)unicode) + 2;
|
||||
if ( (x + cwidth) > (width - gapx) ) break;
|
||||
|
||||
// Draw the letter to the screen
|
||||
text(new String(Character.toChars(unicode)), x, y);
|
||||
|
||||
// Move cursor
|
||||
x += cwidth;
|
||||
// Increment the counter
|
||||
index++;
|
||||
if (index >= count) break;
|
||||
}
|
||||
if (index >= count) break;
|
||||
}
|
||||
|
||||
|
||||
// creating font
|
||||
PFont font;
|
||||
|
||||
font = createFont(fontName+fontType, fontSize, true, charset);
|
||||
|
||||
println("Created font " + fontName + ".vlw");
|
||||
|
||||
// creating file
|
||||
try {
|
||||
print("Saving to sketch FontFiles folder... ");
|
||||
|
||||
OutputStream output = createOutput("FontFiles/" + fontName + str(fontSize) + ".vlw");
|
||||
font.save(output);
|
||||
output.close();
|
||||
|
||||
println("OK!");
|
||||
|
||||
delay(100);
|
||||
|
||||
// Open up the FontFiles folder to access the saved file
|
||||
String path = sketchPath();
|
||||
Desktop.getDesktop().open(new File(path+"/FontFiles"));
|
||||
|
||||
System.err.println("All done! Note: Rectangles are displayed for non-existant characters.");
|
||||
}
|
||||
catch(IOException e) {
|
||||
println("Doh! Failed to create the file");
|
||||
}
|
||||
}
|
BIN
Tools/Create_Smooth_Font/Create_font_5/data/Final-Frontier.ttf
Normal file
BIN
Tools/Create_Smooth_Font/Create_font_5/data/Final-Frontier.ttf
Normal file
Binary file not shown.
33
Tools/PlatformIO/Configuring options.txt
Normal file
33
Tools/PlatformIO/Configuring options.txt
Normal file
@ -0,0 +1,33 @@
|
||||
PlatformIO User notes:
|
||||
|
||||
It is possible to load settings from the calling program rather than modifying
|
||||
the library for each project by modifying the "platformio.ini" file.
|
||||
|
||||
The User_Setup_Select.h file will not load the user setting header files if
|
||||
USER_SETUP_LOADED is defined.
|
||||
|
||||
Instead of using #define, use the -D prefix, for example:
|
||||
|
||||
[env:esp32dev]
|
||||
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
upload_port = ESP32-Test-2481CE9C.local
|
||||
|
||||
build_flags =
|
||||
-Os
|
||||
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||
-DUSER_SETUP_LOADED=1
|
||||
-DILI9163_DRIVER=1
|
||||
-DTFT_WIDTH=128
|
||||
-DTFT_HEIGHT=160
|
||||
-DTFT_MISO=19
|
||||
-DTFT_MOSI=23
|
||||
-DTFT_SCLK=18
|
||||
-DTFT_CS=5
|
||||
-DTFT_DC=19
|
||||
-DTFT_RST=-1
|
||||
-DLOAD_GLCD=1
|
||||
-DSPI_FREQUENCY=27000000
|
||||
|
||||
lib_extra_dirs = B:\Projects\ESP32\ESP32Lib
|
14
User_Setup.h
14
User_Setup.h
@ -88,7 +88,7 @@
|
||||
#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line)
|
||||
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V
|
||||
|
||||
//#define TOUCH_CS PIN_D1 // Chip select pin (T_CS) of touch screen
|
||||
#define TOUCH_CS PIN_D2 // Chip select pin (T_CS) of touch screen
|
||||
|
||||
//#define TFT_WR PIN_D2 // Write strobe for modified Raspberry Pi TFT only
|
||||
|
||||
@ -164,10 +164,14 @@
|
||||
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
|
||||
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
|
||||
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
|
||||
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
|
||||
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
|
||||
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
|
||||
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
|
||||
|
||||
// Comment out the #define below to stop the SPIFFS filing system and smooth font code being loaded
|
||||
// this will save ~20kbytes of FLASH
|
||||
#define SMOOTH_FONT
|
||||
|
||||
// ##################################################################################
|
||||
//
|
||||
// Section 4. Not used
|
||||
@ -192,8 +196,8 @@
|
||||
// #define SPI_FREQUENCY 5000000
|
||||
// #define SPI_FREQUENCY 10000000
|
||||
// #define SPI_FREQUENCY 20000000
|
||||
#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
|
||||
// #define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
|
||||
//#define SPI_FREQUENCY 27000000 // Actually sets it to 26.67MHz = 80/3
|
||||
#define SPI_FREQUENCY 40000000 // Maximum to use SPIFFS
|
||||
// #define SPI_FREQUENCY 80000000
|
||||
|
||||
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
|
||||
@ -210,4 +214,4 @@
|
||||
// Transactions are automatically enabled by the library for an ESP32 (to use HAL mutex)
|
||||
// so changing it here has no effect
|
||||
|
||||
// #define SUPPORT_TRANSACTIONS
|
||||
#define SUPPORT_TRANSACTIONS
|
||||
|
@ -9,7 +9,7 @@
|
||||
// changes being needed. It also improves the portability of users sketches to other
|
||||
// hardware configurations and compatible libraries.
|
||||
//
|
||||
// Create a shortcut to this file on your desktop to permit quick access for editting.
|
||||
// Create a shortcut to this file on your desktop to permit quick access for editing.
|
||||
// Re-compile and upload after making and saving any changes to this file.
|
||||
|
||||
// Customised User_Setup files are stored in the "User_Setups" folder.
|
||||
@ -34,6 +34,8 @@
|
||||
//#include <User_Setups/Setup11_RPi_touch_ILI9486.h> // Setup file configured for my stock RPi TFT with touch
|
||||
//#include <User_Setups/Setup12_M5Stack.h> // Setup file for the ESP32 based M5Stack
|
||||
|
||||
//#include <User_Setups/Setup99.h>
|
||||
|
||||
//#include <User_Setups/SetupX_Template.h> // Setup file template for copying/editting
|
||||
|
||||
|
||||
|
195
examples/Smooth Fonts/Print_Smooth_Font/Print_Smooth_Font.ino
Normal file
195
examples/Smooth Fonts/Print_Smooth_Font/Print_Smooth_Font.ino
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
Sketch to demonstrate using the print class with smooth fonts
|
||||
|
||||
Sketch is writtent for a 240 x 320 display
|
||||
|
||||
Load the font file into SPIFFS first by using the Arduino IDE
|
||||
Sketch Data Upload menu option. Font files must be stored in the
|
||||
sketch data folder (Ctrl+k to view).
|
||||
https://github.com/esp8266/arduino-esp8266fs-plugin
|
||||
https://github.com/me-no-dev/arduino-esp32fs-plugin
|
||||
|
||||
New font files in the .vlw format can be created using the Processing
|
||||
sketch in the library Tools folder. The Processing sketch can convert
|
||||
TrueType fonts in *.ttf or *.otf files.
|
||||
|
||||
Note: SPIFFS does not accept an underscore _ in filenames!
|
||||
|
||||
The library supports 16 bit unicode characters:
|
||||
https://en.wikipedia.org/wiki/Unicode_font
|
||||
|
||||
The characters supported are in the in the Basic Multilingal Plane:
|
||||
https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
|
||||
|
||||
Make sure all the display driver and pin connenctions are correct by
|
||||
editting the User_Setup.h file in the TFT_eSPI library folder.
|
||||
|
||||
#########################################################################
|
||||
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
|
||||
#########################################################################
|
||||
*/
|
||||
|
||||
// Font file is stored in SPIFFS
|
||||
#define FS_NO_GLOBALS
|
||||
#include <FS.h>
|
||||
|
||||
// Graphics and font library
|
||||
#include <TFT_eSPI.h>
|
||||
#include <SPI.h>
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // Invoke library
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Setup
|
||||
// -------------------------------------------------------------------------
|
||||
void setup(void) {
|
||||
Serial.begin(115200); // Used for messages
|
||||
|
||||
tft.init();
|
||||
tft.setRotation(1);
|
||||
|
||||
if (!SPIFFS.begin()) {
|
||||
Serial.println("SPIFFS initialisation failed!");
|
||||
while (1) yield(); // Stay here twiddling thumbs waiting
|
||||
}
|
||||
Serial.println("\r\nInitialisation done.");
|
||||
|
||||
listFiles(); // Lists the files so you can see what is in the SPIFFS
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Main loop
|
||||
// -------------------------------------------------------------------------
|
||||
void loop() {
|
||||
// Wrap test at right and bottom of screen
|
||||
tft.setTextWrap(true, true);
|
||||
|
||||
// Name of font file (library adds leading / and .vlw)
|
||||
String fileName = "Final-Frontier-28";
|
||||
|
||||
// Font and background colour, background colour is used for anti-alias blending
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
// Load the font
|
||||
tft.loadFont(fileName);
|
||||
|
||||
// Display all characters of the font
|
||||
tft.showFont(2000);
|
||||
|
||||
// Set "cursor" at top left corner of display (0,0)
|
||||
// (cursor will move to next line automatically during printing with 'tft.println'
|
||||
// or stay on the line is there is room for the text with tft.print)
|
||||
tft.setCursor(0, 0);
|
||||
|
||||
// Set the font colour to be white with a black background, set text size multiplier to 1
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
|
||||
// We can now plot text on screen using the "print" class
|
||||
tft.println("Hello World!");
|
||||
|
||||
// Set the font colour to be yellow
|
||||
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
|
||||
tft.println(1234.56);
|
||||
|
||||
// Set the font colour to be red
|
||||
tft.setTextColor(TFT_RED, TFT_BLACK);
|
||||
tft.println((uint32_t)3735928559, HEX); // Should print DEADBEEF
|
||||
|
||||
// Set the font colour to be green with black background
|
||||
tft.setTextColor(TFT_GREEN, TFT_BLACK);
|
||||
tft.println("Anti-aliased font!");
|
||||
tft.println("");
|
||||
|
||||
// Test some print formatting functions
|
||||
float fnumber = 123.45;
|
||||
|
||||
// Set the font colour to be blue
|
||||
tft.setTextColor(TFT_BLUE, TFT_BLACK);
|
||||
tft.print("Float = "); tft.println(fnumber); // Print floating point number
|
||||
tft.print("Binary = "); tft.println((int)fnumber, BIN); // Print as integer value in binary
|
||||
tft.print("Hexadecimal = "); tft.println((int)fnumber, HEX); // Print as integer number in Hexadecimal
|
||||
|
||||
// Unload the font to recover used RAM
|
||||
tft.unloadFont();
|
||||
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// List files in ESP8266 or ESP32 SPIFFS memory
|
||||
// -------------------------------------------------------------------------
|
||||
void listFiles(void) {
|
||||
Serial.println();
|
||||
Serial.println("SPIFFS files found:");
|
||||
|
||||
#ifdef ESP32
|
||||
listDir(SPIFFS, "/", true);
|
||||
#else
|
||||
fs::Dir dir = SPIFFS.openDir("/"); // Root directory
|
||||
String line = "=====================================";
|
||||
|
||||
Serial.println(line);
|
||||
Serial.println(" File name Size");
|
||||
Serial.println(line);
|
||||
|
||||
while (dir.next()) {
|
||||
String fileName = dir.fileName();
|
||||
Serial.print(fileName);
|
||||
int spaces = 25 - fileName.length(); // Tabulate nicely
|
||||
if (spaces < 0) spaces = 1;
|
||||
while (spaces--) Serial.print(" ");
|
||||
fs::File f = dir.openFile("r");
|
||||
Serial.print(f.size()); Serial.println(" bytes");
|
||||
yield();
|
||||
}
|
||||
|
||||
Serial.println(line);
|
||||
#endif
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
|
||||
Serial.printf("Listing directory: %s\n", dirname);
|
||||
|
||||
fs::File root = fs.open(dirname);
|
||||
if (!root) {
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
if (!root.isDirectory()) {
|
||||
Serial.println("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
fs::File file = root.openNextFile();
|
||||
while (file) {
|
||||
|
||||
if (file.isDirectory()) {
|
||||
Serial.print("DIR : ");
|
||||
String fileName = file.name();
|
||||
Serial.print(fileName);
|
||||
if (levels) {
|
||||
listDir(fs, file.name(), levels - 1);
|
||||
}
|
||||
} else {
|
||||
String fileName = file.name();
|
||||
Serial.print(" " + fileName);
|
||||
int spaces = 32 - fileName.length(); // Tabulate nicely
|
||||
if (spaces < 1) spaces = 1;
|
||||
while (spaces--) Serial.print(" ");
|
||||
String fileSize = (String) file.size();
|
||||
spaces = 8 - fileSize.length(); // Tabulate nicely
|
||||
if (spaces < 1) spaces = 1;
|
||||
while (spaces--) Serial.print(" ");
|
||||
Serial.println(fileSize + " bytes");
|
||||
}
|
||||
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// -------------------------------------------------------------------------
|
Binary file not shown.
83
examples/Smooth Fonts/Unicode_test/SPIFFS_functions.ino
Normal file
83
examples/Smooth Fonts/Unicode_test/SPIFFS_functions.ino
Normal file
@ -0,0 +1,83 @@
|
||||
/*====================================================================================
|
||||
This sketch supports for the ESP6266 and ESP32 SPIFFS filing system
|
||||
|
||||
Created by Bodmer 15th Jan 2017
|
||||
==================================================================================*/
|
||||
|
||||
//====================================================================================
|
||||
// Print a SPIFFS directory list (root directory)
|
||||
//====================================================================================
|
||||
|
||||
void listFiles(void) {
|
||||
Serial.println();
|
||||
Serial.println("SPIFFS files found:");
|
||||
|
||||
#ifdef ESP32
|
||||
listDir(SPIFFS, "/", true);
|
||||
#else
|
||||
fs::Dir dir = SPIFFS.openDir("/"); // Root directory
|
||||
String line = "=====================================";
|
||||
|
||||
Serial.println(line);
|
||||
Serial.println(" File name Size");
|
||||
Serial.println(line);
|
||||
|
||||
while (dir.next()) {
|
||||
String fileName = dir.fileName();
|
||||
Serial.print(fileName);
|
||||
int spaces = 25 - fileName.length(); // Tabulate nicely
|
||||
if (spaces < 0) spaces = 1;
|
||||
while (spaces--) Serial.print(" ");
|
||||
fs::File f = dir.openFile("r");
|
||||
Serial.print(f.size()); Serial.println(" bytes");
|
||||
yield();
|
||||
}
|
||||
|
||||
Serial.println(line);
|
||||
#endif
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
//====================================================================================
|
||||
|
||||
#ifdef ESP32
|
||||
void listDir(fs::FS &fs, const char * dirname, uint8_t levels) {
|
||||
Serial.printf("Listing directory: %s\n", dirname);
|
||||
|
||||
fs::File root = fs.open(dirname);
|
||||
if (!root) {
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
if (!root.isDirectory()) {
|
||||
Serial.println("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
fs::File file = root.openNextFile();
|
||||
while (file) {
|
||||
|
||||
if (file.isDirectory()) {
|
||||
Serial.print("DIR : ");
|
||||
String fileName = file.name();
|
||||
Serial.print(fileName);
|
||||
if (levels) {
|
||||
listDir(fs, file.name(), levels - 1);
|
||||
}
|
||||
} else {
|
||||
String fileName = file.name();
|
||||
Serial.print(" " + fileName);
|
||||
int spaces = 32 - fileName.length(); // Tabulate nicely
|
||||
if (spaces < 1) spaces = 1;
|
||||
while (spaces--) Serial.print(" ");
|
||||
String fileSize = (String) file.size();
|
||||
spaces = 8 - fileSize.length(); // Tabulate nicely
|
||||
if (spaces < 1) spaces = 1;
|
||||
while (spaces--) Serial.print(" ");
|
||||
Serial.println(fileSize + " bytes");
|
||||
}
|
||||
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
#endif
|
148
examples/Smooth Fonts/Unicode_test/Unicode_test.ino
Normal file
148
examples/Smooth Fonts/Unicode_test/Unicode_test.ino
Normal file
@ -0,0 +1,148 @@
|
||||
// Created by Bodmer 24th Jan 2017 - Tested in Arduino IDE 1.8.5 esp8266 Core 2.4.0
|
||||
|
||||
// The latest Arduino IDE versions support UTF-8 encoding of Unicode characters
|
||||
// within sketches:
|
||||
// https://playground.arduino.cc/Code/UTF-8
|
||||
|
||||
/*
|
||||
The library expects strings to be in UTF-8 encoded format:
|
||||
https://www.fileformat.info/info/unicode/utf8.htm
|
||||
|
||||
Creating varaibles needs to be done with care when using character arrays:
|
||||
char c = 'µ'; // Wrong
|
||||
char bad[4] = "5µA"; // Wrong
|
||||
char good[] = "5µA"; // Good
|
||||
String okay = "5µA"; // Good
|
||||
|
||||
This is because UTF-8 characters outside the basic Latin set occupy more than
|
||||
1 byte per character! A 16 bit unicode character occupies 3 bytes!
|
||||
|
||||
*/
|
||||
|
||||
//====================================================================================
|
||||
// Libraries
|
||||
//====================================================================================
|
||||
// Call up the SPIFFS FLASH filing system this is part of the ESP Core
|
||||
|
||||
#include <TFT_eSPI.h> // Hardware-specific library
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
|
||||
|
||||
uint16_t bg = TFT_BLACK;
|
||||
uint16_t fg = TFT_WHITE;
|
||||
|
||||
|
||||
//====================================================================================
|
||||
// Setup
|
||||
//====================================================================================
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // Used for messages and the C array generator
|
||||
|
||||
Serial.println("NodeMCU vlw font test!");
|
||||
|
||||
if (!SPIFFS.begin()) {
|
||||
Serial.println("SPIFFS initialisation failed!");
|
||||
while (1) yield(); // Stay here twiddling thumbs waiting
|
||||
}
|
||||
Serial.println("\r\nInitialisation done.");
|
||||
|
||||
listFiles(); // Lists the files so you can see what is in the SPIFFS
|
||||
|
||||
tft.begin();
|
||||
tft.setRotation(0); // portrait
|
||||
|
||||
fg = TFT_WHITE;
|
||||
bg = TFT_BLACK;
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
// Loop
|
||||
//====================================================================================
|
||||
void loop()
|
||||
{
|
||||
tft.setTextColor(fg, bg);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Anti-aliased font test
|
||||
|
||||
String test1 = "Hello World";
|
||||
|
||||
// Load a smooth font from SPIFFS
|
||||
tft.loadFont("Final-Frontier-28");
|
||||
|
||||
tft.setRotation(0);
|
||||
|
||||
// Show all characters on screen with 2 second (2000ms) delay between screens
|
||||
tft.showFont(2000); // Note: This function moves the cursor position!
|
||||
|
||||
tft.fillScreen(bg);
|
||||
tft.setCursor(0,0);
|
||||
|
||||
tft.println(test1);
|
||||
|
||||
// Remove font parameters from memory to recover RAM
|
||||
tft.unloadFont();
|
||||
|
||||
delay(2000);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// We can have any random mix of characters in the font
|
||||
|
||||
String test2 = "仝倀"; // Unicodes 0x4EDD, 0x5000
|
||||
|
||||
tft.loadFont("Unicode-Test-72");
|
||||
|
||||
tft.setRotation(1);
|
||||
|
||||
// Show all characters on screen with 2 second (2000ms) delay between screens
|
||||
tft.showFont(2000); // Note: This function moves the cursor position!
|
||||
|
||||
tft.fillScreen(bg);
|
||||
tft.setCursor(0,0);
|
||||
|
||||
tft.setTextColor(TFT_CYAN, bg);
|
||||
tft.println(test2);
|
||||
|
||||
tft.setTextColor(TFT_YELLOW, bg);
|
||||
tft.println("12:00pm");
|
||||
|
||||
tft.setTextColor(TFT_MAGENTA, bg);
|
||||
tft.println("1000Ω");
|
||||
|
||||
// Remove font parameters from memory to recover RAM
|
||||
tft.unloadFont();
|
||||
|
||||
delay(2000);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Latin and Hiragana font mix
|
||||
|
||||
String test3 = "こんにちは";
|
||||
|
||||
tft.loadFont("Latin-Hiragana-24");
|
||||
|
||||
tft.setRotation(0);
|
||||
|
||||
// Show all characters on screen with 2 second (2000ms) delay between screens
|
||||
tft.showFont(2000); // Note: This function moves the cursor position!
|
||||
|
||||
tft.fillScreen(bg);
|
||||
tft.setTextColor(TFT_GREEN, bg);
|
||||
tft.setCursor(0,0);
|
||||
|
||||
tft.println("Konnichiwa");
|
||||
tft.println(test3);
|
||||
tft.println();
|
||||
tft.println("Sayonara");
|
||||
tft.println("さようなら"); // Sayonara
|
||||
|
||||
// Remove font parameters from memory to recover RAM
|
||||
tft.unloadFont();
|
||||
|
||||
delay(2000);
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
}
|
||||
//====================================================================================
|
||||
|
BIN
examples/Smooth Fonts/Unicode_test/data/Final-Frontier-28.vlw
Normal file
BIN
examples/Smooth Fonts/Unicode_test/data/Final-Frontier-28.vlw
Normal file
Binary file not shown.
BIN
examples/Smooth Fonts/Unicode_test/data/Latin-Hiragana-24.vlw
Normal file
BIN
examples/Smooth Fonts/Unicode_test/data/Latin-Hiragana-24.vlw
Normal file
Binary file not shown.
BIN
examples/Smooth Fonts/Unicode_test/data/Unicode-Test-72.vlw
Normal file
BIN
examples/Smooth Fonts/Unicode_test/data/Unicode-Test-72.vlw
Normal file
Binary file not shown.
194
examples/Smooth Fonts/alphaBlend_Test/alphaBlend_Test.ino
Normal file
194
examples/Smooth Fonts/alphaBlend_Test/alphaBlend_Test.ino
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
This tests the alpha blending function that is used with the antialiased
|
||||
fonts:
|
||||
|
||||
Alpha = 0 = 100% background, alpha = 255 = 100% foreground colour
|
||||
|
||||
blendedColor = tft.alphaBlend(alpha, fg_color, bg_color);
|
||||
|
||||
The alphaBlend() function operates on 16 bit colours only
|
||||
A test is included where the colours are mapped to 8 bits after blending
|
||||
|
||||
Information on alpha blending is here
|
||||
https://en.wikipedia.org/wiki/Alpha_compositing
|
||||
|
||||
Example for library:
|
||||
https://github.com/Bodmer/TFT_eSPI
|
||||
|
||||
The sketch has been tested on a 320x240 ILI9341 based TFT, it
|
||||
could be adapted for other screen sizes.
|
||||
|
||||
Created by Bodmer 10/2/18
|
||||
|
||||
#########################################################################
|
||||
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
|
||||
#########################################################################
|
||||
*/
|
||||
|
||||
#include <TFT_eSPI.h> // Include the graphics library
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI(); // Create object "tft"
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Setup
|
||||
// -------------------------------------------------------------------------
|
||||
void setup(void) {
|
||||
tft.init();
|
||||
tft.setRotation(0);
|
||||
tft.fillScreen(TFT_DARKGREY);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Main loop
|
||||
// -------------------------------------------------------------------------
|
||||
void loop()
|
||||
{
|
||||
// 16 bit colours (5 bits red, 6 bits green, 5 bits blue)
|
||||
// Blend from white to full spectrum
|
||||
for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.alphaBlend(a, rainbow(c), TFT_WHITE));
|
||||
}
|
||||
|
||||
// Blend from full spectrum to black
|
||||
for (int a = 255; a > 2; a-=2)
|
||||
{
|
||||
for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.alphaBlend(a, rainbow(c), TFT_BLACK));
|
||||
}
|
||||
|
||||
// Blend from white to black (32 grey levels)
|
||||
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_WHITE));
|
||||
tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_RED));
|
||||
tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_GREEN));
|
||||
tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_BLUE));
|
||||
}
|
||||
|
||||
delay(4000);
|
||||
|
||||
// Blend from white to colour (32 grey levels)
|
||||
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
//tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_WHITE));
|
||||
tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_RED, TFT_WHITE));
|
||||
tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_GREEN, TFT_WHITE));
|
||||
tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_BLUE, TFT_WHITE));
|
||||
}
|
||||
|
||||
delay(4000);
|
||||
|
||||
//*
|
||||
// Decrease to 8 bit colour (3 bits red, 3 bits green, 2 bits blue)
|
||||
// Blend from white to full spectrum
|
||||
for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
// Convert blended 16 bit colour to 8 bits to reduce colour resolution, then map back to 16 bits for displaying
|
||||
for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.color8to16(tft.color16to8(tft.alphaBlend(a, rainbow(c), 0xFFFF))));
|
||||
}
|
||||
|
||||
// Blend from full spectrum to black
|
||||
for (int a = 255; a > 2; a-=2)
|
||||
{
|
||||
// Convert blended 16 bit colour to 8 bits to reduce colour resolution, then map back to 16 bits for displaying
|
||||
for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.color8to16(tft.color16to8(tft.alphaBlend(a, rainbow(c), 0))));
|
||||
}
|
||||
|
||||
// Blend from white to black (4 grey levels - it will draw 4 more with a blue tinge due to lower blue bit count)
|
||||
// Blend from black to a primary colour
|
||||
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
tft.drawFastHLine(192, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_WHITE))));
|
||||
tft.drawFastHLine(204, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_RED))));
|
||||
tft.drawFastHLine(216, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_GREEN))));
|
||||
tft.drawFastHLine(228, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_BLUE))));
|
||||
}
|
||||
|
||||
delay(4000);
|
||||
//*/
|
||||
|
||||
/*
|
||||
// 16 bit colours (5 bits red, 6 bits green, 5 bits blue)
|
||||
for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.alphaBlend(a, rainbow(c), TFT_CYAN));
|
||||
}
|
||||
|
||||
// Blend from full spectrum to cyan
|
||||
for (int a = 255; a > 2; a-=2)
|
||||
{
|
||||
for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.alphaBlend(a, rainbow(c), TFT_YELLOW));
|
||||
}
|
||||
//*/
|
||||
|
||||
/*
|
||||
// Blend other colour transitions for test purposes
|
||||
for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
|
||||
{
|
||||
tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_WHITE, TFT_WHITE)); // Should show as solid white
|
||||
tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_BLACK)); // Should show as solid black
|
||||
tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_YELLOW, TFT_CYAN)); // Brightness should be fairly even
|
||||
tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_CYAN, TFT_MAGENTA));// Brightness should be fairly even
|
||||
}
|
||||
|
||||
delay(4000);
|
||||
//*/
|
||||
}
|
||||
|
||||
|
||||
// #########################################################################
|
||||
// Return a 16 bit rainbow colour
|
||||
// #########################################################################
|
||||
unsigned int rainbow(byte value)
|
||||
{
|
||||
// If 'value' is in the range 0-159 it is converted to a spectrum colour
|
||||
// from 0 = red through to 127 = blue to 159 = violet
|
||||
// Extending the range to 0-191 adds a further violet to red band
|
||||
|
||||
value = value%192;
|
||||
|
||||
byte red = 0; // Red is the top 5 bits of a 16 bit colour value
|
||||
byte green = 0; // Green is the middle 6 bits, but only top 5 bits used here
|
||||
byte blue = 0; // Blue is the bottom 5 bits
|
||||
|
||||
byte sector = value >> 5;
|
||||
byte amplit = value & 0x1F;
|
||||
|
||||
switch (sector)
|
||||
{
|
||||
case 0:
|
||||
red = 0x1F;
|
||||
green = amplit; // Green ramps up
|
||||
blue = 0;
|
||||
break;
|
||||
case 1:
|
||||
red = 0x1F - amplit; // Red ramps down
|
||||
green = 0x1F;
|
||||
blue = 0;
|
||||
break;
|
||||
case 2:
|
||||
red = 0;
|
||||
green = 0x1F;
|
||||
blue = amplit; // Blue ramps up
|
||||
break;
|
||||
case 3:
|
||||
red = 0;
|
||||
green = 0x1F - amplit; // Green ramps down
|
||||
blue = 0x1F;
|
||||
break;
|
||||
case 4:
|
||||
red = amplit; // Red ramps up
|
||||
green = 0;
|
||||
blue = 0x1F;
|
||||
break;
|
||||
case 5:
|
||||
red = 0x1F;
|
||||
green = 0;
|
||||
blue = 0x1F - amplit; // Blue ramps down
|
||||
break;
|
||||
}
|
||||
|
||||
return red << 11 | green << 6 | blue;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,8 @@ getRotation KEYWORD2
|
||||
getTextDatum KEYWORD2
|
||||
fontsLoaded KEYWORD2
|
||||
color565 KEYWORD2
|
||||
color332 KEYWORD2
|
||||
color16to8 KEYWORD2
|
||||
color8to16 KEYWORD2
|
||||
drawNumber KEYWORD2
|
||||
drawFloat KEYWORD2
|
||||
drawString KEYWORD2
|
||||
@ -98,3 +99,8 @@ pushBitmap KEYWORD2
|
||||
pushSprite KEYWORD2
|
||||
setScrollRect KEYWORD2
|
||||
scroll KEYWORD2
|
||||
|
||||
alphaBlend KEYWORD2
|
||||
showFont KEYWORD2
|
||||
loadFont KEYWORD2
|
||||
unloadFont KEYWORD2
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TFT_eSPI",
|
||||
"version": "0.18.17",
|
||||
"version": "0.18.20",
|
||||
"keywords": "tft, display, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486",
|
||||
"description": "A TFT SPI graphics library for ESP8266 and ESP32",
|
||||
"repository":
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=TFT_eSPI
|
||||
version=0.18.17
|
||||
version=0.18.20
|
||||
author=Bodmer
|
||||
maintainer=Bodmer
|
||||
sentence=A fast TFT library for ESP8266 processors and the Arduino IDE
|
||||
|
@ -28,7 +28,7 @@ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvStartvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
|
||||
Selected functions from the Adafruit_GFX library (as it was in 2015) have
|
||||
been imported into the TFT_eSPI.cpp file and modified to improve
|
||||
perfromance, add features and make them compatible with the ESP8266 and
|
||||
performance, add features and make them compatible with the ESP8266 and
|
||||
ESP32.
|
||||
|
||||
The fonts from the Adafruit_GFX and Button functions were added later.
|
||||
@ -68,7 +68,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^End^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Due to the evolution of the TFT_eSPI library the orignal code may no longer
|
||||
Due to the evolution of the TFT_eSPI library the original code may no longer
|
||||
be recognisable, however in most cases the function names can be used as a
|
||||
reference point since the aim is to retain a level of compatibility with
|
||||
the popular Adafruit_GFX graphics functions.
|
||||
|
Loading…
Reference in New Issue
Block a user