Add layout run iterator
This commit is contained in:
parent
5d7dd59078
commit
a9b7b4e914
8 changed files with 135 additions and 97 deletions
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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>,
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue