Skip to content

Commit

Permalink
#1486 fix newline items in lists (#1487)
Browse files Browse the repository at this point in the history
* adds test case with line-breaks in list items

reproduces #1486

* use LineBreaker per item and only draw `firstLine` once

fixes #1486

* boyscout: consistent naming

* boyscout: test multiple line break versions

* update changelog for fix of #1486

---------

Co-authored-by: David <filecage@users.noreply.github.com>
  • Loading branch information
filecage and filecage committed Dec 22, 2023
1 parent 408dc4e commit ebf404e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 58 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,7 @@
### Unreleased

- Add subset for PDF/UA
- Fix for line breaks in list items (#1486)

### [v0.14.0] - 2023-11-09

Expand Down
123 changes: 65 additions & 58 deletions lib/mixins/text.js
Expand Up @@ -153,73 +153,80 @@ export default {
}
};

wrapper = new LineWrapper(this, options);
wrapper.on('line', this._line);
const drawListItem = function(listItem) {
wrapper = new LineWrapper(this, options);
wrapper.on('line', this._line);

level = 1;
let i = 0;
wrapper.once('firstLine', () => {
let item, itemType, labelType, bodyType;
if (options.structParent) {
if (options.structTypes) {
[itemType, labelType, bodyType] = options.structTypes;
} else {
[itemType, labelType, bodyType] = ['LI', 'Lbl', 'LBody'];
}
}

level = 1;
let i = 0;
wrapper.on('firstLine', () => {
let item, itemType, labelType, bodyType;
if (options.structParent) {
if (options.structTypes) {
[ itemType, labelType, bodyType ] = options.structTypes;
} else {
[ itemType, labelType, bodyType ] = [ 'LI', 'Lbl', 'LBody' ];
if (itemType) {
item = this.struct(itemType);
options.structParent.add(item);
} else if (options.structParent) {
item = options.structParent;
}
}

if (itemType) {
item = this.struct(itemType);
options.structParent.add(item);
} else if (options.structParent) {
item = options.structParent;
}
let l;
if ((l = levels[i++]) !== level) {
const diff = itemIndent * (l - level);
this.x += diff;
wrapper.lineWidth -= diff;
level = l;
}

let l;
if ((l = levels[i++]) !== level) {
const diff = itemIndent * (l - level);
this.x += diff;
wrapper.lineWidth -= diff;
level = l;
}
if (item && (labelType || bodyType)) {
item.add(this.struct(labelType || bodyType,
[this.markStructureContent(labelType || bodyType)]));
}
switch (listType) {
case 'bullet':
this.circle(this.x - indent + r, this.y + midLine, r);
this.fill();
break;
case 'numbered':
case 'lettered':
var text = label(numbers[i - 1]);
this._fragment(text, this.x - indent, this.y, options);
break;
}

if (item && (labelType || bodyType)) {
item.add(this.struct(labelType || bodyType,
[ this.markStructureContent(labelType || bodyType) ]));
}
switch (listType) {
case 'bullet':
this.circle(this.x - indent + r, this.y + midLine, r);
this.fill();
break;
case 'numbered':
case 'lettered':
var text = label(numbers[i - 1]);
this._fragment(text, this.x - indent, this.y, options);
break;
}
if (item && labelType && bodyType) {
item.add(this.struct(bodyType, [this.markStructureContent(bodyType)]));
}
if (item && item !== options.structParent) {
item.end();
}
});

if (item && labelType && bodyType) {
item.add(this.struct(bodyType, [ this.markStructureContent(bodyType) ]));
}
if (item && item !== options.structParent) {
item.end();
}
});
wrapper.on('sectionStart', () => {
const pos = indent + itemIndent * (level - 1);
this.x += pos;
return (wrapper.lineWidth -= pos);
});

wrapper.on('sectionStart', () => {
const pos = indent + itemIndent * (level - 1);
this.x += pos;
return (wrapper.lineWidth -= pos);
});
wrapper.on('sectionEnd', () => {
const pos = indent + itemIndent * (level - 1);
this.x -= pos;
return (wrapper.lineWidth += pos);
});

wrapper.wrap(listItem, options);
};

wrapper.on('sectionEnd', () => {
const pos = indent + itemIndent * (level - 1);
this.x -= pos;
return (wrapper.lineWidth += pos);
});

wrapper.wrap(items.join('\n'), options);
for (let i = 0; i < items.length; i++) {
drawListItem.call(this, items[i]);
}

return this;
},
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions tests/visual/text.spec.js
Expand Up @@ -43,4 +43,11 @@ describe('text', function() {
doc.fillColor('#000').list(['One', 'Two', 'Three'], 100, 150);
});
});

test('list with line breaks in items', function() {
return runDocTest(function(doc) {
doc.font('tests/fonts/Roboto-Regular.ttf');
doc.list(['Foo\nBar', 'Foo\rBar', 'Foo\r\nBar'], [100, 150]);
})
})
});

0 comments on commit ebf404e

Please sign in to comment.