mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-04 22:57:50 +03:00
fix(xtc): address PR review feedback for grayscale rendering
- Use FsHelpers::openFileForRead for consistency (XtcParser.cpp) - Simplify file extension checking logic (FileSelectionActivity.cpp) - Fix grayscale rendering bugs (XtcReaderActivity.cpp): - Use drawPixel(x, y, false) for LSB/MSB passes (LUT: 0=apply effect) - Add cleanupGrayscaleWithFrameBuffer() after re-rendering BW - Use conditional HALF_REFRESH based on pagesUntilFullRefresh - Decrement refresh counter instead of resetting - Add cleanupGrayscaleWithFrameBuffer() helper (GfxRenderer)
This commit is contained in:
parent
30c50ef45b
commit
76a1c30a87
@ -369,6 +369,17 @@ void GfxRenderer::restoreBwBuffer() {
|
||||
Serial.printf("[%lu] [GFX] Restored and freed BW buffer chunks\n", millis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup grayscale buffers using the current frame buffer.
|
||||
* Use this when BW buffer was re-rendered instead of stored/restored.
|
||||
*/
|
||||
void GfxRenderer::cleanupGrayscaleWithFrameBuffer() const {
|
||||
uint8_t* frameBuffer = einkDisplay.getFrameBuffer();
|
||||
if (frameBuffer) {
|
||||
einkDisplay.cleanupGrayscaleBuffers(frameBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void GfxRenderer::renderChar(const EpdFontFamily& fontFamily, const uint32_t cp, int* x, const int* y,
|
||||
const bool pixelState, const EpdFontStyle style) const {
|
||||
const EpdGlyph* glyph = fontFamily.getGlyph(cp, style);
|
||||
|
||||
@ -67,6 +67,7 @@ class GfxRenderer {
|
||||
void displayGrayBuffer() const;
|
||||
bool storeBwBuffer(); // Returns true if buffer was stored successfully
|
||||
void restoreBwBuffer();
|
||||
void cleanupGrayscaleWithFrameBuffer() const;
|
||||
|
||||
// Low level functions
|
||||
uint8_t* getFrameBuffer() const;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "XtcParser.h"
|
||||
|
||||
#include <FsHelpers.h>
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include <cstring>
|
||||
@ -31,9 +32,7 @@ XtcError XtcParser::open(const char* filepath) {
|
||||
}
|
||||
|
||||
// Open file
|
||||
m_file = SD.open(filepath, FILE_READ);
|
||||
if (!m_file) {
|
||||
Serial.printf("[%lu] [XTC] Failed to open file: %s\n", millis(), filepath);
|
||||
if (!FsHelpers::openFileForRead("XTC", filepath, m_file)) {
|
||||
m_lastError = XtcError::FILE_NOT_FOUND;
|
||||
return m_lastError;
|
||||
}
|
||||
|
||||
@ -40,18 +40,11 @@ void FileSelectionActivity::loadFiles() {
|
||||
|
||||
if (file.isDirectory()) {
|
||||
files.emplace_back(filename + "/");
|
||||
} else if (filename.length() >= 5 && filename.substr(filename.length() - 5) == ".epub") {
|
||||
files.emplace_back(filename);
|
||||
} else if (filename.length() >= 4) {
|
||||
// Check for XTC format extensions (.xtc, .xtch)
|
||||
std::string ext4 = filename.substr(filename.length() - 4);
|
||||
if (ext4 == ".xtc") {
|
||||
} else {
|
||||
std::string ext4 = filename.length() >= 4 ? filename.substr(filename.length() - 4) : "";
|
||||
std::string ext5 = filename.length() >= 5 ? filename.substr(filename.length() - 5) : "";
|
||||
if (ext5 == ".epub" || ext5 == ".xtch" || ext4 == ".xtc") {
|
||||
files.emplace_back(filename);
|
||||
} else if (filename.length() >= 5) {
|
||||
std::string ext5 = filename.substr(filename.length() - 5);
|
||||
if (ext5 == ".xtch") {
|
||||
files.emplace_back(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
|
||||
@ -236,29 +236,33 @@ void XtcReaderActivity::renderPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Display BW first with half refresh (clean base for grayscale overlay)
|
||||
renderer.displayBuffer(EInkDisplay::HALF_REFRESH);
|
||||
// Display BW with conditional refresh based on pagesUntilFullRefresh
|
||||
if (pagesUntilFullRefresh <= 1) {
|
||||
renderer.displayBuffer(EInkDisplay::HALF_REFRESH);
|
||||
} else {
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
|
||||
// Pass 2: LSB buffer - mark DARK gray only (XTH value 1)
|
||||
// README: "mark the **dark** grays pixels with `1`"
|
||||
// In LUT: 0 bit = apply gray effect, 1 bit = untouched
|
||||
renderer.clearScreen(0x00);
|
||||
for (uint16_t y = 0; y < pageHeight; y++) {
|
||||
for (uint16_t x = 0; x < pageWidth; x++) {
|
||||
if (getPixelValue(x, y) == 1) { // Dark grey only
|
||||
renderer.drawPixel(x, y, true);
|
||||
renderer.drawPixel(x, y, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
renderer.copyGrayscaleLsbBuffers();
|
||||
|
||||
// Pass 3: MSB buffer - mark LIGHT AND DARK gray (XTH value 1 or 2)
|
||||
// README: "mark the **light and dark** grays pixels with `1`"
|
||||
// In LUT: 0 bit = apply gray effect, 1 bit = untouched
|
||||
renderer.clearScreen(0x00);
|
||||
for (uint16_t y = 0; y < pageHeight; y++) {
|
||||
for (uint16_t x = 0; x < pageWidth; x++) {
|
||||
const uint8_t pv = getPixelValue(x, y);
|
||||
if (pv == 1 || pv == 2) { // Dark grey or Light grey
|
||||
renderer.drawPixel(x, y, true);
|
||||
renderer.drawPixel(x, y, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -277,8 +281,11 @@ void XtcReaderActivity::renderPage() {
|
||||
}
|
||||
}
|
||||
|
||||
// Reset refresh counter (grayscale display is a full refresh)
|
||||
pagesUntilFullRefresh = pagesPerRefresh;
|
||||
// Cleanup grayscale buffers with current frame buffer
|
||||
renderer.cleanupGrayscaleWithFrameBuffer();
|
||||
|
||||
// Decrement refresh counter
|
||||
pagesUntilFullRefresh--;
|
||||
|
||||
free(pageBuffer);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user