mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-24 10:16:59 -06:00
Merge pull request #1149 from y-az/fix/arabic-contextual-alternates
Shaping: Arabic keeps contextual alternates
This commit is contained in:
@@ -197,6 +197,20 @@ pub fn shape_with_context(
|
||||
out
|
||||
}
|
||||
|
||||
/// `features` as a run in `script` takes them. Contextual alternates are part of how Arabic joins
|
||||
/// (connecting strokes, tatweel and letter variants): InDesign keeps them in Arabic text with
|
||||
/// Contextual Alternates off, so `calt` off is dropped there.
|
||||
fn script_features(features: &[Feature], script: unicode_script::Script) -> std::borrow::Cow<'_, [Feature]> {
|
||||
use unicode_script::Script;
|
||||
let calt = Tag::new(b"calt");
|
||||
let off = |f: &Feature| f.tag == calt && f.value == 0;
|
||||
if script == Script::Arabic && features.iter().any(off) {
|
||||
features.iter().filter(|f| !off(f)).copied().collect::<Vec<_>>().into()
|
||||
} else {
|
||||
features.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn shape_dir(
|
||||
face: &FontFace,
|
||||
text: &str,
|
||||
@@ -207,6 +221,8 @@ fn shape_dir(
|
||||
context: ShapeContext<'_>,
|
||||
) -> Vec<ShapedGlyph> {
|
||||
let mut out = Vec::with_capacity(text.len());
|
||||
let features = script_features(features, script);
|
||||
let features = &features[..];
|
||||
let shaped = face.hb().map(|hb| {
|
||||
let shaper = face.shaper.shaper(&hb).instance(face.instance.as_ref()).build();
|
||||
let mut buf = UnicodeBuffer::new();
|
||||
@@ -334,6 +350,16 @@ pub fn first_glyph(face: &FontFace, chars: &[char]) -> u32 {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn arabic_keeps_contextual_alternates() {
|
||||
use unicode_script::Script;
|
||||
let off = feature("-calt").unwrap();
|
||||
let liga = feature("-liga").unwrap();
|
||||
let tags = |s: Script| script_features(&[off, liga], s).iter().map(|f| (f.tag, f.value)).collect::<Vec<_>>();
|
||||
assert_eq!(tags(Script::Arabic), vec![(liga.tag, 0)]);
|
||||
assert_eq!(tags(Script::Latin), vec![(off.tag, 0), (liga.tag, 0)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arabic_script_runs_do_not_inherit_the_hebrew_shaper() {
|
||||
use unicode_script::Script;
|
||||
|
||||
Reference in New Issue
Block a user