Fix X3 issue

This commit is contained in:
jpirnay
2026-04-14 19:36:55 +02:00
parent 47dcf23f2c
commit ef31e4c1c1
2 changed files with 94 additions and 86 deletions
+90 -82
View File
@@ -232,7 +232,8 @@ static inline uint8_t bitmapExtract(const uint8_t* bitmap, const int bitPos, con
// bits — MSB-aligned; bit 7 = pixel at phyBitPos, lower (8-count) bits are zero.
// phyBitPos — physical X of the MSB pixel; may be negative for left-edge partial chunks.
// pixelState true → black (clear bits to 0), false → white (set bits to 1).
static inline void writeRowBits(uint8_t* const row, const int phyBitPos, const uint8_t bits, const bool pixelState) {
static inline void writeRowBits(uint8_t* const row, const int phyBitPos, const uint8_t bits, const bool pixelState,
const int widthBytes) {
uint8_t effectiveBits = bits;
int byteIdx;
int shift;
@@ -251,12 +252,10 @@ static inline void writeRowBits(uint8_t* const row, const int phyBitPos, const u
}
if (pixelState) {
row[byteIdx] &= ~(effectiveBits >> shift);
if (shift > 0 && byteIdx + 1 < HalDisplay::DISPLAY_WIDTH_BYTES)
row[byteIdx + 1] &= ~(uint8_t)(effectiveBits << (8 - shift));
if (shift > 0 && byteIdx + 1 < widthBytes) row[byteIdx + 1] &= ~(uint8_t)(effectiveBits << (8 - shift));
} else {
row[byteIdx] |= (effectiveBits >> shift);
if (shift > 0 && byteIdx + 1 < HalDisplay::DISPLAY_WIDTH_BYTES)
row[byteIdx + 1] |= (uint8_t)(effectiveBits << (8 - shift));
if (shift > 0 && byteIdx + 1 < widthBytes) row[byteIdx + 1] |= (uint8_t)(effectiveBits << (8 - shift));
}
}
@@ -284,33 +283,34 @@ static inline uint64_t extractGlyphBlock(const uint8_t* const bitmap, const int
// Each column k maps to row (phyYBase + k*phyYStride) via writeRowBits.
static inline void scatterBlockToFrameBuffer(uint8_t* const frameBuffer, const uint64_t pack, const int colCount,
const int phyYBase, const int phyYStride, const int phyBitPos,
const bool pixelState) {
const bool pixelState, const int displayHeight, const int widthBytes) {
for (int k = 0; k < colCount; k++) {
const uint8_t cols_k = static_cast<uint8_t>(pack >> (56 - 8 * k));
if (cols_k == 0) continue;
const int phyY = phyYBase + k * phyYStride;
if (phyY < 0 || phyY >= HalDisplay::DISPLAY_HEIGHT) continue;
writeRowBits(frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES, phyBitPos, cols_k, pixelState);
if (phyY < 0 || phyY >= displayHeight) continue;
writeRowBits(frameBuffer + phyY * widthBytes, phyBitPos, cols_k, pixelState, widthBytes);
}
}
static void renderGlyphFastBW(uint8_t* const frameBuffer, const uint8_t* const bitmap, const int glyphWidth,
const int glyphHeight, const int screenXBase, const int screenYBase,
const bool pixelState, const GfxRenderer::Orientation orientation) {
const bool pixelState, const GfxRenderer::Orientation orientation, const int displayWidth,
const int displayHeight, const int widthBytes) {
switch (orientation) {
case GfxRenderer::LandscapeCounterClockwise: {
for (int glyphY = 0; glyphY < glyphHeight; glyphY++) {
const int phyY = screenYBase + glyphY;
if (phyY < 0 || phyY >= HalDisplay::DISPLAY_HEIGHT) continue;
uint8_t* const row = frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES;
if (phyY < 0 || phyY >= displayHeight) continue;
uint8_t* const row = frameBuffer + phyY * widthBytes;
const int rowBitStart = glyphY * glyphWidth;
for (int glyphX = 0; glyphX < glyphWidth; glyphX += 8) {
const int count = std::min(8, glyphWidth - glyphX);
const uint8_t gbyte = bitmapExtract(bitmap, rowBitStart + glyphX, count);
if (gbyte == 0) continue;
const int phyBitPos = screenXBase + glyphX;
if (phyBitPos + count <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
writeRowBits(row, phyBitPos, gbyte, pixelState);
if (phyBitPos + count <= 0 || phyBitPos >= displayWidth) continue;
writeRowBits(row, phyBitPos, gbyte, pixelState, widthBytes);
}
}
break;
@@ -318,9 +318,9 @@ static void renderGlyphFastBW(uint8_t* const frameBuffer, const uint8_t* const b
case GfxRenderer::LandscapeClockwise: {
for (int glyphY = 0; glyphY < glyphHeight; glyphY++) {
const int phyY = HalDisplay::DISPLAY_HEIGHT - 1 - (screenYBase + glyphY);
if (phyY < 0 || phyY >= HalDisplay::DISPLAY_HEIGHT) continue;
uint8_t* const row = frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES;
const int phyY = displayHeight - 1 - (screenYBase + glyphY);
if (phyY < 0 || phyY >= displayHeight) continue;
uint8_t* const row = frameBuffer + phyY * widthBytes;
const int rowBitStart = glyphY * glyphWidth;
for (int chunkEnd = glyphWidth - 1; chunkEnd >= 0; chunkEnd -= 8) {
const int chunkStart = std::max(0, chunkEnd - 7);
@@ -328,9 +328,9 @@ static void renderGlyphFastBW(uint8_t* const frameBuffer, const uint8_t* const b
const uint8_t gbyte_fwd = bitmapExtract(bitmap, rowBitStart + chunkStart, count);
const uint8_t gbyte = reverseBits8(gbyte_fwd >> (8 - count));
if (gbyte == 0) continue;
const int phyBitPos = HalDisplay::DISPLAY_WIDTH - 1 - screenXBase - chunkEnd;
if (phyBitPos + count <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
writeRowBits(row, phyBitPos, gbyte, pixelState);
const int phyBitPos = displayWidth - 1 - screenXBase - chunkEnd;
if (phyBitPos + count <= 0 || phyBitPos >= displayWidth) continue;
writeRowBits(row, phyBitPos, gbyte, pixelState, widthBytes);
}
}
break;
@@ -340,13 +340,13 @@ static void renderGlyphFastBW(uint8_t* const frameBuffer, const uint8_t* const b
for (int glyphY = 0; glyphY < glyphHeight; glyphY += 8) {
const int rowCount = std::min(8, glyphHeight - glyphY);
const int phyBitPos = screenYBase + glyphY;
if (phyBitPos + rowCount <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
if (phyBitPos + rowCount <= 0 || phyBitPos >= displayWidth) continue;
for (int glyphX = 0; glyphX < glyphWidth; glyphX += 8) {
const int colCount = std::min(8, glyphWidth - glyphX);
const uint64_t pack =
transpose8x8(extractGlyphBlock(bitmap, glyphWidth, glyphX, glyphY, rowCount, colCount, false));
scatterBlockToFrameBuffer(frameBuffer, pack, colCount, HalDisplay::DISPLAY_HEIGHT - 1 - screenXBase - glyphX,
-1, phyBitPos, pixelState);
scatterBlockToFrameBuffer(frameBuffer, pack, colCount, displayHeight - 1 - screenXBase - glyphX, -1,
phyBitPos, pixelState, displayHeight, widthBytes);
}
}
break;
@@ -355,13 +355,14 @@ static void renderGlyphFastBW(uint8_t* const frameBuffer, const uint8_t* const b
case GfxRenderer::PortraitInverted: {
for (int glyphY = 0; glyphY < glyphHeight; glyphY += 8) {
const int rowCount = std::min(8, glyphHeight - glyphY);
const int phyBitPos = HalDisplay::DISPLAY_WIDTH - 1 - screenYBase - (glyphY + rowCount - 1);
if (phyBitPos + rowCount <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
const int phyBitPos = displayWidth - 1 - screenYBase - (glyphY + rowCount - 1);
if (phyBitPos + rowCount <= 0 || phyBitPos >= displayWidth) continue;
for (int glyphX = 0; glyphX < glyphWidth; glyphX += 8) {
const int colCount = std::min(8, glyphWidth - glyphX);
const uint64_t pack =
transpose8x8(extractGlyphBlock(bitmap, glyphWidth, glyphX, glyphY, rowCount, colCount, true));
scatterBlockToFrameBuffer(frameBuffer, pack, colCount, screenXBase + glyphX, 1, phyBitPos, pixelState);
scatterBlockToFrameBuffer(frameBuffer, pack, colCount, screenXBase + glyphX, 1, phyBitPos, pixelState,
displayHeight, widthBytes);
}
}
break;
@@ -568,19 +569,19 @@ static inline uint8_t build2BitColMask(const uint8_t* const bitmap, const int gl
template <uint8_t drawMask, bool inverted>
static void renderGlyphFast2BitPortrait(uint8_t* const frameBuffer, const uint8_t* const bitmap, const int glyphWidth,
const int glyphHeight, const int screenXBase, const int screenYBase,
const bool writeState) {
const bool writeState, const int displayWidth, const int displayHeight,
const int widthBytes) {
for (int glyphX = 0; glyphX < glyphWidth; glyphX++) {
const int phyY = inverted ? (screenXBase + glyphX) : (HalDisplay::DISPLAY_HEIGHT - 1 - (screenXBase + glyphX));
if (phyY < 0 || phyY >= HalDisplay::DISPLAY_HEIGHT) continue;
uint8_t* const row = frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES;
const int phyY = inverted ? (screenXBase + glyphX) : (displayHeight - 1 - (screenXBase + glyphX));
if (phyY < 0 || phyY >= displayHeight) continue;
uint8_t* const row = frameBuffer + phyY * widthBytes;
for (int glyphY = 0; glyphY < glyphHeight; glyphY += 8) {
const int count = std::min(8, glyphHeight - glyphY);
const uint8_t mask = build2BitColMask<drawMask>(bitmap, glyphWidth, glyphX, glyphY, count, inverted);
if (mask == 0) continue;
const int phyBitPos =
inverted ? (HalDisplay::DISPLAY_WIDTH - 1 - screenYBase - (glyphY + count - 1)) : (screenYBase + glyphY);
if (phyBitPos + count <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
writeRowBits(row, phyBitPos, mask, writeState);
const int phyBitPos = inverted ? (displayWidth - 1 - screenYBase - (glyphY + count - 1)) : (screenYBase + glyphY);
if (phyBitPos + count <= 0 || phyBitPos >= displayWidth) continue;
writeRowBits(row, phyBitPos, mask, writeState, widthBytes);
}
}
}
@@ -588,7 +589,8 @@ static void renderGlyphFast2BitPortrait(uint8_t* const frameBuffer, const uint8_
template <uint8_t drawMask>
static void renderGlyphFast2Bit(uint8_t* const frameBuffer, const uint8_t* const bitmap, const int glyphWidth,
const int glyphHeight, const int screenXBase, const int screenYBase,
const bool pixelState, const GfxRenderer::Orientation orientation) {
const bool pixelState, const GfxRenderer::Orientation orientation,
const int displayWidth, const int displayHeight, const int widthBytes) {
// Non-rotated text fast path for 2-bit glyphs. Writes compact masks directly to framebuffer rows.
// TextRotation::Rotated90CW keeps the legacy per-pixel fallback path for safety and readability.
// BW (drawMask 0x0E) honors the caller's pixelState; grayscale passes always clear the bit.
@@ -598,8 +600,8 @@ static void renderGlyphFast2Bit(uint8_t* const frameBuffer, const uint8_t* const
case GfxRenderer::LandscapeCounterClockwise: {
for (int glyphY = 0; glyphY < glyphHeight; glyphY++) {
const int phyY = screenYBase + glyphY;
if (phyY < 0 || phyY >= HalDisplay::DISPLAY_HEIGHT) continue;
uint8_t* const row = frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES;
if (phyY < 0 || phyY >= displayHeight) continue;
uint8_t* const row = frameBuffer + phyY * widthBytes;
const int rowStartPixel = glyphY * glyphWidth;
for (int glyphX = 0; glyphX < glyphWidth; glyphX += 8) {
const int count = std::min(8, glyphWidth - glyphX);
@@ -613,21 +615,21 @@ static void renderGlyphFast2Bit(uint8_t* const frameBuffer, const uint8_t* const
}
if (mask == 0) continue;
const int phyBitPos = screenXBase + glyphX;
if (phyBitPos + count <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
writeRowBits(row, phyBitPos, mask, writeState);
if (phyBitPos + count <= 0 || phyBitPos >= displayWidth) continue;
writeRowBits(row, phyBitPos, mask, writeState, widthBytes);
}
}
break;
}
case GfxRenderer::LandscapeClockwise: {
// Row-outer/chunk-inner: framebuffer rows are written at stride -DISPLAY_WIDTH_BYTES
// Row-outer/chunk-inner: framebuffer rows are written at stride widthBytes
// (phyY decreases as glyphY increases). Keeping row-outer preserves sequential access
// within each row, which is more cache-friendly than the chunk-outer alternative.
for (int glyphY = 0; glyphY < glyphHeight; glyphY++) {
const int phyY = HalDisplay::DISPLAY_HEIGHT - 1 - (screenYBase + glyphY);
if (phyY < 0 || phyY >= HalDisplay::DISPLAY_HEIGHT) continue;
uint8_t* const row = frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES;
const int phyY = displayHeight - 1 - (screenYBase + glyphY);
if (phyY < 0 || phyY >= displayHeight) continue;
uint8_t* const row = frameBuffer + phyY * widthBytes;
const int rowStartPixel = glyphY * glyphWidth;
for (int chunkEnd = glyphWidth - 1; chunkEnd >= 0; chunkEnd -= 8) {
const int chunkStart = std::max(0, chunkEnd - 7);
@@ -641,9 +643,9 @@ static void renderGlyphFast2Bit(uint8_t* const frameBuffer, const uint8_t* const
mask = build2BitRowMask<drawMask>(bitmap, rowStartPixel, chunkEnd, count, true);
}
if (mask == 0) continue;
const int phyBitPos = HalDisplay::DISPLAY_WIDTH - 1 - screenXBase - chunkEnd;
if (phyBitPos + count <= 0 || phyBitPos >= HalDisplay::DISPLAY_WIDTH) continue;
writeRowBits(row, phyBitPos, mask, writeState);
const int phyBitPos = displayWidth - 1 - screenXBase - chunkEnd;
if (phyBitPos + count <= 0 || phyBitPos >= displayWidth) continue;
writeRowBits(row, phyBitPos, mask, writeState, widthBytes);
}
}
break;
@@ -651,12 +653,12 @@ static void renderGlyphFast2Bit(uint8_t* const frameBuffer, const uint8_t* const
case GfxRenderer::Portrait:
renderGlyphFast2BitPortrait<drawMask, false>(frameBuffer, bitmap, glyphWidth, glyphHeight, screenXBase,
screenYBase, writeState);
screenYBase, writeState, displayWidth, displayHeight, widthBytes);
break;
case GfxRenderer::PortraitInverted:
renderGlyphFast2BitPortrait<drawMask, true>(frameBuffer, bitmap, glyphWidth, glyphHeight, screenXBase,
screenYBase, writeState);
screenYBase, writeState, displayWidth, displayHeight, widthBytes);
break;
}
}
@@ -708,19 +710,23 @@ static void renderCharImpl(const GfxRenderer& renderer, GfxRenderer::RenderMode
switch (drawMask) {
case 0x0E: // BW
renderGlyphFast2Bit<0x0E>(renderer.getFrameBuffer(), bitmap, width, height, innerBase, outerBase,
pixelState, renderer.getOrientation());
pixelState, renderer.getOrientation(), renderer.getDisplayWidth(),
renderer.getDisplayHeight(), renderer.getDisplayWidthBytes());
break;
case 0x06: // raw {1,2}
renderGlyphFast2Bit<0x06>(renderer.getFrameBuffer(), bitmap, width, height, innerBase, outerBase,
pixelState, renderer.getOrientation());
pixelState, renderer.getOrientation(), renderer.getDisplayWidth(),
renderer.getDisplayHeight(), renderer.getDisplayWidthBytes());
break;
case 0x04: // raw {2}
renderGlyphFast2Bit<0x04>(renderer.getFrameBuffer(), bitmap, width, height, innerBase, outerBase,
pixelState, renderer.getOrientation());
pixelState, renderer.getOrientation(), renderer.getDisplayWidth(),
renderer.getDisplayHeight(), renderer.getDisplayWidthBytes());
break;
case 0x02: // raw {1}
renderGlyphFast2Bit<0x02>(renderer.getFrameBuffer(), bitmap, width, height, innerBase, outerBase,
pixelState, renderer.getOrientation());
pixelState, renderer.getOrientation(), renderer.getDisplayWidth(),
renderer.getDisplayHeight(), renderer.getDisplayWidthBytes());
break;
}
return;
@@ -760,7 +766,8 @@ static void renderCharImpl(const GfxRenderer& renderer, GfxRenderer::RenderMode
if constexpr (rotation == TextRotation::None) {
if (renderMode == GfxRenderer::BW) {
renderGlyphFastBW(renderer.getFrameBuffer(), bitmap, width, height, innerBase, outerBase, pixelState,
renderer.getOrientation());
renderer.getOrientation(), renderer.getDisplayWidth(), renderer.getDisplayHeight(),
renderer.getDisplayWidthBytes());
return;
}
}
@@ -795,18 +802,20 @@ static void renderCharImpl(const GfxRenderer& renderer, GfxRenderer::RenderMode
void GfxRenderer::drawPixel(const int x, const int y, const bool state) const {
int phyX = 0;
int phyY = 0;
const int displayWidth = getDisplayWidth();
const int displayHeight = getDisplayHeight();
// Note: this call should be inlined for better performance
rotateCoordinates(getOrientation(), x, y, &phyX, &phyY, panelWidth, panelHeight);
rotateCoordinates(getOrientation(), x, y, &phyX, &phyY, displayWidth, displayHeight);
// Bounds checking against runtime panel dimensions
if (phyX < 0 || phyX >= panelWidth || phyY < 0 || phyY >= panelHeight) {
if (phyX < 0 || phyX >= displayWidth || phyY < 0 || phyY >= displayHeight) {
LOG_ERR("GFX", "!! Outside range (%d, %d) -> (%d, %d)", x, y, phyX, phyY);
return;
}
// Calculate byte position and bit position
const uint32_t byteIndex = static_cast<uint32_t>(phyY) * panelWidthBytes + (phyX / 8);
const uint32_t byteIndex = static_cast<uint32_t>(phyY) * getDisplayWidthBytes() + (phyX / 8);
const uint8_t bitPosition = 7 - (phyX % 8); // MSB first
if (state) {
@@ -910,6 +919,9 @@ void GfxRenderer::drawText(const int fontId, const int x, const int y, const cha
void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, const bool state) const {
if (fontCacheManager_ && fontCacheManager_->isScanning()) return;
const int displayWidth = getDisplayWidth();
const int displayHeight = getDisplayHeight();
if (x1 == x2) {
if (y2 < y1) {
std::swap(y1, y2);
@@ -917,10 +929,10 @@ void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, const bool state) con
// In Portrait/PortraitInverted a logical vertical line maps to a physical horizontal span.
switch (getOrientation()) {
case Portrait:
fillPhysicalHSpan(HalDisplay::DISPLAY_HEIGHT - 1 - x1, y1, y2, state);
fillPhysicalHSpan(displayHeight - 1 - x1, y1, y2, state);
return;
case PortraitInverted:
fillPhysicalHSpan(x1, HalDisplay::DISPLAY_WIDTH - 1 - y2, HalDisplay::DISPLAY_WIDTH - 1 - y1, state);
fillPhysicalHSpan(x1, displayWidth - 1 - y2, displayWidth - 1 - y1, state);
return;
default:
for (int y = y1; y <= y2; y++) drawPixel(x1, y, state);
@@ -936,8 +948,7 @@ void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, const bool state) con
fillPhysicalHSpan(y1, x1, x2, state);
return;
case LandscapeClockwise:
fillPhysicalHSpan(HalDisplay::DISPLAY_HEIGHT - 1 - y1, HalDisplay::DISPLAY_WIDTH - 1 - x2,
HalDisplay::DISPLAY_WIDTH - 1 - x1, state);
fillPhysicalHSpan(displayHeight - 1 - y1, displayWidth - 1 - x2, displayWidth - 1 - x1, state);
return;
default:
for (int x = x1; x <= x2; x++) drawPixel(x, y1, state);
@@ -1099,10 +1110,10 @@ void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, con
void GfxRenderer::fillPhysicalHSpanByte(const int phyY, const int phyX_start, const int phyX_end,
const uint8_t patternByte) const {
const int cX0 = std::max(phyX_start, 0);
const int cX1 = std::min(phyX_end, (int)HalDisplay::DISPLAY_WIDTH - 1);
if (cX0 > cX1 || phyY < 0 || phyY >= (int)HalDisplay::DISPLAY_HEIGHT) return;
const int cX1 = std::min(phyX_end, (int)getDisplayWidth() - 1);
if (cX0 > cX1 || phyY < 0 || phyY >= (int)getDisplayHeight()) return;
uint8_t* const row = frameBuffer + phyY * HalDisplay::DISPLAY_WIDTH_BYTES;
uint8_t* const row = frameBuffer + phyY * getDisplayWidthBytes();
const int startByte = cX0 >> 3;
const int endByte = cX1 >> 3;
const int leftBits = cX0 & 7; // first bit index within startByte
@@ -1143,20 +1154,22 @@ void GfxRenderer::fillPhysicalHSpan(const int phyY, const int phyX_start, const
void GfxRenderer::fillRect(const int x, const int y, const int width, const int height, const bool state) const {
if (width <= 0 || height <= 0) return;
const int displayWidth = getDisplayWidth();
const int displayHeight = getDisplayHeight();
// For each orientation, one logical dimension maps to a constant physical row, allowing the
// perpendicular dimension to be written as a byte-level span — eliminating per-pixel overhead.
switch (getOrientation()) {
case Portrait:
// Logical column x → physical row (479-x); logical y range → physical x span
// Logical column x → physical row (displayHeight-1-x); logical y range → physical x span
for (int lx = x; lx < x + width; lx++) {
fillPhysicalHSpan(HalDisplay::DISPLAY_HEIGHT - 1 - lx, y, y + height - 1, state);
fillPhysicalHSpan(displayHeight - 1 - lx, y, y + height - 1, state);
}
return;
case PortraitInverted:
// Logical column x → physical row x; logical y range → physical x span (mirrored)
for (int lx = x; lx < x + width; lx++) {
fillPhysicalHSpan(lx, HalDisplay::DISPLAY_WIDTH - 1 - (y + height - 1), HalDisplay::DISPLAY_WIDTH - 1 - y,
state);
fillPhysicalHSpan(lx, displayWidth - 1 - (y + height - 1), displayWidth - 1 - y, state);
}
return;
case LandscapeCounterClockwise:
@@ -1166,10 +1179,9 @@ void GfxRenderer::fillRect(const int x, const int y, const int width, const int
}
return;
case LandscapeClockwise:
// Logical row y → physical row (479-y); logical x range → physical x span (mirrored)
// Logical row y → physical row (displayHeight-1-y); logical x range → physical x span (mirrored)
for (int ly = y; ly < y + height; ly++) {
fillPhysicalHSpan(HalDisplay::DISPLAY_HEIGHT - 1 - ly, HalDisplay::DISPLAY_WIDTH - 1 - (x + width - 1),
HalDisplay::DISPLAY_WIDTH - 1 - x, state);
fillPhysicalHSpan(displayHeight - 1 - ly, displayWidth - 1 - (x + width - 1), displayWidth - 1 - x, state);
}
return;
}
@@ -1216,7 +1228,7 @@ void GfxRenderer::fillRectDither(const int x, const int y, const int width, cons
switch (getOrientation()) {
case Portrait:
for (int lx = x; lx < x + width; lx++) {
const int phyY = HalDisplay::DISPLAY_HEIGHT - 1 - lx;
const int phyY = getDisplayHeight() - 1 - lx;
const uint8_t pb = (phyY % 2 == 0) ? 0xAA : 0x55;
fillPhysicalHSpanByte(phyY, y, y + height - 1, pb);
}
@@ -1225,8 +1237,7 @@ void GfxRenderer::fillRectDither(const int x, const int y, const int width, cons
for (int lx = x; lx < x + width; lx++) {
const int phyY = lx;
const uint8_t pb = (phyY % 2 == 0) ? 0xAA : 0x55;
fillPhysicalHSpanByte(phyY, HalDisplay::DISPLAY_WIDTH - 1 - (y + height - 1),
HalDisplay::DISPLAY_WIDTH - 1 - y, pb);
fillPhysicalHSpanByte(phyY, getDisplayWidth() - 1 - (y + height - 1), getDisplayWidth() - 1 - y, pb);
}
return;
case LandscapeCounterClockwise:
@@ -1238,10 +1249,9 @@ void GfxRenderer::fillRectDither(const int x, const int y, const int width, cons
return;
case LandscapeClockwise:
for (int ly = y; ly < y + height; ly++) {
const int phyY = HalDisplay::DISPLAY_HEIGHT - 1 - ly;
const int phyY = getDisplayHeight() - 1 - ly;
const uint8_t pb = (phyY % 2 == 0) ? 0x55 : 0xAA;
fillPhysicalHSpanByte(phyY, HalDisplay::DISPLAY_WIDTH - 1 - (x + width - 1),
HalDisplay::DISPLAY_WIDTH - 1 - x, pb);
fillPhysicalHSpanByte(phyY, getDisplayWidth() - 1 - (x + width - 1), getDisplayWidth() - 1 - x, pb);
}
return;
}
@@ -1255,7 +1265,7 @@ void GfxRenderer::fillRectDither(const int x, const int y, const int width, cons
switch (getOrientation()) {
case Portrait:
for (int lx = x; lx < x + width; lx++) {
const int phyY = HalDisplay::DISPLAY_HEIGHT - 1 - lx;
const int phyY = getDisplayHeight() - 1 - lx;
if (phyY % 2 == 0) continue; // all-white row — no dark pixels to write
fillPhysicalHSpanByte(phyY, y, y + height - 1, 0x55);
}
@@ -1264,8 +1274,7 @@ void GfxRenderer::fillRectDither(const int x, const int y, const int width, cons
for (int lx = x; lx < x + width; lx++) {
const int phyY = lx;
if (phyY % 2 != 0) continue; // all-white row
fillPhysicalHSpanByte(phyY, HalDisplay::DISPLAY_WIDTH - 1 - (y + height - 1),
HalDisplay::DISPLAY_WIDTH - 1 - y, 0xAA);
fillPhysicalHSpanByte(phyY, getDisplayWidth() - 1 - (y + height - 1), getDisplayWidth() - 1 - y, 0xAA);
}
return;
case LandscapeCounterClockwise:
@@ -1277,10 +1286,9 @@ void GfxRenderer::fillRectDither(const int x, const int y, const int width, cons
return;
case LandscapeClockwise:
for (int ly = y; ly < y + height; ly++) {
const int phyY = HalDisplay::DISPLAY_HEIGHT - 1 - ly;
const int phyY = getDisplayHeight() - 1 - ly;
if (phyY % 2 == 0) continue; // all-white row
fillPhysicalHSpanByte(phyY, HalDisplay::DISPLAY_WIDTH - 1 - (x + width - 1),
HalDisplay::DISPLAY_WIDTH - 1 - x, 0xAA);
fillPhysicalHSpanByte(phyY, getDisplayWidth() - 1 - (x + width - 1), getDisplayWidth() - 1 - x, 0xAA);
}
return;
}
@@ -1403,7 +1411,7 @@ void GfxRenderer::drawImage(const uint8_t bitmap[], const int x, const int y, co
const auto currentOrientation = getOrientation();
int rotatedX = 0;
int rotatedY = 0;
rotateCoordinates(currentOrientation, x, y, &rotatedX, &rotatedY, panelWidth, panelHeight);
rotateCoordinates(currentOrientation, x, y, &rotatedX, &rotatedY, getDisplayWidth(), getDisplayHeight());
// Rotate origin corner
switch (currentOrientation) {
case Portrait:
+4 -4
View File
@@ -50,10 +50,10 @@ class GfxRenderer {
// rendering. See drawMaskFor2BitMode() in GfxRenderer.cpp for the per-level
// pixel breakdown and a worked example glyph.
uint8_t* frameBuffer = nullptr;
uint16_t panelWidth = HalDisplay::DISPLAY_WIDTH;
uint16_t panelHeight = HalDisplay::DISPLAY_HEIGHT;
uint16_t panelWidthBytes = HalDisplay::DISPLAY_WIDTH_BYTES;
uint32_t frameBufferSize = HalDisplay::BUFFER_SIZE;
uint16_t panelWidth = 0; // set in begin()
uint16_t panelHeight = 0; // set in begin()
uint16_t panelWidthBytes = 0; // set in begin()
uint32_t frameBufferSize = 0; // set in begin()
std::vector<uint8_t*> bwBufferChunks;
std::map<int, EpdFontFamily> fontMap;