@@ -164,21 +164,21 @@ export default class FontLoader {
164
164
// @ts -ignore
165
165
{ lowMemory : true }
166
166
)
167
- cachedParsedFont . set ( data , font )
168
- }
169
-
170
- // Modify the `charToGlyphIndex` method, so we can know which char is
171
- // being mapped to which glyph.
172
- const originalCharToGlyphIndex = font . charToGlyphIndex
173
- font . charToGlyphIndex = ( char ) => {
174
- const index = originalCharToGlyphIndex . call ( font , char )
175
- if ( index === 0 ) {
176
- // The current requested char is missing a glyph.
177
- if ( ( font as any ) . _trackBrokenChars ) {
178
- ; ( font as any ) . _trackBrokenChars . push ( char )
167
+ // Modify the `charToGlyphIndex` method, so we can know which char is
168
+ // being mapped to which glyph.
169
+ const originalCharToGlyphIndex = font . charToGlyphIndex
170
+ font . charToGlyphIndex = ( char ) => {
171
+ const index = originalCharToGlyphIndex . call ( font , char )
172
+ if ( index === 0 ) {
173
+ // The current requested char is missing a glyph.
174
+ if ( ( font as any ) . _trackBrokenChars ) {
175
+ ; ( font as any ) . _trackBrokenChars . push ( char )
176
+ }
179
177
}
178
+ return index
180
179
}
181
- return index
180
+
181
+ cachedParsedFont . set ( data , font )
182
182
}
183
183
184
184
// We use the first font as the default font fallback.
@@ -506,11 +506,53 @@ export default class FontLoader {
506
506
if ( fontSize === 0 ) {
507
507
return ''
508
508
}
509
- return font
510
- . getPath ( content . replace ( / \n / g, '' ) , left , top , fontSize , {
511
- letterSpacing : letterSpacing / fontSize ,
512
- } )
513
- . toPathData ( 1 )
509
+
510
+ const fullPath = new opentype . Path ( )
511
+
512
+ const options = {
513
+ letterSpacing : letterSpacing / fontSize ,
514
+ }
515
+
516
+ const cachedPath = new WeakMap <
517
+ opentype . Glyph ,
518
+ [ number , number , opentype . Path ]
519
+ > ( )
520
+
521
+ font . forEachGlyph (
522
+ content . replace ( / \n / g, '' ) ,
523
+ left ,
524
+ top ,
525
+ fontSize ,
526
+ options ,
527
+ function ( glyph , gX , gY , gFontSize ) {
528
+ let glyphPath : opentype . Path
529
+ if ( ! cachedPath . has ( glyph ) ) {
530
+ glyphPath = glyph . getPath ( gX , gY , gFontSize , options )
531
+ cachedPath . set ( glyph , [ gX , gY , glyphPath ] )
532
+ } else {
533
+ const [ _x , _y , _glyphPath ] = cachedPath . get ( glyph )
534
+ glyphPath = new opentype . Path ( )
535
+ glyphPath . commands = _glyphPath . commands . map ( ( command ) => {
536
+ const movedCommand = { ...command }
537
+ for ( let k in movedCommand ) {
538
+ if ( typeof movedCommand [ k ] === 'number' ) {
539
+ if ( k === 'x' || k === 'x1' || k === 'x2' ) {
540
+ movedCommand [ k ] += gX - _x
541
+ }
542
+ if ( k === 'y' || k === 'y1' || k === 'y2' ) {
543
+ movedCommand [ k ] += gY - _y
544
+ }
545
+ }
546
+ }
547
+ return movedCommand
548
+ } )
549
+ }
550
+
551
+ fullPath . extend ( glyphPath )
552
+ }
553
+ )
554
+
555
+ return fullPath . toPathData ( 1 )
514
556
} finally {
515
557
unpatch ( )
516
558
}
0 commit comments