Skip to content

Commit 497ac31

Browse files
committed
feat: use Paragraph
1 parent 6a00760 commit 497ac31

File tree

1 file changed

+62
-22
lines changed

1 file changed

+62
-22
lines changed

src/skia/graphic.tsx

+62-22
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ import mapStyleToAttrs from 'zrender/lib/svg/mapStyleToAttrs';
2626
import {
2727
Skia,
2828
Path as SkiaPath,
29-
Text as SkiaText,
30-
matchFont,
3129
Shadow,
3230
useImage,
3331
Image,
@@ -39,6 +37,9 @@ import {
3937
SkPath,
4038
SkiaProps,
4139
ImageProps,
40+
Paragraph,
41+
FontWeight,
42+
FontSlant,
4243
} from '@shopify/react-native-skia';
4344
import React from 'react';
4445

@@ -347,6 +348,35 @@ function SkiaImage({ href, children, ...attrs }: CustomImageProps) {
347348
);
348349
}
349350

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+
350380
export function brushSVGTSpan(
351381
el: TSpan,
352382
scope: BrushScope
@@ -364,42 +394,52 @@ export function brushSVGTSpan(
364394
textBaseline,
365395
} = el.style;
366396
if (!text) return null;
367-
const font = matchFont({
368-
fontFamily,
369-
fontSize,
370-
fontStyle,
371-
fontWeight: fontWeight as any,
372-
});
373397
const attrs: SVGVNodeAttrs = {};
374398
const { id } = el;
375399
const transform = getTransform(el.transform);
376400
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();
378419
const adjustX =
379420
textAlign === 'center'
380-
? textWidth / 2
421+
? -textWidth / 2
381422
: textAlign === 'start' || textAlign === 'left'
382423
? 0
383-
: textWidth;
424+
: -textWidth;
384425
const adjustY =
385426
textBaseline === 'middle'
386-
? textY / 2
387-
: textBaseline === 'bottom'
388-
? textY
389-
: 0;
427+
? -textHeight / 2
428+
: textBaseline === 'top'
429+
? 0
430+
: -textHeight;
390431
if (attrs['fill-opacity'] !== undefined) {
391432
attrs.opacity = attrs['fill-opacity'];
392433
}
393434
return (
394-
<SkiaText
435+
<Paragraph
436+
key={id}
395437
{...attrs}
396438
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)}
403443
/>
404444
);
405445
}

0 commit comments

Comments
 (0)