Skip to content

Text Refactor

Andy Williams edited this page Apr 15, 2021 · 12 revisions

Introduction

The next major release (probably Abelour) will feature a refactor of the text handling parts to address the issues and limitations encountered.

Background

Text handling and typesetting is one of the hardest and most complex piece of a UI toolkit. The current implementation was a good first step, but as the project has matured and developers have shared their feedback, it is clear that we're ready to take the next step.

Problems

Goal

The goal of this project is to develop a text handling solution that will have;

  • Extensibility - developers can create custom widgets and leverage the text handling utilities
  • Functionality - developers can provide a rich user experience
  • Testability & Performance - developers can test and benchmark their apps across all supported languages, locales, and regions.

Possibly out of scope for a refactor project, but we need to keep in mind:

  • Accessibility - users can read and write text via accessibility tools (eg screen readers)
  • Internationalization - users can configure an app to their mother-tongue

Prior art

Libraries of note that we should checkout to understand the complexities ahead:

Ideas

  • Content Hinting - enable devs to hint at the content of a UI Text element to leverage platforms APIs for providing suggestions (from dictionary or contacts), check spelling, keyboard tayloring (numeric vs alphanumeric, action button type, input language)
  • Mathematical expressions
  • Wrapping Binding - takes a mode, width, and string binding as inputs, then splits the text from the binding into lines less than or equal to the given length depending on the wrapping mode, providing as output a list binding which can be bound to a text line list collection. <- Andy notes here that whatever we do should not require binding, but could have binding helpers.
  • Using a strings.Builder or bytes.Buffer for providing an efficient way to append a lot of information to the string (like when typing). It would also open up for having canvas.Text be an io.Writer (and io.Reader In the case of the buffer).
  • Text Measurement Cache - measuring text is a time consuming operation and is called frequently, we could see a performance increase by caching the result for a given input (text, font, size, and style).
  • Adding MeasureTextDistanceToBaseline function (or something like this) alongside MeasureText or driver equivalent to enable future alignment according to widgets text baseline.
  • String Bundling - to assist in internationalization fyne bundle or a new fyne translate could be used to bundle string resources into the binary in such a way that they can be keyed with language tag (eg. "en-US") and ID (eg. "welcome_message")
  • We will need to support at a minimum RTL (right to left) as well as the default LTR, but bi-directional will be required for a complete solution
  • Shaping is exceptionally hard - I recommend everyone become familiar with Harfbuzz and pango
  • Gio project is keen to collaborate on these problems so a shared solution could be created for Go text rendering (https://gophers.slack.com/archives/CM87SNCGM/p1617180821092100)

Welcome to the Fyne wiki.

Project documentation

Getting involved

Platform details

Clone this wiki locally