Skip to content

Commit

Permalink
Fixes for AAT substitutions re: dfrg#17
Browse files Browse the repository at this point in the history
* Push potentially intermediate ligatures back onto stack in ligature subtable
* Handle END_OF_TEXT in insertion subtable
* Correct advance count in insertion subtable
  • Loading branch information
dfrg authored and kirawi committed Sep 7, 2021
1 parent 50d2b20 commit c6c9fa7
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 14 deletions.
24 changes: 11 additions & 13 deletions src/internal/aat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,8 @@ pub mod morx {
if action & (LAST | STORE) != 0 {
let ligature = self.ligature(ligature_index)?;
f(glyph_index, ligature, state.indices.get(pos + 1..end_pos)?)?;
state.glyphs[pos] = ligature;
pos += 1;
}
if action & LAST != 0 || cycles > (MAX_CYCLES * 2) {
break;
Expand Down Expand Up @@ -906,6 +908,7 @@ pub mod morx {
state: &mut InsertionState,
index: usize,
glyph_id: u16,
end_of_text: bool,
mut f: impl FnMut(usize, Array<'a, u16>) -> Option<()>,
) -> Option<usize> {
const SET_MARK: u16 = 0x8000;
Expand All @@ -914,20 +917,22 @@ pub mod morx {
const _MARKED_IS_KASHIDA_LIKE: u16 = 0x1000;
const CURRENT_INSERT_BEFORE: u16 = 0x800;
const MARKED_INSERT_BEFORE: u16 = 0x400;
let class = self.state_table.class(glyph_id);
let class = if end_of_text {
0
} else {
self.state_table.class(glyph_id)
};
let entry = self
.state_table
.entry::<InsertionData>(state.state, class)?;
state.state = entry.new_state;
let mut working_index = index;
let mut mark_inserted = 0;
let mut inserted = false;
if entry.data.mark_index != 0xFFFF {
let before = entry.flags & MARKED_INSERT_BEFORE != 0;
let base = if before { state.mark } else { state.mark + 1 };
let glyphs = self.marked_glyphs(entry.flags, entry.data.mark_index)?;
mark_inserted = glyphs.len();
inserted = true;
working_index += mark_inserted;
f(base, glyphs)?;
}
Expand All @@ -944,7 +949,6 @@ pub mod morx {
};
let glyphs = self.current_glyphs(entry.flags, entry.data.current_index)?;
current_inserted = glyphs.len();
inserted = true;
f(base, glyphs)?;
}
let mut advance = entry.flags & DONT_ADVANCE == 0;
Expand All @@ -956,16 +960,10 @@ pub mod morx {
} else {
state.cycles += 1;
}
if inserted {
// It doesn't seem likely to find a don't advance flag with an active
// insertion state. The only logical place to position the cursor is
// following the entire group of inserted glyphs.
let count = mark_inserted + current_inserted;
// Always advance to the end of the inserted glyphs, adding an extra 1
// if the don't advance flag is not set.
Some(count + advance as usize)
if advance {
Some(mark_inserted + current_inserted + 1)
} else {
Some(advance as usize)
Some(mark_inserted)
}
}

Expand Down
19 changes: 18 additions & 1 deletion src/shape/aat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub fn apply_morx(
let mut state = InsertionState::new();
while i < buffer.glyphs.len() && ops < max_ops {
let g = buffer.glyphs[i].id;
match t.next(&mut state, i, g, |i, array| {
match t.next(&mut state, i, g, false, |i, array| {
// if TRACE {
// let rep = array.iter().collect::<Vec<_>>();
// println!("Insert[{}] {:?}", i, &rep);
Expand All @@ -148,6 +148,23 @@ pub fn apply_morx(
}
ops += 1;
}
// Apply END_OF_TEXT state
t.next(
&mut state,
buffer.glyphs.len().saturating_sub(1),
0,
true,
|i, array| {
buffer.multiply(i, array.len());
let start = i;
let end = start + array.len();
for (g, s) in buffer.glyphs[start..end].iter_mut().zip(array.iter()) {
g.id = s;
g.flags = 0;
}
Some(())
},
);
}
}
}
Expand Down

0 comments on commit c6c9fa7

Please sign in to comment.