Fix inconsisent bounding box sizes at the same subpixel positions

parent 109f3a10
......@@ -804,22 +804,27 @@ impl<'a> ScaledGlyph<'a> {
/// Augments this glyph with positioning information, making methods that
/// depend on the position of the glyph available.
pub fn positioned(self, p: Point<f32>) -> PositionedGlyph<'a> {
// Use subpixel fraction in floor/ceil rounding to elimate rounding error
// from identical subpixel positions
let (x_trunc, x_fract) = (p.x.trunc() as i32, p.x.fract());
let (y_trunc, y_fract) = (p.y.trunc() as i32, p.y.fract());
let bb = match self.g.inner {
GlyphInner::Proxy(ref font, id) => font
.info
.get_glyph_bitmap_box_subpixel(id, self.scale.x, self.scale.y, p.x, p.y)
.get_glyph_bitmap_box_subpixel(id, self.scale.x, self.scale.y, x_fract, y_fract)
.map(|bb| Rect {
min: point(bb.x0, bb.y0),
max: point(bb.x1, bb.y1),
min: point(x_trunc + bb.x0, y_trunc + bb.y0),
max: point(x_trunc + bb.x1, y_trunc + bb.y1),
}),
GlyphInner::Shared(ref data) => data.extents.map(|bb| Rect {
min: point(
(bb.min.x as f32 * self.scale.x + p.x).floor() as i32,
(bb.min.y as f32 * self.scale.y + p.y).floor() as i32,
(bb.min.x as f32 * self.scale.x + x_fract).floor() as i32 + x_trunc,
(bb.min.y as f32 * self.scale.y + y_fract).floor() as i32 + y_trunc,
),
max: point(
(bb.max.x as f32 * self.scale.x + p.x).ceil() as i32,
(bb.max.y as f32 * self.scale.y + p.y).ceil() as i32,
(bb.max.x as f32 * self.scale.x + x_fract).ceil() as i32 + x_trunc,
(bb.max.y as f32 * self.scale.y + y_fract).ceil() as i32 + y_trunc,
),
}),
};
......
extern crate rusttype;
use rusttype::*;
static ROBOTO_REGULAR: &[u8] = include_bytes!("../fonts/Roboto-Regular.ttf");
#[test]
fn consistent_bounding_box_subpixel_size_proxy() {
let font = Font::from_bytes(ROBOTO_REGULAR).unwrap();
let height_at_y = |y| {
font.glyph('s')
.scaled(rusttype::Scale::uniform(20.0))
.positioned(rusttype::Point { x: 0.0, y })
.pixel_bounding_box()
.unwrap()
.height()
};
assert_eq!(height_at_y(50.833_336), height_at_y(110.833_336));
}
#[test]
fn consistent_bounding_box_subpixel_size_standalone() {
let font = Font::from_bytes(ROBOTO_REGULAR).unwrap();
let height_at_y = |y| {
font.glyph('s')
.standalone()
.scaled(rusttype::Scale::uniform(20.0))
.positioned(rusttype::Point { x: 0.0, y })
.pixel_bounding_box()
.unwrap()
.height()
};
assert_eq!(height_at_y(50.833_336), height_at_y(110.833_336));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment