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)?;
}
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.
// This is done as as separate pre-pass to avoid borrow checker issues
@ -108,24 +113,27 @@ impl TextPipeline {
.into_iter()
.map(|_| -> (&str, Attrs) { unreachable!() })
.collect();
spans.extend(
sections
.iter()
.enumerate()
.filter(|(_section_index, section)| section.style.font_size > 0.0)
.map(|(section_index, section)| {
(
&section.value[..],
get_attrs(
section,
section_index,
font_system,
&self.map_handle_to_font_id,
scale_factor,
),
)
}),
);
// `metrics.font_size` hack continued: ignore all spans when scale_factor is zero.
if scale_factor > 0.0 {
spans.extend(
sections
.iter()
.enumerate()
.filter(|(_section_index, section)| section.style.font_size > 0.0)
.map(|(section_index, section)| {
(
&section.value[..],
get_attrs(
section,
section_index,
font_system,
&self.map_handle_to_font_id,
scale_factor,
),
)
}),
);
}
let spans_iter = spans.iter().copied();
buffer.set_metrics(font_system, metrics);