Move to SDK EInkDisplay and enable anti-aliased 2-bit text (#5)
* First pass at moving to SDK EInkDisplay library * Add 2-bit grayscale text and anti-aliased rendering of text * Render status bar for empty chapters * Refresh screen every 15 pages to avoid ghosting * Simplify boot and sleep screens * Give FileSelectionScreen task more stack memory * Move text around slightly on Boot and Sleep screens * Re-use existing buffer and write to whole screen for 'partial update'
This commit is contained in:
@@ -31,4 +31,5 @@ typedef struct {
|
||||
uint8_t advanceY; ///< Newline distance (y axis)
|
||||
int ascender; ///< Maximal height of a glyph above the base line
|
||||
int descender; ///< Maximal height of a glyph below the base line
|
||||
bool is2Bit;
|
||||
} EpdFontData;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* generated by fontconvert.py
|
||||
* name: babyblue
|
||||
* size: 8
|
||||
* mode: 1-bit
|
||||
*/
|
||||
#pragma once
|
||||
#include "EpdFontData.h"
|
||||
@@ -500,5 +501,5 @@ static const EpdUnicodeInterval babyblueIntervals[] = {
|
||||
};
|
||||
|
||||
static const EpdFontData babyblue = {
|
||||
babyblueBitmaps, babyblueGlyphs, babyblueIntervals, 5, 17, 13, -4,
|
||||
babyblueBitmaps, babyblueGlyphs, babyblueIntervals, 5, 17, 13, -4, false,
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2608
lib/EpdFont/builtinFonts/bookerly_2b.h
Normal file
2608
lib/EpdFont/builtinFonts/bookerly_2b.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2748
lib/EpdFont/builtinFonts/bookerly_bold_2b.h
Normal file
2748
lib/EpdFont/builtinFonts/bookerly_bold_2b.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2859
lib/EpdFont/builtinFonts/bookerly_bold_italic_2b.h
Normal file
2859
lib/EpdFont/builtinFonts/bookerly_bold_italic_2b.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2680
lib/EpdFont/builtinFonts/bookerly_italic_2b.h
Normal file
2680
lib/EpdFont/builtinFonts/bookerly_italic_2b.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@
|
||||
* generated by fontconvert.py
|
||||
* name: ubuntu_10
|
||||
* size: 10
|
||||
* mode: 1-bit
|
||||
*/
|
||||
#pragma once
|
||||
#include "EpdFontData.h"
|
||||
@@ -762,5 +763,5 @@ static const EpdUnicodeInterval ubuntu_10Intervals[] = {
|
||||
};
|
||||
|
||||
static const EpdFontData ubuntu_10 = {
|
||||
ubuntu_10Bitmaps, ubuntu_10Glyphs, ubuntu_10Intervals, 31, 24, 20, -4,
|
||||
ubuntu_10Bitmaps, ubuntu_10Glyphs, ubuntu_10Intervals, 31, 24, 20, -4, false,
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* generated by fontconvert.py
|
||||
* name: ubuntu_bold_10
|
||||
* size: 10
|
||||
* mode: 1-bit
|
||||
*/
|
||||
#pragma once
|
||||
#include "EpdFontData.h"
|
||||
@@ -806,5 +807,5 @@ static const EpdUnicodeInterval ubuntu_bold_10Intervals[] = {
|
||||
};
|
||||
|
||||
static const EpdFontData ubuntu_bold_10 = {
|
||||
ubuntu_bold_10Bitmaps, ubuntu_bold_10Glyphs, ubuntu_bold_10Intervals, 31, 24, 20, -4,
|
||||
ubuntu_bold_10Bitmaps, ubuntu_bold_10Glyphs, ubuntu_bold_10Intervals, 31, 24, 20, -4, false,
|
||||
};
|
||||
|
||||
@@ -13,12 +13,14 @@ parser = argparse.ArgumentParser(description="Generate a header file from a font
|
||||
parser.add_argument("name", action="store", help="name of the font.")
|
||||
parser.add_argument("size", type=int, help="font size to use.")
|
||||
parser.add_argument("fontstack", action="store", nargs='+', help="list of font files, ordered by descending priority.")
|
||||
parser.add_argument("--2bit", dest="is2Bit", action="store_true", help="generate 2-bit greyscale bitmap instead of 1-bit black and white.")
|
||||
parser.add_argument("--additional-intervals", dest="additional_intervals", action="append", help="Additional code point intervals to export as min,max. This argument can be repeated.")
|
||||
args = parser.parse_args()
|
||||
|
||||
GlyphProps = namedtuple("GlyphProps", ["width", "height", "advance_x", "left", "top", "data_length", "data_offset", "code_point"])
|
||||
|
||||
font_stack = [freetype.Face(f) for f in args.fontstack]
|
||||
is2Bit = args.is2Bit
|
||||
size = args.size
|
||||
font_name = args.name
|
||||
|
||||
@@ -173,26 +175,73 @@ for i_start, i_end in intervals:
|
||||
pixels4g.append(px)
|
||||
px = 0
|
||||
|
||||
# Downsample to 1-bit bitmap - treat any non-zero as black
|
||||
pixelsbw = []
|
||||
px = 0
|
||||
pitch = (bitmap.width // 2) + (bitmap.width % 2)
|
||||
for y in range(bitmap.rows):
|
||||
for x in range(bitmap.width):
|
||||
px = px << 1
|
||||
bm = pixels4g[y * pitch + (x // 2)]
|
||||
px += 1 if ((x & 1) == 0 and bm & 0xF > 0) or ((x & 1) == 1 and bm & 0xF0 > 0) else 0
|
||||
if is2Bit:
|
||||
# 0 = white, 15 black, 8+ dark grey, 7- light grey
|
||||
# Downsample to 2-bit bitmap
|
||||
pixels2b = []
|
||||
px = 0
|
||||
pitch = (bitmap.width // 2) + (bitmap.width % 2)
|
||||
for y in range(bitmap.rows):
|
||||
for x in range(bitmap.width):
|
||||
px = px << 2
|
||||
bm = pixels4g[y * pitch + (x // 2)]
|
||||
bm = (bm >> ((x % 2) * 4)) & 0xF
|
||||
|
||||
if (y * bitmap.width + x) % 8 == 7:
|
||||
pixelsbw.append(px)
|
||||
px = 0
|
||||
if (bitmap.width * bitmap.rows) % 8 != 0:
|
||||
px = px << (8 - (bitmap.width * bitmap.rows) % 8)
|
||||
pixelsbw.append(px)
|
||||
if bm == 15:
|
||||
px += 3
|
||||
elif bm >= 8:
|
||||
px += 2
|
||||
elif bm > 0:
|
||||
px += 1
|
||||
|
||||
if (y * bitmap.width + x) % 4 == 3:
|
||||
pixels2b.append(px)
|
||||
px = 0
|
||||
if (bitmap.width * bitmap.rows) % 4 != 0:
|
||||
px = px << (4 - (bitmap.width * bitmap.rows) % 4) * 2
|
||||
pixels2b.append(px)
|
||||
|
||||
# for y in range(bitmap.rows):
|
||||
# line = ''
|
||||
# for x in range(bitmap.width):
|
||||
# pixelPosition = y * bitmap.width + x
|
||||
# byte = pixels2b[pixelPosition // 4]
|
||||
# bit_index = (3 - (pixelPosition % 4)) * 2
|
||||
# line += '#' if ((byte >> bit_index) & 3) > 0 else '.'
|
||||
# print(line)
|
||||
# print('')
|
||||
else:
|
||||
# Downsample to 1-bit bitmap - treat any non-zero as black
|
||||
pixelsbw = []
|
||||
px = 0
|
||||
pitch = (bitmap.width // 2) + (bitmap.width % 2)
|
||||
for y in range(bitmap.rows):
|
||||
for x in range(bitmap.width):
|
||||
px = px << 1
|
||||
bm = pixels4g[y * pitch + (x // 2)]
|
||||
px += 1 if ((x & 1) == 0 and bm & 0xF > 0) or ((x & 1) == 1 and bm & 0xF0 > 0) else 0
|
||||
|
||||
if (y * bitmap.width + x) % 8 == 7:
|
||||
pixelsbw.append(px)
|
||||
px = 0
|
||||
if (bitmap.width * bitmap.rows) % 8 != 0:
|
||||
px = px << (8 - (bitmap.width * bitmap.rows) % 8)
|
||||
pixelsbw.append(px)
|
||||
|
||||
# for y in range(bitmap.rows):
|
||||
# line = ''
|
||||
# for x in range(bitmap.width):
|
||||
# pixelPosition = y * bitmap.width + x
|
||||
# byte = pixelsbw[pixelPosition // 8]
|
||||
# bit_index = 7 - (pixelPosition % 8)
|
||||
# line += '#' if (byte >> bit_index) & 1 else '.'
|
||||
# print(line)
|
||||
# print('')
|
||||
|
||||
pixels = pixels2b if is2Bit else pixelsbw
|
||||
|
||||
# Build output data
|
||||
packed = bytes(pixelsbw)
|
||||
packed = bytes(pixels)
|
||||
glyph = GlyphProps(
|
||||
width = bitmap.width,
|
||||
height = bitmap.rows,
|
||||
@@ -216,7 +265,7 @@ for index, glyph in enumerate(all_glyphs):
|
||||
glyph_data.extend([b for b in packed])
|
||||
glyph_props.append(props)
|
||||
|
||||
print(f"/**\n * generated by fontconvert.py\n * name: {font_name}\n * size: {size}\n */")
|
||||
print(f"/**\n * generated by fontconvert.py\n * name: {font_name}\n * size: {size}\n * mode: {'2-bit' if is2Bit else '1-bit'}\n */")
|
||||
print("#pragma once")
|
||||
print("#include \"EpdFontData.h\"\n")
|
||||
print(f"static const uint8_t {font_name}Bitmaps[{len(glyph_data)}] = {{")
|
||||
@@ -244,4 +293,5 @@ print(f" {len(intervals)},")
|
||||
print(f" {norm_ceil(face.size.height)},")
|
||||
print(f" {norm_ceil(face.size.ascender)},")
|
||||
print(f" {norm_floor(face.size.descender)},")
|
||||
print(f" {'true' if is2Bit else 'false'},")
|
||||
print("};")
|
||||
|
||||
Reference in New Issue
Block a user