Skip to content

Add font collection revision tracking and skb_editor_update_layout()#105

Open
ApoorvaJ wants to merge 1 commit into
memononen:mainfrom
ApoorvaJ:font-collection-revision
Open

Add font collection revision tracking and skb_editor_update_layout()#105
ApoorvaJ wants to merge 1 commit into
memononen:mainfrom
ApoorvaJ:font-collection-revision

Conversation

@ApoorvaJ

Copy link
Copy Markdown
Contributor

In some applications, fonts are loaded asynchronously: text is shaped with the fonts available now, missing glyphs are reported through the fallback callback, the application fetches the fonts and adds them to the collection. Until now there was no way to make existing layouts pick up the newly added fonts:

  • skb_layout_params_hash_append() identified the font collection only by its id, which is assigned once at creation. A layout shaped against an older state of the collection therefore hashed identically to an up-to-date one, so both the layout cache and the rich layout's incremental rebuild kept serving stale layouts.
  • The editor relayouts only as a side effect of content mutations (set text, insert, remove, attribute changes, undo); there was no public entry point to refresh the layout without touching the text. The only workaround was to reset the content wholesale, e.g. calling skb_editor_set_rich_text() with a copy of the current text, which churns the selection, composition, and undo state.

This commit makes font collection changes observable, and gives the editor a way to act on them:

  • skb_font_collection_t keeps a revision counter, bumped on every successful font add or remove, exposed via skb_font_collection_get_revision().
  • skb_layout_params_hash_append() includes the revision next to the collection id, so the layout cache and skb_rich_layout's params hash naturally treat layouts shaped against an older revision as stale.
  • New skb_editor_update_layout() re-runs the editor's layout update without modifying any editor state. Through the params hash it rebuilds everything when the font collection has changed, and is effectively a no-op otherwise, so it is safe to call liberally (e.g. whenever an async font fetch completes).

Tests: font_collection_tests covers the revision bumps on add/remove (including no bump on failed add/remove) and the resulting params hash change; editor_tests covers the end-to-end case of shaping Latin and Arabic text with a Latin-only collection, adding an Arabic font, and verifying that skb_editor_update_layout() reshapes the Arabic run with the new font while the text and selection stay untouched.


As with my recent commits, I've used Claude to help me with this change. I've thoroughly reviewed it. I believe the use-case is real, and it solves a problem in my project. As always I defer to your judgement on all matters. Happy to iterate as much as you need.

Fonts are often loaded asynchronously: text is shaped with the fonts
available now, missing glyphs are reported through the fallback
callback, the application fetches the fonts and adds them to the
collection. Until now there was no way to make existing layouts pick
up the newly added fonts:

- skb_layout_params_hash_append() identified the font collection only
  by its id, which is assigned once at creation. A layout shaped
  against an older state of the collection therefore hashed identically
  to an up-to-date one, so both the layout cache and the rich layout's
  incremental rebuild kept serving stale layouts.
- The editor relayouts only as a side effect of content mutations
  (set text, insert, remove, attribute changes, undo); there was no
  public entry point to refresh the layout without touching the text.
  The only workaround was to reset the content wholesale, e.g. calling
  skb_editor_set_rich_text() with a copy of the current text, which
  churns the selection, composition, and undo state.

This commit makes font collection changes observable, and gives the
editor a way to act on them:

- skb_font_collection_t keeps a revision counter, bumped on every
  successful font add or remove, exposed via
  skb_font_collection_get_revision().
- skb_layout_params_hash_append() includes the revision next to the
  collection id, so the layout cache and skb_rich_layout's params hash
  naturally treat layouts shaped against an older revision as stale.
- New skb_editor_update_layout() re-runs the editor's layout update
  without modifying any editor state. Through the params hash it
  rebuilds everything when the font collection has changed, and is
  effectively a no-op otherwise, so it is safe to call liberally
  (e.g. whenever an async font fetch completes).

Tests: font_collection_tests covers the revision bumps on add/remove
(including no bump on failed add/remove) and the resulting params hash
change; editor_tests covers the end-to-end case of shaping Latin and
Arabic text with a Latin-only collection, adding an Arabic font, and
verifying that skb_editor_update_layout() reshapes the Arabic run with
the new font while the text and selection stay untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant