Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto generate font #1097

Merged
merged 31 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5dc16fa
Added font auto-generate script
yehoshuapw Apr 18, 2022
8abbc65
Added FontAwesome5-Solid+Brands+Regular.woff to git
yehoshuapw Apr 18, 2022
7b0a5d6
fontgen: Added ability to choose fonts with .c
yehoshuapw Apr 18, 2022
83780b4
fontgen: added missing requested font check
yehoshuapw Apr 19, 2022
cea34b9
fontgen: move features into fonts
yehoshuapw Apr 19, 2022
3bb597f
fontgen: removed ability of removing .c ext
yehoshuapw Apr 19, 2022
4b8424c
fontgen: use patch file for jetbrains 0 fix
yehoshuapw Apr 19, 2022
147cfc3
fontgen: simplify enabled fonts
yehoshuapw Apr 19, 2022
36a1250
fontgen: remove .c from requested font if there
yehoshuapw Apr 19, 2022
dadbb9a
fontgen: minor changes
yehoshuapw Apr 19, 2022
fbe98d7
fontgen: simplfy json after removed external features key
yehoshuapw Apr 20, 2022
7aa36a0
fonts: update README.md to match new method
yehoshuapw Apr 20, 2022
d6faf91
fontgen: generate fonts at runtime with CMake
yehoshuapw Apr 20, 2022
c7b157e
Added lv_font_conv to workflow main
yehoshuapw Apr 20, 2022
5a16e1b
fontgen: make simulator build fonts too
yehoshuapw Apr 20, 2022
b9c35de
fontgen: generate font .c files in build dir
yehoshuapw Apr 20, 2022
6d57001
fontgen: move lv_font_conv doc
yehoshuapw Apr 24, 2022
f645cbc
fontgen: remove "generating the fonts" section
yehoshuapw Apr 24, 2022
95ff573
fontgen: remove "feature" feature
yehoshuapw Apr 24, 2022
97bdfd7
fontgen: lock version at current
yehoshuapw Apr 24, 2022
f31adfb
fontgen: install npm, lv_font_conv in Dockerfile
yehoshuapw Apr 24, 2022
c48a7b1
fotngen: check for lv_font_conv
yehoshuapw Apr 27, 2022
7d81157
fontgen: assume plain .patch for single string patch
yehoshuapw Apr 27, 2022
0a45043
fontgen: remove double-asterisk in readme
yehoshuapw Apr 27, 2022
415c4d3
fontgen: verify lv_font_conv at cmake
yehoshuapw Apr 27, 2022
0fcbf22
fontgen: remove advanced (format string, process as list) from patching
yehoshuapw Apr 27, 2022
08491cb
fontgen: changes to allow CMake to work from other project
yehoshuapw Apr 28, 2022
e21d92b
fongen: don't pre-build fonts
yehoshuapw Apr 28, 2022
24b7950
docker: bump ubuntu to 20.04 and node to 18
yehoshuapw May 8, 2022
8becd02
update docker to 22, and use python3 by default
yehoshuapw May 10, 2022
c455087
fontgen: update README.md to remove patch advanced options
yehoshuapw May 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/lv_sim.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ jobs:
sudo apt-get update
sudo apt-get -y install libsdl2-dev

- name: Install lv_font_conv
run:
npm i -g [email protected]

#########################################################################################
# Checkout

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ jobs:
pip3 install --user setuptools
pip3 install --user adafruit-nrfutil

- name: Install lv_font_conv
run:
npm i -g [email protected]

#########################################################################################
# Checkout

Expand Down
5 changes: 5 additions & 0 deletions doc/buildAndProgram.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ To build this project, you'll need:
python -m pip install -r tools/mcuboot/requirements.txt
```
- A reasonably recent version of CMake (I use 3.16.5)
- lv_font_conv, to generate the font .c files
- see [lv_font_conv](https://github.com/lvgl/lv_font_conv#install-the-script)
- install npm (commonly done via the package manager)
- install lv_font_conv: `npm i lv_font_conv -g`
- if installed non-globally, make sure `lv_font_conv` is in the PATH

## Build steps
### Clone the repo
Expand Down
14 changes: 10 additions & 4 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:18.04
FROM ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update -qq \
Expand All @@ -11,21 +11,27 @@ RUN apt-get update -qq \
make \
python3 \
python3-pip \
python-is-python3 \
tar \
unzip \
wget \
# aarch64 packages
wget \
curl \
# aarch64 packages
libffi-dev \
libssl-dev \
python3-dev \
python \
git \
apt-utils \
&& curl -sL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/cache/apt/* /var/lib/apt/lists/*;

# Git needed for PROJECT_GIT_COMMIT_HASH variable setting

RUN pip3 install adafruit-nrfutil
RUN pip3 install -Iv cryptography==3.3
RUN pip3 install cbor
RUN npm i [email protected] -g

# build.sh knows how to compile
COPY build.sh /opt/
Expand Down
3 changes: 1 addition & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ list(APPEND IMAGE_FILES
displayapp/icons/bluetooth/os_bt_disconnected.c

)

include(displayapp/fonts/CMakeLists.txt)
list(APPEND SOURCE_FILES
BootloaderVersion.cpp
logging/NrfLogger.cpp
Expand Down Expand Up @@ -920,7 +920,6 @@ add_custom_command(TARGET ${EXECUTABLE_NAME}
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_FILE_NAME}.out "${EXECUTABLE_FILE_NAME}.hex"
COMMENT "post build steps for ${EXECUTABLE_FILE_NAME}")


# Build binary intended to be used by bootloader
set(EXECUTABLE_MCUBOOT_NAME "pinetime-mcuboot-app")
set(EXECUTABLE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
Expand Down
19 changes: 19 additions & 0 deletions src/displayapp/fonts/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.10)

set(FONTS jetbrains_mono_42 jetbrains_mono_76 jetbrains_mono_bold_20
jetbrains_mono_extrabold_compressed lv_font_navi_80 lv_font_sys_48
open_sans_light)
find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED)
configure_file(${CMAKE_CURRENT_LIST_DIR}/jetbrains_mono_bold_20.c_zero.patch
displayapp/fonts/jetbrains_mono_bold_20.c_zero.patch COPYONLY)
foreach(FONT ${FONTS})
set_source_files_properties(displayapp/fonts/${FONT}.c
PROPERTIES GENERATED TRUE)

add_custom_command(OUTPUT displayapp/fonts/${FONT}.c
COMMAND python ${CMAKE_CURRENT_LIST_DIR}/generate.py
yehoshuapw marked this conversation as resolved.
Show resolved Hide resolved
-f ${FONT} ${CMAKE_CURRENT_LIST_DIR}/fonts.json
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/fonts.json
WORKING_DIRECTORY displayapp/fonts
)
endforeach()
Binary file not shown.
85 changes: 9 additions & 76 deletions src/displayapp/fonts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@
* [Awesome font from LVGL](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff)
* [Open Sans Light from Google](https://fonts.google.com/specimen/Open+Sans)

## Generate the fonts:

* Open the [LVGL font converter](https://lvgl.io/tools/fontconverter)
* Enter the settings for the font that you wish to convert
* Click on Convert, download the file and place it in `src/DisplayApp/Fonts`

### How to add new symbols:

* Browse [this cheatsheet](https://fontawesome.com/cheatsheet/free/solid) and pick symbols
* For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list (Remember to keep this
readme updated with newest range list)
* For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list (or the symbol list when its simple enough) in the `fonts.json` file
* Convert this hex value into a UTF-8 code
using [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f185&mode=hex)
* Define the new symbols in `src/displayapp/screens/Symbols.h`:
Expand All @@ -23,77 +16,17 @@
static constexpr const char* newSymbol = "\xEF\x86\x85";
```

### Small font

* Name: jetbrains_mono_bold_20
* Size: 20
* Bpp: 1 bit-per-pixel
* Do not enable font compression or horizontal subpixel rendering
* Load the file `JetBrainsMono-Bold.tff` (use the file in this repo to ensure the version matches) and specify the following range: `0x20-0x7e, 0x410-0x44f`
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following
range: `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015`
* Fix an error in the font conversion.

Replace the following:

/* U+0030 "0" */
0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7f,
0xdf, 0xf7, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f,
0x8f, 0xc0,

with

/* U+0030 "0" */
0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e,
0xdf, 0xb7, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f,
0x8f, 0xc0,

(there are two changes: 7f -> 7e and f7 -> b7)

### Medium font
### the config file format:

* Name: jetbrains_mono_42
* Size: 42
* Bpp: 1 bit-per-pixel
* Do not enable font compression or horizontal subpixel rendering
* Load the file `JetBrainsMono-Regular.tff` (use the file in this repo to ensure the version matches) and specify the following range: `0x25, 0x30-0x3a`

### Large font

* Name: jetbrains_mono_76
* Size: 76
* Bpp: 1 bit-per-pixel
* Do not enable font compression or horizontal subpixel rendering
* Load the file `JetBrainsMono-Regular.tff` (use the file in this repo to ensure the version matches) and specify the following range: `0x25, 0x2D, 0x2F, 0x30-0x3a`

### Digital watchface font

* Name: jetbrains_mono_extrabold_compressed
* Size: 80
* Bpp: 1 bit-per-pixel
* Do not enable font compression or horizontal subpixel rendering
* Load the file `JetBrainsMono-ExtraBold.tff` (use the file in this repo to ensure the version matches) and specify the following range: `0x30-0x3a`

### PineTimeStyle font

* Name: open_sans_light
* Size: 150
* Bpp: 1 bit-per-pixel
* Do not enable font compression or horizontal subpixel rendering
* Load the file `open_sans_light.tff` (use the file in this repo to ensure the version matches) and specify the following symbols: `0123456789`

### Symbols font (Used in QuickSettings for example)

* Name: lv_font_sys_48
* Size: 48
* Bpp: 1 bit-per-pixel
* Do not enable font compression or horizontal subpixel rendering
* Load the file `icons_sys_48.tff` and specify the following range: `0xe902, 0xe904-0xe907, 0xe90b-0xe90c`
inside `fonts`, there is a dictionary of fonts,
and for each font there is:
* sources - list of file,range(,symbols) wanted (as a dictionary of those)
* bpp - bits per pixel.
* size - size.
* patches - list of extra "patches" to run, either string to file which should be run, or list of arguments (with first one being the command being run)
* compress - optional. default disabled. add `"compress": true` to enable

### Navigation font

`navigtion.ttf` is created with the web app [icomoon](https://icomoon.io/app) by importing the svg files from `src/displayapp/icons/navigation/unique` and generating the font. `lv_font_navi_80.json` is a project file for the site, which you can import to add or remove icons.

This font must be generated with the `lv_font_conv` tool, which has additional options not available in the online converter.

`lv_font_conv --font navigation.ttf -r '0xe900-0xe929' --size 80 --format lvgl --bpp 2 -o lv_font_navi_80.c`
78 changes: 78 additions & 0 deletions src/displayapp/fonts/fonts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"jetbrains_mono_bold_20": {
"sources": [
{
"file": "JetBrainsMono-Bold.ttf",
"range": "0x20-0x7e, 0x410-0x44f"
},
{
"file": "FontAwesome5-Solid+Brands+Regular.woff",
"range": "0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015"
}
],
"bpp": 1,
"size": 20,
"patches": ["jetbrains_mono_bold_20.c_zero.patch"]
},
"jetbrains_mono_42": {
"sources": [
{
"file": "JetBrainsMono-Regular.ttf",
"range": "0x25, 0x30-0x3a"
}
],
"bpp": 1,
"size": 42
},
"jetbrains_mono_76": {
"sources": [
{
"file": "JetBrainsMono-Regular.ttf",
"range": "0x25, 0x2D, 0x2F, 0x30-0x3a"
}
],
"bpp": 1,
"size": 76
},
"jetbrains_mono_extrabold_compressed": {
"sources": [
{
"file": "JetBrainsMono-ExtraBold.ttf",
"range": "0x30-0x3a"
}
],
"bpp": 1,
"size": 80
},
"open_sans_light": {
"sources": [
{
"file": "open_sans_light.ttf",
"symbols": "0123456789"
}
],
"bpp": 1,
"size": 150
},
"lv_font_sys_48": {
"sources": [
{
"file": "icons_sys_48.ttf",
"range": "0xe902, 0xe904-0xe907, 0xe90b-0xe90c"
}
],
"bpp": 1,
"size": 48
},
"lv_font_navi_80": {
"sources": [
{
"file": "navigation.ttf",
"range": "0xe900-0xe929"
}
],
"bpp": 2,
"size": 80,
"compress": true
}
}
74 changes: 74 additions & 0 deletions src/displayapp/fonts/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python

import io
import sys
import json
import shutil
import typing
import os.path
import argparse
import subprocess

class Source(object):
def __init__(self, d):
self.file = d['file']
if not os.path.exists(self.file):
self.file = os.path.join(os.path.dirname(sys.argv[0]), self.file)
self.range = d.get('range')
self.symbols = d.get('symbols')


def gen_lvconv_line(dest: str, size: int, bpp: int, sources: typing.List[Source], compress:bool=False):
args = ['lv_font_conv', '--size', str(size), '--output', dest, '--bpp', str(bpp), '--format', 'lvgl']
if not compress:
args.append('--no-compress')
for source in sources:
args.extend(['--font', source.file])
if source.range:
args.extend(['--range', source.range])
if source.symbols:
args.extend(['--symbols', source.symbols])

return args

def main():
ap = argparse.ArgumentParser(description='auto generate LVGL font files from fonts')
ap.add_argument('config', type=str, help='config file to use')
ap.add_argument('-f', '--font', type=str, action='append', help='Choose specific fonts to generate (default: all)', default=[])
args = ap.parse_args()

if not shutil.which('lv_font_conv'):
sys.exit(f'Missing lv_font_conv. (make sure it is installed and in PATH)')
if not os.path.exists(args.config):
sys.exit(f'Error: the config file {args.config} does not exist.')
if not os.access(args.config, os.R_OK):
sys.exit(f'Error: the config file {args.config} is not accessable (permissions?).')
with open(args.config, 'r') as fd:
data = json.load(fd)

fonts_to_run = set(data.keys())

if args.font:
enabled_fonts = set()
for font in args.font:
enabled_fonts.add(font[:-2] if font.endswith('.c') else font)
d = enabled_fonts.difference(fonts_to_run)
if d:
print(f'Warning: requested font{"s" if len(d)>1 else ""} missing: {" ".join(d)}')
fonts_to_run = fonts_to_run.intersection(enabled_fonts)

for name in fonts_to_run:
font = data[name]
sources = font.pop('sources')
patches = font.pop('patches') if 'patches' in font else []
font['sources'] = [Source(thing) for thing in sources]
line = gen_lvconv_line(f'{name}.c', **font)
subprocess.check_call(line)
if patches:
for patch in patches:
subprocess.check_call(['/usr/bin/patch', name+'.c', patch])



if __name__ == '__main__':
main()
Loading