Shape plan caching (#2876)

This commit is contained in:
Laurenz 2023-12-18 15:35:21 +01:00 committed by GitHub
parent 84597b46a4
commit a821b48cf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,10 +2,11 @@ use std::borrow::Cow;
use std::fmt::{self, Debug, Formatter};
use std::ops::Range;
use std::str::FromStr;
use std::sync::Arc;
use az::SaturatingAs;
use ecow::EcoString;
use rustybuzz::{Tag, UnicodeBuffer};
use rustybuzz::{ShapePlan, Tag, UnicodeBuffer};
use unicode_script::{Script, UnicodeScript};
use super::SpanMapper;
@ -690,9 +691,21 @@ fn shape_segment<'a>(
Dir::RTL => rustybuzz::Direction::RightToLeft,
_ => unimplemented!("vertical text layout"),
});
buffer.guess_segment_properties();
// Prepare the shape plan. This plan depends on direction, script, language,
// and features, but is independent from the text and can thus be
// memoized.
let plan = create_shape_plan(
&font,
buffer.direction(),
buffer.script(),
buffer.language().as_ref(),
&ctx.features,
);
// Shape!
let buffer = rustybuzz::shape(font.rusty(), &ctx.features, buffer);
let buffer = rustybuzz::shape_with_plan(font.rusty(), &plan, buffer);
let infos = buffer.glyph_infos();
let pos = buffer.glyph_positions();
let ltr = ctx.dir.is_positive();
@ -783,6 +796,24 @@ fn shape_segment<'a>(
ctx.used.pop();
}
/// Create a shape plan.
#[comemo::memoize]
fn create_shape_plan(
font: &Font,
direction: rustybuzz::Direction,
script: rustybuzz::Script,
language: Option<&rustybuzz::Language>,
features: &[rustybuzz::Feature],
) -> Arc<ShapePlan> {
Arc::new(rustybuzz::ShapePlan::new(
font.rusty(),
direction,
Some(script),
language,
features,
))
}
/// Shape the text with tofus from the given font.
fn shape_tofus(ctx: &mut ShapingContext, base: usize, text: &str, font: Font) {
let x_advance = font.advance(0).unwrap_or_default();