mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 21:00:03 -04:00
Move ends_with_newline back into Row
This commit is contained in:
@@ -739,7 +739,9 @@ impl GalleyCache {
|
||||
let mut text_left = job.text.as_str();
|
||||
let mut first_row_min_height = job.first_row_min_height;
|
||||
loop {
|
||||
let end = text_left.find('\n').map_or(job.text.len(), |i| i + current);
|
||||
let end = text_left
|
||||
.find('\n')
|
||||
.map_or(job.text.len(), |i| i + current + 1);
|
||||
let start = current;
|
||||
|
||||
let mut line_job = LayoutJob {
|
||||
@@ -749,8 +751,7 @@ impl GalleyCache {
|
||||
..job.wrap
|
||||
},
|
||||
sections: Vec::new(),
|
||||
// Prevent an infinite recursion
|
||||
break_on_newline: false,
|
||||
break_on_newline: true,
|
||||
halign: job.halign,
|
||||
justify: job.justify,
|
||||
first_row_min_height,
|
||||
@@ -782,28 +783,14 @@ impl GalleyCache {
|
||||
current = section_end;
|
||||
}
|
||||
|
||||
// If the current line is empty, add an extra offset to make sure it's not omitted
|
||||
// because the resulting galley will have a height of zero.
|
||||
let extra_y_offset = if start == end && end != job.text.len() {
|
||||
while job.sections[current_section].byte_range.end == end {
|
||||
current_section += 1;
|
||||
}
|
||||
let format = &job.sections[current_section].format;
|
||||
format
|
||||
.line_height
|
||||
.unwrap_or(fonts.row_height(&format.font_id))
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
let galley = self.layout(fonts, line_job);
|
||||
let galley = self.layout_component_line(fonts, line_job);
|
||||
// This will prevent us from invalidating cache entries unnecessarily
|
||||
if left_max_rows != usize::MAX {
|
||||
left_max_rows -= galley.rows.len();
|
||||
}
|
||||
galleys.push((galley, extra_y_offset));
|
||||
galleys.push(galley);
|
||||
|
||||
current = end + 1;
|
||||
current = end;
|
||||
if current >= job.text.len() {
|
||||
break;
|
||||
} else {
|
||||
@@ -822,29 +809,30 @@ impl GalleyCache {
|
||||
pixels_per_point: fonts.pixels_per_point,
|
||||
};
|
||||
|
||||
for (galley, extra_y_offset) in galleys {
|
||||
for (i, galley) in galleys.iter().enumerate() {
|
||||
let current_offset = emath::vec2(0.0, merged_galley.rect.height());
|
||||
merged_galley
|
||||
.rows
|
||||
.extend(galley.rows.iter().map(|placed_row| {
|
||||
let new_pos = placed_row.pos + current_offset;
|
||||
merged_galley.mesh_bounds = merged_galley
|
||||
.mesh_bounds
|
||||
.union(placed_row.visuals.mesh_bounds.translate(new_pos.to_vec2()));
|
||||
|
||||
super::PlacedRow {
|
||||
row: placed_row.row.clone(),
|
||||
pos: round_to_pixel(new_pos),
|
||||
ends_with_newline: placed_row.ends_with_newline,
|
||||
}
|
||||
}));
|
||||
if let Some(last) = merged_galley.rows.last_mut() {
|
||||
last.ends_with_newline = true;
|
||||
let mut rows = galley.rows.iter();
|
||||
if i != galleys.len() - 1 && !galley.elided {
|
||||
let popped = rows.next_back();
|
||||
debug_assert_eq!(popped.unwrap().row.glyphs.len(), 0);
|
||||
}
|
||||
merged_galley.rect = merged_galley
|
||||
.rect
|
||||
.union(galley.rect.translate(current_offset));
|
||||
merged_galley.rect.max.y += extra_y_offset;
|
||||
|
||||
merged_galley.rows.extend(rows.map(|placed_row| {
|
||||
let new_pos = round_to_pixel(placed_row.pos + current_offset);
|
||||
merged_galley.mesh_bounds = merged_galley
|
||||
.mesh_bounds
|
||||
.union(placed_row.visuals.mesh_bounds.translate(new_pos.to_vec2()));
|
||||
merged_galley.rect = merged_galley
|
||||
.rect
|
||||
.union(emath::Rect::from_min_size(new_pos, placed_row.size));
|
||||
|
||||
super::PlacedRow {
|
||||
row: placed_row.row.clone(),
|
||||
pos: new_pos,
|
||||
}
|
||||
}));
|
||||
|
||||
merged_galley.num_vertices += galley.num_vertices;
|
||||
merged_galley.num_indices += galley.num_indices;
|
||||
if galley.elided {
|
||||
@@ -853,13 +841,30 @@ impl GalleyCache {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(last) = merged_galley.rows.last_mut() {
|
||||
last.ends_with_newline = false;
|
||||
}
|
||||
|
||||
merged_galley
|
||||
}
|
||||
|
||||
fn layout_component_line(&mut self, fonts: &mut FontsImpl, job: LayoutJob) -> Arc<Galley> {
|
||||
let hash = crate::util::hash(&job);
|
||||
|
||||
match self.cache.entry(hash) {
|
||||
std::collections::hash_map::Entry::Occupied(entry) => {
|
||||
let cached = entry.into_mut();
|
||||
cached.last_used = self.generation;
|
||||
cached.galley.clone()
|
||||
}
|
||||
std::collections::hash_map::Entry::Vacant(entry) => {
|
||||
let galley = super::layout(fonts, job.into());
|
||||
let galley = Arc::new(galley);
|
||||
entry.insert(CachedGalley {
|
||||
last_used: self.generation,
|
||||
galley: galley.clone(),
|
||||
});
|
||||
galley
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn layout(&mut self, fonts: &mut FontsImpl, mut job: LayoutJob) -> Arc<Galley> {
|
||||
if job.wrap.max_width.is_finite() {
|
||||
// Protect against rounding errors in egui layout code.
|
||||
|
||||
@@ -220,9 +220,9 @@ fn rows_from_paragraphs(
|
||||
glyphs: vec![],
|
||||
visuals: Default::default(),
|
||||
size: vec2(0.0, paragraph.empty_paragraph_height),
|
||||
ends_with_newline: !is_last_paragraph,
|
||||
}),
|
||||
pos: pos2(paragraph.cursor_x, 0.0),
|
||||
ends_with_newline: !is_last_paragraph,
|
||||
});
|
||||
} else {
|
||||
let paragraph_max_x = paragraph.glyphs.last().unwrap().max_x();
|
||||
@@ -236,13 +236,15 @@ fn rows_from_paragraphs(
|
||||
glyphs: paragraph.glyphs,
|
||||
visuals: Default::default(),
|
||||
size: rect.size(),
|
||||
ends_with_newline: !is_last_paragraph,
|
||||
}),
|
||||
pos: rect.min,
|
||||
ends_with_newline: !is_last_paragraph,
|
||||
});
|
||||
} else {
|
||||
line_break(¶graph, job, &mut rows, elided);
|
||||
rows.last_mut().unwrap().ends_with_newline = !is_last_paragraph;
|
||||
let placed_row = rows.last_mut().unwrap();
|
||||
let row = Arc::get_mut(&mut placed_row.row).unwrap();
|
||||
row.ends_with_newline = !is_last_paragraph;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,9 +290,9 @@ fn line_break(
|
||||
glyphs: vec![],
|
||||
visuals: Default::default(),
|
||||
size: rect.size(),
|
||||
ends_with_newline: false,
|
||||
}),
|
||||
pos: rect.min,
|
||||
ends_with_newline: false,
|
||||
});
|
||||
row_start_x += first_row_indentation;
|
||||
first_row_indentation = 0.0;
|
||||
@@ -316,9 +318,9 @@ fn line_break(
|
||||
glyphs,
|
||||
visuals: Default::default(),
|
||||
size: rect.size(),
|
||||
ends_with_newline: false,
|
||||
}),
|
||||
pos: rect.min,
|
||||
ends_with_newline: false,
|
||||
});
|
||||
|
||||
// Start a new row:
|
||||
@@ -359,9 +361,9 @@ fn line_break(
|
||||
glyphs,
|
||||
visuals: Default::default(),
|
||||
size: rect.size(),
|
||||
ends_with_newline: false,
|
||||
}),
|
||||
pos: rect.min,
|
||||
ends_with_newline: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,13 +546,6 @@ pub struct PlacedRow {
|
||||
|
||||
/// The position of this [`Row`] relative to the galley.
|
||||
pub pos: Pos2,
|
||||
|
||||
/// If true, this [`PlacedRow`] came from a paragraph ending with a `\n`.
|
||||
/// The `\n` itself is omitted from [`Row::glyphs`].
|
||||
/// A `\n` in the input text always creates a new [`PlacedRow`] below it,
|
||||
/// so that text that ends with `\n` has an empty [`PlacedRow`] last.
|
||||
/// This also implies that the last [`PlacedRow`] in a [`Galley`] always has `ends_with_newline == false`.
|
||||
pub ends_with_newline: bool,
|
||||
}
|
||||
|
||||
impl PlacedRow {
|
||||
@@ -586,6 +579,13 @@ pub struct Row {
|
||||
|
||||
/// The mesh, ready to be rendered.
|
||||
pub visuals: RowVisuals,
|
||||
|
||||
/// If true, this [`Row`] came from a paragraph ending with a `\n`.
|
||||
/// The `\n` itself is omitted from [`glyphs`].
|
||||
/// A `\n` in the input text always creates a new [`Row`] below it,
|
||||
/// so that text that ends with `\n` has an empty [`Row`] last.
|
||||
/// This also implies that the last [`Row`] in a [`Galley`] always has `ends_with_newline == false`.
|
||||
pub ends_with_newline: bool,
|
||||
}
|
||||
|
||||
/// The tessellated output of a row.
|
||||
|
||||
Reference in New Issue
Block a user