Skip to content

Commit 7d78496

Browse files
committed
Added dx parameter for sub-pixel rasterization
Added dx parameter which allows for controlling the horizontal offset within the pixel. This allows drawing glyphs at the exact floating point x position provided by accumulating the horizontal advance_width metric when drawing text.
1 parent 0eb26ca commit 7d78496

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

src/font.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -443,12 +443,13 @@ impl Font {
443443
/// * `index` - The character in the font to to generate the layout metrics for.
444444
/// * `px` - The size to generate the layout metrics for the character at. Cannot be negative.
445445
/// The units of the scale are pixels per Em unit.
446+
/// * `dx` - The sub-pixel x offset in which to render the glyph.
446447
/// # Returns
447448
///
448449
/// * `Metrics` - Sizing and positioning metadata for the glyph.
449450
#[inline]
450-
pub fn metrics(&self, character: char, px: f32) -> Metrics {
451-
self.metrics_indexed(self.lookup_glyph_index(character), px)
451+
pub fn metrics(&self, character: char, px: f32, dx: f32) -> Metrics {
452+
self.metrics_indexed(self.lookup_glyph_index(character), px, dx)
452453
}
453454

454455
/// Retrieves the layout metrics at the given index. You normally want to be using
@@ -458,13 +459,14 @@ impl Font {
458459
/// * `index` - The glyph index in the font to to generate the layout metrics for.
459460
/// * `px` - The size to generate the layout metrics for the glyph at. Cannot be negative. The
460461
/// units of the scale are pixels per Em unit.
462+
/// * `dx` - The sub-pixel x offset in which to render the glyph.
461463
/// # Returns
462464
///
463465
/// * `Metrics` - Sizing and positioning metadata for the glyph.
464-
pub fn metrics_indexed(&self, index: u16, px: f32) -> Metrics {
466+
pub fn metrics_indexed(&self, index: u16, px: f32, dx: f32) -> Metrics {
465467
let glyph = &self.glyphs[index as usize];
466468
let scale = self.scale_factor(px);
467-
let (metrics, _, _) = self.metrics_raw(scale, glyph, 0.0);
469+
let (metrics, _, _) = self.metrics_raw(scale, glyph, dx);
468470
metrics
469471
}
470472

@@ -480,7 +482,7 @@ impl Font {
480482
offset_y += 1.0;
481483
}
482484
let metrics = Metrics {
483-
xmin: as_i32(floor(bounds.xmin)),
485+
xmin: as_i32(floor(bounds.xmin + offset)),
484486
ymin: as_i32(floor(bounds.ymin)),
485487
width: as_i32(ceil(bounds.width + offset_x)) as usize,
486488
height: as_i32(ceil(bounds.height + offset_y)) as usize,
@@ -505,7 +507,7 @@ impl Font {
505507
/// the top left corner of the glyph.
506508
#[inline]
507509
pub fn rasterize_config(&self, config: GlyphRasterConfig) -> (Metrics, Vec<u8>) {
508-
self.rasterize_indexed(config.glyph_index, config.px)
510+
self.rasterize_indexed(config.glyph_index, config.px, 0.0)
509511
}
510512

511513
/// Retrieves the layout metrics and rasterized bitmap for the given character. If the
@@ -516,15 +518,16 @@ impl Font {
516518
/// * `character` - The character to rasterize.
517519
/// * `px` - The size to render the character at. Cannot be negative. The units of the scale
518520
/// are pixels per Em unit.
521+
/// * `dx` - The sub-pixel x offset in which to render the glyph.
519522
/// # Returns
520523
///
521524
/// * `Metrics` - Sizing and positioning metadata for the rasterized glyph.
522525
/// * `Vec<u8>` - Coverage vector for the glyph. Coverage is a linear scale where 0 represents
523526
/// 0% coverage of that pixel by the glyph and 255 represents 100% coverage. The vec starts at
524527
/// the top left corner of the glyph.
525528
#[inline]
526-
pub fn rasterize(&self, character: char, px: f32) -> (Metrics, Vec<u8>) {
527-
self.rasterize_indexed(self.lookup_glyph_index(character), px)
529+
pub fn rasterize(&self, character: char, px: f32, dx: f32) -> (Metrics, Vec<u8>) {
530+
self.rasterize_indexed(self.lookup_glyph_index(character), px, dx)
528531
}
529532

530533
/// Retrieves the layout rasterized bitmap for the given raster config. If the raster config's
@@ -576,19 +579,21 @@ impl Font {
576579
/// * `index` - The glyph index in the font to rasterize.
577580
/// * `px` - The size to render the character at. Cannot be negative. The units of the scale
578581
/// are pixels per Em unit.
582+
/// * `dx` - The sub-pixel x offset in which to render the glyph.
583+
/// # Returns
579584
/// # Returns
580585
///
581586
/// * `Metrics` - Sizing and positioning metadata for the rasterized glyph.
582587
/// * `Vec<u8>` - Coverage vector for the glyph. Coverage is a linear scale where 0 represents
583588
/// 0% coverage of that pixel by the glyph and 255 represents 100% coverage. The vec starts at
584589
/// the top left corner of the glyph.
585-
pub fn rasterize_indexed(&self, index: u16, px: f32) -> (Metrics, Vec<u8>) {
590+
pub fn rasterize_indexed(&self, index: u16, px: f32, dx: f32) -> (Metrics, Vec<u8>) {
586591
if px <= 0.0 {
587592
return (Metrics::default(), Vec::new());
588593
}
589594
let glyph = &self.glyphs[index as usize];
590595
let scale = self.scale_factor(px);
591-
let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, 0.0);
596+
let (metrics, offset_x, offset_y) = self.metrics_raw(scale, glyph, dx);
592597
let mut canvas = Raster::new(metrics.width, metrics.height);
593598
canvas.draw(&glyph, scale, scale, offset_x, offset_y);
594599
(metrics, canvas.get_bitmap())

src/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ impl<'a, U: Copy + Clone> Layout<U> {
454454
let glyph_index = font.lookup_glyph_index(character);
455455
let char_data = CharacterData::classify(character, glyph_index);
456456
let metrics = if !char_data.is_control() {
457-
font.metrics_indexed(glyph_index, style.px)
457+
font.metrics_indexed(glyph_index, style.px, 0.0)
458458
} else {
459459
Metrics::default()
460460
};

0 commit comments

Comments
 (0)