Paperd.Ink Library 0.0.5
Library for interacting with Paperd.Ink devices.
Loading...
Searching...
No Matches
PaperdinkUIClass Class Reference

#include <ui_base.h>

Inheritance diagram for PaperdinkUIClass:
PaperdinkUIBaseClass

Public Member Functions

void display_grid (GxEPD2_GFX &display)
 
void display_text_center (GxEPD2_GFX &display, int16_t x, int16_t y, const char *string, int16_t w=0, int16_t h=0, const GFXfont *font=&PAPERDINK_FONT_SML, uint16_t color=GxEPD_BLACK, uint8_t size=1)
 
uint16_t read16 (File &f)
 
uint32_t read32 (File &f)
 
void display_bitmap_fs (GxEPD2_GFX &display, fs::FS &fs, const char *filename, int16_t x, int16_t y, bool with_color)
 

Additional Inherited Members

- Public Attributes inherited from PaperdinkUIBaseClass
const GFXfont * font = &PAPERDINK_FONT_SML
 
const GFXfont * font_bold = &PAPERDINK_FONT_SML_BOLD
 
int primary_color = GxEPD_BLACK
 
int secondary_color = GxEPD_WHITE
 
int tertiary_color = GxEPD_BLACK
 

Detailed Description

Definition at line 16 of file ui_base.h.

Member Function Documentation

◆ display_bitmap_fs()

void PaperdinkUIClass::display_bitmap_fs ( GxEPD2_GFX & display,
fs::FS & fs,
const char * filename,
int16_t x,
int16_t y,
bool with_color )

Definition at line 70 of file ui_base.cpp.

71{
72 File file;
73 bool valid = false; // valid format to be handled
74 bool flip = true; // bitmap is stored bottom-to-top
75 uint32_t startTime = millis();
76
77 if ((x >= display.width()) || (y >= display.height())) return;
78
79 DEBUG.println();
80 DEBUG.print("Loading image '");
81 DEBUG.print(filename);
82 DEBUG.println('\'');
83
84 file = fs.open(String("/") + filename, FILE_READ);
85 if (!file) {
86 DEBUG.print("File not found");
87 return;
88 }
89
90 // Parse BMP header
91 if (read16(file) == 0x4D42) { // BMP signature
92 uint32_t fileSize = read32(file);
93 uint32_t creatorBytes = read32(file);
94 uint32_t imageOffset = read32(file); // Start of image data
95 uint32_t headerSize = read32(file);
96 uint32_t width = read32(file);
97 uint32_t height = read32(file);
98 uint16_t planes = read16(file);
99 uint16_t depth = read16(file); // bits per pixel
100 uint32_t format = read32(file);
101 if ((planes == 1) && ((format == 0) || (format == 3))) { // uncompressed is handled, 565 also
102 DEBUG.print("File size: "); DEBUG.println(fileSize);
103 DEBUG.print("Image Offset: "); DEBUG.println(imageOffset);
104 DEBUG.print("Header size: "); DEBUG.println(headerSize);
105 DEBUG.print("Bit Depth: "); DEBUG.println(depth);
106 DEBUG.print("Image size: ");
107 DEBUG.print(width);
108 DEBUG.print('x');
109 DEBUG.println(height);
110 // BMP rows are padded (if needed) to 4-byte boundary
111 uint32_t rowSize = (width * depth / 8 + 3) & ~3;
112 if (depth < 8) rowSize = ((width * depth + 8 - depth) / 8 + 3) & ~3;
113 if (height < 0) {
114 height = -height;
115 flip = false;
116 }
117 uint16_t w = width;
118 uint16_t h = height;
119 if ((x + w - 1) >= display.width()) w = display.width() - x;
120 if ((y + h - 1) >= display.height()) h = display.height() - y;
121 valid = true;
122 uint8_t bitmask = 0xFF;
123 uint8_t bitshift = 8 - depth;
124 uint16_t red, green, blue;
125 bool whitish, colored;
126 if (depth == 1) with_color = false;
127 if (depth <= 8) {
128 if (depth < 8) bitmask >>= depth;
129 file.seekSet(54); //palette is always @ 54
130 for (uint16_t pn = 0; pn < (1 << depth); pn++) {
131 blue = file.read();
132 green = file.read();
133 red = file.read();
134 file.read();
135 whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
136 colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
137 if (0 == pn % 8) mono_palette_buffer[pn / 8] = 0;
138 mono_palette_buffer[pn / 8] |= whitish << pn % 8;
139 if (0 == pn % 8) color_palette_buffer[pn / 8] = 0;
140 color_palette_buffer[pn / 8] |= colored << pn % 8;
141 }
142 }
143 //display.fillScreen(GxEPD_WHITE);
144 uint32_t rowPosition = flip ? imageOffset + (height - h) * rowSize : imageOffset;
145 for (uint16_t row = 0; row < h; row++, rowPosition += rowSize) { // for each line
146 uint32_t in_remain = rowSize;
147 uint32_t in_idx = 0;
148 uint32_t in_bytes = 0;
149 uint8_t in_byte = 0; // for depth <= 8
150 uint8_t in_bits = 0; // for depth <= 8
151 uint16_t color = GxEPD_BLACK;
152 file.seekSet(rowPosition);
153 for (uint16_t col = 0; col < w; col++) { // for each pixel
154 // Time to read more pixel data?
155 if (in_idx >= in_bytes) { // ok, exact match for 24bit also (size IS multiple of 3)
156 in_bytes = file.read(input_buffer, in_remain > sizeof(input_buffer) ? sizeof(input_buffer) : in_remain);
157 in_remain -= in_bytes;
158 in_idx = 0;
159 }
160 switch (depth) {
161 case 24:
162 blue = input_buffer[in_idx++];
163 green = input_buffer[in_idx++];
164 red = input_buffer[in_idx++];
165 whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
166 colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
167 break;
168 case 16:
169 {
170 uint8_t lsb = input_buffer[in_idx++];
171 uint8_t msb = input_buffer[in_idx++];
172 if (format == 0) { // 555
173 blue = (lsb & 0x1F) << 3;
174 green = ((msb & 0x03) << 6) | ((lsb & 0xE0) >> 2);
175 red = (msb & 0x7C) << 1;
176 } else {// 565
177 blue = (lsb & 0x1F) << 3;
178 green = ((msb & 0x07) << 5) | ((lsb & 0xE0) >> 3);
179 red = (msb & 0xF8);
180 }
181 whitish = with_color ? ((red > 0x80) && (green > 0x80) && (blue > 0x80)) : ((red + green + blue) > 3 * 0x80); // whitish
182 colored = (red > 0xF0) || ((green > 0xF0) && (blue > 0xF0)); // reddish or yellowish?
183 }
184 break;
185 case 1:
186 case 4:
187 case 8:
188 {
189 if (0 == in_bits) {
190 in_byte = input_buffer[in_idx++];
191 in_bits = 8;
192 }
193 uint16_t pn = (in_byte >> bitshift) & bitmask;
194 whitish = mono_palette_buffer[pn / 8] & (0x1 << pn % 8);
195 colored = color_palette_buffer[pn / 8] & (0x1 << pn % 8);
196 in_byte <<= depth;
197 in_bits -= depth;
198 }
199 break;
200 }
201 if (whitish)
202 color = GxEPD_WHITE;
203 else if (colored && with_color)
204 color = GxEPD_RED;
205 else
206 color = GxEPD_BLACK;
207 uint16_t yrow = y + (flip ? h - row - 1 : row);
208 display.drawPixel(x + col, yrow, color);
209 } // end pixel
210 } // end line
211 DEBUG.print("loaded in "); DEBUG.print(millis() - startTime); DEBUG.println(" ms");
212 }
213 }
214 file.close();
215 if (!valid)
216 DEBUG.println("bitmap format not handled.");
217}
#define GxEPD_RED
Definition GxEPD2.h:25
#define GxEPD_BLACK
Definition GxEPD2.h:19
#define GxEPD_WHITE
Definition GxEPD2.h:20
uint16_t read16(File &f)
Definition ui_base.cpp:48
uint32_t read32(File &f)
Definition ui_base.cpp:58
#define DEBUG

◆ display_grid()

void PaperdinkUIClass::display_grid ( GxEPD2_GFX & display)

Definition at line 3 of file ui_base.cpp.

4{
5 /* Vertical line at half width */
6 display.drawLine(display.width() * 0.5, 0, display.width() * 0.5, display.height(), GxEPD_BLACK);
7 /* Vertical line at 1/4 width */
8 display.drawLine(display.width() * 0.25, 0, display.width() * 0.25, display.height(), GxEPD_BLACK);
9 /* Vertical line at 3/4 width */
10 display.drawLine(display.width() * 0.75, 0, display.width() * 0.75, display.height(), GxEPD_BLACK);
11
12 /* Horizontal line at half height */
13 display.drawLine(0, display.height() * 0.5, display.width(), display.height() * 0.5, GxEPD_BLACK);
14 /* Horizontal line at 1/4 width */
15 display.drawLine(0, display.height() * 0.25, display.width(), display.height() * 0.25, GxEPD_BLACK);
16 /* Horizontal line at 3/4 width */
17 display.drawLine(0, display.height() * 0.75, display.width(), display.height() * 0.75, GxEPD_BLACK);
18}

◆ display_text_center()

void PaperdinkUIClass::display_text_center ( GxEPD2_GFX & display,
int16_t x,
int16_t y,
const char * string,
int16_t w = 0,
int16_t h = 0,
const GFXfont * font = &PAPERDINK_FONT_SML,
uint16_t color = GxEPD_BLACK,
uint8_t size = 1 )

Definition at line 21 of file ui_base.cpp.

22{
23 int16_t xt, yt;
24 uint16_t wt, ht, prev_height = y, prev_width = x;
25
26 display.setFont(font);
27 display.setTextColor(color);
28 display.setTextSize(size);
29
30 display.getTextBounds(string, 0, 0, &xt, &yt, &wt, &ht);
31 if (w == 0 || h == 0)
32 /* No centering */
33 display.setCursor(prev_width, prev_height + ht);
34 else
35 display.setCursor(prev_width + ((w - wt) / 2), prev_height + ((h - ht) / 2));
36
37 display.print(string);
38}
const GFXfont * font
Definition ui_base.h:9

◆ read16()

uint16_t PaperdinkUIClass::read16 ( File & f)

Definition at line 48 of file ui_base.cpp.

49{
50 // BMP data is stored little-endian, same as Arduino.
51 uint16_t result;
52
53 ((uint8_t *)&result)[0] = f.read(); // LSB
54 ((uint8_t *)&result)[1] = f.read(); // MSB
55 return result;
56}

◆ read32()

uint32_t PaperdinkUIClass::read32 ( File & f)

Definition at line 58 of file ui_base.cpp.

59{
60 // BMP data is stored little-endian, same as Arduino.
61 uint32_t result;
62
63 ((uint8_t *)&result)[0] = f.read(); // LSB
64 ((uint8_t *)&result)[1] = f.read();
65 ((uint8_t *)&result)[2] = f.read();
66 ((uint8_t *)&result)[3] = f.read(); // MSB
67 return result;
68}

The documentation for this class was generated from the following files: