@@ -5,68 +5,75 @@ import {
55 SUPPORTED_MODIFIERS_GLOBAL ,
66 TEXT_COLORS ,
77 TEXT_SHADOW_COLORS ,
8+ NEWLINE_REGEX ,
89} from '../constants' ;
910
1011export default function renderText ( text : string , ctx : CanvasRenderingContext2D ) {
11- let cursorX = 0 ;
1212 let cursorY = FONT_SIZE - FONT_OFFSET ;
13- let currentColor : number = TEXT_COLORS . f ;
14- let currentShadowColor : number = TEXT_SHADOW_COLORS . f ;
15- let isBold = false ;
1613
17- for ( let i = 0 ; i < text . length ; i ++ ) {
18- const char = text [ i ] as string ;
19- const nextChar = text [ i + 1 ] ;
14+ text . split ( NEWLINE_REGEX ) . forEach ( ( line ) => {
15+ let currentColor : number = TEXT_COLORS . f ;
16+ let currentShadowColor : number = TEXT_SHADOW_COLORS . f ;
17+ let isBold = false ;
18+ let cursorX = 0 ;
2019
21- // Check if this character and the next one are a supported modifier
22- // WARNING: JavaScript has inconsistent RegEx test behaviour with the global flag enabled -
23- // On subsequent test() calls, it begins searching from the index of the previous match.
24- // For this reason, we have to create a new, non-global RegEx to test our expression.
25- // I hate JS.
26- if ( char === '&' && new RegExp ( SUPPORTED_MODIFIERS_GLOBAL . source ) . test ( char + nextChar ) ) {
27- if ( nextChar && nextChar in TEXT_COLORS ) {
28- currentColor = TEXT_COLORS [ nextChar as HexDigit ] ;
29- currentShadowColor = TEXT_SHADOW_COLORS [ nextChar as HexDigit ] ;
30- } else if ( nextChar === 'r' ) {
31- currentColor = TEXT_COLORS . f ;
32- currentShadowColor = TEXT_SHADOW_COLORS . f ;
33- isBold = false ;
34- } else if ( nextChar === 'l' ) {
35- isBold = true ;
20+ for ( let i = 0 ; i < line . length ; i ++ ) {
21+ const char = line [ i ] as string ;
22+ const nextChar = line [ i + 1 ] ;
23+
24+ // Check if this character and the next one are a supported modifier
25+ // WARNING: JavaScript has inconsistent RegEx test behaviour with the global flag enabled -
26+ // On consecutive test() calls, it begins searching from the index of the previous match.
27+ // For this reason, we have to create a new, non-global RegEx to test our expression. I hate JS.
28+ if (
29+ nextChar &&
30+ char === '&' &&
31+ new RegExp ( SUPPORTED_MODIFIERS_GLOBAL . source ) . test ( char + nextChar )
32+ ) {
33+ if ( nextChar in TEXT_COLORS ) {
34+ currentColor = TEXT_COLORS [ nextChar as HexDigit ] ;
35+ currentShadowColor = TEXT_SHADOW_COLORS [ nextChar as HexDigit ] ;
36+ } else if ( nextChar === 'r' ) {
37+ currentColor = TEXT_COLORS . f ;
38+ currentShadowColor = TEXT_SHADOW_COLORS . f ;
39+ isBold = false ;
40+ } else if ( nextChar === 'l' ) {
41+ isBold = true ;
42+ } else {
43+ continue ;
44+ }
45+
46+ // Skip the next character as it is part of a modifying sequence
47+ i += 1 ;
3648 } else {
37- continue ;
38- }
49+ const shadowX = cursorX + FONT_OFFSET ;
50+ const shadowY = cursorY + FONT_OFFSET ;
3951
40- // Skip the next character as it is part of a modifying sequence
41- i += 1 ;
42- } else if ( char === '\n' ) {
43- cursorX = 0 ;
44- cursorY = FONT_SIZE * 2 + FONT_OFFSET ;
45- } else {
46- const shadowX = cursorX + FONT_OFFSET ;
47- const shadowY = cursorY + FONT_OFFSET ;
52+ // Draw shadow
53+ ctx . fillStyle = `#${ currentShadowColor . toString ( 16 ) } ` ;
54+ ctx . fillText ( char , shadowX , shadowY ) ;
55+ if ( isBold ) {
56+ ctx . fillText ( char , shadowX + FONT_OFFSET , shadowY ) ;
57+ }
4858
49- // Draw shadow
50- ctx . fillStyle = `#${ currentShadowColor . toString ( 16 ) } ` ;
51- ctx . fillText ( char , shadowX , shadowY ) ;
52- if ( isBold ) {
53- ctx . fillText ( char , shadowX + FONT_OFFSET , shadowY ) ;
54- }
59+ // Draw text
60+ ctx . fillStyle = `#${ currentColor . toString ( 16 ) } ` ;
61+ ctx . fillText ( char , cursorX , cursorY ) ;
62+ if ( isBold ) {
63+ ctx . fillText ( char , cursorX + FONT_OFFSET , cursorY ) ;
64+ }
5565
56- // Draw text
57- ctx . fillStyle = `#${ currentColor . toString ( 16 ) } ` ;
58- ctx . fillText ( char , cursorX , cursorY ) ;
59- if ( isBold ) {
60- ctx . fillText ( char , cursorX + FONT_OFFSET , cursorY ) ;
61- }
66+ // Add extra space in between letters if character is bold
67+ let { width } = ctx . measureText ( char ) ;
68+ if ( isBold ) {
69+ width += FONT_OFFSET ;
70+ }
6271
63- // Add extra space in between letters if character is bold
64- let { width } = ctx . measureText ( char ) ;
65- if ( isBold ) {
66- width += FONT_OFFSET ;
72+ cursorX += width ;
6773 }
68-
69- cursorX += width ;
7074 }
71- }
75+
76+ // Move the cursor down to the next line. Add double-spacing to account for shadow
77+ cursorY += FONT_SIZE + ( FONT_OFFSET * 2 ) ;
78+ } ) ;
7279}
0 commit comments