Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 21 additions & 10 deletions binding/emit_c_micropython_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
target_banner,
)
from .runtime_exports import filter_module_funcs_for_target, filter_registration_module_funcs
from .util import eprint, memoize
from .util import eprint, guarded, memoize
from .context import EmitterResult


Expand Down Expand Up @@ -2929,15 +2929,21 @@ def gen_global(global_name, global_type_ast):
* {module_name} {global_name} global definitions
*/

static const mp_lv_struct_t mp_{global_name} = {{
{{ &mp_{struct_name}_type }},
({cast}*)&{global_name}
}};
{definition}
""".format(
module_name=module_name,
global_name=global_name,
struct_name=global_type,
cast=gen.visit(global_type_ast),
definition=guarded(
"""static const mp_lv_struct_t mp_{global_name} = {{
{{ &mp_{struct_name}_type }},
({cast}*)&{global_name}
}};""".format(
global_name=global_name,
struct_name=global_type,
cast=gen.visit(global_type_ast),
),
global_name,
),
)
)

Expand Down Expand Up @@ -3157,10 +3163,15 @@ def gen_global(global_name, global_type_ast):
),
blobs="".join(
[
"{{ MP_ROM_QSTR(MP_QSTR_{name}), MP_ROM_PTR(&mp_{global_name}) }},\n ".format(
name=export_name(global_name, "blob"),
global_name=global_name,
guarded(
"{{ MP_ROM_QSTR(MP_QSTR_{name}), MP_ROM_PTR(&mp_{global_name}) }},".format(
name=export_name(global_name, "blob"),
global_name=global_name,
),
global_name,
indent=" ",
)
+ "\n "
# _nesting is deliberately kept here even though the
# canonical API model marks it private: see the
# comment in emit_backend.module_registration_plan and
Expand Down
23 changes: 19 additions & 4 deletions binding/emit_circuitpython_glue.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import collections

from . import runtime
from .util import guarded
from .emit_backend import enum_namespace_plan, module_registration_plan, public_enum_module_names, public_struct_c_names


Expand Down Expand Up @@ -74,9 +75,12 @@ def _module_global_entries(
)
for global_name in plan.generated_globals:
entries.append(
" {{ MP_ROM_QSTR(MP_QSTR_{name}), MP_ROM_PTR(&mp_{global_name}) }}".format(
name=export_name(global_name, "blob"),
global_name=global_name,
guarded(
" {{ MP_ROM_QSTR(MP_QSTR_{name}), MP_ROM_PTR(&mp_{global_name}) }},".format(
name=export_name(global_name, "blob"),
global_name=global_name,
),
global_name,
)
)
if plan.enum_names:
Expand Down Expand Up @@ -125,6 +129,17 @@ def _module_global_entries(
return entries


def _table(entries):
"""Join table entries; an entry that already ends in its comma keeps it.

Entries wrapped in ``#if``/``#endif`` carry their comma inside the guard.
"""
return "\n".join(
entry if entry.endswith(",") or entry.endswith("#endif") else entry + ","
for entry in entries
)


def finish_cp_fragment(max_phase):
"""Emit mergeable module entry table for shared-bindings/lvgl/__init__.c."""
int_constants = runtime.get("int_constants", [])
Expand Down Expand Up @@ -192,7 +207,7 @@ def finish_cp_fragment(max_phase):

const size_t lvgl_module_entry_count = sizeof(lvgl_module_entries) / sizeof(lvgl_module_entries[0]);
""".format(
table=",\n".join(all_entries) if all_entries else " /* no module entries */"
table=_table(all_entries) if all_entries else " /* no module entries */"
)
)

Expand Down
16 changes: 10 additions & 6 deletions binding/emit_cpython_glue.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import collections

from . import runtime
from .util import guarded
from .emit_backend import enum_namespace_plan, module_registration_plan, public_enum_module_names, public_struct_c_names


Expand Down Expand Up @@ -424,12 +425,15 @@ def finish_py_module(max_phase):
)
py_name = simplify_identifier(global_name)
print(
' {{ PyObject *obj = lv_to_mp_struct({type_object}, (void *)&{global_name});'
' if (obj == NULL) return NULL;'
' if (PyModule_AddObject(m, "{py_name}", obj) < 0) {{ Py_DECREF(obj); return NULL; }} }}'.format(
type_object=type_object,
global_name=global_name,
py_name=py_name,
guarded(
' {{ PyObject *obj = lv_to_mp_struct({type_object}, (void *)&{global_name});'
' if (obj == NULL) return NULL;'
' if (PyModule_AddObject(m, "{py_name}", obj) < 0) {{ Py_DECREF(obj); return NULL; }} }}'.format(
type_object=type_object,
global_name=global_name,
py_name=py_name,
),
global_name,
)
)

Expand Down
29 changes: 29 additions & 0 deletions binding/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""Small utilities: memoize and stderr logging for analyze/emit."""
from __future__ import print_function

import re
import sys
from functools import lru_cache

Expand All @@ -29,3 +30,31 @@ def clear_memoized():

def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)


_MONTSERRAT_FONT = re.compile(r"lv_font_montserrat_(\d+)$")


def config_guard(global_name):
"""Return the ``lv_conf.h`` switch a generated global depends on, or None.

A build can turn a built-in Montserrat size off (``-DLV_FONT_MONTSERRAT_40=0``)
without regenerating the binding, so the font's wrapper and its module entry
are emitted inside ``#if`` on that switch.
"""
match = _MONTSERRAT_FONT.match(global_name)
if match is None:
return None
return "LV_FONT_MONTSERRAT_%s" % match.group(1)


def guarded(text, global_name, indent=""):
"""Wrap ``text`` in ``#if``/``#endif`` on `config_guard` when it has one.

``indent`` goes before ``text`` and ``#endif``, for a line that the caller's
template has already indented.
"""
guard = config_guard(global_name)
if guard is None:
return text
return "#if %s\n%s%s\n%s#endif" % (guard, indent, text, indent)
14 changes: 14 additions & 0 deletions docs/reference/fonts.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ loaded font is parsed into the heap (roughly its file size: see the sizes in
your everyday fonts compiled in; load the occasional large size, or a script
you only sometimes need, at runtime.

## Leaving a built-in font out

Each `LV_FONT_MONTSERRAT_<n>` in `lv_conf.h` can be set from the build, so a
firmware short of flash can drop a compiled-in size without editing
`lv_conf.h` or regenerating the binding:

```bash
make BOARD=... CFLAGS_EXTRA=-DLV_FONT_MONTSERRAT_40=0
```

`lv.font_montserrat_40` is then missing from the module, and you can load
`montserrat_40.bin` at runtime instead. This only turns sizes off: a size that
`lv_conf.h` leaves out has no wrapper in the generated binding.

## Getting a font onto the board

```bash
Expand Down
34 changes: 32 additions & 2 deletions generated/lvgl_circuitpython.c
Original file line number Diff line number Diff line change
Expand Up @@ -27522,50 +27522,60 @@ static const mp_lv_struct_t mp_lv_tree_node_class = {
* lvgl lv_font_montserrat_14 global definitions
*/

#if LV_FONT_MONTSERRAT_14
static const mp_lv_struct_t mp_lv_font_montserrat_14 = {
{ &mp_lv_font_t_type },
(lv_font_t*)&lv_font_montserrat_14
};
#endif


/*
* lvgl lv_font_montserrat_16 global definitions
*/

#if LV_FONT_MONTSERRAT_16
static const mp_lv_struct_t mp_lv_font_montserrat_16 = {
{ &mp_lv_font_t_type },
(lv_font_t*)&lv_font_montserrat_16
};
#endif


/*
* lvgl lv_font_montserrat_24 global definitions
*/

#if LV_FONT_MONTSERRAT_24
static const mp_lv_struct_t mp_lv_font_montserrat_24 = {
{ &mp_lv_font_t_type },
(lv_font_t*)&lv_font_montserrat_24
};
#endif


/*
* lvgl lv_font_montserrat_32 global definitions
*/

#if LV_FONT_MONTSERRAT_32
static const mp_lv_struct_t mp_lv_font_montserrat_32 = {
{ &mp_lv_font_t_type },
(lv_font_t*)&lv_font_montserrat_32
};
#endif


/*
* lvgl lv_font_montserrat_40 global definitions
*/

#if LV_FONT_MONTSERRAT_40
static const mp_lv_struct_t mp_lv_font_montserrat_40 = {
{ &mp_lv_font_t_type },
(lv_font_t*)&lv_font_montserrat_40
};
#endif

/* Global struct wrapper for int */

Expand Down Expand Up @@ -48882,11 +48892,21 @@ static const mp_rom_map_elem_t lvgl_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_TABLE_CELL_NONE), MP_ROM_PTR(MP_ROM_INT(ENUM_LV_TABLE_CELL_NONE)) },
{ MP_ROM_QSTR(MP_QSTR_color_filter_shade), MP_ROM_PTR(&mp_lv_color_filter_shade) },
{ MP_ROM_QSTR(MP_QSTR_tree_node_class), MP_ROM_PTR(&mp_lv_tree_node_class) },
#if LV_FONT_MONTSERRAT_14
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_14), MP_ROM_PTR(&mp_lv_font_montserrat_14) },
#endif
#if LV_FONT_MONTSERRAT_16
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_16), MP_ROM_PTR(&mp_lv_font_montserrat_16) },
#endif
#if LV_FONT_MONTSERRAT_24
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_24), MP_ROM_PTR(&mp_lv_font_montserrat_24) },
#endif
#if LV_FONT_MONTSERRAT_32
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_32), MP_ROM_PTR(&mp_lv_font_montserrat_32) },
#endif
#if LV_FONT_MONTSERRAT_40
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_40), MP_ROM_PTR(&mp_lv_font_montserrat_40) },
#endif
{ MP_ROM_QSTR(MP_QSTR_style_const_prop_id_inv), MP_ROM_PTR(&mp_lv_style_const_prop_id_inv) },
{ MP_ROM_QSTR(MP_QSTR_obj_class), MP_ROM_PTR(&mp_lv_obj_class) },
{ MP_ROM_QSTR(MP_QSTR_binfont_font_class), MP_ROM_PTR(&mp_lv_binfont_font_class) },
Expand Down Expand Up @@ -49464,7 +49484,7 @@ static const mp_rom_map_elem_t lvgl_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_group_deinit), MP_ROM_PTR(&mp_lv_group_deinit_mpobj) },
{ MP_ROM_QSTR(MP_QSTR_fs_init), MP_ROM_PTR(&mp_lv_fs_init_mpobj) },
{ MP_ROM_QSTR(MP_QSTR_fs_deinit), MP_ROM_PTR(&mp_lv_fs_deinit_mpobj) },
{ MP_ROM_QSTR(MP_QSTR_event_mark_deleted), MP_ROM_PTR(&mp_lv_event_mark_deleted_mpobj) }
{ MP_ROM_QSTR(MP_QSTR_event_mark_deleted), MP_ROM_PTR(&mp_lv_event_mark_deleted_mpobj) },
};

static MP_DEFINE_CONST_DICT(lvgl_module_globals, lvgl_module_globals_table);
Expand Down Expand Up @@ -49509,11 +49529,21 @@ const mp_rom_map_elem_t lvgl_module_entries[] = {
{ MP_ROM_QSTR(MP_QSTR_TABLE_CELL_NONE), MP_ROM_PTR(MP_ROM_INT(ENUM_LV_TABLE_CELL_NONE)) },
{ MP_ROM_QSTR(MP_QSTR_color_filter_shade), MP_ROM_PTR(&mp_lv_color_filter_shade) },
{ MP_ROM_QSTR(MP_QSTR_tree_node_class), MP_ROM_PTR(&mp_lv_tree_node_class) },
#if LV_FONT_MONTSERRAT_14
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_14), MP_ROM_PTR(&mp_lv_font_montserrat_14) },
#endif
#if LV_FONT_MONTSERRAT_16
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_16), MP_ROM_PTR(&mp_lv_font_montserrat_16) },
#endif
#if LV_FONT_MONTSERRAT_24
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_24), MP_ROM_PTR(&mp_lv_font_montserrat_24) },
#endif
#if LV_FONT_MONTSERRAT_32
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_32), MP_ROM_PTR(&mp_lv_font_montserrat_32) },
#endif
#if LV_FONT_MONTSERRAT_40
{ MP_ROM_QSTR(MP_QSTR_font_montserrat_40), MP_ROM_PTR(&mp_lv_font_montserrat_40) },
#endif
{ MP_ROM_QSTR(MP_QSTR_style_const_prop_id_inv), MP_ROM_PTR(&mp_lv_style_const_prop_id_inv) },
{ MP_ROM_QSTR(MP_QSTR_obj_class), MP_ROM_PTR(&mp_lv_obj_class) },
{ MP_ROM_QSTR(MP_QSTR_binfont_font_class), MP_ROM_PTR(&mp_lv_binfont_font_class) },
Expand Down Expand Up @@ -50091,7 +50121,7 @@ const mp_rom_map_elem_t lvgl_module_entries[] = {
{ MP_ROM_QSTR(MP_QSTR_group_deinit), MP_ROM_PTR(&mp_lv_group_deinit_mpobj) },
{ MP_ROM_QSTR(MP_QSTR_fs_init), MP_ROM_PTR(&mp_lv_fs_init_mpobj) },
{ MP_ROM_QSTR(MP_QSTR_fs_deinit), MP_ROM_PTR(&mp_lv_fs_deinit_mpobj) },
{ MP_ROM_QSTR(MP_QSTR_event_mark_deleted), MP_ROM_PTR(&mp_lv_event_mark_deleted_mpobj) }
{ MP_ROM_QSTR(MP_QSTR_event_mark_deleted), MP_ROM_PTR(&mp_lv_event_mark_deleted_mpobj) },
};

const size_t lvgl_module_entry_count = sizeof(lvgl_module_entries) / sizeof(lvgl_module_entries[0]);
Expand Down
Loading
Loading