-
Notifications
You must be signed in to change notification settings - Fork 6k
Expose LineMetrics in dart:ui #10670
Conversation
| } | ||
|
|
||
| /// Data class that holds the metrics for a single line in the [Paragraph]. | ||
| class LineMetrics { |
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.
Add this class to stub ui and file an issue to implement for the web
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// | ||
| /// This can potentially return a large amount of data, so it is not recommended | ||
| /// to repeatedly call this. Instead, cache the results. | ||
| List<LineMetrics> getLineMetrics(); |
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.
These will need implementations in the _engine sub directory. In this case I would return an empty list similar to what the implementation for getBoxesForPlaceholders does.
cc @yjbanov
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 me know if any of the metrics here are difficult to obtain for web. Some of them are quite libtxt/skia specific. I can still remove some of them easily without hurting functionality too much.
cc @mdebbar
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.
lib/stub_ui/lib/src/ui/text.dart
Outdated
| this.lineNumber, | ||
| List<RunMetrics> rMetrics, | ||
| List<int> rMetricsIndexes, | ||
| ) : runMetrics = Map() { |
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 it possible to use an immutable map here? If it's too expensive, we could use an immutable map in debug builds and a regular map in profile/release builds.
| /// metrics of each laid out line. | ||
| /// | ||
| /// This can potentially return a large amount of data, so it is not recommended | ||
| /// to repeatedly call this. Instead, cache the results. |
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 value available prior to calling layout? If not, let's document that.
Does the value depend on ParagraphConstraints passed to the layout method? If not, we could cache right here and not scare the user with the large amount of data disclaimer. Actually, even if it does depend on the ParagraphConstratins, we can still cache and invalidate the cache next time layout is called.
lib/ui/text/line_metrics.h
Outdated
| // Zero indexed line number. | ||
| size_t line_number = 0; | ||
|
|
||
| std::map<size_t, txt::RunMetrics> run_metrics; |
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.
The fields are immutable in Dart. Do they have to be publicly mutable in the engine?
lib/ui/text/paragraph.cc
Outdated
| } | ||
|
|
||
| std::vector<LineMetrics> Paragraph::getLineMetrics() { | ||
| return m_paragraphImpl->getLineMetrics(); |
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 seems to be doing a lot of copying.
lib/ui/text/paragraph.h
Outdated
| std::vector<TextBox> getRectsForPlaceholders(); | ||
| Dart_Handle getPositionForOffset(double dx, double dy); | ||
| Dart_Handle getWordBoundary(unsigned offset); | ||
| std::vector<LineMetrics> getLineMetrics(); |
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 looks like an expensive data structure, because it doesn't use pointers. Passing it around would involve, copying the vector, copying each LineMetrics object, and recursively copying std::map<size_t, txt::RunMetrics> that's inside it.
|
|
||
| namespace flutter { | ||
|
|
||
| struct LineMetrics { |
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.
Docs? For example, it would be interesting to know why the memory layout is chosen to be flat.
lib/ui/text.dart
Outdated
| this.lineNumber, | ||
| List<RunMetrics> rMetrics, | ||
| List<int> rMetricsIndexes, | ||
| ) : runMetrics = Map() { |
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.
use Map.fromIterables(rMetricsIndexes, rMetrics)
lib/ui/text.dart
Outdated
| } | ||
| } | ||
|
|
||
| /// The index in the text buffer the line begins. |
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.
change this to "where the line begins" (same for endIndex, endExcludingWhitespace, endIncludingNewline)
| txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection()); | ||
|
|
||
| txt::TextStyle text_style; | ||
| // We must supply a font here, as the default is Arial, and we do not |
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 remove this comment. This test seems similar to most other paragraph unit test which use Roboto because it is available as a test font.
goderbauer
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.
Reviewed the dart files
|
|
||
| /// Data class that holds the metrics for a single line in the [Paragraph]. | ||
| class LineMetrics { | ||
|
|
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: remove empty line
lib/stub_ui/lib/src/ui/text.dart
Outdated
| } | ||
| } | ||
|
|
||
| /// The index in the text buffer the line begins. |
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 missing a "where" or some word like it before "the line begins"?
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.
(Same comment for many of the following docs).
lib/stub_ui/lib/src/ui/text.dart
Outdated
| this.lineNumber, | ||
| List<RunMetrics> rMetrics, | ||
| List<int> rMetricsIndexes, | ||
| ) : runMetrics = Map() { |
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.
| ) : runMetrics = Map() { | |
| ) : runMetrics = <int, RunMetrics>{} { |
lib/stub_ui/lib/src/ui/text.dart
Outdated
| List<int> rMetricsIndexes, | ||
| ) : runMetrics = Map() { | ||
| for (int i = 0; i < rMetrics.length; ++i) { | ||
| runMetrics[rMetricsIndexes[i]] = rMetrics[i]; |
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 Map.fromIterables be helpful here at all?
lib/stub_ui/lib/src/ui/text.dart
Outdated
| } | ||
| } | ||
|
|
||
| /// The index in the text buffer the line begins. |
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.
(maybe this is clear from context where this will be used, but...)
While reading through these API docs I kept wondering what "the test buffer" is that's mentioned here over and over.
lib/stub_ui/lib/src/ui/text.dart
Outdated
|
|
||
| /// Extent above baseline. | ||
| final double top; | ||
| /// Distance to reserve above baseline. |
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.
insert empty line after each property?
lib/stub_ui/lib/src/ui/text.dart
Outdated
| final double top; | ||
| /// Distance to reserve above baseline. | ||
| /// | ||
| /// Since this is the raw metric from the font, [ascent] is usually negative. |
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 only true for ascent? Or also for some of the other metrics here?
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 me double check, but it may also apply to top, although we dont track top separately so an abs is never applied to it.
lib/stub_ui/lib/src/ui/text.dart
Outdated
| final double avgCharWidth; | ||
| /// Maximum character width. | ||
| final double maxCharWidth; | ||
| /// Minimum x. |
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.
What's x?
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.
That is a good question, I am not totally sure myself, but I will find out. This is one of the metrics from SkFontMetrics, but we don't seem to use it anywhere. It is provided to us nonetheless.
There is some ambiguous naming going on where X refers to x-coordinate as well as x the ascii letter. I can try to clarify this in our API.
lib/stub_ui/lib/src/ui/text.dart
Outdated
| final double capHeight; | ||
| /// Underline thickness. | ||
| /// | ||
| /// Can be null. |
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.
When is it null, can we say?
(same for other properties)
lib/ui/text.dart
Outdated
| middle, | ||
| } | ||
|
|
||
| /// Data class that holds the metrics for a single line in the [Paragraph]. |
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.
All comments I made on the previous file also apply here.
@jonahwilliams I thought we no longer repeat doc comments in the stub impl... Is the doc comment duplication still necessary?
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.
You don't need to repeat doc comments.
That said, I'm not enforcing this via a lint until there is an unfork, because the code in stub_ui is not the source of truth.
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.
@GaryQian Can you remove the comments from the stubs then?
|
@GaryQian Heads up! I just pushed a change that renamed |
lib/stub_ui/lib/src/ui/text.dart
Outdated
| } | ||
| } | ||
|
|
||
| /// The index in the text buffer the line begins. |
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.
what is this index? number of UTF-16 words?
We shouldn't add any new APIs that use UTF-16 word counts.
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// This is equivalent to `ascent + descent` | ||
| final double height; | ||
|
|
||
| /// Width of the line. |
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 documentation violates our style guide
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// The right edge can be obtained with `left + width`. | ||
| final double left; | ||
|
|
||
| /// The y position of the baseline for this line from the top of the paragraph. |
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 be consistent in our style here: x-coordinate, y position, etc. Maybe see what we do today in the framework (e.g. it might be _x_ coordinate)
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// The y position of the baseline for this line from the top of the paragraph. | ||
| final double baseline; | ||
|
|
||
| /// Zero indexed line number. |
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.
"Zero indexed line number" tells me nothing really. What is a line number?
Maybe "The number of this line in the overall paragraph, with the first line being index zero" or something?
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// | ||
| /// Each entry will be keyed under the ending index the run applies to. Each | ||
| /// [RunMetrics] entry corresponds to the text covered by the range of | ||
| /// `[previous key, current key)`. For a given index `i`, the [RunMetrics] |
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.
generally speaking many of our developers don't know the [/( ... )/] convention. Please be explicit in prose instead.
| class LineMetrics { | ||
|
|
||
| @pragma('vm:entry-point') | ||
| LineMetrics._( |
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 this constructor have to be private?
Might be worth having this be a public constructor with named arguments and having a private constructor with positional arguments for calling from C++. Having a way to create this class from Dart seems valuable (e.g. for testing).
lib/stub_ui/lib/src/ui/text.dart
Outdated
| final Map<int, RunMetrics> runMetrics; | ||
| } | ||
|
|
||
| /// Data class that tracks the raw font metrics for a particular text buffer index. |
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.
what is a "Data class"?
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// Data class that tracks the raw font metrics for a particular text buffer index. | ||
| class RunMetrics { | ||
| @pragma('vm:entry-point') | ||
| RunMetrics._( |
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.
same comment about constructors
| /// | ||
| /// Can be null. | ||
| final double strikeoutPosition; | ||
| } |
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.
these docs all need much more detail. see the style guide for writing prompts.
lib/stub_ui/lib/src/ui/text.dart
Outdated
| /// | ||
| /// This can potentially return a large amount of data, so it is not recommended | ||
| /// to repeatedly call this. Instead, cache the results. | ||
| List<LineMetrics> getLineMetrics(); |
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 call this computeLineMetrics to make it sound expensive. Things called getFoo should really be getters, and those look cheap.
|
Status Update: This is on hold momentarily as I fix a segfault in the tracking of the metrics in LibTxt. Next, I'll strip this down to minimize UTF-16 index usage in anticipation for dart's updated text system. |
|
Waiting on #11064 to land in order to continue on this. |
|
Ok, this simplified version should be ready for another round of review. We no longer track anything that is connected to or indexed by UTF-16 codepoints. This means the |
goderbauer
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 for the .dart files with some minor nits
| middle, | ||
| } | ||
|
|
||
| class LineMetrics { |
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.
Add a doc comment for the class and constructor?
lib/ui/text.dart
Outdated
| /// The [ascent] is provided as a positive value, even though it is typically defined | ||
| /// in fonts as negative. This is to ensure the signage of operations with these | ||
| /// metrics directly reflects the intended signage of the value. For example, | ||
| /// the y coordinate of the top edge of the line is 'baseline - ascent`. |
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.
should ' be a `?
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.
Same question everywhere below.
lib/ui/text.dart
Outdated
| this.left = null, | ||
| this.baseline = null, | ||
| this.lineNumber = null, | ||
| }) {} |
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 should just be : instead of {}
lib/ui/text.dart
Outdated
| this.left, | ||
| this.baseline, | ||
| this.lineNumber, | ||
| ) {} |
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.
same.
lib/ui/text.dart
Outdated
|
|
||
| class LineMetrics { | ||
| LineMetrics({ | ||
| this.hardBreak = null, |
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 the = null here? That's the default.
lib/ui/text.dart
Outdated
| middle, | ||
| } | ||
|
|
||
| /// `LineMetrics` stores the measurements and statistics of a single line in the |
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 should be enclosed in [] instead of `
lib/ui/text.dart
Outdated
| /// extent of the line instead of per-run or per-glyph metrics. For more detailed | ||
| /// metrics, see [TextBox] and [Paragraph.getBoxesForRange]. | ||
| /// | ||
| /// `LineMetrics` should be obtained directly from the [Paragraph.computeLineMetrics] |
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.
Same here.
[email protected]:flutter/engine.git/compare/ba1a303ae2d7...9f1eab2 git log ba1a303..9f1eab2 --no-merges --oneline 2019-08-26 [email protected] Expose LineMetrics in dart:ui (flutter/engine#10670) 2019-08-26 [email protected] Roll buildroot and update gn script for bitcode_marker (flutter/engine#11449) 2019-08-26 [email protected] Roll src/third_party/skia d617d5d29ca5..464eb78e444b (10 commits) (flutter/engine#11444) 2019-08-26 [email protected] Roll fuchsia/clang/mac-amd64 from RDjN2... to CGYQg... (flutter/engine#11442) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected] on the revert to ensure that a human is aware of the problem. To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md
This PR performs the tonic/custom transition for the new LibTxt metrics between native and dart.
Part of a series of changes to fix flutter/flutter#35994
Adds
getLineMetrics()todart:ui Paragraph. This is a catch-all "return all of the metrics at once" call that is a good point to start.This blanket method will provide full access to the data we track. I am currently considering adding additional API to slice the data into more manageable chunks so that the data required can be queried more directly, reducing the amount of unused data passed through tonic.
The dart:ui tests will reside in the framework test suite due to a lack of direct dart:ui testing setup and will be in a separate PR (I will link shortly).