use glyphon::{
Attrs, Buffer, Color, FontSystem, Metrics, Shaping, SwashCache, TextArea, TextBounds,
};
use sys_locale::get_locale;
pub struct TextSystem {
pub fonts: FontSystem,
pub swash: SwashCache,
}
impl TextSystem {
pub fn new() -> color_eyre::Result<Self> {
let locale = get_locale().unwrap_or_else(|| "en-US".to_string());
let mut db = glyphon::fontdb::Database::new();
#[cfg(not(target_arch = "wasm32"))]
{
db.load_system_fonts();
}
let fonts = FontSystem::new_with_locale_and_db(locale, db);
Ok(Self {
fonts,
swash: SwashCache::new(),
})
}
}
#[derive(serde::Deserialize, Debug, Clone, Copy)]
struct TextColor(
#[serde(deserialize_with = "palette::serde::deserialize_with_optional_alpha")] palette::Srgba,
);
impl TextSystem {
pub fn prepare(&mut self, _data: &TextSystemData) {}
fn convert_world_to_glyphon_world(&self, point: glam::Vec2) -> glam::Vec2 {
point
}
pub fn produce_world(
&mut self,
_data: &TextSystemData,
) -> impl IntoIterator<Item = (Buffer, BufferMapper)> {
let metrics = Metrics::new(32.0, 20.0);
let mut buffer = Buffer::new(&mut self.fonts, metrics);
{
let mut buffer = buffer.borrow_with(&mut self.fonts);
buffer.set_size(250.0, 25.0);
let attrs = Attrs::new().family(glyphon::Family::Name("Poiret One"));
buffer.set_text("Hello, game! 🦀\n", attrs, Shaping::Advanced);
buffer.shape_until_scroll(true);
}
let loc = glam::Vec2::new(32.0, 32.0);
let mut buffer2 = Buffer::new(&mut self.fonts, metrics);
{
let mut buffer2 = buffer2.borrow_with(&mut self.fonts);
buffer2.set_size(250.0, 25.0);
let attrs = Attrs::new()
.family(glyphon::Family::Name("Poiret One"))
.color(glyphon::Color::rgb(255, 255, 255));
buffer2.set_text("Y tho? 🦀\n", attrs, Shaping::Advanced);
buffer2.shape_until_scroll(true);
}
let loc2 = glam::Vec2::new(32.0, 64.0);
vec![
(
buffer,
BufferMapper::new(self.convert_world_to_glyphon_world(loc), 1.0),
),
(
buffer2,
BufferMapper::new(self.convert_world_to_glyphon_world(loc2), 1.0),
),
]
}
pub fn produce_camera(
&mut self,
_data: &TextSystemData,
) -> impl IntoIterator<Item = (Buffer, BufferMapper)> {
let metrics = Metrics::new(32.0, 20.0);
let mut buffer = Buffer::new(&mut self.fonts, metrics);
{
let mut buffer = buffer.borrow_with(&mut self.fonts);
buffer.set_size(200.0, 25.0);
let srgb_red: palette::Srgb<u8> = palette::named::WHITE.into_format();
let (r, g, b) = srgb_red.into_components();
let color = glyphon::Color::rgb(r, g, b);
let attrs = Attrs::new()
.family(glyphon::Family::Name("Poiret One"))
.color(color);
buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced);
buffer.shape_until_scroll(true);
}
vec![(buffer, BufferMapper::new((32.0, 32.0).into(), 1.0))]
}
}
pub struct BufferMapper {
position: glam::Vec2,
scale: f32,
}
impl BufferMapper {
fn new(position: glam::Vec2, scale: f32) -> Self {
Self { position, scale }
}
pub(crate) fn produce<'a>(&self, buffer: &'a Buffer) -> TextArea<'a> {
TextArea {
buffer,
left: self.position.x,
top: self.position.y,
scale: self.scale,
bounds: TextBounds {
..Default::default()
},
default_color: Color::rgba(255, 0, 0, 200),
}
}
}
pub struct TextSystemData {}
impl TextSystemData {
pub fn extract() -> Self {
Self {}
}
}