-
Notifications
You must be signed in to change notification settings - Fork 2k
Add Galley::intrinsic_size and use it in AtomLayout
#7146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3e07862
cd3ac65
f44b50a
cdea02f
6ddac6a
b4929ec
abc2467
bf95df2
64296db
2b371d6
817109e
8b40114
60e8baf
a93b0a9
0981aac
b2e85e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -82,6 +82,7 @@ pub fn layout(fonts: &mut FontsImpl, job: Arc<LayoutJob>) -> Galley { | |||
| num_indices: 0, | ||||
| pixels_per_point: fonts.pixels_per_point(), | ||||
| elided: true, | ||||
| intrinsic_size: Vec2::ZERO, | ||||
| }; | ||||
| } | ||||
|
|
||||
|
|
@@ -94,6 +95,8 @@ pub fn layout(fonts: &mut FontsImpl, job: Arc<LayoutJob>) -> Galley { | |||
|
|
||||
| let point_scale = PointScale::new(fonts.pixels_per_point()); | ||||
|
|
||||
| let intrinsic_size = calculate_intrinsic_size(point_scale, &job, ¶graphs); | ||||
|
|
||||
| let mut elided = false; | ||||
| let mut rows = rows_from_paragraphs(paragraphs, &job, &mut elided); | ||||
| if elided { | ||||
|
|
@@ -124,7 +127,7 @@ pub fn layout(fonts: &mut FontsImpl, job: Arc<LayoutJob>) -> Galley { | |||
| } | ||||
|
|
||||
| // Calculate the Y positions and tessellate the text: | ||||
| galley_from_rows(point_scale, job, rows, elided) | ||||
| galley_from_rows(point_scale, job, rows, elided, intrinsic_size) | ||||
| } | ||||
|
|
||||
| // Ignores the Y coordinate. | ||||
|
|
@@ -190,6 +193,46 @@ fn layout_section( | |||
| } | ||||
| } | ||||
|
|
||||
| /// Calculate the intrinsic size of the text. | ||||
| /// | ||||
| /// The result is eventually passed to `Response::intrinsic_size`. | ||||
| /// This works by calculating the size of each `Paragraph` (instead of each `Row`). | ||||
| fn calculate_intrinsic_size( | ||||
| point_scale: PointScale, | ||||
| job: &LayoutJob, | ||||
| paragraphs: &[Paragraph], | ||||
| ) -> Vec2 { | ||||
| let mut intrinsic_size = Vec2::ZERO; | ||||
| for (idx, paragraph) in paragraphs.iter().enumerate() { | ||||
| if paragraph.glyphs.is_empty() { | ||||
| if idx == 0 { | ||||
| intrinsic_size.y += point_scale.round_to_pixel(paragraph.empty_paragraph_height); | ||||
| } | ||||
| continue; | ||||
| } | ||||
| intrinsic_size.x = f32::max( | ||||
| paragraph | ||||
| .glyphs | ||||
| .last() | ||||
| .map(|l| l.max_x()) | ||||
| .unwrap_or_default(), | ||||
| intrinsic_size.x, | ||||
| ); | ||||
|
|
||||
| let mut height = paragraph | ||||
| .glyphs | ||||
| .iter() | ||||
| .map(|g| g.line_height) | ||||
| .max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)) | ||||
| .unwrap_or(paragraph.empty_paragraph_height); | ||||
| if idx == 0 { | ||||
| height = f32::max(height, job.first_row_min_height); | ||||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add a test for this in egui/crates/epaint/src/text/fonts.rs Line 1079 in f46926a
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw your comment in #7146 (comment) - let's do that in a follow-up PR then :) |
||||
| } | ||||
| intrinsic_size.y += point_scale.round_to_pixel(height); | ||||
| } | ||||
| intrinsic_size | ||||
| } | ||||
|
|
||||
| // Ignores the Y coordinate. | ||||
| fn rows_from_paragraphs( | ||||
| paragraphs: Vec<Paragraph>, | ||||
|
|
@@ -610,6 +653,7 @@ fn galley_from_rows( | |||
| job: Arc<LayoutJob>, | ||||
| mut rows: Vec<PlacedRow>, | ||||
| elided: bool, | ||||
| intrinsic_size: Vec2, | ||||
| ) -> Galley { | ||||
| let mut first_row_min_height = job.first_row_min_height; | ||||
| let mut cursor_y = 0.0; | ||||
|
|
@@ -680,6 +724,7 @@ fn galley_from_rows( | |||
| num_vertices, | ||||
| num_indices, | ||||
| pixels_per_point: point_scale.pixels_per_point, | ||||
| intrinsic_size, | ||||
| }; | ||||
|
|
||||
| if galley.job.round_output_to_gui { | ||||
|
|
||||
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
if-statement even needed? Seems like the logic below should be robust to handling this regardless? In fact, more robust, since the code below takesfirst_row_min_heightinto accountThere 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, otherwise the test_split_paragraphs test fails. (I explained why in this comment in case you didn't see it #7146 (comment))
I'll try to fix this in a separate PR.
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.
Nice, thanks!