mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 23:00:04 -04:00
Move cached-multiline-layout code into a helper function
This commit is contained in:
@@ -727,42 +727,7 @@ struct GalleyCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GalleyCache {
|
impl GalleyCache {
|
||||||
fn layout(&mut self, fonts: &mut FontsImpl, mut job: LayoutJob) -> Arc<Galley> {
|
fn layout_multiline(&mut self, fonts: &mut FontsImpl, job: LayoutJob) -> 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 mut current_section = 0;
|
let mut current_section = 0;
|
||||||
let mut current = 0;
|
let mut current = 0;
|
||||||
let mut left_max_rows = job.wrap.max_rows;
|
let mut left_max_rows = job.wrap.max_rows;
|
||||||
@@ -857,7 +822,47 @@ impl GalleyCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let galley = Arc::new(merged_galley);
|
merged_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.
|
||||||
|
|
||||||
|
// 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(
|
self.cache.insert(
|
||||||
hash,
|
hash,
|
||||||
CachedGalley {
|
CachedGalley {
|
||||||
|
|||||||
Reference in New Issue
Block a user