Prepare for display orientation part 1 (#2661)

This commit is contained in:
Totoo
2025-05-22 17:24:53 +02:00
committed by GitHub
parent 6f6d863a14
commit a1d7cf2b86
85 changed files with 405 additions and 334 deletions

View File

@@ -34,7 +34,7 @@ namespace lcd {
class ILI9341 {
public:
constexpr ILI9341()
ILI9341()
: scroll_state{0, 0, height(), 0} {
}
@@ -72,12 +72,23 @@ class ILI9341 {
draw_pixels(r, colors.data(), colors.size());
}
void draw_pixels(
const ui::Rect r,
const std::vector<ui::Color>& colors) {
draw_pixels(r, colors.data(), colors.size());
}
template <size_t N>
void read_pixels(
const ui::Rect r,
std::array<ui::ColorRGB888, N>& colors) {
read_pixels(r, colors.data(), colors.size());
}
void read_pixels(
const ui::Rect r,
std::vector<ui::ColorRGB888>& colors) {
read_pixels(r, colors.data(), colors.size());
}
void draw_bitmap(
const ui::Point p,
@@ -138,9 +149,9 @@ class ILI9341 {
*/
ui::Coord scroll_area_y(const ui::Coord y) const;
constexpr ui::Dim width() const { return ui::screen_width; }
constexpr ui::Dim height() const { return ui::screen_height; }
constexpr ui::Rect screen_rect() const { return {0, 0, width(), height()}; }
ui::Dim width() { return ui::screen_width; }
ui::Dim height() { return ui::screen_height; }
ui::Rect screen_rect() { return {0, 0, width(), height()}; }
void draw_pixels(const ui::Rect r, const ui::Color* const colors, const size_t count);
void read_pixels(const ui::Rect r, ui::ColorRGB888* const colors, const size_t count);

View File

@@ -63,7 +63,32 @@ Optional<File::Error> PNGWriter::create(
}
file.write(png_file_header);
file.write(png_ihdr_screen_capture);
// ihdr dynamic
std::array<uint8_t, 25> png_ihdr_dyn;
for (uint8_t i = 0; i < 25; i++) {
png_ihdr_dyn[i] = png_ihdr_screen_capture[i];
}
// Write width (4 bytes big-endian)
png_ihdr_dyn[8] = (width >> 24) & 0xFF;
png_ihdr_dyn[9] = (width >> 16) & 0xFF;
png_ihdr_dyn[10] = (width >> 8) & 0xFF;
png_ihdr_dyn[11] = width & 0xFF;
// Write height (4 bytes big-endian)
png_ihdr_dyn[12] = (height >> 24) & 0xFF;
png_ihdr_dyn[13] = (height >> 16) & 0xFF;
png_ihdr_dyn[14] = (height >> 8) & 0xFF;
png_ihdr_dyn[15] = height & 0xFF;
crc.reset();
crc.process_bytes(png_ihdr_dyn.data(), 25);
uint32_t crci = crc.checksum();
png_ihdr_dyn[21] = (crci >> 24) & 0xFF;
png_ihdr_dyn[22] = (crci >> 16) & 0xFF;
png_ihdr_dyn[23] = (crci >> 8) & 0xFF;
png_ihdr_dyn[24] = crci & 0xFF;
file.write(png_ihdr_dyn);
write_chunk_header(
2 + height * (5 + 1 + width * 3) + 4,
@@ -108,6 +133,35 @@ void PNGWriter::write_scanline(const std::array<ui::ColorRGB888, 240>& scanline)
scanline_count++;
}
void PNGWriter::write_scanline(const std::vector<ui::ColorRGB888>& scanline) {
constexpr uint8_t scanline_filter_type = 0;
// Total block length = 1 filter byte + scanline byte length
const uint32_t deflate_block_length = 1 + static_cast<uint32_t>(scanline.size() * sizeof(ui::ColorRGB888));
const std::array<uint8_t, 6> deflate_and_scanline_header{
static_cast<uint8_t>((scanline_count == (height - 1)) ? 0x01 : 0x00), // Final block?
static_cast<uint8_t>(deflate_block_length & 0xff), // Length LSB
static_cast<uint8_t>((deflate_block_length >> 8) & 0xff), // Length MSB
static_cast<uint8_t>((deflate_block_length & 0xff) ^ 0xff), // ~Length LSB
static_cast<uint8_t>(((deflate_block_length >> 8) & 0xff) ^ 0xff), // ~Length MSB
scanline_filter_type};
write_chunk_content(deflate_and_scanline_header);
adler_32.feed(scanline_filter_type);
adler_32.feed(scanline);
// Chunked writing to avoid large single writes
constexpr size_t CHUNK_SIZE = 80; // Tune for your hardware/filesystem
for (size_t i = 0; i < scanline.size(); i += CHUNK_SIZE) {
size_t chunk_len = std::min(CHUNK_SIZE, scanline.size() - i);
write_chunk_content(&scanline[i], chunk_len * sizeof(ui::ColorRGB888));
}
scanline_count++;
}
void PNGWriter::write_chunk_header(
const size_t length,
const std::array<uint8_t, 4>& type) {

View File

@@ -38,11 +38,12 @@ class PNGWriter {
Optional<File::Error> create(const std::filesystem::path& filename);
void write_scanline(const std::array<ui::ColorRGB888, 240>& scanline);
void write_scanline(const std::vector<ui::ColorRGB888>& scanline);
private:
// TODO: These constants are baked in a few places, do not change blithely.
static constexpr int width{240};
static constexpr int height{320};
int width{ui::screen_width};
int height{ui::screen_height};
File file{};
int scanline_count{0};

View File

@@ -28,6 +28,9 @@
namespace ui {
uint16_t screen_width = 240;
uint16_t screen_height = 320;
// CGA palette
// Index into this table should match STR_COLOR_ escape string in ui.hpp
Color term_colors[16] = {

View File

@@ -50,8 +50,8 @@ namespace ui {
using Coord = int16_t;
using Dim = int16_t;
constexpr uint16_t screen_width = 240;
constexpr uint16_t screen_height = 320;
extern uint16_t screen_width;
extern uint16_t screen_height;
/* Dimensions for the default font character. */
constexpr uint16_t char_width = 8;