canvas-hypertxt icon indicating copy to clipboard operation
canvas-hypertxt copied to clipboard

Advanced mode: Blocking Constraints

Open Awendel opened this issue 3 years ago • 4 comments

One example where this library doesn't work well: have a Paragraph with some inline spans that have different styling (e.g. bold, different fontSize etc.) currently the library assumes styling is uniform across paragraph.

The way to solve this is to offer an API function that work per Span and not per Paragraph, but being able to pass on constraints. Such as for a given "line" how much of the available space is blocked already (could encode it as vectors, e.g. if line width is 100, 0-20 blocked, 60-80 blocked etc).

This would also allow Text to "wrap around" objects (e.g. image inside text), which is currently not possible with HTML / CSS.

The result of this advanced function call could be used for Canvas or SVG text rendering.

Essentially for a given Array of Spans with different Style and array of line blocking vector (which one could manually precompute), one wants returned an array of "TextFragments", that each have their own bounding box, X and Y etc.

Awendel avatar Aug 27 '22 14:08 Awendel

Wouldn't having a "first line indent" px be enough? If you want to split styling you need only split your outputs and track your indents. The bigger issue here is the space between the spans. Only you know what it should be and there is no way in canvas to teach the kerning/hinting engine that you are mixing styles.

jassmith avatar Aug 27 '22 15:08 jassmith

true that could work, would just require more work for the developer. But yes with firstLineIndent, technically it should be possible to have multipleSpans with different styles render together.

perhaps we could start there and down the line offer a more advanced API that takes care of producing TextFragment arrays automatically including for content it should wrap around.

Awendel avatar Aug 27 '22 16:08 Awendel

The problem with a convenience API is its likely going to be a less efficient API. The most efficient way to deal with spans would be:

  1. split text into spans
  2. configure context for span
  3. measure span
  4. draw span
  5. go to 2

since we don't do the drawing for the user and only they know what state they are changing between draw calls, we would have to be very obtuse about state changes and span setup.

jassmith avatar Aug 27 '22 18:08 jassmith

That is correct, except for that you don't have to draw the Span, you can also collect the result in bulk and draw later or do the calculations in a WebWorker for improved latency.

And you are also correct that it would be a less efficient API.

Currently the library emulates the text splitting behaviour of the inbuilt browser so that the logic can be brought into contexts with no native line splitting (canvas, svg).

You could consider if you wanted the library to be more than that: mainly that now that you control the rendering stack, one could offer features that HTML does not support, such as wrapping around / inside objects, which can be done in all professional publishing software (InDesign, ...) but not yet in the browser: Example Image:

maxresdefault

Which would only require to pass on "blocking" segments of a given line etc.

But I understand if its out of scope for this library, it is yours after all!

Awendel avatar Aug 28 '22 09:08 Awendel