diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 6dcc8e86..1b5efff8 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -1,14 +1,12 @@ #include "GfxRenderer.h" #include + #include -void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { - fontMap.insert({fontId, font}); -} +void GfxRenderer::insertFont(const int fontId, EpdFontFamily font) { fontMap.insert({fontId, font}); } -void GfxRenderer::rotateCoordinates(const int x, const int y, int *rotatedX, - int *rotatedY) const { +void GfxRenderer::rotateCoordinates(const int x, const int y, int* rotatedX, int* rotatedY) const { switch (orientation) { case Portrait: { // Logical portrait (480x800) → panel (800x480) @@ -63,14 +61,14 @@ void GfxRenderer::drawPixel(const int x, const int y, const bool state) const { const uint8_t bitPosition = 7 - (rotatedX % 8); // MSB first if (state) { - frameBuffer[byteIndex] &= ~(1 << bitPosition); // Clear bit + frameBuffer[byteIndex] &= ~(1 << bitPosition); // Clear bit } else { - frameBuffer[byteIndex] |= 1 << bitPosition; // Set bit + frameBuffer[byteIndex] |= 1 << bitPosition; // Set bit } } bool GfxRenderer::readPixel(const int x, const int y) const { - uint8_t *frameBuffer = display.getFrameBuffer(); + uint8_t* frameBuffer = display.getFrameBuffer(); if (!frameBuffer) { return false; } @@ -80,21 +78,18 @@ bool GfxRenderer::readPixel(const int x, const int y) const { rotateCoordinates(x, y, &rotatedX, &rotatedY); // Bounds checking against physical panel dimensions - if (rotatedX < 0 || rotatedX >= HalDisplay::DISPLAY_WIDTH || - rotatedY < 0 || rotatedY >= HalDisplay::DISPLAY_HEIGHT) { + if (rotatedX < 0 || rotatedX >= HalDisplay::DISPLAY_WIDTH || rotatedY < 0 || rotatedY >= HalDisplay::DISPLAY_HEIGHT) { return false; } - const uint16_t byteIndex = - rotatedY * HalDisplay::DISPLAY_WIDTH_BYTES + (rotatedX / 8); + const uint16_t byteIndex = rotatedY * HalDisplay::DISPLAY_WIDTH_BYTES + (rotatedX / 8); const uint8_t bitPosition = 7 - (rotatedX % 8); // Bit cleared = black, bit set = white return !(frameBuffer[byteIndex] & (1 << bitPosition)); } -int GfxRenderer::getTextWidth(const int fontId, const char *text, - const EpdFontFamily::Style style) const { +int GfxRenderer::getTextWidth(const int fontId, const char* text, const EpdFontFamily::Style style) const { if (fontMap.count(fontId) == 0) { Serial.printf("[%lu] [GFX] Font %d not found\n", millis(), fontId); return 0; @@ -105,15 +100,13 @@ int GfxRenderer::getTextWidth(const int fontId, const char *text, return w; } -void GfxRenderer::drawCenteredText(const int fontId, const int y, - const char *text, const bool black, +void GfxRenderer::drawCenteredText(const int fontId, const int y, const char* text, const bool black, const EpdFontFamily::Style style) const { const int x = (getScreenWidth() - getTextWidth(fontId, text, style)) / 2; drawText(fontId, x, y, text, black, style); } -void GfxRenderer::drawText(const int fontId, const int x, const int y, - const char *text, const bool black, +void GfxRenderer::drawText(const int fontId, const int x, const int y, const char* text, const bool black, const EpdFontFamily::Style style) const { const int yPos = y + getFontAscenderSize(fontId); int xpos = x; @@ -135,13 +128,12 @@ void GfxRenderer::drawText(const int fontId, const int x, const int y, } uint32_t cp; - while ((cp = utf8NextCodepoint(reinterpret_cast(&text)))) { + while ((cp = utf8NextCodepoint(reinterpret_cast(&text)))) { renderChar(font, cp, &xpos, &yPos, black, style); } } -void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, - const bool state) const { +void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, const bool state) const { // Bresenham's line algorithm int dx = abs(x2 - x1); int dy = abs(y2 - y1); @@ -151,9 +143,9 @@ void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, while (true) { drawPixel(x1, y1, state); - + if (x1 == x2 && y1 == y2) break; - + int e2 = 2 * err; if (e2 > -dy) { err -= dy; @@ -166,17 +158,15 @@ void GfxRenderer::drawLine(int x1, int y1, int x2, int y2, } } -void GfxRenderer::drawRect(const int x, const int y, const int width, - const int height, const bool state) const { +void GfxRenderer::drawRect(const int x, const int y, const int width, const int height, const bool state) const { drawLine(x, y, x + width - 1, y, state); drawLine(x + width - 1, y, x + width - 1, y + height - 1, state); drawLine(x + width - 1, y + height - 1, x, y + height - 1, state); drawLine(x, y, x, y + height - 1, state); } -void GfxRenderer::fillRect(const int x, const int y, const int width, - const int height, const bool state) const { - uint8_t *frameBuffer = display.getFrameBuffer(); +void GfxRenderer::fillRect(const int x, const int y, const int width, const int height, const bool state) const { + uint8_t* frameBuffer = display.getFrameBuffer(); if (!frameBuffer) { return; } @@ -190,8 +180,7 @@ void GfxRenderer::fillRect(const int x, const int y, const int width, const int x2 = std::min(screenWidth - 1, x + width - 1); const int y2 = std::min(screenHeight - 1, y + height - 1); - if (x1 > x2 || y1 > y2) - return; + if (x1 > x2 || y1 > y2) return; // Optimized path for Portrait mode (most common) if (orientation == Portrait) { @@ -204,13 +193,12 @@ void GfxRenderer::fillRect(const int x, const int y, const int width, for (int sx = x1; sx <= x2; sx++) { const int physY = HalDisplay::DISPLAY_HEIGHT - 1 - sx; - const uint16_t byteIndex = - physY * HalDisplay::DISPLAY_WIDTH_BYTES + physXByte; + const uint16_t byteIndex = physY * HalDisplay::DISPLAY_WIDTH_BYTES + physXByte; if (state) { - frameBuffer[byteIndex] &= ~mask; // Black + frameBuffer[byteIndex] &= ~mask; // Black } else { - frameBuffer[byteIndex] |= mask; // White + frameBuffer[byteIndex] |= mask; // White } } } @@ -227,8 +215,7 @@ void GfxRenderer::fillRect(const int x, const int y, const int width, for (int sx = x1; sx <= x2; sx++) { const int physY = sx; - const uint16_t byteIndex = - physY * HalDisplay::DISPLAY_WIDTH_BYTES + physXByte; + const uint16_t byteIndex = physY * HalDisplay::DISPLAY_WIDTH_BYTES + physXByte; if (state) { frameBuffer[byteIndex] &= ~mask; @@ -282,8 +269,8 @@ void GfxRenderer::fillRect(const int x, const int y, const int width, } } -void GfxRenderer::fillRectDithered(const int x, const int y, const int width, - const int height, const uint8_t grayLevel) const { +void GfxRenderer::fillRectDithered(const int x, const int y, const int width, const int height, + const uint8_t grayLevel) const { // Simulate grayscale using dithering patterns // 0x00 = black, 0xFF = white, values in between = dithered @@ -292,7 +279,7 @@ void GfxRenderer::fillRectDithered(const int x, const int y, const int width, return; } if (grayLevel >= 0xF0) { - fillRect(x, y, width, height, false); // Solid white + fillRect(x, y, width, height, false); // Solid white return; } @@ -314,10 +301,14 @@ void GfxRenderer::fillRectDithered(const int x, const int y, const int width, int bayerValue; int px = sx % 2; int py = sy % 2; - if (px == 0 && py == 0) bayerValue = 0; - else if (px == 1 && py == 0) bayerValue = 2; - else if (px == 0 && py == 1) bayerValue = 3; - else bayerValue = 1; + if (px == 0 && py == 0) + bayerValue = 0; + else if (px == 1 && py == 0) + bayerValue = 2; + else if (px == 0 && py == 1) + bayerValue = 3; + else + bayerValue = 1; bool isBlack = bayerValue >= threshold; drawPixel(sx, sy, isBlack); @@ -325,8 +316,8 @@ void GfxRenderer::fillRectDithered(const int x, const int y, const int width, } } -void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, - const int height, const int radius, const bool state) const { +void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, const int height, const int radius, + const bool state) const { if (radius <= 0) { drawRect(x, y, width, height, state); return; @@ -338,19 +329,23 @@ void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, int d = 1 - r; while (px <= py) { - cx = x + r; cy = y + r; + cx = x + r; + cy = y + r; drawPixel(cx - py, cy - px, state); drawPixel(cx - px, cy - py, state); - cx = x + width - 1 - r; cy = y + r; + cx = x + width - 1 - r; + cy = y + r; drawPixel(cx + py, cy - px, state); drawPixel(cx + px, cy - py, state); - cx = x + r; cy = y + height - 1 - r; + cx = x + r; + cy = y + height - 1 - r; drawPixel(cx - py, cy + px, state); drawPixel(cx - px, cy + py, state); - cx = x + width - 1 - r; cy = y + height - 1 - r; + cx = x + width - 1 - r; + cy = y + height - 1 - r; drawPixel(cx + py, cy + px, state); drawPixel(cx + px, cy + py, state); @@ -369,8 +364,8 @@ void GfxRenderer::drawRoundedRect(const int x, const int y, const int width, drawLine(x + width - 1, y + r, x + width - 1, y + height - 1 - r, state); } -void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, - const int height, const int radius, const bool state) const { +void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, const int height, const int radius, + const bool state) const { if (radius <= 0) { fillRect(x, y, width, height, state); return; @@ -405,8 +400,7 @@ void GfxRenderer::fillRoundedRect(const int x, const int y, const int width, } } -void GfxRenderer::fillRoundedRectDithered(const int x, const int y, const int width, - const int height, const int radius, +void GfxRenderer::fillRoundedRectDithered(const int x, const int y, const int width, const int height, const int radius, const uint8_t grayLevel) const { if (grayLevel == 0x00) { fillRoundedRect(x, y, width, height, radius, true); @@ -463,10 +457,14 @@ void GfxRenderer::fillRoundedRectDithered(const int x, const int y, const int wi int bayerValue; int bx = sx % 2; int by = sy % 2; - if (bx == 0 && by == 0) bayerValue = 0; - else if (bx == 1 && by == 0) bayerValue = 2; - else if (bx == 0 && by == 1) bayerValue = 3; - else bayerValue = 1; + if (bx == 0 && by == 0) + bayerValue = 0; + else if (bx == 1 && by == 0) + bayerValue = 2; + else if (bx == 0 && by == 1) + bayerValue = 3; + else + bayerValue = 1; bool isBlack = bayerValue >= threshold; drawPixel(sx, sy, isBlack); @@ -497,8 +495,7 @@ void GfxRenderer::drawImage(const uint8_t bitmap[], const int x, const int y, co display.drawImage(bitmap, rotatedX, rotatedY, width, height); } -void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y, - const int maxWidth, const int maxHeight, +void GfxRenderer::drawBitmap(const Bitmap& bitmap, const int x, const int y, const int maxWidth, const int maxHeight, const float cropX, const float cropY) const { // For 1-bit bitmaps, use optimized 1-bit rendering path (no crop support for // 1-bit) @@ -513,14 +510,11 @@ void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y, int cropPixY = std::floor(bitmap.getHeight() * cropY / 2.0f); if (maxWidth > 0 && (1.0f - cropX) * bitmap.getWidth() > maxWidth) { - scale = static_cast(maxWidth) / - static_cast((1.0f - cropX) * bitmap.getWidth()); + scale = static_cast(maxWidth) / static_cast((1.0f - cropX) * bitmap.getWidth()); isScaled = true; } if (maxHeight > 0 && (1.0f - cropY) * bitmap.getHeight() > maxHeight) { - scale = std::min( - scale, static_cast(maxHeight) / - static_cast((1.0f - cropY) * bitmap.getHeight())); + scale = std::min(scale, static_cast(maxHeight) / static_cast((1.0f - cropY) * bitmap.getHeight())); isScaled = true; } @@ -528,12 +522,11 @@ void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y, // IMPORTANT: Use int, not uint8_t, to avoid overflow for images > 1020 pixels // wide const int outputRowSize = (bitmap.getWidth() + 3) / 4; - auto *outputRow = static_cast(malloc(outputRowSize)); - auto *rowBytes = static_cast(malloc(bitmap.getRowBytes())); + auto* outputRow = static_cast(malloc(outputRowSize)); + auto* rowBytes = static_cast(malloc(bitmap.getRowBytes())); if (!outputRow || !rowBytes) { - Serial.printf("[%lu] [GFX] !! Failed to allocate BMP row buffers\n", - millis()); + Serial.printf("[%lu] [GFX] !! Failed to allocate BMP row buffers\n", millis()); free(outputRow); free(rowBytes); return; @@ -542,19 +535,17 @@ void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y, for (int bmpY = 0; bmpY < (bitmap.getHeight() - cropPixY); bmpY++) { // The BMP's (0, 0) is the bottom-left corner (if the height is positive, // top-left if negative). Screen's (0, 0) is the top-left corner. - int screenY = - -cropPixY + (bitmap.isTopDown() ? bmpY : bitmap.getHeight() - 1 - bmpY); + int screenY = -cropPixY + (bitmap.isTopDown() ? bmpY : bitmap.getHeight() - 1 - bmpY); if (isScaled) { screenY = std::floor(screenY * scale); } - screenY += y; // the offset should not be scaled + screenY += y; // the offset should not be scaled if (screenY >= getScreenHeight()) { break; } if (bitmap.readNextRow(outputRow, rowBytes) != BmpReaderError::Ok) { - Serial.printf("[%lu] [GFX] Failed to read row %d from bitmap\n", millis(), - bmpY); + Serial.printf("[%lu] [GFX] Failed to read row %d from bitmap\n", millis(), bmpY); free(outputRow); free(rowBytes); return; @@ -574,7 +565,7 @@ void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y, if (isScaled) { screenX = std::floor(screenX * scale); } - screenX += x; // the offset should not be scaled + screenX += x; // the offset should not be scaled if (screenX >= getScreenWidth()) { break; } @@ -604,9 +595,8 @@ void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y, free(rowBytes); } -void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, - int h) const { - uint8_t *frameBuffer = display.getFrameBuffer(); +void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, int h) const { + uint8_t* frameBuffer = display.getFrameBuffer(); if (!frameBuffer) { return; } @@ -622,17 +612,15 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, if (orientation == Portrait && renderMode == BW) { for (int row = 0; row < h; row++) { const int screenY = y + row; - if (screenY < 0 || screenY >= screenHeight) - continue; + if (screenY < 0 || screenY >= screenHeight) continue; // In Portrait, screenY maps to physical X coordinate const int physX = screenY; - const uint8_t *srcRow = data + row * srcRowBytes; + const uint8_t* srcRow = data + row * srcRowBytes; for (int col = 0; col < w; col++) { const int screenX = x + col; - if (screenX < 0 || screenX >= screenWidth) - continue; + if (screenX < 0 || screenX >= screenWidth) continue; // Extract 2-bit value (4 pixels per byte) const uint8_t val = (srcRow[col / 4] >> (6 - ((col % 4) * 2))) & 0x3; @@ -642,10 +630,9 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, if (val < 2) { // In Portrait: physical Y = DISPLAY_HEIGHT - 1 - screenX const int physY = HalDisplay::DISPLAY_HEIGHT - 1 - screenX; - const uint16_t byteIndex = - physY * HalDisplay::DISPLAY_WIDTH_BYTES + (physX / 8); + const uint16_t byteIndex = physY * HalDisplay::DISPLAY_WIDTH_BYTES + (physX / 8); const uint8_t bitPosition = 7 - (physX % 8); - frameBuffer[byteIndex] &= ~(1 << bitPosition); // Clear bit = black + frameBuffer[byteIndex] &= ~(1 << bitPosition); // Clear bit = black } } } @@ -656,15 +643,13 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, if (orientation == PortraitInverted && renderMode == BW) { for (int row = 0; row < h; row++) { const int screenY = y + row; - if (screenY < 0 || screenY >= screenHeight) - continue; + if (screenY < 0 || screenY >= screenHeight) continue; - const uint8_t *srcRow = data + row * srcRowBytes; + const uint8_t* srcRow = data + row * srcRowBytes; for (int col = 0; col < w; col++) { const int screenX = x + col; - if (screenX < 0 || screenX >= screenWidth) - continue; + if (screenX < 0 || screenX >= screenWidth) continue; const uint8_t val = (srcRow[col / 4] >> (6 - ((col % 4) * 2))) & 0x3; @@ -673,8 +658,7 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, // physical Y = screenX const int physX = HalDisplay::DISPLAY_WIDTH - 1 - screenY; const int physY = screenX; - const uint16_t byteIndex = - physY * HalDisplay::DISPLAY_WIDTH_BYTES + (physX / 8); + const uint16_t byteIndex = physY * HalDisplay::DISPLAY_WIDTH_BYTES + (physX / 8); const uint8_t bitPosition = 7 - (physX % 8); frameBuffer[byteIndex] &= ~(1 << bitPosition); } @@ -684,20 +668,16 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, } // Optimized path for Landscape modes with BW rendering - if ((orientation == LandscapeClockwise || - orientation == LandscapeCounterClockwise) && - renderMode == BW) { + if ((orientation == LandscapeClockwise || orientation == LandscapeCounterClockwise) && renderMode == BW) { for (int row = 0; row < h; row++) { const int screenY = y + row; - if (screenY < 0 || screenY >= screenHeight) - continue; + if (screenY < 0 || screenY >= screenHeight) continue; - const uint8_t *srcRow = data + row * srcRowBytes; + const uint8_t* srcRow = data + row * srcRowBytes; for (int col = 0; col < w; col++) { const int screenX = x + col; - if (screenX < 0 || screenX >= screenWidth) - continue; + if (screenX < 0 || screenX >= screenWidth) continue; const uint8_t val = (srcRow[col / 4] >> (6 - ((col % 4) * 2))) & 0x3; @@ -710,8 +690,7 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, physX = screenX; physY = screenY; } - const uint16_t byteIndex = - physY * HalDisplay::DISPLAY_WIDTH_BYTES + (physX / 8); + const uint16_t byteIndex = physY * HalDisplay::DISPLAY_WIDTH_BYTES + (physX / 8); const uint8_t bitPosition = 7 - (physX % 8); frameBuffer[byteIndex] &= ~(1 << bitPosition); } @@ -723,15 +702,13 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, // Fallback: generic path for grayscale modes for (int row = 0; row < h; row++) { const int screenY = y + row; - if (screenY < 0 || screenY >= screenHeight) - continue; + if (screenY < 0 || screenY >= screenHeight) continue; - const uint8_t *srcRow = data + row * srcRowBytes; + const uint8_t* srcRow = data + row * srcRowBytes; for (int col = 0; col < w; col++) { const int screenX = x + col; - if (screenX < 0 || screenX >= screenWidth) - continue; + if (screenX < 0 || screenX >= screenWidth) continue; const uint8_t val = (srcRow[col / 4] >> (6 - ((col % 4) * 2))) & 0x3; @@ -744,31 +721,27 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w, } } -void GfxRenderer::drawBitmap1Bit(const Bitmap &bitmap, const int x, const int y, - const int maxWidth, +void GfxRenderer::drawBitmap1Bit(const Bitmap& bitmap, const int x, const int y, const int maxWidth, const int maxHeight) const { float scale = 1.0f; bool isScaled = false; if (maxWidth > 0 && bitmap.getWidth() > maxWidth) { - scale = - static_cast(maxWidth) / static_cast(bitmap.getWidth()); + scale = static_cast(maxWidth) / static_cast(bitmap.getWidth()); isScaled = true; } if (maxHeight > 0 && bitmap.getHeight() > maxHeight) { - scale = std::min(scale, static_cast(maxHeight) / - static_cast(bitmap.getHeight())); + scale = std::min(scale, static_cast(maxHeight) / static_cast(bitmap.getHeight())); isScaled = true; } // For 1-bit BMP, output is still 2-bit packed (for consistency with // readNextRow) const int outputRowSize = (bitmap.getWidth() + 3) / 4; - auto *outputRow = static_cast(malloc(outputRowSize)); - auto *rowBytes = static_cast(malloc(bitmap.getRowBytes())); + auto* outputRow = static_cast(malloc(outputRowSize)); + auto* rowBytes = static_cast(malloc(bitmap.getRowBytes())); if (!outputRow || !rowBytes) { - Serial.printf("[%lu] [GFX] !! Failed to allocate 1-bit BMP row buffers\n", - millis()); + Serial.printf("[%lu] [GFX] !! Failed to allocate 1-bit BMP row buffers\n", millis()); free(outputRow); free(rowBytes); return; @@ -777,29 +750,24 @@ void GfxRenderer::drawBitmap1Bit(const Bitmap &bitmap, const int x, const int y, for (int bmpY = 0; bmpY < bitmap.getHeight(); bmpY++) { // Read rows sequentially using readNextRow if (bitmap.readNextRow(outputRow, rowBytes) != BmpReaderError::Ok) { - Serial.printf("[%lu] [GFX] Failed to read row %d from 1-bit bitmap\n", - millis(), bmpY); + Serial.printf("[%lu] [GFX] Failed to read row %d from 1-bit bitmap\n", millis(), bmpY); free(outputRow); free(rowBytes); return; } // Calculate screen Y based on whether BMP is top-down or bottom-up - const int bmpYOffset = - bitmap.isTopDown() ? bmpY : bitmap.getHeight() - 1 - bmpY; - int screenY = - y + (isScaled ? static_cast(std::floor(bmpYOffset * scale)) - : bmpYOffset); + const int bmpYOffset = bitmap.isTopDown() ? bmpY : bitmap.getHeight() - 1 - bmpY; + int screenY = y + (isScaled ? static_cast(std::floor(bmpYOffset * scale)) : bmpYOffset); if (screenY >= getScreenHeight()) { - continue; // Continue reading to keep row counter in sync + continue; // Continue reading to keep row counter in sync } if (screenY < 0) { continue; } for (int bmpX = 0; bmpX < bitmap.getWidth(); bmpX++) { - int screenX = - x + (isScaled ? static_cast(std::floor(bmpX * scale)) : bmpX); + int screenX = x + (isScaled ? static_cast(std::floor(bmpX * scale)) : bmpX); if (screenX >= getScreenWidth()) { break; } @@ -1008,31 +976,24 @@ void GfxRenderer::drawRoundedBitmap(const Bitmap& bitmap, const int x, const int free(rowBytes); } -void GfxRenderer::fillPolygon(const int *xPoints, const int *yPoints, - int numPoints, bool state) const { - if (numPoints < 3) - return; +void GfxRenderer::fillPolygon(const int* xPoints, const int* yPoints, int numPoints, bool state) const { + if (numPoints < 3) return; // Find bounding box int minY = yPoints[0], maxY = yPoints[0]; for (int i = 1; i < numPoints; i++) { - if (yPoints[i] < minY) - minY = yPoints[i]; - if (yPoints[i] > maxY) - maxY = yPoints[i]; + if (yPoints[i] < minY) minY = yPoints[i]; + if (yPoints[i] > maxY) maxY = yPoints[i]; } // Clip to screen - if (minY < 0) - minY = 0; - if (maxY >= getScreenHeight()) - maxY = getScreenHeight() - 1; + if (minY < 0) minY = 0; + if (maxY >= getScreenHeight()) maxY = getScreenHeight() - 1; // Allocate node buffer for scanline algorithm - auto *nodeX = static_cast(malloc(numPoints * sizeof(int))); + auto* nodeX = static_cast(malloc(numPoints * sizeof(int))); if (!nodeX) { - Serial.printf("[%lu] [GFX] !! Failed to allocate polygon node buffer\n", - millis()); + Serial.printf("[%lu] [GFX] !! Failed to allocate polygon node buffer\n", millis()); return; } @@ -1043,13 +1004,11 @@ void GfxRenderer::fillPolygon(const int *xPoints, const int *yPoints, // Find all intersection points with edges int j = numPoints - 1; for (int i = 0; i < numPoints; i++) { - if ((yPoints[i] < scanY && yPoints[j] >= scanY) || - (yPoints[j] < scanY && yPoints[i] >= scanY)) { + if ((yPoints[i] < scanY && yPoints[j] >= scanY) || (yPoints[j] < scanY && yPoints[i] >= scanY)) { // Calculate X intersection using fixed-point to avoid float int dy = yPoints[j] - yPoints[i]; if (dy != 0) { - nodeX[nodes++] = xPoints[i] + (scanY - yPoints[i]) * - (xPoints[j] - xPoints[i]) / dy; + nodeX[nodes++] = xPoints[i] + (scanY - yPoints[i]) * (xPoints[j] - xPoints[i]) / dy; } } j = i; @@ -1072,10 +1031,8 @@ void GfxRenderer::fillPolygon(const int *xPoints, const int *yPoints, int endX = nodeX[i + 1]; // Clip to screen - if (startX < 0) - startX = 0; - if (endX >= getScreenWidth()) - endX = getScreenWidth() - 1; + if (startX < 0) startX = 0; + if (endX >= getScreenWidth()) endX = getScreenWidth() - 1; // Draw horizontal line for (int x = startX; x <= endX; x++) { @@ -1097,8 +1054,14 @@ uint8_t* GfxRenderer::captureRegion(int x, int y, int width, int height, size_t* // Clip to screen bounds const int screenWidth = getScreenWidth(); const int screenHeight = getScreenHeight(); - if (x < 0) { width += x; x = 0; } - if (y < 0) { height += y; y = 0; } + if (x < 0) { + width += x; + x = 0; + } + if (y < 0) { + height += y; + y = 0; + } if (x + width > screenWidth) width = screenWidth - x; if (y + height > screenHeight) height = screenHeight - y; @@ -1220,8 +1183,7 @@ void GfxRenderer::invertScreen() const { void GfxRenderer::displayBuffer(const HalDisplay::RefreshMode refreshMode) const { display.displayBuffer(refreshMode); } -std::string GfxRenderer::truncatedText(const int fontId, const char *text, - const int maxWidth, +std::string GfxRenderer::truncatedText(const int fontId, const char* text, const int maxWidth, const EpdFontFamily::Style style) const { std::string item = text; int itemWidth = getTextWidth(fontId, item.c_str(), style); @@ -1289,19 +1251,18 @@ int GfxRenderer::getLineHeight(const int fontId) const { return fontMap.at(fontId).getData(EpdFontFamily::REGULAR)->advanceY; } -void GfxRenderer::drawButtonHints(const int fontId, const char *btn1, - const char *btn2, const char *btn3, - const char *btn4) { +void GfxRenderer::drawButtonHints(const int fontId, const char* btn1, const char* btn2, const char* btn3, + const char* btn4) { const Orientation orig_orientation = getOrientation(); setOrientation(Orientation::Portrait); const int pageHeight = getScreenHeight(); constexpr int buttonWidth = 106; constexpr int buttonHeight = 40; - constexpr int buttonY = 40; // Distance from bottom - constexpr int textYOffset = 7; // Distance from top of button to text baseline + constexpr int buttonY = 40; // Distance from bottom + constexpr int textYOffset = 7; // Distance from top of button to text baseline constexpr int buttonPositions[] = {25, 130, 245, 350}; - const char *labels[] = {btn1, btn2, btn3, btn4}; + const char* labels[] = {btn1, btn2, btn3, btn4}; for (int i = 0; i < 4; i++) { // Only draw if the label is non-empty @@ -1318,44 +1279,41 @@ void GfxRenderer::drawButtonHints(const int fontId, const char *btn1, setOrientation(orig_orientation); } -void GfxRenderer::drawSideButtonHints(const int fontId, const char *topBtn, - const char *bottomBtn) const { +void GfxRenderer::drawSideButtonHints(const int fontId, const char* topBtn, const char* bottomBtn) const { const int screenWidth = getScreenWidth(); - constexpr int buttonWidth = 40; // Width on screen (height when rotated) - constexpr int buttonHeight = 80; // Height on screen (width when rotated) - constexpr int buttonX = 5; // Distance from right edge + constexpr int buttonWidth = 40; // Width on screen (height when rotated) + constexpr int buttonHeight = 80; // Height on screen (width when rotated) + constexpr int buttonX = 5; // Distance from right edge // Position for the button group - buttons share a border so they're adjacent - constexpr int topButtonY = 345; // Top button position + constexpr int topButtonY = 345; // Top button position - const char *labels[] = {topBtn, bottomBtn}; + const char* labels[] = {topBtn, bottomBtn}; // Draw the shared border for both buttons as one unit const int x = screenWidth - buttonX - buttonWidth; // Draw top button outline (3 sides, bottom open) if (topBtn != nullptr && topBtn[0] != '\0') { - drawLine(x, topButtonY, x + buttonWidth - 1, topButtonY); // Top - drawLine(x, topButtonY, x, topButtonY + buttonHeight - 1); // Left + drawLine(x, topButtonY, x + buttonWidth - 1, topButtonY); // Top + drawLine(x, topButtonY, x, topButtonY + buttonHeight - 1); // Left drawLine(x + buttonWidth - 1, topButtonY, x + buttonWidth - 1, - topButtonY + buttonHeight - 1); // Right + topButtonY + buttonHeight - 1); // Right } // Draw shared middle border - if ((topBtn != nullptr && topBtn[0] != '\0') || - (bottomBtn != nullptr && bottomBtn[0] != '\0')) { + if ((topBtn != nullptr && topBtn[0] != '\0') || (bottomBtn != nullptr && bottomBtn[0] != '\0')) { drawLine(x, topButtonY + buttonHeight, x + buttonWidth - 1, - topButtonY + buttonHeight); // Shared border + topButtonY + buttonHeight); // Shared border } // Draw bottom button outline (3 sides, top is shared) if (bottomBtn != nullptr && bottomBtn[0] != '\0') { drawLine(x, topButtonY + buttonHeight, x, - topButtonY + 2 * buttonHeight - 1); // Left - drawLine(x + buttonWidth - 1, topButtonY + buttonHeight, - x + buttonWidth - 1, - topButtonY + 2 * buttonHeight - 1); // Right + topButtonY + 2 * buttonHeight - 1); // Left + drawLine(x + buttonWidth - 1, topButtonY + buttonHeight, x + buttonWidth - 1, + topButtonY + 2 * buttonHeight - 1); // Right drawLine(x, topButtonY + 2 * buttonHeight - 1, x + buttonWidth - 1, - topButtonY + 2 * buttonHeight - 1); // Bottom + topButtonY + 2 * buttonHeight - 1); // Bottom } // Draw text for each button @@ -1384,9 +1342,7 @@ int GfxRenderer::getTextHeight(const int fontId) const { return fontMap.at(fontId).getData(EpdFontFamily::REGULAR)->ascender; } -void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, - const int y, const char *text, - const bool black, +void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, const int y, const char* text, const bool black, const EpdFontFamily::Style style) const { // Cannot draw a NULL / empty string if (text == nullptr || *text == '\0') { @@ -1408,11 +1364,11 @@ void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, // Original (glyphX, glyphY) -> Rotated (glyphY, -glyphX) // Text reads from bottom to top - int yPos = y; // Current Y position (decreases as we draw characters) + int yPos = y; // Current Y position (decreases as we draw characters) uint32_t cp; - while ((cp = utf8NextCodepoint(reinterpret_cast(&text)))) { - const EpdGlyph *glyph = font.getGlyph(cp, style); + while ((cp = utf8NextCodepoint(reinterpret_cast(&text)))) { + const EpdGlyph* glyph = font.getGlyph(cp, style); if (!glyph) { glyph = font.getGlyph(REPLACEMENT_GLYPH, style); } @@ -1427,7 +1383,7 @@ void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, const int left = glyph->left; const int top = glyph->top; - const uint8_t *bitmap = &font.getData(style)->bitmap[offset]; + const uint8_t* bitmap = &font.getData(style)->bitmap[offset]; if (bitmap != nullptr) { for (int glyphY = 0; glyphY < height; glyphY++) { @@ -1437,8 +1393,7 @@ void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, // 90° clockwise rotation transformation: // screenX = x + (ascender - top + glyphY) // screenY = yPos - (left + glyphX) - const int screenX = - x + (font.getData(style)->ascender - top + glyphY); + const int screenX = x + (font.getData(style)->ascender - top + glyphY); const int screenY = yPos - left - glyphX; if (is2Bit) { @@ -1448,8 +1403,7 @@ void GfxRenderer::drawTextRotated90CW(const int fontId, const int x, if (renderMode == BW && bmpVal < 3) { drawPixel(screenX, screenY, black); - } else if (renderMode == GRAYSCALE_MSB && - (bmpVal == 1 || bmpVal == 2)) { + } else if (renderMode == GRAYSCALE_MSB && (bmpVal == 1 || bmpVal == 2)) { drawPixel(screenX, screenY, false); } else if (renderMode == GRAYSCALE_LSB && bmpVal == 1) { drawPixel(screenX, screenY, false); @@ -1485,7 +1439,7 @@ void GfxRenderer::copyGrayscaleMsbBuffers() const { display.copyGrayscaleMsbBuff void GfxRenderer::displayGrayBuffer() const { display.displayGrayBuffer(); } void GfxRenderer::freeBwBufferChunks() { - for (auto &bwBufferChunk : bwBufferChunks) { + for (auto& bwBufferChunk : bwBufferChunks) { if (bwBufferChunk) { free(bwBufferChunk); bwBufferChunk = nullptr; @@ -1511,20 +1465,20 @@ bool GfxRenderer::storeBwBuffer() { for (size_t i = 0; i < BW_BUFFER_NUM_CHUNKS; i++) { // Check if any chunks are already allocated if (bwBufferChunks[i]) { - Serial.printf("[%lu] [GFX] !! BW buffer chunk %zu already stored - this " - "is likely a bug, freeing chunk\n", - millis(), i); + Serial.printf( + "[%lu] [GFX] !! BW buffer chunk %zu already stored - this " + "is likely a bug, freeing chunk\n", + millis(), i); free(bwBufferChunks[i]); bwBufferChunks[i] = nullptr; } const size_t offset = i * BW_BUFFER_CHUNK_SIZE; - bwBufferChunks[i] = static_cast(malloc(BW_BUFFER_CHUNK_SIZE)); + bwBufferChunks[i] = static_cast(malloc(BW_BUFFER_CHUNK_SIZE)); if (!bwBufferChunks[i]) { - Serial.printf( - "[%lu] [GFX] !! Failed to allocate BW buffer chunk %zu (%zu bytes)\n", - millis(), i, BW_BUFFER_CHUNK_SIZE); + Serial.printf("[%lu] [GFX] !! Failed to allocate BW buffer chunk %zu (%zu bytes)\n", millis(), i, + BW_BUFFER_CHUNK_SIZE); // Free previously allocated chunks freeBwBufferChunks(); return false; @@ -1533,8 +1487,8 @@ bool GfxRenderer::storeBwBuffer() { memcpy(bwBufferChunks[i], frameBuffer + offset, BW_BUFFER_CHUNK_SIZE); } - Serial.printf("[%lu] [GFX] Stored BW buffer in %zu chunks (%zu bytes each)\n", - millis(), BW_BUFFER_NUM_CHUNKS, BW_BUFFER_CHUNK_SIZE); + Serial.printf("[%lu] [GFX] Stored BW buffer in %zu chunks (%zu bytes each)\n", millis(), BW_BUFFER_NUM_CHUNKS, + BW_BUFFER_CHUNK_SIZE); return true; } @@ -1546,7 +1500,7 @@ bool GfxRenderer::storeBwBuffer() { void GfxRenderer::restoreBwBuffer() { // Check if any all chunks are allocated bool missingChunks = false; - for (const auto &bwBufferChunk : bwBufferChunks) { + for (const auto& bwBufferChunk : bwBufferChunks) { if (!bwBufferChunk) { missingChunks = true; break; @@ -1560,8 +1514,7 @@ void GfxRenderer::restoreBwBuffer() { uint8_t* frameBuffer = display.getFrameBuffer(); if (!frameBuffer) { - Serial.printf("[%lu] [GFX] !! No framebuffer in restoreBwBuffer\n", - millis()); + Serial.printf("[%lu] [GFX] !! No framebuffer in restoreBwBuffer\n", millis()); freeBwBufferChunks(); return; } @@ -1569,9 +1522,7 @@ void GfxRenderer::restoreBwBuffer() { for (size_t i = 0; i < BW_BUFFER_NUM_CHUNKS; i++) { // Check if chunk is missing if (!bwBufferChunks[i]) { - Serial.printf( - "[%lu] [GFX] !! BW buffer chunks not stored - this is likely a bug\n", - millis()); + Serial.printf("[%lu] [GFX] !! BW buffer chunks not stored - this is likely a bug\n", millis()); freeBwBufferChunks(); return; } @@ -1597,10 +1548,9 @@ void GfxRenderer::cleanupGrayscaleWithFrameBuffer() const { } } -void GfxRenderer::renderChar(const EpdFontFamily &fontFamily, const uint32_t cp, - int *x, const int *y, const bool pixelState, - const EpdFontFamily::Style style) const { - const EpdGlyph *glyph = fontFamily.getGlyph(cp, style); +void GfxRenderer::renderChar(const EpdFontFamily& fontFamily, const uint32_t cp, int* x, const int* y, + const bool pixelState, const EpdFontFamily::Style style) const { + const EpdGlyph* glyph = fontFamily.getGlyph(cp, style); if (!glyph) { glyph = fontFamily.getGlyph(REPLACEMENT_GLYPH, style); } @@ -1617,7 +1567,7 @@ void GfxRenderer::renderChar(const EpdFontFamily &fontFamily, const uint32_t cp, const uint8_t height = glyph->height; const int left = glyph->left; - const uint8_t *bitmap = nullptr; + const uint8_t* bitmap = nullptr; bitmap = &fontFamily.getData(style)->bitmap[offset]; if (bitmap != nullptr) { @@ -1639,8 +1589,7 @@ void GfxRenderer::renderChar(const EpdFontFamily &fontFamily, const uint32_t cp, if (renderMode == BW && bmpVal < 3) { // Black (also paints over the grays in BW mode) drawPixel(screenX, screenY, pixelState); - } else if (renderMode == GRAYSCALE_MSB && - (bmpVal == 1 || bmpVal == 2)) { + } else if (renderMode == GRAYSCALE_MSB && (bmpVal == 1 || bmpVal == 2)) { // Light gray (also mark the MSB if it's going to be a dark gray // too) We have to flag pixels in reverse for the gray buffers, as 0 // leave alone, 1 update @@ -1664,32 +1613,31 @@ void GfxRenderer::renderChar(const EpdFontFamily &fontFamily, const uint32_t cp, *x += glyph->advanceX; } -void GfxRenderer::getOrientedViewableTRBL(int *outTop, int *outRight, - int *outBottom, int *outLeft) const { +void GfxRenderer::getOrientedViewableTRBL(int* outTop, int* outRight, int* outBottom, int* outLeft) const { switch (orientation) { - case Portrait: - *outTop = VIEWABLE_MARGIN_TOP; - *outRight = VIEWABLE_MARGIN_RIGHT; - *outBottom = VIEWABLE_MARGIN_BOTTOM; - *outLeft = VIEWABLE_MARGIN_LEFT; - break; - case LandscapeClockwise: - *outTop = VIEWABLE_MARGIN_LEFT; - *outRight = VIEWABLE_MARGIN_TOP; - *outBottom = VIEWABLE_MARGIN_RIGHT; - *outLeft = VIEWABLE_MARGIN_BOTTOM; - break; - case PortraitInverted: - *outTop = VIEWABLE_MARGIN_BOTTOM; - *outRight = VIEWABLE_MARGIN_LEFT; - *outBottom = VIEWABLE_MARGIN_TOP; - *outLeft = VIEWABLE_MARGIN_RIGHT; - break; - case LandscapeCounterClockwise: - *outTop = VIEWABLE_MARGIN_RIGHT; - *outRight = VIEWABLE_MARGIN_BOTTOM; - *outBottom = VIEWABLE_MARGIN_LEFT; - *outLeft = VIEWABLE_MARGIN_TOP; - break; + case Portrait: + *outTop = VIEWABLE_MARGIN_TOP; + *outRight = VIEWABLE_MARGIN_RIGHT; + *outBottom = VIEWABLE_MARGIN_BOTTOM; + *outLeft = VIEWABLE_MARGIN_LEFT; + break; + case LandscapeClockwise: + *outTop = VIEWABLE_MARGIN_LEFT; + *outRight = VIEWABLE_MARGIN_TOP; + *outBottom = VIEWABLE_MARGIN_RIGHT; + *outLeft = VIEWABLE_MARGIN_BOTTOM; + break; + case PortraitInverted: + *outTop = VIEWABLE_MARGIN_BOTTOM; + *outRight = VIEWABLE_MARGIN_LEFT; + *outBottom = VIEWABLE_MARGIN_TOP; + *outLeft = VIEWABLE_MARGIN_RIGHT; + break; + case LandscapeCounterClockwise: + *outTop = VIEWABLE_MARGIN_RIGHT; + *outRight = VIEWABLE_MARGIN_BOTTOM; + *outBottom = VIEWABLE_MARGIN_LEFT; + *outLeft = VIEWABLE_MARGIN_TOP; + break; } } diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index 77572377..7998bea6 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -8,17 +8,17 @@ #include "Bitmap.h" class GfxRenderer { -public: + public: enum RenderMode { BW, GRAYSCALE_LSB, GRAYSCALE_MSB }; // Logical screen orientation from the perspective of callers enum Orientation { - Portrait, // 480x800 logical coordinates (current default) - LandscapeClockwise, // 800x480 logical coordinates, rotated 180° (swap - // top/bottom) - PortraitInverted, // 480x800 logical coordinates, inverted - LandscapeCounterClockwise // 800x480 logical coordinates, native panel - // orientation + Portrait, // 480x800 logical coordinates (current default) + LandscapeClockwise, // 800x480 logical coordinates, rotated 180° (swap + // top/bottom) + PortraitInverted, // 480x800 logical coordinates, inverted + LandscapeCounterClockwise // 800x480 logical coordinates, native panel + // orientation }; private: @@ -30,13 +30,12 @@ public: HalDisplay& display; RenderMode renderMode; Orientation orientation; - uint8_t *bwBufferChunks[BW_BUFFER_NUM_CHUNKS] = {nullptr}; + uint8_t* bwBufferChunks[BW_BUFFER_NUM_CHUNKS] = {nullptr}; std::map fontMap; - void renderChar(const EpdFontFamily &fontFamily, uint32_t cp, int *x, - const int *y, bool pixelState, + void renderChar(const EpdFontFamily& fontFamily, uint32_t cp, int* x, const int* y, bool pixelState, EpdFontFamily::Style style) const; void freeBwBufferChunks(); - void rotateCoordinates(int x, int y, int *rotatedX, int *rotatedY) const; + void rotateCoordinates(int x, int y, int* rotatedX, int* rotatedY) const; public: explicit GfxRenderer(HalDisplay& halDisplay) : display(halDisplay), renderMode(BW), orientation(Portrait) {} @@ -66,7 +65,7 @@ public: // Drawing void drawPixel(int x, int y, bool state = true) const; - bool readPixel(int x, int y) const; // Returns true if pixel is black + bool readPixel(int x, int y) const; // Returns true if pixel is black void drawLine(int x1, int y1, int x2, int y2, bool state = true) const; void drawRect(int x, int y, int width, int height, bool state = true) const; void fillRect(int x, int y, int width, int height, bool state = true) const; @@ -74,69 +73,57 @@ public: void drawRoundedRect(int x, int y, int width, int height, int radius, bool state = true) const; void fillRoundedRect(int x, int y, int width, int height, int radius, bool state = true) const; void fillRoundedRectDithered(int x, int y, int width, int height, int radius, uint8_t grayLevel) const; - void drawImage(const uint8_t bitmap[], int x, int y, int width, - int height) const; - void drawBitmap(const Bitmap &bitmap, int x, int y, int maxWidth, - int maxHeight, float cropX = 0, float cropY = 0) const; - void drawBitmap1Bit(const Bitmap &bitmap, int x, int y, int maxWidth, - int maxHeight) const; + void drawImage(const uint8_t bitmap[], int x, int y, int width, int height) const; + void drawBitmap(const Bitmap& bitmap, int x, int y, int maxWidth, int maxHeight, float cropX = 0, + float cropY = 0) const; + void drawBitmap1Bit(const Bitmap& bitmap, int x, int y, int maxWidth, int maxHeight) const; void drawTransparentBitmap(const Bitmap& bitmap, int x, int y, int w, int h) const; void drawRoundedBitmap(const Bitmap& bitmap, int x, int y, int w, int h, int radius) const; void draw2BitImage(const uint8_t data[], int x, int y, int w, int h) const; - void fillPolygon(const int *xPoints, const int *yPoints, int numPoints, - bool state = true) const; + void fillPolygon(const int* xPoints, const int* yPoints, int numPoints, bool state = true) const; // Region caching - copies a rectangular region to/from a buffer // Returns allocated buffer on success, nullptr on failure. Caller owns the // memory. - uint8_t *captureRegion(int x, int y, int width, int height, - size_t *outSize) const; + uint8_t* captureRegion(int x, int y, int width, int height, size_t* outSize) const; // Restores a previously captured region. Buffer must match dimensions. - void restoreRegion(const uint8_t *buffer, int x, int y, int width, - int height) const; + void restoreRegion(const uint8_t* buffer, int x, int y, int width, int height) const; // Text - int getTextWidth(int fontId, const char *text, - EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; - void - drawCenteredText(int fontId, int y, const char *text, bool black = true, - EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; - void drawText(int fontId, int x, int y, const char *text, bool black = true, + int getTextWidth(int fontId, const char* text, EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; + void drawCenteredText(int fontId, int y, const char* text, bool black = true, + EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; + void drawText(int fontId, int x, int y, const char* text, bool black = true, EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; int getSpaceWidth(int fontId) const; int getFontAscenderSize(int fontId) const; int getLineHeight(int fontId) const; - std::string - truncatedText(int fontId, const char *text, int maxWidth, - EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; + std::string truncatedText(int fontId, const char* text, int maxWidth, + EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; // UI Components - void drawButtonHints(int fontId, const char *btn1, const char *btn2, - const char *btn3, const char *btn4); - void drawSideButtonHints(int fontId, const char *topBtn, - const char *bottomBtn) const; + void drawButtonHints(int fontId, const char* btn1, const char* btn2, const char* btn3, const char* btn4); + void drawSideButtonHints(int fontId, const char* topBtn, const char* bottomBtn) const; -private: + private: // Helper for drawing rotated text (90 degrees clockwise, for side buttons) - void drawTextRotated90CW( - int fontId, int x, int y, const char *text, bool black = true, - EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; + void drawTextRotated90CW(int fontId, int x, int y, const char* text, bool black = true, + EpdFontFamily::Style style = EpdFontFamily::REGULAR) const; int getTextHeight(int fontId) const; -public: + public: // Grayscale functions void setRenderMode(const RenderMode mode) { this->renderMode = mode; } void copyGrayscaleLsbBuffers() const; void copyGrayscaleMsbBuffers() const; void displayGrayBuffer() const; - bool storeBwBuffer(); // Returns true if buffer was stored successfully - void restoreBwBuffer(); // Restore and free the stored buffer + bool storeBwBuffer(); // Returns true if buffer was stored successfully + void restoreBwBuffer(); // Restore and free the stored buffer void cleanupGrayscaleWithFrameBuffer() const; // Low level functions - uint8_t *getFrameBuffer() const; + uint8_t* getFrameBuffer() const; static size_t getBufferSize(); void grayscaleRevert() const; - void getOrientedViewableTRBL(int *outTop, int *outRight, int *outBottom, - int *outLeft) const; + void getOrientedViewableTRBL(int* outTop, int* outRight, int* outBottom, int* outLeft) const; }; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index c4361bb9..18b933ce 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -13,8 +13,7 @@ #include "ThemeSelectionActivity.h" #include "fontIds.h" -const char *SettingsActivity::categoryNames[categoryCount] = { - "Display", "Reader", "Controls", "System"}; +const char* SettingsActivity::categoryNames[categoryCount] = {"Display", "Reader", "Controls", "System"}; namespace { constexpr int displaySettingsCount = 7; @@ -32,25 +31,17 @@ const SettingInfo displaySettings[displaySettingsCount] = { constexpr int readerSettingsCount = 9; const SettingInfo readerSettings[readerSettingsCount] = { - SettingInfo::Enum("Font Family", &CrossPointSettings::fontFamily, - {"Bookerly", "Noto Sans", "Open Dyslexic"}), - SettingInfo::Enum("Font Size", &CrossPointSettings::fontSize, - {"Small", "Medium", "Large", "X Large"}), - SettingInfo::Enum("Line Spacing", &CrossPointSettings::lineSpacing, - {"Tight", "Normal", "Wide"}), - SettingInfo::Value("Screen Margin", &CrossPointSettings::screenMargin, - {5, 40, 5}), - SettingInfo::Enum("Paragraph Alignment", - &CrossPointSettings::paragraphAlignment, + SettingInfo::Enum("Font Family", &CrossPointSettings::fontFamily, {"Bookerly", "Noto Sans", "Open Dyslexic"}), + SettingInfo::Enum("Font Size", &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}), + SettingInfo::Enum("Line Spacing", &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}), + SettingInfo::Value("Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}), + SettingInfo::Enum("Paragraph Alignment", &CrossPointSettings::paragraphAlignment, {"Justify", "Left", "Center", "Right"}), SettingInfo::Toggle("Hyphenation", &CrossPointSettings::hyphenationEnabled), - SettingInfo::Enum( - "Reading Orientation", &CrossPointSettings::orientation, - {"Portrait", "Landscape CW", "Inverted", "Landscape CCW"}), - SettingInfo::Toggle("Extra Paragraph Spacing", - &CrossPointSettings::extraParagraphSpacing), - SettingInfo::Toggle("Text Anti-Aliasing", - &CrossPointSettings::textAntiAliasing)}; + SettingInfo::Enum("Reading Orientation", &CrossPointSettings::orientation, + {"Portrait", "Landscape CW", "Inverted", "Landscape CCW"}), + SettingInfo::Toggle("Extra Paragraph Spacing", &CrossPointSettings::extraParagraphSpacing), + SettingInfo::Toggle("Text Anti-Aliasing", &CrossPointSettings::textAntiAliasing)}; constexpr int controlsSettingsCount = 4; const SettingInfo controlsSettings[controlsSettingsCount] = { @@ -59,11 +50,8 @@ const SettingInfo controlsSettings[controlsSettingsCount] = { {"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght", "Bck, Cnfrm, Rght, Lft"}), SettingInfo::Enum("Side Button Layout (reader)", &CrossPointSettings::sideButtonLayout, {"Prev, Next", "Next, Prev"}), - SettingInfo::Toggle("Long-press Chapter Skip", - &CrossPointSettings::longPressChapterSkip), - SettingInfo::Enum("Short Power Button Click", - &CrossPointSettings::shortPwrBtn, - {"Ignore", "Sleep", "Page Turn"})}; + SettingInfo::Toggle("Long-press Chapter Skip", &CrossPointSettings::longPressChapterSkip), + SettingInfo::Enum("Short Power Button Click", &CrossPointSettings::shortPwrBtn, {"Ignore", "Sleep", "Page Turn"})}; constexpr int systemSettingsCount = 5; const SettingInfo systemSettings[systemSettingsCount] = { @@ -79,11 +67,10 @@ struct CategoryData { int count; }; -const CategoryData allCategories[4] = { - {"Display", displaySettings, displaySettingsCount}, - {"Reader", readerSettings, readerSettingsCount}, - {"Controls", controlsSettings, controlsSettingsCount}, - {"System", systemSettings, systemSettingsCount}}; +const CategoryData allCategories[4] = {{"Display", displaySettings, displaySettingsCount}, + {"Reader", readerSettings, readerSettingsCount}, + {"Controls", controlsSettings, controlsSettingsCount}, + {"System", systemSettings, systemSettingsCount}}; void updateContextForSetting(ThemeEngine::ThemeContext& ctx, const std::string& prefix, int i, const SettingInfo& info, bool isSelected, bool fullUpdate) { @@ -123,8 +110,8 @@ void updateContextForSetting(ThemeEngine::ThemeContext& ctx, const std::string& } } // namespace -void SettingsActivity::taskTrampoline(void *param) { - auto *self = static_cast(param); +void SettingsActivity::taskTrampoline(void* param) { + auto* self = static_cast(param); self->displayTaskLoop(); } @@ -136,16 +123,16 @@ void SettingsActivity::onEnter() { // For themed mode, provide all data upfront if (ThemeEngine::ThemeManager::get().getElement("Settings")) { - updateThemeContext(true); // Full update + updateThemeContext(true); // Full update } updateRequired = true; xTaskCreate(&SettingsActivity::taskTrampoline, "SettingsActivityTask", - 4096, // Stack size - this, // Parameters - 1, // Priority - &displayTaskHandle // Task handle + 4096, // Stack size + this, // Parameters + 1, // Priority + &displayTaskHandle // Task handle ); } @@ -194,16 +181,12 @@ void SettingsActivity::loop() { if (mappedInput.wasPressed(MappedInputManager::Button::Up) || mappedInput.wasPressed(MappedInputManager::Button::Left)) { // Move selection up (with wrap-around) - selectedCategoryIndex = (selectedCategoryIndex > 0) - ? (selectedCategoryIndex - 1) - : (categoryCount - 1); + selectedCategoryIndex = (selectedCategoryIndex > 0) ? (selectedCategoryIndex - 1) : (categoryCount - 1); updateRequired = true; } else if (mappedInput.wasPressed(MappedInputManager::Button::Down) || mappedInput.wasPressed(MappedInputManager::Button::Right)) { // Move selection down (with wrap around) - selectedCategoryIndex = (selectedCategoryIndex < categoryCount - 1) - ? (selectedCategoryIndex + 1) - : 0; + selectedCategoryIndex = (selectedCategoryIndex < categoryCount - 1) ? (selectedCategoryIndex + 1) : 0; updateRequired = true; } } @@ -213,13 +196,12 @@ void SettingsActivity::enterCategoryLegacy(int categoryIndex) { xSemaphoreTake(renderingMutex, portMAX_DELAY); exitActivity(); - enterNewActivity(new CategorySettingsActivity( - renderer, mappedInput, allCategories[categoryIndex].name, - allCategories[categoryIndex].settings, allCategories[categoryIndex].count, - [this] { - exitActivity(); - updateRequired = true; - })); + enterNewActivity(new CategorySettingsActivity(renderer, mappedInput, allCategories[categoryIndex].name, + allCategories[categoryIndex].settings, + allCategories[categoryIndex].count, [this] { + exitActivity(); + updateRequired = true; + })); xSemaphoreGive(renderingMutex); } @@ -251,29 +233,24 @@ void SettingsActivity::render() const { const auto pageHeight = renderer.getScreenHeight(); // Draw header - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Settings", true, - EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Settings", true, EpdFontFamily::BOLD); // Draw selection renderer.fillRect(0, 60 + selectedCategoryIndex * 30 - 2, pageWidth - 1, 30); for (int i = 0; i < categoryCount; i++) { - const int categoryY = 60 + i * 30; // 30 pixels between categories + const int categoryY = 60 + i * 30; // 30 pixels between categories // Draw category name - renderer.drawText(UI_10_FONT_ID, 20, categoryY, categoryNames[i], - i != selectedCategoryIndex); + renderer.drawText(UI_10_FONT_ID, 20, categoryY, categoryNames[i], i != selectedCategoryIndex); } // Draw version text above button hints - renderer.drawText( - SMALL_FONT_ID, - pageWidth - 20 - renderer.getTextWidth(SMALL_FONT_ID, CROSSPOINT_VERSION), - pageHeight - 60, CROSSPOINT_VERSION); + renderer.drawText(SMALL_FONT_ID, pageWidth - 20 - renderer.getTextWidth(SMALL_FONT_ID, CROSSPOINT_VERSION), + pageHeight - 60, CROSSPOINT_VERSION); const auto labels = mappedInput.mapLabels("« Back", "Select", "", ""); - renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, - labels.btn4); + renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4); renderer.displayBuffer(); } @@ -285,7 +262,7 @@ void SettingsActivity::updateThemeContext(bool fullUpdate) { if (fullUpdate) { themeContext.setInt("Categories.Count", categoryCount); } - + themeContext.setInt("Categories.Selected", selectedCategoryIndex); for (int i = 0; i < categoryCount; i++) { @@ -308,9 +285,9 @@ void SettingsActivity::updateThemeContext(bool fullUpdate) { // Also provide current category's settings as "Settings" for simpler themes if (fullUpdate) { - themeContext.setInt("Settings.Count", allCategories[selectedCategoryIndex].count); + themeContext.setInt("Settings.Count", allCategories[selectedCategoryIndex].count); } - + for (int i = 0; i < allCategories[selectedCategoryIndex].count; i++) { updateContextForSetting(themeContext, "Settings", i, allCategories[selectedCategoryIndex].settings[i], i == selectedSettingIndex, fullUpdate); @@ -323,14 +300,14 @@ void SettingsActivity::handleThemeInput() { // Up/Down navigates settings within current category if (mappedInput.wasPressed(MappedInputManager::Button::Up)) { selectedSettingIndex = (selectedSettingIndex > 0) ? (selectedSettingIndex - 1) : (currentCategorySettingsCount - 1); - updateThemeContext(false); // Partial update + updateThemeContext(false); // Partial update updateRequired = true; return; } if (mappedInput.wasPressed(MappedInputManager::Button::Down)) { selectedSettingIndex = (selectedSettingIndex < currentCategorySettingsCount - 1) ? (selectedSettingIndex + 1) : 0; - updateThemeContext(false); // Partial update + updateThemeContext(false); // Partial update updateRequired = true; return; } @@ -340,7 +317,7 @@ void SettingsActivity::handleThemeInput() { mappedInput.wasPressed(MappedInputManager::Button::PageBack)) { selectedCategoryIndex = (selectedCategoryIndex > 0) ? (selectedCategoryIndex - 1) : (categoryCount - 1); selectedSettingIndex = 0; // Reset to first setting in new category - updateThemeContext(true); // Full update (category changed) + updateThemeContext(true); // Full update (category changed) updateRequired = true; return; } @@ -349,7 +326,7 @@ void SettingsActivity::handleThemeInput() { mappedInput.wasPressed(MappedInputManager::Button::PageForward)) { selectedCategoryIndex = (selectedCategoryIndex < categoryCount - 1) ? (selectedCategoryIndex + 1) : 0; selectedSettingIndex = 0; - updateThemeContext(true); // Full update + updateThemeContext(true); // Full update updateRequired = true; return; } @@ -357,7 +334,7 @@ void SettingsActivity::handleThemeInput() { // Confirm toggles/activates current setting if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) { toggleCurrentSetting(); - updateThemeContext(false); // Values changed, partial update is enough (names don't change) + updateThemeContext(false); // Values changed, partial update is enough (names don't change) updateRequired = true; return; } diff --git a/src/main.cpp b/src/main.cpp index 82573e2f..825aef2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,94 +38,78 @@ EpdFont bookerly14RegularFont(&bookerly_14_regular); EpdFont bookerly14BoldFont(&bookerly_14_bold); EpdFont bookerly14ItalicFont(&bookerly_14_italic); EpdFont bookerly14BoldItalicFont(&bookerly_14_bolditalic); -EpdFontFamily bookerly14FontFamily(&bookerly14RegularFont, &bookerly14BoldFont, - &bookerly14ItalicFont, +EpdFontFamily bookerly14FontFamily(&bookerly14RegularFont, &bookerly14BoldFont, &bookerly14ItalicFont, &bookerly14BoldItalicFont); #ifndef OMIT_FONTS EpdFont bookerly12RegularFont(&bookerly_12_regular); EpdFont bookerly12BoldFont(&bookerly_12_bold); EpdFont bookerly12ItalicFont(&bookerly_12_italic); EpdFont bookerly12BoldItalicFont(&bookerly_12_bolditalic); -EpdFontFamily bookerly12FontFamily(&bookerly12RegularFont, &bookerly12BoldFont, - &bookerly12ItalicFont, +EpdFontFamily bookerly12FontFamily(&bookerly12RegularFont, &bookerly12BoldFont, &bookerly12ItalicFont, &bookerly12BoldItalicFont); EpdFont bookerly16RegularFont(&bookerly_16_regular); EpdFont bookerly16BoldFont(&bookerly_16_bold); EpdFont bookerly16ItalicFont(&bookerly_16_italic); EpdFont bookerly16BoldItalicFont(&bookerly_16_bolditalic); -EpdFontFamily bookerly16FontFamily(&bookerly16RegularFont, &bookerly16BoldFont, - &bookerly16ItalicFont, +EpdFontFamily bookerly16FontFamily(&bookerly16RegularFont, &bookerly16BoldFont, &bookerly16ItalicFont, &bookerly16BoldItalicFont); EpdFont bookerly18RegularFont(&bookerly_18_regular); EpdFont bookerly18BoldFont(&bookerly_18_bold); EpdFont bookerly18ItalicFont(&bookerly_18_italic); EpdFont bookerly18BoldItalicFont(&bookerly_18_bolditalic); -EpdFontFamily bookerly18FontFamily(&bookerly18RegularFont, &bookerly18BoldFont, - &bookerly18ItalicFont, +EpdFontFamily bookerly18FontFamily(&bookerly18RegularFont, &bookerly18BoldFont, &bookerly18ItalicFont, &bookerly18BoldItalicFont); EpdFont notosans12RegularFont(¬osans_12_regular); EpdFont notosans12BoldFont(¬osans_12_bold); EpdFont notosans12ItalicFont(¬osans_12_italic); EpdFont notosans12BoldItalicFont(¬osans_12_bolditalic); -EpdFontFamily notosans12FontFamily(¬osans12RegularFont, ¬osans12BoldFont, - ¬osans12ItalicFont, +EpdFontFamily notosans12FontFamily(¬osans12RegularFont, ¬osans12BoldFont, ¬osans12ItalicFont, ¬osans12BoldItalicFont); EpdFont notosans14RegularFont(¬osans_14_regular); EpdFont notosans14BoldFont(¬osans_14_bold); EpdFont notosans14ItalicFont(¬osans_14_italic); EpdFont notosans14BoldItalicFont(¬osans_14_bolditalic); -EpdFontFamily notosans14FontFamily(¬osans14RegularFont, ¬osans14BoldFont, - ¬osans14ItalicFont, +EpdFontFamily notosans14FontFamily(¬osans14RegularFont, ¬osans14BoldFont, ¬osans14ItalicFont, ¬osans14BoldItalicFont); EpdFont notosans16RegularFont(¬osans_16_regular); EpdFont notosans16BoldFont(¬osans_16_bold); EpdFont notosans16ItalicFont(¬osans_16_italic); EpdFont notosans16BoldItalicFont(¬osans_16_bolditalic); -EpdFontFamily notosans16FontFamily(¬osans16RegularFont, ¬osans16BoldFont, - ¬osans16ItalicFont, +EpdFontFamily notosans16FontFamily(¬osans16RegularFont, ¬osans16BoldFont, ¬osans16ItalicFont, ¬osans16BoldItalicFont); EpdFont notosans18RegularFont(¬osans_18_regular); EpdFont notosans18BoldFont(¬osans_18_bold); EpdFont notosans18ItalicFont(¬osans_18_italic); EpdFont notosans18BoldItalicFont(¬osans_18_bolditalic); -EpdFontFamily notosans18FontFamily(¬osans18RegularFont, ¬osans18BoldFont, - ¬osans18ItalicFont, +EpdFontFamily notosans18FontFamily(¬osans18RegularFont, ¬osans18BoldFont, ¬osans18ItalicFont, ¬osans18BoldItalicFont); EpdFont opendyslexic8RegularFont(&opendyslexic_8_regular); EpdFont opendyslexic8BoldFont(&opendyslexic_8_bold); EpdFont opendyslexic8ItalicFont(&opendyslexic_8_italic); EpdFont opendyslexic8BoldItalicFont(&opendyslexic_8_bolditalic); -EpdFontFamily opendyslexic8FontFamily(&opendyslexic8RegularFont, - &opendyslexic8BoldFont, - &opendyslexic8ItalicFont, +EpdFontFamily opendyslexic8FontFamily(&opendyslexic8RegularFont, &opendyslexic8BoldFont, &opendyslexic8ItalicFont, &opendyslexic8BoldItalicFont); EpdFont opendyslexic10RegularFont(&opendyslexic_10_regular); EpdFont opendyslexic10BoldFont(&opendyslexic_10_bold); EpdFont opendyslexic10ItalicFont(&opendyslexic_10_italic); EpdFont opendyslexic10BoldItalicFont(&opendyslexic_10_bolditalic); -EpdFontFamily opendyslexic10FontFamily(&opendyslexic10RegularFont, - &opendyslexic10BoldFont, - &opendyslexic10ItalicFont, +EpdFontFamily opendyslexic10FontFamily(&opendyslexic10RegularFont, &opendyslexic10BoldFont, &opendyslexic10ItalicFont, &opendyslexic10BoldItalicFont); EpdFont opendyslexic12RegularFont(&opendyslexic_12_regular); EpdFont opendyslexic12BoldFont(&opendyslexic_12_bold); EpdFont opendyslexic12ItalicFont(&opendyslexic_12_italic); EpdFont opendyslexic12BoldItalicFont(&opendyslexic_12_bolditalic); -EpdFontFamily opendyslexic12FontFamily(&opendyslexic12RegularFont, - &opendyslexic12BoldFont, - &opendyslexic12ItalicFont, +EpdFontFamily opendyslexic12FontFamily(&opendyslexic12RegularFont, &opendyslexic12BoldFont, &opendyslexic12ItalicFont, &opendyslexic12BoldItalicFont); EpdFont opendyslexic14RegularFont(&opendyslexic_14_regular); EpdFont opendyslexic14BoldFont(&opendyslexic_14_bold); EpdFont opendyslexic14ItalicFont(&opendyslexic_14_italic); EpdFont opendyslexic14BoldItalicFont(&opendyslexic_14_bolditalic); -EpdFontFamily opendyslexic14FontFamily(&opendyslexic14RegularFont, - &opendyslexic14BoldFont, - &opendyslexic14ItalicFont, +EpdFontFamily opendyslexic14FontFamily(&opendyslexic14RegularFont, &opendyslexic14BoldFont, &opendyslexic14ItalicFont, &opendyslexic14BoldItalicFont); -#endif // OMIT_FONTS +#endif // OMIT_FONTS EpdFont smallFont(¬osans_8_regular); EpdFontFamily smallFontFamily(&smallFont); @@ -150,7 +134,7 @@ void exitActivity() { } } -void enterNewActivity(Activity *activity) { +void enterNewActivity(Activity* activity) { currentActivity = activity; currentActivity->onEnter(); } @@ -173,9 +157,7 @@ void verifyPowerButtonDuration() { // now from millis()==0 (i.e. device start time). const uint16_t calibration = start; const uint16_t calibratedPressDuration = - (calibration < SETTINGS.getPowerButtonDuration()) - ? SETTINGS.getPowerButtonDuration() - calibration - : 1; + (calibration < SETTINGS.getPowerButtonDuration()) ? SETTINGS.getPowerButtonDuration() - calibration : 1; gpio.update(); // Needed because inputManager.isPressed() may take up to ~500ms to return the correct state @@ -223,55 +205,43 @@ void enterDeepSleep() { } void onGoHome(); -void onGoToMyLibraryWithTab(const std::string &path, - MyLibraryActivity::Tab tab); -void onGoToReader(const std::string &initialEpubPath, - MyLibraryActivity::Tab fromTab) { +void onGoToMyLibraryWithTab(const std::string& path, MyLibraryActivity::Tab tab); +void onGoToReader(const std::string& initialEpubPath, MyLibraryActivity::Tab fromTab) { exitActivity(); - enterNewActivity(new ReaderActivity(renderer, mappedInputManager, - initialEpubPath, fromTab, onGoHome, - onGoToMyLibraryWithTab)); -} -void onContinueReading() { - onGoToReader(APP_STATE.openEpubPath, MyLibraryActivity::Tab::Recent); + enterNewActivity( + new ReaderActivity(renderer, mappedInputManager, initialEpubPath, fromTab, onGoHome, onGoToMyLibraryWithTab)); } +void onContinueReading() { onGoToReader(APP_STATE.openEpubPath, MyLibraryActivity::Tab::Recent); } void onGoToFileTransfer() { exitActivity(); - enterNewActivity( - new CrossPointWebServerActivity(renderer, mappedInputManager, onGoHome)); + enterNewActivity(new CrossPointWebServerActivity(renderer, mappedInputManager, onGoHome)); } void onGoToSettings() { exitActivity(); - enterNewActivity( - new SettingsActivity(renderer, mappedInputManager, onGoHome)); + enterNewActivity(new SettingsActivity(renderer, mappedInputManager, onGoHome)); } void onGoToMyLibrary() { exitActivity(); - enterNewActivity(new MyLibraryActivity(renderer, mappedInputManager, onGoHome, - onGoToReader)); + enterNewActivity(new MyLibraryActivity(renderer, mappedInputManager, onGoHome, onGoToReader)); } -void onGoToMyLibraryWithTab(const std::string &path, - MyLibraryActivity::Tab tab) { +void onGoToMyLibraryWithTab(const std::string& path, MyLibraryActivity::Tab tab) { exitActivity(); - enterNewActivity(new MyLibraryActivity(renderer, mappedInputManager, onGoHome, - onGoToReader, tab, path)); + enterNewActivity(new MyLibraryActivity(renderer, mappedInputManager, onGoHome, onGoToReader, tab, path)); } void onGoToBrowser() { exitActivity(); - enterNewActivity( - new OpdsBookBrowserActivity(renderer, mappedInputManager, onGoHome)); + enterNewActivity(new OpdsBookBrowserActivity(renderer, mappedInputManager, onGoHome)); } void onGoHome() { exitActivity(); - enterNewActivity(new HomeActivity( - renderer, mappedInputManager, onContinueReading, onGoToMyLibrary, - onGoToSettings, onGoToFileTransfer, onGoToBrowser)); + enterNewActivity(new HomeActivity(renderer, mappedInputManager, onContinueReading, onGoToMyLibrary, onGoToSettings, + onGoToFileTransfer, onGoToBrowser)); } void setupDisplayAndFonts() { @@ -291,7 +261,7 @@ void setupDisplayAndFonts() { renderer.insertFont(OPENDYSLEXIC_10_FONT_ID, opendyslexic10FontFamily); renderer.insertFont(OPENDYSLEXIC_12_FONT_ID, opendyslexic12FontFamily); renderer.insertFont(OPENDYSLEXIC_14_FONT_ID, opendyslexic14FontFamily); -#endif // OMIT_FONTS +#endif // OMIT_FONTS renderer.insertFont(UI_10_FONT_ID, ui10FontFamily); renderer.insertFont(UI_12_FONT_ID, ui12FontFamily); renderer.insertFont(SMALL_FONT_ID, smallFontFamily); @@ -319,8 +289,7 @@ void setup() { Serial.printf("[%lu] [ ] SD card initialization failed\n", millis()); setupDisplayAndFonts(); exitActivity(); - enterNewActivity(new FullScreenMessageActivity( - renderer, mappedInputManager, "SD card error", EpdFontFamily::BOLD)); + enterNewActivity(new FullScreenMessageActivity(renderer, mappedInputManager, "SD card error", EpdFontFamily::BOLD)); return; } @@ -335,9 +304,7 @@ void setup() { // First serial output only here to avoid timing inconsistencies for power // button press duration verification - Serial.printf("[%lu] [ ] Starting CrossPoint version " CROSSPOINT_VERSION - "\n", - millis()); + Serial.printf("[%lu] [ ] Starting CrossPoint version " CROSSPOINT_VERSION "\n", millis()); setupDisplayAndFonts(); @@ -377,9 +344,8 @@ void loop() { gpio.update(); if (Serial && millis() - lastMemPrint >= 10000) { - Serial.printf( - "[%lu] [MEM] Free: %d bytes, Total: %d bytes, Min Free: %d bytes\n", - millis(), ESP.getFreeHeap(), ESP.getHeapSize(), ESP.getMinFreeHeap()); + Serial.printf("[%lu] [MEM] Free: %d bytes, Total: %d bytes, Min Free: %d bytes\n", millis(), ESP.getFreeHeap(), + ESP.getHeapSize(), ESP.getMinFreeHeap()); lastMemPrint = millis(); } @@ -392,9 +358,7 @@ void loop() { const unsigned long sleepTimeoutMs = SETTINGS.getSleepTimeoutMs(); if (millis() - lastActivityTime >= sleepTimeoutMs) { - Serial.printf( - "[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", - millis(), sleepTimeoutMs); + Serial.printf("[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", millis(), sleepTimeoutMs); enterDeepSleep(); // This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start return; @@ -416,9 +380,8 @@ void loop() { if (loopDuration > maxLoopDuration) { maxLoopDuration = loopDuration; if (maxLoopDuration > 50) { - Serial.printf( - "[%lu] [LOOP] New max loop duration: %lu ms (activity: %lu ms)\n", - millis(), maxLoopDuration, activityDuration); + Serial.printf("[%lu] [LOOP] New max loop duration: %lu ms (activity: %lu ms)\n", millis(), maxLoopDuration, + activityDuration); } } @@ -426,8 +389,8 @@ void loop() { // When an activity requests skip loop delay (e.g., webserver running), use // yield() for faster response Otherwise, use longer delay to save power if (currentActivity && currentActivity->skipLoopDelay()) { - yield(); // Give FreeRTOS a chance to run tasks, but return immediately + yield(); // Give FreeRTOS a chance to run tasks, but return immediately } else { - delay(10); // Normal delay when no activity requires fast response + delay(10); // Normal delay when no activity requires fast response } }