Skip to content

LibTxt: Implement Strut and provide an API to it. Fix text clipping in textboxes. #26085

Closed

Description

@GaryQian

This issue will track the work required and progress on the implementation of strut, which will provide a paragraph-level minimum line height and leading to ensure that lines will take up a more predictable amount of space.

Strut is a feature that defines a line height scale, font size, and leading scale. Each line will then be laid out, and if any part of the the height is less than the mins defined by (leading * fontSize / 2) + (heightScale * fontSize) + (leading * fontSize / 2), then the min strut values will be used. If it is greater, then the actual values will be used.

The effect strut has is as if a zero width invisible space glyph was laid out at the beginning of each line. The line becomes unable to be shorter than this invisible space.

  • Expose API for user-supplied paragraph styles
  • Implement strut in LibTxt
  • Expose strut API in framework
  • Move textbox decoration padding into strut instead.
  • Use forceStrutHeight for textfields because future lines can be in fonts that are taller or lower.

Features up for discussion:

  • 'Force strut' option that forces line heights to be exactly that defined by the strut, which will provide rigid and unchanging line positions. Such an option would ignore the properties of the text and will possibly cause text overlap.

This issue will be updated as the work is completed/evolves

Some use cases are:

  • Force all lines to be the same height or to match the heights of a different
  • Ensure very small fonts in a paragraph have as much line spacing as larger fonts.
  • Create buffer zones to absorb extra line height from tall fonts.

For reference, strut can be defined by css in https://www.w3.org/TR/CSS2/visudet.html#strut. This blog post is also useful in visualizing and understanding what strut is doing here: https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align

Activity

  1. added
    a: text inputEntering text in a text field or keyboard related problems
    engineflutter/engine related. See also e: labels.
    a: typographyText rendering, possibly libtxt
    on Jan 4, 2019
  2. self-assigned this
    on Jan 4, 2019
  3. GaryQian commented on Jan 9, 2019

    @GaryQian
    ContributorAuthor

    flutter-team-archive/engine#7414 is the engine-side implementation of strut.

  4. added this to the milestone on Jan 10, 2019
  5. GaryQian commented on Jan 10, 2019

    @GaryQian
    ContributorAuthor

    #26332 is the framework side implementation.

  6. GaryQian commented on Jan 16, 2019

    @GaryQian
    ContributorAuthor

    Core implementation is mostly completed. Cleaning up. reviewing, and testing the Strut now.

    After strut lands, I will use it to fix some of the vertical text layout related bugs we have been seeing.

  7. GaryQian commented on Jan 16, 2019

    @GaryQian
    ContributorAuthor

    An additional feature that may be useful is the ability to get the strut metrics. Since strut metrics do not require any text, we are able to return guidelines to what a paragraph's shape will be before text is supplied. This can be used in places such as the prediction of textfield height before any text is entered or the necessary caret height in an empty textbox.

  8. HansMuller commented on Jan 17, 2019

    @HansMuller
    Contributor

    Strut is a feature that defines a line height scale, font size, and leading scale. Each line will then be laid out, and if any part of the the height is less than the mins defined by (leadingScale * fontSize / 2) + (heightScale * fontSize) + (leadingScale * fontSize / 2), then the min strut values will be used. If it is greater, then the actual values will be used

    "mins defined by" ... "then the min strut values" - isn't this sum a single "min", i.e. isn't just the minium overall line height?

    Maybe what you're getting at is a minium value for the baseline: (leadingScale * fontSize / 2) + (heightScale * fontSize), as well as the minimum line height: (leadingScale * fontSize) + (heightScale * fontSize)?

  9. GaryQian commented on Jan 17, 2019

    @GaryQian
    ContributorAuthor

    I think I'll actually break up the strut definition into two sections: one higher level overview and then a more detailed definition with more rigidly defined terms.

  10. GaryQian commented on Jan 29, 2019

    @GaryQian
    ContributorAuthor

    flutter/assets-for-api-docs#54 Generate diagrams and examples for strut.

  11. GaryQian commented on Jan 30, 2019

    @GaryQian
    ContributorAuthor

    Status update: Approved and tests pass locally, looking for a window to land changes after build bots are fixed.

  12. GaryQian commented on Feb 4, 2019

    @GaryQian
    ContributorAuthor

    Strut landed. Beginning implementation of fixes that use strut.

  13. GaryQian commented on Feb 8, 2019

    @GaryQian
    ContributorAuthor

    #27612 Force line height in TextFields with strut
    and
    flutter-team-archive/engine#7734 Use all font managers to discover fonts for strut.
    make use of strut to fix textfield height/clipping bugs.

  14. GaryQian commented on Feb 13, 2019

    @GaryQian
    ContributorAuthor

    The CJK text clipping issue seems to go away once strut is introduced as the first line is by default locked to what is calculated as the "preferredLineHeight". This prevents the larger CJK fonts from shifting the entire text block too low, which was the cause of the clipping before.

  15. figo-fe commented on Mar 6, 2019

    @figo-fe

    I found it is still not work in stable-1.2.1(Android 9.0), What else need to do? I tried to add strut but it is not supported...
    Can you show me a demo? Thanks! @GaryQian

    TextField(
      autofocus: true,
      textInputAction: TextInputAction.search,
      decoration: InputDecoration.collapsed(
        hintText: '请输入关键词',
      ),
      style: TextStyle(fontSize: 14),
      onSubmitted: (word) {
        doSearch(word);
      },
    )
    

    image

  16. GaryQian commented on Mar 6, 2019

    @GaryQian
    ContributorAuthor

    The strut integration into textfields (#27612) was landed after strut in general was landed. This means that it did not make the 1.2.1 release. From the releases tab, it looks like the feature made it into 1.3.0, which should be available on the beta, dev and master channels.

  17. GaryQian commented on Mar 6, 2019

    @GaryQian
    ContributorAuthor

    Since the primary issues with strut have been resolved, I will close this issue for now, and address the remaining straggling components independently.

  18. github-actions commented on Aug 14, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  19. locked as resolved and limited conversation to collaborators on Aug 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

a: text inputEntering text in a text field or keyboard related problemsa: typographyText rendering, possibly libtxtengineflutter/engine related. See also e: labels.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions