Skip to content

Commit

Permalink
Fixed character–section mapping during bidi processing
Browse files Browse the repository at this point in the history
  • Loading branch information
1ec5 committed Aug 23, 2024
1 parent df663a5 commit abf39ed
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
12 changes: 6 additions & 6 deletions src/symbol/shaping.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ describe('TaggedString', () => {
test('splits surrogate pairs', () => {
const tagged = new TaggedString();
tagged.text = '𰻞𰻞麵𪚥𪚥';
expect(tagged.codeUnitIndex(0)).toBe(0);
expect(tagged.codeUnitIndex(1)).toBe(2);
expect(tagged.codeUnitIndex(2)).toBe(4);
expect(tagged.codeUnitIndex(3)).toBe(5);
expect(tagged.codeUnitIndex(4)).toBe(7);
expect(tagged.codeUnitIndex(5)).toBe(9);
expect(tagged.toCodeUnitIndex(0)).toBe(0);
expect(tagged.toCodeUnitIndex(1)).toBe(2);
expect(tagged.toCodeUnitIndex(2)).toBe(4);
expect(tagged.toCodeUnitIndex(3)).toBe(5);
expect(tagged.toCodeUnitIndex(4)).toBe(7);
expect(tagged.toCodeUnitIndex(5)).toBe(9);
});
});
});
Expand Down
23 changes: 18 additions & 5 deletions src/symbol/shaping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class TaggedString {
/**
* Converts a UTF-16 character index to a UTF-16 code unit (JavaScript character index).
*/
codeUnitIndex(unicodeIndex: number): number {
toCodeUnitIndex(unicodeIndex: number): number {
return [...this.text].slice(0, unicodeIndex).join('').length;
}

Expand Down Expand Up @@ -270,7 +270,7 @@ function shapeText(
// Bidi doesn't have to be style-aware
lines = [];
// ICU operates on code units.
lineBreaks = lineBreaks.map(index => logicalInput.codeUnitIndex(index));
lineBreaks = lineBreaks.map(index => logicalInput.toCodeUnitIndex(index));
const untaggedLines =
processBidirectionalText(logicalInput.toString(), lineBreaks);
for (const line of untaggedLines) {
Expand All @@ -288,14 +288,27 @@ function shapeText(
// with formatting
lines = [];
// ICU operates on code units.
lineBreaks = lineBreaks.map(index => logicalInput.codeUnitIndex(index));
lineBreaks = lineBreaks.map(index => logicalInput.toCodeUnitIndex(index));

// Convert character-based section index to be based on code units.
let i = 0;
const sectionIndex = [];
for (const char of logicalInput.text) {
sectionIndex.push(...Array(char.length).fill(logicalInput.sectionIndex[i]));
i++;
}

const processedLines =
processStyledBidirectionalText(logicalInput.text, logicalInput.sectionIndex, lineBreaks);
processStyledBidirectionalText(logicalInput.text, sectionIndex, lineBreaks);
for (const line of processedLines) {
const taggedLine = new TaggedString();
taggedLine.text = line[0];
taggedLine.sectionIndex = line[1];
taggedLine.sections = logicalInput.sections;
let elapsedChars = '';
for (const char of line[0]) {
taggedLine.sectionIndex.push(line[1][elapsedChars.length]);
elapsedChars += char;
}
lines.push(taggedLine);
}
} else {
Expand Down

0 comments on commit abf39ed

Please sign in to comment.