@ -271,9 +271,12 @@ export const measureText = (
container . style . whiteSpace = "pre" ;
container . style . font = font ;
container . style . minHeight = "1em" ;
const textWidth = getTextWidth ( text , font ) ;
if ( maxWidth ) {
const lineHeight = getApproxLineHeight ( font ) ;
container . style . width = ` ${ String ( maxWidth + 1 ) } px ` ;
container . style . width = ` ${ String ( Math . min ( textWidth , maxWidth ) + 1 ) } px ` ;
container . style . overflow = "hidden" ;
container . style . wordBreak = "break-word" ;
container . style . lineHeight = ` ${ String ( lineHeight ) } px ` ;
@ -291,7 +294,10 @@ export const measureText = (
// Baseline is important for positioning text on canvas
const baseline = span . offsetTop + span . offsetHeight ;
// Since span adds 1px extra width to the container
const width = container . offsetWidth - 1 ;
let width = container . offsetWidth ;
if ( maxWidth && textWidth > maxWidth ) {
width = width - 1 ;
}
const height = container . offsetHeight ;
document . body . removeChild ( container ) ;
if ( isTestEnv ( ) ) {
@ -312,7 +318,7 @@ export const getApproxLineHeight = (font: FontString) => {
} ;
let canvas : HTMLCanvasElement | undefined ;
const get Text Width = ( text : string , font : FontString ) = > {
const get Line Width = ( text : string , font : FontString ) = > {
if ( ! canvas ) {
canvas = document . createElement ( "canvas" ) ;
}
@ -330,10 +336,18 @@ const getTextWidth = (text: string, font: FontString) => {
return metrics . width ;
} ;
export const getTextWidth = ( text : string , font : FontString ) = > {
const lines = text . split ( "\n" ) ;
let width = 0 ;
lines . forEach ( ( line ) = > {
width = Math . max ( width , getLineWidth ( line , font ) ) ;
} ) ;
return width ;
} ;
export const wrapText = ( text : string , font : FontString , maxWidth : number ) = > {
const lines : Array < string > = [ ] ;
const originalLines = text . split ( "\n" ) ;
const spaceWidth = getTextWidth ( " " , font ) ;
const spaceWidth = get Line Width( " " , font ) ;
const push = ( str : string ) = > {
if ( str . trim ( ) ) {
@ -351,7 +365,7 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => {
let index = 0 ;
while ( index < words . length ) {
const currentWordWidth = get Text Width( words [ index ] , font ) ;
const currentWordWidth = get Line Width( words [ index ] , font ) ;
// Start breaking longer words exceeding max width
if ( currentWordWidth >= maxWidth ) {
@ -400,7 +414,7 @@ export const wrapText = (text: string, font: FontString, maxWidth: number) => {
// Start appending words in a line till max width reached
while ( currentLineWidthTillNow < maxWidth && index < words . length ) {
const word = words [ index ] ;
currentLineWidthTillNow = get Text Width( currentLine + word , font ) ;
currentLineWidthTillNow = get Line Width( currentLine + word , font ) ;
if ( currentLineWidthTillNow >= maxWidth ) {
push ( currentLine ) ;
@ -448,7 +462,7 @@ export const charWidth = (() => {
cachedCharWidth [ font ] = [ ] ;
}
if ( ! cachedCharWidth [ font ] [ ascii ] ) {
const width = get Text Width( char , font ) ;
const width = get Line Width( char , font ) ;
cachedCharWidth [ font ] [ ascii ] = width ;
}
@ -508,7 +522,7 @@ export const getApproxCharsToFitInWidth = (font: FontString, width: number) => {
while ( widthTillNow <= width ) {
const batch = dummyText . substr ( index , index + batchLength ) ;
str += batch ;
widthTillNow += get Text Width( str , font ) ;
widthTillNow += get Line Width( str , font ) ;
if ( index === dummyText . length - 1 ) {
index = 0 ;
}
@ -517,7 +531,7 @@ export const getApproxCharsToFitInWidth = (font: FontString, width: number) => {
while ( widthTillNow > width ) {
str = str . substr ( 0 , str . length - 1 ) ;
widthTillNow = get Text Width( str , font ) ;
widthTillNow = get Line Width( str , font ) ;
}
return str . length ;
} ;