From a03a5a6dfc2e1c5c0c31d5e31195509681f65231 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Fri, 12 Jan 2024 20:55:01 +1100 Subject: [PATCH 1/5] Update font.rs --- src/font.rs | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/font.rs b/src/font.rs index 2f6fdc60..45eda04e 100644 --- a/src/font.rs +++ b/src/font.rs @@ -577,12 +577,50 @@ impl Font { /// 0% coverage of that pixel by the glyph and 255 represents 100% coverage. The vec starts at /// the top left corner of the glyph. pub fn rasterize_indexed(&self, index: u16, px: f32) -> (Metrics, Vec) { + self.rasterize_indexed_offset(index, px, 0.0) + } + + /// Retrieves the layout metrics and rasterized bitmap at the given index. You normally want to + /// be using rasterize(char, f32) instead, unless your glyphs are pre-indexed. + /// + /// This will perform the operation with the width multiplied by 3, as to simulate subpixels. + /// Taking these as RGB values will perform subpixel anti aliasing. + /// # Arguments + /// + /// * `index` - The glyph index in the font to rasterize. + /// * `px` - The size to render the character at. Cannot be negative. The units of the scale + /// are pixels per Em unit. + /// # Returns + /// + /// * `Metrics` - Sizing and positioning metadata for the rasterized glyph. + /// * `Vec` - Swizzled RGB coverage vector for the glyph. Coverage is a linear scale where 0 + /// represents 0% coverage of that subpixel by the glyph and 255 represents 100% coverage. The + /// vec starts at the top left corner of the glyph. + pub fn rasterize_indexed_subpixel(&self, index: u16, px: f32) -> (Metrics, Vec) { + self.rasterize_indexed_subpixel_offset(index, px, 0.0) + } + + /// Retrieves the layout metrics and rasterized bitmap at the given index. You normally want to + /// be using rasterize(char, f32) instead, unless your glyphs are pre-indexed. + /// # Arguments + /// + /// * `index` - The glyph index in the font to rasterize. + /// * `px` - The size to render the character at. Cannot be negative. The units of the scale + /// are pixels per Em unit. + /// * `offset` - Additional horizontal offset to apply while rendering for more control over hinting. + /// # Returns + /// + /// * `Metrics` - Sizing and positioning metadata for the rasterized glyph. + /// * `Vec` - Coverage vector for the glyph. Coverage is a linear scale where 0 represents + /// 0% coverage of that pixel by the glyph and 255 represents 100% coverage. The vec starts at + /// the top left corner of the glyph. + pub fn rasterize_indexed_offset(&self, index: u16, px: f32, offset: f32) -> (Metrics, Vec) { if px <= 0.0 { return (Metrics::default(), Vec::new()); } let glyph = &self.glyphs[index as usize]; let scale = self.scale_factor(px); - let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, 0.0); + let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, offset); let mut canvas = Raster::new(metrics.width, metrics.height); canvas.draw(&glyph, scale, scale, offset_x, offset_y); (metrics, canvas.get_bitmap()) @@ -598,19 +636,20 @@ impl Font { /// * `index` - The glyph index in the font to rasterize. /// * `px` - The size to render the character at. Cannot be negative. The units of the scale /// are pixels per Em unit. + /// * `offset` - Additional horizontal offset to apply while rendering for more control over hinting. /// # Returns /// /// * `Metrics` - Sizing and positioning metadata for the rasterized glyph. /// * `Vec` - Swizzled RGB coverage vector for the glyph. Coverage is a linear scale where 0 /// represents 0% coverage of that subpixel by the glyph and 255 represents 100% coverage. The /// vec starts at the top left corner of the glyph. - pub fn rasterize_indexed_subpixel(&self, index: u16, px: f32) -> (Metrics, Vec) { + pub fn rasterize_indexed_subpixel_offset(&self, index: u16, px: f32, offset: f32) -> (Metrics, Vec) { if px <= 0.0 { return (Metrics::default(), Vec::new()); } let glyph = &self.glyphs[index as usize]; let scale = self.scale_factor(px); - let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, 0.0); + let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, offset); let mut canvas = Raster::new(metrics.width * 3, metrics.height); canvas.draw(&glyph, scale * 3.0, scale, offset_x, offset_y); (metrics, canvas.get_bitmap()) From 60ed53e70da7e2994c558ce745e3ee9dcbe93777 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Fri, 12 Jan 2024 20:59:14 +1100 Subject: [PATCH 2/5] Update mod.rs --- src/platform/float/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platform/float/mod.rs b/src/platform/float/mod.rs index f277d4bf..fe1c5eb0 100644 --- a/src/platform/float/mod.rs +++ b/src/platform/float/mod.rs @@ -16,7 +16,6 @@ pub use floor::*; pub use fract::*; pub use get_bitmap::*; pub use sqrt::*; -pub use trunc::*; /// Sets the high bit 0x80000000 on a float. #[inline(always)] From 96f251cbdb4d7ce64d16989d5d8050cdf1eb2c54 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:06:06 +1100 Subject: [PATCH 3/5] Revert "Update mod.rs" This reverts commit 60ed53e70da7e2994c558ce745e3ee9dcbe93777. --- src/platform/float/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/float/mod.rs b/src/platform/float/mod.rs index fe1c5eb0..f277d4bf 100644 --- a/src/platform/float/mod.rs +++ b/src/platform/float/mod.rs @@ -16,6 +16,7 @@ pub use floor::*; pub use fract::*; pub use get_bitmap::*; pub use sqrt::*; +pub use trunc::*; /// Sets the high bit 0x80000000 on a float. #[inline(always)] From 10c4871d8b6a06d149a6e1359d4c606bfaede55d Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:38:19 +1100 Subject: [PATCH 4/5] Update font.rs --- src/font.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/font.rs b/src/font.rs index 45eda04e..5be0af4e 100644 --- a/src/font.rs +++ b/src/font.rs @@ -649,7 +649,7 @@ impl Font { } let glyph = &self.glyphs[index as usize]; let scale = self.scale_factor(px); - let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, offset); + let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, offset * 3.0); let mut canvas = Raster::new(metrics.width * 3, metrics.height); canvas.draw(&glyph, scale * 3.0, scale, offset_x, offset_y); (metrics, canvas.get_bitmap()) From 0bc262ab9aeb05a0950118d584369c80c7182239 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:33:21 +1100 Subject: [PATCH 5/5] Expose vertical offset as well --- src/font.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/font.rs b/src/font.rs index 5be0af4e..fd0428b2 100644 --- a/src/font.rs +++ b/src/font.rs @@ -458,15 +458,15 @@ impl Font { pub fn metrics_indexed(&self, index: u16, px: f32) -> Metrics { let glyph = &self.glyphs[index as usize]; let scale = self.scale_factor(px); - let (metrics, _, _) = self.metrics_raw(scale, glyph, 0.0); + let (metrics, _, _) = self.metrics_raw(scale, glyph, (0.0, 0.0)); metrics } /// Internal function to generate the metrics, offset_x, and offset_y of the glyph. - fn metrics_raw(&self, scale: f32, glyph: &Glyph, offset: f32) -> (Metrics, f32, f32) { + fn metrics_raw(&self, scale: f32, glyph: &Glyph, offset: (f32, f32)) -> (Metrics, f32, f32) { let bounds = glyph.bounds.scale(scale); - let mut offset_x = fract(bounds.xmin + offset); - let mut offset_y = fract(1.0 - fract(bounds.height) - fract(bounds.ymin)); + let mut offset_x = fract(bounds.xmin + offset.0); + let mut offset_y = fract(1.0 - fract(bounds.height) - fract(bounds.ymin + offset.1)); if is_negative(offset_x) { offset_x += 1.0; } @@ -577,7 +577,7 @@ impl Font { /// 0% coverage of that pixel by the glyph and 255 represents 100% coverage. The vec starts at /// the top left corner of the glyph. pub fn rasterize_indexed(&self, index: u16, px: f32) -> (Metrics, Vec) { - self.rasterize_indexed_offset(index, px, 0.0) + self.rasterize_indexed_offset(index, px, (0.0, 0.0)) } /// Retrieves the layout metrics and rasterized bitmap at the given index. You normally want to @@ -597,7 +597,7 @@ impl Font { /// represents 0% coverage of that subpixel by the glyph and 255 represents 100% coverage. The /// vec starts at the top left corner of the glyph. pub fn rasterize_indexed_subpixel(&self, index: u16, px: f32) -> (Metrics, Vec) { - self.rasterize_indexed_subpixel_offset(index, px, 0.0) + self.rasterize_indexed_subpixel_offset(index, px, (0.0, 0.0)) } /// Retrieves the layout metrics and rasterized bitmap at the given index. You normally want to @@ -607,14 +607,15 @@ impl Font { /// * `index` - The glyph index in the font to rasterize. /// * `px` - The size to render the character at. Cannot be negative. The units of the scale /// are pixels per Em unit. - /// * `offset` - Additional horizontal offset to apply while rendering for more control over hinting. + /// * `offset` - Additional horizontal and vertical (in that order) offset to apply while + /// rendering for more control over hinting. /// # Returns /// /// * `Metrics` - Sizing and positioning metadata for the rasterized glyph. /// * `Vec` - Coverage vector for the glyph. Coverage is a linear scale where 0 represents /// 0% coverage of that pixel by the glyph and 255 represents 100% coverage. The vec starts at /// the top left corner of the glyph. - pub fn rasterize_indexed_offset(&self, index: u16, px: f32, offset: f32) -> (Metrics, Vec) { + pub fn rasterize_indexed_offset(&self, index: u16, px: f32, offset: (f32, f32)) -> (Metrics, Vec) { if px <= 0.0 { return (Metrics::default(), Vec::new()); } @@ -636,20 +637,26 @@ impl Font { /// * `index` - The glyph index in the font to rasterize. /// * `px` - The size to render the character at. Cannot be negative. The units of the scale /// are pixels per Em unit. - /// * `offset` - Additional horizontal offset to apply while rendering for more control over hinting. + /// * `offset` - Additional horizontal and vertical (in that order) offset to apply while + /// rendering for more control over hinting. /// # Returns /// /// * `Metrics` - Sizing and positioning metadata for the rasterized glyph. /// * `Vec` - Swizzled RGB coverage vector for the glyph. Coverage is a linear scale where 0 /// represents 0% coverage of that subpixel by the glyph and 255 represents 100% coverage. The /// vec starts at the top left corner of the glyph. - pub fn rasterize_indexed_subpixel_offset(&self, index: u16, px: f32, offset: f32) -> (Metrics, Vec) { + pub fn rasterize_indexed_subpixel_offset( + &self, + index: u16, + px: f32, + offset: (f32, f32), + ) -> (Metrics, Vec) { if px <= 0.0 { return (Metrics::default(), Vec::new()); } let glyph = &self.glyphs[index as usize]; let scale = self.scale_factor(px); - let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, offset * 3.0); + let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, (offset.0 * 3.0, offset.1)); let mut canvas = Raster::new(metrics.width * 3, metrics.height); canvas.draw(&glyph, scale * 3.0, scale, offset_x, offset_y); (metrics, canvas.get_bitmap())