WICG / canvas-formatted-text

Other
80 stars 17 forks source link

Bringing back line-at-a-time formatting #46

Closed travisleithead closed 2 years ago

travisleithead commented 2 years ago

By popular demand, and from several internal customer requests (both at Microsoft and at Google), we should support line-at-a-time rendering (see also: https://github.com/WICG/canvas-formatted-text/issues/41 which could be addressed by this.)

In recent discussion, it was suggested that something like a

FormattedText.formatLine(...)

might be a good starting point.

travisleithead commented 2 years ago

Proposed approach:

  1. Author creates a FormattedText instance using the current approach (e.g., format(...)), but does not bother providing constraints. As such, the text will be formatted/shaped all on one infinitely long line. Alternatively, they can provide the contraints that they want for their first line, knowing that all following lines will be wrapped to that constraint despite the fact that they may intend to change the constraints on the following lines... This step is about getting all the relevant text input into the metrics objects.
  2. The FormattedText instance will provide a reflowFrom API which takes a line number and an optional constraints reference. Reflow implies that the new contraints will only be applied to the specified line and any subsequent lines (as the new contraints are enforced).
    • As currently described, omitting a width implies infinite width, and similar for height. So omitting the constraints object is equivalent to providing an empty constraint object, which is equivalent to removing the contraints for the given (and following) lines.
      • Authors that didn't constrain the FormattedText instance at format time, may call reflowFrom(0, <new constraints>)
      • Authors that already contrained line 1 (index 0) will already have the first line metrics (and can render it), and then need only provide the new contraints for the next line: reflowFrom(1, <new contraints>). This will keep line 0 untouched, and only reflow line index 1 to the new contraints, which may add/remove lines as the contraints allow.
  3. With each reflowFrom call, iterating each line, the author can cut/slice the original text content into any set of contraints (or even start over with line index 0 if desired). At the conclusion of each reflowFrom command, all the text is formatted and can be optionally drawn, or any one single line can be drawn as the scenario necessitates.
travisleithead commented 2 years ago

(Note the actual approach differs substantially from the proposed approach noted above.)