Zero fontsize panic workaround (#15371)

# Objective

- Fix https://github.com/bevyengine/bevy/issues/15366. `cosmic-text`
buffers refuse to function if the `Metrics` font size is zero.

## Solution

- Trick `cosmic-text` into clearing its internal buffer when the largest
font size of segments is zero by sending it no spans and a tiny
`Metrics::font_size` and `Metrics::line_height`.

## Testing

- [x] Fixes @brandon-reinhart 's bug.
This commit is contained in:
UkoeHB 2024-09-23 12:31:50 -05:00 committed by GitHub
parent 8e3db957c5
commit 21da0b72ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -90,7 +90,12 @@ impl TextPipeline {
.ok_or(TextError::NoSuchFont)?; .ok_or(TextError::NoSuchFont)?;
} }
let line_height = font_size * 1.2; let line_height = font_size * 1.2;
let metrics = Metrics::new(font_size, line_height).scale(scale_factor as f32); let mut metrics = Metrics::new(font_size, line_height).scale(scale_factor as f32);
// Metrics of 0.0 cause `Buffer::set_metrics` to panic. We hack around this by 'falling
// through' to call `Buffer::set_rich_text` with zero spans so any cached text will be cleared without
// deallocating the buffer.
metrics.font_size = metrics.font_size.max(0.000001);
metrics.line_height = metrics.line_height.max(0.000001);
// Load Bevy fonts into cosmic-text's font system. // Load Bevy fonts into cosmic-text's font system.
// This is done as as separate pre-pass to avoid borrow checker issues // This is done as as separate pre-pass to avoid borrow checker issues
@ -108,6 +113,8 @@ impl TextPipeline {
.into_iter() .into_iter()
.map(|_| -> (&str, Attrs) { unreachable!() }) .map(|_| -> (&str, Attrs) { unreachable!() })
.collect(); .collect();
// `metrics.font_size` hack continued: ignore all spans when scale_factor is zero.
if scale_factor > 0.0 {
spans.extend( spans.extend(
sections sections
.iter() .iter()
@ -126,6 +133,7 @@ impl TextPipeline {
) )
}), }),
); );
}
let spans_iter = spans.iter().copied(); let spans_iter = spans.iter().copied();
buffer.set_metrics(font_system, metrics); buffer.set_metrics(font_system, metrics);