Aleo, Noto Sans, Open Dyslexic fonts (#163)
## Summary
* Swap out Bookerly font due to licensing issues, replace default font
with Aleo
* I did a bunch of searching around for a nice replacement font, and
this trumped several other like Literata, Merriwether, Vollkorn, etc
* Add Noto Sans, and Open Dyslexic as font options
* They can be selected in the settings screen
* Add font size options (Small, Medium, Large, Extra Large)
* Adjustable in settings
* Swap out uses of reader font in headings and replaced with slightly
larger Ubuntu font
* Replaced PixelArial14 font as it was difficult to track down, replace
with Space Grotesk
* Remove auto formatting on generated font files
* Massively speeds up formatting step now that there is a lot more CPP
font source
* Include fonts with their licenses in the repo
## Additional Context
Line compression setting will follow
| Font | Small | Medium | Large | X Large |
| --- | --- | --- | --- | --- |
| Aleo |

|

|

|

|
| Noto Sans |

|

|

|

|
| Open Dyslexic |

|

|

|

|
2025-12-30 18:21:47 +10:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
cd "$(dirname "$0")"
|
|
|
|
|
|
|
|
|
|
READER_FONT_STYLES=("Regular" "Italic" "Bold" "BoldItalic")
|
2025-12-31 01:28:25 +10:00
|
|
|
BOOKERLY_FONT_SIZES=(12 14 16 18)
|
Aleo, Noto Sans, Open Dyslexic fonts (#163)
## Summary
* Swap out Bookerly font due to licensing issues, replace default font
with Aleo
* I did a bunch of searching around for a nice replacement font, and
this trumped several other like Literata, Merriwether, Vollkorn, etc
* Add Noto Sans, and Open Dyslexic as font options
* They can be selected in the settings screen
* Add font size options (Small, Medium, Large, Extra Large)
* Adjustable in settings
* Swap out uses of reader font in headings and replaced with slightly
larger Ubuntu font
* Replaced PixelArial14 font as it was difficult to track down, replace
with Space Grotesk
* Remove auto formatting on generated font files
* Massively speeds up formatting step now that there is a lot more CPP
font source
* Include fonts with their licenses in the repo
## Additional Context
Line compression setting will follow
| Font | Small | Medium | Large | X Large |
| --- | --- | --- | --- | --- |
| Aleo |

|

|

|

|
| Noto Sans |

|

|

|

|
| Open Dyslexic |

|

|

|

|
2025-12-30 18:21:47 +10:00
|
|
|
NOTOSANS_FONT_SIZES=(12 14 16 18)
|
|
|
|
|
OPENDYSLEXIC_FONT_SIZES=(8 10 12 14)
|
|
|
|
|
|
2026-01-23 03:54:39 -05:00
|
|
|
# Custom font sizes - modify this array to change sizes for user-provided fonts
|
|
|
|
|
CUSTOM_FONT_SIZES=(12 14 16 18)
|
|
|
|
|
|
2025-12-31 01:28:25 +10:00
|
|
|
for size in ${BOOKERLY_FONT_SIZES[@]}; do
|
Aleo, Noto Sans, Open Dyslexic fonts (#163)
## Summary
* Swap out Bookerly font due to licensing issues, replace default font
with Aleo
* I did a bunch of searching around for a nice replacement font, and
this trumped several other like Literata, Merriwether, Vollkorn, etc
* Add Noto Sans, and Open Dyslexic as font options
* They can be selected in the settings screen
* Add font size options (Small, Medium, Large, Extra Large)
* Adjustable in settings
* Swap out uses of reader font in headings and replaced with slightly
larger Ubuntu font
* Replaced PixelArial14 font as it was difficult to track down, replace
with Space Grotesk
* Remove auto formatting on generated font files
* Massively speeds up formatting step now that there is a lot more CPP
font source
* Include fonts with their licenses in the repo
## Additional Context
Line compression setting will follow
| Font | Small | Medium | Large | X Large |
| --- | --- | --- | --- | --- |
| Aleo |

|

|

|

|
| Noto Sans |

|

|

|

|
| Open Dyslexic |

|

|

|

|
2025-12-30 18:21:47 +10:00
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
2025-12-31 01:28:25 +10:00
|
|
|
font_name="bookerly_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
|
|
|
|
font_path="../builtinFonts/source/Bookerly/Bookerly-${style}.ttf"
|
Aleo, Noto Sans, Open Dyslexic fonts (#163)
## Summary
* Swap out Bookerly font due to licensing issues, replace default font
with Aleo
* I did a bunch of searching around for a nice replacement font, and
this trumped several other like Literata, Merriwether, Vollkorn, etc
* Add Noto Sans, and Open Dyslexic as font options
* They can be selected in the settings screen
* Add font size options (Small, Medium, Large, Extra Large)
* Adjustable in settings
* Swap out uses of reader font in headings and replaced with slightly
larger Ubuntu font
* Replaced PixelArial14 font as it was difficult to track down, replace
with Space Grotesk
* Remove auto formatting on generated font files
* Massively speeds up formatting step now that there is a lot more CPP
font source
* Include fonts with their licenses in the repo
## Additional Context
Line compression setting will follow
| Font | Small | Medium | Large | X Large |
| --- | --- | --- | --- | --- |
| Aleo |

|

|

|

|
| Noto Sans |

|

|

|

|
| Open Dyslexic |

|

|

|

|
2025-12-30 18:21:47 +10:00
|
|
|
output_path="../builtinFonts/${font_name}.h"
|
|
|
|
|
python fontconvert.py $font_name $size $font_path --2bit > $output_path
|
|
|
|
|
echo "Generated $output_path"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
for size in ${NOTOSANS_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
|
|
|
|
font_name="notosans_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
|
|
|
|
font_path="../builtinFonts/source/NotoSans/NotoSans-${style}.ttf"
|
|
|
|
|
output_path="../builtinFonts/${font_name}.h"
|
|
|
|
|
python fontconvert.py $font_name $size $font_path --2bit > $output_path
|
|
|
|
|
echo "Generated $output_path"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
for size in ${OPENDYSLEXIC_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
|
|
|
|
font_name="opendyslexic_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
|
|
|
|
font_path="../builtinFonts/source/OpenDyslexic/OpenDyslexic-${style}.otf"
|
|
|
|
|
output_path="../builtinFonts/${font_name}.h"
|
|
|
|
|
python fontconvert.py $font_name $size $font_path --2bit > $output_path
|
|
|
|
|
echo "Generated $output_path"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
UI_FONT_SIZES=(10 12)
|
|
|
|
|
UI_FONT_STYLES=("Regular" "Bold")
|
|
|
|
|
|
|
|
|
|
for size in ${UI_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${UI_FONT_STYLES[@]}; do
|
|
|
|
|
font_name="ubuntu_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
|
|
|
|
font_path="../builtinFonts/source/Ubuntu/Ubuntu-${style}.ttf"
|
|
|
|
|
output_path="../builtinFonts/${font_name}.h"
|
|
|
|
|
python fontconvert.py $font_name $size $font_path > $output_path
|
|
|
|
|
echo "Generated $output_path"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
2025-12-31 01:28:25 +10:00
|
|
|
python fontconvert.py notosans_8_regular 8 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf > ../builtinFonts/notosans_8_regular.h
|
2026-01-23 03:54:39 -05:00
|
|
|
|
|
|
|
|
# ============================================================================
|
|
|
|
|
# Custom Fonts Processing
|
|
|
|
|
# ============================================================================
|
|
|
|
|
# Process all custom fonts in the custom/ folder
|
|
|
|
|
# Each subfolder should contain TTF files named: FontName-Regular.ttf, FontName-Bold.ttf, etc.
|
|
|
|
|
|
|
|
|
|
CUSTOM_DIR="../builtinFonts/custom"
|
|
|
|
|
CUSTOM_HEADER="../builtinFonts/custom/customFonts.h"
|
|
|
|
|
|
|
|
|
|
# Collect custom font names
|
|
|
|
|
declare -a CUSTOM_FONT_NAMES=()
|
|
|
|
|
declare -a CUSTOM_FONT_LOWERCASE=()
|
|
|
|
|
|
|
|
|
|
if [ -d "$CUSTOM_DIR" ]; then
|
|
|
|
|
for font_dir in "$CUSTOM_DIR"/*/; do
|
|
|
|
|
if [ -d "$font_dir" ]; then
|
|
|
|
|
# Get the font folder name (e.g., "FernMicro")
|
|
|
|
|
font_folder_name=$(basename "$font_dir")
|
|
|
|
|
font_name_lower=$(echo "$font_folder_name" | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
|
|
|
|
|
# Check if Regular font exists (required)
|
|
|
|
|
regular_font=$(find "$font_dir" -maxdepth 1 -iname "*-Regular.ttf" -o -iname "*-Regular.otf" 2>/dev/null | head -1)
|
|
|
|
|
if [ -z "$regular_font" ]; then
|
|
|
|
|
echo "Warning: Skipping $font_folder_name - no Regular font found"
|
|
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
CUSTOM_FONT_NAMES+=("$font_folder_name")
|
|
|
|
|
CUSTOM_FONT_LOWERCASE+=("$font_name_lower")
|
|
|
|
|
|
|
|
|
|
echo "Processing custom font: $font_folder_name"
|
|
|
|
|
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
|
|
|
|
style_lower=$(echo $style | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
output_name="${font_name_lower}_${size}_${style_lower}"
|
|
|
|
|
output_path="../builtinFonts/custom/${output_name}.h"
|
|
|
|
|
|
|
|
|
|
# Find the font file for this style (try TTF then OTF)
|
|
|
|
|
font_file=$(find "$font_dir" -maxdepth 1 -iname "*-${style}.ttf" -o -iname "*-${style}.otf" 2>/dev/null | head -1)
|
|
|
|
|
|
|
|
|
|
if [ -n "$font_file" ]; then
|
|
|
|
|
python fontconvert.py "$output_name" "$size" "$font_file" --2bit > "$output_path"
|
|
|
|
|
echo "Generated $output_path"
|
|
|
|
|
else
|
|
|
|
|
# If style not found, use Regular as fallback
|
|
|
|
|
echo "Note: $font_folder_name-${style} not found, using Regular"
|
|
|
|
|
python fontconvert.py "$output_name" "$size" "$regular_font" --2bit > "$output_path"
|
|
|
|
|
echo "Generated $output_path (fallback from Regular)"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Generate customFonts.h registry (header with extern declarations)
|
|
|
|
|
echo "Generating customFonts.h registry..."
|
|
|
|
|
|
|
|
|
|
CUSTOM_CPP="../../../src/customFonts.cpp"
|
|
|
|
|
|
|
|
|
|
cat > "$CUSTOM_HEADER" << 'HEADER_START'
|
|
|
|
|
/**
|
|
|
|
|
* Generated by convert-builtin-fonts.sh
|
|
|
|
|
* Registry of available custom fonts
|
|
|
|
|
*/
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <EpdFont.h>
|
|
|
|
|
#include <EpdFontFamily.h>
|
|
|
|
|
|
|
|
|
|
class GfxRenderer;
|
|
|
|
|
|
|
|
|
|
HEADER_START
|
|
|
|
|
|
|
|
|
|
# Write the count
|
|
|
|
|
echo "#define CUSTOM_FONT_COUNT ${#CUSTOM_FONT_NAMES[@]}" >> "$CUSTOM_HEADER"
|
|
|
|
|
echo "" >> "$CUSTOM_HEADER"
|
|
|
|
|
|
|
|
|
|
# Write font names array
|
|
|
|
|
if [ ${#CUSTOM_FONT_NAMES[@]} -gt 0 ]; then
|
|
|
|
|
echo "static const char* CUSTOM_FONT_NAMES[] = {" >> "$CUSTOM_HEADER"
|
|
|
|
|
for i in "${!CUSTOM_FONT_NAMES[@]}"; do
|
|
|
|
|
if [ $i -lt $((${#CUSTOM_FONT_NAMES[@]} - 1)) ]; then
|
|
|
|
|
echo " \"${CUSTOM_FONT_NAMES[$i]}\"," >> "$CUSTOM_HEADER"
|
|
|
|
|
else
|
|
|
|
|
echo " \"${CUSTOM_FONT_NAMES[$i]}\"" >> "$CUSTOM_HEADER"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
echo "};" >> "$CUSTOM_HEADER"
|
|
|
|
|
else
|
|
|
|
|
echo "static const char* CUSTOM_FONT_NAMES[] = {};" >> "$CUSTOM_HEADER"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "" >> "$CUSTOM_HEADER"
|
|
|
|
|
|
|
|
|
|
# Include all generated headers in the header file
|
|
|
|
|
echo "// Include all custom font headers" >> "$CUSTOM_HEADER"
|
|
|
|
|
for font_name_lower in "${CUSTOM_FONT_LOWERCASE[@]}"; do
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
|
|
|
|
style_lower=$(echo $style | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
echo "#include <builtinFonts/custom/${font_name_lower}_${size}_${style_lower}.h>" >> "$CUSTOM_HEADER"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo "" >> "$CUSTOM_HEADER"
|
|
|
|
|
|
|
|
|
|
# Generate extern declarations for EpdFont and EpdFontFamily in header
|
|
|
|
|
if [ ${#CUSTOM_FONT_NAMES[@]} -gt 0 ]; then
|
|
|
|
|
echo "// Extern EpdFont declarations for custom fonts" >> "$CUSTOM_HEADER"
|
|
|
|
|
for font_name_lower in "${CUSTOM_FONT_LOWERCASE[@]}"; do
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
|
|
|
|
var_name="${font_name_lower}${size}${style}Font"
|
|
|
|
|
echo "extern EpdFont ${var_name};" >> "$CUSTOM_HEADER"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo "" >> "$CUSTOM_HEADER"
|
|
|
|
|
echo "// Extern EpdFontFamily declarations for custom fonts" >> "$CUSTOM_HEADER"
|
|
|
|
|
|
|
|
|
|
for font_name_lower in "${CUSTOM_FONT_LOWERCASE[@]}"; do
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
family_name="${font_name_lower}${size}FontFamily"
|
|
|
|
|
echo "extern EpdFontFamily ${family_name};" >> "$CUSTOM_HEADER"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "" >> "$CUSTOM_HEADER"
|
|
|
|
|
|
|
|
|
|
# Function declaration in header
|
|
|
|
|
echo "// Function to register all custom fonts with the renderer" >> "$CUSTOM_HEADER"
|
|
|
|
|
echo "void registerCustomFonts(GfxRenderer& renderer);" >> "$CUSTOM_HEADER"
|
|
|
|
|
echo "" >> "$CUSTOM_HEADER"
|
|
|
|
|
|
|
|
|
|
# Generate the .cpp file with actual definitions
|
|
|
|
|
cat > "$CUSTOM_CPP" << 'CPP_START'
|
|
|
|
|
/**
|
|
|
|
|
* Generated by convert-builtin-fonts.sh
|
|
|
|
|
* Custom font definitions
|
|
|
|
|
*/
|
|
|
|
|
#include <builtinFonts/custom/customFonts.h>
|
|
|
|
|
#include <GfxRenderer.h>
|
|
|
|
|
#include "fontIds.h"
|
|
|
|
|
|
|
|
|
|
CPP_START
|
|
|
|
|
|
|
|
|
|
# Generate EpdFont definitions in .cpp
|
|
|
|
|
if [ ${#CUSTOM_FONT_NAMES[@]} -gt 0 ]; then
|
|
|
|
|
echo "// EpdFont definitions for custom fonts" >> "$CUSTOM_CPP"
|
|
|
|
|
for font_name_lower in "${CUSTOM_FONT_LOWERCASE[@]}"; do
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
for style in ${READER_FONT_STYLES[@]}; do
|
|
|
|
|
style_lower=$(echo $style | tr '[:upper:]' '[:lower:]')
|
|
|
|
|
var_name="${font_name_lower}${size}${style}Font"
|
|
|
|
|
data_name="${font_name_lower}_${size}_${style_lower}"
|
|
|
|
|
echo "EpdFont ${var_name}(&${data_name});" >> "$CUSTOM_CPP"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo "" >> "$CUSTOM_CPP"
|
|
|
|
|
echo "// EpdFontFamily definitions for custom fonts" >> "$CUSTOM_CPP"
|
|
|
|
|
|
|
|
|
|
for font_name_lower in "${CUSTOM_FONT_LOWERCASE[@]}"; do
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
family_name="${font_name_lower}${size}FontFamily"
|
|
|
|
|
regular="${font_name_lower}${size}RegularFont"
|
|
|
|
|
bold="${font_name_lower}${size}BoldFont"
|
|
|
|
|
italic="${font_name_lower}${size}ItalicFont"
|
|
|
|
|
bolditalic="${font_name_lower}${size}BoldItalicFont"
|
|
|
|
|
echo "EpdFontFamily ${family_name}(&${regular}, &${bold}, &${italic}, &${bolditalic});" >> "$CUSTOM_CPP"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "" >> "$CUSTOM_CPP"
|
|
|
|
|
|
|
|
|
|
# Generate registerCustomFonts function in .cpp
|
|
|
|
|
echo "void registerCustomFonts(GfxRenderer& renderer) {" >> "$CUSTOM_CPP"
|
|
|
|
|
|
|
|
|
|
if [ ${#CUSTOM_FONT_NAMES[@]} -gt 0 ]; then
|
|
|
|
|
echo "#if CUSTOM_FONT_COUNT > 0" >> "$CUSTOM_CPP"
|
|
|
|
|
for font_name_lower in "${CUSTOM_FONT_LOWERCASE[@]}"; do
|
|
|
|
|
font_name_upper=$(echo "$font_name_lower" | tr '[:lower:]' '[:upper:]')
|
|
|
|
|
for size in ${CUSTOM_FONT_SIZES[@]}; do
|
|
|
|
|
family_name="${font_name_lower}${size}FontFamily"
|
|
|
|
|
echo " renderer.insertFont(${font_name_upper}_${size}_FONT_ID, ${family_name});" >> "$CUSTOM_CPP"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
echo "#else" >> "$CUSTOM_CPP"
|
|
|
|
|
echo " (void)renderer; // Suppress unused parameter warning" >> "$CUSTOM_CPP"
|
|
|
|
|
echo "#endif" >> "$CUSTOM_CPP"
|
|
|
|
|
else
|
|
|
|
|
echo " (void)renderer; // Suppress unused parameter warning" >> "$CUSTOM_CPP"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "}" >> "$CUSTOM_CPP"
|
|
|
|
|
echo "" >> "$CUSTOM_CPP"
|
|
|
|
|
|
|
|
|
|
echo "Generated customFonts.h and customFonts.cpp with ${#CUSTOM_FONT_NAMES[@]} custom font(s)"
|