Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Unreleased

- Fix wrapped right-to-left text shaped as one run, e.g. Arabic with `features`, drawing the space at the end of each line on its left, which pushed every line but the last one space past the right margin with `align: 'right'`. Fixes #1422
- Fix the underline, strike-through, link and `goTo` rectangle of text drawn with a `baseline` other than the default sitting an ascent too low, because they were placed from the top of the line while the glyphs had moved up with the baseline. Fixes #994, #1245
- Fix links to a named destination going nowhere in readers that look the name up in sorted order, such as Chrome (PDFium) and qpdf, because name tree keys were sorted by locale with `localeCompare` instead of by their bytes: with destinations named `appendix` and `Chapter1`, `Chapter1` was written second and could not be found. The keys of the `EmbeddedFiles` and `JavaScript` name trees are sorted the same way
- Escape document information in XMP metadata and omit characters XML 1.0 cannot represent, without changing the PDF Info dictionary. Fixes #1817
Expand Down
5 changes: 4 additions & 1 deletion lib/mixins/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,10 @@ export default {
positions[positions.length - 1] = space;
}
} else {
[encoded, positions] = this._font.encode(text, options.features);
// Don't draw the whitespace at the end of a wrapped line. The alignment
// above leaves it out, and right-to-left text puts it on the left.
const drawn = options.width ? text.replace(/\s+$/, '') : text;
[encoded, positions] = this._font.encode(drawn, options.features);
}

const scale = this._fontSize / 1000;
Expand Down
Binary file added tests/fonts/NotoKufiArabic-Subset.ttf
Binary file not shown.
23 changes: 23 additions & 0 deletions tests/unit/text.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,29 @@ Q
expect(lines).toEqual(['a ', 'design-system']);
});

test('right-to-left wrapped lines do not draw their trailing space - issue #1422', () => {
document.font('tests/fonts/NotoKufiArabic-Subset.ttf', 12);
const features = ['rtla'];
const [[space]] = document._font.encode(' ', features);
const glyphs = [];
const addContent = document.addContent;
document.addContent = function (data) {
if (data.endsWith('TJ')) {
glyphs.push(data.match(/<([0-9a-f]+)>/)[1].match(/.{4}/g));
}
return addContent.call(this, data);
};

document.text('هذا نص عربي', { width: 60, align: 'right', features });

// The trailing space of the first line comes first once the line is
// reversed, and would push the line one space past the right margin.
expect(glyphs).toHaveLength(2);
expect(glyphs[0]).toHaveLength(6);
expect(glyphs[0][0]).not.toBe(space);
expect(glyphs[0]).toContain(space);
});

test('a continued segment can switch to lineBreak whitespace', () => {
const lines = [];
const line = document._line;
Expand Down