Skip to content

Force line height in TextFields with strut#27612

Merged
GaryQian merged 37 commits intoflutter:masterfrom
GaryQian:textfield
Feb 23, 2019
Merged

Force line height in TextFields with strut#27612
GaryQian merged 37 commits intoflutter:masterfrom
GaryQian:textfield

Conversation

@GaryQian
Copy link
Contributor

@GaryQian GaryQian commented Feb 6, 2019

Fixes #20183

This uses strut to force line heights to stay consistent even when taller glyphs are typed. This guarantees the TextField height is large enough to contain the text as well as prevents clipping of the text.

When not explicitly provided, the strut is derived from the TextStyle of the textfield. Strut can be completely disabled by passing StrutStyle.disabled(), which will have the effect of no strut at all.

Since CJK fonts are frequently taller than alphanumeric fonts, Textfields with the font set to alphanumeric fonts tend to experience less line spacing between CJK text than usual. The opposite is also true, where alphanumeric text will see more line spacing than normal when a CJK font is set.

git log --oneline --no-merges 33bb91c..21c5919
21c5919 [re-land] Use all font managers to discover fonts for strut. (#7803)
5809ade Make the layout of dynamic patch bundle similar to APK. (#7925)
e2a449a Move canvas clear after preroll (#7923)
8529dbc Remove unused FML file export.h (#7926)
f80928a Roll src/third_party/skia fdd15284affe..ee1c8a733e5b (15 commits) (#7924)
93f339f fix Memory leak when using PlatformView [IOS] #24714 (#7919)
2d33e77 Roll src/third_party/skia 969659dbb313..fdd15284affe (2 commits) (#7922)
6d4edf2 Roll src/third_party/skia 9431161ca973..969659dbb313 (3 commits) (#7921)

@zoechi zoechi added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. f: cupertino flutter/packages/flutter/cupertino repository a: typography Text rendering, possibly libtxt labels Feb 7, 2019
GaryQian added a commit to flutter/goldens that referenced this pull request Feb 7, 2019
@GaryQian
Copy link
Contributor Author

GaryQian commented Feb 7, 2019

Requires engine roll with flutter/engine#7734 to pass tests.

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. Some of the test are a little hard to judge because the relationship between the vertical dimensions they're checking and the text style etc isn't obvious.

@GaryQian
Copy link
Contributor Author

GaryQian commented Feb 8, 2019

This change depends on flutter/engine#7734 and will include an engine roll.

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

/// Equivalent to having no strut at all. All lines will be laid out according to
/// the properties defined in [TextStyle].
///
/// Default strut is not the same as [StrutStyle.disabled].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that you mean StrutStyle.disabled != StrutStyle().

This line is a little confusing; maybe it doesn't bear saying at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the distinction is between omitting it and having it inherit vs passing [StrutStyle.disabled]. I guess if they dont disable it, it isnt particularly jarring as it doesnt have any direct impact that would be visible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But yeah, it would be inherently true that there was a difference or else it wouldnt exist (in a well designed API at least). I'll remove it.

/// to lock all lines to the height of the base [TextStyle], provided by
/// [style]. This ensures the typed text fits within the alotted space.
///
/// If null, the strut used will is inherit values from the [style] and will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If null, a [StrutStyle] based on [style], with [StrutStyle.forceStrutHeight] set to true, will be used. If [style] is null (the default) then the theme's [TextStyle] will be used instead.

However: we don't seem to be defaulting style to the theme's style?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior is actually inherited from the TextStyle taking the theme's style, which the StrutStyle then in turn inherits.

/// instead.
///
/// To disable strut-based vertical alignment and allow dynamic vertical
/// layout based on the glyphs typed, passing [StrutStyle.disabled] will
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passing [StrutStyle.disabled] will make strut take no effect => use [StrutStyle]


expect(
tester.getSize(find.byType(CupertinoTextField)),
const Size(200, 63), // 29 is the height of the default font * 3 (17 * 3) + decoration (12).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NICE. Thanks for these explanations!

Copy link
Contributor

@matthew-carroll matthew-carroll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More comments to come...our Cupertino review meeting ran out of time.

///
/// To disable strut-based vertical alignment and allow dynamic vertical
/// layout based on the glyphs typed, use [StrutStyle.disabled].
/// {@endtemplate}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind adding a URL reference to something that explains the concept of a strut in general? It's an odd name for those that are not already familiar with it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can put a link to https://www.w3.org/TR/CSS2/visudet.html#line-height in the docs for StrutStyle. Sticking the link everywhere strut is used might cause a bit too much clutter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just recommending that it be added to this template. The other places where this template appears is likely to be the first and only interaction most developers have with this concept, so it seemed like a good place for an external reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://en.wikipedia.org/wiki/Strut_(typesetting) may also be a good more generic albeit brief reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh my bad, missed that this was the template! That's a good idea.

}
final CupertinoThemeData themeData = CupertinoTheme.of(context);
final TextStyle textStyle = widget.style ?? themeData.textTheme.textStyle;
final TextStyle textStyle = themeData.textTheme.textStyle.merge(widget.style);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is technically a breaking change. Can you elaborate on why this was changed? Also, do you plan to announce this breaking change when merged?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I should talk to someone more familiar with Cupertino about the exact desired behavior here. This is the behavior in material, and the way strut inherits the textStyle's properties is dependent on the textstyle being complete.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked with xster and we have agreed the change here is reasonable. I have sent a breaking change announce out and added the API break tag. The change here should be minor and can be bypassed with the inherit: false parameter in TextStyle

}

@override
String toStringShort() => '$runtimeType';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason that this is the desired behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was based around the same override in text_style.dart:935 where presumably, the full toString that includes all of the properties, is often times too long and makes output unreadable. A similar argument can be applied to StrutStyle, which also contains a large number of potentially cluttering properties that are not necessarily relevant in the short version of the toString.

@GaryQian GaryQian added the c: API break Backwards-incompatible API changes label Feb 20, 2019
@GaryQian GaryQian merged commit 7b5a769 into flutter:master Feb 23, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: text input Entering text in a text field or keyboard related problems a: typography Text rendering, possibly libtxt c: API break Backwards-incompatible API changes f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TextField, Enter Chinese in android device ,The bottom is cut

6 participants