-
Notifications
You must be signed in to change notification settings - Fork 6k
TextStyle level leadingDistribution #24025
TextStyle level leadingDistribution #24025
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
| : metrics_font_height + metrics.fLeading; | ||
|
|
||
| // Scale the ascent and descent such that the sum of ascent and | ||
| // descent is `style.height * style.font_size`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Diff 1/2: fontsize * style.height * style.font_size -> style.height * style.font_size
| // https://glyphsapp.com/tutorials/vertical-metrics | ||
| // | ||
| // Doing this ascent/descent normalization to the EM Square allows | ||
| // a sane, consistent, and reasonable "blob_height" to be specified, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Diff 2/2: "text height" -> "blob_height"
| : (paragraph_style_.strut_leading * | ||
| paragraph_style_.strut_font_size); | ||
|
|
||
| const double available_height = paragraph_style_.strut_text_height_behavior & TextHeightBehavior::kHalfLeading |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not default to paragraphStyle.textHeightBehavior (or should it?)
| const double font_height = | ||
| shouldNormalizeFont ? style.font_size : metrics_font_height; | ||
|
|
||
| const size_t text_height_behavior = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defaults to ParagraphStyle.textHeightBehavior if TextStyle.textHeightBehavior is not specified.
In the framework TextPainter does not (directly) have a height multiplier field, but currently has a textHeightBehavior field. With this implementation TextPainter.textHeightBehavior has the lowest precedence in the textHeightBehavior defaulting rules.
lib/ui/text.dart
Outdated
|
|
||
| /// {@macro dart.ui.leadingDistribution} | ||
| enum LeadingDistribution { | ||
| /// Distributes the ["leading"](https://www.w3.org/TR/CSS2/visudet.html#leading) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's link to https://en.wikipedia.org/wiki/Leading rather than the CSS spec though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to avoid using the term altogether then? The Wikipedia page says "the exact definition varies", and "In electronic typesetting, "leading" often instead means the distance from one baseline to the next. ".
lib/ui/text.dart
Outdated
| /// font's ascent/discent ratio. | ||
| /// | ||
| /// {@template dart.ui.leading} | ||
| /// The leading space of a text run is defined as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"leading" is a noun, not an adjective. (It's pronounced like the metal Pb, as opposed to like the opposite of "following")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(which is to say, it's "the leading", not "the leading space".)
lib/ui/text.dart
Outdated
| 'letterSpacing: ${ _encoded[0] & 0x00800 == 0x00800 ? "${_letterSpacing}x" : "unspecified"}, ' | ||
| 'wordSpacing: ${ _encoded[0] & 0x01000 == 0x01000 ? "${_wordSpacing}x" : "unspecified"}, ' | ||
| 'height: ${ _encoded[0] & 0x02000 == 0x02000 ? "${_height}x" : "unspecified"}, ' | ||
| 'textHeightBehavior: ${ _encoded[0] & 0x0100 == 0x0100 ? "${TextHeightBehavior.fromEncoded(_encoded[8])}x" : "unspecified"}, ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i suspect the "x" here is a copy/paste typo?
third_party/txt/src/txt/text_style.h
Outdated
| // Multiple behaviors can be applied at once with a bitwise | operator. For | ||
| // example, disabling first ascent and last descent can achieved with: | ||
| // | ||
| // (kDisableFirstAscent | kDisableLastDescent). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should update the docs to mention half-leading too
|
glancing through this it seems reasonable. (didn't do a detailed review) |
b2c3923 to
547fc9e
Compare
547fc9e to
63f5fbf
Compare
94606b1 to
b703222
Compare
426ba83 to
d6c9f49
Compare
johnsonmh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
| List<String>? fontFamilyFallback, | ||
| double? fontSize, | ||
| double? height, | ||
| //TODO(LongCatIsLooong): implement textHeightBehavir. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: textHeightBehavior, or maybe this comment should be removed entirely?
| const double leading = | ||
| text_height_behavior & TextHeightBehavior::kHalfLeading | ||
| ? blob_height - font_height | ||
| : style.has_height_override ? 0.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't quite figure out this part of the ternary. This 0.0 will be hit when: "if not half leading, and style has a height override, then leading == 0"? Is that because we don't consider there to be any "leading" with AD scaling, instead of adding leading we just stretch the ascent and descent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note and totally personal preference so feel free to ignore: it takes me a few extra seconds to parse the nested ternary, I personally would find something like this easier to read:
if (halfLeading) {
leading = blob_height - font_height;
else {
leading = style.has_height_override ? 0.0 : metrics.fLeading;
}| half_leading; | ||
| double ascent = disableAscent ? -metrics.fAscent : modifiedAscent; | ||
| double descent = disableDescent ? metrics.fDescent | ||
| //: blob_height - leading - modifiedAscent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should probably be removed.
| double ascent = disableAscent ? -metrics.fAscent : modifiedAscent; | ||
| double descent = disableDescent ? metrics.fDescent | ||
| //: blob_height - leading - modifiedAscent; | ||
| : metrics.fDescent / metrics_font_height * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, consider putting this in a double called modifiedDescent.
| code_unit_runs_.clear(); | ||
| inline_placeholder_code_unit_runs_.clear(); | ||
| max_right_ = FLT_MIN; | ||
| max_right_ = -FLT_MAX; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with what this does, is this change related/required by the current change? Will it have any side effects, or is FLT_MIN always the - of FLT_MAX?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the documentation FLT_MIN is the smallest positive double (that's not 0). I had to change this for some strut related stuff so descent can go negative. Some of other occurrences may not be directly related to this change but they all seem to make more sense with -FLT_MAX.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - I think all of these initializers should have been -FLT_MAX. They are all used in std::max(current_value, new_value) expressions, and the goal is to ensure that any new_value is greater than the initialized current_value.
Another option would be using std::numeric_limits<double>::lowest()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switched to std::numeric_limits as they all seem to be doubles.
| if (has_text_height_behavior_override != | ||
| other.has_text_height_behavior_override) | ||
| return false; | ||
| if (has_text_height_behavior_override && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just text_height_behavior != other.text_height_behavior?
|
@Hixie Are you still planning on the detailed review? |
|
Looks like the presubmit failure is real. The test needs to be updated. |
b5fba22 to
45964a1
Compare
|
Updated the PR to:
|
|
Ready for review. |
lib/ui/text.dart
Outdated
| } | ||
|
|
||
| /// {@macro dart.ui.leadingDistribution} | ||
| enum LeadingDistribution { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional, but it seems that most text related enums/classes are prefixed with Text.
I don't have a particularly strong conviction either way, but It would also be reasonable to call this TextLeadingDistribution for consistency. That being said, as far as I know, the concept of leading is unique to text layout, so this naming should be sufficient (currently) to identify the feature uniquely.
| /// height after layout to be taller than specified here. The `fontSize` must | ||
| /// be provided for this property to take effect. | ||
| /// | ||
| /// * `leading`: The minimum amount of leading between lines as a multiple of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want to improve documentation on this property as well to better distinguish it, since there are now two similarly named properties right next to each other.
| kDisableFirstAscent = 0x1, | ||
| kDisableLastDescent = 0x2, | ||
| kDisableAll = 0x1 | 0x2, | ||
| kHalfLeading = 0x1 << 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer consistent naming in the engine and the framework. This was called even in framework. Two names for the same property makes this much more confusing to read and maintain.
1843fce to
f3e74f4
Compare
johnsonmh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| List<String>? fontFamilyFallback, | ||
| double? fontSize, | ||
| double? height, | ||
| //TODO(LongCatIsLooong): implement leadingDistribution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this TODO meant to be here? It looks like this is implemented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by that I meant currently setting leadingDistribution doesn't do anything on web and it needs to be implemented.
* 4f660da Roll Dart SDK from 63c6585d8499 to 6b7054122356 (1 revision) (flutter/engine#24625) * 25887bc Roll Skia from e79bb32365ea to 4ac9aadd306b (4 revisions) (flutter/engine#24630) * 1bdf5d3 TextStyle level leadingDistribution (flutter/engine#24025) * c4678d6 Fix input flow event logic (flutter/engine#24526)
This reverts commit 1bdf5d3.
… in flutter#24665 This reverts commit 6191270.
The framework failure seems to be caused by some
toStringchanges.I'll check with Christian and see if this produces the correct graphics.
Screencast
TextSpans rendered side by side: "firstTextRunljx" and "secondTextRunljx".TextSpans occupied as seen by the frameworkexample.mp4
TODO (after this PR)
Pre-launch Checklist
writing and running engine tests.
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.