Do not store reference to font in shape or layout glyphs

This commit is contained in:
Jeremy Soller 2022-10-25 10:13:44 -06:00
parent 3c573df261
commit 42de42d59e
No known key found for this signature in database
GPG key ID: 87F211AF2BE4C2FE
5 changed files with 68 additions and 47 deletions

View file

@ -1,38 +1,47 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::{CacheKey, Font};
use super::{CacheKey, FontMatches};
pub struct FontLayoutGlyph<'a> {
pub struct FontLayoutGlyph {
pub start: usize,
pub end: usize,
pub x: f32,
pub w: f32,
pub rtl: bool,
pub font: &'a Font<'a>,
pub inner: (CacheKey, i32, i32),
pub cache_key: CacheKey,
pub x_int: i32,
pub y_int: i32,
}
pub struct FontLayoutLine<'a> {
pub struct FontLayoutLine {
pub rtl: bool,
pub glyphs: Vec<FontLayoutGlyph<'a>>,
pub glyphs: Vec<FontLayoutGlyph>,
}
impl<'a> FontLayoutLine<'a> {
pub fn draw<F: FnMut(i32, i32, u32)>(&self, base: u32, mut f: F) {
impl FontLayoutLine {
pub fn draw<F: FnMut(i32, i32, u32)>(&self, matches: &FontMatches<'_>, base: u32, mut f: F) {
for glyph in self.glyphs.iter() {
use swash::scale::{Render, Source, StrikeWith};
use swash::zeno::{Format, Vector};
let mut cache = glyph.font.cache.lock().unwrap();
let font = match matches.get_font(&glyph.cache_key.font_id) {
Some(some) => some,
None => {
log::warn!("did not find font {:?}", glyph.cache_key.font_id);
continue;
},
};
let (cache_key, x_int, y_int) = glyph.inner;
let mut cache = font.cache.lock().unwrap();
let (cache_key, x_int, y_int) = (glyph.cache_key, glyph.x_int, glyph.y_int);
let image_opt = cache.entry(cache_key).or_insert_with(|| {
let mut scale_context = glyph.font.scale_context.lock().unwrap();
let mut scale_context = font.scale_context.lock().unwrap();
// Build the scaler
let mut scaler = scale_context
.builder(glyph.font.swash)
.builder(font.swash)
.size(cache_key.font_size as f32)
.hint(true)
.build();

View file

@ -57,7 +57,6 @@ impl<'a> FontMatches<'a> {
missing.push(start_word + info.cluster as usize);
}
let inner = info.glyph_id as swash::GlyphId;
glyphs.push(FontShapeGlyph {
start: start_word + info.cluster as usize,
end: end_word, // Set later
@ -65,8 +64,8 @@ impl<'a> FontMatches<'a> {
y_advance,
x_offset,
y_offset,
font,
inner,
font_id: font.info.id,
glyph_id: info.glyph_id.try_into().unwrap(),
});
}
@ -325,4 +324,13 @@ impl<'a> FontMatches<'a> {
FontShapeLine { rtl, spans }
}
pub fn get_font(&self, id: &fontdb::ID) -> Option<&Font> {
for font in self.fonts.iter() {
if &font.info.id == id {
return Some(font);
}
}
None
}
}

View file

@ -1,58 +1,64 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::{CacheKey, Font, FontLayoutGlyph, FontLayoutLine};
use super::{CacheKey, FontLayoutGlyph, FontLayoutLine};
pub struct FontShapeGlyph<'a> {
pub struct FontShapeGlyph {
pub start: usize,
pub end: usize,
pub x_advance: f32,
pub y_advance: f32,
pub x_offset: f32,
pub y_offset: f32,
pub font: &'a Font<'a>,
pub inner: swash::GlyphId,
pub font_id: fontdb::ID,
pub glyph_id: u16,
}
impl<'a> FontShapeGlyph<'a> {
fn layout(&self, font_size: i32, x: f32, y: f32, rtl: bool) -> FontLayoutGlyph<'a> {
impl FontShapeGlyph {
fn layout(&self, font_size: i32, x: f32, y: f32, rtl: bool) -> FontLayoutGlyph {
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;
let inner = CacheKey::new(self.font.info.id, self.inner, font_size, (x + x_offset, y - y_offset));
let (cache_key, x_int, y_int) = CacheKey::new(
self.font_id,
self.glyph_id,
font_size,
(x + x_offset, y - y_offset)
);
FontLayoutGlyph {
start: self.start,
end: self.end,
x,
w: x_advance,
rtl,
font: self.font,
inner,
cache_key,
x_int,
y_int,
}
}
}
pub struct FontShapeWord<'a> {
pub struct FontShapeWord {
pub blank: bool,
pub glyphs: Vec<FontShapeGlyph<'a>>,
pub glyphs: Vec<FontShapeGlyph>,
}
pub struct FontShapeSpan<'a> {
pub struct FontShapeSpan {
pub rtl: bool,
pub words: Vec<FontShapeWord<'a>>,
pub words: Vec<FontShapeWord>,
}
pub struct FontShapeLine<'a> {
pub struct FontShapeLine {
pub rtl: bool,
pub spans: Vec<FontShapeSpan<'a>>,
pub spans: Vec<FontShapeSpan>,
}
impl<'a> FontShapeLine<'a> {
impl FontShapeLine {
pub fn layout(
&self,
font_size: i32,
line_width: i32,
layout_lines: &mut Vec<FontLayoutLine<'a>>,
layout_lines: &mut Vec<FontLayoutLine>,
mut layout_i: usize,
) {
let mut push_line = true;