Skip to content

Commit

Permalink
Make Galleys share Rows and store their offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
afishhh committed Nov 28, 2024
1 parent 150c0f6 commit db32a1e
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 127 deletions.
4 changes: 2 additions & 2 deletions crates/egui/src/text_selection/accesskit_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ pub fn update_accesskit_for_text_widget(
};

ctx.with_accessibility_parent(parent_id, || {
for (row_index, row) in galley.rows.iter().enumerate() {
for (row_index, (row, offset)) in galley.rows.iter().enumerate() {
let row_id = parent_id.with(row_index);
ctx.accesskit_node_builder(row_id, |builder| {
builder.set_role(accesskit::Role::TextRun);
let rect = row.rect.translate(galley_pos.to_vec2());
let rect = row.rect.translate(offset.to_vec2() + galley_pos.to_vec2());
builder.set_bounds(accesskit::Rect {
x0: rect.min.x.into(),
y0: rect.min.y.into(),
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/text_selection/cursor_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ fn ccursor_from_accesskit_text_position(
position: &accesskit::TextPosition,
) -> Option<CCursor> {
let mut total_length = 0usize;
for (i, row) in galley.rows.iter().enumerate() {
for (i, (row, _)) in galley.rows.iter().enumerate() {
let row_id = id.with(i);
if row_id.accesskit_id() == position.node {
return Some(CCursor {
Expand Down
7 changes: 5 additions & 2 deletions crates/egui/src/text_selection/label_text_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,10 @@ impl LabelSelectionState {
if let epaint::Shape::Text(text_shape) = &mut shape.shape {
let galley = Arc::make_mut(&mut text_shape.galley);
for row_selection in row_selections {
if let Some(row) = galley.rows.get_mut(row_selection.row) {
if let Some((row, _)) =
galley.rows.get_mut(row_selection.row)
{
let row = Arc::make_mut(row);
for vertex_index in row_selection.vertex_indices {
if let Some(vertex) = row
.visuals
Expand Down Expand Up @@ -659,7 +662,7 @@ fn selected_text(galley: &Galley, cursor_range: &CursorRange) -> String {
}

fn estimate_row_height(galley: &Galley) -> f32 {
if let Some(row) = galley.rows.first() {
if let Some((row, _)) = galley.rows.first() {
row.rect.height()
} else {
galley.size().y
Expand Down
4 changes: 3 additions & 1 deletion crates/egui/src/text_selection/visuals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ pub fn paint_text_selection(
let max = max.rcursor;

for ri in min.row..=max.row {
let row = &mut galley.rows[ri];
let (row, _) = &mut galley.rows[ri];
let row = Arc::make_mut(row);

let left = if ri == min.row {
row.x_offset(min.column)
} else {
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/widget_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ impl WidgetText {
Self::RichText(text) => text.font_height(fonts, style),
Self::LayoutJob(job) => job.font_height(fonts),
Self::Galley(galley) => {
if let Some(row) = galley.rows.first() {
if let Some((row, _)) = galley.rows.first() {
row.height()
} else {
galley.size().y
Expand Down
13 changes: 8 additions & 5 deletions crates/egui/src/widgets/label.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::sync::Arc;

use crate::{
epaint, pos2, text_selection, vec2, Align, Direction, FontSelection, Galley, Pos2, Response,
Sense, Stroke, TextWrapMode, Ui, Widget, WidgetInfo, WidgetText, WidgetType,
epaint, pos2, text_selection, Align, Direction, FontSelection, Galley, Pos2, Response, Sense,
Stroke, TextWrapMode, Ui, Widget, WidgetInfo, WidgetText, WidgetType,
};

use self::text_selection::LabelSelectionState;
Expand Down Expand Up @@ -194,10 +194,13 @@ impl Label {
let pos = pos2(ui.max_rect().left(), ui.cursor().top());
assert!(!galley.rows.is_empty(), "Galleys are never empty");
// collect a response from many rows:
let rect = galley.rows[0].rect.translate(vec2(pos.x, pos.y));
let rect = galley.rows[0]
.0
.rect
.translate(galley.rows[0].1.to_vec2() + pos.to_vec2());
let mut response = ui.allocate_rect(rect, sense);
for row in galley.rows.iter().skip(1) {
let rect = row.rect.translate(vec2(pos.x, pos.y));
for (row, offset) in galley.rows.iter().skip(1) {
let rect = row.rect.translate(offset.to_vec2() + pos.to_vec2());
response |= ui.allocate_rect(rect, sense);
}
(pos, galley, response)
Expand Down
4 changes: 3 additions & 1 deletion crates/epaint/src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,9 @@ impl Shape {

// Scale text:
let galley = Arc::make_mut(&mut text_shape.galley);
for row in &mut galley.rows {
for (row, offset) in &mut galley.rows {
let row = Arc::make_mut(row);
*offset = *offset * transform.scaling;
row.visuals.mesh_bounds = transform.scaling * row.visuals.mesh_bounds;
for v in &mut row.visuals.mesh.vertices {
v.pos = Pos2::new(transform.scaling * v.pos.x, transform.scaling * v.pos.y);
Expand Down
3 changes: 2 additions & 1 deletion crates/epaint/src/shape_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ pub fn adjust_colors(

if !galley.is_empty() {
let galley = std::sync::Arc::make_mut(galley);
for row in &mut galley.rows {
for (row, _) in &mut galley.rows {
let row = Arc::make_mut(row);
for vertex in &mut row.visuals.mesh.vertices {
adjust_color(&mut vertex.color);
}
Expand Down
10 changes: 7 additions & 3 deletions crates/epaint/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ impl AllocInfo {
pub fn from_galley(galley: &Galley) -> Self {
Self::from_slice(galley.text().as_bytes())
+ Self::from_slice(&galley.rows)
+ galley.rows.iter().map(Self::from_galley_row).sum()
+ galley
.rows
.iter()
.map(|(row, _)| Self::from_galley_row(row))
.sum()
}

fn from_galley_row(row: &crate::text::Row) -> Self {
Expand Down Expand Up @@ -213,8 +217,8 @@ impl PaintStats {
self.shape_text += AllocInfo::from_galley(&text_shape.galley);

for row in &text_shape.galley.rows {
self.text_shape_indices += AllocInfo::from_slice(&row.visuals.mesh.indices);
self.text_shape_vertices += AllocInfo::from_slice(&row.visuals.mesh.vertices);
self.text_shape_indices += AllocInfo::from_slice(&row.0.visuals.mesh.indices);
self.text_shape_vertices += AllocInfo::from_slice(&row.0.visuals.mesh.vertices);
}
}
Shape::Mesh(mesh) => {
Expand Down
8 changes: 5 additions & 3 deletions crates/epaint/src/tessellator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1778,16 +1778,18 @@ impl Tessellator {

let rotator = Rot2::from_angle(*angle);

for row in &galley.rows {
for (row, row_pos) in &galley.rows {
if row.visuals.mesh.is_empty() {
continue;
}

let final_pos = galley_pos + row_pos.to_vec2();

let mut row_rect = row.visuals.mesh_bounds;
if *angle != 0.0 {
row_rect = row_rect.rotate_bb(rotator);
}
row_rect = row_rect.translate(galley_pos.to_vec2());
row_rect = row_rect.translate(final_pos.to_vec2());

if self.options.coarse_tessellation_culling && !self.clip_rect.intersects(row_rect) {
// culling individual lines of text is important, since a single `Shape::Text`
Expand Down Expand Up @@ -1836,7 +1838,7 @@ impl Tessellator {
};

Vertex {
pos: galley_pos + offset,
pos: final_pos + offset,
uv: (uv.to_vec2() * uv_normalizer).to_pos2(),
color,
}
Expand Down
36 changes: 8 additions & 28 deletions crates/epaint/src/text/fonts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,34 +832,14 @@ impl GalleyCache {

for galley in galleys {
let current_offset = emath::vec2(0.0, merged_galley.rect.height());
merged_galley.rows.extend(galley.rows.iter().map(|row| {
super::Row {
// FIXME: what is this???
section_index_at_start: row.section_index_at_start,
glyphs: row
.glyphs
.iter()
.cloned()
.map(|mut p| {
p.pos.y += current_offset.y;
p
})
.collect(),
rect: row.rect.translate(current_offset),
visuals: {
let mut visuals = row.visuals.clone();
for vertex in visuals.mesh.vertices.iter_mut() {
vertex.pos.y += current_offset.y;
}
visuals.mesh_bounds =
visuals.mesh_bounds.translate(current_offset);
merged_galley.mesh_bounds =
merged_galley.mesh_bounds.union(visuals.mesh_bounds);
visuals
},
ends_with_newline: row.ends_with_newline,
}
}));
merged_galley
.rows
.extend(galley.rows.iter().map(|(row, prev_offset)| {
merged_galley.mesh_bounds =
merged_galley.mesh_bounds.union(row.visuals.mesh_bounds);

(row.clone(), *prev_offset + current_offset)
}));
merged_galley.rect = merged_galley
.rect
.union(galley.rect.translate(current_offset));
Expand Down
Loading

0 comments on commit db32a1e

Please sign in to comment.