diff --git a/assets/lato-light.kttf b/assets/lato-light.kttf index 15e547e1171fc26bd38cfd25279144307481d46c..a4088c10216b5bf7172ba407895f446d1ca94598 100644 --- a/assets/lato-light.kttf +++ b/assets/lato-light.kttf @@ -1,5 +1,7 @@ { "file": "lato-light.ttf", "char_range_start": "0x20", - "char_range_end": "0x7f" + "char_range_end": "0x7f", + "offset_x": 0.0, + "offset_y": 25.0, } \ No newline at end of file diff --git a/assets/roboto.kttf b/assets/roboto.kttf index 9c7d59c6ed7f1c15a4d89b38b98ae946f470213b..d6411ede9bc5e2d8aa598405121d96b8028640a7 100644 --- a/assets/roboto.kttf +++ b/assets/roboto.kttf @@ -1,5 +1,7 @@ { "file": "roboto.ttf", "char_range_start": "0x20", - "char_range_end": "0x7f" + "char_range_end": "0x7f", + "offset_x": 0.0, + "offset_y": 25.0, } \ No newline at end of file diff --git a/examples/layout.rs b/examples/layout.rs index 41e335a54a0255ba8db2998b4a4468d87c91f3a9..6fdc489262656d4c4e1dc796f472809824ce5572 100644 --- a/examples/layout.rs +++ b/examples/layout.rs @@ -128,7 +128,7 @@ fn startup( </ElementBundle> </WindowBundle> </KayakAppBundle> - } + }; commands.spawn(UICameraBundle::new(widget_context)); } diff --git a/kayak_font/assets/lato-light.kttf b/kayak_font/assets/lato-light.kttf new file mode 100644 index 0000000000000000000000000000000000000000..a4088c10216b5bf7172ba407895f446d1ca94598 --- /dev/null +++ b/kayak_font/assets/lato-light.kttf @@ -0,0 +1,7 @@ +{ + "file": "lato-light.ttf", + "char_range_start": "0x20", + "char_range_end": "0x7f", + "offset_x": 0.0, + "offset_y": 25.0, +} \ No newline at end of file diff --git a/kayak_font/assets/lato-light.kttf-cached.png b/kayak_font/assets/lato-light.kttf-cached.png new file mode 100644 index 0000000000000000000000000000000000000000..6163dc114490f069d785bef1b745bbca5ac7051d Binary files /dev/null and b/kayak_font/assets/lato-light.kttf-cached.png differ diff --git a/kayak_font/assets/lato-light.ttf b/kayak_font/assets/lato-light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..dfa72ce808fbb783042da88ce1bae5d9adb54fb6 Binary files /dev/null and b/kayak_font/assets/lato-light.ttf differ diff --git a/kayak_font/assets/roboto.kttf b/kayak_font/assets/roboto.kttf index 9c7d59c6ed7f1c15a4d89b38b98ae946f470213b..d6411ede9bc5e2d8aa598405121d96b8028640a7 100644 --- a/kayak_font/assets/roboto.kttf +++ b/kayak_font/assets/roboto.kttf @@ -1,5 +1,7 @@ { "file": "roboto.ttf", "char_range_start": "0x20", - "char_range_end": "0x7f" + "char_range_end": "0x7f", + "offset_x": 0.0, + "offset_y": 25.0, } \ No newline at end of file diff --git a/kayak_font/examples/renderer/shader.wgsl b/kayak_font/examples/renderer/shader.wgsl index 4bfdf8f701d0c5f46187aefc63043144488e487a..36af3a3045da9d17a6dfe361f221bdf6d84517c4 100644 --- a/kayak_font/examples/renderer/shader.wgsl +++ b/kayak_font/examples/renderer/shader.wgsl @@ -41,7 +41,7 @@ var font_sampler: sampler; @fragment fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { - var px_range = 2.5; + var px_range = 4.5; var tex_dimensions = textureDimensions(font_texture); var msdf_unit = vec2<f32>(px_range, px_range) / vec2<f32>(f32(tex_dimensions.x), f32(tex_dimensions.y)); var x = textureSample(font_texture, font_sampler, vec2<f32>(in.uv.x, in.uv.y), i32(in.uv.z)); diff --git a/kayak_font/src/ttf/loader.rs b/kayak_font/src/ttf/loader.rs index 2c39c09b89517636e9412b1e22e1ddf380e49d21..1b3664375300bf11c9be2e881ae478c731ed24bb 100644 --- a/kayak_font/src/ttf/loader.rs +++ b/kayak_font/src/ttf/loader.rs @@ -21,6 +21,8 @@ pub struct KTTF { file: String, char_range_start: String, char_range_end: String, + offset_x: Option<f32>, + offset_y: Option<f32>, } impl AssetLoader for TTFLoader { @@ -43,7 +45,7 @@ impl AssetLoader for TTFLoader { u32::from_str_radix(kttf.char_range_start.trim_start_matches("0x"), 16)?; let char_range_end = u32::from_str_radix(kttf.char_range_end.trim_start_matches("0x"), 16)?; - let font_bytes = load_context.read_asset_bytes(kttf.file).await?; + let font_bytes = load_context.read_asset_bytes(kttf.file.clone()).await?; let mut cache_path = std::path::PathBuf::from(load_context.path()); let file_name = load_context @@ -85,6 +87,8 @@ impl AssetLoader for TTFLoader { } } + let loaded_file = &kttf; + for char_u in font_range { let c = char::from_u32(char_u).unwrap(); let glyph_id = *char_to_glyph.get(&c).unwrap(); @@ -108,11 +112,17 @@ impl AssetLoader for TTFLoader { // let (left, bottom, right, top) = shape.get_bounds(); let scale = Vector2::new(1.0, 1.0); - let px_range = 2.0; + let px_range = 2.5; let range = px_range / scale.x.min(scale.y); - let (translation, plane) = - calculate_plane(&mut shape, pixel_scale as f32, 1.0, px_range as f32, 1.0); + let (translation, plane) = calculate_plane( + loaded_file, + &mut shape, + pixel_scale as f32, + 1.0, + px_range as f32, + 1.0, + ); let advance = face.glyph_hor_advance(glyph_id).unwrap_or(0) as f32 / size_x as f32; let c = *glyph_to_char.get(&glyph_id).unwrap(); glyphs.push(Glyph { @@ -208,7 +218,7 @@ impl AssetLoader for TTFLoader { }, bevy::render::render_resource::TextureDimension::D2, image_bytes, - TextureFormat::Rgba8UnormSrgb, + TextureFormat::Rgba8Unorm, ); image.reinterpret_stacked_2d_as_array(char_count); let image_handle = @@ -227,6 +237,7 @@ impl AssetLoader for TTFLoader { } fn calculate_plane( + loaded_file: &KTTF, shape: &mut Shape, geometry_scale: f32, scale: f32, @@ -292,13 +303,20 @@ fn calculate_plane( // t = geometry_scale as f64 * (-translation_y + (h as f64 - 0.5) * inv_box_scale); // } + let left = loaded_file + .offset_x + .unwrap_or_default(); + let top = loaded_file + .offset_y + .unwrap_or_default(); + ( 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: left * geometry_scale, // l as f32, + bottom: 0.0, // b as f32, + right: 0.0, // r as f32, + top: top * geometry_scale, //0.0, // t as f32, }, ) } diff --git a/src/render/texture_atlas/extract.rs b/src/render/texture_atlas/extract.rs index 3e343fec29efb825f68afdd160acb381c25d061a..24f7c8d876abc73e5936e5d800e1ea2d8fc4b667 100644 --- a/src/render/texture_atlas/extract.rs +++ b/src/render/texture_atlas/extract.rs @@ -13,7 +13,7 @@ pub fn extract_texture_atlas( camera_entity: Entity, render_primitive: &RenderPrimitive, images: &Res<Assets<Image>>, - dpi: f32, + _dpi: f32, ) -> Vec<ExtractQuadBundle> { let mut extracted_quads = Vec::new(); diff --git a/src/render/unified/shader.wgsl b/src/render/unified/shader.wgsl index d2308ad37247e4fa0d580f7414a976c36d5825b9..cc6061d4ceb11fffbbac17adbff3e94f22de3a0b 100644 --- a/src/render/unified/shader.wgsl +++ b/src/render/unified/shader.wgsl @@ -70,6 +70,10 @@ fn sample_sdf(coords: vec2<f32>, arr: i32, scale: f32) -> f32 { return clamp((median3(sample.rgb) - 0.5) * scale + 0.5, 0., 1.); } +fn range_curve(font_size: f32) -> f32 { + return (8.528 - 9.428 * font_size + 3.428 * pow(font_size, 2.0)) + 1.0; +} + @fragment fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { if quad_type.t == 0 { @@ -86,7 +90,9 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { return vec4<f32>(in.color.rgb, rect_dist * in.color.a); } if quad_type.t == 1 { - var px_range = 2.5; + // var px_range = 4.5; + let font_size = min(max(in.size.y, 0.0), 32.0) / 32.0; + var px_range = range_curve(font_size); var tex_dimensions = textureDimensions(font_texture); var msdf_unit = vec2(px_range, px_range) / vec2(f32(tex_dimensions.x), f32(tex_dimensions.y)); let subpixel_width = fwidth(in.uv.x) / 3.; @@ -100,13 +106,13 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> { return vec4(red * in.color.r, green * in.color.g, blue * in.color.b, alpha); } if quad_type.t == 2 { - var px_range = 2.5; + // var px_range = 5.5; + let font_size = min(max(in.size.y, 0.0), 32.0) / 32.0; + var px_range = range_curve(font_size); var tex_dimensions = textureDimensions(font_texture); var msdf_unit = vec2(px_range, px_range) / vec2(f32(tex_dimensions.x), f32(tex_dimensions.y)); let scale = dot(msdf_unit, 0.5 / fwidth(in.uv.xy)); - let alpha = sample_sdf(vec2(in.uv.x, 1. - in.uv.y), i32(in.uv.z), scale); - return vec4(in.color.rgb, alpha); } if quad_type.t == 3 {