diff --git a/kayak_font/src/bevy/loader.rs b/kayak_font/src/bevy/loader.rs index 763bfe467b4043db60d0e896c2d30503a95bdb98..6e9c236e4ee50566280f52b5006ec1db3e3ec161 100644 --- a/kayak_font/src/bevy/loader.rs +++ b/kayak_font/src/bevy/loader.rs @@ -1,4 +1,4 @@ -use crate::{KayakFont, Sdf, ImageType}; +use crate::{ImageType, KayakFont, Sdf}; use bevy::asset::{AssetLoader, AssetPath, BoxedFuture, LoadContext, LoadedAsset}; #[derive(Default)] diff --git a/kayak_font/src/bevy/renderer/font_texture_cache.rs b/kayak_font/src/bevy/renderer/font_texture_cache.rs index d2097167428163504acda3866bb5f5990e5238f0..ec1baecfc02a7489c1f2b4f9e5e67b783ea1f21c 100644 --- a/kayak_font/src/bevy/renderer/font_texture_cache.rs +++ b/kayak_font/src/bevy/renderer/font_texture_cache.rs @@ -1,4 +1,4 @@ -use crate::{KayakFont, Sdf, ImageType}; +use crate::{ImageType, KayakFont, Sdf}; use bevy::{ math::Vec2, prelude::{Handle, Res, Resource}, diff --git a/kayak_font/src/lib.rs b/kayak_font/src/lib.rs index f1ab7d4cb885800bc065240efdb192301848cbf2..30e246008d37a7c67aee7fc29d05a37d0c6867ca 100644 --- a/kayak_font/src/lib.rs +++ b/kayak_font/src/lib.rs @@ -3,10 +3,10 @@ mod font; mod glyph; mod layout; mod metrics; +mod msdf; mod sdf; -mod utility; mod ttf; -mod msdf; +mod utility; pub use atlas::*; pub use font::*; @@ -20,14 +20,17 @@ pub mod bevy; #[cfg(test)] mod tests { - use crate::{Alignment, KayakFont, Sdf, TextProperties, ImageType}; + use crate::{Alignment, ImageType, KayakFont, Sdf, TextProperties}; fn make_font() -> KayakFont { let bytes = std::fs::read("assets/roboto.kayak_font") .expect("a `roboto.kayak_font` file in the `assets/` directory of this crate"); #[cfg(feature = "bevy_renderer")] - return KayakFont::new(Sdf::from_bytes(&bytes), ImageType::Atlas(bevy::asset::Handle::default())); + return KayakFont::new( + Sdf::from_bytes(&bytes), + ImageType::Atlas(bevy::asset::Handle::default()), + ); #[cfg(not(feature = "bevy_renderer"))] return KayakFont::new(Sdf::from_bytes(&bytes)); diff --git a/kayak_font/src/msdf/contour.rs b/kayak_font/src/msdf/contour.rs index 672d37764a8ef6b3afe76af83425cb4a8f082bc3..dc3f55adbf13e115851d8abbfa8609b29028db95 100644 --- a/kayak_font/src/msdf/contour.rs +++ b/kayak_font/src/msdf/contour.rs @@ -148,11 +148,20 @@ impl Contour { return Vector2::sign(total) as i32; } - pub fn bound_miters(&self, l: &mut f64, b: &mut f64, r: &mut f64, t: &mut f64, border: f64, miter_limit: f64, polarity: i32) { + pub fn bound_miters( + &self, + l: &mut f64, + b: &mut f64, + r: &mut f64, + t: &mut f64, + border: f64, + miter_limit: f64, + polarity: i32, + ) { if self.edges.is_empty() { return; } - + let mut prev_dir = self.edges.last().unwrap().direction(1.0).normalize(true); for edge in self.edges.iter() { @@ -164,7 +173,8 @@ impl Contour { let q = 0.5 * (1.0 - Vector2::dot_product(prev_dir, dir)); if q > 0.0 { miter_length = (1.0 / q.sqrt()).min(miter_limit); - let miter = edge.point(0.0) + border * miter_length * (prev_dir + dir).normalize(true); + let miter = + edge.point(0.0) + border * miter_length * (prev_dir + dir).normalize(true); bound_point(l, b, r, t, miter); } } @@ -186,4 +196,4 @@ fn bound_point(l: &mut f64, b: &mut f64, r: &mut f64, t: &mut f64, p: Vector2) { if p.y > *t { *t = p.y; } -} \ No newline at end of file +} diff --git a/kayak_font/src/msdf/edge_coloring.rs b/kayak_font/src/msdf/edge_coloring.rs index 46436d7a593cd33d62bc0f8adbc3b8916d150e2f..b74f326fc602802d9baa702e7965034010fdf7c4 100644 --- a/kayak_font/src/msdf/edge_coloring.rs +++ b/kayak_font/src/msdf/edge_coloring.rs @@ -261,17 +261,27 @@ pub fn ink_trap(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { for i in 0..corner_count { if !corners[i].minor { major_corner_count -= 1; - switch_color(&mut color, &mut seed, num::cast::FromPrimitive::from_usize(!major_corner_count * initial_color as usize).unwrap()); + switch_color( + &mut color, + &mut seed, + num::cast::FromPrimitive::from_usize( + !major_corner_count * initial_color as usize, + ) + .unwrap(), + ); corners[i].color = color; if initial_color != EdgeColor::BLACK { initial_color = color; } } - } + } for i in 0..corner_count { if corners[i].minor { let next_color = corners[(i + 1) % corner_count].color; - corners[i].color = num::cast::FromPrimitive::from_usize((color as usize & next_color as usize) ^ EdgeColor::WHITE as usize).unwrap(); + corners[i].color = num::cast::FromPrimitive::from_usize( + (color as usize & next_color as usize) ^ EdgeColor::WHITE as usize, + ) + .unwrap(); } else { color = corners[i].color; } @@ -283,7 +293,8 @@ pub fn ink_trap(shape: &mut Shape, angle_threshold: f64, mut seed: usize) { let m = contour.edges.len(); for i in 0..m { let index = (start + i) % m; - if spline + 1 < corner_count && corners[spline + 1].index as usize == index { + if spline + 1 < corner_count && corners[spline + 1].index as usize == index + { spline += 1; color = corners[spline].color; } diff --git a/kayak_font/src/msdf/edge_segment/cubic.rs b/kayak_font/src/msdf/edge_segment/cubic.rs index c59c37522b86b44d9ed5b0c174e969e91dae134d..21444bfa057dc957a9b6cd2680826390bb9dd1d2 100644 --- a/kayak_font/src/msdf/edge_segment/cubic.rs +++ b/kayak_font/src/msdf/edge_segment/cubic.rs @@ -128,8 +128,8 @@ pub fn signed_distance( ep_dir = direction(p0, p1, p2, p3, 1.0); let distance = (p3 - origin).length(); if distance.abs() < min_distance.abs() { - min_distance = non_zero_sign(Vector2::cross_product(ep_dir, p3 - origin)) as f64 - * distance; + min_distance = + non_zero_sign(Vector2::cross_product(ep_dir, p3 - origin)) as f64 * distance; param = Vector2::dot_product(ep_dir - (p3 - origin), ep_dir) / Vector2::dot_product(ep_dir, ep_dir); } @@ -137,12 +137,13 @@ pub fn signed_distance( for i in 0..MSDFGEN_CUBIC_SEARCH_STARTS { let mut t = (i / MSDFGEN_CUBIC_SEARCH_STARTS) as f64; - let mut qe = qa + 3.0 * t * ab + 3.0 * t * t * br + t * t *t * as_; + let mut qe = qa + 3.0 * t * ab + 3.0 * t * t * br + t * t * t * as_; for _ in 0..MSDFGEN_CUBIC_SEARCH_STEPS { let d1 = 3.0 * ab + 6.0 * t * br + 3.0 * t * t * as_; let d2 = 6.0 * br + 6.0 * t * as_; - t -= Vector2::dot_product(qe, d1) / (Vector2::dot_product(d1, d1) + Vector2::dot_product(qe, d2)); - + t -= Vector2::dot_product(qe, d1) + / (Vector2::dot_product(d1, d1) + Vector2::dot_product(qe, d2)); + if t < 0.0 || t > 1.0 { break; } diff --git a/kayak_font/src/msdf/edge_segment/mod.rs b/kayak_font/src/msdf/edge_segment/mod.rs index de0d53ef611ecdb390d68424dbf1f3728f82c66e..41411b487fe3213046cb41ee2268910f6117192f 100644 --- a/kayak_font/src/msdf/edge_segment/mod.rs +++ b/kayak_font/src/msdf/edge_segment/mod.rs @@ -54,12 +54,18 @@ impl EdgeSegment { pub fn new_quadratic(p0: Vector2, mut p1: Vector2, p2: Vector2, color: EdgeColor) -> Self { if p1 == p0 || p1 == p2 { - p1 = 0.5*(p0+p2); + p1 = 0.5 * (p0 + p2); } Self::QuadraticSegment { p0, p1, p2, color } } - pub fn new_cubic(p0: Vector2, mut p1: Vector2, mut p2: Vector2, p3: Vector2, color: EdgeColor) -> Self { + pub fn new_cubic( + p0: Vector2, + mut p1: Vector2, + mut p2: Vector2, + p3: Vector2, + color: EdgeColor, + ) -> Self { if (p1 == p0 || p1 == p3) && (p2 == p0 || p2 == p3) { p1 = mix(p0, p3, 1.0 / 3.0); p2 = mix(p0, p3, 2.0 / 3.0); diff --git a/kayak_font/src/msdf/gen.rs b/kayak_font/src/msdf/gen.rs index 54fe2bebc97c837ad54c25e9eebb1d2040c20faa..61cc4f9f581e9af5213fdd022df8267dea1d053a 100644 --- a/kayak_font/src/msdf/gen.rs +++ b/kayak_font/src/msdf/gen.rs @@ -63,7 +63,9 @@ pub fn pixel_clash(a: FloatRGB, b: FloatRGB, threshold: f64) -> bool { } } - ((b1 - a1).abs() >= threshold as f32) && !(b0 == b1 && b0 == b2) && (a2 - 0.5).abs() >= (b2 - 0.5).abs() + ((b1 - a1).abs() >= threshold as f32) + && !(b0 == b1 && b0 == b2) + && (a2 - 0.5).abs() >= (b2 - 0.5).abs() // let a_calcd = if a.r > 0.5 { 1.0 } else { 0.0 } // + if a.g > 0.5 { 1.0 } else { 0.0 } diff --git a/kayak_font/src/msdf/shape.rs b/kayak_font/src/msdf/shape.rs index 62f18a483e194fcae1cf1b8bbc3f4f179b63633f..5b4d34f3f636dd3bf207d820a3e892e3bacb83a9 100644 --- a/kayak_font/src/msdf/shape.rs +++ b/kayak_font/src/msdf/shape.rs @@ -26,19 +26,22 @@ impl Shape { } } - fn find_bounds( - &mut self, - left: &mut f64, - bottom: &mut f64, - right: &mut f64, - top: &mut f64, - ) { + fn find_bounds(&mut self, left: &mut f64, bottom: &mut f64, right: &mut f64, top: &mut f64) { for contour in self.contours.iter_mut() { contour.find_bounds(left, bottom, right, top); } } - pub fn bound_miters(&self, l: &mut f64, b: &mut f64, r: &mut f64, t: &mut f64, border: f64, miter_limit: f64, polarity: i32) { + pub fn bound_miters( + &self, + l: &mut f64, + b: &mut f64, + r: &mut f64, + t: &mut f64, + border: f64, + miter_limit: f64, + polarity: i32, + ) { for contour in self.contours.iter() { contour.bound_miters(l, b, r, t, border, miter_limit, polarity); } diff --git a/kayak_font/src/ttf/loader.rs b/kayak_font/src/ttf/loader.rs index 0a12a7f07846436cc1dcc5701c745de848a5a192..ad1d68711a3e3589bd56afbe0730fb93b3efd42b 100644 --- a/kayak_font/src/ttf/loader.rs +++ b/kayak_font/src/ttf/loader.rs @@ -1,5 +1,5 @@ use bevy::{ - asset::{AssetLoader, LoadContext, LoadedAsset, FileAssetIo}, + asset::{AssetLoader, FileAssetIo, LoadContext, LoadedAsset}, render::render_resource::{Extent3d, TextureFormat}, utils::{BoxedFuture, HashMap}, }; @@ -26,7 +26,10 @@ impl AssetLoader for TTFLoader { load_context: &'a mut LoadContext, ) -> BoxedFuture<'a, Result<(), anyhow::Error>> { Box::pin(async move { - let asset_io = load_context.asset_io().downcast_ref::<FileAssetIo>().unwrap(); + let asset_io = load_context + .asset_io() + .downcast_ref::<FileAssetIo>() + .unwrap(); let kttf: KTTF = nanoserde::DeJson::deserialize_json(std::str::from_utf8(bytes).unwrap()).unwrap(); @@ -37,7 +40,13 @@ impl AssetLoader for TTFLoader { let font_bytes = load_context.read_asset_bytes(kttf.file).await?; let mut cache_path = std::path::PathBuf::from(load_context.path()); - let file_name = load_context.path().file_name().unwrap().to_str().unwrap().to_string(); + let file_name = load_context + .path() + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_string(); cache_path.set_file_name(format!("{}-cached.png", file_name)); let cache_image = load_context.read_asset_bytes(&cache_path).await; @@ -138,14 +147,16 @@ impl AssetLoader for TTFLoader { ); // let left = (translation.x - char_bounds.x_min as f64 * pixel_scale).max(0.0).floor() as u32; - let right = (translation.x + char_bounds.x_max as f64 * pixel_scale).floor() as u32; + let right = + (translation.x + char_bounds.x_max as f64 * pixel_scale).floor() as u32; // let top = (translation.y - char_bounds.y_min as f64 * pixel_scale).max(0.0).floor() as u32; - let bottom = (translation.y + char_bounds.y_max as f64 * pixel_scale).floor() as u32; - + let bottom = + (translation.y + char_bounds.y_max as f64 * pixel_scale).floor() as u32; + for x in 0..(right + 2).min(64) { for y in 0..bottom + 48 { - // for x in 0..size_x as u32 { - // for y in 0..size_y as u32 { + // for x in 0..size_x as u32 { + // for y in 0..size_y as u32 { let pixel = output.get_pixel(x as usize, y as usize); image_builder.put_pixel( x, @@ -168,7 +179,9 @@ impl AssetLoader for TTFLoader { } let image_bytes = if cache_image.is_err() { - image_builder.save(asset_io.root_path().join(cache_path)).unwrap(); + image_builder + .save(asset_io.root_path().join(cache_path)) + .unwrap(); image_builder.as_bytes().to_vec() } else { let cache_image = cache_image.unwrap(); @@ -275,10 +288,10 @@ fn calculate_plane( ( Vector2::new(translation_x, translation_y) * geometry_scale as f64, Rect { - left: 0.0, // l as f32, - bottom: 0.0, // b as f32, - right: 0.0, // r as f32, - top: 24.0 * geometry_scale, // t as f32, + left: 0.0, // l as f32, + bottom: 0.0, // b as f32, + right: 0.0, // r as f32, + top: 24.0 * geometry_scale, // t as f32, }, ) }