Skip to content

Text Refactor

Stuart Scott edited this page Apr 16, 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

  • No rich text support; eg bulleted/numbered lists, headings, paragraphs, images, links
  • No bi-directional support (LTR, RTL, mixed)
  • Hard to convey semantic meaning of text; eg cannot configure widgets to be H1-H6, Subtitle, Body, Caption, et al. (https://gophers.slack.com/archives/CK5U4BU87/p1607524897399600, https://gophers.slack.com/archives/CK5U4BU87/p1610012275206000)
  • No support for mixing styles; eg neither widget.Label nor widget.Entry cannot show a clickable hyperlink
  • Difficult for devs to customize existing widgets; eg cannot create center-aligned, widget.Entry (https://gophers.slack.com/archives/CB4QUBXGQ/p1554989104009500, https://gophers.slack.com/archives/CK5U4BU87/p1603126884485900) <- Andy is not sure this is a problem to solve, as most of our widgets are not customisable in this way.
  • Difficult for devs to create custom text widgets and access toolkit behaviour such as wrapping, selecting, and editing. For example, a dev cannot render multiple editable lines in a custom font without re-implementing textProvider and Entry.
  • Performance is low as the entire text must be rendered - could be improved with "collectionification" (applying lessons learned from caches in collection widgets) - applies to TextGrid as well

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