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