Skip to content
Snippets Groups Projects
Commit f4943999 authored by StarArawn's avatar StarArawn
Browse files

Moved layout code into the font.

parent 6b37be51
No related branches found
No related tags found
No related merge requests found
use bevy::{ use bevy::{
core_pipeline::{node::MAIN_PASS_DRIVER, MainPass2dNode}, core_pipeline::node::MAIN_PASS_DRIVER,
prelude::{Commands, Plugin, Res}, prelude::{Commands, Plugin, Res},
render2::{ render2::{
camera::ActiveCameras, camera::ActiveCameras,
......
use bevy::core::FloatOrd; use bevy::core::FloatOrd;
use bevy::core_pipeline::ClearColor;
use bevy::ecs::prelude::*; use bevy::ecs::prelude::*;
use bevy::render2::render_phase::{DrawFunctionId, PhaseItem}; use bevy::render2::render_phase::{DrawFunctionId, PhaseItem};
use bevy::render2::render_resource::{CachedPipelineId, RenderPassColorAttachment}; use bevy::render2::render_resource::{CachedPipelineId, RenderPassColorAttachment};
...@@ -67,7 +66,7 @@ impl Node for MainPassUINode { ...@@ -67,7 +66,7 @@ impl Node for MainPassUINode {
.query .query
.get_manual(world, view_entity) .get_manual(world, view_entity)
.expect("view entity should exist"); .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 { let pass_descriptor = RenderPassDescriptor {
label: Some("main_transparent_pass_UI"), label: Some("main_transparent_pass_UI"),
......
use bevy::{ use bevy::{
math::Vec2, math::Vec2,
prelude::{Assets, Commands, Res, ResMut}, prelude::{Assets, Commands, Res},
sprite2::Rect, sprite2::Rect,
}; };
use kayak_core::render_primitive::RenderPrimitive; use kayak_core::render_primitive::RenderPrimitive;
...@@ -16,7 +16,7 @@ use super::font_mapping::FontMapping; ...@@ -16,7 +16,7 @@ use super::font_mapping::FontMapping;
pub fn extract_texts( pub fn extract_texts(
mut commands: Commands, mut commands: Commands,
context: Res<BevyContext>, context: Res<BevyContext>,
mut fonts: ResMut<Assets<KayakFont>>, fonts: Res<Assets<KayakFont>>,
font_mapping: Res<FontMapping>, font_mapping: Res<FontMapping>,
) { ) {
let render_commands = if let Ok(context) = context.kayak_context.read() { let render_commands = if let Ok(context) = context.kayak_context.read() {
...@@ -45,53 +45,30 @@ pub fn extract_texts( ...@@ -45,53 +45,30 @@ pub fn extract_texts(
let font_handle = font_mapping.get_handle(font).unwrap(); let font_handle = font_mapping.get_handle(font).unwrap();
let font = fonts.get(font_handle.clone()).unwrap(); let font = fonts.get(font_handle.clone()).unwrap();
let max_glyph_size = font.sdf.max_glyph_size();
let mut x = 0.0; let chars_layouts =
for c in content.chars() { font.get_layout(Vec2::new(layout.posx, layout.posy), content, font_size);
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 font_ratio = font_size / font.sdf.atlas.size; for char_layout in chars_layouts {
let resized_max_glyph_size = extracted_texts.push(ExtractQuadBundle {
(max_glyph_size.x * font_ratio, max_glyph_size.y * font_ratio); extracted_quad: ExtractedQuad {
font_handle: Some(font_handle.clone()),
let position_x = layout.posx + x + left * font_size; rect: Rect {
let position_y = (layout.posy + (-top * font_size)) + font_size; min: char_layout.position,
extracted_texts.push(ExtractQuadBundle { max: char_layout.position + char_layout.size,
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,
}, },
}); color: to_bevy_color(background_color),
vertex_index: 0,
x += glyph.advance * font_size; 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); commands.spawn_batch(extracted_texts);
......
...@@ -12,7 +12,7 @@ use bevy::{ ...@@ -12,7 +12,7 @@ use bevy::{
}, },
utils::HashSet, utils::HashSet,
}; };
use kayak_font::{KayakFont, Sdf, FontTextureCache}; use kayak_font::{FontTextureCache, KayakFont, Sdf};
mod extract; mod extract;
mod font_mapping; mod font_mapping;
...@@ -54,7 +54,6 @@ fn load_fonts( ...@@ -54,7 +54,6 @@ fn load_fonts(
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
) { ) {
let sdf = Sdf::from_string(include_str!("../../../../../assets/roboto.json").to_string()); 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"); let atlas_image: Handle<Image> = asset_server.load("roboto.png");
......
use std::collections::HashMap; use std::collections::HashMap;
use bevy::{math::Vec2, prelude::Handle, reflect::TypeUuid, render2::texture::Image};
use bevy::{prelude::Handle, reflect::TypeUuid, render2::texture::Image};
use crate::Sdf; use crate::Sdf;
...@@ -13,6 +12,13 @@ pub struct KayakFont { ...@@ -13,6 +12,13 @@ pub struct KayakFont {
char_ids: HashMap<char, u32>, char_ids: HashMap<char, u32>,
} }
#[derive(Default, Debug, Clone, Copy)]
pub struct LayoutRect {
pub position: Vec2,
pub size: Vec2,
pub content: char,
}
impl KayakFont { impl KayakFont {
pub fn new(sdf: Sdf, atlas_image: Handle<Image>) -> Self { pub fn new(sdf: Sdf, atlas_image: Handle<Image>) -> Self {
Self { Self {
...@@ -33,4 +39,40 @@ impl KayakFont { ...@@ -33,4 +39,40 @@ impl KayakFont {
pub fn get_char_id(&self, c: char) -> Option<u32> { pub fn get_char_id(&self, c: char) -> Option<u32> {
self.char_ids.get(&c).and_then(|id| Some(*id)) 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
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment