Skip to content

Commit c1c349a

Browse files
committed
📖
1 parent bf692d8 commit c1c349a

File tree

4 files changed

+63
-11
lines changed

4 files changed

+63
-11
lines changed

docs/docs/text/paragraph.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,32 +78,42 @@ const textStyle = {
7878
};
7979
```
8080

81-
## Paragraph Height
81+
## Paragraph Bounding Box
8282

83-
To get the paragraph height, you can calculate the layout using `layout()` and once done, you can invoke `getHeight()`.
83+
Before getting the paragraph height and width, you need to compute its layout using `layout()` and and once done, you can invoke `getHeight()` for the height and `getLongestLine()` for the width.
8484

8585
```tsx twoslash
8686
import { useMemo } from "react";
87-
import { Paragraph, Skia, useFonts } from "@shopify/react-native-skia";
87+
import { Paragraph, Skia, useFonts, Canvas, Rect } from "@shopify/react-native-skia";
8888

8989
const MyParagraph = () => {
9090
const paragraph = useMemo(() => {
9191
const para = Skia.ParagraphBuilder.Make()
92-
.addText("Say Hello to ")
93-
.addText("Skia 🎨")
94-
.pop()
92+
.addText("Say Hello to React Native Skia")
9593
.build();
9694
// Calculate the layout
97-
para.layout(300);
95+
para.layout(200);
9896
return para;
9997
}, []);
10098
// Now the paragraph height is available
10199
const height = paragraph.getHeight();
100+
const width = paragraph.getLongestLine();
102101
// Render the paragraph
103-
return <Paragraph paragraph={paragraph} x={0} y={0} width={300} />;
102+
return (
103+
<Canvas style={{ width: 256, height: 256 }}>
104+
{/* Maximum paragraph width */}
105+
<Rect x={0} y={0} width={200} height={256} color="magenta" />
106+
{/* Paragraph bounding box */}
107+
<Rect x={0} y={0} width={width} height={height} color="cyan" />
108+
<Paragraph paragraph={paragraph} x={0} y={0} width={200} />
109+
</Canvas>
110+
);
104111
};
105112
```
106113

114+
<img src={require("/static/img/paragraph/boundingbox-node.png").default} width="256" height="256" />
115+
116+
107117
## Fonts
108118

109119
By default, the paragraph API will use the system fonts.
25.2 KB
Loading

package/src/renderer/__tests__/e2e/Paragraphs.spec.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,42 @@ describe("Paragraphs", () => {
528528
`snapshots/paragraph/paragraph-bounding-box-${surface.OS}.png`
529529
);
530530
});
531+
it("should draw the bounding box (3)", async () => {
532+
const img = await surface.drawOffscreen(
533+
(Skia, canvas, ctx) => {
534+
const robotoRegular = Skia.Typeface.MakeFreeTypeFaceFromData(
535+
Skia.Data.fromBytes(new Uint8Array(ctx.RobotoRegular))
536+
)!;
537+
const provider = Skia.TypefaceFontProvider.Make();
538+
provider.registerFont(robotoRegular, "Roboto");
539+
const para = Skia.ParagraphBuilder.Make({}, provider)
540+
.pushStyle({
541+
fontFamilies: ["Roboto"],
542+
color: Skia.Color("black"),
543+
fontSize: 30,
544+
})
545+
.addText("Say Hello to React Native Skia")
546+
.pop()
547+
.build();
548+
const maxWidth = ctx.canvasWidth * 0.78125;
549+
para.layout(maxWidth);
550+
const paint = Skia.Paint();
551+
paint.setColor(Skia.Color("magenta"));
552+
const height = para.getHeight();
553+
const width = para.getLongestLine();
554+
canvas.drawRect(Skia.XYWHRect(0, 0, maxWidth, ctx.canvasHeight), paint);
555+
paint.setColor(Skia.Color("cyan"));
556+
canvas.drawRect(Skia.XYWHRect(0, 0, width, height), paint);
557+
para.paint(canvas, 0, 0);
558+
},
559+
{
560+
RobotoRegular,
561+
canvasWidth: surface.width,
562+
canvasHeight: surface.height,
563+
}
564+
);
565+
checkImage(img, docPath(`paragraph/boundingbox-${surface.OS}.png`));
566+
});
531567

532568
itRunsE2eOnly("should return the paragraph height", async () => {
533569
const { width, height } = await surface.eval((Skia) => {

package/src/skia/web/JsiSkParagraphBuilderFactory.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
import { Host } from "./Host";
1010
import { JsiSkParagraphBuilder } from "./JsiSkParagraphBuilder";
1111
import { JsiSkParagraphStyle } from "./JsiSkParagraphStyle";
12-
import { JsiSkTypeface } from "./JsiSkTypeface";
12+
import { JsiSkTypefaceFontProvider } from "./JsiSkTypefaceFontProvider";
1313

1414
export class JsiSkParagraphBuilderFactory
1515
extends Host
@@ -31,11 +31,17 @@ export class JsiSkParagraphBuilderFactory
3131
"SkTypefaceFontProvider is required on React Native Web."
3232
);
3333
}
34+
const fontCollection = this.CanvasKit.FontCollection.Make();
35+
fontCollection.setDefaultFontManager(
36+
JsiSkTypefaceFontProvider.fromValue(typefaceProvider)
37+
);
38+
fontCollection.enableFontFallback();
39+
3440
return new JsiSkParagraphBuilder(
3541
this.CanvasKit,
36-
this.CanvasKit.ParagraphBuilder.MakeFromFontProvider(
42+
this.CanvasKit.ParagraphBuilder.MakeFromFontCollection(
3743
style,
38-
JsiSkTypeface.fromValue(typefaceProvider)
44+
fontCollection
3945
)
4046
);
4147
}

0 commit comments

Comments
 (0)