@@ -26,8 +26,6 @@ import mapStyleToAttrs from 'zrender/lib/svg/mapStyleToAttrs';
26
26
import {
27
27
Skia ,
28
28
Path as SkiaPath ,
29
- Text as SkiaText ,
30
- matchFont ,
31
29
Shadow ,
32
30
useImage ,
33
31
Image ,
@@ -39,6 +37,9 @@ import {
39
37
SkPath ,
40
38
SkiaProps ,
41
39
ImageProps ,
40
+ Paragraph ,
41
+ FontWeight ,
42
+ FontSlant ,
42
43
} from '@shopify/react-native-skia' ;
43
44
import React from 'react' ;
44
45
@@ -347,6 +348,35 @@ function SkiaImage({ href, children, ...attrs }: CustomImageProps) {
347
348
) ;
348
349
}
349
350
351
+ const createFontSlant = ( fontStyle : TSpanStyleProps [ 'fontStyle' ] ) => {
352
+ switch ( fontStyle ) {
353
+ case 'italic' :
354
+ return FontSlant . Italic ;
355
+ case 'oblique' :
356
+ return FontSlant . Oblique ;
357
+ default :
358
+ return FontSlant . Upright ;
359
+ }
360
+ } ;
361
+
362
+ const createFontWeight = ( fontWeight : TSpanStyleProps [ 'fontWeight' ] ) => {
363
+ if ( typeof fontWeight === 'string' ) {
364
+ switch ( fontWeight ) {
365
+ case 'normal' :
366
+ return FontWeight . Normal ;
367
+ case 'bold' :
368
+ return FontWeight . Bold ;
369
+ case 'bolder' :
370
+ return FontWeight . ExtraBold ;
371
+ case 'lighter' :
372
+ return FontWeight . Light ;
373
+ default :
374
+ return parseInt ( fontWeight , 10 ) ;
375
+ }
376
+ }
377
+ return fontWeight ;
378
+ } ;
379
+
350
380
export function brushSVGTSpan (
351
381
el : TSpan ,
352
382
scope : BrushScope
@@ -364,42 +394,52 @@ export function brushSVGTSpan(
364
394
textBaseline,
365
395
} = el . style ;
366
396
if ( ! text ) return null ;
367
- const font = matchFont ( {
368
- fontFamily,
369
- fontSize,
370
- fontStyle,
371
- fontWeight : fontWeight as any ,
372
- } ) ;
373
397
const attrs : SVGVNodeAttrs = { } ;
374
398
const { id } = el ;
375
399
const transform = getTransform ( el . transform ) ;
376
400
setStyleAttrs ( attrs , el . style , el , scope ) ;
377
- const { width : textWidth , y : textY } = font . measureText ( text ) ;
401
+
402
+ const para = Skia . ParagraphBuilder . Make ( { } )
403
+ . pushStyle ( {
404
+ heightMultiplier : 1 ,
405
+ fontFamilies : [ fontFamily ] ,
406
+ fontSize :
407
+ typeof fontSize === 'string' ? parseInt ( fontSize , 10 ) : fontSize ,
408
+ color : typeof fill === 'string' ? Skia . Color ( fill ) : undefined ,
409
+ fontStyle : {
410
+ weight : createFontWeight ( fontWeight ) ,
411
+ slant : createFontSlant ( fontStyle ) ,
412
+ } ,
413
+ } )
414
+ . addText ( text )
415
+ . build ( ) ;
416
+ para . layout ( Infinity ) ;
417
+ const textHeight = para . getHeight ( ) ;
418
+ const textWidth = para . getLongestLine ( ) ;
378
419
const adjustX =
379
420
textAlign === 'center'
380
- ? textWidth / 2
421
+ ? - textWidth / 2
381
422
: textAlign === 'start' || textAlign === 'left'
382
423
? 0
383
- : textWidth ;
424
+ : - textWidth ;
384
425
const adjustY =
385
426
textBaseline === 'middle'
386
- ? textY / 2
387
- : textBaseline === 'bottom '
388
- ? textY
389
- : 0 ;
427
+ ? - textHeight / 2
428
+ : textBaseline === 'top '
429
+ ? 0
430
+ : - textHeight ;
390
431
if ( attrs [ 'fill-opacity' ] !== undefined ) {
391
432
attrs . opacity = attrs [ 'fill-opacity' ] ;
392
433
}
393
434
return (
394
- < SkiaText
435
+ < Paragraph
436
+ key = { id }
395
437
{ ...attrs }
396
438
transform = { transform }
397
- key = { id }
398
- x = { x - adjustX }
399
- y = { y - adjustY }
400
- text = { text }
401
- font = { font }
402
- color = { typeof fill === 'string' ? fill : undefined }
439
+ paragraph = { para }
440
+ x = { x + adjustX }
441
+ y = { y + adjustY }
442
+ width = { Math . ceil ( textWidth ) }
403
443
/>
404
444
) ;
405
445
}
0 commit comments