1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 14:20:04 -04:00
This commit is contained in:
Hubert Głuchowski
2024-12-04 19:30:13 +01:00
parent e15b34b984
commit c6592ec898
3 changed files with 63 additions and 63 deletions

View File

@@ -1783,13 +1783,13 @@ impl Tessellator {
continue; continue;
} }
let final_pos = galley_pos + row.pos.to_vec2(); let final_row_pos = galley_pos + row.pos.to_vec2();
let mut row_rect = row.visuals.mesh_bounds; let mut row_rect = row.visuals.mesh_bounds;
if *angle != 0.0 { if *angle != 0.0 {
row_rect = row_rect.rotate_bb(rotator); row_rect = row_rect.rotate_bb(rotator);
} }
row_rect = row_rect.translate(final_pos.to_vec2()); row_rect = row_rect.translate(final_row_pos.to_vec2());
if self.options.coarse_tessellation_culling && !self.clip_rect.intersects(row_rect) { if self.options.coarse_tessellation_culling && !self.clip_rect.intersects(row_rect) {
// culling individual lines of text is important, since a single `Shape::Text` // culling individual lines of text is important, since a single `Shape::Text`
@@ -1838,7 +1838,7 @@ impl Tessellator {
}; };
Vertex { Vertex {
pos: final_pos + offset, pos: final_row_pos + offset,
uv: (uv.to_vec2() * uv_normalizer).to_pos2(), uv: (uv.to_vec2() * uv_normalizer).to_pos2(),
color, color,
} }

View File

@@ -727,6 +727,65 @@ struct GalleyCache {
} }
impl GalleyCache { impl GalleyCache {
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.
// Say the user asks to wrap at width 200.0.
// The text layout wraps, and reports that the final width was 196.0 points.
// This then trickles up the `Ui` chain and gets stored as the width for a tooltip (say).
// On the next frame, this is then set as the max width for the tooltip,
// and we end up calling the text layout code again, this time with a wrap width of 196.0.
// Except, somewhere in the `Ui` chain with added margins etc, a rounding error was introduced,
// so that we actually set a wrap-width of 195.9997 instead.
// Now the text that fit perfrectly at 196.0 needs to wrap one word earlier,
// and so the text re-wraps and reports a new width of 185.0 points.
// And then the cycle continues.
// So we limit max_width to integers.
// Related issues:
// * https://github.com/emilk/egui/issues/4927
// * https://github.com/emilk/egui/issues/4928
// * https://github.com/emilk/egui/issues/5084
// * https://github.com/emilk/egui/issues/5163
job.wrap.max_width = job.wrap.max_width.round();
}
let hash = crate::util::hash(&job); // TODO(emilk): even faster hasher?
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) => {
if job.break_on_newline {
let galley = self.layout_multiline(fonts, job);
let galley = Arc::new(galley);
self.cache.insert(
hash,
CachedGalley {
last_used: self.generation,
galley: galley.clone(),
},
);
galley
} else {
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_multiline(&mut self, fonts: &mut FontsImpl, job: LayoutJob) -> Galley { fn layout_multiline(&mut self, fonts: &mut FontsImpl, job: LayoutJob) -> Galley {
let pixels_per_point = fonts.pixels_per_point; let pixels_per_point = fonts.pixels_per_point;
let round_to_pixel = let round_to_pixel =
@@ -870,65 +929,6 @@ impl GalleyCache {
} }
} }
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.
// Say the user asks to wrap at width 200.0.
// The text layout wraps, and reports that the final width was 196.0 points.
// This then trickles up the `Ui` chain and gets stored as the width for a tooltip (say).
// On the next frame, this is then set as the max width for the tooltip,
// and we end up calling the text layout code again, this time with a wrap width of 196.0.
// Except, somewhere in the `Ui` chain with added margins etc, a rounding error was introduced,
// so that we actually set a wrap-width of 195.9997 instead.
// Now the text that fit perfrectly at 196.0 needs to wrap one word earlier,
// and so the text re-wraps and reports a new width of 185.0 points.
// And then the cycle continues.
// So we limit max_width to integers.
// Related issues:
// * https://github.com/emilk/egui/issues/4927
// * https://github.com/emilk/egui/issues/4928
// * https://github.com/emilk/egui/issues/5084
// * https://github.com/emilk/egui/issues/5163
job.wrap.max_width = job.wrap.max_width.round();
}
let hash = crate::util::hash(&job); // TODO(emilk): even faster hasher?
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) => {
if job.break_on_newline {
let galley = self.layout_multiline(fonts, job);
let galley = Arc::new(galley);
self.cache.insert(
hash,
CachedGalley {
last_used: self.generation,
galley: galley.clone(),
},
);
galley
} else {
let galley = super::layout(fonts, job.into());
let galley = Arc::new(galley);
entry.insert(CachedGalley {
last_used: self.generation,
galley: galley.clone(),
});
galley
}
}
}
}
pub fn num_galleys_in_cache(&self) -> usize { pub fn num_galleys_in_cache(&self) -> usize {
self.cache.len() self.cache.len()
} }

View File

@@ -595,7 +595,7 @@ fn halign_and_justify_row(
} }
} }
// Note we **don't** ignore the leading/trailing whitespace here! // Note we ignore the leading/trailing whitespace here!
row.size.x = target_max_x - target_min_x; row.size.x = target_max_x - target_min_x;
} }