shopify / react-native-skia Goto Github PK
View Code? Open in Web Editor NEWHigh-performance React Native Graphics using Skia
Home Page: https://shopify.github.io/react-native-skia
License: MIT License
High-performance React Native Graphics using Skia
Home Page: https://shopify.github.io/react-native-skia
License: MIT License
We really don't need to expose these properties to our users - although we can still use them if needed if they are just removed from prop types.
I tried running the example, using the link to .../package and installing the alpha release but I'm getting this error.
react-native-skia/package/cpp/rnskia/RNSkPlatformContext.h:12:10: fatal error: 'SkStream.h' file not found
Currently there are no example available with complex uniform values.
Hey,
it seems there is a problem in building native dependencies on iOS on newest version:
Undefined symbols for architecture x86_64:
"SkFontMgr_New_Custom_Data(sk_sp<SkData>*, int)", referenced from:
RNSkia::JsiSkFontMgrFactory::FromData(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long) in libreact-native-skia.a(RNSkManager.o)
Xcode: 13.1
react-native: 0.66.4
react-native-skia 0.1.69
Hey guys!
Thank you so much for your work, I love it. I just patched Android to make it build on RN <0.65 and Expo like @mrousavy did here: https://github.com/mrousavy/react-native-mmkv/pull/267/files
I'm going to send a PR :)
Hi @chrfalch , @wcandillon
It would be very useful to have the possibility that every time a new version is released in the readme part of the installation it is automatically updated.
For example I don't know, use github's actions to make it update automatically.
The following demo for blend modes seems to produce an unexpected result: https://gist.github.com/wcandillon/98c254161b78f274f224a0c8fa6df561
However the result is identical between RN Skia and CanvasKit.
To be investigated.
Example: If a component uses a fixed path string, the string will be converted to a path each time the component is instantiated. We should check if we could identify more of these scenarios and offer some kind of native caching.
We should add integration with react-native-reanimated shared values.
The integration should add listeners to shared values so that when a value changes the SkiaView / Canvas is repainted.
The integration should not add a hard dependency on Reanimated. If Reanimated is installed, the hook should work - if not it should emit a warning.
The integration should be implemented as a hook called useSharedValueEffect
and the signature will be like this:
/**
* Connects a shared value from reanimated to a SkiaView or Canvas
* so whenever the shared value changes the SkiaView will redraw.
* @param ref Reference to the SkiaView or Canvas
* @param value Shared value to add change listeners for
* @param values Additional (optional) shared values to add change listeners for
*/
export type useSharedValueEffectType = <T = number>(
ref: RefObject<SkiaView>,
value: SharedValueTypeWrapper<T>,
...values: SharedValueTypeWrapper<T>[]
) => void;
On iOS the process of removing and unregistering a SkiaView is a bit more complicated than on Android, since the iOS RCTViewManager
does not have a notification for a view removal. This causes a memory leak and we need to track adding/removing the SkiaView by using the willMoveToWindow
on the wrapping UIView. This causes some issues with the implementation of the RNSkDrawView
not being available when we create/remove the view (ex. in navigation transitions). In addition all of this can cause a race condition where the view is removed while it has a pending draw request that will be executed after the view was removed.
We need to solve a few things here
Currently, uniforms are passed to shaders as an array:
<Shader source={source} uniforms={[blue, r]} />
How about passing them as a map, the same way its done in gl-react
? (see e.g. https://gl-react-cookbook.surge.sh/colordisc)
<Shader source={source} uniforms={{blue, r}} />
Then order would not matter, but the object keys must match the uniform name in the shader.
I love what you guys have done with the project. I am extremely hopeful, looking at what creative people are doing using this package when it's not even stable.
So, I was wondering what's the future plan of this project? are you guys planning to build a UI component as flutter has for Material and Cupertino?
I'm trying to follow the steps for running the examples playground, but when running yarn on the "package" directory, it will fail when trying to create symlinks in Windows 10. The exact error is the following:
Updating symlinks for Android build...
Creating symlink to api E:\Development\Repositories\react-native-skia\package\scripts E:\Development\Repositories\react-native-skia\package
node:internal/fs/utils:344
throw err;
^
Error: EEXIST: file already exists, symlink 'E:\Development\Repositories\react-native-skia\package\cpp\api' -> 'E:\Development\Repositories\react-native-skia\package\android\cpp\api'
at Object.symlinkSync (node:fs:1651:3)
at createSymlink (E:\Development\Repositories\react-native-skia\package\scripts\install-npm.js:8:6)
at Object.<anonymous> (E:\Development\Repositories\react-native-skia\package\scripts\install-npm.js:16:1)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
at node:internal/main/run_main_module:17:47 {
errno: -4075,
syscall: 'symlink',
code: 'EEXIST',
path: 'E:\\Development\\Repositories\\react-native-skia\\package\\cpp\\api',
dest: 'E:\\Development\\Repositories\\react-native-skia\\package\\android\\cpp\\api'
If I try to build the example regardless of this error, when running "npx react-native run-android" it will fail and complain about some source files missing, presumably because the symlink did not work. This was executed on a freshly cloned repository, so no previous build steps were run, but the destination link path mentioned in the error seems to be versioned in Github.
NOTE It seems like the library won't build on Windows either, even if I restrict it to build the android binaries only. I'm using the ninja binary that comes with the Android SDK cmake (v3.10). It seems like the build script is unable to create and enter the "out" folder in the cloned skia submodule.
An approach to this would be to have something like useDerivedValue
in Reanimated 2
const props = useDerivedValue(() => ({x, y, value}));
return (<Text
font={font}
x={() => props.value.x}
y={() => props.value.y}
value={() => props.value.value}
/>);
We could also have some utility function to make the binding (could be refined):
const props = useDerivedValue(() => ({x, y, value}));
return (<Text
font={font}
...animatedProps(props)
/>);
The current icon/logo image is just a mashup and needs to be replaced. It should be replaced with the logo used for the project.
When running some pages of the examples project I get the following error.
The views that trigger this error are: API (for some sub-views), Filters and Animation. The other pages work fine.
I work on a M1 mac with a physical ios device.
Value is undefined, expected an Object
[native code]
[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:149917:22](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:149917:22)[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146270:9](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146270:9)[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146318:19](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146318:19)
forEach@[native code]
draw@[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146317:45](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146317:45)[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146364:29](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146364:29)
forEach@[native code]
processChildren@[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146362:21](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:146362:21)
draw@[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:149530:35](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:149530:35)[http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:122624:16](http://192.168.1.190:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.shopify.reactnative.skia.example:122624:16)
RCTFatal
RNSkia::PlatformContext::raiseError(std::exception const&)
RNSkia::RNSkDrawView::drawInSurface(sk_sp<SkSurface>, int, int, double, std::__1::shared_ptrRNSkia::RNSkPlatformContext)
RNSkDrawViewImpl::drawFrame(double)
RNSkia::RNSkDrawView::performDraw()
decltype(*(std::__1::forwardRNSkia::RNSkDrawView*&(fp0)).fp()) std::__1::__invoke<void (RNSkia::RNSkDrawView::&)(), RNSkia::RNSkDrawView*&, void>(void (RNSkia::RNSkDrawView::*&)(), RNSkia::RNSkDrawView*&)
std::__1::__bind_return<void (RNSkia::RNSkDrawView::*)(), std::__1::tupleRNSkia::RNSkDrawView*, std::__1::tuple<>, __is_valid_bind_return<void (RNSkia::RNSkDrawView::*)(), std::__1::tupleRNSkia::RNSkDrawView*, std::__1::tuple<> >::value>::type std::__1::__apply_functor<void (RNSkia::RNSkDrawView::*)(), std::__1::tupleRNSkia::RNSkDrawView*, 0ul, std::__1::tuple<> >(void (RNSkia::RNSkDrawView::*&)(), std::__1::tupleRNSkia::RNSkDrawView*&, std::__1::__tuple_indices<0ul>, std::__1::tuple<>&&)
std::__1::__bind_return<void (RNSkia::RNSkDrawView::*)(), std::__1::tupleRNSkia::RNSkDrawView*, std::__1::tuple<>, __is_valid_bind_return<void (RNSkia::RNSkDrawView::*)(), std::__1::tupleRNSkia::RNSkDrawView*, std::__1::tuple<> >::value>::type std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>::operator()<>()
decltype(std::__1::forward<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>&>(fp)()) std::__1::__invoke<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>&>(std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>&)
void std::__1::__invoke_void_return_wrapper<void, true>::__call<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>&>(std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>&)
std::__1::__function::__alloc_func<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>, std::__1::allocator<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*> >, void ()>::operator()()
std::__1::__function::__func<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*>, std::__1::allocator<std::__1::__bind<void (RNSkia::RNSkDrawView::*)(), RNSkia::RNSkDrawView*> >, void ()>::operator()()
std::__1::__function::__value_func<void ()>::operator()() const
std::__1::function<void ()>::operator()() const
facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3::operator()(facebook::react::JSExecutor*) const
decltype(std::__1::forward<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3&>(fp)(std::__1::forwardfacebook::react::JSExecutor*(fp0))) std::__1::__invoke<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3&, facebook::react::JSExecutor*>(facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3&, facebook::react::JSExecutor*&&)
void std::__1::__invoke_void_return_wrapper<void, true>::__call<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3&, facebook::react::JSExecutor*>(facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3&, facebook::react::JSExecutor*&&)
std::__1::__function::__alloc_func<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3, std::__1::allocator<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3>, void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&)
std::__1::__function::__func<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3, std::__1::allocator<facebook::react::Instance::JSCallInvoker::scheduleAsync(std::__1::function<void ()>&&)::$_3>, void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&)
std::__1::__function::__value_func<void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*&&) const
std::__1::function<void (facebook::react::JSExecutor*)>::operator()(facebook::react::JSExecutor*) const
facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8::operator()() const
decltype(std::__1::forward<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&>(fp)()) std::__1::__invoke<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&>(facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&)
void std::__1::__invoke_void_return_wrapper<void, true>::__call<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&>(facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8&)
std::__1::__function::__alloc_func<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8, std::__1::allocator<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8>, void ()>::operator()()
std::__1::__function::__func<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8, std::__1::allocator<facebook::react::NativeToJsBridge::runOnExecutorQueue(std::__1::function<void (facebook::react::JSExecutor*)>)::$_8>, void ()>::operator()()
std::__1::__function::__value_func<void ()>::operator()() const
std::__1::function<void ()>::operator()() const
facebook::react::tryAndReturnError(std::__1::function<void ()> const&)
facebook::react::RCTMessageThread::tryFunc(std::__1::function<void ()> const&)
facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1::operator()() const
decltype(std::__1::forward<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(fp)()) std::__1::__invoke<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&)
void std::__1::__invoke_void_return_wrapper<void, true>::__call<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&)
std::__1::__function::__alloc_func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()()
std::__1::__function::__func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()()
std::__1::__function::__value_func<void ()>::operator()() const
std::__1::function<void ()>::operator()() const
invocation function for block in facebook::react::RCTMessageThread::runAsync(std::__1::function<void ()>)
338F58B1-9B75-38A0-B908-E2574AB1D39A
338F58B1-9B75-38A0-B908-E2574AB1D39A
338F58B1-9B75-38A0-B908-E2574AB1D39A
CFRunLoopRunSpecific
+[RCTCxxBridge runRunLoop]
4E7D1FF6-6B64-3833-9E60-CC662AFE2647
_pthread_start
thread_start
I tried to use the simple example from here https://shopify.github.io/react-native-skia/docs/paint/overview in react native expo
// code
import {Canvas, Circle, Paint, Group} from "@shopify/react-native-skia";
export default function App() {
const r = 128;
return (
<Canvas style={{ flex: 1 }}>
<Paint color="lightblue" />
<Circle cx={r} cy={r} r={r} />
{/* The paint is inherited by the following sibling and descendants. */}
<Group style="stroke" strokeWidth={10}>
<Circle cx={3 * r} cy={3 * r} r={r} />
</Group>
</Canvas>
);
}
i'm getting the following error
ReferenceError: Can't find variable: SkiaApi
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError
at node_modules/metro-runtime/src/polyfills/require.js:204:6 in guardedLoadModule
at http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:169518:3 in global code
here is my package.json dependencies
"dependencies": {
"@shopify/react-native-skia": "https://github.com/Shopify/react-native-skia/releases/download/v0.1.64-alpha/shopify-react-native-skia-0.1.64.tgz",
"expo": "~44.0.0",
"expo-status-bar": "~1.2.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-gesture-handler": "^2.1.1",
"react-native-reanimated": "^2.3.1",
"react-native-web": "0.17.1"
},
Please help and thanks for the great work!
A common way to animate paths in RN is to use SVG and animate through the path string property. This can cause a lot of overhead, and we might want to offer a better solution in RN Skia to avoid the adoption of the same pattern here.
Skia already has a path interpolation function on the Path object which can be used and it seems (after testing) to be fast enough to use for animated interpolation.
The only issue with this function is that it is not exposed in the CanvasKit API so we might need to introduce some kind of utility namespace for functionality that are not a CanvasKit member - or discuss with the CanvasKit/Skia team if they should introduce this functionality as well.
We're currently shipping our typescript files directly - we should add a step for compiling them to JS and deploy these files as well.
Hi, I wanted to try the sample projects so I followed the guide below: https://github.com/Shopify/react-native-skia#playground
Step:
yarn
command in the react-native-skia
directorycd package && yarn
commandWhen I run the following command I get the following error:
Where am I doing wrong?
Version: 0.1.47
React-Native: 0.65.2
@babel/core: "^7.14.8"
,
@babel/preset-typescript: "^7.15.0"
,
typescript: 4.4.4
Platforms: iOS & Android
I am getting the following error when bundling the app:
The exported identifier "Point" is not declared in Babel's scope tracker
as a JavaScript value binding, and "@babel/plugin-transform-typescript"
never encountered it as a TypeScript type declaration.
It will be treated as a JavaScript value.
This problem is likely caused by another plugin injecting
"Point" without registering it in the scope tracker. If you are the author
of that plugin, please use "scope.registerDeclaration(declarationPath)".
The exported identifier "Point" is not declared in Babel's scope tracker
as a JavaScript value binding, and "@babel/plugin-transform-typescript"
never encountered it as a TypeScript type declaration.
It will be treated as a JavaScript value.
This problem is likely caused by another plugin injecting
"Point" without registering it in the scope tracker. If you are the author
of that plugin, please use "scope.registerDeclaration(declarationPath)".
Android Bundling failed 2019ms
node_modules/@shopify/react-native-skia/src/renderer/processors/Shapes.ts: /node_modules/@shopify/react-native-skia/src/renderer/processors/Shapes.ts: Exporting local "Point", which is not declared.
10 | }
11 |
> 12 | export { Point };
| ^^^^^
13 |
14 | interface PointCircleDef {
15 | c: Point;
SyntaxError: /node_modules/@shopify/react-native-skia/src/renderer/processors/Shapes.ts: Exporting local "Point", which is not declared.
10 | }
11 |
> 12 | export { Point };
| ^^^^^
13 |
14 | interface PointCircleDef {
15 | c: Point;
at File.buildCodeFrameError (/node_modules/@babel/core/lib/transformation/file/file.js:249:12)
at NodePath.buildCodeFrameError (/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/index.js:139:21)
at getLocalMetadata (/node_modules/@babel/helper-module-transforms/lib/normalize-and-load-metadata.js:315:22)
at /node_modules/@babel/helper-module-transforms/lib/normalize-and-load-metadata.js:344:33
at Array.forEach (<anonymous>)
at /node_modules/@babel/helper-module-transforms/lib/normalize-and-load-metadata.js:341:33
at Array.forEach (<anonymous>)
at getLocalExportMetadata (/node_modules/@babel/helper-module-transforms/lib/normalize-and-load-metadata.js:328:27)
at getModuleMetadata (/node_modules/@babel/helper-module-transforms/lib/normalize-and-load-metadata.js:121:21)
If you need more info please let me know!
I managed to make this what you see in the image, but how can I go about adding a gradient background to the text.
Effect I'd like to be able to mimic as a gradient looks like this:
Code:
import React from "react";
import {Canvas, Path} from "@shopify/react-native-skia";
const App = () => {
return (
<Canvas style={{ flex: 1 }}>
<Path
path="M 17.625 0.3 L 17.625 7.875 Q 18.325 6.85 19.388 6.175 A 4.281 4.281 0 0 1 21.022 5.569 A 5.675 5.675 0 0 1 21.925 5.5 A 5.806 5.806 0 0 1 23.191 5.629 Q 24.027 5.816 24.636 6.273 A 3.315 3.315 0 0 1 25.212 6.825 A 4.601 4.601 0 0 1 26.114 8.67 Q 26.277 9.33 26.297 10.102 A 8.441 8.441 0 0 1 26.3 10.325 L 26.3 18.8 L 24.05 18.8 L 24.05 10.575 Q 24.05 9.501 23.688 8.76 A 2.687 2.687 0 0 0 23.413 8.313 Q 22.775 7.475 21.575 7.475 Q 21 7.475 20.438 7.688 Q 19.875 7.9 19.375 8.275 A 6.538 6.538 0 0 0 18.553 9.012 A 7.356 7.356 0 0 0 18.425 9.15 Q 17.975 9.65 17.625 10.2 L 17.625 18.8 L 15.375 18.8 L 15.375 0.3 L 17.625 0.3 Z M 60.4 18.8 L 60.4 0.3 L 62.65 0.3 L 62.65 10.875 L 68.525 5.55 L 69.825 6.975 L 64.8 11.425 L 70.925 17.55 L 69.375 19.05 L 62.65 12.125 L 62.65 18.8 L 60.4 18.8 Z M 78.8 24.1 L 79.3 22.225 A 2.564 2.564 0 0 0 79.589 22.369 Q 79.741 22.433 79.917 22.489 A 4.564 4.564 0 0 0 80.037 22.525 Q 80.475 22.65 81.05 22.65 Q 81.575 22.65 82.038 22.5 A 2.32 2.32 0 0 0 82.615 22.216 A 2.973 2.973 0 0 0 82.925 21.975 Q 83.35 21.6 83.738 20.95 Q 84.039 20.445 84.332 19.743 A 15.434 15.434 0 0 0 84.5 19.325 L 85.075 17.825 L 83.875 17.825 L 78.8 6.4 L 80.8 5.5 L 85.65 16.325 L 89.425 5.6 L 91.5 6.4 L 86.725 19.45 Q 86.175 20.95 85.563 21.938 A 8.217 8.217 0 0 1 84.989 22.753 Q 84.666 23.155 84.322 23.462 A 4.918 4.918 0 0 1 84.25 23.525 A 4.25 4.25 0 0 1 83.259 24.168 A 3.798 3.798 0 0 1 82.738 24.363 A 6.002 6.002 0 0 1 81.357 24.591 A 6.959 6.959 0 0 1 81 24.6 A 6.355 6.355 0 0 1 80.38 24.571 Q 80.074 24.541 79.808 24.48 A 3.647 3.647 0 0 1 79.687 24.45 Q 79.125 24.3 78.8 24.1 Z M 199.55 24.1 L 200.05 22.225 A 2.564 2.564 0 0 0 200.339 22.369 Q 200.491 22.433 200.667 22.489 A 4.564 4.564 0 0 0 200.787 22.525 Q 201.225 22.65 201.8 22.65 Q 202.325 22.65 202.788 22.5 A 2.32 2.32 0 0 0 203.365 22.216 A 2.973 2.973 0 0 0 203.675 21.975 Q 204.1 21.6 204.487 20.95 Q 204.789 20.445 205.082 19.743 A 15.434 15.434 0 0 0 205.25 19.325 L 205.825 17.825 L 204.625 17.825 L 199.55 6.4 L 201.55 5.5 L 206.4 16.325 L 210.175 5.6 L 212.25 6.4 L 207.475 19.45 Q 206.925 20.95 206.312 21.938 A 8.217 8.217 0 0 1 205.739 22.753 Q 205.416 23.155 205.072 23.462 A 4.918 4.918 0 0 1 205 23.525 A 4.25 4.25 0 0 1 204.009 24.168 A 3.798 3.798 0 0 1 203.488 24.363 A 6.002 6.002 0 0 1 202.107 24.591 A 6.959 6.959 0 0 1 201.75 24.6 A 6.355 6.355 0 0 1 201.13 24.571 Q 200.824 24.541 200.558 24.48 A 3.647 3.647 0 0 1 200.437 24.45 Q 199.875 24.3 199.55 24.1 Z M 244.25 6.8 L 244.25 5.8 L 246.3 5.8 L 246.3 18.5 Q 246.3 20.125 245.875 21.275 A 5.337 5.337 0 0 1 245.321 22.38 A 4.396 4.396 0 0 1 244.662 23.163 Q 243.875 23.9 242.775 24.25 A 7.349 7.349 0 0 1 241.342 24.547 A 9.367 9.367 0 0 1 240.325 24.6 Q 239.15 24.6 238.075 24.325 A 6.754 6.754 0 0 1 236.703 23.817 A 5.943 5.943 0 0 1 236.15 23.5 L 236.975 21.55 A 5.14 5.14 0 0 0 237.929 22.143 A 6.184 6.184 0 0 0 238.375 22.338 A 4.226 4.226 0 0 0 239.172 22.557 Q 239.564 22.626 240.015 22.644 A 7.947 7.947 0 0 0 240.325 22.65 Q 242.1 22.65 243.112 21.725 Q 244.125 20.8 244.125 18.725 L 244.125 17.125 A 3.95 3.95 0 0 1 243.625 17.62 Q 243.229 17.952 242.687 18.263 A 3.977 3.977 0 0 1 241.392 18.721 A 5.397 5.397 0 0 1 240.45 18.8 Q 239.35 18.8 238.3 18.363 Q 237.25 17.925 236.45 17.088 A 6.042 6.042 0 0 1 235.461 15.69 A 7.396 7.396 0 0 1 235.163 15.038 A 6.603 6.603 0 0 1 234.762 13.514 A 8.834 8.834 0 0 1 234.675 12.25 A 7.769 7.769 0 0 1 234.899 10.359 A 6.876 6.876 0 0 1 235.15 9.563 A 7.074 7.074 0 0 1 235.963 8.02 A 6.267 6.267 0 0 1 236.438 7.425 Q 237.25 6.525 238.35 6.013 Q 239.45 5.5 240.7 5.5 A 5.787 5.787 0 0 1 241.797 5.6 A 4.567 4.567 0 0 1 242.713 5.875 Q 243.6 6.25 244.25 6.8 Z M 120.3 17.175 L 119.825 18.925 Q 118.974 18.925 118.374 18.686 A 2.339 2.339 0 0 1 117.925 18.45 A 2.388 2.388 0 0 1 117.057 17.372 A 3.099 3.099 0 0 1 116.95 17.075 Q 116.075 17.975 114.938 18.538 A 5.494 5.494 0 0 1 112.618 19.098 A 6.387 6.387 0 0 1 112.45 19.1 Q 111.6 19.1 110.813 18.838 Q 110.025 18.575 109.413 18 A 3.674 3.674 0 0 1 108.745 17.145 A 4.822 4.822 0 0 1 108.438 16.5 A 4.877 4.877 0 0 1 108.183 15.58 Q 108.102 15.126 108.082 14.605 A 9.104 9.104 0 0 1 108.075 14.25 L 108.075 5.8 L 110.325 5.8 L 110.325 13.95 Q 110.325 15.475 110.963 16.288 Q 111.6 17.1 112.875 17.1 Q 113.925 17.1 114.875 16.688 Q 115.825 16.275 116.575 15.575 L 116.575 5.8 L 118.825 5.8 L 118.825 15.425 A 3.955 3.955 0 0 0 118.839 15.774 Q 118.854 15.942 118.885 16.083 A 1.662 1.662 0 0 0 118.95 16.313 Q 119.056 16.598 119.215 16.776 A 0.977 0.977 0 0 0 119.275 16.838 Q 119.475 17.025 119.75 17.1 Q 120.025 17.175 120.3 17.175 Z M 47.775 5.8 L 47.775 7.975 Q 48.475 6.925 49.563 6.213 A 4.329 4.329 0 0 1 51.339 5.556 A 5.657 5.657 0 0 1 52.15 5.5 A 5.806 5.806 0 0 1 53.416 5.629 Q 54.252 5.816 54.861 6.273 A 3.315 3.315 0 0 1 55.437 6.825 A 4.601 4.601 0 0 1 56.339 8.67 Q 56.502 9.33 56.522 10.102 A 8.441 8.441 0 0 1 56.525 10.325 L 56.525 18.8 L 54.275 18.8 L 54.275 10.575 Q 54.275 9.15 53.625 8.313 A 2.115 2.115 0 0 0 52.139 7.496 A 3.097 3.097 0 0 0 51.775 7.475 Q 51.2 7.475 50.65 7.688 Q 50.1 7.9 49.588 8.275 Q 49.075 8.65 48.638 9.15 Q 48.2 9.65 47.85 10.2 L 47.85 18.8 L 45.6 18.8 L 45.6 5.8 L 47.775 5.8 Z M 222.925 5.8 L 222.925 7.975 Q 223.625 6.925 224.712 6.213 A 4.329 4.329 0 0 1 226.489 5.556 A 5.657 5.657 0 0 1 227.3 5.5 A 5.806 5.806 0 0 1 228.566 5.629 Q 229.402 5.816 230.011 6.273 A 3.315 3.315 0 0 1 230.587 6.825 A 4.601 4.601 0 0 1 231.489 8.67 Q 231.652 9.33 231.672 10.102 A 8.441 8.441 0 0 1 231.675 10.325 L 231.675 18.8 L 229.425 18.8 L 229.425 10.575 Q 229.425 9.15 228.775 8.313 A 2.115 2.115 0 0 0 227.289 7.496 A 3.097 3.097 0 0 0 226.925 7.475 Q 226.35 7.475 225.8 7.688 Q 225.25 7.9 224.737 8.275 Q 224.225 8.65 223.787 9.15 Q 223.35 9.65 223 10.2 L 223 18.8 L 220.75 18.8 L 220.75 5.8 L 222.925 5.8 Z M 148.725 0.825 L 148.05 2.725 Q 147.525 2.45 146.925 2.225 A 3.543 3.543 0 0 0 146.019 2.02 A 4.339 4.339 0 0 0 145.6 2 A 2.701 2.701 0 0 0 144.843 2.101 A 2.073 2.073 0 0 0 143.912 2.663 A 2.115 2.115 0 0 0 143.426 3.505 Q 143.322 3.831 143.29 4.227 A 4.573 4.573 0 0 0 143.275 4.6 L 143.275 6.275 L 147.125 6.275 L 147.125 8.225 L 143.275 8.225 L 143.275 18.8 L 141.025 18.8 L 141.025 8.225 L 139.025 8.225 L 139.025 6.275 L 141.025 6.275 L 141.025 4.75 A 6.398 6.398 0 0 1 141.111 3.675 A 4.983 4.983 0 0 1 141.35 2.775 A 4.737 4.737 0 0 1 141.884 1.734 A 4.157 4.157 0 0 1 142.25 1.275 Q 142.825 0.65 143.65 0.325 A 4.722 4.722 0 0 1 145.06 0.013 A 5.591 5.591 0 0 1 145.45 0 Q 146.5 0 147.263 0.238 Q 148.025 0.475 148.725 0.825 Z M 0 3.4 L 0 1.3 L 13.125 1.3 L 13.125 3.4 L 7.75 3.4 L 7.75 18.8 L 5.375 18.8 L 5.375 3.4 L 0 3.4 Z M 271.725 7.55 L 272.2 5.8 A 4.381 4.381 0 0 1 273.257 5.918 Q 273.97 6.095 274.431 6.541 A 2.538 2.538 0 0 1 275.075 7.625 A 2.695 2.695 0 0 1 275.217 7.424 Q 275.296 7.323 275.395 7.21 A 6.838 6.838 0 0 1 275.612 6.975 A 4.096 4.096 0 0 1 276.072 6.569 A 5.293 5.293 0 0 1 276.5 6.275 A 5.254 5.254 0 0 1 277.215 5.908 A 6.526 6.526 0 0 1 277.7 5.725 Q 278.375 5.5 279.2 5.5 Q 280.325 5.5 281.362 5.95 Q 282.4 6.4 283.187 7.25 A 5.926 5.926 0 0 1 284.087 8.538 A 7.471 7.471 0 0 1 284.45 9.35 A 7.184 7.184 0 0 1 284.853 10.994 A 9.29 9.29 0 0 1 284.925 12.175 A 9.03 9.03 0 0 1 284.779 13.832 A 7.394 7.394 0 0 1 284.462 15 A 7.467 7.467 0 0 1 283.799 16.386 A 6.278 6.278 0 0 1 283.213 17.188 A 5.698 5.698 0 0 1 281.594 18.501 A 5.459 5.459 0 0 1 281.4 18.6 Q 280.375 19.1 279.25 19.1 A 5.206 5.206 0 0 1 277.674 18.866 A 4.758 4.758 0 0 1 277.088 18.638 Q 276.1 18.175 275.45 17.575 L 275.45 24.3 L 273.2 24.3 L 273.2 9.125 A 2.754 2.754 0 0 0 273.168 8.691 Q 273.132 8.467 273.056 8.291 A 1.051 1.051 0 0 0 272.788 7.913 Q 272.375 7.55 271.725 7.55 Z M 286.55 7.55 L 287.025 5.8 A 4.381 4.381 0 0 1 288.082 5.918 Q 288.795 6.095 289.256 6.541 A 2.538 2.538 0 0 1 289.9 7.625 A 2.695 2.695 0 0 1 290.042 7.424 Q 290.121 7.323 290.22 7.21 A 6.838 6.838 0 0 1 290.437 6.975 A 4.096 4.096 0 0 1 290.897 6.569 A 5.293 5.293 0 0 1 291.325 6.275 A 5.254 5.254 0 0 1 292.04 5.908 A 6.526 6.526 0 0 1 292.525 5.725 Q 293.2 5.5 294.025 5.5 Q 295.15 5.5 296.187 5.95 Q 297.225 6.4 298.012 7.25 A 5.926 5.926 0 0 1 298.912 8.538 A 7.471 7.471 0 0 1 299.275 9.35 A 7.184 7.184 0 0 1 299.678 10.994 A 9.29 9.29 0 0 1 299.75 12.175 A 9.03 9.03 0 0 1 299.604 13.832 A 7.394 7.394 0 0 1 299.287 15 A 7.467 7.467 0 0 1 298.624 16.386 A 6.278 6.278 0 0 1 298.038 17.188 A 5.698 5.698 0 0 1 296.419 18.501 A 5.459 5.459 0 0 1 296.225 18.6 Q 295.2 19.1 294.075 19.1 A 5.206 5.206 0 0 1 292.499 18.866 A 4.758 4.758 0 0 1 291.913 18.638 Q 290.925 18.175 290.275 17.575 L 290.275 24.3 L 288.025 24.3 L 288.025 9.125 A 2.754 2.754 0 0 0 287.993 8.691 Q 287.957 8.467 287.881 8.291 A 1.051 1.051 0 0 0 287.613 7.913 Q 287.2 7.55 286.55 7.55 Z M 182.075 6.275 L 182.55 2.175 L 184.275 2.175 L 184.275 6.275 L 187.875 6.275 L 187.875 8.225 L 184.275 8.225 L 184.275 14.5 A 5.419 5.419 0 0 0 184.298 15.012 Q 184.322 15.262 184.37 15.478 A 2.757 2.757 0 0 0 184.438 15.725 A 2.741 2.741 0 0 0 184.588 16.098 Q 184.712 16.347 184.875 16.525 Q 185.15 16.825 185.537 16.963 Q 185.925 17.1 186.35 17.1 A 3.473 3.473 0 0 0 187.316 16.968 A 3.217 3.217 0 0 0 187.525 16.9 Q 188.075 16.7 188.575 16.425 L 189.2 18.225 A 4.637 4.637 0 0 1 188.795 18.439 Q 188.395 18.628 187.85 18.813 Q 187 19.1 186.075 19.1 A 4.625 4.625 0 0 1 184.779 18.928 A 3.488 3.488 0 0 1 183.112 17.875 A 3.947 3.947 0 0 1 182.319 16.444 Q 182.126 15.846 182.06 15.12 A 8.759 8.759 0 0 1 182.025 14.325 L 182.025 8.225 L 179.775 8.225 L 179.775 6.275 L 182.075 6.275 Z M 39.075 6.85 L 39.075 5.8 L 41.125 5.8 L 41.125 15.65 A 3.037 3.037 0 0 0 41.15 16.059 Q 41.233 16.667 41.588 16.888 Q 42.05 17.175 42.6 17.175 L 42.125 18.925 Q 39.784 18.925 39.251 17.07 A 3.398 3.398 0 0 1 39.225 16.975 A 7.125 7.125 0 0 1 38.726 17.568 A 8.193 8.193 0 0 1 38.538 17.763 Q 38.15 18.15 37.65 18.45 Q 37.15 18.75 36.525 18.925 Q 35.9 19.1 35.15 19.1 Q 33.925 19.1 32.863 18.625 Q 31.8 18.15 31.013 17.275 A 6.223 6.223 0 0 1 30.048 15.83 A 7.551 7.551 0 0 1 29.762 15.163 A 7.222 7.222 0 0 1 29.368 13.516 A 9.287 9.287 0 0 1 29.3 12.375 A 8.264 8.264 0 0 1 29.552 10.311 A 7.46 7.46 0 0 1 29.75 9.663 A 6.946 6.946 0 0 1 30.54 8.086 A 6.199 6.199 0 0 1 31.013 7.475 Q 31.825 6.55 32.963 6.025 A 5.781 5.781 0 0 1 35.157 5.506 A 6.771 6.771 0 0 1 35.45 5.5 Q 36.575 5.5 37.488 5.888 A 6.5 6.5 0 0 1 38.559 6.461 A 5.526 5.526 0 0 1 39.075 6.85 Z M 266.575 6.85 L 266.575 5.8 L 268.625 5.8 L 268.625 15.65 A 3.037 3.037 0 0 0 268.65 16.059 Q 268.733 16.667 269.088 16.888 Q 269.55 17.175 270.1 17.175 L 269.625 18.925 Q 267.284 18.925 266.751 17.07 A 3.398 3.398 0 0 1 266.725 16.975 A 7.125 7.125 0 0 1 266.226 17.568 A 8.193 8.193 0 0 1 266.038 17.763 Q 265.65 18.15 265.15 18.45 Q 264.65 18.75 264.025 18.925 Q 263.4 19.1 262.65 19.1 Q 261.425 19.1 260.362 18.625 Q 259.3 18.15 258.513 17.275 A 6.223 6.223 0 0 1 257.548 15.83 A 7.551 7.551 0 0 1 257.262 15.163 A 7.222 7.222 0 0 1 256.868 13.516 A 9.287 9.287 0 0 1 256.8 12.375 A 8.264 8.264 0 0 1 257.052 10.311 A 7.46 7.46 0 0 1 257.25 9.663 A 6.946 6.946 0 0 1 258.04 8.086 A 6.199 6.199 0 0 1 258.513 7.475 Q 259.325 6.55 260.463 6.025 A 5.781 5.781 0 0 1 262.657 5.506 A 6.771 6.771 0 0 1 262.95 5.5 Q 264.075 5.5 264.987 5.888 A 6.5 6.5 0 0 1 266.059 6.461 A 5.526 5.526 0 0 1 266.575 6.85 Z M 131.025 5.65 L 130.35 7.975 Q 129.897 7.784 129.284 7.775 A 4.148 4.148 0 0 0 129.225 7.775 Q 128.525 7.775 127.863 8.075 A 3.3 3.3 0 0 0 126.835 8.812 A 3.897 3.897 0 0 0 126.688 8.975 A 3.884 3.884 0 0 0 126.206 9.696 Q 126.011 10.066 125.863 10.513 Q 125.581 11.357 125.553 12.474 A 10.001 10.001 0 0 0 125.55 12.725 L 125.55 18.8 L 123.3 18.8 L 123.3 5.8 L 125.475 5.8 L 125.475 8.625 Q 125.7 8.025 126.075 7.45 Q 126.45 6.875 126.963 6.45 A 4.169 4.169 0 0 1 127.923 5.858 A 4.83 4.83 0 0 1 128.15 5.763 A 3.861 3.861 0 0 1 129.149 5.526 A 4.777 4.777 0 0 1 129.65 5.5 Q 130.025 5.5 130.388 5.538 A 4.924 4.924 0 0 1 130.688 5.578 Q 130.87 5.608 131.025 5.65 Z M 171.775 5.65 L 171.1 7.975 Q 170.647 7.784 170.034 7.775 A 4.148 4.148 0 0 0 169.975 7.775 Q 169.275 7.775 168.612 8.075 A 3.3 3.3 0 0 0 167.585 8.812 A 3.897 3.897 0 0 0 167.438 8.975 A 3.884 3.884 0 0 0 166.956 9.696 Q 166.761 10.066 166.612 10.513 Q 166.331 11.357 166.303 12.474 A 10.001 10.001 0 0 0 166.3 12.725 L 166.3 18.8 L 164.05 18.8 L 164.05 5.8 L 166.225 5.8 L 166.225 8.625 Q 166.45 8.025 166.825 7.45 Q 167.2 6.875 167.712 6.45 A 4.169 4.169 0 0 1 168.673 5.858 A 4.83 4.83 0 0 1 168.9 5.763 A 3.861 3.861 0 0 1 169.899 5.526 A 4.777 4.777 0 0 1 170.4 5.5 Q 170.775 5.5 171.138 5.538 A 4.924 4.924 0 0 1 171.438 5.578 Q 171.62 5.608 171.775 5.65 Z M 199.175 5.65 L 198.5 7.975 Q 198.047 7.784 197.434 7.775 A 4.148 4.148 0 0 0 197.375 7.775 Q 196.675 7.775 196.013 8.075 A 3.3 3.3 0 0 0 194.985 8.812 A 3.897 3.897 0 0 0 194.838 8.975 A 3.884 3.884 0 0 0 194.356 9.696 Q 194.161 10.066 194.013 10.513 Q 193.731 11.357 193.703 12.474 A 10.001 10.001 0 0 0 193.7 12.725 L 193.7 18.8 L 191.45 18.8 L 191.45 5.8 L 193.625 5.8 L 193.625 8.625 Q 193.85 8.025 194.225 7.45 Q 194.6 6.875 195.112 6.45 A 4.169 4.169 0 0 1 196.073 5.858 A 4.83 4.83 0 0 1 196.3 5.763 A 3.861 3.861 0 0 1 197.299 5.526 A 4.777 4.777 0 0 1 197.8 5.5 Q 198.175 5.5 198.538 5.538 A 4.924 4.924 0 0 1 198.838 5.578 Q 199.02 5.608 199.175 5.65 Z M 92.391 10.715 A 8.549 8.549 0 0 0 92.25 12.3 A 8.676 8.676 0 0 0 92.282 13.057 A 7.18 7.18 0 0 0 92.737 15.05 A 7.363 7.363 0 0 0 92.865 15.357 A 6.359 6.359 0 0 0 94.088 17.2 Q 94.95 18.1 96.138 18.6 A 6.162 6.162 0 0 0 96.9 18.864 A 6.873 6.873 0 0 0 98.725 19.1 A 7.612 7.612 0 0 0 98.981 19.096 A 6.608 6.608 0 0 0 101.287 18.613 Q 102.475 18.125 103.35 17.225 A 5.956 5.956 0 0 0 103.812 16.69 A 6.54 6.54 0 0 0 104.713 15.063 A 6.954 6.954 0 0 0 105.046 13.903 A 8.519 8.519 0 0 0 105.2 12.25 A 8.731 8.731 0 0 0 105.141 11.22 A 6.953 6.953 0 0 0 104.7 9.45 A 7.18 7.18 0 0 0 104.535 9.069 A 6.105 6.105 0 0 0 103.325 7.325 Q 102.45 6.45 101.263 5.975 A 6.514 6.514 0 0 0 101.113 5.918 A 6.797 6.797 0 0 0 98.725 5.5 Q 97.35 5.5 96.163 5.975 Q 94.975 6.45 94.113 7.325 Q 93.25 8.2 92.75 9.463 A 6.828 6.828 0 0 0 92.391 10.715 Z M 148.241 10.715 A 8.549 8.549 0 0 0 148.1 12.3 A 8.676 8.676 0 0 0 148.132 13.057 A 7.18 7.18 0 0 0 148.587 15.05 A 7.363 7.363 0 0 0 148.715 15.357 A 6.359 6.359 0 0 0 149.938 17.2 Q 150.8 18.1 151.987 18.6 A 6.162 6.162 0 0 0 152.75 18.864 A 6.873 6.873 0 0 0 154.575 19.1 A 7.612 7.612 0 0 0 154.831 19.096 A 6.608 6.608 0 0 0 157.137 18.613 Q 158.325 18.125 159.2 17.225 A 5.956 5.956 0 0 0 159.662 16.69 A 6.54 6.54 0 0 0 160.563 15.063 A 6.954 6.954 0 0 0 160.896 13.903 A 8.519 8.519 0 0 0 161.05 12.25 A 8.731 8.731 0 0 0 160.991 11.22 A 6.953 6.953 0 0 0 160.55 9.45 A 7.18 7.18 0 0 0 160.385 9.069 A 6.105 6.105 0 0 0 159.175 7.325 Q 158.3 6.45 157.112 5.975 A 6.514 6.514 0 0 0 156.963 5.918 A 6.797 6.797 0 0 0 154.575 5.5 Q 153.2 5.5 152.013 5.975 Q 150.825 6.45 149.963 7.325 Q 149.1 8.2 148.6 9.463 A 6.828 6.828 0 0 0 148.241 10.715 Z M 216.75 5.8 L 216.75 18.8 L 214.5 18.8 L 214.5 5.8 L 216.75 5.8 Z M 102.9 12.3 Q 102.9 11.325 102.588 10.45 A 4.891 4.891 0 0 0 101.994 9.286 A 4.429 4.429 0 0 0 101.713 8.925 Q 101.15 8.275 100.388 7.888 Q 99.625 7.5 98.725 7.5 A 4.812 4.812 0 0 0 97.418 7.668 A 3.509 3.509 0 0 0 95.65 8.8 A 4.47 4.47 0 0 0 94.732 10.643 Q 94.567 11.308 94.552 12.087 A 8.217 8.217 0 0 0 94.55 12.25 Q 94.55 13.225 94.863 14.113 A 5.033 5.033 0 0 0 95.441 15.272 A 4.538 4.538 0 0 0 95.737 15.663 Q 96.3 16.325 97.063 16.713 Q 97.825 17.1 98.725 17.1 A 4.672 4.672 0 0 0 99.704 17.001 A 3.796 3.796 0 0 0 100.475 16.75 Q 101.25 16.4 101.788 15.763 A 4.342 4.342 0 0 0 102.475 14.621 A 5.175 5.175 0 0 0 102.613 14.25 A 5.7 5.7 0 0 0 102.859 13.086 A 7.252 7.252 0 0 0 102.9 12.3 Z M 158.75 12.3 Q 158.75 11.325 158.438 10.45 A 4.891 4.891 0 0 0 157.844 9.286 A 4.429 4.429 0 0 0 157.563 8.925 Q 157 8.275 156.237 7.888 Q 155.475 7.5 154.575 7.5 A 4.812 4.812 0 0 0 153.268 7.668 A 3.509 3.509 0 0 0 151.5 8.8 A 4.47 4.47 0 0 0 150.582 10.643 Q 150.417 11.308 150.402 12.087 A 8.217 8.217 0 0 0 150.4 12.25 Q 150.4 13.225 150.713 14.113 A 5.033 5.033 0 0 0 151.291 15.272 A 4.538 4.538 0 0 0 151.587 15.663 Q 152.15 16.325 152.913 16.713 Q 153.675 17.1 154.575 17.1 A 4.672 4.672 0 0 0 155.554 17.001 A 3.796 3.796 0 0 0 156.325 16.75 Q 157.1 16.4 157.638 15.763 A 4.342 4.342 0 0 0 158.325 14.621 A 5.175 5.175 0 0 0 158.463 14.25 A 5.7 5.7 0 0 0 158.709 13.086 A 7.252 7.252 0 0 0 158.75 12.3 Z M 38.875 15.475 L 38.875 8.5 Q 38.2 8.025 37.388 7.738 Q 36.575 7.45 35.675 7.45 A 4.036 4.036 0 0 0 34.558 7.601 A 3.612 3.612 0 0 0 34.025 7.8 Q 33.275 8.15 32.738 8.788 A 4.348 4.348 0 0 0 32.111 9.788 A 5.375 5.375 0 0 0 31.9 10.325 A 5.856 5.856 0 0 0 31.629 11.645 A 7.155 7.155 0 0 0 31.6 12.3 A 6.431 6.431 0 0 0 31.717 13.549 A 5.445 5.445 0 0 0 31.9 14.238 A 4.821 4.821 0 0 0 32.369 15.244 A 4.136 4.136 0 0 0 32.75 15.763 Q 33.3 16.4 34.038 16.75 A 3.67 3.67 0 0 0 35.487 17.097 A 4.281 4.281 0 0 0 35.65 17.1 Q 36.6 17.1 37.45 16.65 Q 38.3 16.2 38.875 15.475 Z M 266.375 15.475 L 266.375 8.5 Q 265.7 8.025 264.888 7.738 Q 264.075 7.45 263.175 7.45 A 4.036 4.036 0 0 0 262.058 7.601 A 3.612 3.612 0 0 0 261.525 7.8 Q 260.775 8.15 260.237 8.788 A 4.348 4.348 0 0 0 259.611 9.788 A 5.375 5.375 0 0 0 259.4 10.325 A 5.856 5.856 0 0 0 259.129 11.645 A 7.155 7.155 0 0 0 259.1 12.3 A 6.431 6.431 0 0 0 259.217 13.549 A 5.445 5.445 0 0 0 259.4 14.238 A 4.821 4.821 0 0 0 259.869 15.244 A 4.136 4.136 0 0 0 260.25 15.763 Q 260.8 16.4 261.537 16.75 A 3.67 3.67 0 0 0 262.987 17.097 A 4.281 4.281 0 0 0 263.15 17.1 Q 264.1 17.1 264.95 16.65 Q 265.8 16.2 266.375 15.475 Z M 275.45 9.15 L 275.45 15.55 Q 276.1 16.225 276.937 16.663 A 3.889 3.889 0 0 0 278.539 17.093 A 4.641 4.641 0 0 0 278.8 17.1 A 3.578 3.578 0 0 0 279.851 16.949 A 3.215 3.215 0 0 0 280.35 16.75 Q 281.05 16.4 281.562 15.763 A 4.289 4.289 0 0 0 282.155 14.768 A 5.289 5.289 0 0 0 282.35 14.238 Q 282.625 13.35 282.625 12.25 Q 282.625 11.125 282.312 10.238 A 5.121 5.121 0 0 0 281.89 9.322 A 4.202 4.202 0 0 0 281.463 8.725 Q 280.925 8.1 280.213 7.775 Q 279.5 7.45 278.7 7.45 Q 277.625 7.45 276.763 7.988 Q 275.9 8.525 275.45 9.15 Z M 290.275 9.15 L 290.275 15.55 Q 290.925 16.225 291.762 16.663 A 3.889 3.889 0 0 0 293.364 17.093 A 4.641 4.641 0 0 0 293.625 17.1 A 3.578 3.578 0 0 0 294.676 16.949 A 3.215 3.215 0 0 0 295.175 16.75 Q 295.875 16.4 296.387 15.763 A 4.289 4.289 0 0 0 296.98 14.768 A 5.289 5.289 0 0 0 297.175 14.238 Q 297.45 13.35 297.45 12.25 Q 297.45 11.125 297.137 10.238 A 5.121 5.121 0 0 0 296.715 9.322 A 4.202 4.202 0 0 0 296.288 8.725 Q 295.75 8.1 295.037 7.775 Q 294.325 7.45 293.525 7.45 Q 292.45 7.45 291.588 7.988 Q 290.725 8.525 290.275 9.15 Z M 244.05 15.3 L 244.05 8.5 A 6.936 6.936 0 0 0 243.305 8.051 A 8.762 8.762 0 0 0 242.725 7.775 A 3.741 3.741 0 0 0 241.9 7.531 Q 241.52 7.463 241.087 7.452 A 6.562 6.562 0 0 0 240.925 7.45 Q 240.15 7.45 239.437 7.763 Q 238.725 8.075 238.175 8.675 A 4.221 4.221 0 0 0 237.513 9.649 A 5.189 5.189 0 0 0 237.3 10.138 A 4.917 4.917 0 0 0 237.039 11.175 A 6.687 6.687 0 0 0 236.975 12.125 A 6.123 6.123 0 0 0 237.067 13.207 A 4.85 4.85 0 0 0 237.3 14.063 Q 237.625 14.925 238.175 15.538 Q 238.725 16.15 239.437 16.475 Q 240.15 16.8 240.95 16.8 A 3.819 3.819 0 0 0 242.094 16.633 A 3.401 3.401 0 0 0 242.75 16.35 A 5.214 5.214 0 0 0 243.495 15.846 A 4.077 4.077 0 0 0 244.05 15.3 Z M 302.382 16.91 A 2.215 2.215 0 0 0 302.325 17.425 Q 302.325 18.1 302.825 18.6 A 2.079 2.079 0 0 0 302.841 18.616 A 1.604 1.604 0 0 0 304 19.1 A 2.151 2.151 0 0 0 304.156 19.094 A 1.615 1.615 0 0 0 305.2 18.638 A 1.508 1.508 0 0 0 305.598 17.982 A 1.924 1.924 0 0 0 305.675 17.425 A 1.556 1.556 0 0 0 305.53 16.757 A 1.739 1.739 0 0 0 305.162 16.25 A 2.12 2.12 0 0 0 305.032 16.133 A 1.581 1.581 0 0 0 304 15.75 Q 303.694 15.75 303.441 15.816 A 1.425 1.425 0 0 0 302.763 16.2 A 1.494 1.494 0 0 0 302.382 16.91 Z M 215.625 3.575 Q 214.975 3.575 214.512 3.113 A 1.515 1.515 0 0 1 214.05 2.02 A 1.817 1.817 0 0 1 214.05 2 A 1.997 1.997 0 0 1 214.107 1.508 A 1.397 1.397 0 0 1 214.475 0.85 A 1.415 1.415 0 0 1 215.211 0.464 A 2.066 2.066 0 0 1 215.625 0.425 Q 216.275 0.425 216.737 0.888 A 1.515 1.515 0 0 1 217.2 1.98 A 1.817 1.817 0 0 1 217.2 2 A 1.997 1.997 0 0 1 217.143 2.492 A 1.397 1.397 0 0 1 216.775 3.15 A 1.415 1.415 0 0 1 216.039 3.536 A 2.066 2.066 0 0 1 215.625 3.575 Z"
color="#ff5722"
style="stroke"
/>
</Canvas>
);
};
export default App;
P.s.
@chrfalch:
I'm getting the following warnings:
Even though Skia internally uses RRect
as its name for round rectangles, it might be easier for us to provide a RoundRect
component in the reconciler.
I'm too busy to start experimenting and contributing into this paradigm shifting project.
I assume this functionality is planned and we're all salivating over the day we can replace all our RN primitives and render our entire apps with react-native-skia
. Implementing the layout model used in RN styles will be a big step towards the takeover.
Turns out there's a project that has been working towards similar functionality for react-three-fiber.
It is a bit off-spec and over developed being designed for a 3d canvas context but there is a solid foundation that will give us a head start.
Hope this helps!
I was faced with this message Skia surface could not be created from parameters.
on the terminal.
I couldn't fix it.
"dependencies": {
"@shopify/react-native-skia": "https://github.com/Shopify/react-native-skia/releases/download/v0.1.47-alpha/shopify-react-native-skia-0.1.47.tgz",
"react": "17.0.2",
"react-native": "0.66.4"
},
import React from 'react';
import {SafeAreaView, StatusBar, useColorScheme} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {Canvas, Circle, Group} from '@shopify/react-native-skia';
export const HelloWorld = () => {
const width = 256;
const height = 256;
const r = 215;
return (
<Canvas style={{flex: 1}}>
<Group blendMode="multiply">
<Circle cx={r} cy={r} r={r} color="cyan" />
<Circle cx={width - r} cy={r} r={r} color="magenta" />
<Circle cx={width / 2} cy={height - r} r={r} color="yellow" />
</Group>
</Canvas>
);
};
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<HelloWorld />
</SafeAreaView>
);
};
export default App;
I tried this version v0.1.43
too.
It could be useful to add a matrix property to group. The idea is that if you work with a transform library you may want to supply the matrix directly instead of decomposing it back to the sequence of 2d transforms.
We could task advantage to this small task to add support for robust Matrix construction via ::fromValue
the same way we did it for points, rect, and rrect in Skia.
We could also think about some sort of lerp utility to go from one (random) transform to any other (random) transform.
When trying to setup the library on macOS for development according to the instructions at https://github.com/Shopify/react-native-skia#building, compile errors occur when building Skia for iOS through yarn build-skia
:
build-skia-error.txt
build-skia-error-2.txt
I then ran git submodule update --remote --merge
to update the submodules:
diff --git a/externals/depot_tools b/externals/depot_tools
index 5ba5119..db41eed 160000
--- a/externals/depot_tools
+++ b/externals/depot_tools
@@ -1 +1 @@
-Subproject commit 5ba5119227002ab191b0f916df435b7410c4ca3c
+Subproject commit db41eed6b7442273b54bac9695567d97b60718de
diff --git a/externals/skia b/externals/skia
index 0b898c4..b4d28b2 160000
--- a/externals/skia
+++ b/externals/skia
@@ -1 +1 @@
-Subproject commit 0b898c4b8e2a5291d378a99701a533eaf1d4d301
+Subproject commit b4d28b2f35396ae4dd69338254415066629dfd25
After this, Skia compiles and builds correctly, but I don't know if updating the submodules is required.
Maybe there is some step missing in the build instructions?
After installing react-native-skia
, npx react-native run-android
fails with the following error.
FAILURE: Build completed with 2 failures.
1: Task failed with an exception.
-----------
* Where:
Build file '/my-project/node_modules/@shopify/react-native-skia/android/build.gradle' line: 28
* What went wrong:
A problem occurred evaluating project ':shopify_react-native-skia'.
> Plugin with id 'maven' not found.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================
2: Task failed with an exception.
-----------
* What went wrong:
A problem occurred configuring project ':shopify_react-native-skia'.
> compileSdkVersion is not specified. Please add it to build.gradle
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
==============================================================================
* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/7.0.2/userguide/command_line_interface.html#sec:command_line_warnings
BUILD FAILED in 5s
After some digging, I tried to make it work with this PR #43 (still failing for now).
To build on Linux, I had to do the following before running yarn build-skia-android
:
# https://docs.conda.io/en/latest/miniconda.html
conda create -n "py2" python=2
conda activate py2
pip install ninja
Then run ANDROID_NDK=$ANDROID_HOME/ndk/21.4.7075529 && yarn build-skia-android
Hi @chrfalch , @wcandillon :
What do you think some props have a default value?
Taking for example Text:
Name | Type | Description | Default |
---|---|---|---|
value | string |
Text to draw | Hello World! |
familyName | string |
Font family name | serif |
size | number |
Font size | 12 |
We want to be able to use http(s) URIs directly when creating image, SVG, fonts etc (through an SkData instance).
I found the naming useProgress problematic:
The way the Group component processes children seem to be inconsistent with the rest of the tree.
<Group blendMode="clear">
<Paint blendMode="difference" />
<Path path={src} color="lightblue" />
<Path path={dst} color="pink" />
</Group>
seems to use the clear blend mode where difference might be the expected result.
the key in obj
syntax doesn't work in the reconciller. The situation needs to be sanatized.
$ /Users/wcandillon/tmp/react-native-skia/package/node_modules/.bin/tsc
src/animation/TimelineInfo/parameters/tests/getResolvedPosition.spec.ts:1:26 - error TS2307: Cannot find module '../../Timeline' or its corresponding type declarations.
1 import { Timeline } from "../../Timeline";
~~~~~~~~~~~~~~~~
Found 1 error.
This difference can only be seen when using fit="none"
. I couldn't find any obvious difference in the cpp code. To be investigated.
Hi @wcandillon , would it be possible to have support for https://snack.expo.dev in the future?
Hi @chrfalch , @wcandillon :
The set methods instead of returning a void
it would not be possible to return the type of the object.
For example for Paint
return IPaint
so you could do something similar as in the example below.
import {Skia, BlendMode, SkiaView, useDrawCallback} from "@shopify/react-native-skia";
const paint = Skia.Paint()
.setAntiAlias(true)
.setBlendMode(BlendMode.Multiply); <-- Edit
export const HelloWorld = () => {
const width = 256;
const height = 256;
const r = 215;
const onDraw = useDrawCallback((canvas) => {
// Cyan Circle
const cyan = paint.copy().setColor(Skia.Color("cyan")); <-- Edit
canvas.drawCircle(r, r, r, cyan);
// Magenta Circle
const magenta = paint.copy().setColor(Skia.Color("magenta")); <-- Edit
// Yellow Circle
const yellow = paint.copy().setColor(Skia.Color("yellow"));
canvas
.drawCircle(width - r, r, r, magenta)
.drawCircle(width/2, height - r, r, yellow); <-- Edit
});
return (
<SkiaView style={{ flex: 1 }} onDraw={onDraw} />
);
};
When calling Path.getBounds() on a new path for the first time, the returned rectangle is empty, ie. width/height is zero.
A solution is to use Path.computeTightBounds() instead, but this can be more expensive and does not cache its results.
I haven't found any issues about this in the Skia bug tracker, but we need to investigate and see if there is anything related to the caching used by getBounds() that results in the above behavior.
Hey, I've launched the typescript tabs expo template and tried running basic official hello world example, but getting the following error in terminal:
iOS Running app on iPhone 12
ReferenceError: Can't find variable: SkiaApi
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError
at node_modules/metro-runtime/src/polyfills/require.js:204:6 in guardedLoadModule
at http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:258689:3 in global code
Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called.
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:172:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/@react-native/polyfills/error-guard.js:49:36 in ErrorUtils.reportFatalError
Also, IDK why running yarn upgrade
throws following:
error /Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia: Command failed.
Exit code: 1
Command: yarn node scripts/install-npm.js
Arguments:
Directory: /Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia
Output:
yarn node v1.22.17
Updating symlinks for Android build...
Creating symlink to api /Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/scripts /Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia
internal/fs/utils.js:314
throw err;
^
Error: EEXIST: file already exists, symlink '/Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/cpp/api' -> '/Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/android/cpp/api'
at Object.symlinkSync (fs.js:1210:3)
at createSymlink (/Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/scripts/install-npm.js:8:6)
at Object.<anonymous> (/Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/scripts/install-npm.js:16:1)
at Module._compile (internal/modules/cjs/loader.js:1072:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
at Module.load (internal/modules/cjs/loader.js:937:32)
at Function.Module._load (internal/modules/cjs/loader.js:778:12)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
at internal/main/run_main_module.js:17:47 {
errno: -17,
syscall: 'symlink',
code: 'EEXIST',
path: '/Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/cpp/api',
dest: '/Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia/android/cpp/api'
}
error Command failed.
Exit code: 1
Command: /usr/local/bin/node
Arguments: scripts/install-npm.js
Directory: /Users/dmytro/Work/personal/haboo/node_modules/@shopify/react-native-skia
Output:
info Visit https://yarnpkg.com/en/docs/cli/node for documentation about this command.
Reproduction repository: https://github.com/sinnrrr/haboo
Package version: v0.1.43-alpha
Platform: iOS (I think other platform do have same issue, because the problem is in JS)
This is especially evident when running a lot of animations (SkiaViews in continuous mode).
Hey ๐
Thank you so much for this great work!
I was wondering whether there is an official roadmap where we can see which features you guys are still working on? For example, I thought about getting into all of this by bringing over the Skottie module(?). However, I don't know whether someone else is already working on it. So, for contributors, I think it'd be great to have a shared roadmap?
(asking because in the presentation video of Skia you guys gave estimates when you will have 100% feature completeness)
And Android and RN web, blend modes behave the same (as expected except for some blend modes: #5)
https://skia.org/docs/user/api/skblendmode_overview/
On iOS, only a few blend modes are working (blend mode test is in #5).
We need to enable Bitcode for the device builds of the skia library to support deploying apps with Skia on iOS.
When converting from a JS object to a SkRect, we use the static function JsiSkxxxx::fromValue
to get to the underlying host object. In the JsiSkRect
implementation we test the incoming object to see if it is a host object or a rect-like object. A small mistake was made that caused the JSI asObject
method to be called twice, which is noticeable in the instrumentation/profiling of an app using a lot of rects.
const auto object = obj.asObject(runtime);
if (object.isHostObject(runtime)) {
return obj.asObject(runtime)
.asHostObject<JsiSkRect>(runtime)
.get()
->getObject();
} else {
auto x = object.getProperty(runtime, "x").asNumber();
auto y = object.getProperty(runtime, "y").asNumber();
auto width = object.getProperty(runtime, "width").asNumber();
auto height = object.getProperty(runtime, "height").asNumber();
return std::make_shared<SkRect>(SkRect::MakeXYWH(x, y, width, height));
}
Hi @chrfalch , @wcandillon :
It would be possible to have an example in the future of an animation with text similar to this:
Currently only scalars are supported as uniforms:
Are you already working on supporting arrays as uniforms?
I am trying to use a latest version of the library (0.1.66-alpha) in a fresh react native package. Initially, I got an error which looks like this:
Use of class template 'sk_sp' requires template arguments
This is resolved by adding a template argument in JsiSkFontMgr.h
. If I replace sk_sp(typeface)
with sk_sp<SkTypeface(typeface)
, the error is gone.
But after that, I got another error (linking error).
Undefined symbols for architecture x86_64:
"SkFontMgr_New_Custom_Data(sk_sp<SkData>*, int)", referenced from:
RNSkia::JsiSkFontMgrFactory::FromData(facebook::jsi::Runtime&, facebook::jsi::Value const&, facebook::jsi::Value const*, unsigned long) in libreact-native-skia.a(RNSkManager.o)
ld: symbol(s) not found for architecture x86_64
I am not sure, why this is happening.
More information:
Works fine with 0.1.63
RN Version - 0.66.4
Xcode - 12.5.1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.