From f4943999cf97fd5bded738a774c88feeacfa08d9 Mon Sep 17 00:00:00 2001 From: StarArawn <toasterthegamer@gmail.com> Date: Sat, 11 Dec 2021 09:47:11 -0500 Subject: [PATCH] Moved layout code into the font. --- bevy_kayak_ui/src/render/mod.rs | 2 +- bevy_kayak_ui/src/render/ui_pass.rs | 3 +- .../src/render/unified/font/extract.rs | 69 +++++++------------ bevy_kayak_ui/src/render/unified/font/mod.rs | 3 +- kayak_font/src/font.rs | 46 ++++++++++++- 5 files changed, 70 insertions(+), 53 deletions(-) diff --git a/bevy_kayak_ui/src/render/mod.rs b/bevy_kayak_ui/src/render/mod.rs index 47655a5..4e38626 100644 --- a/bevy_kayak_ui/src/render/mod.rs +++ b/bevy_kayak_ui/src/render/mod.rs @@ -1,5 +1,5 @@ use bevy::{ - core_pipeline::{node::MAIN_PASS_DRIVER, MainPass2dNode}, + core_pipeline::node::MAIN_PASS_DRIVER, prelude::{Commands, Plugin, Res}, render2::{ camera::ActiveCameras, diff --git a/bevy_kayak_ui/src/render/ui_pass.rs b/bevy_kayak_ui/src/render/ui_pass.rs index d78ccec..0d37c93 100644 --- a/bevy_kayak_ui/src/render/ui_pass.rs +++ b/bevy_kayak_ui/src/render/ui_pass.rs @@ -1,5 +1,4 @@ use bevy::core::FloatOrd; -use bevy::core_pipeline::ClearColor; use bevy::ecs::prelude::*; use bevy::render2::render_phase::{DrawFunctionId, PhaseItem}; use bevy::render2::render_resource::{CachedPipelineId, RenderPassColorAttachment}; @@ -67,7 +66,7 @@ impl Node for MainPassUINode { .query .get_manual(world, view_entity) .expect("view entity should exist"); - let clear_color = world.get_resource::<ClearColor>().unwrap(); + // let clear_color = world.get_resource::<ClearColor>().unwrap(); { let pass_descriptor = RenderPassDescriptor { label: Some("main_transparent_pass_UI"), diff --git a/bevy_kayak_ui/src/render/unified/font/extract.rs b/bevy_kayak_ui/src/render/unified/font/extract.rs index 6bc4a3a..feae2c4 100644 --- a/bevy_kayak_ui/src/render/unified/font/extract.rs +++ b/bevy_kayak_ui/src/render/unified/font/extract.rs @@ -1,6 +1,6 @@ use bevy::{ math::Vec2, - prelude::{Assets, Commands, Res, ResMut}, + prelude::{Assets, Commands, Res}, sprite2::Rect, }; use kayak_core::render_primitive::RenderPrimitive; @@ -16,7 +16,7 @@ use super::font_mapping::FontMapping; pub fn extract_texts( mut commands: Commands, context: Res<BevyContext>, - mut fonts: ResMut<Assets<KayakFont>>, + fonts: Res<Assets<KayakFont>>, font_mapping: Res<FontMapping>, ) { let render_commands = if let Ok(context) = context.kayak_context.read() { @@ -45,53 +45,30 @@ pub fn extract_texts( let font_handle = font_mapping.get_handle(font).unwrap(); let font = fonts.get(font_handle.clone()).unwrap(); - let max_glyph_size = font.sdf.max_glyph_size(); - let mut x = 0.0; - for c in content.chars() { - if let Some(glyph) = font.sdf.glyphs.iter().find(|glyph| glyph.unicode == c) { - let plane_bounds = glyph.plane_bounds.as_ref(); - let (left, top, _width, _height) = match plane_bounds { - Some(val) => ( - val.left, - val.top, - val.size().x * font_size, - val.size().y * font_size, - ), - None => (0.0, 0.0, 0.0, 0.0), - }; + let chars_layouts = + font.get_layout(Vec2::new(layout.posx, layout.posy), content, font_size); - let font_ratio = font_size / font.sdf.atlas.size; - let resized_max_glyph_size = - (max_glyph_size.x * font_ratio, max_glyph_size.y * font_ratio); - - let position_x = layout.posx + x + left * font_size; - let position_y = (layout.posy + (-top * font_size)) + font_size; - extracted_texts.push(ExtractQuadBundle { - extracted_quad: ExtractedQuad { - font_handle: Some(font_handle.clone()), - rect: Rect { - min: Vec2::new(position_x, position_y), - max: Vec2::new( - position_x + resized_max_glyph_size.0, - position_y + resized_max_glyph_size.1, - ), - }, - color: to_bevy_color(background_color), - vertex_index: 0, - char_id: font.get_char_id(c).unwrap(), - z_index: layout.z_index, - quad_type: UIQuadType::Text, - type_index: 0, - border_radius: (0.0, 0.0, 0.0, 0.0), - image: None, - uv_max: None, - uv_min: None, + for char_layout in chars_layouts { + extracted_texts.push(ExtractQuadBundle { + extracted_quad: ExtractedQuad { + font_handle: Some(font_handle.clone()), + rect: Rect { + min: char_layout.position, + max: char_layout.position + char_layout.size, }, - }); - - x += glyph.advance * font_size; - } + color: to_bevy_color(background_color), + vertex_index: 0, + char_id: font.get_char_id(char_layout.content).unwrap(), + z_index: layout.z_index, + quad_type: UIQuadType::Text, + type_index: 0, + border_radius: (0.0, 0.0, 0.0, 0.0), + image: None, + uv_max: None, + uv_min: None, + }, + }); } } commands.spawn_batch(extracted_texts); diff --git a/bevy_kayak_ui/src/render/unified/font/mod.rs b/bevy_kayak_ui/src/render/unified/font/mod.rs index 5ea79d0..f4cd0ba 100644 --- a/bevy_kayak_ui/src/render/unified/font/mod.rs +++ b/bevy_kayak_ui/src/render/unified/font/mod.rs @@ -12,7 +12,7 @@ use bevy::{ }, utils::HashSet, }; -use kayak_font::{KayakFont, Sdf, FontTextureCache}; +use kayak_font::{FontTextureCache, KayakFont, Sdf}; mod extract; mod font_mapping; @@ -54,7 +54,6 @@ fn load_fonts( asset_server: Res<AssetServer>, ) { let sdf = Sdf::from_string(include_str!("../../../../../assets/roboto.json").to_string()); - let max_glyph_size = sdf.max_glyph_size(); let atlas_image: Handle<Image> = asset_server.load("roboto.png"); diff --git a/kayak_font/src/font.rs b/kayak_font/src/font.rs index 2a2b06d..69a5802 100644 --- a/kayak_font/src/font.rs +++ b/kayak_font/src/font.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; - -use bevy::{prelude::Handle, reflect::TypeUuid, render2::texture::Image}; +use bevy::{math::Vec2, prelude::Handle, reflect::TypeUuid, render2::texture::Image}; use crate::Sdf; @@ -13,6 +12,13 @@ pub struct KayakFont { char_ids: HashMap<char, u32>, } +#[derive(Default, Debug, Clone, Copy)] +pub struct LayoutRect { + pub position: Vec2, + pub size: Vec2, + pub content: char, +} + impl KayakFont { pub fn new(sdf: Sdf, atlas_image: Handle<Image>) -> Self { Self { @@ -33,4 +39,40 @@ impl KayakFont { pub fn get_char_id(&self, c: char) -> Option<u32> { self.char_ids.get(&c).and_then(|id| Some(*id)) } + + pub fn get_layout(&self, position: Vec2, content: &String, font_size: f32) -> Vec<LayoutRect> { + let mut positions_and_size = Vec::new(); + let max_glyph_size = self.sdf.max_glyph_size(); + let font_ratio = font_size / self.sdf.atlas.size; + let resized_max_glyph_size = (max_glyph_size.x * font_ratio, max_glyph_size.y * font_ratio); + + let mut x = 0.0; + for c in content.chars() { + if let Some(glyph) = self.sdf.glyphs.iter().find(|glyph| glyph.unicode == c) { + let plane_bounds = glyph.plane_bounds.as_ref(); + let (left, top, _width, _height) = match plane_bounds { + Some(val) => ( + val.left, + val.top, + val.size().x * font_size, + val.size().y * font_size, + ), + None => (0.0, 0.0, 0.0, 0.0), + }; + + let position_x = position.x + x + left * font_size; + let position_y = (position.y + (-top * font_size)) + font_size; + + positions_and_size.push(LayoutRect { + position: Vec2::new(position_x, position_y), + size: Vec2::new(resized_max_glyph_size.0, resized_max_glyph_size.1), + content: c, + }); + + x += glyph.advance * font_size; + } + } + + positions_and_size + } } -- GitLab