diff --git a/docs/docs/text/blob.md b/docs/docs/text/blob.md
new file mode 100644
index 0000000000..75c2808685
--- /dev/null
+++ b/docs/docs/text/blob.md
@@ -0,0 +1,38 @@
+---
+id: blob
+title: Text Blob
+sidebar_label: Text Blob
+slug: /text/blob
+---
+
+A text blob contains glyphs, their positions, and paint attributes specific to text.
+
+| Name | Type | Description |
+|:------------|:-----------|:-------------------------------------------------------------|
+| blob | `TextBlob` | Text blob |
+| x? | `number` | x coordinate of the origin of the entire run. Default is 0 |
+| y? | `number` | y coordinate of the origin of the entire run. Default is 0 |
+
+## Example
+
+```tsx twoslash
+import {Canvas, TextBlob, Skia} from "@shopify/react-native-skia";
+
+
+export const HelloWorld = () => {
+ const typeface = Skia.FontMgr.RefDefault().matchFamilyStyle("helvetica");
+ if (!typeface) {
+ throw new Error("Helvetica not found");
+ }
+ const font = Skia.Font(typeface, 30);
+ const blob = Skia.TextBlob.MakeFromText("Hello World!", font);
+ return (
+
+ );
+};
+```
\ No newline at end of file
diff --git a/docs/docs/text/path.md b/docs/docs/text/path.md
new file mode 100644
index 0000000000..75ddf8e878
--- /dev/null
+++ b/docs/docs/text/path.md
@@ -0,0 +1,41 @@
+---
+id: path
+title: Text Path
+sidebar_label: Text Path
+slug: /text/path
+---
+
+Draws text along an SVG path.
+The fonts available in the canvas are described in [here](/docs/text/fonts).
+
+| Name | Type | Description |
+|:------------|:-------------------|:-------------------------------------------------------------|
+| path | `Path` or `string` | Path to draw. Can be a string using the [SVG Path notation](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#line_commands) or an object created with `Skia.Path.Make()` |
+| text | `string` | Text to draw |
+| font | `Font` | Font to use (see [Fonts](/docs/text/fonts)) |
+| familyName? | `string` | Font family name to use (see [Fonts](/docs/text/fonts)) |
+| size? | `number` | Font size if `familName` is provided |
+
+## Example
+
+```tsx twoslash
+import {Canvas, Group, TextPath, Skia} from "@shopify/react-native-skia";
+
+const circle = Skia.Path.Make();
+circle.addCircle(128, 128, 128);
+
+export const HelloWorld = () => {
+ return (
+
+ );
+};
+```
diff --git a/docs/sidebars.js b/docs/sidebars.js
index b88d3d22e3..d0e03b19df 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -47,7 +47,13 @@ const sidebars = {
collapsed: true,
type: "category",
label: "Text",
- items: ["text/fonts", "text/text", "text/glyphs"],
+ items: [
+ "text/fonts",
+ "text/text",
+ "text/glyphs",
+ "text/path",
+ "text/blob",
+ ],
},
{
collapsed: true,
diff --git a/example/src/Examples/API/Path2.tsx b/example/src/Examples/API/Path2.tsx
index 026559b2fc..110f0f627d 100644
--- a/example/src/Examples/API/Path2.tsx
+++ b/example/src/Examples/API/Path2.tsx
@@ -7,6 +7,8 @@ import {
Path,
Group,
rect,
+ TextPath,
+ useFont,
} from "@shopify/react-native-skia";
import { Title } from "./components/Title";
@@ -43,6 +45,10 @@ const result = Skia.Path.MakeFromOp(rect1, circle, PathOp.Difference)!;
result.simplify();
export const PathExample = () => {
+ const font = useFont(require("./Roboto-Regular.otf"), 32);
+ if (!font) {
+ return null;
+ }
return (
Path Operations
@@ -68,6 +74,12 @@ export const PathExample = () => {
+ Text Path
+
);
};
@@ -89,4 +101,8 @@ const styles = StyleSheet.create({
width: SIZE,
height: SIZE,
},
+ textPath: {
+ width: SIZE,
+ height: SIZE,
+ },
});
diff --git a/example/src/Examples/API/Roboto-Regular.otf b/example/src/Examples/API/Roboto-Regular.otf
new file mode 100644
index 0000000000..8f0906a79c
Binary files /dev/null and b/example/src/Examples/API/Roboto-Regular.otf differ
diff --git a/package/cpp/api/JsiSkApi.h b/package/cpp/api/JsiSkApi.h
index 53a21ba791..b0d1b2e705 100644
--- a/package/cpp/api/JsiSkApi.h
+++ b/package/cpp/api/JsiSkApi.h
@@ -35,6 +35,8 @@
#include "JsiSkDataFactory.h"
#include "JsiSkFontMgrFactory.h"
#include "JsiSkSurfaceFactory.h"
+#include "JsiSkTextBlobFactory.h"
+#include "JsiSkContourMeasureIter.h"
namespace RNSkia
{
@@ -60,6 +62,7 @@ namespace RNSkia
installFunction("XYWHRect", JsiSkRect::createCtor(context));
installFunction("RRectXY", JsiSkRRect::createCtor(context));
installFunction("Point", JsiSkPoint::createCtor(context));
+ installFunction("ContourMeasureIter", JsiSkContourMeasureIter::createCtor(context));
installFunction("MakeVertices", JsiSkVertices::createCtor(context));
// Static members
@@ -87,6 +90,7 @@ namespace RNSkia
"RuntimeEffect", std::make_shared(context));
installReadonlyProperty("Shader",
std::make_shared(context));
+ installReadonlyProperty("TextBlob", std::make_shared(context));
installReadonlyProperty("Surface", std::make_shared(context));
};
};
diff --git a/package/cpp/api/JsiSkCanvas.h b/package/cpp/api/JsiSkCanvas.h
index 01e27fec63..8ffe51fd51 100644
--- a/package/cpp/api/JsiSkCanvas.h
+++ b/package/cpp/api/JsiSkCanvas.h
@@ -11,6 +11,7 @@
#include "JsiSkRRect.h"
#include "JsiSkSVG.h"
#include "JsiSkVertices.h"
+#include "JsiSkTextBlob.h"
#include
#include