@@ -152,12 +152,21 @@ export class Text extends Shape {
152152 ]
153153 }
154154
155+ private computeFontSize ( text : string , defaultFontSize : number , context : CanvasRenderingContext2D ) : number {
156+ let defaultTextWidth = 0 ;
157+ if ( defaultFontSize < 1 ) {
158+ context . font = Text . buildFont ( this . style , 1 , this . font ) ;
159+ defaultTextWidth = context . measureText ( text ) . width * defaultFontSize ;
160+ } else defaultTextWidth = context . measureText ( text ) . width ;
161+ if ( defaultTextWidth >= this . boundingBox . size . x ) return defaultFontSize * this . boundingBox . size . x / defaultTextWidth ;
162+ return defaultFontSize
163+ }
164+
155165 private automaticFontSize ( context : CanvasRenderingContext2D ) : number {
156166 let fontsize = Math . min ( this . boundingBox . size . y ?? Number . POSITIVE_INFINITY , this . fontsize ?? Number . POSITIVE_INFINITY ) ;
157167 if ( fontsize == Number . POSITIVE_INFINITY ) fontsize = C . DEFAULT_FONTSIZE ;
158168 context . font = Text . buildFont ( this . style , fontsize , this . font ) ;
159- if ( context . measureText ( this . text ) . width >= this . boundingBox . size . x ) fontsize = fontsize * this . boundingBox . size . x / context . measureText ( this . text ) . width ;
160- return fontsize
169+ return this . computeFontSize ( this . text , fontsize , context )
161170 }
162171
163172 private setRectOffsetX ( ) : number {
@@ -225,7 +234,13 @@ export class Text extends Shape {
225234 context . resetTransform ( ) ;
226235 context . translate ( origin . x , origin . y ) ;
227236 context . rotate ( Math . PI / 180 * this . orientation ) ;
228- if ( this . isScaled ) context . scale ( Math . abs ( contextMatrix . a ) , Math . abs ( contextMatrix . d ) ) ;
237+ if ( this . isScaled ) {
238+ if ( this . fontsize < 1 ) {
239+ context . scale ( Math . abs ( contextMatrix . a * this . fontsize ) , Math . abs ( contextMatrix . d * this . fontsize ) ) ;
240+ context . font = Text . buildFont ( this . style , 1 , this . font ) ;
241+ }
242+ else context . scale ( Math . abs ( contextMatrix . a ) , Math . abs ( contextMatrix . d ) ) ;
243+ }
229244 this . write ( this . writtenText , context ) ;
230245 }
231246
@@ -263,10 +278,11 @@ export class Text extends Shape {
263278
264279 private multiLineWrite ( writtenText : string [ ] , middleFactor : number , context : CanvasRenderingContext2D ) : void {
265280 const nRows = writtenText . length - 1 ;
281+ const fontsize = Math . max ( this . fontsize , 1 ) ;
266282 writtenText . forEach ( ( row , index ) => {
267283 [ "top" , "hanging" ] . includes ( this . baseline )
268- ? context . fillText ( index == 0 ? Text . capitalize ( row ) : row , 0 , index * this . fontsize + this . offset )
269- : context . fillText ( index == 0 ? Text . capitalize ( row ) : row , 0 , ( index - nRows / middleFactor ) * this . fontsize + this . offset ) ;
284+ ? context . fillText ( index == 0 ? Text . capitalize ( row ) : row , 0 , index * fontsize + this . offset )
285+ : context . fillText ( index == 0 ? Text . capitalize ( row ) : row , 0 , ( index - nRows / middleFactor ) * fontsize + this . offset ) ;
270286 } ) ;
271287 }
272288
@@ -319,7 +335,7 @@ export class Text extends Shape {
319335 const [ writtenText , fontsize ] = this . formatInBoundingBox ( context ) ;
320336 this . fontsize = Math . abs ( fontsize ) ;
321337 this . height = writtenText . length * this . fontsize ;
322- this . width = this . getLongestRow ( context , writtenText ) ;
338+ this . width = this . fontsize > 1 ? this . getLongestRow ( context , writtenText ) : this . boundingBox . size . x ?? this . getLongestRow ( context , writtenText ) ;
323339 this . rowIndices = this . computeRowIndices ( writtenText ) ;
324340 return writtenText
325341 }
@@ -330,7 +346,7 @@ export class Text extends Shape {
330346 if ( oneRowLength < this . boundingBox . size . x ) {
331347 return [ [ this . text . trimStart ( ) ] , fontsize > this . boundingBox . size . y ? this . boundingBox . size . y ?? fontsize : fontsize ] ;
332348 }
333- if ( ! this . boundingBox . size . y ) return [ this . fixedFontSplit ( context ) , fontsize ] ;
349+ if ( ! this . boundingBox . size . y ) return this . fixedFontSplit ( fontsize , context )
334350 return this . autoFontSplit ( fontsize , context ) ;
335351 }
336352
@@ -339,14 +355,11 @@ export class Text extends Shape {
339355 return this . splitInWords ( ) ;
340356 }
341357
342- private pushSeparatorInWords ( pickedChars : number ) : [ string , number ] {
343- return [ this . text [ pickedChars ] , pickedChars + 1 ]
344- }
345-
346358 private buildWord ( pickedChars : number , word : string ) : [ string , number ] {
347- while ( ! C . TEXT_SEPARATORS . includes ( this . text [ pickedChars ] ) && pickedChars < this . text . length ) {
359+ while ( pickedChars < this . text . length ) {
348360 word += this . text [ pickedChars ] ;
349361 pickedChars ++ ;
362+ if ( C . TEXT_SEPARATORS . includes ( word [ word . length - 1 ] ) ) break ;
350363 }
351364 return [ word , pickedChars ]
352365 }
@@ -356,8 +369,7 @@ export class Text extends Shape {
356369 let pickedChars = 0 ;
357370 while ( pickedChars < this . text . length ) {
358371 let word = "" ;
359- if ( C . TEXT_SEPARATORS . includes ( this . text [ pickedChars ] ) ) [ word , pickedChars ] = this . pushSeparatorInWords ( pickedChars )
360- else [ word , pickedChars ] = this . buildWord ( pickedChars , word ) ;
372+ [ word , pickedChars ] = this . buildWord ( pickedChars , word ) ;
361373 words . push ( word ) ;
362374 }
363375 return words . length > 1 ? words : this . text . split ( "" )
@@ -376,23 +388,30 @@ export class Text extends Shape {
376388 return [ row + this . words [ pickedWords ] , pickedWords + 1 ]
377389 }
378390
379- private computeNewRow ( context : CanvasRenderingContext2D , pickedWords : number , rows : string [ ] ) : [ string [ ] , number ] {
391+ private computeNewRow ( context : CanvasRenderingContext2D , pickedWords : number , rows : string [ ] , fontsize : number ) : [ string [ ] , number , number ] {
380392 let newRow = '' ;
381393 while ( context . measureText ( newRow ) . width < this . boundingBox . size . x && pickedWords < this . words . length ) {
382- if ( this . isTextTooWide ( context , newRow + this . words [ pickedWords ] ) && newRow != '' ) break
383- else [ newRow , pickedWords ] = this . addPickedWordToRow ( newRow , pickedWords ) ;
394+ if ( this . isTextTooWide ( context , newRow + this . words [ pickedWords ] ) ) {
395+ if ( newRow != '' ) break
396+ }
397+ [ newRow , pickedWords ] = this . addPickedWordToRow ( newRow , pickedWords ) ;
384398 }
385399 if ( newRow . length != 0 ) rows . push ( newRow ) ;
386- return [ rows , pickedWords ]
400+ return [ rows , pickedWords , fontsize ]
387401 }
388402
389- private fixedFontSplit ( context : CanvasRenderingContext2D ) : string [ ] {
403+ private fixedFontSplit ( fontsize : number , context : CanvasRenderingContext2D ) : [ string [ ] , number ] {
390404 let rows : string [ ] = [ ] ;
391405 let pickedWords = 0 ;
392- while ( pickedWords < this . words . length ) [ rows , pickedWords ] = this . computeNewRow ( context , pickedWords , rows ) ;
393- return rows
406+ while ( pickedWords < this . words . length ) {
407+ [ rows , pickedWords , fontsize ] = this . computeNewRow ( context , pickedWords , rows , fontsize ) ;
408+ if ( this . isTextTooWide ( context , rows [ rows . length - 1 ] ) ) {
409+ fontsize = this . computeFontSize ( rows [ rows . length - 1 ] , fontsize , context ) ;
410+ context . font = Text . buildFont ( this . style , fontsize , this . font ) ;
411+ }
412+ }
413+ return [ rows , fontsize ]
394414 }
395-
396415 private cleanStartAllRows ( rows : string [ ] ) : string [ ] { return rows . map ( row => row . trimStart ( ) ) }
397416
398417 private checkWordsLength ( context : CanvasRenderingContext2D ) : boolean {
@@ -404,7 +423,7 @@ export class Text extends Shape {
404423
405424 private computeTextHeight ( fontsize : number , textHeight : number , rows : string [ ] , context : CanvasRenderingContext2D ) : [ string [ ] , number ] {
406425 if ( this . checkWordsLength ( context ) ) {
407- rows = this . fixedFontSplit ( context ) ;
426+ rows = this . fixedFontSplit ( fontsize , context ) [ 0 ] ;
408427 textHeight = fontsize * rows . length ;
409428 }
410429 return [ rows , textHeight ]
0 commit comments