use crate::TextError;
use crate::{FontSmoothing, FontSource, GenericFontFamily};
use bevy_derive::Deref;
use bevy_derive::DerefMut;
use bevy_ecs::resource::Resource;
use bevy_platform::collections::HashMap;
use parley::FontContext;
use parley::LayoutContext;
use swash::scale::ScaleContext;
#[derive(Copy, Clone, PartialEq, Default, Debug)]
pub struct TextBrush {
pub section_index: u32,
pub font_smoothing: FontSmoothing,
}
impl TextBrush {
pub fn new(section_index: u32, font_smoothing: FontSmoothing) -> Self {
TextBrush {
section_index,
font_smoothing,
}
}
}
#[derive(Resource, Default, Deref, DerefMut)]
pub struct FontCx {
#[deref]
pub context: FontContext,
generic_families: HashMap<GenericFontFamily, String>,
}
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,
};
let family_id = self
.collection
.generic_families(generic_family.into())
.next();
family_id.and_then(|id| self.collection.family_name(id))
}
pub fn set_generic_family(
&mut self,
generic_family: GenericFontFamily,
family_name: &str,
) -> Result<(), TextError> {
self.collection
.family_id(family_name)
.ok_or(TextError::NoSuchFontFamily(family_name.to_string()))
.map(|id| {
self.collection
.set_generic_families(generic_family.into(), core::iter::once(id));
self.generic_families
.insert(generic_family, family_name.to_string());
})
}
pub fn set_serif_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::Serif, family_name)
}
pub fn set_sans_serif_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::SansSerif, family_name)
}
pub fn set_cursive_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::Cursive, family_name)
}
pub fn set_fantasy_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::Fantasy, family_name)
}
pub fn set_monospace_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::Monospace, family_name)
}
pub fn set_system_ui_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::SystemUi, family_name)
}
pub fn set_ui_serif_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::UiSerif, family_name)
}
pub fn set_ui_sans_serif_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::UiSansSerif, family_name)
}
pub fn set_ui_monospace_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::UiMonospace, family_name)
}
pub fn set_ui_rounded_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::UiRounded, family_name)
}
pub fn set_emoji_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::Emoji, family_name)
}
pub fn set_math_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::Math, family_name)
}
pub fn set_fang_song_family(&mut self, family_name: &str) -> Result<(), TextError> {
self.set_generic_family(GenericFontFamily::FangSong, family_name)
}
pub fn restore_generic_families(&mut self) {
for (generic_family, family_name) in core::mem::take(&mut self.generic_families).iter() {
if let Err(err) = self.set_generic_family(*generic_family, family_name) {
bevy_log::warn!(
"Failed to restore generic font family mapping: {generic_family:?} -> {family_name}, {err}"
);
}
}
}
}
#[derive(Resource, Default, Deref, DerefMut)]
pub struct LayoutCx(pub LayoutContext<TextBrush>);
#[derive(Resource, Default, Deref, DerefMut)]
pub struct ScaleCx(pub ScaleContext);