Switch to ab_glyph by default, faster with identical results

This commit is contained in:
Jeremy Soller 2022-10-05 08:46:54 -06:00
parent d64583a8f4
commit 132fb02008
No known key found for this signature in database
GPG key ID: 87F211AF2BE4C2FE
2 changed files with 74 additions and 20 deletions

View file

@ -6,12 +6,13 @@ edition = "2021"
publish = false publish = false
[dependencies] [dependencies]
ab_glyph = { version = "0.2", optional = true }
orbclient = "0.3" orbclient = "0.3"
rusttype = "0.9" rusttype = { version = "0.9", optional = true }
rustybuzz = "0.5" rustybuzz = "0.5"
unicode-bidi = "0.3" unicode-bidi = "0.3"
unicode-script = "0.5" unicode-script = "0.5"
[features] [features]
default = [] default = ["ab_glyph"]
mono = [] mono = []

View file

@ -1,37 +1,29 @@
#[cfg(feature = "ab_glyph")]
use ab_glyph::Font as AbGlyphFont;
use orbclient::{Color, EventOption, Renderer, Window, WindowFlag}; use orbclient::{Color, EventOption, Renderer, Window, WindowFlag};
use std::{ use std::{
cmp, cmp,
env, env,
fs, fs,
marker::PhantomData,
time::Instant, time::Instant,
}; };
struct Font<'a> { struct FontLayoutGlyph<'a, T: 'a> {
data: &'a [u8],
pub rustybuzz: rustybuzz::Face<'a>,
pub rusttype: rusttype::Font<'a>,
}
impl<'a> Font<'a> {
pub fn new(data: &'a [u8], index: u32) -> Option<Self> {
Some(Self {
data,
rustybuzz: rustybuzz::Face::from_slice(data, index)?,
rusttype: rusttype::Font::try_from_bytes_and_index(data, index)?,
})
}
}
struct FontLayoutGlyph<'a> {
start: usize, start: usize,
end: usize, end: usize,
x: f32, x: f32,
w: f32, w: f32,
#[cfg(feature = "ab_glyph")]
inner: Option<ab_glyph::OutlinedGlyph>,
#[cfg(feature = "rusttype")]
inner: rusttype::PositionedGlyph<'a>, inner: rusttype::PositionedGlyph<'a>,
phantom: PhantomData<&'a T>,
} }
struct FontLayoutLine<'a> { struct FontLayoutLine<'a> {
glyphs: Vec<FontLayoutGlyph<'a>>, glyphs: Vec<FontLayoutGlyph<'a, ()>>,
} }
impl<'a> FontLayoutLine<'a> { impl<'a> FontLayoutLine<'a> {
@ -43,6 +35,20 @@ impl<'a> FontLayoutLine<'a> {
color: Color, color: Color,
) { ) {
for glyph in self.glyphs.iter() { for glyph in self.glyphs.iter() {
#[cfg(feature = "ab_glyph")]
if let Some(ref outline) = glyph.inner {
let bb = outline.px_bounds();
let x = line_x + bb.min.x as i32;
let y = line_y + bb.min.y as i32;
outline.draw(|off_x, off_y, v| {
let c = (v * 255.0) as u32;
r.pixel(x + off_x as i32, y + off_y as i32, Color{
data: c << 24 | (color.data & 0x00FF_FFFF)
});
});
}
#[cfg(feature = "rusttype")]
if let Some(bb) = glyph.inner.pixel_bounding_box() { if let Some(bb) = glyph.inner.pixel_bounding_box() {
let x = line_x + bb.min.x; let x = line_x + bb.min.x;
let y = line_y + bb.min.y; let y = line_y + bb.min.y;
@ -64,6 +70,11 @@ struct FontShapeGlyph<'a> {
y_advance: f32, y_advance: f32,
x_offset: f32, x_offset: f32,
y_offset: f32, y_offset: f32,
#[cfg(feature = "ab_glyph")]
font: &'a ab_glyph::FontRef<'a>,
#[cfg(feature = "ab_glyph")]
inner: ab_glyph::GlyphId,
#[cfg(feature = "rusttype")]
inner: rusttype::Glyph<'a>, inner: rusttype::Glyph<'a>,
} }
@ -126,6 +137,18 @@ impl<'a> FontShapeLine<'a> {
} }
} }
#[cfg(feature = "ab_glyph")]
let inner = glyph.font.outline_glyph(
glyph.inner.with_scale_and_position(
font_size as f32,
ab_glyph::point(
x + x_offset,
y + y_offset,
)
)
);
#[cfg(feature = "rusttype")]
let inner = glyph.inner.clone() let inner = glyph.inner.clone()
.scaled(rusttype::Scale::uniform(font_size as f32)) .scaled(rusttype::Scale::uniform(font_size as f32))
.positioned(rusttype::point( .positioned(rusttype::point(
@ -139,6 +162,7 @@ impl<'a> FontShapeLine<'a> {
x, x,
w: x_advance, w: x_advance,
inner, inner,
phantom: PhantomData,
}); });
push_line = true; push_line = true;
@ -195,7 +219,12 @@ impl<'a> FontMatches<'a> {
misses += 1; misses += 1;
} }
#[cfg(feature = "ab_glyph")]
let inner = ab_glyph::GlyphId(info.glyph_id as u16);
#[cfg(feature = "rusttype")]
let inner = font.rusttype.glyph(rusttype::GlyphId(info.glyph_id as u16)); let inner = font.rusttype.glyph(rusttype::GlyphId(info.glyph_id as u16));
glyphs.push(FontShapeGlyph { glyphs.push(FontShapeGlyph {
start: start_span + info.cluster as usize, start: start_span + info.cluster as usize,
end: end_span, // Set later end: end_span, // Set later
@ -203,6 +232,8 @@ impl<'a> FontMatches<'a> {
y_advance, y_advance,
x_offset, x_offset,
y_offset, y_offset,
#[cfg(feature = "ab_glyph")]
font: &font.ab_glyph,
inner, inner,
}); });
} }
@ -327,6 +358,28 @@ impl<'a> FontMatches<'a> {
} }
} }
struct Font<'a> {
data: &'a [u8],
pub rustybuzz: rustybuzz::Face<'a>,
#[cfg(feature = "ab_glyph")]
pub ab_glyph: ab_glyph::FontRef<'a>,
#[cfg(feature = "rusttype")]
pub rusttype: rusttype::Font<'a>,
}
impl<'a> Font<'a> {
pub fn new(data: &'a [u8], index: u32) -> Option<Self> {
Some(Self {
data,
rustybuzz: rustybuzz::Face::from_slice(data, index)?,
#[cfg(feature = "ab_glyph")]
ab_glyph: ab_glyph::FontRef::try_from_slice_and_index(data, index).ok()?,
#[cfg(feature = "rusttype")]
rusttype: rusttype::Font::try_from_bytes_and_index(data, index)?,
})
}
}
struct FontSystem<'a> { struct FontSystem<'a> {
fonts: Vec<Font<'a>>, fonts: Vec<Font<'a>>,
} }