Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
TFT_eSPI
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
TFT_eSPI
Commits
505ca81a
Commit
505ca81a
authored
Oct 11, 2020
by
Bodmer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Complete viewport update
parent
ee91f723
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
251 additions
and
236 deletions
+251
-236
Extensions/Smooth_font.cpp
Extensions/Smooth_font.cpp
+12
-9
TFT_eSPI.cpp
TFT_eSPI.cpp
+217
-202
TFT_eSPI.h
TFT_eSPI.h
+5
-2
examples/160 x 128/TFT_Char_times/TFT_Char_times.ino
examples/160 x 128/TFT_Char_times/TFT_Char_times.ino
+11
-17
examples/Sprite/Animated_dial/Animated_dial.ino
examples/Sprite/Animated_dial/Animated_dial.ino
+2
-2
examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino
examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino
+2
-2
library.json
library.json
+1
-1
library.properties
library.properties
+1
-1
No files found.
Extensions/Smooth_font.cpp
View file @
505ca81a
...
...
@@ -359,9 +359,13 @@ bool TFT_eSPI::getUnicodeIndex(uint16_t unicode, uint16_t *index)
// Expects file to be open
void
TFT_eSPI
::
drawGlyph
(
uint16_t
code
)
{
uint16_t
fg
=
textcolor
;
uint16_t
bg
=
textbgcolor
;
if
(
code
<
0x21
)
{
if
(
code
==
0x20
)
{
//if (fg!=bg) fillRect(cursor_x, cursor_y, gFont.spaceWidth, gFont.yAdvance, bg);
cursor_x
+=
gFont
.
spaceWidth
;
return
;
}
...
...
@@ -377,18 +381,15 @@ void TFT_eSPI::drawGlyph(uint16_t code)
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
))
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
(
textwrapY
&&
((
cursor_y
+
gFont
.
yAdvance
)
>=
height
()
))
cursor_y
=
0
;
if
(
cursor_x
==
0
)
cursor_x
-=
gdX
[
gNum
];
uint8_t
*
pbuffer
=
nullptr
;
...
...
@@ -402,15 +403,17 @@ void TFT_eSPI::drawGlyph(uint16_t code)
}
#endif
int16_t
xs
=
0
;
uint32_t
dl
=
0
;
uint8_t
pixel
;
int16_t
cy
=
cursor_y
+
gFont
.
maxAscent
-
gdY
[
gNum
];
int16_t
cx
=
cursor_x
+
gdX
[
gNum
];
int16_t
xs
=
cx
;
uint32_t
dl
=
0
;
uint8_t
pixel
;
startWrite
();
// Avoid slow ESP32 transaction overhead for every pixel
//if (fg!=bg) fillRect(cursor_x, cursor_y, gxAdvance[gNum], gFont.yAdvance, bg);
for
(
int
y
=
0
;
y
<
gHeight
[
gNum
];
y
++
)
{
#ifdef FONT_FS_AVAILABLE
...
...
TFT_eSPI.cpp
View file @
505ca81a
...
...
@@ -26,6 +26,26 @@
#include "Processors/TFT_eSPI_Generic.c"
#endif
// Clipping macro for pushImage
#define PI_CLIP \
if (_vpOoB) return; \
x+= _xDatum; \
y+= _yDatum; \
\
if ((x >= _vpW) || (y >= _vpH)) return; \
\
int32_t dx = 0; \
int32_t dy = 0; \
int32_t dw = w; \
int32_t dh = h; \
\
if (x < _vpX) { dx = _vpX - x; dw -= dx; x = _vpX; } \
if (y < _vpY) { dy = _vpY - y; dh -= dy; y = _vpY; } \
\
if ((x + dw) > _vpW ) dw = _vpW - x; \
if ((y + dh) > _vpH ) dh = _vpH - y; \
\
if (dw < 1 || dh < 1) return;
/***************************************************************************************
** Function name: begin_tft_write (was called spi_begin)
...
...
@@ -91,50 +111,63 @@ inline void TFT_eSPI::begin_tft_read(void){
***************************************************************************************/
void
TFT_eSPI
::
setViewport
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
bool
vpDatum
)
{
// Set to whole screen in case of error
_xDatum
=
0
;
_yDatum
=
0
;
_vpX
=
0
;
_vpY
=
0
;
_vpW
=
_width
;
_vpH
=
_height
;
_vpDatum
=
false
;
// Check if out of bounds
if
((
x
>=
_width
)
||
(
y
>=
_height
))
return
;
// Clip
if
(
x
<
0
)
{
x
=
0
;
}
if
(
y
<
0
)
{
y
=
0
;
}
if
((
x
+
w
)
>
_width
)
w
=
_width
-
x
;
if
((
y
+
h
)
>
_height
)
h
=
_height
-
y
;
// Check if out of bounds
if
(
w
<
1
||
h
<
1
)
return
;
if
(
vpDatum
)
// Viewport
_xDatum
=
x
;
// Datum x position in screen coordinates
_yDatum
=
y
;
// Datum y position in screen coordinates
_xWidth
=
w
;
// Viewport width
_yHeight
=
h
;
// Viewport height
// Clipped viewport
_vpX
=
0
;
// Viewport top left corner x coordinate
_vpY
=
0
;
// Viewport top left corner y coordinate
_vpW
=
_width
;
// Equivalent of TFT width (Nb: viewport right edge coord + 1)
_vpH
=
_height
;
// Equivalent of TFT height (Nb: viewport bottom edge coord + 1)
_vpDatum
=
false
;
// Datum is at top left corner of screen (true = top left of viewport)
_vpOoB
=
false
;
// Out of Bounds flag (true is all of viewport is off screen)
// Clip viewport to screen area
if
(
x
<
0
)
{
w
+=
x
;
x
=
0
;
}
if
(
y
<
0
)
{
h
+=
y
;
y
=
0
;
}
if
((
x
+
w
)
>
_width
)
{
w
=
_width
-
x
;
}
if
((
y
+
h
)
>
_height
)
{
h
=
_height
-
y
;
}
//Serial.print(" x=");Serial.print( x);Serial.print(", y=");Serial.print( y);
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
// Check if viewport is entirely out of bounds
if
(
w
<
1
||
h
<
1
)
{
_xDatum
=
x
;
_yDatum
=
y
;
_vpX
=
0
;
_vpY
=
0
;
_vpW
=
w
;
_vpH
=
h
;
// Set default values and Out of Bounds flag in case of error
_xDatum
=
0
;
_yDatum
=
0
;
_xWidth
=
_width
;
_yHeight
=
_height
;
_vpOoB
=
true
;
// Set Out of Bounds flag to inhibit all drawing
return
;
}
else
if
(
!
vpDatum
)
{
_xDatum
=
0
;
_xDatum
=
0
;
// Reset to top left of screen if not useing a viewport datum
_yDatum
=
0
;
_vpX
=
x
;
_vpY
=
y
;
_vpW
=
x
+
w
;
_vpH
=
y
+
h
;
_xWidth
=
_width
;
_yHeight
=
_height
;
}
// Store the on screen viewport metrics and datum position
_vpX
=
x
;
_vpY
=
y
;
_vpW
=
x
+
w
;
_vpH
=
y
+
h
;
_vpDatum
=
vpDatum
;
//Serial.print(" _xDatum=");Serial.print( _xDatum);Serial.print(", _yDatum=");Serial.print( _yDatum);
//Serial.print(", _xWidth=");Serial.print(_xWidth);Serial.print(", _yHeight=");Serial.println(_yHeight);
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
}
/***************************************************************************************
...
...
@@ -143,15 +176,18 @@ void TFT_eSPI::setViewport(int32_t x, int32_t y, int32_t w, int32_t h, bool vpDa
***************************************************************************************/
void
TFT_eSPI
::
resetViewport
(
void
)
{
//
Set to
whole screen
//
Reset viewport to the
whole screen
_xDatum
=
0
;
_yDatum
=
0
;
_vpX
=
0
;
_vpY
=
0
;
_vpW
=
_width
;
_vpH
=
_height
;
_xWidth
=
_width
;
_yHeight
=
_height
;
_vpDatum
=
false
;
_vpOoB
=
false
;
}
/***************************************************************************************
...
...
@@ -198,10 +234,10 @@ void TFT_eSPI::frameViewport(uint16_t color, int32_t w)
int32_t
_hTemp
=
_vpH
;
_vpH
=
_height
;
bool
_dTemp
=
_vpDatum
;
_vpDatum
=
false
;
fillRect
(
_x
Datum
+
_xTemp
-
w
,
_yDatum
+
_yTemp
-
w
,
_wTemp
-
_xTemp
+
w
+
w
,
w
,
color
);
fillRect
(
_x
Datum
+
_xTemp
-
w
,
_yDatum
+
_yTemp
,
w
,
_hTemp
-
_yTemp
,
color
);
fillRect
(
_
xDatum
+
_wTemp
,
_yDatum
+
_yTemp
,
w
,
_hTemp
-
_yTemp
,
color
);
fillRect
(
_x
Datum
+
_xTemp
-
w
,
_yDatum
+
_hTemp
,
_wTemp
-
_xTemp
+
w
+
w
,
w
,
color
);
fillRect
(
_x
Temp
-
_xDatum
,
_yTemp
-
w
-
_yDatum
,
_wTemp
-
_xTemp
+
w
+
w
,
w
,
color
);
fillRect
(
_x
Temp
-
w
-
_xDatum
,
_yTemp
-
_yDatum
,
w
,
_hTemp
-
_yTemp
,
color
);
fillRect
(
_
wTemp
-
_xDatum
,
_yTemp
-
_yDatum
,
w
,
_hTemp
-
_yTemp
,
color
);
fillRect
(
_x
Temp
-
w
-
_xDatum
,
_hTemp
-
_yDatum
,
_wTemp
-
_xTemp
+
w
+
w
,
w
,
color
);
_vpX
=
_xTemp
;
_vpY
=
_yTemp
;
...
...
@@ -308,13 +344,8 @@ TFT_eSPI::TFT_eSPI(int16_t w, int16_t h)
_init_width
=
_width
=
w
;
// Set by specific xxxxx_Defines.h file or by users sketch
_init_height
=
_height
=
h
;
// Set by specific xxxxx_Defines.h file or by users sketch
// Set display clip window to whole screen
_xDatum
=
0
;
_yDatum
=
0
;
_vpX
=
0
;
_vpY
=
0
;
_vpW
=
_width
;
_vpH
=
_height
;
// Reset the viewport to the whole screen
resetViewport
();
rotation
=
0
;
cursor_y
=
cursor_x
=
0
;
...
...
@@ -626,17 +657,8 @@ void TFT_eSPI::setRotation(uint8_t m)
addr_row
=
0xFFFF
;
addr_col
=
0xFFFF
;
if
(
!
_vpDatum
)
{
// Reset viewport to whole screen
_xDatum
=
0
;
_yDatum
=
0
;
_vpX
=
0
;
_vpY
=
0
;
_vpW
=
_width
;
_vpH
=
_height
;
}
// Reset the viewport to the whole screen
resetViewport
();
}
...
...
@@ -804,6 +826,19 @@ uint32_t TFT_eSPI::readcommand32(uint8_t cmd_function, uint8_t index)
***************************************************************************************/
uint16_t
TFT_eSPI
::
readPixel
(
int32_t
x0
,
int32_t
y0
)
{
if
(
_vpOoB
)
return
0
;
x0
+=
_xDatum
;
y0
+=
_yDatum
;
// Range checking
if
((
x0
<
_vpX
)
||
(
y0
<
_vpY
)
||
(
x0
>=
_vpW
)
||
(
y0
>=
_vpH
))
return
0
;
#ifdef CGRAM_OFFSET
x0
+=
colstart
;
y0
+=
rowstart
;
#endif
#if defined(TFT_PARALLEL_8_BIT)
CS_L
;
...
...
@@ -813,13 +848,15 @@ uint16_t TFT_eSPI::readPixel(int32_t x0, int32_t y0)
// Set masked pins D0- D7 to input
busDir
(
dir_mask
,
INPUT
);
#if !defined (SSD1963_DRIVER)
// Dummy read to throw away don't care value
readByte
();
#endif
// Fetch the 16 bit BRG pixel
//uint16_t rgb = (readByte() << 8) | readByte();
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER)
| defined (SSD1963_DRIVER)
// Read 3 bytes
// Read window pixel 24 bit RGB values and fill in LS bits
uint16_t
rgb
=
((
readByte
()
&
0xF8
)
<<
8
)
|
((
readByte
()
&
0xFC
)
<<
3
)
|
(
readByte
()
>>
3
);
...
...
@@ -924,7 +961,21 @@ void TFT_eSPI::setCallback(getColorCallback getCol)
***************************************************************************************/
void
TFT_eSPI
::
readRect
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
uint16_t
*
data
)
{
if
((
x
>
_width
)
||
(
y
>
_height
)
||
(
w
==
0
)
||
(
h
==
0
))
return
;
if
(
_vpOoB
)
return
;
x
+=
_xDatum
;
y
+=
_yDatum
;
// Clipping
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
if
(
x
<
_vpX
)
{
w
+=
x
-
_vpX
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
h
+=
y
-
_vpY
;
y
=
_vpY
;
}
if
((
x
+
w
)
>
_vpW
)
w
=
_vpW
-
x
;
if
((
y
+
h
)
>
_vpH
)
h
=
_vpH
-
y
;
if
((
w
<
1
)
||
(
h
<
1
))
return
;
#if defined(TFT_PARALLEL_8_BIT)
...
...
@@ -935,13 +986,13 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
// Set masked pins D0- D7 to input
busDir
(
dir_mask
,
INPUT
);
// Dummy read to throw away don't care value
readByte
();
// Total pixel count
uint32_t
len
=
w
*
h
;
#if defined (ILI9341_DRIVER) | defined (ILI9488_DRIVER) // Read 3 bytes
// Dummy read to throw away don't care value
readByte
();
// Fetch the 24 bit RGB value
while
(
len
--
)
{
// Assemble the RGB 16 bit colour
...
...
@@ -950,7 +1001,23 @@ void TFT_eSPI::readRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
// Swapped byte order for compatibility with pushRect()
*
data
++
=
(
rgb
<<
8
)
|
(
rgb
>>
8
);
}
#elif defined (SSD1963_DRIVER)
// Fetch the 18 bit BRG pixels
while
(
len
--
)
{
uint16_t
bgr
=
((
readByte
()
&
0xF8
)
>>
3
);;
// CS_L adds a small delay
bgr
|=
((
readByte
()
&
0xFC
)
<<
3
);
bgr
|=
(
readByte
()
<<
8
);
// Swap Red and Blue (could check MADCTL setting to see if this is needed)
uint16_t
rgb
=
(
bgr
>>
11
)
|
(
bgr
<<
11
)
|
(
bgr
&
0x7E0
);
// Swapped byte order for compatibility with pushRect()
*
data
++
=
(
rgb
<<
8
)
|
(
rgb
>>
8
);
}
#else // ILI9481 reads as 16 bits
// Dummy read to throw away don't care value
readByte
();
// Fetch the 16 bit BRG pixels
while
(
len
--
)
{
#ifdef ILI9486_DRIVER
...
...
@@ -1049,21 +1116,7 @@ void TFT_eSPI::pushRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *da
***************************************************************************************/
void
TFT_eSPI
::
pushImage
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
uint16_t
*
data
)
{
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
int32_t
dx
=
0
;
int32_t
dy
=
0
;
int32_t
dw
=
w
;
int32_t
dh
=
h
;
if
(
x
<
_vpX
)
{
dx
=
_vpX
-
x
;
dw
-=
dx
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
dy
=
_vpY
-
y
;
dh
-=
dy
;
y
=
_vpY
;
}
if
((
x
+
dw
)
>
_vpW
)
dw
=
_vpW
-
x
;
if
((
y
+
dh
)
>
_vpH
)
dh
=
_vpH
-
y
;
if
(
dw
<
1
||
dh
<
1
)
return
;
PI_CLIP
;
begin_tft_write
();
inTransaction
=
true
;
...
...
@@ -1093,21 +1146,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
***************************************************************************************/
void
TFT_eSPI
::
pushImage
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
uint16_t
*
data
,
uint16_t
transp
)
{
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
int32_t
dx
=
0
;
int32_t
dy
=
0
;
int32_t
dw
=
w
;
int32_t
dh
=
h
;
if
(
x
<
_vpX
)
{
dx
=
_vpX
-
x
;
dw
-=
dx
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
dy
=
_vpY
-
y
;
dh
-=
dy
;
y
=
_vpY
;
}
if
((
x
+
dw
)
>
_vpW
)
dw
=
_vpW
-
x
;
if
((
y
+
dh
)
>
_vpH
)
dh
=
_vpH
-
y
;
if
(
dw
<
1
||
dh
<
1
)
return
;
PI_CLIP
;
begin_tft_write
();
inTransaction
=
true
;
...
...
@@ -1167,20 +1206,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t *d
void
TFT_eSPI
::
pushImage
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
const
uint16_t
*
data
)
{
// Requires 32 bit aligned access, so use PROGMEM 16 bit word functions
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
int32_t
dx
=
0
;
int32_t
dy
=
0
;
int32_t
dw
=
w
;
int32_t
dh
=
h
;
if
(
x
<
_vpX
)
{
dx
=
_vpX
-
x
;
dw
-=
dx
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
dy
=
_vpY
-
y
;
dh
-=
dy
;
y
=
_vpY
;
}
if
((
x
+
dw
)
>
_vpW
)
dw
=
_vpW
-
x
;
if
((
y
+
dh
)
>
_vpH
)
dh
=
_vpH
-
y
;
if
(
dw
<
1
||
dh
<
1
)
return
;
PI_CLIP
;
begin_tft_write
();
inTransaction
=
true
;
...
...
@@ -1203,7 +1229,6 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
end_tft_write
();
}
/***************************************************************************************
** Function name: pushImage - for FLASH (PROGMEM) stored images
** Description: plot 16 bit image with 1 colour being transparent
...
...
@@ -1211,20 +1236,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
void
TFT_eSPI
::
pushImage
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
const
uint16_t
*
data
,
uint16_t
transp
)
{
// Requires 32 bit aligned access, so use PROGMEM 16 bit word functions
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
int32_t
dx
=
0
;
int32_t
dy
=
0
;
int32_t
dw
=
w
;
int32_t
dh
=
h
;
if
(
x
<
_vpX
)
{
dx
=
_vpX
-
x
;
dw
-=
dx
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
dy
=
_vpY
-
y
;
dh
-=
dy
;
y
=
_vpY
;
}
if
((
x
+
dw
)
>
_vpW
)
dw
=
_vpW
-
x
;
if
((
y
+
dh
)
>
_vpH
)
dh
=
_vpH
-
y
;
if
(
dw
<
1
||
dh
<
1
)
return
;
PI_CLIP
;
begin_tft_write
();
inTransaction
=
true
;
...
...
@@ -1280,21 +1292,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, const uint1
***************************************************************************************/
void
TFT_eSPI
::
pushImage
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
uint8_t
*
data
,
bool
bpp8
,
uint16_t
*
cmap
)
{
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
int32_t
dx
=
0
;
int32_t
dy
=
0
;
int32_t
dw
=
w
;
int32_t
dh
=
h
;
if
(
x
<
_vpX
)
{
dx
=
_vpX
-
x
;
dw
-=
dx
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
dy
=
_vpY
-
y
;
dh
-=
dy
;
y
=
_vpY
;
}
if
((
x
+
dw
)
>
_vpW
)
dw
=
_vpW
-
x
;
if
((
y
+
dh
)
>
_vpH
)
dh
=
_vpH
-
y
;
if
(
dw
<
1
||
dh
<
1
)
return
;
PI_CLIP
;
begin_tft_write
();
inTransaction
=
true
;
...
...
@@ -1437,20 +1435,7 @@ void TFT_eSPI::pushImage(int32_t x, int32_t y, int32_t w, int32_t h, uint8_t *da
***************************************************************************************/
void
TFT_eSPI
::
pushImage
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
uint8_t
*
data
,
uint8_t
transp
,
bool
bpp8
,
uint16_t
*
cmap
)
{
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
int32_t
dx
=
0
;
int32_t
dy
=
0
;
int32_t
dw
=
w
;
int32_t
dh
=
h
;
if
(
x
<
_vpX
)
{
dx
=
_vpX
-
x
;
dw
-=
dx
;
x
=
_vpX
;
}
if
(
y
<
_vpY
)
{
dy
=
_vpY
-
y
;
dh
-=
dy
;
y
=
_vpY
;
}
if
((
x
+
dw
)
>
_vpW
)
dw
=
_vpW
-
x
;
if
((
y
+
dh
)
>
_vpH
)
dh
=
_vpH
-
y
;
if
(
dw
<
1
||
dh
<
1
)
return
;
PI_CLIP
;
begin_tft_write
();
inTransaction
=
true
;
...
...
@@ -2476,8 +2461,7 @@ uint8_t TFT_eSPI::getTextDatum(void)
// Return the size of the display (per current rotation)
int16_t
TFT_eSPI
::
width
(
void
)
{
if
(
_vpDatum
)
return
_vpW
-
_vpX
;
else
return
_width
;
return
_xWidth
;
}
...
...
@@ -2487,8 +2471,7 @@ int16_t TFT_eSPI::width(void)
***************************************************************************************/
int16_t
TFT_eSPI
::
height
(
void
)
{
if
(
_vpDatum
)
return
_vpH
-
_vpY
;
else
return
_height
;
return
_yHeight
;
}
...
...
@@ -2628,28 +2611,34 @@ int16_t TFT_eSPI::fontHeight(void)
***************************************************************************************/
void
TFT_eSPI
::
drawChar
(
int32_t
x
,
int32_t
y
,
uint16_t
c
,
uint32_t
color
,
uint32_t
bg
,
uint8_t
size
)
{
if
((
x
>=
_vpW
)
||
// Clip right
(
y
>=
_vpH
)
||
// Clip bottom
((
x
+
6
*
size
-
1
)
<
_vpX
)
||
// Clip left
((
y
+
8
*
size
-
1
)
<
_vpY
))
// Clip top
return
;
if
(
_vpOoB
)
return
;
int32_t
xd
=
x
+
_xDatum
;
int32_t
yd
=
y
+
_yDatum
;
if
(
c
<
32
)
return
;
#ifdef LOAD_GLCD
//>>>>>>>>>>>>>>>>>>
#ifdef LOAD_GFXFF
#ifdef LOAD_GFXFF
if
(
!
gfxFont
)
{
// 'Classic' built-in font
#endif
#endif
//>>>>>>>>>>>>>>>>>>
if
((
xd
>=
_vpW
)
||
// Clip right
(
yd
>=
_vpH
)
||
// Clip bottom
((
xd
+
6
*
size
-
1
)
<
_vpX
)
||
// Clip left
((
yd
+
8
*
size
-
1
)
<
_vpY
))
// Clip top
return
;
bool
fillbg
=
(
bg
!=
color
);
bool
clip
=
xd
<
_vpX
||
xd
+
6
*
textsize
>=
_vpW
||
yd
<
_vpY
||
yd
+
8
*
textsize
>=
_vpH
;
if
((
size
==
1
)
&&
fillbg
&&
x
>=
_vpX
&&
(
x
+
6
*
size
-
1
)
<
_vpW
)
{
if
((
size
==
1
)
&&
fillbg
&&
!
clip
)
{
uint8_t
column
[
6
];
uint8_t
mask
=
0x1
;
begin_tft_write
();
setWindow
(
x
,
y
,
x
+
5
,
y
+
8
);
setWindow
(
x
d
,
yd
,
xd
+
5
,
yd
+
8
);
for
(
int8_t
i
=
0
;
i
<
5
;
i
++
)
column
[
i
]
=
pgm_read_byte
(
font
+
(
c
*
5
)
+
i
);
column
[
5
]
=
0
;
...
...
@@ -2668,6 +2657,7 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
else
{
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction
=
true
;
for
(
int8_t
i
=
0
;
i
<
6
;
i
++
)
{
uint8_t
line
;
if
(
i
==
5
)
...
...
@@ -2694,9 +2684,9 @@ void TFT_eSPI::drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
#ifdef LOAD_GFXFF
#ifdef LOAD_GFXFF
}
else
{
// Custom font
#endif
#endif
//>>>>>>>>>>>>>>>>>>>>>>>>>>>
#endif // LOAD_GLCD
...
...
@@ -2789,14 +2779,6 @@ void TFT_eSPI::setWindow(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
//begin_tft_write(); // Must be called before setWindow
if
(
_vpDatum
)
{
x0
+=
_xDatum
;
x1
+=
_xDatum
;
y0
+=
_yDatum
;
y1
+=
_yDatum
;
}
#if defined (SSD1963_DRIVER)
if
((
rotation
&
0x1
)
==
0
)
{
swap_coord
(
x0
,
y0
);
swap_coord
(
x1
,
y1
);
}
#endif
...
...
@@ -2870,15 +2852,14 @@ void TFT_eSPI::readAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h)
***************************************************************************************/
void
TFT_eSPI
::
drawPixel
(
int32_t
x
,
int32_t
y
,
uint32_t
color
)
{
if
(
_vpOoB
)
return
;
x
+=
_xDatum
;
y
+=
_yDatum
;
// Range checking
if
((
x
<
_vpX
)
||
(
y
<
_vpY
)
||
(
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
if
(
_vpDatum
)
{
x
+=
_xDatum
;
y
+=
_yDatum
;
}
#ifdef CGRAM_OFFSET
x
+=
colstart
;
y
+=
rowstart
;
...
...
@@ -3077,6 +3058,11 @@ void TFT_eSPI::drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t
***************************************************************************************/
void
TFT_eSPI
::
drawFastVLine
(
int32_t
x
,
int32_t
y
,
int32_t
h
,
uint32_t
color
)
{
if
(
_vpOoB
)
return
;
x
+=
_xDatum
;
y
+=
_yDatum
;
// Clipping
if
((
x
<
_vpX
)
||
(
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
...
...
@@ -3102,6 +3088,11 @@ void TFT_eSPI::drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
***************************************************************************************/
void
TFT_eSPI
::
drawFastHLine
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
uint32_t
color
)
{
if
(
_vpOoB
)
return
;
x
+=
_xDatum
;
y
+=
_yDatum
;
// Clipping
if
((
y
<
_vpY
)
||
(
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
...
...
@@ -3127,6 +3118,11 @@ void TFT_eSPI::drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
***************************************************************************************/
void
TFT_eSPI
::
fillRect
(
int32_t
x
,
int32_t
y
,
int32_t
w
,
int32_t
h
,
uint32_t
color
)
{
if
(
_vpOoB
)
return
;
x
+=
_xDatum
;
y
+=
_yDatum
;
// Clipping
if
((
x
>=
_vpW
)
||
(
y
>=
_vpH
))
return
;
...
...
@@ -3138,6 +3134,15 @@ void TFT_eSPI::fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t col
if
((
w
<
1
)
||
(
h
<
1
))
return
;
//Serial.print(" _xDatum=");Serial.print( _xDatum);Serial.print(", _yDatum=");Serial.print( _yDatum);
//Serial.print(", _xWidth=");Serial.print(_xWidth);Serial.print(", _yHeight=");Serial.println(_yHeight);
//Serial.print(" _vpX=");Serial.print( _vpX);Serial.print(", _vpY=");Serial.print( _vpY);
//Serial.print(", _vpW=");Serial.print(_vpW);Serial.print(", _vpH=");Serial.println(_vpH);
//Serial.print(" x=");Serial.print( y);Serial.print(", y=");Serial.print( y);
//Serial.print(", w=");Serial.print(w);Serial.print(", h=");Serial.println(h);
begin_tft_write
();
setWindow
(
x
,
y
,
x
+
w
-
1
,
y
+
h
-
1
);
...
...
@@ -3581,7 +3586,7 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y)
// Any UTF-8 decoding must be done before calling drawChar()
int16_t
TFT_eSPI
::
drawChar
(
uint16_t
uniCode
,
int32_t
x
,
int32_t
y
,
uint8_t
font
)
{
if
(
!
uniCode
)
return
0
;
if
(
_vpOoB
||
!
uniCode
)
return
0
;
if
(
font
==
1
)
{
#ifdef LOAD_GLCD
...
...
@@ -3645,19 +3650,23 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
}
#endif
if
(
x
+
width
*
textsize
<
(
int16_t
)
_vpX
||
x
>=
_vpW
)
return
width
*
textsize
;
int32_t
xd
=
x
+
_xDatum
;
int32_t
yd
=
y
+
_yDatum
;
if
((
xd
+
width
*
textsize
<
_vpX
||
xd
>=
_vpW
)
&&
(
yd
+
height
*
textsize
<
_vpY
||
yd
>=
_vpH
))
return
width
*
textsize
;
int32_t
w
=
width
;
int32_t
pX
=
0
;
int32_t
pY
=
y
;
uint8_t
line
=
0
;
bool
clip
=
xd
<
_vpX
||
xd
+
width
*
textsize
>=
_vpW
||
yd
<
_vpY
||
yd
+
height
*
textsize
>=
_vpH
;
#ifdef LOAD_FONT2 // chop out code if we do not need it
if
(
font
==
2
)
{
w
=
w
+
6
;
// Should be + 7 but we need to compensate for width increment
w
=
w
/
8
;
if
(
textcolor
==
textbgcolor
||
textsize
!=
1
||
x
<
_vpX
||
x
+
width
*
textsize
>=
_vpW
)
{
if
(
textcolor
==
textbgcolor
||
textsize
!=
1
||
clip
)
{
//begin_tft_write(); // Sprite class can use this function, avoiding begin_tft_write()
inTransaction
=
true
;
...
...
@@ -3698,9 +3707,10 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
end_tft_write
();
}
else
{
// Faster drawing of characters and background using block write
begin_tft_write
();
setWindow
(
x
,
y
,
x
+
width
-
1
,
y
+
height
-
1
);
setWindow
(
x
d
,
yd
,
xd
+
width
-
1
,
yd
+
height
-
1
);
uint8_t
mask
;
for
(
int32_t
i
=
0
;
i
<
height
;
i
++
)
{
...
...
@@ -3734,7 +3744,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
inTransaction
=
true
;
w
*=
height
;
// Now w is total number of pixels in the character
if
(
textcolor
==
textbgcolor
&&
x
>=
_vpX
&&
x
+
width
*
textsize
<=
_vpW
)
{
if
(
textcolor
==
textbgcolor
&&
!
clip
)
{
int32_t
px
=
0
,
py
=
pY
;
// To hold character block start and end column and row values
int32_t
pc
=
0
;
// Pixel count
uint8_t
np
=
textsize
*
textsize
;
// Number of pixels in a drawn pixel
...
...
@@ -3750,12 +3761,12 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
line
&=
0x7F
;
line
++
;
if
(
ts
)
{
px
=
x
+
textsize
*
(
pc
%
width
);
// Keep these px and py calculations outside the loop as they are slow
py
=
y
+
textsize
*
(
pc
/
width
);
px
=
x
d
+
textsize
*
(
pc
%
width
);
// Keep these px and py calculations outside the loop as they are slow
py
=
y
d
+
textsize
*
(
pc
/
width
);
}
else
{
px
=
x
+
pc
%
width
;
// Keep these px and py calculations outside the loop as they are slow
py
=
y
+
pc
/
width
;
px
=
x
d
+
pc
%
width
;
// Keep these px and py calculations outside the loop as they are slow
py
=
y
d
+
pc
/
width
;
}
while
(
line
--
)
{
// In this case the while(line--) is faster
pc
++
;
// This is faster than putting pc+=line before while()?
...
...
@@ -3768,8 +3779,8 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
else
{
tft_Write_16
(
textcolor
);}
px
+=
textsize
;
if
(
px
>=
(
x
+
width
*
textsize
))
{
px
=
x
;
if
(
px
>=
(
x
d
+
width
*
textsize
))
{
px
=
x
d
;
py
+=
textsize
;
}
}
...
...
@@ -3781,11 +3792,11 @@ int16_t TFT_eSPI::drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font)
}
}
else
{
// Text colour != background and textsize = 1 and character is within
screen
area
// Text colour != background and textsize = 1 and character is within
viewport
area
// so use faster drawing of characters and background using block write
if
(
text
size
==
1
&&
x
>=
_vpX
&&
x
+
width
<=
_vpW
)
if
(
text
color
!=
textbgcolor
&&
textsize
==
1
&&
!
clip
)
{
setWindow
(
x
,
y
,
x
+
width
-
1
,
y
+
height
-
1
);
setWindow
(
x
d
,
yd
,
xd
+
width
-
1
,
yd
+
height
-
1
);
// Maximum font size is equivalent to 180x180 pixels in area
while
(
w
>
0
)
{
...
...
@@ -3969,11 +3980,6 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
padding
+=
2
;
break
;
}
/* // Check coordinates are OK, adjust if not
if (poX < 0) poX = 0;
if (poX+cwidth > width()) poX = width() - cwidth;
if (poY < 0) poY = 0;
if (poY+cheight-baseline> height()) poY = height() - cheight; //*/
}
...
...
@@ -4010,7 +4016,16 @@ int16_t TFT_eSPI::drawString(const char *string, int32_t poX, int32_t poY, uint8
#ifdef SMOOTH_FONT
if
(
fontLoaded
)
{
if
(
textcolor
!=
textbgcolor
)
fillRect
(
poX
,
poY
,
cwidth
,
cheight
,
textbgcolor
);
/*
// The above only works for a single text line, not if the text is going to wrap...
// So need to use code like this in a while loop to fix it:
if (textwrapX && (cursor_x + width * textsize > this->width())) {
cursor_y += height;
cursor_x = 0;
}
if (textwrapY && (cursor_y >= (int32_t)this->height())) cursor_y = 0;
cursor_x += drawChar(uniCode, cursor_x, cursor_y, textfont);
*/
setCursor
(
poX
,
poY
);
while
(
n
<
len
)
{
...
...
TFT_eSPI.h
View file @
505ca81a
...
...
@@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.3.
0
"
#define TFT_ESPI_VERSION "2.3.
1
"
/***************************************************************************************
** Section 1: Load required header files
...
...
@@ -736,10 +736,13 @@ class TFT_eSPI : public Print {
int32_t
addr_row
,
addr_col
;
// Window position - used to minimise window commands
// Viewport variables
int32_t
_vpX
,
_vpY
,
_vpW
,
_vpH
;
int32_t
_vpX
,
_vpY
,
_vpW
,
_vpH
;
// Note: x start, y start, x end + 1, y end + 1
int32_t
_xDatum
;
int32_t
_yDatum
;
int32_t
_xWidth
;
int32_t
_yHeight
;
bool
_vpDatum
;
bool
_vpOoB
;
uint32_t
fontsloaded
;
// Bit field of fonts loaded
...
...
examples/160 x 128/TFT_Char_times/TFT_Char_times.ino
View file @
505ca81a
...
...
@@ -45,12 +45,11 @@ void loop() {
tft
.
setTextColor
(
TFT_RED
,
TFT_BLACK
);
tft
.
drawFloat
(
drawTime
/
2890.0
,
3
,
0
,
80
,
4
);
if
(
drawTime
<
100
)
tft
.
drawString
(
"Font 1 not loaded!"
,
0
,
108
,
2
);
delay
(
4000
);
tft
.
fillScreen
(
TFT_BLACK
);
tft
.
setTextColor
(
TFT_WHITE
,
TFT_BLACK
);
drawTime
=
millis
();
drawTime
=
millis
();
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
tft
.
drawNumber
(
i
,
0
,
0
,
2
);
...
...
@@ -60,12 +59,11 @@ void loop() {
tft
.
setTextColor
(
TFT_RED
,
TFT_BLACK
);
tft
.
drawFloat
(
drawTime
/
2890.0
,
3
,
0
,
80
,
4
);
if
(
drawTime
<
200
)
tft
.
drawString
(
"Font 2 not loaded!"
,
0
,
108
,
2
);
delay
(
4000
);
tft
.
fillScreen
(
TFT_BLACK
);
tft
.
setTextColor
(
TFT_WHITE
,
TFT_BLACK
);
drawTime
=
millis
();
drawTime
=
millis
();
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
tft
.
drawNumber
(
i
,
0
,
0
,
4
);
...
...
@@ -75,12 +73,11 @@ void loop() {
tft
.
setTextColor
(
TFT_RED
,
TFT_BLACK
);
tft
.
drawFloat
(
drawTime
/
2890.0
,
3
,
0
,
80
,
4
);
if
(
drawTime
<
200
)
tft
.
drawString
(
"Font 4 not loaded!"
,
0
,
108
,
2
);
delay
(
4000
);
tft
.
fillScreen
(
TFT_BLACK
);
tft
.
setTextColor
(
TFT_WHITE
,
TFT_BLACK
);
drawTime
=
millis
();
drawTime
=
millis
();
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
yield
();
tft
.
drawNumber
(
i
,
0
,
0
,
6
);
...
...
@@ -90,12 +87,11 @@ void loop() {
tft
.
setTextColor
(
TFT_RED
,
TFT_BLACK
);
tft
.
drawFloat
(
drawTime
/
2890.0
,
3
,
0
,
80
,
4
);
if
(
drawTime
<
200
)
tft
.
drawString
(
"Font 6 not loaded!"
,
0
,
108
,
2
);
delay
(
4000
);
tft
.
fillScreen
(
TFT_BLACK
);
tft
.
setTextColor
(
TFT_WHITE
,
TFT_BLACK
);
drawTime
=
millis
();
drawTime
=
millis
();
for
(
int
i
=
0
;
i
<
1000
;
i
++
)
{
yield
();
tft
.
drawNumber
(
i
,
0
,
0
,
7
);
...
...
@@ -105,12 +101,11 @@ void loop() {
tft
.
setTextColor
(
TFT_RED
,
TFT_BLACK
);
tft
.
drawFloat
(
drawTime
/
2890.0
,
3
,
0
,
80
,
4
);
if
(
drawTime
<
200
)
tft
.
drawString
(
"Font 7 not loaded!"
,
0
,
108
,
2
);
delay
(
4000
);
tft
.
fillScreen
(
TFT_BLACK
);
tft
.
setTextColor
(
TFT_WHITE
,
TFT_BLACK
);
drawTime
=
millis
();
drawTime
=
millis
();
for
(
int
i
=
0
;
i
<
100
;
i
++
)
{
yield
();
tft
.
drawNumber
(
i
,
0
,
0
,
8
);
...
...
@@ -120,8 +115,7 @@ void loop() {
tft
.
setTextColor
(
TFT_RED
,
TFT_BLACK
);
tft
.
drawFloat
(
drawTime
/
190.0
,
3
,
0
,
80
,
4
);
if
(
drawTime
<
200
)
tft
.
drawString
(
"Font 8 not loaded!"
,
0
,
108
,
2
);
delay
(
4000
);
}
...
...
examples/Sprite/Animated_dial/Animated_dial.ino
View file @
505ca81a
...
...
@@ -89,7 +89,7 @@ void setup() {
spr
.
setTextColor
(
TFT_WHITE
,
bg_color
);
spr
.
setTextDatum
(
MC_DATUM
);
spr
.
setTextPadding
(
spr_width
);
spr
.
drawNumber
(
0
,
spr_width
/
2
,
0
);
spr
.
drawNumber
(
0
,
spr_width
/
2
,
spr
.
fontHeight
()
/
2
);
spr
.
pushSprite
(
DIAL_CENTRE_X
-
spr_width
/
2
,
DIAL_CENTRE_Y
-
spr
.
fontHeight
()
/
2
);
// Plot the label text
...
...
@@ -203,7 +203,7 @@ void plotNeedle(int16_t angle, uint16_t ms_delay)
}
// Update the number at the centre of the dial
spr
.
drawNumber
(
old_angle
+
120
,
spr_width
/
2
,
0
);
spr
.
drawNumber
(
old_angle
+
120
,
spr_width
/
2
,
spr
.
fontHeight
()
/
2
);
spr
.
pushSprite
(
120
-
spr_width
/
2
,
120
-
spr
.
fontHeight
()
/
2
);
// Slow needle down slightly as it approaches the new position
...
...
examples/Sprite/Rotated_Sprite_1/Rotated_Sprite_1.ino
View file @
505ca81a
...
...
@@ -132,7 +132,7 @@ void loop() {
for
(
int16_t
angle
=
30
;
angle
<=
360
;
angle
+=
30
)
{
spr
.
fillSprite
(
TFT_BLACK
);
// Clear the Sprite
spr
.
drawNumber
(
num
,
20
,
15
,
4
);
// Plot number, in Sprite at
15
,15 and with font 4
spr
.
drawNumber
(
num
,
20
,
15
,
4
);
// Plot number, in Sprite at
20
,15 and with font 4
spr
.
pushRotated
(
angle
,
TFT_BLACK
);
// Plot rotated Sprite, black being transparent
num
++
;
}
...
...
@@ -143,7 +143,7 @@ void loop() {
for
(
int16_t
angle
=
-
90
;
angle
<
270
;
angle
+=
30
)
{
spr
.
fillSprite
(
TFT_BLACK
);
// Clear the Sprite
spr
.
drawNumber
(
angle
+
90
,
15
,
15
,
4
);
// Plot number, in Sprite at 15
,15 and with font 4
spr
.
drawNumber
(
angle
+
90
,
20
,
15
,
4
);
// Plot number, in Sprite at 20
,15 and with font 4
spr
.
pushRotated
(
angle
,
TFT_BLACK
);
// Plot rotated Sprite, black being transparent
num
++
;
}
...
...
library.json
View file @
505ca81a
{
"name"
:
"TFT_eSPI"
,
"version"
:
"2.3.
0
"
,
"version"
:
"2.3.
1
"
,
"keywords"
:
"Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140"
,
"description"
:
"A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32"
,
"repository"
:
...
...
library.properties
View file @
505ca81a
name
=
TFT_eSPI
version
=
2.3.
0
version
=
2.3.
1
author
=
Bodmer
maintainer
=
Bodmer
sentence
=
TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment