Add layout run iterator

This commit is contained in:
Jeremy Soller 2022-10-25 12:52:46 -06:00
parent 5d7dd59078
commit a9b7b4e914
No known key found for this signature in database
GPG key ID: 87F211AF2BE4C2FE
8 changed files with 135 additions and 97 deletions

View file

@ -1,140 +0,0 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct CacheKey {
pub font_id: fontdb::ID,
pub glyph_id: u16,
pub font_size: i32,
pub x_bin: SubpixelBin,
pub y_bin: SubpixelBin,
}
impl CacheKey {
pub fn new(
font_id: fontdb::ID,
glyph_id: u16,
font_size: i32,
pos: (f32, f32),
) -> (Self, i32, i32) {
let (x, x_bin) = SubpixelBin::new(pos.0);
let (y, y_bin) = SubpixelBin::new(pos.1);
(
Self {
font_id,
glyph_id,
font_size,
x_bin,
y_bin,
},
x,
y,
)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SubpixelBin {
Zero,
One,
Two,
Three,
}
impl SubpixelBin {
pub fn new(pos: f32) -> (i32, Self) {
let trunc = pos.trunc() as i32;
let fract = pos.fract();
if pos.is_sign_negative() {
if fract > -0.125 {
(trunc, Self::Zero)
} else if fract > -0.375 {
(trunc - 1, Self::Three)
} else if fract > -0.625 {
(trunc - 1, Self::Two)
} else if fract > -0.875 {
(trunc - 1, Self::One)
} else {
(trunc - 1, Self::Zero)
}
} else {
#[allow(clippy::collapsible_else_if)]
if fract < 0.125 {
(trunc, Self::Zero)
} else if fract < 0.375 {
(trunc, Self::One)
} else if fract < 0.625 {
(trunc, Self::Two)
} else if fract < 0.875 {
(trunc, Self::Three)
} else {
(trunc + 1, Self::Zero)
}
}
}
pub fn as_float(&self) -> f32 {
match self {
Self::Zero => 0.0,
Self::One => 0.25,
Self::Two => 0.5,
Self::Three => 0.75,
}
}
}
#[test]
fn test_subpixel_bins() {
// POSITIVE TESTS
// Maps to 0.0
assert_eq!(SubpixelBin::new(0.0), (0, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(0.124), (0, SubpixelBin::Zero));
// Maps to 0.25
assert_eq!(SubpixelBin::new(0.125), (0, SubpixelBin::One));
assert_eq!(SubpixelBin::new(0.25), (0, SubpixelBin::One));
assert_eq!(SubpixelBin::new(0.374), (0, SubpixelBin::One));
// Maps to 0.5
assert_eq!(SubpixelBin::new(0.375), (0, SubpixelBin::Two));
assert_eq!(SubpixelBin::new(0.5), (0, SubpixelBin::Two));
assert_eq!(SubpixelBin::new(0.624), (0, SubpixelBin::Two));
// Maps to 0.75
assert_eq!(SubpixelBin::new(0.625), (0, SubpixelBin::Three));
assert_eq!(SubpixelBin::new(0.75), (0, SubpixelBin::Three));
assert_eq!(SubpixelBin::new(0.874), (0, SubpixelBin::Three));
// Maps to 1.0
assert_eq!(SubpixelBin::new(0.875), (1, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(0.999), (1, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(1.0), (1, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(1.124), (1, SubpixelBin::Zero));
// NEGATIVE TESTS
// Maps to 0.0
assert_eq!(SubpixelBin::new(-0.0), (0, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(-0.124), (0, SubpixelBin::Zero));
// Maps to 0.25
assert_eq!(SubpixelBin::new(-0.125), (-1, SubpixelBin::Three));
assert_eq!(SubpixelBin::new(-0.25), (-1, SubpixelBin::Three));
assert_eq!(SubpixelBin::new(-0.374), (-1, SubpixelBin::Three));
// Maps to 0.5
assert_eq!(SubpixelBin::new(-0.375), (-1, SubpixelBin::Two));
assert_eq!(SubpixelBin::new(-0.5), (-1, SubpixelBin::Two));
assert_eq!(SubpixelBin::new(-0.624), (-1, SubpixelBin::Two));
// Maps to 0.75
assert_eq!(SubpixelBin::new(-0.625), (-1, SubpixelBin::One));
assert_eq!(SubpixelBin::new(-0.75), (-1, SubpixelBin::One));
assert_eq!(SubpixelBin::new(-0.874), (-1, SubpixelBin::One));
// Maps to 1.0
assert_eq!(SubpixelBin::new(-0.875), (-1, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(-0.999), (-1, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(-1.0), (-1, SubpixelBin::Zero));
assert_eq!(SubpixelBin::new(-1.124), (-1, SubpixelBin::Zero));
}

View file

@ -1,19 +0,0 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::CacheKey;
pub struct FontLayoutGlyph {
pub start: usize,
pub end: usize,
pub x: f32,
pub w: f32,
pub rtl: bool,
pub cache_key: CacheKey,
pub x_int: i32,
pub y_int: i32,
}
pub struct FontLayoutLine {
pub rtl: bool,
pub glyphs: Vec<FontLayoutGlyph>,
}

View file

@ -2,15 +2,9 @@
pub(crate) mod fallback;
pub(crate) use self::cache::*;
mod cache;
pub(crate) use self::font::*;
mod font;
pub(crate) use self::layout::*;
mod layout;
pub use self::matches::*;
mod matches;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::{CacheKey, FontLayoutGlyph, FontLayoutLine};
use crate::{CacheKey, LayoutGlyph, LayoutLine};
pub struct FontShapeGlyph {
pub start: usize,
@ -14,7 +14,7 @@ pub struct FontShapeGlyph {
}
impl FontShapeGlyph {
fn layout(&self, font_size: i32, x: f32, y: f32, rtl: bool) -> FontLayoutGlyph {
fn layout(&self, font_size: i32, x: f32, y: f32, rtl: bool) -> LayoutGlyph {
let x_offset = font_size as f32 * self.x_offset;
let y_offset = font_size as f32 * self.y_offset;
let x_advance = font_size as f32 * self.x_advance;
@ -25,7 +25,7 @@ impl FontShapeGlyph {
font_size,
(x + x_offset, y - y_offset)
);
FontLayoutGlyph {
LayoutGlyph {
start: self.start,
end: self.end,
x,
@ -58,7 +58,7 @@ impl FontShapeLine {
&self,
font_size: i32,
line_width: i32,
layout_lines: &mut Vec<FontLayoutLine>,
layout_lines: &mut Vec<LayoutLine>,
mut layout_i: usize,
) {
let mut push_line = true;
@ -171,8 +171,7 @@ impl FontShapeLine {
std::mem::swap(&mut glyphs, &mut glyphs_swap);
layout_lines.insert(
layout_i,
FontLayoutLine {
rtl: self.rtl,
LayoutLine {
glyphs: glyphs_swap,
},
);
@ -205,8 +204,7 @@ impl FontShapeLine {
std::mem::swap(&mut glyphs, &mut glyphs_swap);
layout_lines.insert(
layout_i,
FontLayoutLine {
rtl: self.rtl,
LayoutLine {
glyphs: glyphs_swap,
},
);
@ -221,8 +219,7 @@ impl FontShapeLine {
if push_line {
layout_lines.insert(
layout_i,
FontLayoutLine {
rtl: self.rtl,
LayoutLine {
glyphs,
},
);