Skip to content

Commit

Permalink
add boundsOfString method
Browse files Browse the repository at this point in the history
- Allow users to compute the actual rendered bounds of a string (which includes multi-line support)
  • Loading branch information
hollandjake committed Jan 12, 2025
1 parent c792968 commit 5f47c6b
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions lib/mixins/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,59 @@ export default {
return ((this._font.widthOfString(string, this._fontSize, options.features) + (options.characterSpacing || 0) * (string.length - 1)) * horizontalScaling) / 100;
},

/**
* Compute the height and width of a string
* based on what will actually be rendered by `doc.text()`
*
* @param string - The string to measure
* @param options - Any text options (The same you would apply to `doc.text()`)
* @returns {{width: number, height: number}}
*/
boundsOfString(string, options = {}) {
const { x, y } = this;

options = this._initOptions(options);

const lineGap = options.lineGap || this._lineGap || 0;
const lineHeight = this.currentLineHeight(true) + lineGap;
let contentWidth = 0;
this._text(string, this.x, this.y, options, (text, options) => {
text = `${text}`.replace(/\n/g, "");
if (text.length > 0) {
// handle options
let wordSpacing = options.wordSpacing || 0;
const characterSpacing = options.characterSpacing || 0;

// text alignments
if (options.width && options.align === "justify") {
// calculate the word spacing value
wordSpacing = Math.max(
0,
(options.lineWidth -
this.widthOfString(text.replace(/\s+/g, ""), options)) /
Math.max(1, text.trim().split(/\s+/).length - 1) -
(this.widthOfString(" ") + characterSpacing),
);
}

// calculate the actual rendered width of the string after word and character spacing
const renderedWidth =
options.textWidth +
wordSpacing * (options.wordCount - 1) +
characterSpacing * (text.length - 1);
contentWidth = Math.max(contentWidth, renderedWidth);
}

return (this.y += lineHeight);
});

const contentHeight = this.y - y;
this.x = x;
this.y = y;

return { width: contentWidth, height: contentHeight };
},

heightOfString(text, options) {
const { x, y } = this;

Expand Down

0 comments on commit 5f47c6b

Please sign in to comment.