fix(screenshot): send GxEPD2 rotation in header; full rot 0-3 decode in Python

Firmware (7-byte header):
  Byte 7 = display->screenshotRotation() — GxEPD2/GFX rotation value (0-3).
  DisplayDriver::screenshotRotation() defaults to 0 (OLED).
  GxEPDDisplay::screenshotRotation() returns display.getRotation(), the
  live GxEPD2 value (reflects runtime setDisplayRotation() calls, not just
  the compile-time DISPLAY_ROTATION macro).

Python decoder:
  - Parse 7-byte header; pass rotation to eink_buffer_to_image().
  - Implement all four GxEPD2 drawPixel coordinate transforms:
      rot 0: phys_x=lx,            phys_y=ly
      rot 1: phys_x=vis_w-1-ly,    phys_y=lx
      rot 2: phys_x=vis_w-1-lx,    phys_y=vis_h-1-ly  (180° flip)
      rot 3: phys_x=ly,            phys_y=vis_h-1-lx
  - vis_w/vis_h derived from log dimensions + rotation parity (no constants).
  - Print rot= in the status line so the user sees which rotation was used.

This fixes the 180° rotated image seen with rotation=2 (portrait inverted)
without hardcoding a flip — correct for any rotation value.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-28 08:10:16 +02:00
parent 37432491dd
commit d1a88c8277
4 changed files with 55 additions and 34 deletions

View File

@@ -258,7 +258,8 @@ public:
// Override in e-ink drivers to return the GxEPD2-reported dimensions (which use
// WIDTH_VISIBLE instead of the full physical WIDTH used by DisplayDriver).
// OLED drivers: width()/height() already reflect the visible canvas, so no override needed.
virtual int screenshotWidth() { return width(); }
virtual int screenshotHeight() { return height(); }
virtual int screenshotWidth() { return width(); }
virtual int screenshotHeight() { return height(); }
virtual uint8_t screenshotRotation() { return 0; } // 0-3, GxEPD2/GFX rotation value
#endif
};

View File

@@ -84,8 +84,9 @@ public:
uint8_t getDisplayType() override { return 1; } // 1 = e-ink
// Return GxEPD2's own reported dimensions (uses WIDTH_VISIBLE, not the full physical WIDTH
// stored in DisplayDriver). After setRotation(1): width()=HEIGHT, height()=WIDTH_VISIBLE.
int screenshotWidth() override { return (int)display.width(); }
int screenshotHeight() override { return (int)display.height(); }
int screenshotWidth() override { return (int)display.width(); }
int screenshotHeight() override { return (int)display.height(); }
uint8_t screenshotRotation() override { return (uint8_t)display.getRotation(); }
#endif
// Line height and approx. char width for each font size: