Uses it in the artboard title but also updates the flutter runtime massively to support FFI & WASM C++ Rive Text. PRing to let the tests run.
Diffs=
3be5ff0d8 Text (#4372)
Pick up the Skia path also when building for debug. In debug, we were linking against two different Skias between the Android app and the renderer library.
Diffs=
90245a5e1 Fix the Android debug build
Fix for issue discussed here:
https://2dimensions.slack.com/archives/CLLCU09T6/p1667317349310539
Boils down to a missing animation in a blend state:

We make some assumptions about our Animation Instances always having a backing animation. I've mode those assumptions more robust by including an assert and by having a Blend State always provide an animation, so if one is missing an empty one (with no keyframes) will be used. This maintains edit time and runtime fidelity.
Diffs=
0a0f3c267 Fix for missing animation in a blend state. (#4415)
Elementwise ternary ?: operations on vectors aren't supported until clang 13. This change adds a "simd::if_then_else" method that we will have to use instead, which has a fallback implementation for compilers that don't support the vector ternary.
Diffs=
440512dca Add simd::if_then_else (#4403)
We can't expect every platform that uses Rive to have access to a recent clang. Add fallbacks with a performance warning when builtins aren't supported.
It's worth considering adding a gcc or older clang runner in order to test these fallbacks.
Diffs=
e98b93a61 Add SIMD fallbacks for missing builtins
Fixed a bug that prevented fits and alignments that were set in the RiveViewModel's init from propagating to the RiveView
Diffs=
26aa419fd Fixed a bug that prevented fits and alignments that were set in the RiveViewModel's init from propagating to the RiveView.
fixes#3927https://github.com/rive-app/rive/issues/3927
i did it once by changing how to determine the work end area, but then compared to flutter, which was doing this by changing how advance works. which is probably better.
Diffs=
bd567e2ba apply speed to both time and total time
Adding support for bidirectional text using SheenBidi to break styled runs into directional runs. This also needs to introduce the "baseDirection" of a paragraph (and the concept of a paragraph) in order to properly flow the runs after shaping.
Diffs=
291a3a02b Bidi Text Support (#4282)
Fixes issue caught by Duolingo with nested artboards and non-zero origins. Adds AABB::fromLTWH to keep AABB to Rect tidy.
Diffs=
99c5590bc Fix non-framed artboard origin rendering. (#4281)
Fixing some verbiage and links from copy/pasta from the README docs updates
Diffs=
b9f2a3491 docs: fix links and some verbiage in the iOS runtime README
This is to generate custom sized images from SVGs, defaults will still work the same as before.
Diffs=
434223338 Optional width and height parameters for thumbnailer
Updating the line breaker to support:
- forced line breaks (return characters)
- store break points in context of runs (no searching when breaking)
- perform alignment (center/left/right)
In order to implement tests for this in Rive, I moved the Harfbuzz shaper into Rive (conditionally compiled out) but now we can test line-breaking logic in Rive core.
Since I had to update some of the build scripts, I ran the same new premake formatter we've been using.
<img width="910" alt="CleanShot 2022-09-19 at 21 03 53@2x" src="https://user-images.githubusercontent.com/454182/191164998-6b7b131b-b624-41c7-81d2-c2e01a050680.png">
Diffs=
a1d921c85 Line breaker (#4249)
While working on marshaling the RenderFont abstraction to Dart FFI and WASM, it became clear that dealing with vectors inside of vectors gets tricky.
We can wrap one single vector into a return struct like:
```
struct EasyToMarshal {
std::vector<float>* ptrToVector;
float* dataInVector;
size_t size;
};
```
This is what we currently do and FFI/WASM is expected to then call in to C++ to delete ptrToVector when it's done with the data.
This gets problematic to do when ptrToVector contains types that internally contain more vectors. The size and memory layout of vector isn't guaranteed across platforms with different STL implementations.
The result from the shaper was a vector of RenderGlyphRuns:
```
struct RenderGlyphRun {
rcp<RenderFont> font;
float size;
std::vector<GlyphID> glyphs; // [#glyphs]
std::vector<uint32_t> textOffsets; // [#glyphs]
std::vector<float> xpos; // [#glyphs + 1]
};
std::vector<RenderGlyphRun> shapeText(...){}
```
This PR introduces a DynamicArray (totally up for renaming this to something less lame) which makes it really easy to marshal DynamicArrays inside of other DynamicArrays as we know the memory layout is just like rive::Span (a pointer and a size).
Separately, this does make me wonder if we should use uint64_t for size in DynamicArrays so we can guarantee those are always 64 bit (the FFI and WASM tooling doesn't make it easy to marhsal runtime determined sizes).
Diffs=
e62737cf9 include cstring for memcpy
468dd3a2b Add growToFit, assert we didn’t overflow size_t, and in place constructor calls
f0947d32f Add realloc down to actual used size from capacity.
516d0fc12 Move resize to builder and rename to simple array.
091904d22 malloc/realloc version
e574043f7 More windows fixes
c1f5b96ec Fix windows compiler warning.
164911445 Implement a dynamic array (simple vector for marshaling).
Saves us from having to type the class name twice:
make_rcp<MyClass>()
vs.
rcp<MyClass>(new MyClass())
Diffs=
51eb2ee20 Add a make_rcp<>() helper method
A couple of fixes:
- skia renderer uses new harfbuzz dependency paths
- skia builds of viewer don't try to include tess specific logic for example atlas
Diffs=
45293a868 oops
f8a8f4c0c override skia cache folder
d86875260 Try
10b22bfe3 Attempt using correct skia dir
85feea448 more fixes
0b0371b24 switching to bash
ad07fbd18 Tweak for linux build
dab0642a0 Adding config dirs for linux
7e5a2aa47 Build harfbuzz from the recorder builder
a77709a68 Fixing skia viewer and renderer builds.
Implement Iter as an STL-style iterator that can be traversed very
efficiently using range-for:
for (auto [verb, pts] : rawPath) { ... }
Manually inject the implicit moveTos in RawPath (namely, the implicit
moveTo(0) at the beginning of a path, if the client didn't add one, and
a similar moveTo after close).
The implicit moveTos fix a bug in RawPath::bounds where we were not
accounting for the implicit moveTo(0), as well as a bug in
ContourMeasureIter::tryNext where we expected the first contour in a
path to begin with PathVerb::move.
With the implicit moveTos guaranteed to be in the raw path, the iterator
can be simplified to just peek back one point and give a contiguous array
beginning with p0 for each verb. In addition to generally simplifying
things, one more perk of having all the points contiguous is that it
also enables fast SIMD loads.
IterateRawPath bench result:
MacOS NEON: 8.71ms -> 5.02 (58%)
Windows SSE: 5.63ms -> 4.20 (75%)
BuildRawPath bench result:
MacOS NEON: 2.09ms -> 2.19 (105%)
Windows SSE: 2.18ms -> 2.27 (104%)
Diffs=
fdeff54d1 Simpify RawPath::Iter (#4157)
- builds and gets harfbuzz the same way we do our other dependencies
- slight tweak to building libpng so it also builds from the dependencies folder
Diffs=
0e69f1166 building harfbuzz with our premake setup and removing third_party (for now)
Deletes the version that takes spans of points and verbs. We are
planning to inject the implicit moveTos into RawPath, at which point we
won't be able to just copy in arrays of points and verbs anymore.
Also changes the "RawPath" version of the factory method to take a
non-const "RawPath&" ref. This enables zero-copy construction via
stealing the arrays out from under the RawPath's points and verbs.
Diffs=
1bd616612 Update Factory::makeRenderPath to only accept a RawPath (#4211)
Implements an example Atlas packer (ideally run offline/in a pre-runtime step using the runtime API). Imagine a game engine like Defold using this at edit time/from within engine tooling to pack all the images necessary for all the Rive files in one level into a single Atlas/set of Atlases to minimize state changes when drawing the whole scene.
Example implementation is mostly here: packages/runtime/viewer/src/sample_tools
The example does both atlas packing and runtime image resolving from the Atlas from the same set of utility classes and their corresponding objects in order to keep the example simple (no serialization of the atlas metadata or pixels). It also uses a very naive packing technique, but it illustrates these main features:
1. find all the image assets in a file
2. packing them sequentially into an atlas
3. ...while building up metadata of where they are in the atlas
4. strips the images from the file
5. shows how to then re-load the file (with no in-band images) and use the generated atlas
6. implements a FileAssetResolver to resolve the images in the Atlas and provide UV transforms
Steps 1-4 are what an engine would do at edit/export time. Steps 5-6 show what a runtime would do to then use the files generated in steps 1-4.
All of this is implemented in the viewer, minor changes were necessary to the runtime to transform UVs with a transform provided by the RenderImage and fix some bugs. See how the viewer wires this all up here: 86dbad80c6/packages/runtime/viewer/src/viewer_content/scene_content.cpp (L185-L233)
Diffs=
38b70a98d Cleanup
ac44c1ad7 Fix broken test.
40d2fa966 Fixing UV modification at load time.
736bcf133 Adding an example atlas packer.
e42e484eb Starting to add example atlas packer.
438f98716 Adding imgui menu bar
Adds a "simd" namespace with vector utilities (SSE, NEON, WASM_SIMD),
and implements RawPath::bounds in SIMD. This namespace relies
exclusively on the latest clang vector extensions, so from here on, Rive
needs to be built with a recent clang. On our own bots, we had to bump
the Android builder to NDK r25b, the Ubuntu builder to 22.04, and the
MacOS builder to macos-12.
RawPathBounds bench result:
MacOS: 2.37ms -> .579 (4.1x)
Windows: 3.53ms -> 1.68 (2.1x)
Windows SSE can be optimized down to .927ms (3.8x) by forcing the SSE
min/max instructions, but they have different behavior with NaN, which
is why clang doesn't use them directly, so it seems like an
over-optimization at this point.
Diffs=
986b49674 Add a simd library for SSE / NEON / WASM_SIMD (#4199)
When using the earcut triangulatation we pass through the vertex buffer straight from raw path and just use an index buffer generating by the triangulation.
Diffs=
ba0406a89 Fix tess test.
oops - forgot to build the tess renderer on the prev PR (should update the bots to build viewer in a few configs)
Diffs=
a7615ab7c Update call site for RawPath constructor
Adds a ```File::stripAssets``` utility method that is optionally compiled in. This allows removing in-band asset bytes from the file. It only does this for the provided asset types. Right now we only put image assets in-band, but in the future we may have fonts, scripts, sounds, other .riv files, etc so allowing the utility to only strip specific concrete file types is nice to have.
The next step will be to use this utility to show how you'd create an atlas out of the in-band images, strip out the images, and save a smaller .riv that uses images from that generated atlas.
I envision adding more utility methods like this for tools that want to manipulate Rive content at build/pre-package time. These should be able to be compiled out as they are rarely necessary at mass-consumption runtime (I doubt anyone wants these in WASM unless they're building their game engine, not just the player, in JS).
Diffs=
698af558e Fix linux build.
cb742eb08 Adds a utility to strip out FileAssetContents for given FileAsset types.
We may want to try and standardize on clang SIMD vector extensions,
which means everything has to build with clang.
Diffs=
07186fc98 Build RiveSharp with clang (#4194)