From 20a46eb5260573418ef4941d227ce2a5bfbb25b9 Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 2 Jun 2020 00:55:26 -0400 Subject: [PATCH] Make all the fonts available in iced ui rework --- voxygen/src/menu/main/ui/connecting.rs | 19 +++++++---- voxygen/src/menu/main/ui/login.rs | 33 +++++++++++------- voxygen/src/menu/main/ui/mod.rs | 14 ++++++-- voxygen/src/ui/fonts.rs | 46 ++++++++++++++++++++++++-- voxygen/src/ui/ice/cache.rs | 27 ++++++++++++++- voxygen/src/ui/ice/mod.rs | 10 +++--- voxygen/src/ui/ice/renderer/mod.rs | 4 ++- voxygen/src/ui/mod.rs | 23 +++---------- 8 files changed, 126 insertions(+), 50 deletions(-) diff --git a/voxygen/src/menu/main/ui/connecting.rs b/voxygen/src/menu/main/ui/connecting.rs index 59cee400e1..2c463ca985 100644 --- a/voxygen/src/menu/main/ui/connecting.rs +++ b/voxygen/src/menu/main/ui/connecting.rs @@ -1,10 +1,13 @@ use super::{IcedImgs as Imgs, Message}; use crate::{ i18n::Localization, - ui::ice::{ - component::neat_button, - widget::{image, BackgroundContainer, Image}, - ButtonStyle, Element, + ui::{ + fonts::IcedFonts as Fonts, + ice::{ + component::neat_button, + widget::{image, BackgroundContainer, Image}, + ButtonStyle, Element, + }, }, }; use iced::{button, Color, Column, Container, HorizontalAlignment, Length, Row, Space, Text}; @@ -27,6 +30,7 @@ impl Screen { pub(super) fn view( &mut self, + fonts: &Fonts, imgs: &Imgs, bg_img: image::Handle, start: &std::time::Instant, @@ -43,13 +47,14 @@ impl Screen { .disabled_text_color(DISABLED_TEXT_COLOR); let version = Text::new(version) - .size(15) // move version text size to const + .size(fonts.cyri.scale(15)) // move version text size to const .width(Length::Fill) .height(Length::Fill) .horizontal_alignment(HorizontalAlignment::Right); let status = Text::new(status_text) - .size(80) + .size(fonts.alkhemi.scale(80)) + .font(fonts.alkhemi.id) .color(Color::from_rgba(1.0, 1.0, 1.0, fade_msg)) .width(Length::Fill); @@ -68,7 +73,7 @@ impl Screen { let cancel = Container::new(cancel) .width(Length::Fill) - .height(Length::Units(50)) + .height(Length::Units(fonts.cyri.scale(50))) .center_x() .padding(3); diff --git a/voxygen/src/menu/main/ui/login.rs b/voxygen/src/menu/main/ui/login.rs index 1d46028638..59725601d5 100644 --- a/voxygen/src/menu/main/ui/login.rs +++ b/voxygen/src/menu/main/ui/login.rs @@ -1,13 +1,16 @@ use super::{IcedImgs as Imgs, Info, LoginInfo, Message}; use crate::{ i18n::Localization, - ui::ice::{ - component::neat_button, - widget::{ - compound_graphic::{CompoundGraphic, Graphic}, - BackgroundContainer, Image, Padding, + ui::{ + fonts::IcedFonts as Fonts, + ice::{ + component::neat_button, + widget::{ + compound_graphic::{CompoundGraphic, Graphic}, + BackgroundContainer, Image, Padding, + }, + ButtonStyle, Element, }, - ButtonStyle, Element, }, }; use iced::{ @@ -45,6 +48,7 @@ impl Screen { pub(super) fn view( &mut self, + fonts: &Fonts, imgs: &Imgs, login_info: &LoginInfo, info: &Info, @@ -103,7 +107,7 @@ impl Screen { .color(Rgba::new(255, 255, 255, 240)), ]) .height(Length::Shrink), - Text::new(intro_text).size(21), + Text::new(intro_text).size(fonts.cyri.scale(21)), ) .max_width(450) .padding(Padding::new().horizontal(20).top(10).bottom(60)); @@ -117,7 +121,9 @@ impl Screen { buttons.into() }; - let banner = self.banner.view(imgs, login_info, i18n, button_style); + let banner = self + .banner + .view(fonts, imgs, login_info, i18n, button_style); let central_column = Container::new(banner) .width(Length::Fill) @@ -126,7 +132,7 @@ impl Screen { .align_y(Align::Center); let right_column = Text::new(version) - .size(15) + .size(fonts.cyri.scale(15)) .width(Length::Fill) .horizontal_alignment(HorizontalAlignment::Right); @@ -169,11 +175,14 @@ impl Banner { fn view( &mut self, + fonts: &Fonts, imgs: &Imgs, login_info: &LoginInfo, i18n: &Localization, button_style: ButtonStyle, ) -> Element { + let input_text_size = fonts.cyri.scale(INPUT_TEXT_SIZE); + let banner_content = Column::with_children(vec![ Image::new(imgs.v_logo) .fix_aspect_ratio() @@ -191,7 +200,7 @@ impl Banner { &login_info.username, Message::Username, ) - .size(INPUT_TEXT_SIZE) + .size(input_text_size) .on_submit(Message::FocusPassword), ) .padding(Padding::new().horizontal(10).top(10)) @@ -206,7 +215,7 @@ impl Banner { &login_info.password, Message::Password, ) - .size(INPUT_TEXT_SIZE) + .size(input_text_size) .password() .on_submit(Message::Multiplayer), ) @@ -222,7 +231,7 @@ impl Banner { &login_info.server, Message::Server, ) - .size(INPUT_TEXT_SIZE) + .size(input_text_size) .on_submit(Message::Multiplayer), ) .padding(Padding::new().horizontal(10).top(8)) diff --git a/voxygen/src/menu/main/ui/mod.rs b/voxygen/src/menu/main/ui/mod.rs index e6774244b6..96c8fbed0c 100644 --- a/voxygen/src/menu/main/ui/mod.rs +++ b/voxygen/src/menu/main/ui/mod.rs @@ -6,7 +6,7 @@ use crate::{ render::Renderer, ui::{ self, - fonts::Fonts, + fonts::{Fonts, IcedFonts}, ice::{Element, IcedUi}, img_ids::{BlankGraphic, ImageGraphic, VoxelGraphic}, Graphic, Ui, @@ -133,6 +133,7 @@ enum Screen { // TODO: use i18n font scale thing struct IcedState { + fonts: IcedFonts, imgs: IcedImgs, bg_img: widget::image::Handle, i18n: std::sync::Arc, @@ -166,6 +167,7 @@ enum Message { impl IcedState { fn new( + fonts: IcedFonts, imgs: IcedImgs, bg_img: widget::image::Handle, i18n: std::sync::Arc, @@ -184,6 +186,7 @@ impl IcedState { }; Self { + fonts, imgs, bg_img, i18n, @@ -211,6 +214,7 @@ impl IcedState { match &mut self.screen { Screen::Login { screen } => screen.view( + &self.fonts, &self.imgs, &self.login_info, &self.info, @@ -223,6 +227,7 @@ impl IcedState { start, status_text, } => screen.view( + &self.fonts, &self.imgs, self.bg_img, &start, @@ -409,7 +414,7 @@ impl<'a> MainMenuUi { // Load fonts. let fonts = Fonts::load(&i18n.fonts, &mut ui).expect("Impossible to load fonts!"); - // TODO: newtype Font + // TODO: don't add default font twice let ice_font = { use std::io::Read; let mut buf = Vec::new(); @@ -423,7 +428,12 @@ impl<'a> MainMenuUi { }; let mut ice_ui = IcedUi::new(window, ice_font).unwrap(); + + let ice_fonts = + IcedFonts::load(&i18n.fonts, &mut ice_ui).expect("Impossible to load fonts"); + let ice_state = IcedState::new( + ice_fonts, IcedImgs::load(&mut ice_ui).expect("Failed to load images"), ice_ui.add_graphic(Graphic::Image(DynamicImage::load_expect(bg_img_spec))), i18n.clone(), diff --git a/voxygen/src/ui/fonts.rs b/voxygen/src/ui/fonts.rs index 05ba6d3aab..d8afb3cdce 100644 --- a/voxygen/src/ui/fonts.rs +++ b/voxygen/src/ui/fonts.rs @@ -8,11 +8,11 @@ pub struct Font { impl Font { #[allow(clippy::needless_return)] // TODO: Pending review in #587 - pub fn new(font: &i18n::Font, ui: &mut crate::ui::Ui) -> Font { - return Self { + pub fn new(font: &i18n::Font, ui: &mut crate::ui::Ui) -> Self { + Self { metadata: font.clone(), conrod_id: ui.new_font(crate::ui::Font::load_expect(&font.asset_key)), - }; + } } /// Scale input size to final UI size @@ -40,3 +40,43 @@ macro_rules! conrod_fonts { conrod_fonts! { [opensans, metamorph, alkhemi, cyri, wizard] } + +pub struct IcedFont { + metadata: i18n::Font, + pub id: crate::ui::ice::FontId, +} + +impl IcedFont { + pub fn new(font: &i18n::Font, ui: &mut crate::ui::ice::IcedUi) -> Self { + Self { + metadata: font.clone(), + id: ui.add_font((*crate::ui::ice::RawFont::load_expect(&font.asset_key)).clone()), + } + } + + /// Scale input size to final UI size + /// TODO: change metadata to use u16 + pub fn scale(&self, value: u16) -> u16 { self.metadata.scale(value as u32) as u16 } +} + +macro_rules! iced_fonts { + ($([ $( $name:ident$(,)? )* ])*) => { + $( + pub struct IcedFonts { + $(pub $name: IcedFont,)* + } + + impl IcedFonts { + pub fn load(fonts: &i18n::Fonts, ui: &mut crate::ui::ice::IcedUi) -> Result { + Ok(Self { + $( $name: IcedFont::new(fonts.get(stringify!($name)).unwrap(), ui),)* + }) + } + } + )* + }; +} + +iced_fonts! { + [opensans, metamorph, alkhemi, cyri, wizard] +} diff --git a/voxygen/src/ui/ice/cache.rs b/voxygen/src/ui/ice/cache.rs index 8e20b3c4ab..3dfc25f777 100644 --- a/voxygen/src/ui/ice/cache.rs +++ b/voxygen/src/ui/ice/cache.rs @@ -15,8 +15,12 @@ const POSITION_TOLERANCE: f32 = 0.1; type GlyphBrush = glyph_brush::GlyphBrush<(Aabr, Aabr), ()>; +// TODO: might not need pub pub type Font = glyph_brush::ab_glyph::FontArc; +#[derive(Clone, Copy, Default)] +pub struct FontId(pub(super) glyph_brush::FontId); + pub struct Cache { glyph_brush: RefCell, glyph_cache_tex: Texture, @@ -56,7 +60,12 @@ impl Cache { pub fn glyph_calculator(&self) -> RefMut { self.glyph_brush.borrow_mut() } - // TODO: add font fn + // TODO: consider not re-adding default font + pub fn add_font(&mut self, font: RawFont) -> FontId { + let font = Font::try_from_vec(font.0).unwrap(); + let id = self.glyph_brush.get_mut().add_font(font); + FontId(id) + } pub fn graphic_cache(&self) -> &GraphicCache { &self.graphic_cache } @@ -91,3 +100,19 @@ impl Cache { Ok(()) } } + +// TODO: use font type instead of raw vec once we convert to full iced +#[derive(Clone)] +pub struct RawFont(pub Vec); +impl common::assets::Asset for RawFont { + const ENDINGS: &'static [&'static str] = &["ttf"]; + + fn parse( + mut buf_reader: std::io::BufReader, + ) -> Result { + use std::io::Read; + let mut buf = Vec::new(); + buf_reader.read_to_end(&mut buf)?; + Ok(Self(buf)) + } +} diff --git a/voxygen/src/ui/ice/mod.rs b/voxygen/src/ui/ice/mod.rs index b7791e4638..1a45117781 100644 --- a/voxygen/src/ui/ice/mod.rs +++ b/voxygen/src/ui/ice/mod.rs @@ -6,7 +6,7 @@ mod renderer; pub mod widget; mod winit_conversion; -pub use cache::Font; +pub use cache::{Font, FontId, RawFont}; pub use graphic::{Id, Rotation}; pub use iced::Event; pub use renderer::{ButtonStyle, IcedRenderer}; @@ -23,9 +23,6 @@ use vek::*; pub type Element<'a, M> = iced::Element<'a, M, IcedRenderer>; -#[derive(Clone, Copy, Default)] -pub struct FontId(glyph_brush::FontId); - pub struct IcedUi { renderer: IcedRenderer, cache: Option, @@ -54,7 +51,10 @@ impl IcedUi { }) } - // Add an new graphic that is referencable via the returned Id + /// Add a new font that is referncable via the returned Id + pub fn add_font(&mut self, font: RawFont) -> FontId { self.renderer.add_font(font) } + + /// Add a new graphic that is referencable via the returned Id pub fn add_graphic(&mut self, graphic: Graphic) -> graphic::Id { self.renderer.add_graphic(graphic) } diff --git a/voxygen/src/ui/ice/renderer/mod.rs b/voxygen/src/ui/ice/renderer/mod.rs index 02774e09a5..a5cf9aa4da 100644 --- a/voxygen/src/ui/ice/renderer/mod.rs +++ b/voxygen/src/ui/ice/renderer/mod.rs @@ -12,7 +12,7 @@ use super::{ super::graphic::{self, Graphic, TexId}, cache::Cache, widget::image, - Font, Rotation, + Font, FontId, RawFont, Rotation, }; use crate::{ render::{ @@ -127,6 +127,8 @@ impl IcedRenderer { }) } + pub fn add_font(&mut self, font: RawFont) -> FontId { self.cache.add_font(font) } + pub fn add_graphic(&mut self, graphic: Graphic) -> graphic::Id { self.cache.add_graphic(graphic) } diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index 158bcd31d4..6cf668eeb7 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -47,12 +47,7 @@ use conrod_core::{ use core::{convert::TryInto, f32, f64, ops::Range}; use graphic::TexId; use hashbrown::hash_map::Entry; -use std::{ - fs::File, - io::{BufReader, Read}, - sync::Arc, - time::Duration, -}; +use std::{sync::Arc, time::Duration}; use tracing::{error, warn}; use vek::*; @@ -102,17 +97,6 @@ impl DrawCommand { } } -pub struct Font(text::Font); -impl assets::Asset for Font { - const ENDINGS: &'static [&'static str] = &["ttf"]; - - fn parse(mut buf_reader: BufReader, _specifier: &str) -> Result { - let mut buf = Vec::new(); - buf_reader.read_to_end(&mut buf)?; - Ok(Font(text::Font::from_bytes(buf).unwrap())) - } -} - pub struct Ui { pub ui: conrod_core::Ui, image_map: Map<(graphic::Id, Rotation)>, @@ -224,8 +208,9 @@ impl Ui { self.image_map.replace(id, (graphic_id, Rotation::None)); } - pub fn new_font(&mut self, font: Arc) -> font::Id { - self.ui.fonts.insert(font.as_ref().0.clone()) + pub fn new_font(&mut self, font: Arc) -> font::Id { + let font = text::Font::from_bytes(font.0.clone()).unwrap(); + self.ui.fonts.insert(font) } pub fn id_generator(&mut self) -> Generator { self.ui.widget_id_generator() }