diff --git a/example/lib/renderfont_demo.dart b/example/lib/renderfont_demo.dart index 20b2a72..c27fdc7 100644 --- a/example/lib/renderfont_demo.dart +++ b/example/lib/renderfont_demo.dart @@ -86,9 +86,7 @@ Future renderFontDemo() async { // run.xAt(index) } glyphRuns.dispose(); - // var glyph = roboto.getPath(222); - // glyph.issueCommands(paintGlyphPath); - // glyph.dispose(); + montserrat.dispose(); roboto.dispose(); } diff --git a/lib/src/renderfont_ffi.dart b/lib/src/renderfont_ffi.dart index fcfcb97..83d9820 100644 --- a/lib/src/renderfont_ffi.dart +++ b/lib/src/renderfont_ffi.dart @@ -28,19 +28,19 @@ class GlyphPathStruct extends Struct { external int verbCount; } -class DynamicUint16Array extends Struct { +class SimpleUint16Array extends Struct { external Pointer data; @Uint64() external int size; } -class DynamicUint32Array extends Struct { +class SimpleUint32Array extends Struct { external Pointer data; @Uint64() external int size; } -class DynamicFloatArray extends Struct { +class SimpleFloatArray extends Struct { external Pointer data; @Uint64() external int size; @@ -59,9 +59,10 @@ class RenderGlyphRunNative extends Struct implements RenderGlyphRun { @Float() external double size; - external DynamicUint16Array glyphs; - external DynamicUint32Array textOffsets; - external DynamicFloatArray xpos; + external SimpleUint16Array glyphs; + external SimpleUint32Array textOffsets; + external SimpleFloatArray xpos; + external SimpleUint32Array breaks; @override double get fontSize => size; diff --git a/lib/src/renderfont_wasm.dart b/lib/src/renderfont_wasm.dart index c2e0a0d..59037f2 100644 --- a/lib/src/renderfont_wasm.dart +++ b/lib/src/renderfont_wasm.dart @@ -13,6 +13,7 @@ late js.JsFunction _deleteRenderFont; late js.JsFunction _makeGlyphPath; late js.JsFunction _deleteGlyphPath; late js.JsFunction _shapeText; +late js.JsFunction _deleteShapeResult; class RawPathWasm extends RawPath { final int rawPathPtr; @@ -129,11 +130,12 @@ class RawPathIterator extends Iterator { } class TextShapeResultWasm extends TextShapeResult { + final int rawPathResultsPtr; final List runs; - TextShapeResultWasm(this.runs); + TextShapeResultWasm(this.rawPathResultsPtr, this.runs); @override - void dispose() {} + void dispose() => _deleteShapeResult.apply([rawPathResultsPtr]); @override RenderGlyphRun runAt(int index) => runs[index]; @@ -167,11 +169,13 @@ class RenderGlyphRunWasm extends RenderGlyphRun { final WasmDynamicArray glyphs; final WasmDynamicArray textOffsets; final WasmDynamicArray xPositions; + final WasmDynamicArray breaks; RenderGlyphRunWasm(this.byteData) : glyphs = byteData.readDynamicArray(8), textOffsets = byteData.readDynamicArray(16), - xPositions = byteData.readDynamicArray(24); + xPositions = byteData.readDynamicArray(24), + breaks = byteData.readDynamicArray(32); @override double get fontSize => byteData.getFloat32(4, Endian.little); @@ -237,30 +241,23 @@ class RenderFontWasm extends RenderFont { Uint32List.fromList(text.codeUnits), writer.uint8Buffer, ], - ) as Uint8List; + ) as js.JsObject; - var reader = BinaryReader.fromList(result); + var rawResult = result['rawResult'] as int; + var results = result['results'] as Uint8List; + + var reader = BinaryReader.fromList(results); var dataPointer = reader.readUint32(); var dataSize = reader.readUint32(); - print("RUN COUNTe ${dataSize}"); + var runList = []; for (int i = 0; i < dataSize; i++) { - // var data = ByteData.view(result.buffer, dataPointer); - // var fontSizeOfRun = data.getFloat32(4, Endian.little); - // print("RFS $fontSizeOfRun"); runList - .add(RenderGlyphRunWasm(ByteData.view(result.buffer, dataPointer))); - // print("FONT SIZE: ${run.fontSize}"); - dataPointer += 4 + 4 + 8 + 8 + 8; + .add(RenderGlyphRunWasm(ByteData.view(results.buffer, dataPointer))); + dataPointer += 4 + 4 + 8 + 8 + 8 + 8; } - // var view = ByteData.view( - // result.buffer, result.offsetInBytes, result.lengthInBytes); - // // size_t is 32 bit (4 bytes) in wasm - // var resultRunCount = view.getUint32(4, Endian.little); - // var resultRunCount = view.getUint32(4, Endian.little); - // for (int i = 0; i < resultRunCount; i++) {} - return TextShapeResultWasm(runList); + return TextShapeResultWasm(rawResult, runList); } } @@ -303,6 +300,7 @@ Future initRenderFont() async { _makeGlyphPath = module['makeGlyphPath'] as js.JsFunction; _deleteGlyphPath = module['deleteGlyphPath'] as js.JsFunction; _shapeText = module['shapeText'] as js.JsFunction; + _deleteShapeResult = module['deleteShapeResult'] as js.JsFunction; completer.complete(); } ], diff --git a/wasm/js/render_font.js b/wasm/js/render_font.js index 3c8cfbd..9dc0478 100644 --- a/wasm/js/render_font.js +++ b/wasm/js/render_font.js @@ -44,6 +44,9 @@ RenderFont["onRuntimeInitialized"] = function () { var nativeShapeText = RenderFont["shapeText"]; RenderFont["shapeText"] = function (codeUnits, runsList) { var shapeResult = nativeShapeText(codeUnits, runsList); - return HEAPU8["subarray"](shapeResult); + return { + "rawResult": shapeResult, + "results": HEAPU8["subarray"](shapeResult), + }; }; }; diff --git a/wasm/premake5_wasm.lua b/wasm/premake5_wasm.lua index 42c080e..d0fe554 100644 --- a/wasm/premake5_wasm.lua +++ b/wasm/premake5_wasm.lua @@ -103,7 +103,6 @@ linkoptions { '--closure 1', '--closure-args="--externs ./js/externs.js"', '--bind', - '-s ASSERTIONS=0', '-s FORCE_FILESYSTEM=0', '-s MODULARIZE=1', '-s NO_EXIT_RUNTIME=1', @@ -125,28 +124,40 @@ linkoptions { } filter {'options:single_file'} -linkoptions { - '-o %{cfg.targetdir}/render_font_single.js' -} +do + linkoptions { + '-o %{cfg.targetdir}/render_font_single.js' + } +end filter {'options:not single_file'} -linkoptions { - '-o %{cfg.targetdir}/render_font.js' -} +do + linkoptions { + '-o %{cfg.targetdir}/render_font.js' + } +end filter 'options:single_file' -linkoptions { - '-s SINGLE_FILE=1' -} +do + linkoptions { + '-s SINGLE_FILE=1' + } +end filter 'configurations:debug' -defines {'DEBUG'} -symbols 'On' +do + defines {'DEBUG'} + symbols 'On' + linkoptions {'-s ASSERTIONS=1'} +end filter 'configurations:release' -defines {'RELEASE'} -defines {'NDEBUG'} -optimize 'On' +do + defines {'RELEASE'} + defines {'NDEBUG'} + optimize 'On' + linkoptions {'-s ASSERTIONS=0'} +end buildoptions { '-Oz', diff --git a/wasm/renderfont_bindings.cpp b/wasm/renderfont_bindings.cpp index 9f56836..faf2dba 100644 --- a/wasm/renderfont_bindings.cpp +++ b/wasm/renderfont_bindings.cpp @@ -27,7 +27,7 @@ WasmPtr makeRenderFont(emscripten::val byteArray) { return (WasmPtr) nullptr; } -void deleteRenderFont(WasmPtr renderFont) { delete reinterpret_cast(renderFont); } +void deleteRenderFont(WasmPtr renderFont) { reinterpret_cast(renderFont)->unref(); } struct GlyphPath { WasmPtr rawPath; @@ -50,6 +50,10 @@ GlyphPath makeGlyphPath(WasmPtr renderFontPtr, rive::GlyphID id) { void deleteGlyphPath(WasmPtr rawPath) { delete reinterpret_cast(rawPath); } +void deleteShapeResult(WasmPtr shaperResult) { + delete reinterpret_cast*>(shaperResult); +} + WasmPtr shapeText(emscripten::val codeUnits, emscripten::val runsList) { std::vector runsBytes(runsList["byteLength"].as()); { @@ -88,4 +92,5 @@ EMSCRIPTEN_BINDINGS(RenderFont) { function("deleteGlyphPath", &deleteGlyphPath); function("shapeText", &shapeText); + function("deleteShapeResult", &deleteShapeResult); } \ No newline at end of file