From 02a6c20f4611a7527979d3d8ac398824bd584d12 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 19 Sep 2026 09:27:24 +0100 Subject: [PATCH 01/11] Added a new `DefaultFontSource(pub FontSource)` resource and a new `Default` variant to `FontSource`. `DefaultFontSource` is looked up when resolving `FontSource::Default`. DefaultFontSource(FontSource::Default)` is mapped to the default font asset handle. --- ...source_resolve_default_source_parameter.md | 0 .../release-notes/default_font_source.md | 5 ++ crates/bevy_sprite/src/text2d.rs | 9 ++- crates/bevy_text/src/font.rs | 64 ++++++++++++++++++- crates/bevy_text/src/lib.rs | 1 + crates/bevy_text/src/parley_context.rs | 5 +- crates/bevy_text/src/pipeline.rs | 12 +++- crates/bevy_text/src/text.rs | 53 +++++++++++---- crates/bevy_ui/src/widget/text.rs | 9 ++- .../bevy_ui/src/widget/text_input_layout.rs | 19 ++++-- 10 files changed, 149 insertions(+), 28 deletions(-) create mode 100644 _release-content/migration-guides/font_source_resolve_default_source_parameter.md create mode 100644 _release-content/release-notes/default_font_source.md diff --git a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/_release-content/release-notes/default_font_source.md b/_release-content/release-notes/default_font_source.md new file mode 100644 index 0000000000000..18480d175c917 --- /dev/null +++ b/_release-content/release-notes/default_font_source.md @@ -0,0 +1,5 @@ +--- +title: Default font source +authors: ["@ickdhonpe"] +pull_requests: [] +--- \ No newline at end of file diff --git a/crates/bevy_sprite/src/text2d.rs b/crates/bevy_sprite/src/text2d.rs index 2fe8383af35b7..5979d4ce697d1 100644 --- a/crates/bevy_sprite/src/text2d.rs +++ b/crates/bevy_sprite/src/text2d.rs @@ -22,9 +22,9 @@ use bevy_image::prelude::*; use bevy_math::{FloatOrd, Vec2, Vec3}; use bevy_reflect::{prelude::ReflectDefault, Reflect}; use bevy_text::{ - ComputedTextBlock, Font, FontAtlasSet, FontCx, FontHinting, LayoutCx, LetterSpacing, LineBreak, - LineHeight, RemSize, ScaleCx, TextBounds, TextColor, TextError, TextFont, TextLayout, - TextLayoutInfo, TextPipeline, TextReader, TextSection, TextWriter, + ComputedTextBlock, DefaultFontSource, Font, FontAtlasSet, FontCx, FontHinting, LayoutCx, + LetterSpacing, LineBreak, LineHeight, RemSize, ScaleCx, TextBounds, TextColor, TextError, + TextFont, TextLayout, TextLayoutInfo, TextPipeline, TextReader, TextSection, TextWriter, }; use bevy_transform::components::Transform; use bevy_window::{PrimaryWindow, Window}; @@ -171,6 +171,7 @@ pub fn update_text2d_layout( mut reprocess_queue: Local, mut textures: ResMut>, fonts: Res>, + default_font_source: Res, camera_query: Query<(&Camera, &VisibleEntities, Option<&RenderLayers>)>, mut font_atlas_set: ResMut, mut text_pipeline: ResMut, @@ -278,6 +279,7 @@ pub fn update_text2d_layout( &mut layout_cx, logical_viewport_size, *rem_size, + &default_font_source.0, ) { Err( TextError::NoSuchFont @@ -453,6 +455,7 @@ mod tests { .init_resource::() .init_resource::() .init_resource::() + .init_resource::() .add_systems( Update, ( diff --git a/crates/bevy_text/src/font.rs b/crates/bevy_text/src/font.rs index e683ae9a18486..2d899e8c2ffde 100644 --- a/crates/bevy_text/src/font.rs +++ b/crates/bevy_text/src/font.rs @@ -1,12 +1,14 @@ +use crate::DefaultFontSource; use crate::FontCx; use crate::FontSource; use crate::TextFont; use bevy_asset::Asset; use bevy_asset::AssetId; use bevy_asset::Assets; -use bevy_ecs::change_detection::DetectChangesMut; +use bevy_ecs::change_detection::{DetectChanges, DetectChangesMut}; use bevy_ecs::system::Local; use bevy_ecs::system::Query; +use bevy_ecs::system::Res; use bevy_ecs::system::ResMut; use bevy_platform::collections::HashSet; use bevy_reflect::TypePath; @@ -54,6 +56,7 @@ pub fn load_font_assets_into_font_collection( mut loaded_fonts: Local>>, mut font_cx: ResMut, mut text_font_query: Query<&mut TextFont>, + default_font_source: Res, ) { let font_removed = loaded_fonts.iter().any(|id| !fonts.contains(*id)); let new_asset_ids: Vec<_> = if font_removed { @@ -66,7 +69,7 @@ pub fn load_font_assets_into_font_collection( fonts.ids().filter(|id| loaded_fonts.insert(*id)).collect() }; - if new_asset_ids.is_empty() && !font_removed { + if new_asset_ids.is_empty() && !font_removed && !default_font_source.is_changed() { return; } @@ -110,6 +113,7 @@ pub fn load_font_assets_into_font_collection( .flatten() .into_iter() .any(|source| match source { + FontSource::Default => true, FontSource::Handle(handle) => new_asset_ids.contains(&handle.id()), FontSource::Family(name) => font_cx .collection @@ -145,14 +149,66 @@ pub fn load_font_assets_into_font_collection( mod tests { use bevy_app::{App, Update}; use bevy_asset::Assets; - use bevy_ecs::change_detection::DetectChanges; use super::*; + #[test] + fn default_font_changes_invalidate_default_text_fonts() { + let mut app = App::new(); + app.init_resource::>() + .init_resource::() + .init_resource::() + .add_systems(Update, load_font_assets_into_font_collection); + let default_entity = app.world_mut().spawn(TextFont::default()).id(); + let nested_entity = app + .world_mut() + .spawn(TextFont { + font: FontSource::list([FontSource::list([FontSource::Default])]), + ..Default::default() + }) + .id(); + let explicit_entity = app.world_mut().spawn(TextFont::from("Other")).id(); + let entities = [default_entity, nested_entity, explicit_entity]; + app.update(); + + for insert_asset in [false, true] { + let ticks = entities.map(|entity| { + app.world() + .entity(entity) + .get_ref::() + .unwrap() + .last_changed() + }); + if insert_asset { + app.world_mut() + .resource_mut::>() + .add(Font::from_bytes( + include_bytes!("FiraMono-subset.ttf").to_vec(), + )); + } else { + app.world_mut().resource_mut::().0 = + FontSource::family("Fira Mono"); + } + app.update(); + for (entity, tick) in entities.into_iter().zip(ticks) { + assert_eq!( + tick != app + .world() + .entity(entity) + .get_ref::() + .unwrap() + .last_changed(), + entity != explicit_entity + ); + } + } + } + #[test] fn font_asset_registration_and_cleanup() { let mut app = App::new(); app.init_resource::>() + .init_resource::() .init_resource::() .add_systems(Update, load_font_assets_into_font_collection); @@ -202,6 +258,7 @@ mod tests { fn text_font_is_set_changed_when_its_font_asset_is_inserted() { let mut app = App::new(); app.init_resource::>() + .init_resource::() .init_resource::() .add_systems(Update, load_font_assets_into_font_collection); @@ -252,6 +309,7 @@ mod tests { fn textfonts_are_not_set_changed_when_a_font_asset_is_inserted_for_other_textfonts() { let mut app = App::new(); app.init_resource::>() + .init_resource::() .init_resource::() .add_systems(Update, load_font_assets_into_font_collection); diff --git a/crates/bevy_text/src/lib.rs b/crates/bevy_text/src/lib.rs index 3d15d739d7226..70a1c5dba2242 100644 --- a/crates/bevy_text/src/lib.rs +++ b/crates/bevy_text/src/lib.rs @@ -126,6 +126,7 @@ impl Plugin for TextPlugin { .init_resource::() .init_resource::() .init_resource::() + .init_resource::() .add_systems( PostUpdate, ( diff --git a/crates/bevy_text/src/parley_context.rs b/crates/bevy_text/src/parley_context.rs index 3e9ce1d51c1bf..b178b60725e11 100644 --- a/crates/bevy_text/src/parley_context.rs +++ b/crates/bevy_text/src/parley_context.rs @@ -50,8 +50,11 @@ impl FontCx { pub fn get_family<'a>(&'a mut self, source: &'a FontSource) -> Option<&'a str> { let generic_family = match source { FontSource::Family(family) => return Some(family.as_str()), - FontSource::Handle(_) | FontSource::Families(_) | FontSource::List(_) => return None, FontSource::Generic(generic_family) => *generic_family, + FontSource::Handle(_) + | FontSource::Families(_) + | FontSource::List(_) + | FontSource::Default => return None, }; let family_id = self diff --git a/crates/bevy_text/src/pipeline.rs b/crates/bevy_text/src/pipeline.rs index e2ebe3d0c5ddb..58803493853a5 100644 --- a/crates/bevy_text/src/pipeline.rs +++ b/crates/bevy_text/src/pipeline.rs @@ -82,6 +82,7 @@ impl TextPipeline { layout_cx: &mut LayoutCx, logical_viewport_size: Vec2, base_rem_size: RemSize, + default_font_source: &FontSource, ) -> Result<(), TextError> { computed.entities.clear(); computed.needs_rerender = false; @@ -126,7 +127,10 @@ impl TextPipeline { } if matches!(text_font.font, FontSource::Handle(_)) - && text_font.font.resolve_font_family(fonts).is_err() + && text_font + .font + .resolve_font_family(fonts, default_font_source) + .is_err() { return Err(TextError::NoSuchFont); } @@ -227,7 +231,9 @@ impl TextPipeline { continue; } - let resolved_family = text_font.font.resolve_font_family(fonts)?; + let resolved_family = text_font + .font + .resolve_font_family(fonts, default_font_source)?; builder.push(StyleProperty::FontFamily(resolved_family), range.clone()); builder.push( @@ -307,6 +313,7 @@ impl TextPipeline { layout_cx: &mut LayoutCx, logical_viewport_size: Vec2, base_rem_size: RemSize, + default_font_source: &FontSource, ) -> Result { const MIN_WIDTH_CONTENT_BOUNDS: TextBounds = TextBounds::new_horizontal(0.0); @@ -324,6 +331,7 @@ impl TextPipeline { layout_cx, logical_viewport_size, base_rem_size, + default_font_source, )?; let layout_buffer = &mut computed.layout; diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 3f80adb23cc67..1fe223032ac73 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -280,7 +280,7 @@ impl From for parley::Alignment { /// /// You can check which font family is used for a given [`FontSource`] /// by calling [`FontCx::get_family`](crate::FontCx::get_family). -#[derive(Clone, Debug, Reflect, PartialEq, FromTemplate)] +#[derive(Clone, Debug, Reflect, PartialEq, FromTemplate, Default)] pub enum FontSource { /// Use a specific font face referenced by a [`Font`] asset handle. /// @@ -288,8 +288,7 @@ pub enum FontSource { /// * if `default_font` feature is enabled (enabled by default in `bevy` crate), /// `FiraMono-subset.ttf` compiled into the library is used. /// * otherwise no text will be rendered, unless a custom font is loaded into the default font - /// handle. - #[default] + /// handle. Handle(Handle), /// Resolve the font by family name using the font database. Family(SmolStr), @@ -301,6 +300,9 @@ pub enum FontSource { List(#[template(built_in)] Vec), /// Resolve the font using a generic font family. Generic(GenericFontFamily), + /// Use the default font source from the `DefaultFontSource` resource. + #[default] + Default, } impl FontSource { @@ -444,8 +446,20 @@ impl FontSource { pub fn resolve_font_family<'a>( &'a self, fonts: &'a Assets, + default_source: &'a Self, ) -> Result, TextError> { + if matches!(self, FontSource::Default) && !matches!(default_source, FontSource::Default) { + return default_source.resolve_font_family(fonts, &FontSource::Default); + } + Ok(match self { + FontSource::Default => FontFamily::named( + fonts + .get(Handle::default().id()) + .ok_or(TextError::NoSuchFont)? + .alias + .as_str(), + ), FontSource::Handle(handle) => { FontFamily::Single(parley::FontFamilyName::Named(Cow::Borrowed( fonts @@ -462,6 +476,7 @@ impl FontSource { match font_sources.as_slice() { [] => FontFamily::List(Cow::Owned(Vec::new())), [source] => match *source { + FontSource::Default => source.resolve_font_family(fonts, default_source)?, FontSource::Handle(handle) => { FontFamily::Single(parley::FontFamilyName::Named(Cow::Borrowed( fonts @@ -494,6 +509,23 @@ impl FontSource { let mut families = Vec::new(); for source in font_sources.iter().copied() { match source { + FontSource::Default => { + match source.resolve_font_family(fonts, default_source)? { + FontFamily::Single(family) => families.push(family), + FontFamily::List(list) => { + families.extend(list.into_owned()) + } + FontFamily::Source(source) => { + for family in parley::FontFamilyName::parse_css_list( + source.as_ref(), + ) + .map_while(Result::ok) + { + families.push(family.into_owned()); + } + } + } + } FontSource::Handle(handle) => { families.push(parley::FontFamilyName::Named(Cow::Borrowed( fonts @@ -543,12 +575,6 @@ impl FontSource { } } -impl Default for FontSource { - fn default() -> Self { - Self::Handle(Handle::default()) - } -} - impl From> for FontSource { fn from(handle: Handle) -> Self { Self::Handle(handle) @@ -591,6 +617,11 @@ impl From<[FontSource; N]> for FontSource { } } +/// Holds the default font source. Used when `Fontsource` is set to `Default`. +/// `DefaultFontSource(FontSource::Default)` is mapped to the default Font asset. +#[derive(Clone, Debug, Reflect, PartialEq, Default, Resource)] +pub struct DefaultFontSource(pub FontSource); + /// Generic font families that are resolved through Parley's font database. #[derive(Default, Clone, Copy, Debug, Reflect, PartialEq, Eq, Hash)] #[repr(u8)] @@ -1728,7 +1759,7 @@ mod tests { let list = FontSource::List(Vec::new()); assert!(list.flatten().is_empty()); assert_eq!( - list.resolve_font_family(&Assets::::default()), + list.resolve_font_family(&Assets::::default(), &FontSource::Default), Ok(FontFamily::List(Cow::Owned(Vec::new()))) ); } @@ -1742,7 +1773,7 @@ mod tests { let source = FontSource::list([FontSource::from(dummy_font_handle)]); assert_eq!( - source.resolve_font_family(&fonts), + source.resolve_font_family(&fonts, &FontSource::Default), Ok(FontFamily::Single(parley::FontFamilyName::Named( Cow::Borrowed("Dummy Font") ))) diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 9afa952b860ff..ee9cef33e4f5e 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -19,9 +19,10 @@ use bevy_log::warn_once; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; use bevy_text::{ - ComputedTextBlock, Font, FontAtlasSet, FontCx, FontHinting, LayoutCx, LetterSpacing, LineBreak, - LineHeight, RemSize, ScaleCx, TextBounds, TextColor, TextError, TextFont, TextLayout, - TextLayoutInfo, TextMeasureInfo, TextPipeline, TextReader, TextSection, TextWriter, + ComputedTextBlock, DefaultFontSource, Font, FontAtlasSet, FontCx, FontHinting, LayoutCx, + LetterSpacing, LineBreak, LineHeight, RemSize, ScaleCx, TextBounds, TextColor, TextError, + TextFont, TextLayout, TextLayoutInfo, TextMeasureInfo, TextPipeline, TextReader, TextSection, + TextWriter, }; use taffy::{style::AvailableSpace, MaybeMath, ResolveOrZero}; use tracing::error; @@ -305,6 +306,7 @@ pub fn measure_text_system( mut font_system: ResMut, mut layout_cx: ResMut, rem_size: Res, + default_font_source: Res, ) { for ( entity, @@ -340,6 +342,7 @@ pub fn measure_text_system( &mut layout_cx, computed_target.logical_size(), *rem_size, + &default_font_source.0, ) { Ok(measure) => { if block.linebreak == LineBreak::NoWrap { diff --git a/crates/bevy_ui/src/widget/text_input_layout.rs b/crates/bevy_ui/src/widget/text_input_layout.rs index 0e9385d4e4966..04d5a17fca67d 100644 --- a/crates/bevy_ui/src/widget/text_input_layout.rs +++ b/crates/bevy_ui/src/widget/text_input_layout.rs @@ -18,9 +18,10 @@ use bevy_platform::hash::FixedHasher; use bevy_text::{ add_glyph_to_atlas, cursor_reveal_rect, get_glyph_atlas_info, scrollable_text_layout_width, - EditableText, EditableTextGeneration, Font, FontAtlasKey, FontAtlasSet, FontCx, FontHinting, - FontSize, GlyphCacheKey, LayoutCx, LineBreak, LineHeight, PositionedGlyph, RemSize, - RunGeometry, ScaleCx, TextBrush, TextFont, TextLayout, TextLayoutInfo, TextLineYBounds, + DefaultFontSource, EditableText, EditableTextGeneration, Font, FontAtlasKey, FontAtlasSet, + FontCx, FontHinting, FontSize, GlyphCacheKey, LayoutCx, LineBreak, LineHeight, PositionedGlyph, + RemSize, RunGeometry, ScaleCx, TextBrush, TextFont, TextLayout, TextLayoutInfo, + TextLineYBounds, }; use bevy_time::{Real, Time}; use parley::{BoundingBox, PositionedLayoutItem, StyleProperty}; @@ -90,6 +91,7 @@ pub fn update_editable_text_content_size( fonts: Res>, mut font_cx: ResMut, rem_size: Res, + default_font_source: Res, ) { for (editable_text, text_font, line_height, target, mut content_size, mut size_state) in &mut text_input_query @@ -116,7 +118,11 @@ pub fn update_editable_text_content_size( .collection .query(&mut font_context.source_cache); - match text_font.font.resolve_font_family(fonts.as_ref()).ok()? { + match text_font + .font + .resolve_font_family(fonts.as_ref(), &default_font_source.0) + .ok()? + { parley::FontFamily::Source(source) => { query.set_families( parley::FontFamilyName::parse_css_list(&source) @@ -199,6 +205,7 @@ pub fn update_editable_text_styles( Ref, )>, rem_size: Res, + default_font_source: Res, ) { for (mut editable_text, text_font, line_height, target, text_layout) in editable_text_query.iter_mut() @@ -223,7 +230,9 @@ pub fn update_editable_text_styles( } if text_font.is_changed() - && let Ok(resolved_family) = text_font.font.resolve_font_family(fonts.as_ref()) + && let Ok(resolved_family) = text_font + .font + .resolve_font_family(fonts.as_ref(), &default_font_source.0) { let family = resolved_family.into_owned(); let style_set = editable_text.editor.edit_styles(); From 210fbc093907fc30ad0ca0ba3a96fc5d93a666a0 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 19 Sep 2026 09:43:27 +0100 Subject: [PATCH 02/11] Added `Deref` and `DerefMut` derives for `DefaultFontSize`. --- crates/bevy_text/src/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 1fe223032ac73..8a823fde9778c 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -619,7 +619,7 @@ impl From<[FontSource; N]> for FontSource { /// Holds the default font source. Used when `Fontsource` is set to `Default`. /// `DefaultFontSource(FontSource::Default)` is mapped to the default Font asset. -#[derive(Clone, Debug, Reflect, PartialEq, Default, Resource)] +#[derive(Clone, Debug, Reflect, PartialEq, Default, Resource, Deref, DerefMut)] pub struct DefaultFontSource(pub FontSource); /// Generic font families that are resolved through Parley's font database. From 5f9a6b5ce66dd3d0a6f1f35316161f0c9ee02276 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 19 Sep 2026 09:50:00 +0100 Subject: [PATCH 03/11] Updated release note --- _release-content/release-notes/default_font_source.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/_release-content/release-notes/default_font_source.md b/_release-content/release-notes/default_font_source.md index 18480d175c917..efbd261005dba 100644 --- a/_release-content/release-notes/default_font_source.md +++ b/_release-content/release-notes/default_font_source.md @@ -1,5 +1,9 @@ --- title: Default font source authors: ["@ickdhonpe"] -pull_requests: [] ---- \ No newline at end of file +pull_requests: [25847] +--- + +`DefaultFontSource` is a new resource that newtypes `FontSource` and can be used to set a global default font. +`FontSource` has a new variant `Default`. During font resolution if `FontSource::Default` is found, the `FontSource` from `DefaultFontSource` is used instead. +`DefaultFontSource(FontSource::Default)` is mapped to `FontSource::Handle(Handle::default())`. From caa3445935e69678a052559f190dc9efc77ea577 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 19 Sep 2026 09:58:27 +0100 Subject: [PATCH 04/11] updated migration guide --- .../font_source_resolve_default_source_parameter.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md index e69de29bb2d1d..233c94b57c58c 100644 --- a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md +++ b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md @@ -0,0 +1,6 @@ +--- +title: New `default_source` parameter on `FontSource::resolve_font_family` +pull_requests: [25847] +--- + +The `FontSource::resolve_font_family` method now takes a `default_source` argument that is used to resolve `FontSource::Default`. \ No newline at end of file From a7513d952c26b2a1b342369a3f717a94d4707533 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 19 Sep 2026 10:05:52 +0100 Subject: [PATCH 05/11] Fixed migration guide formatting --- .../font_source_resolve_default_source_parameter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md index 233c94b57c58c..396066ddab1a3 100644 --- a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md +++ b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md @@ -3,4 +3,4 @@ title: New `default_source` parameter on `FontSource::resolve_font_family` pull_requests: [25847] --- -The `FontSource::resolve_font_family` method now takes a `default_source` argument that is used to resolve `FontSource::Default`. \ No newline at end of file +The `FontSource::resolve_font_family` method now takes a `default_source` argument that is used to resolve `FontSource::Default`. From 84473f6b47f5485d8e2e2a9113816b19b63baaed Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 19 Sep 2026 11:34:55 +0100 Subject: [PATCH 06/11] Doc comment edit --- crates/bevy_text/src/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 8a823fde9778c..75bae127b0016 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -617,7 +617,7 @@ impl From<[FontSource; N]> for FontSource { } } -/// Holds the default font source. Used when `Fontsource` is set to `Default`. +/// The default font source used to resolve `FontSource::Default`. /// `DefaultFontSource(FontSource::Default)` is mapped to the default Font asset. #[derive(Clone, Debug, Reflect, PartialEq, Default, Resource, Deref, DerefMut)] pub struct DefaultFontSource(pub FontSource); From 9293ab393cb62c7c802b25ccb10fd8fe14eeaf63 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Mon, 21 Sep 2026 23:04:32 +0100 Subject: [PATCH 07/11] Update _release-content/migration-guides/font_source_resolve_default_source_parameter.md Co-authored-by: Alice Cecile --- .../font_source_resolve_default_source_parameter.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md index 396066ddab1a3..0b54304f58b38 100644 --- a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md +++ b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md @@ -4,3 +4,5 @@ pull_requests: [25847] --- The `FontSource::resolve_font_family` method now takes a `default_source` argument that is used to resolve `FontSource::Default`. + +You should set the value of the `DefaultFont` resource to set the default font for your app now. From 831a7ecef0f2acb0462734e1518645c605927c30 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Mon, 21 Sep 2026 23:04:44 +0100 Subject: [PATCH 08/11] Update crates/bevy_text/src/text.rs Co-authored-by: Alice Cecile --- crates/bevy_text/src/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 75bae127b0016..f8189c85f03bd 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -300,7 +300,7 @@ pub enum FontSource { List(#[template(built_in)] Vec), /// Resolve the font using a generic font family. Generic(GenericFontFamily), - /// Use the default font source from the `DefaultFontSource` resource. + /// Use the default font source from the [`DefaultFontSource`] resource. #[default] Default, } From a96be01d40c02d6ea855b61737f61ca2e0a7c43a Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Mon, 21 Sep 2026 23:14:23 +0100 Subject: [PATCH 09/11] Removed release note. --- _release-content/release-notes/default_font_source.md | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 _release-content/release-notes/default_font_source.md diff --git a/_release-content/release-notes/default_font_source.md b/_release-content/release-notes/default_font_source.md deleted file mode 100644 index efbd261005dba..0000000000000 --- a/_release-content/release-notes/default_font_source.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Default font source -authors: ["@ickdhonpe"] -pull_requests: [25847] ---- - -`DefaultFontSource` is a new resource that newtypes `FontSource` and can be used to set a global default font. -`FontSource` has a new variant `Default`. During font resolution if `FontSource::Default` is found, the `FontSource` from `DefaultFontSource` is used instead. -`DefaultFontSource(FontSource::Default)` is mapped to `FontSource::Handle(Handle::default())`. From aaeec50e10446c0875c0c81207ec9e9bc170ea66 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Mon, 21 Sep 2026 23:15:20 +0100 Subject: [PATCH 10/11] fix for semicolon_if_nothing_returned lint --- crates/bevy_text/src/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_text/src/text.rs b/crates/bevy_text/src/text.rs index 75bae127b0016..d728a21fc4abc 100644 --- a/crates/bevy_text/src/text.rs +++ b/crates/bevy_text/src/text.rs @@ -513,7 +513,7 @@ impl FontSource { match source.resolve_font_family(fonts, default_source)? { FontFamily::Single(family) => families.push(family), FontFamily::List(list) => { - families.extend(list.into_owned()) + families.extend(list.into_owned()); } FontFamily::Source(source) => { for family in parley::FontFamilyName::parse_css_list( From 3fc06433e5d2774da09779b047ec227a432319ca Mon Sep 17 00:00:00 2001 From: Alice Cecile Date: Tue, 22 Sep 2026 00:09:33 -0400 Subject: [PATCH 11/11] Fix resource name in migration guide Co-authored-by: Alice Cecile --- .../font_source_resolve_default_source_parameter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md index 0b54304f58b38..fd3852a7f7d9f 100644 --- a/_release-content/migration-guides/font_source_resolve_default_source_parameter.md +++ b/_release-content/migration-guides/font_source_resolve_default_source_parameter.md @@ -5,4 +5,4 @@ pull_requests: [25847] The `FontSource::resolve_font_family` method now takes a `default_source` argument that is used to resolve `FontSource::Default`. -You should set the value of the `DefaultFont` resource to set the default font for your app now. +You should set the value of the `DefaultFontSource` resource to set the default font for your app now.