Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Marcussacapuces91/doc-TFT_eSPI/llms.txt

Use this file to discover all available pages before exploring further.

A viewport is a rectangular clipping region that constrains all subsequent drawing operations to a defined area of the screen. Any pixels that would fall outside the viewport are silently discarded — the display hardware outside that region is never touched. This makes viewports useful for building windowed UIs, protecting status bars from being overwritten, and optimising partial-screen updates by ensuring drawing calls can never stray into unintended areas. TFT_eSPI signals viewport capability at compile time via the TFT_ESPI_FEATURES constant: bit 0 set (#define TFT_ESPI_FEATURES 1) indicates that the viewport API is available.

Setting a Viewport

void setViewport(int32_t x, int32_t y, int32_t w, int32_t h,
                 bool vpDatum = true);
x
int32_t
required
X coordinate of the viewport’s top-left corner in screen coordinates.
y
int32_t
required
Y coordinate of the viewport’s top-left corner in screen coordinates.
w
int32_t
required
Width of the viewport in pixels.
h
int32_t
required
Height of the viewport in pixels.
vpDatum
bool
Controls how drawing coordinates are interpreted after the viewport is active.
  • true (default): Drawing coordinates are relative to the viewport’s top-left corner — coordinate (0, 0) means the top-left of the viewport.
  • false: Drawing coordinates are absolute screen coordinates — the viewport only clips; it does not shift the origin.

Example

#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();

void setup() {
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_DARKGREY);

  // Define a 160×120 viewport starting at (40, 30)
  // vpDatum = true: coords inside are relative to the viewport
  tft.setViewport(40, 30, 160, 120);

  // Fill the viewport with navy — does not affect anything outside it
  tft.fillScreen(TFT_NAVY);

  // Draw a string at (5, 5) relative to the viewport's top-left corner
  tft.setTextColor(TFT_WHITE, TFT_NAVY);
  tft.drawString("Inside viewport", 5, 5, 2);

  // Draw a border around the viewport using its own colour
  tft.frameViewport(TFT_YELLOW, 2);

  // Remove the viewport — drawing is now unrestricted again
  tft.resetViewport();
}

Removing a Viewport

void resetViewport(void);
Clears the viewport clipping region and restores the full screen as the drawing area. After resetViewport(), coordinates are once again absolute screen coordinates.

Viewport Getters

Once a viewport is active, you can query its parameters:
MethodReturn typeDescription
getViewportX()int32_tX origin of the viewport in screen coordinates
getViewportY()int32_tY origin of the viewport in screen coordinates
getViewportWidth()int32_tWidth of the viewport in pixels
getViewportHeight()int32_tHeight of the viewport in pixels
getViewportDatum()booltrue if datum is relative to viewport origin
Serial.printf("Viewport: x=%d  y=%d  w=%d  h=%d  datum=%d\n",
  tft.getViewportX(),
  tft.getViewportY(),
  tft.getViewportWidth(),
  tft.getViewportHeight(),
  tft.getViewportDatum());

Checking for Intersection

bool checkViewport(int32_t x, int32_t y, int32_t w, int32_t h);
Returns true if the rectangle described by (x, y, w, h) intersects the current viewport. This is useful before performing expensive drawing operations — you can skip work entirely when nothing would be visible:
if (tft.checkViewport(spriteX, spriteY, spriteW, spriteH)) {
  spr.pushSprite(spriteX, spriteY);  // Only push if visible
}

Drawing a Frame Around the Viewport

void frameViewport(uint16_t color, int32_t w);
Draws a rectangle of width w pixels in color around the current viewport boundary. The frame is drawn outside the viewport, so the interior clipping region is unaffected. This is useful for visually highlighting the active region during development or for UI panel borders.
tft.frameViewport(TFT_ORANGE, 3);  // 3-pixel orange border

Direct CGRAM Window Control

For advanced low-level use, TFT_eSPI exposes direct control over the display’s CGRAM address window — the rectangular region within the display driver that the next batch of pixel data will be written into.

setWindow vs. setAddrWindow

virtual void setWindow(int32_t xs, int32_t ys, int32_t xe, int32_t ye);
void         setAddrWindow(int32_t xs, int32_t ys, int32_t w, int32_t h);
  • setWindow(xs, ys, xe, ye) — sets the CGRAM window using inclusive start and end coordinates.
  • setAddrWindow(xs, ys, w, h) — convenience wrapper that takes a top-left origin plus width and height instead of end coordinates.
These calls position the display driver’s write pointer. Subsequent pushColor() or writeColor() calls will fill the window row by row. You must call startWrite() before and endWrite() after to bracket the SPI transaction:
tft.startWrite();
tft.setAddrWindow(10, 10, 50, 50);          // 50×50 region at (10,10)
for (int i = 0; i < 50 * 50; i++) {
  tft.writeColor(TFT_CYAN, 1);
}
tft.endWrite();

Clipping Window Helpers

Two boolean helpers check whether a given window intersects the current viewport. They also clip the coordinates in place to the intersection:
bool clipAddrWindow(int32_t* x, int32_t* y, int32_t* w, int32_t* h);
bool clipWindow(int32_t* xs, int32_t* ys, int32_t* xe, int32_t* ye);
  • clipAddrWindow() — works with origin + size format (x, y, w, h).
  • clipWindow() — works with start + end format (xs, ys, xe, ye).
Both return false if the rectangle lies entirely outside the viewport (no pixels would be drawn), allowing you to bail out early. They return true and modify the pointed-to values to the clipped coordinates when partial overlap exists.

Viewport with Absolute Coordinates

Setting vpDatum = false keeps the coordinate origin at the physical display’s top-left corner. The viewport still clips all drawing to the defined rectangle, but you do not need to offset your coordinates:
// Viewport at (100,50) with size 200×100 — coords stay absolute
tft.setViewport(100, 50, 200, 100, false);

// Draw at absolute screen position (120, 70) — within the viewport
tft.fillRect(120, 70, 40, 40, TFT_GREEN);

// This would be clipped: rect at (50,50) is outside the viewport
tft.fillRect(50, 50, 40, 40, TFT_RED);  // No-op
TFT_ESPI_FEATURES (value 1) has bit 0 set to indicate that viewport capability is compiled in. You can check this at runtime to write code that gracefully degrades if a stripped-down build is in use:
if (TFT_ESPI_FEATURES & 0x01) {
  tft.setViewport(0, 0, 160, 120);
}

Build docs developers (and LLMs) love