beeware/toga

Incorrect custom font registration isn't handled properly

Closed this issue · 2 comments

Describe the bug

Font backends throw a ValueError if the user attempts to register a custom font, but the path either doesn't exist or isn't openable as a font. Unfortunately, this only happens when the font is applied; assuming this is the initial font set on a widget when it's created, it gets eaten by this compatibility shim:

@_applicator.setter
def _applicator(self, value):
self._assigned_applicator = value
if value is not None:
try:
self.apply()
######################################################################
# 10-2024: Backwards compatibility for Toga < 0.5.0
######################################################################
except Exception:
warn(
"Failed to apply style when assigning applicator, or when "
"assigning a new style once applicator is present. Node should be "
"sufficiently initialized to apply its style before it is assigned "
"an applicator. This will be an exception in a future version.\n"
"This error probably means you've updated Travertino to 0.5.0 but "
"are still using Toga <= 0.4.8; to fix, either update Toga to "
">= 0.5.0, or pin Travertino to 0.3.0.",
RuntimeWarning,
stacklevel=2,
)
######################################################################
# End backwards compatibility
######################################################################

The result is that this error message is shown, instead of the intended one. The widget does fall back to using the system font, but how exactly it's displayed varies both by platform and by what other attributes are included... as an example, on macOS, if you only specify the font_family and font_size, the size is ignored; however, if you also include other properties like font_weight, font_style, or even color, everything is displayed as expected (including size).

Steps to reproduce

Font.register("Bad path", self.paths.app / "resources/foo.ttf")
bad_path_label = toga(
    "Should be system (nonexistent path)",
    font_family="Bad path",
    font_size=30,
)

Font.register("Bad file", self.paths.app / "resources/photo.png")
bad_file_label = toga.Label(
    "Should be system (unusable file)",
    font_family="Bad file",
    font_size=30,
)

Expected behavior

The log should display the specific font-loading error, and the widget should receive the proper font size and other attributes.

Screenshots

No response

Environment

  • Toga: Both main branch and #3526
  • At least macOS, Android, and iOS

Logs

Additional context

The font backends all perform essentially the same logic, but not always in the same order, which is probably why the font displays inconsistently between platforms. Once #3526 lands, I want to go in and standardize them, and it'll probably make sense to tackle this either as part of that or afterwards.

Hmm... the compat shim is reworked, is this still a bug?

I think this has been fixed by #3569.