Skip to content

Commit

Permalink
Add support to scale text horizontally
Browse files Browse the repository at this point in the history
inspired by #445
  • Loading branch information
liborm85 committed Dec 27, 2024
1 parent 42172c5 commit 133a321
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Update fontkit to 2.0
- Update linebreak to 1.1
- Add support for spot colors
- Add support to scale text horizontally
- Fix sets tab order to "Structure" when a document is tagged
- Fix font cache collision for fonts with missing postscript name or bad TTF metadata
- Fix measuring text when OpenType features are passed in to .text()
Expand Down
1 change: 1 addition & 0 deletions docs/text.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ below.
* `lineGap` - the amount of space between each line of text
* `wordSpacing` - the amount of space between each word in the text
* `characterSpacing` - the amount of space between each character in the text
* `horizontalScaling` - ability to scale text horizontally (`100` percent by default)
* `fill` - whether to fill the text (`true` by default)
* `stroke` - whether to stroke the text
* `link` - a URL to link this text to (shortcut to create an annotation)
Expand Down
32 changes: 32 additions & 0 deletions examples/kitchen-sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,36 @@ doc.moveDown()
.fillColor('PANTONE185C')
.text('This text uses spot color!');

doc.moveDown();

doc
.font('Helvetica')
.fillColor('#000')
.text('Horizontal scaling support:');

doc.moveDown();

doc
.text(loremIpsum, {
height: 100,
width: 300,
align: 'justify',
});

doc
.text(loremIpsum, {
height: 100,
width: 300,
align: 'justify',
horizontalScaling: 75
});

doc
.text(loremIpsum, {
height: 100,
width: 300,
align: 'justify',
horizontalScaling: 130
});

doc.end();
Binary file modified examples/kitchen-sink.pdf
Binary file not shown.
19 changes: 10 additions & 9 deletions lib/line_wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ class LineWrapper extends EventEmitter {
constructor(document, options) {
super();
this.document = document;
this.indent = options.indent || 0;
this.characterSpacing = options.characterSpacing || 0;
this.wordSpacing = options.wordSpacing === 0;
this.horizontalScaling = options.horizontalScaling || 100;
this.indent = ((options.indent || 0) * this.horizontalScaling) / 100;
this.characterSpacing = ((options.characterSpacing || 0) * this.horizontalScaling) / 100;
this.wordSpacing = ((options.wordSpacing === 0) * this.horizontalScaling) / 100;
this.columns = options.columns || 1;
this.columnGap = options.columnGap != null ? options.columnGap : 18; // 1/4 inch
this.lineWidth =
(options.width - this.columnGap * (this.columns - 1)) / this.columns;
this.columnGap = ((options.columnGap != null ? options.columnGap : 18) * this.horizontalScaling) / 100; // 1/4 inch
this.lineWidth = (((options.width * this.horizontalScaling) / 100) - (this.columnGap * (this.columns - 1))) / this.columns;
this.spaceLeft = this.lineWidth;
this.startX = this.document.x;
this.startY = this.document.y;
Expand Down Expand Up @@ -165,14 +165,15 @@ class LineWrapper extends EventEmitter {

wrap(text, options) {
// override options from previous continued fragments
this.horizontalScaling = options.horizontalScaling || 100;
if (options.indent != null) {
this.indent = options.indent;
this.indent = (options.indent * this.horizontalScaling) / 100;
}
if (options.characterSpacing != null) {
this.characterSpacing = options.characterSpacing;
this.characterSpacing = (options.characterSpacing * this.horizontalScaling) / 100;
}
if (options.wordSpacing != null) {
this.wordSpacing = options.wordSpacing;
this.wordSpacing = (options.wordSpacing * this.horizontalScaling) / 100;
}
if (options.ellipsis != null) {
this.ellipsis = options.ellipsis;
Expand Down
26 changes: 15 additions & 11 deletions lib/mixins/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default {
const addStructure = () => {
if (options.structParent) {
options.structParent.add(this.struct(options.structType || 'P',
[ this.markStructureContent(options.structType || 'P') ]));
[this.markStructureContent(options.structType || 'P')]));
}
};

Expand Down Expand Up @@ -80,10 +80,8 @@ export default {
},

widthOfString(string, options = {}) {
return (
this._font.widthOfString(string, this._fontSize, options.features) +
(options.characterSpacing || 0) * (string.length - 1)
);
const horizontalScaling = options.horizontalScaling || 100;
return ((this._font.widthOfString(string, this._fontSize, options.features) + (options.characterSpacing || 0) * (string.length - 1)) * horizontalScaling) / 100;
},

heightOfString(text, options) {
Expand Down Expand Up @@ -121,7 +119,7 @@ export default {
const levels = [];
const numbers = [];

var flatten = function(list) {
var flatten = function (list) {
let n = 1;
for (let i = 0; i < list.length; i++) {
const item = list[i];
Expand All @@ -141,7 +139,7 @@ export default {

flatten(list);

const label = function(n) {
const label = function (n) {
switch (listType) {
case 'numbered':
return `${n}.`;
Expand All @@ -153,7 +151,7 @@ export default {
}
};

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

Expand Down Expand Up @@ -299,6 +297,7 @@ export default {
const align = options.align || 'left';
let wordSpacing = options.wordSpacing || 0;
const characterSpacing = options.characterSpacing || 0;
const horizontalScaling = options.horizontalScaling || 100;

// text alignments
if (options.width) {
Expand All @@ -320,7 +319,7 @@ export default {
wordSpacing = Math.max(
0,
(options.lineWidth - textWidth) / Math.max(1, words.length - 1) -
spaceWidth
spaceWidth
);
break;
}
Expand Down Expand Up @@ -388,13 +387,13 @@ export default {
this._fontSize < 10 ? 0.5 : Math.floor(this._fontSize / 10);
this.lineWidth(lineWidth);

let lineY = (y + this.currentLineHeight()) - lineWidth
let lineY = (y + this.currentLineHeight()) - lineWidth
this.moveTo(x, lineY);
this.lineTo(x + renderedWidth, lineY);
this.stroke();
this.restore();
}

// create strikethrough line
if (options.strike) {
this.save();
Expand Down Expand Up @@ -457,6 +456,11 @@ export default {
this.addContent(`${number(characterSpacing)} Tc`);
}

// Horizontal scaling
if (horizontalScaling !== 100) {
this.addContent(`${horizontalScaling} Tz`);
}

// Add the actual text
// If we have a word spacing value, we need to encode each word separately
// since the normal Tw operator only works on character code 32, which isn't
Expand Down

0 comments on commit 133a321

Please sign in to comment.